ng-virtual-list 14.12.0 → 14.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (460) hide show
  1. package/README.md +1 -11
  2. package/esm2020/lib/components/ng-list-item/base/base-virtual-list-item-component.mjs +309 -0
  3. package/{esm2022 → esm2020}/lib/components/ng-list-item/base/index.mjs +2 -2
  4. package/{esm2022 → esm2020}/lib/components/ng-list-item/const/index.mjs +40 -40
  5. package/{esm2022 → esm2020}/lib/components/ng-list-item/interfaces/index.mjs +1 -1
  6. package/{esm2022 → esm2020}/lib/components/ng-list-item/interfaces/template-context.mjs +1 -1
  7. package/esm2020/lib/components/ng-list-item/ng-virtual-list-item.component.mjs +200 -0
  8. package/{esm2022 → esm2020}/lib/components/ng-list-item/ng-virtual-list-item.module.mjs +20 -20
  9. package/{esm2022 → esm2020}/lib/components/ng-list-item/utils/create-display-id.mjs +9 -9
  10. package/{esm2022 → esm2020}/lib/components/ng-list-item/utils/get-element-by-index.mjs +19 -19
  11. package/{esm2022 → esm2020}/lib/components/ng-list-item/utils/index.mjs +4 -4
  12. package/{esm2022 → esm2020}/lib/components/ng-list-item/utils/matrix-3d.mjs +12 -12
  13. package/esm2020/lib/components/ng-prerender-container/components/ng-prerender-list/ng-prerender-list.component.mjs +278 -0
  14. package/{esm2022 → esm2020}/lib/components/ng-prerender-container/components/ng-prerender-list/ng-prerender-list.module.mjs +21 -21
  15. package/esm2020/lib/components/ng-prerender-container/components/ng-prerender-list-item/ng-prerender-list-item.component.mjs +94 -0
  16. package/{esm2022 → esm2020}/lib/components/ng-prerender-container/components/ng-prerender-list-item/ng-prerender-list-item.module.mjs +20 -20
  17. package/esm2020/lib/components/ng-prerender-container/components/ng-prerender-scroller/ng-prerender-scroller.component.mjs +141 -0
  18. package/{esm2022 → esm2020}/lib/components/ng-prerender-container/components/ng-prerender-scroller/ng-prerender-scroller.module.mjs +20 -20
  19. package/{esm2022 → esm2020}/lib/components/ng-prerender-container/core/index.mjs +2 -2
  20. package/esm2020/lib/components/ng-prerender-container/core/prerender-track-box.mjs +201 -0
  21. package/{esm2022 → esm2020}/lib/components/ng-prerender-container/events/index.mjs +5 -5
  22. package/{esm2022 → esm2020}/lib/components/ng-prerender-container/interfaces/index.mjs +1 -1
  23. package/{esm2022 → esm2020}/lib/components/ng-prerender-container/interfaces/refresh-params.mjs +1 -1
  24. package/esm2020/lib/components/ng-prerender-container/ng-prerender-container.component.mjs +90 -0
  25. package/{esm2022 → esm2020}/lib/components/ng-prerender-container/ng-prerender-container.module.mjs +20 -20
  26. package/{esm2022 → esm2020}/lib/components/ng-prerender-container/types/cache.mjs +1 -1
  27. package/{esm2022 → esm2020}/lib/components/ng-prerender-container/types/index.mjs +1 -1
  28. package/{esm2022 → esm2020}/lib/components/ng-scroll-bar/const/index.mjs +8 -8
  29. package/{esm2022 → esm2020}/lib/components/ng-scroll-bar/enums/index.mjs +2 -2
  30. package/{esm2022 → esm2020}/lib/components/ng-scroll-bar/enums/scrollbar-states.mjs +6 -6
  31. package/{esm2022 → esm2020}/lib/components/ng-scroll-bar/interfaces/index.mjs +1 -1
  32. package/{esm2022 → esm2020}/lib/components/ng-scroll-bar/interfaces/scroll-bar-template-context.mjs +1 -1
  33. package/{esm2022 → esm2020}/lib/components/ng-scroll-bar/interfaces/scrollbar-drag-data.mjs +1 -1
  34. package/esm2020/lib/components/ng-scroll-bar/ng-scroll-bar-public.service.mjs +27 -0
  35. package/esm2020/lib/components/ng-scroll-bar/ng-scroll-bar.component.mjs +324 -0
  36. package/{esm2022 → esm2020}/lib/components/ng-scroll-bar/ng-scroll-bar.module.mjs +19 -19
  37. package/{esm2022 → esm2020}/lib/components/ng-scroll-bar/ng-scroll-bar.service.mjs +38 -36
  38. package/{esm2022 → esm2020}/lib/components/ng-scroll-bar/types/index.mjs +1 -1
  39. package/{esm2022 → esm2020}/lib/components/ng-scroll-bar/types/scrollbar-state.mjs +1 -1
  40. package/esm2020/lib/components/ng-scroll-view/base/base-scroll-view.component.mjs +260 -0
  41. package/{esm2022 → esm2020}/lib/components/ng-scroll-view/const/index.mjs +9 -9
  42. package/{esm2022 → esm2020}/lib/components/ng-scroll-view/enums/index.mjs +2 -2
  43. package/{esm2022 → esm2020}/lib/components/ng-scroll-view/enums/scroller-direction.mjs +11 -11
  44. package/{esm2022 → esm2020}/lib/components/ng-scroll-view/enums/scroller-directions.mjs +1 -1
  45. package/{esm2022 → esm2020}/lib/components/ng-scroll-view/index.mjs +3 -3
  46. package/{esm2022 → esm2020}/lib/components/ng-scroll-view/interfaces/index.mjs +1 -1
  47. package/{esm2022 → esm2020}/lib/components/ng-scroll-view/interfaces/scroll-to-params.mjs +1 -1
  48. package/esm2020/lib/components/ng-scroll-view/ng-scroll-view.component.mjs +856 -0
  49. package/esm2020/lib/components/ng-scroll-view/utils/calculate-direction.mjs +17 -0
  50. package/{esm2022 → esm2020}/lib/components/ng-scroll-view/utils/calculate-velocity.mjs +11 -11
  51. package/{esm2022 → esm2020}/lib/components/ng-scroll-view/utils/get-dir.mjs +9 -9
  52. package/{esm2022 → esm2020}/lib/components/ng-scroll-view/utils/index.mjs +5 -5
  53. package/{esm2022 → esm2020}/lib/components/ng-scroll-view/utils/matrix-3d.mjs +9 -9
  54. package/esm2020/lib/components/ng-scroll-view/utils/scroll-box.mjs +45 -0
  55. package/{esm2022 → esm2020}/lib/components/ng-scroller/enums/index.mjs +2 -2
  56. package/{esm2022 → esm2020}/lib/components/ng-scroller/enums/scroller-direction.mjs +5 -5
  57. package/{esm2022 → esm2020}/lib/components/ng-scroller/enums/scroller-directions.mjs +1 -1
  58. package/esm2020/lib/components/ng-scroller/ng-scroller.component.mjs +521 -0
  59. package/{esm2022 → esm2020}/lib/components/ng-scroller/ng-scroller.module.mjs +22 -22
  60. package/{esm2022 → esm2020}/lib/components/ng-scroller/utils/index.mjs +2 -2
  61. package/esm2020/lib/components/ng-scroller/utils/interfaces/calculate-scroll-metrics.mjs +2 -0
  62. package/esm2020/lib/components/ng-scroller/utils/interfaces/calculate-scroll-params.mjs +2 -0
  63. package/esm2020/lib/components/ng-scroller/utils/interfaces/calculate-scroll-position-params.mjs +2 -0
  64. package/esm2020/lib/components/ng-scroller/utils/interfaces/index.mjs +2 -0
  65. package/esm2020/lib/components/ng-scroller/utils/scroll-box.mjs +52 -0
  66. package/{esm2022 → esm2020}/lib/const/index.mjs +164 -164
  67. package/esm2020/lib/core/cache-map.mjs +100 -0
  68. package/{esm2022 → esm2020}/lib/core/const/index.mjs +2 -2
  69. package/{esm2022 → esm2020}/lib/core/enums/index.mjs +2 -2
  70. package/{esm2022 → esm2020}/lib/core/enums/item-display-methods.mjs +13 -13
  71. package/{esm2022 → esm2020}/lib/core/events/index.mjs +2 -2
  72. package/{esm2022 → esm2020}/lib/core/events/track-box-events.mjs +11 -11
  73. package/{esm2022 → esm2020}/lib/core/interfaces/get-item-position-options.mjs +1 -1
  74. package/{esm2022 → esm2020}/lib/core/interfaces/get-metrics-returns.mjs +1 -1
  75. package/{esm2022 → esm2020}/lib/core/interfaces/index.mjs +1 -1
  76. package/{esm2022 → esm2020}/lib/core/interfaces/item.mjs +1 -1
  77. package/{esm2022 → esm2020}/lib/core/interfaces/metrics.mjs +1 -1
  78. package/esm2020/lib/core/interfaces/recalculate-metrics-options.mjs +2 -0
  79. package/{esm2022 → esm2020}/lib/core/interfaces/update-collection-options.mjs +1 -1
  80. package/{esm2022 → esm2020}/lib/core/interfaces/update-collection-returns.mjs +1 -1
  81. package/esm2020/lib/core/track-box.mjs +1352 -0
  82. package/esm2020/lib/core/tracker.mjs +209 -0
  83. package/{esm2022 → esm2020}/lib/core/types/cache-map-events.mjs +1 -1
  84. package/{esm2022 → esm2020}/lib/core/types/cache-map-listeners.mjs +1 -1
  85. package/{esm2022 → esm2020}/lib/core/types/cache.mjs +1 -1
  86. package/{esm2022 → esm2020}/lib/core/types/index.mjs +1 -1
  87. package/{esm2022 → esm2020}/lib/core/types/on-change-event-listener.mjs +1 -1
  88. package/{esm2022 → esm2020}/lib/core/types/on-tick-event-listener.mjs +1 -1
  89. package/{esm2022 → esm2020}/lib/core/utils/get-service-id-prop.mjs +9 -9
  90. package/{esm2022 → esm2020}/lib/core/utils/index.mjs +2 -2
  91. package/{esm2022 → esm2020}/lib/directives/index.mjs +3 -3
  92. package/esm2020/lib/directives/locale-sensitive/locale-sensitive.directive.mjs +67 -0
  93. package/{esm2022 → esm2020}/lib/directives/locale-sensitive/locale-sensitive.module.mjs +19 -19
  94. package/esm2020/lib/directives/virtual-click/virtual-click.directive.mjs +66 -0
  95. package/{esm2022 → esm2020}/lib/directives/virtual-click/virtual-click.module.mjs +19 -19
  96. package/{esm2022 → esm2020}/lib/enums/alignments.mjs +11 -11
  97. package/{esm2022 → esm2020}/lib/enums/collapsing-modes.mjs +21 -21
  98. package/{esm2022 → esm2020}/lib/enums/collection-modes.mjs +17 -17
  99. package/{esm2022 → esm2020}/lib/enums/directions.mjs +17 -17
  100. package/{esm2022 → esm2020}/lib/enums/focus-alignments.mjs +13 -13
  101. package/{esm2022 → esm2020}/lib/enums/index.mjs +11 -11
  102. package/{esm2022 → esm2020}/lib/enums/selecting-modes-types.mjs +21 -21
  103. package/{esm2022 → esm2020}/lib/enums/selecting-modes.mjs +21 -21
  104. package/{esm2022 → esm2020}/lib/enums/snap-to-item-aligns.mjs +21 -21
  105. package/{esm2022 → esm2020}/lib/enums/snapping-methods.mjs +17 -17
  106. package/{esm2022 → esm2020}/lib/enums/spreading-modes.mjs +17 -17
  107. package/{esm2022 → esm2020}/lib/enums/text-directions.mjs +13 -13
  108. package/{esm2022 → esm2020}/lib/interfaces/animation-params.mjs +1 -1
  109. package/{esm2022 → esm2020}/lib/interfaces/base-virtual-list-item-component.mjs +1 -1
  110. package/{esm2022 → esm2020}/lib/interfaces/index.mjs +1 -1
  111. package/{esm2022 → esm2020}/lib/interfaces/item-transformation.mjs +1 -1
  112. package/{esm2022 → esm2020}/lib/interfaces/point.mjs +1 -1
  113. package/{esm2022 → esm2020}/lib/interfaces/rect.mjs +1 -1
  114. package/{esm2022 → esm2020}/lib/interfaces/render-stabilizer-options.mjs +1 -1
  115. package/{esm2022 → esm2020}/lib/interfaces/scroll-event.mjs +1 -1
  116. package/{esm2022 → esm2020}/lib/interfaces/scroll-options.mjs +1 -1
  117. package/{esm2022 → esm2020}/lib/interfaces/scroll-params.mjs +1 -1
  118. package/{esm2022 → esm2020}/lib/interfaces/scroll-to-params.mjs +1 -1
  119. package/{esm2022 → esm2020}/lib/interfaces/scrolling-settings.mjs +1 -1
  120. package/{esm2022 → esm2020}/lib/interfaces/size.mjs +1 -1
  121. package/{esm2022 → esm2020}/lib/models/collection.model.mjs +2 -2
  122. package/{esm2022 → esm2020}/lib/models/component.model.mjs +1 -1
  123. package/{esm2022 → esm2020}/lib/models/display-object-config.model.mjs +1 -1
  124. package/{esm2022 → esm2020}/lib/models/display-object-measures.model.mjs +1 -1
  125. package/{esm2022 → esm2020}/lib/models/index.mjs +1 -1
  126. package/{esm2022 → esm2020}/lib/models/item-config-map.model.mjs +1 -1
  127. package/{esm2022 → esm2020}/lib/models/item.model.mjs +1 -1
  128. package/{esm2022 → esm2020}/lib/models/render-collection.model.mjs +2 -2
  129. package/{esm2022 → esm2020}/lib/models/render-item-config.model.mjs +1 -1
  130. package/{esm2022 → esm2020}/lib/models/render-item-measures.model.mjs +2 -2
  131. package/{esm2022 → esm2020}/lib/models/render-item.model.mjs +2 -2
  132. package/esm2020/lib/ng-virtual-list-public.service.mjs +122 -0
  133. package/esm2020/lib/ng-virtual-list.component.mjs +3255 -0
  134. package/{esm2022 → esm2020}/lib/ng-virtual-list.module.mjs +23 -23
  135. package/esm2020/lib/ng-virtual-list.service.mjs +430 -0
  136. package/esm2020/lib/transformations/deck-of-cards-3d.mjs +57 -0
  137. package/esm2020/lib/transformations/deck-of-cards.mjs +54 -0
  138. package/esm2020/lib/transformations/event-horizon.mjs +47 -0
  139. package/{esm2022 → esm2020}/lib/transformations/index.mjs +12 -12
  140. package/esm2020/lib/transformations/linear.mjs +47 -0
  141. package/esm2020/lib/transformations/swipe-3d.mjs +51 -0
  142. package/{esm2022 → esm2020}/lib/types/alignment.mjs +1 -1
  143. package/{esm2022 → esm2020}/lib/types/arithmetic-expression.mjs +1 -1
  144. package/{esm2022 → esm2020}/lib/types/collapsing-mode.mjs +1 -1
  145. package/{esm2022 → esm2020}/lib/types/collection-mode.mjs +1 -1
  146. package/{esm2022 → esm2020}/lib/types/color.mjs +1 -1
  147. package/{esm2022 → esm2020}/lib/types/direction.mjs +1 -1
  148. package/{esm2022 → esm2020}/lib/types/float-or-persentage-value.mjs +1 -1
  149. package/{esm2022 → esm2020}/lib/types/focus-alignment.mjs +1 -1
  150. package/{esm2022 → esm2020}/lib/types/focus-item-params.mjs +1 -1
  151. package/{esm2022 → esm2020}/lib/types/gradient-color-position.mjs +1 -1
  152. package/{esm2022 → esm2020}/lib/types/gradient-color-positions.mjs +1 -1
  153. package/{esm2022 → esm2020}/lib/types/id.mjs +1 -1
  154. package/{esm2022 → esm2020}/lib/types/index.mjs +1 -1
  155. package/{esm2022 → esm2020}/lib/types/item-transform.mjs +1 -1
  156. package/{esm2022 → esm2020}/lib/types/scroll-direction.mjs +1 -1
  157. package/{esm2022 → esm2020}/lib/types/selecting-mode.mjs +1 -1
  158. package/{esm2022 → esm2020}/lib/types/snap-to-item-align.mjs +1 -1
  159. package/{esm2022 → esm2020}/lib/types/snapping-distance.mjs +1 -1
  160. package/{esm2022 → esm2020}/lib/types/snapping-method.mjs +1 -1
  161. package/{esm2022 → esm2020}/lib/types/spreading-mode.mjs +1 -1
  162. package/{esm2022 → esm2020}/lib/types/text-direction.mjs +1 -1
  163. package/esm2020/lib/utils/animator/animator.mjs +80 -0
  164. package/{esm2022 → esm2020}/lib/utils/animator/const/index.mjs +1 -1
  165. package/{esm2022 → esm2020}/lib/utils/animator/ease.mjs +6 -6
  166. package/{esm2022 → esm2020}/lib/utils/animator/index.mjs +4 -4
  167. package/esm2020/lib/utils/animator/interfaces/animator-params.mjs +2 -0
  168. package/esm2020/lib/utils/animator/interfaces/animator-update-data.mjs +2 -0
  169. package/{esm2022 → esm2020}/lib/utils/animator/interfaces/index.mjs +1 -1
  170. package/esm2020/lib/utils/animator/types/easing.mjs +2 -0
  171. package/{esm2022 → esm2020}/lib/utils/animator/types/index.mjs +1 -1
  172. package/esm2020/lib/utils/buffer-interpolation.mjs +29 -0
  173. package/esm2020/lib/utils/cmap.mjs +34 -0
  174. package/esm2020/lib/utils/debounce.mjs +61 -0
  175. package/esm2020/lib/utils/disposable-component.mjs +29 -0
  176. package/esm2020/lib/utils/event-emitter/event-emitter.mjs +106 -0
  177. package/{esm2022 → esm2020}/lib/utils/event-emitter/index.mjs +2 -2
  178. package/esm2020/lib/utils/event-emitter/interfaces/event-emitter.mjs +2 -0
  179. package/{esm2022 → esm2020}/lib/utils/event-emitter/interfaces/index.mjs +1 -1
  180. package/esm2020/lib/utils/get-scroll-state-version.mjs +12 -0
  181. package/{esm2022 → esm2020}/lib/utils/get-selector-by-item-id.mjs +4 -4
  182. package/{esm2022 → esm2020}/lib/utils/index.mjs +4 -4
  183. package/esm2020/lib/utils/is-collapse-mode.mjs +18 -0
  184. package/{esm2022 → esm2020}/lib/utils/is-collection-mode.mjs +15 -15
  185. package/esm2020/lib/utils/is-direction.mjs +15 -0
  186. package/esm2020/lib/utils/is-persentage-value.mjs +14 -0
  187. package/esm2020/lib/utils/is-select-mode.mjs +18 -0
  188. package/{esm2022 → esm2020}/lib/utils/is-spreading-mode.mjs +15 -15
  189. package/esm2020/lib/utils/list-validators.mjs +27 -0
  190. package/esm2020/lib/utils/normalize-collection.mjs +42 -0
  191. package/esm2020/lib/utils/object.mjs +28 -0
  192. package/esm2020/lib/utils/parse-arithmetic-expression.mjs +53 -0
  193. package/esm2020/lib/utils/parse-float-or-persentage-value.mjs +17 -0
  194. package/esm2020/lib/utils/screen-reader-formatter.mjs +43 -0
  195. package/esm2020/lib/utils/scroll-event.mjs +46 -0
  196. package/esm2020/lib/utils/scrolling-direction.mjs +28 -0
  197. package/{esm2022 → esm2020}/lib/utils/snapping-method.mjs +8 -8
  198. package/esm2020/lib/utils/toggle-class-name.mjs +15 -0
  199. package/{esm2022 → esm2020}/lib/utils/validation.mjs +55 -55
  200. package/{esm2022 → esm2020}/ng-virtual-list.mjs +4 -4
  201. package/{esm2022 → esm2020}/public-api.mjs +19 -19
  202. package/fesm2015/ng-virtual-list.mjs +10731 -0
  203. package/fesm2015/ng-virtual-list.mjs.map +1 -0
  204. package/{fesm2022 → fesm2020}/ng-virtual-list.mjs +10451 -10455
  205. package/fesm2020/ng-virtual-list.mjs.map +1 -0
  206. package/index.d.ts +5 -5
  207. package/lib/components/ng-list-item/base/base-virtual-list-item-component.d.ts +83 -83
  208. package/lib/components/ng-list-item/base/index.d.ts +2 -2
  209. package/lib/components/ng-list-item/const/index.d.ts +3 -3
  210. package/lib/components/ng-list-item/interfaces/index.d.ts +2 -2
  211. package/lib/components/ng-list-item/interfaces/template-context.d.ts +42 -42
  212. package/lib/components/ng-list-item/ng-virtual-list-item.component.d.ts +30 -30
  213. package/lib/components/ng-list-item/ng-virtual-list-item.module.d.ts +9 -9
  214. package/lib/components/ng-list-item/utils/create-display-id.d.ts +7 -7
  215. package/lib/components/ng-list-item/utils/get-element-by-index.d.ts +15 -15
  216. package/lib/components/ng-list-item/utils/index.d.ts +4 -4
  217. package/lib/components/ng-list-item/utils/matrix-3d.d.ts +7 -7
  218. package/lib/components/ng-prerender-container/components/ng-prerender-list/ng-prerender-list.component.d.ts +104 -104
  219. package/lib/components/ng-prerender-container/components/ng-prerender-list/ng-prerender-list.module.d.ts +10 -10
  220. package/lib/components/ng-prerender-container/components/ng-prerender-list-item/ng-prerender-list-item.component.d.ts +17 -17
  221. package/lib/components/ng-prerender-container/components/ng-prerender-list-item/ng-prerender-list-item.module.d.ts +9 -9
  222. package/lib/components/ng-prerender-container/components/ng-prerender-scroller/ng-prerender-scroller.component.d.ts +62 -62
  223. package/lib/components/ng-prerender-container/components/ng-prerender-scroller/ng-prerender-scroller.module.d.ts +9 -9
  224. package/lib/components/ng-prerender-container/core/index.d.ts +2 -2
  225. package/lib/components/ng-prerender-container/core/prerender-track-box.d.ts +35 -35
  226. package/lib/components/ng-prerender-container/events/index.d.ts +6 -6
  227. package/lib/components/ng-prerender-container/interfaces/index.d.ts +2 -2
  228. package/lib/components/ng-prerender-container/interfaces/refresh-params.d.ts +17 -17
  229. package/lib/components/ng-prerender-container/ng-prerender-container.component.d.ts +40 -40
  230. package/lib/components/ng-prerender-container/ng-prerender-container.module.d.ts +9 -9
  231. package/lib/components/ng-prerender-container/types/cache.d.ts +13 -13
  232. package/lib/components/ng-prerender-container/types/index.d.ts +2 -2
  233. package/lib/components/ng-scroll-bar/const/index.d.ts +3 -3
  234. package/lib/components/ng-scroll-bar/enums/index.d.ts +2 -2
  235. package/lib/components/ng-scroll-bar/enums/scrollbar-states.d.ts +5 -5
  236. package/lib/components/ng-scroll-bar/interfaces/index.d.ts +3 -3
  237. package/lib/components/ng-scroll-bar/interfaces/scroll-bar-template-context.d.ts +26 -26
  238. package/lib/components/ng-scroll-bar/interfaces/scrollbar-drag-data.d.ts +13 -13
  239. package/lib/components/ng-scroll-bar/ng-scroll-bar-public.service.d.ts +16 -16
  240. package/lib/components/ng-scroll-bar/ng-scroll-bar.component.d.ts +102 -102
  241. package/lib/components/ng-scroll-bar/ng-scroll-bar.module.d.ts +8 -8
  242. package/lib/components/ng-scroll-bar/ng-scroll-bar.service.d.ts +22 -22
  243. package/lib/components/ng-scroll-bar/types/index.d.ts +2 -2
  244. package/lib/components/ng-scroll-bar/types/scrollbar-state.d.ts +2 -2
  245. package/lib/components/ng-scroll-view/base/base-scroll-view.component.d.ts +89 -89
  246. package/lib/components/ng-scroll-view/const/index.d.ts +7 -7
  247. package/lib/components/ng-scroll-view/enums/index.d.ts +4 -4
  248. package/lib/components/ng-scroll-view/enums/scroller-direction.d.ts +10 -10
  249. package/lib/components/ng-scroll-view/enums/scroller-directions.d.ts +8 -8
  250. package/lib/components/ng-scroll-view/index.d.ts +5 -5
  251. package/lib/components/ng-scroll-view/interfaces/index.d.ts +2 -2
  252. package/lib/components/ng-scroll-view/interfaces/scroll-to-params.d.ts +22 -22
  253. package/lib/components/ng-scroll-view/ng-scroll-view.component.d.ts +124 -124
  254. package/lib/components/ng-scroll-view/utils/calculate-direction.d.ts +10 -7
  255. package/lib/components/ng-scroll-view/utils/calculate-velocity.d.ts +7 -7
  256. package/lib/components/ng-scroll-view/utils/get-dir.d.ts +7 -7
  257. package/lib/components/ng-scroll-view/utils/index.d.ts +5 -5
  258. package/lib/components/ng-scroll-view/utils/matrix-3d.d.ts +7 -7
  259. package/lib/components/ng-scroll-view/utils/scroll-box.d.ts +39 -39
  260. package/lib/components/ng-scroller/enums/index.d.ts +4 -4
  261. package/lib/components/ng-scroller/enums/scroller-direction.d.ts +4 -4
  262. package/lib/components/ng-scroller/enums/scroller-directions.d.ts +3 -3
  263. package/lib/components/ng-scroller/ng-scroller.component.d.ts +164 -164
  264. package/lib/components/ng-scroller/ng-scroller.module.d.ts +11 -11
  265. package/lib/components/ng-scroller/utils/index.d.ts +2 -2
  266. package/lib/components/ng-scroller/utils/interfaces/calculate-scroll-metrics.d.ts +11 -0
  267. package/lib/components/ng-scroller/utils/interfaces/calculate-scroll-params.d.ts +19 -0
  268. package/lib/components/ng-scroller/utils/interfaces/calculate-scroll-position-params.d.ts +10 -0
  269. package/lib/components/ng-scroller/utils/interfaces/index.d.ts +4 -0
  270. package/lib/components/ng-scroller/utils/scroll-box.d.ts +23 -40
  271. package/lib/const/index.d.ts +153 -153
  272. package/lib/core/cache-map.d.ts +46 -46
  273. package/lib/core/const/index.d.ts +1 -1
  274. package/lib/core/enums/index.d.ts +2 -2
  275. package/lib/core/enums/item-display-methods.d.ts +12 -12
  276. package/lib/core/events/index.d.ts +2 -2
  277. package/lib/core/events/track-box-events.d.ts +10 -10
  278. package/lib/core/interfaces/get-item-position-options.d.ts +10 -10
  279. package/lib/core/interfaces/get-metrics-returns.d.ts +11 -11
  280. package/lib/core/interfaces/index.d.ts +8 -8
  281. package/lib/core/interfaces/item.d.ts +9 -9
  282. package/lib/core/interfaces/metrics.d.ts +51 -51
  283. package/lib/core/interfaces/recalculate-metrics-options.d.ts +33 -32
  284. package/lib/core/interfaces/update-collection-options.d.ts +10 -10
  285. package/lib/core/interfaces/update-collection-returns.d.ts +14 -14
  286. package/lib/core/track-box.d.ts +153 -153
  287. package/lib/core/tracker.d.ts +55 -55
  288. package/lib/core/types/cache-map-events.d.ts +8 -8
  289. package/lib/core/types/cache-map-listeners.d.ts +9 -9
  290. package/lib/core/types/cache.d.ts +12 -12
  291. package/lib/core/types/index.d.ts +6 -6
  292. package/lib/core/types/on-change-event-listener.d.ts +7 -7
  293. package/lib/core/types/on-tick-event-listener.d.ts +7 -7
  294. package/lib/core/utils/get-service-id-prop.d.ts +7 -7
  295. package/lib/core/utils/index.d.ts +2 -2
  296. package/lib/directives/index.d.ts +3 -3
  297. package/lib/directives/locale-sensitive/locale-sensitive.directive.d.ts +29 -29
  298. package/lib/directives/locale-sensitive/locale-sensitive.module.d.ts +8 -8
  299. package/lib/directives/virtual-click/virtual-click.directive.d.ts +22 -22
  300. package/lib/directives/virtual-click/virtual-click.module.d.ts +8 -8
  301. package/lib/enums/alignments.d.ts +10 -10
  302. package/lib/enums/collapsing-modes.d.ts +20 -20
  303. package/lib/enums/collection-modes.d.ts +16 -16
  304. package/lib/enums/directions.d.ts +16 -16
  305. package/lib/enums/focus-alignments.d.ts +12 -12
  306. package/lib/enums/index.d.ts +11 -11
  307. package/lib/enums/selecting-modes-types.d.ts +20 -20
  308. package/lib/enums/selecting-modes.d.ts +20 -20
  309. package/lib/enums/snap-to-item-aligns.d.ts +20 -20
  310. package/lib/enums/snapping-methods.d.ts +16 -16
  311. package/lib/enums/spreading-modes.d.ts +16 -16
  312. package/lib/enums/text-directions.d.ts +12 -12
  313. package/lib/interfaces/animation-params.d.ts +14 -14
  314. package/lib/interfaces/base-virtual-list-item-component.d.ts +23 -23
  315. package/lib/interfaces/index.d.ts +11 -11
  316. package/lib/interfaces/item-transformation.d.ts +22 -22
  317. package/lib/interfaces/point.d.ts +16 -16
  318. package/lib/interfaces/rect.d.ts +17 -17
  319. package/lib/interfaces/render-stabilizer-options.d.ts +12 -12
  320. package/lib/interfaces/scroll-event.d.ts +58 -58
  321. package/lib/interfaces/scroll-options.d.ts +28 -28
  322. package/lib/interfaces/scroll-params.d.ts +17 -17
  323. package/lib/interfaces/scroll-to-params.d.ts +7 -7
  324. package/lib/interfaces/scrolling-settings.d.ts +38 -38
  325. package/lib/interfaces/size.d.ts +16 -16
  326. package/lib/models/collection.model.d.ts +9 -9
  327. package/lib/models/component.model.d.ts +3 -3
  328. package/lib/models/display-object-config.model.d.ts +21 -21
  329. package/lib/models/display-object-measures.model.d.ts +45 -45
  330. package/lib/models/index.d.ts +9 -9
  331. package/lib/models/item-config-map.model.d.ts +35 -35
  332. package/lib/models/item.model.d.ts +17 -17
  333. package/lib/models/render-collection.model.d.ts +9 -9
  334. package/lib/models/render-item-config.model.d.ts +119 -119
  335. package/lib/models/render-item-measures.model.d.ts +116 -116
  336. package/lib/models/render-item.model.d.ts +40 -40
  337. package/lib/ng-virtual-list-public.service.d.ts +92 -92
  338. package/lib/ng-virtual-list.component.d.ts +771 -770
  339. package/lib/ng-virtual-list.module.d.ts +12 -12
  340. package/lib/ng-virtual-list.service.d.ts +153 -153
  341. package/lib/transformations/deck-of-cards-3d.d.ts +54 -54
  342. package/lib/transformations/deck-of-cards.d.ts +50 -50
  343. package/lib/transformations/event-horizon.d.ts +26 -26
  344. package/lib/transformations/index.d.ts +7 -7
  345. package/lib/transformations/linear.d.ts +26 -26
  346. package/lib/transformations/swipe-3d.d.ts +38 -38
  347. package/lib/types/alignment.d.ts +8 -8
  348. package/lib/types/arithmetic-expression.d.ts +10 -10
  349. package/lib/types/collapsing-mode.d.ts +8 -8
  350. package/lib/types/collection-mode.d.ts +8 -8
  351. package/lib/types/color.d.ts +4 -4
  352. package/lib/types/direction.d.ts +8 -8
  353. package/lib/types/float-or-persentage-value.d.ts +7 -7
  354. package/lib/types/focus-alignment.d.ts +8 -8
  355. package/lib/types/focus-item-params.d.ts +13 -13
  356. package/lib/types/gradient-color-position.d.ts +7 -7
  357. package/lib/types/gradient-color-positions.d.ts +8 -8
  358. package/lib/types/id.d.ts +7 -7
  359. package/lib/types/index.d.ts +20 -20
  360. package/lib/types/item-transform.d.ts +9 -9
  361. package/lib/types/scroll-direction.d.ts +8 -8
  362. package/lib/types/selecting-mode.d.ts +8 -8
  363. package/lib/types/snap-to-item-align.d.ts +8 -8
  364. package/lib/types/snapping-distance.d.ts +8 -8
  365. package/lib/types/snapping-method.d.ts +10 -10
  366. package/lib/types/spreading-mode.d.ts +8 -8
  367. package/lib/types/text-direction.d.ts +10 -10
  368. package/lib/utils/animator/animator.d.ts +16 -16
  369. package/lib/utils/animator/const/index.d.ts +1 -1
  370. package/lib/utils/animator/ease.d.ts +2 -2
  371. package/lib/utils/animator/index.d.ts +6 -6
  372. package/lib/utils/animator/interfaces/animator-params.d.ts +18 -18
  373. package/lib/utils/animator/interfaces/animator-update-data.d.ts +13 -13
  374. package/lib/utils/animator/interfaces/index.d.ts +3 -3
  375. package/lib/utils/animator/types/easing.d.ts +7 -7
  376. package/lib/utils/animator/types/index.d.ts +2 -2
  377. package/lib/utils/buffer-interpolation.d.ts +5 -5
  378. package/lib/utils/cmap.d.ts +16 -16
  379. package/lib/utils/debounce.d.ts +25 -25
  380. package/lib/utils/disposable-component.d.ts +15 -15
  381. package/lib/utils/event-emitter/event-emitter.d.ts +42 -42
  382. package/lib/utils/event-emitter/index.d.ts +4 -4
  383. package/lib/utils/event-emitter/interfaces/event-emitter.d.ts +37 -37
  384. package/lib/utils/event-emitter/interfaces/index.d.ts +2 -2
  385. package/lib/utils/get-scroll-state-version.d.ts +1 -1
  386. package/lib/utils/get-selector-by-item-id.d.ts +2 -2
  387. package/lib/utils/index.d.ts +6 -6
  388. package/lib/utils/is-collapse-mode.d.ts +8 -8
  389. package/lib/utils/is-collection-mode.d.ts +8 -8
  390. package/lib/utils/is-direction.d.ts +8 -8
  391. package/lib/utils/is-persentage-value.d.ts +7 -7
  392. package/lib/utils/is-select-mode.d.ts +8 -8
  393. package/lib/utils/is-spreading-mode.d.ts +8 -8
  394. package/lib/utils/list-validators.d.ts +2 -2
  395. package/lib/utils/normalize-collection.d.ts +8 -8
  396. package/lib/utils/object.d.ts +4 -4
  397. package/lib/utils/parse-arithmetic-expression.d.ts +8 -8
  398. package/lib/utils/parse-float-or-persentage-value.d.ts +7 -7
  399. package/lib/utils/screen-reader-formatter.d.ts +7 -4
  400. package/lib/utils/scroll-event.d.ts +48 -48
  401. package/lib/utils/scrolling-direction.d.ts +17 -17
  402. package/lib/utils/snapping-method.d.ts +3 -3
  403. package/lib/utils/toggle-class-name.d.ts +7 -7
  404. package/lib/utils/validation.d.ts +35 -35
  405. package/package.json +11 -5
  406. package/public-api.d.ts +16 -16
  407. package/esm2022/lib/components/ng-list-item/base/base-virtual-list-item-component.mjs +0 -315
  408. package/esm2022/lib/components/ng-list-item/ng-virtual-list-item.component.mjs +0 -200
  409. package/esm2022/lib/components/ng-prerender-container/components/ng-prerender-list/ng-prerender-list.component.mjs +0 -279
  410. package/esm2022/lib/components/ng-prerender-container/components/ng-prerender-list-item/ng-prerender-list-item.component.mjs +0 -94
  411. package/esm2022/lib/components/ng-prerender-container/components/ng-prerender-scroller/ng-prerender-scroller.component.mjs +0 -142
  412. package/esm2022/lib/components/ng-prerender-container/core/prerender-track-box.mjs +0 -198
  413. package/esm2022/lib/components/ng-prerender-container/ng-prerender-container.component.mjs +0 -93
  414. package/esm2022/lib/components/ng-scroll-bar/ng-scroll-bar-public.service.mjs +0 -25
  415. package/esm2022/lib/components/ng-scroll-bar/ng-scroll-bar.component.mjs +0 -324
  416. package/esm2022/lib/components/ng-scroll-view/base/base-scroll-view.component.mjs +0 -262
  417. package/esm2022/lib/components/ng-scroll-view/ng-scroll-view.component.mjs +0 -859
  418. package/esm2022/lib/components/ng-scroll-view/utils/calculate-direction.mjs +0 -17
  419. package/esm2022/lib/components/ng-scroll-view/utils/scroll-box.mjs +0 -45
  420. package/esm2022/lib/components/ng-scroller/ng-scroller.component.mjs +0 -525
  421. package/esm2022/lib/components/ng-scroller/utils/scroll-box.mjs +0 -52
  422. package/esm2022/lib/core/cache-map.mjs +0 -101
  423. package/esm2022/lib/core/interfaces/recalculate-metrics-options.mjs +0 -2
  424. package/esm2022/lib/core/track-box.mjs +0 -1353
  425. package/esm2022/lib/core/tracker.mjs +0 -207
  426. package/esm2022/lib/directives/locale-sensitive/locale-sensitive.directive.mjs +0 -68
  427. package/esm2022/lib/directives/virtual-click/virtual-click.directive.mjs +0 -67
  428. package/esm2022/lib/ng-virtual-list-public.service.mjs +0 -120
  429. package/esm2022/lib/ng-virtual-list.component.mjs +0 -3246
  430. package/esm2022/lib/ng-virtual-list.service.mjs +0 -431
  431. package/esm2022/lib/transformations/deck-of-cards-3d.mjs +0 -57
  432. package/esm2022/lib/transformations/deck-of-cards.mjs +0 -54
  433. package/esm2022/lib/transformations/event-horizon.mjs +0 -47
  434. package/esm2022/lib/transformations/linear.mjs +0 -47
  435. package/esm2022/lib/transformations/swipe-3d.mjs +0 -51
  436. package/esm2022/lib/utils/animator/animator.mjs +0 -78
  437. package/esm2022/lib/utils/animator/interfaces/animator-params.mjs +0 -2
  438. package/esm2022/lib/utils/animator/interfaces/animator-update-data.mjs +0 -2
  439. package/esm2022/lib/utils/animator/types/easing.mjs +0 -2
  440. package/esm2022/lib/utils/buffer-interpolation.mjs +0 -29
  441. package/esm2022/lib/utils/cmap.mjs +0 -34
  442. package/esm2022/lib/utils/debounce.mjs +0 -61
  443. package/esm2022/lib/utils/disposable-component.mjs +0 -27
  444. package/esm2022/lib/utils/event-emitter/event-emitter.mjs +0 -105
  445. package/esm2022/lib/utils/event-emitter/interfaces/event-emitter.mjs +0 -2
  446. package/esm2022/lib/utils/get-scroll-state-version.mjs +0 -12
  447. package/esm2022/lib/utils/is-collapse-mode.mjs +0 -18
  448. package/esm2022/lib/utils/is-direction.mjs +0 -15
  449. package/esm2022/lib/utils/is-persentage-value.mjs +0 -14
  450. package/esm2022/lib/utils/is-select-mode.mjs +0 -18
  451. package/esm2022/lib/utils/list-validators.mjs +0 -27
  452. package/esm2022/lib/utils/normalize-collection.mjs +0 -42
  453. package/esm2022/lib/utils/object.mjs +0 -28
  454. package/esm2022/lib/utils/parse-arithmetic-expression.mjs +0 -53
  455. package/esm2022/lib/utils/parse-float-or-persentage-value.mjs +0 -17
  456. package/esm2022/lib/utils/screen-reader-formatter.mjs +0 -43
  457. package/esm2022/lib/utils/scroll-event.mjs +0 -48
  458. package/esm2022/lib/utils/scrolling-direction.mjs +0 -29
  459. package/esm2022/lib/utils/toggle-class-name.mjs +0 -15
  460. package/fesm2022/ng-virtual-list.mjs.map +0 -1
@@ -1,3246 +0,0 @@
1
- import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, inject, Input, Output, ViewChild, ViewContainerRef, ViewEncapsulation, } from '@angular/core';
2
- import { BehaviorSubject, combineLatest, debounceTime, delay, distinctUntilChanged, filter, fromEvent, map, of, skip, Subject, switchMap, take, takeUntil, tap, } from 'rxjs';
3
- import { NgVirtualListItemComponent } from './components/ng-list-item/ng-virtual-list-item.component';
4
- import { BEHAVIOR_INSTANT, CLASS_LIST_HORIZONTAL, CLASS_LIST_VERTICAL, DEFAULT_DIRECTION, DEFAULT_DYNAMIC_SIZE, DEFAULT_ENABLED_BUFFER_OPTIMIZATION, DEFAULT_ITEM_SIZE, DEFAULT_BUFFER_SIZE, DEFAULT_LIST_SIZE, DEFAULT_STICKY_ENABLED, DEFAULT_SNAPPING_METHOD, HEIGHT_PROP_NAME, LEFT_PROP_NAME, MAX_SCROLL_TO_ITERATIONS, PX, FOCUS, TOP_PROP_NAME, TRACK_BY_PROPERTY_NAME, WIDTH_PROP_NAME, DEFAULT_MAX_BUFFER_SIZE, DEFAULT_SELECTING_MODES, DEFAULT_SELECT_BY_CLICK, DEFAULT_COLLAPSE_BY_CLICK, DEFAULT_COLLECTION_MODE, DEFAULT_SCREEN_READER_MESSAGE, DEFAULT_SNAP_TO_END_TRANSITION_INSTANT_OFFSET, DEFAULT_SNAP_SCROLLTO_END, MIN_PIXELS_FOR_PREVENT_SNAPPING, MOUSE_DOWN, TOUCH_START, DEFAULT_LANG_TEXT_DIR, DEFAULT_CLICK_DISTANCE, DEFAULT_WAIT_FOR_PREPARATION, DEFAULT_SCROLLBAR_THICKNESS, DEFAULT_SCROLLBAR_MIN_SIZE, KEY_DOWN, BEHAVIOR_AUTO, DEFAULT_SCROLLBAR_ENABLED, DEFAULT_SCROLLBAR_INTERACTIVE, DEFAULT_OVERSCROLL_ENABLED, DEFAULT_ANIMATION_PARAMS, DEFAULT_SCROLL_BEHAVIOR, DEFAULT_SNAP_SCROLLTO_START, EMPTY_SCROLL_STATE_VERSION, MAX_REGULAR_SNAPED_COMPONENTS, PREPARE_ITERATIONS, PREPARATION_REUPDATE_LENGTH, ROLE_LIST_BOX, ROLE_LIST, KEY_TAB, MAX_VELOCITY_FOR_SCROLL_QUALITY_OPTIMIZATION_LVL1, PREPARE_ITERATIONS_FOR_UPDATE_ITEMS, PREPARATION_REUPDATE_LENGTH_FOR_UPDATE_ITEMS, PREPARE_ITERATIONS_FOR_COLLAPSE_ITEMS, PREPARATION_REUPDATE_LENGTH_FOR_COLLAPSE_ITEMS, MAX_NUMBERS_OF_SKIPS_FOR_QUALITY_OPTIMIZATION_LVL1, DEFAULT_SCROLLING_SETTINGS, DEFAULT_SNAP_TO_ITEM, DEFAULT_SNAP_TO_ITEM_ALIGN, VIEWPORT, DEFAULT_MOTION_BLUR, DEFAULT_MAX_MOTION_BLUR, DEFAULT_SCROLLING_ONE_BY_ONE, DEFAULT_MOTION_BLUR_ENABLED, DEFAULT_DIVIDES, DEFAULT_SNAPPING_DISTANCE, DEFAULT_MAX_ITEM_SIZE, DEFAULT_MIN_ITEM_SIZE, DEFAULT_ALIGNMENT, DEFAULT_COLLAPSING_MODES, DEFAULT_SPREADING_MODE, DEFAULT_ZINDEX_WHEN_SELECTING, DEFAULT_OVERLAPPING_SCROLLBAR, } from './const';
5
- import { Alignments, CollectionModes, Directions, FocusAlignments, SelectingModes, SnappingMethods, SnapToItemAligns, SpreadingModes, TextDirections, } from './enums';
6
- import { debounce, ScrollEvent, toggleClassName } from './utils';
7
- import { TrackBox } from './core/track-box';
8
- import { isSnappingMethodAdvenced } from './utils/snapping-method';
9
- import { isDirection } from './utils/is-direction';
10
- import { NgVirtualListService } from './ng-virtual-list.service';
11
- import { isSelectMode } from './utils/is-select-mode';
12
- import { isCollapseMode } from './utils/is-collapse-mode';
13
- import { SelectingModesTypes } from './enums/selecting-modes-types';
14
- import { CMap } from './utils/cmap';
15
- import { validateArray, validateBoolean, validateFloat, validateFunction, validateInt, validateObject, validateString, } from './utils/validation';
16
- import { copyValueAsReadonly, objectAsReadonly } from './utils/object';
17
- import { isCollectionMode } from './utils/is-collection-mode';
18
- import { NgScrollerComponent } from './components/ng-scroller/ng-scroller.component';
19
- import { NgPrerenderContainer } from './components/ng-prerender-container/ng-prerender-container.component';
20
- import { formatActualDisplayItems, formatScreenReaderMessage } from './utils/screen-reader-formatter';
21
- import { validateId, validateIteration, validateScrollBehavior, validateScrollIteration } from './utils/list-validators';
22
- import { EVENT_KEY_DOWN, KEY_ARR_DOWN, KEY_ARR_LEFT, KEY_ARR_RIGHT, KEY_ARR_UP } from './components/ng-list-item/const';
23
- import { NgVirtualListPublicService } from './ng-virtual-list-public.service';
24
- import { isPercentageValue } from './utils/is-persentage-value';
25
- import { parseArithmeticExpression } from './utils/parse-arithmetic-expression';
26
- import { normalizeCollection } from './utils/normalize-collection';
27
- import { CollapsingModes } from './enums';
28
- import { isSpreadingMode } from './utils/is-spreading-mode';
29
- import { getScrollStateVersion } from './utils/get-scroll-state-version';
30
- import { DisposableComponent } from './utils/disposable-component';
31
- import * as i0 from "@angular/core";
32
- import * as i1 from "@angular/common";
33
- import * as i2 from "./components/ng-scroller/ng-scroller.component";
34
- import * as i3 from "./components/ng-prerender-container/ng-prerender-container.component";
35
- import * as i4 from "./directives/locale-sensitive/locale-sensitive.directive";
36
- /**
37
- * Virtual list component.
38
- * Maximum performance for extremely large lists.
39
- * It is based on algorithms for virtualization of screen objects.
40
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/ng-virtual-list.component.ts
41
- * @author Evgenii Alexandrovich Grebennikov
42
- * @email djonnyx@gmail.com
43
- */
44
- export class NgVirtualListComponent extends DisposableComponent {
45
- static __nextId = 0;
46
- _id = NgVirtualListComponent.__nextId;
47
- /**
48
- * Readonly. Returns the unique identifier of the component.
49
- */
50
- get id() { return this._id; }
51
- _service = inject(NgVirtualListService);
52
- _prerender;
53
- _listContainerRef;
54
- _snapContainerRef;
55
- _scrollerComponent;
56
- _$scroller = new BehaviorSubject(undefined);
57
- $scroller = this._$scroller.asObservable();
58
- _$list = new BehaviorSubject(undefined);
59
- $list = this._$list.asObservable();
60
- /**
61
- * Fires when the list has been scrolled.
62
- */
63
- onScroll = new EventEmitter();
64
- /**
65
- * Fires when the list has completed scrolling.
66
- */
67
- onScrollEnd = new EventEmitter();
68
- /**
69
- * Fires when the viewport size is changed.
70
- */
71
- onViewportChange = new EventEmitter();
72
- /**
73
- * Emit the component ID when an element crosses the alignment line specified by the snapToItemAlign property.
74
- */
75
- onSnapItem = new EventEmitter();
76
- /**
77
- * Fires when an element is clicked.
78
- */
79
- onItemClick = new EventEmitter();
80
- /**
81
- * Fires when elements are selected.
82
- */
83
- onSelect = new EventEmitter();
84
- /**
85
- * Fires when elements are collapsed.
86
- */
87
- onCollapse = new EventEmitter();
88
- /**
89
- * Fires when the scroll reaches the start.
90
- */
91
- onScrollReachStart = new EventEmitter();
92
- /**
93
- * Fires when the scroll reaches the end.
94
- */
95
- onScrollReachEnd = new EventEmitter();
96
- _$show = new BehaviorSubject(false);
97
- $show = this._$show.asObservable();
98
- _$initialized = new BehaviorSubject(false);
99
- $initialized = this._$initialized.asObservable();
100
- _$scrollbarThickness = new BehaviorSubject(DEFAULT_SCROLLBAR_THICKNESS);
101
- $scrollbarThickness = this._$scrollbarThickness.asObservable();
102
- _scrollbarThicknessTransform = (v) => {
103
- const valid = validateInt(v, true);
104
- if (!valid) {
105
- console.error('The "scrollbarThickness" parameter must be of type `number`.');
106
- return DEFAULT_SCROLLBAR_THICKNESS;
107
- }
108
- return v;
109
- };
110
- /**
111
- * Scrollbar thickness.
112
- */
113
- set scrollbarThickness(v) {
114
- if (this._$scrollbarThickness.getValue() === v) {
115
- return;
116
- }
117
- const transformedValue = this._scrollbarThicknessTransform(v);
118
- this._$scrollbarThickness.next(transformedValue);
119
- }
120
- ;
121
- get scrollbarThickness() { return this._$scrollbarThickness.getValue(); }
122
- _$scrollbarMinSize = new BehaviorSubject(DEFAULT_SCROLLBAR_MIN_SIZE);
123
- $scrollbarMinSize = this._$scrollbarMinSize.asObservable();
124
- _scrollbarMinSizeTransform = (v) => {
125
- const valid = validateInt(v);
126
- if (!valid) {
127
- console.error('The "scrollbarMinSize" parameter must be of type `number`.');
128
- return DEFAULT_SCROLLBAR_MIN_SIZE;
129
- }
130
- return v;
131
- };
132
- /**
133
- * Minimum scrollbar size.
134
- */
135
- set scrollbarMinSize(v) {
136
- if (this._$scrollbarMinSize.getValue() === v) {
137
- return;
138
- }
139
- const transformedValue = this._scrollbarMinSizeTransform(v);
140
- this._$scrollbarMinSize.next(transformedValue);
141
- }
142
- ;
143
- get scrollbarMinSize() { return this._$scrollbarMinSize.getValue(); }
144
- _$scrollbarThumbRenderer = new BehaviorSubject(null);
145
- $scrollbarThumbRenderer = this._$scrollbarThumbRenderer.asObservable();
146
- _scrollbarThumbRendererTransform = (v) => {
147
- const valid = validateObject(v, true, true);
148
- if (!valid) {
149
- console.error('The "scrollbarThumbRenderer" parameter must be of type `object`.');
150
- return null;
151
- }
152
- return v;
153
- };
154
- /**
155
- * Scrollbar customization template.
156
- */
157
- set scrollbarThumbRenderer(v) {
158
- if (this._$scrollbarThumbRenderer.getValue() === v) {
159
- return;
160
- }
161
- const transformedValue = this._scrollbarThumbRendererTransform(v);
162
- this._$scrollbarThumbRenderer.next(transformedValue);
163
- }
164
- ;
165
- get scrollbarThumbRenderer() { return this._$scrollbarThumbRenderer.getValue(); }
166
- _$scrollbarThumbParams = new BehaviorSubject({});
167
- $scrollbarThumbParams = this._$scrollbarThumbParams.asObservable();
168
- _scrollbarThumbParamsTransform = (v) => {
169
- const valid = validateObject(v, true, true);
170
- if (!valid) {
171
- console.error('The "scrollbarThumbParams" parameter must be of type `object`.');
172
- return null;
173
- }
174
- return v;
175
- };
176
- /**
177
- * Additional options for the scrollbar.
178
- */
179
- set scrollbarThumbParams(v) {
180
- if (this._$scrollbarThumbParams.getValue() === v) {
181
- return;
182
- }
183
- const transformedValue = this._scrollbarThumbParamsTransform(v);
184
- this._$scrollbarThumbParams.next(transformedValue);
185
- }
186
- ;
187
- get scrollbarThumbParams() { return this._$scrollbarThumbParams.getValue(); }
188
- _loading = {
189
- transform: (v) => {
190
- const valid = validateBoolean(v);
191
- if (!valid) {
192
- console.error('The "loading" parameter must be of type `boolean`.');
193
- return false;
194
- }
195
- return v;
196
- },
197
- };
198
- _$loading = new BehaviorSubject(false);
199
- $loading = this._$loading.asObservable();
200
- _loadingTransform = (v) => {
201
- const valid = validateBoolean(v);
202
- if (!valid) {
203
- console.error('The "loading" parameter must be of type `boolean`.');
204
- return false;
205
- }
206
- return v;
207
- };
208
- /**
209
- * If `true`, the scrollBar goes into loading state. The default value is `false`.
210
- */
211
- set loading(v) {
212
- if (this._$loading.getValue() === v) {
213
- return;
214
- }
215
- const transformedValue = this._loadingTransform(v);
216
- this._$loading.next(transformedValue);
217
- }
218
- ;
219
- get loading() { return this._$loading.getValue(); }
220
- _$waitForPreparation = new BehaviorSubject(DEFAULT_WAIT_FOR_PREPARATION);
221
- $waitForPreparation = this._$waitForPreparation.asObservable();
222
- _waitForPreparationTransform = (v) => {
223
- const valid = validateObject(v);
224
- if (!valid) {
225
- console.error('The "waitForPreparation" parameter must be of type `boolean`.');
226
- return DEFAULT_WAIT_FOR_PREPARATION;
227
- }
228
- return v;
229
- };
230
- /**
231
- * If true, it will wait until the list items are fully prepared before displaying them.. The default value is `true`.
232
- */
233
- set waitForPreparation(v) {
234
- if (this._$waitForPreparation.getValue() === v) {
235
- return;
236
- }
237
- const transformedValue = this._waitForPreparationTransform(v);
238
- this._$waitForPreparation.next(transformedValue);
239
- }
240
- ;
241
- get waitForPreparation() { return this._$waitForPreparation.getValue(); }
242
- _$clickDistance = new BehaviorSubject(DEFAULT_CLICK_DISTANCE);
243
- $clickDistance = this._$clickDistance.asObservable();
244
- _clickDistanceTransform = (v) => {
245
- const valid = validateInt(v);
246
- if (!valid) {
247
- console.error('The "clickDistance" parameter must be of type `number`.');
248
- return DEFAULT_CLICK_DISTANCE;
249
- }
250
- return v;
251
- };
252
- /**
253
- * The maximum scroll distance at which a click event is triggered.
254
- */
255
- set clickDistance(v) {
256
- if (this._$clickDistance.getValue() === v) {
257
- return;
258
- }
259
- const transformedValue = this._clickDistanceTransform(v);
260
- this._$clickDistance.next(transformedValue);
261
- }
262
- ;
263
- get clickDistance() { return this._$clickDistance.getValue(); }
264
- _$items = new BehaviorSubject([]);
265
- $items = this._$items.asObservable();
266
- _itemsTransform = (v) => {
267
- let valid = validateArray(v, true, true);
268
- if (valid) {
269
- if (v) {
270
- const trackBy = this.trackBy;
271
- for (let i = 0, l = v.length; i < l; i++) {
272
- const item = v[i];
273
- valid = validateObject(item, true, true);
274
- if (valid) {
275
- if (item && !(validateFloat(item?.[trackBy], true) || validateString(item?.[trackBy], true, true))) {
276
- valid = false;
277
- break;
278
- }
279
- }
280
- }
281
- }
282
- }
283
- if (!valid) {
284
- console.error('The "items" parameter must be of type `IVirtualListCollection` or `null`.');
285
- return [];
286
- }
287
- return v;
288
- };
289
- /**
290
- * Collection of list items.
291
- */
292
- set items(v) {
293
- if (this._$items.getValue() === v) {
294
- return;
295
- }
296
- const transformedValue = this._itemsTransform(v);
297
- this._$items.next(transformedValue);
298
- }
299
- ;
300
- get items() { return this._$items.getValue(); }
301
- _$selectedIds = new BehaviorSubject(null);
302
- $selectedIds = this._$selectedIds.asObservable();
303
- _selectedIdsTransform = (v) => {
304
- let valid = validateArray(v, true, true) || validateString(v, true, true) || validateFloat(v, true);
305
- if (valid) {
306
- if (v && Array.isArray(v)) {
307
- for (let i = 0, l = v.length; i < l; i++) {
308
- const item = v[i];
309
- valid = validateString(item) || validateFloat(item);
310
- if (!valid) {
311
- break;
312
- }
313
- }
314
- }
315
- }
316
- if (!valid) {
317
- console.error('The "selectedIds" parameter must be of type `Array<Id> | Id` or `null`.');
318
- return this._isMultiSelection ? [] : null;
319
- }
320
- return v;
321
- };
322
- /**
323
- * Sets the selected items.
324
- */
325
- set selectedIds(v) {
326
- if (this._$selectedIds.getValue() === v) {
327
- return;
328
- }
329
- const transformedValue = this._selectedIdsTransform(v);
330
- this._$selectedIds.next(transformedValue);
331
- }
332
- ;
333
- get selectedIds() { return this._$selectedIds.getValue(); }
334
- _$defaultItemValue = new BehaviorSubject(null);
335
- $defaultItemValue = this._$defaultItemValue.asObservable();
336
- set defaultItemValue(v) {
337
- if (this._$defaultItemValue.getValue() === v) {
338
- return;
339
- }
340
- this._$defaultItemValue.next(v);
341
- }
342
- ;
343
- get defaultItemValue() { return this._$defaultItemValue.getValue(); }
344
- _$collapsedIds = new BehaviorSubject([]);
345
- $collapsedIds = this._$collapsedIds.asObservable();
346
- _collapsedIdsTransform = (v) => {
347
- let valid = validateArray(v, true, true);
348
- if (valid) {
349
- if (v && Array.isArray(v)) {
350
- for (let i = 0, l = v.length; i < l; i++) {
351
- const item = v[i];
352
- valid = validateString(item) || validateFloat(item);
353
- if (!valid) {
354
- break;
355
- }
356
- }
357
- }
358
- }
359
- if (!valid) {
360
- console.error('The "collapsedIds" parameter must be of type `Array<Id>`.');
361
- return [];
362
- }
363
- return v;
364
- };
365
- /**
366
- * Sets the collapsed items.
367
- */
368
- set collapsedIds(v) {
369
- if (this._$collapsedIds.getValue() === v) {
370
- return;
371
- }
372
- const transformedValue = this._collapsedIdsTransform(v);
373
- this._$collapsedIds.next(transformedValue);
374
- }
375
- ;
376
- get collapsedIds() { return this._$collapsedIds.getValue(); }
377
- _$selectByClick = new BehaviorSubject(DEFAULT_SELECT_BY_CLICK);
378
- $selectByClick = this._$selectByClick.asObservable();
379
- _selectByClickTransform = (v) => {
380
- const valid = validateBoolean(v);
381
- if (!valid) {
382
- console.error('The "selectByClick" parameter must be of type `boolean`.');
383
- return DEFAULT_SELECT_BY_CLICK;
384
- }
385
- return v;
386
- };
387
- /**
388
- * If `false`, the element is selected using the config.api method passed to the template;
389
- * if `true`, the element is selected by clicking on it. The default value is `true`.
390
- */
391
- set selectByClick(v) {
392
- if (this._$selectByClick.getValue() === v) {
393
- return;
394
- }
395
- const transformedValue = this._selectByClickTransform(v);
396
- this._$selectByClick.next(transformedValue);
397
- }
398
- ;
399
- get selectByClick() { return this._$selectByClick.getValue(); }
400
- _$collapseByClick = new BehaviorSubject(DEFAULT_COLLAPSE_BY_CLICK);
401
- $collapseByClick = this._$collapseByClick.asObservable();
402
- _collapseByClickTransform = (v) => {
403
- const valid = validateBoolean(v);
404
- if (!valid) {
405
- console.error('The "collapseByClick" parameter must be of type `boolean`.');
406
- return DEFAULT_COLLAPSE_BY_CLICK;
407
- }
408
- return v;
409
- };
410
- /**
411
- * If `false`, the element is collapsed using the config.collapse method passed to the template;
412
- * if `true`, the element is collapsed by clicking on it. The default value is `true`.
413
- */
414
- set collapseByClick(v) {
415
- if (this._$collapseByClick.getValue() === v) {
416
- return;
417
- }
418
- const transformedValue = this._collapseByClickTransform(v);
419
- this._$collapseByClick.next(transformedValue);
420
- }
421
- ;
422
- get collapseByClick() { return this._$collapseByClick.getValue(); }
423
- /**
424
- * @deprecated
425
- * Use the `stickyEnabled` property instead.
426
- */
427
- set snap(v) {
428
- throw Error(`Property snap is deprecated. Use the \`stickyEnabled\` property instead.`);
429
- }
430
- ;
431
- _$stickyEnabled = new BehaviorSubject(DEFAULT_STICKY_ENABLED);
432
- $stickyEnabled = this._$stickyEnabled.asObservable();
433
- _stickyEnabledTransform = (v) => {
434
- const valid = validateBoolean(v);
435
- if (!valid) {
436
- console.error('The "stickyEnabled" parameter must be of type `boolean`.');
437
- return DEFAULT_STICKY_ENABLED;
438
- }
439
- return v;
440
- };
441
- /**
442
- * Determines whether items with the given `sticky` in `itemConfigMap` will stick to the edges. Default value is "true".
443
- */
444
- set stickyEnabled(v) {
445
- if (this._$stickyEnabled.getValue() === v) {
446
- return;
447
- }
448
- const transformedValue = this._stickyEnabledTransform(v);
449
- this._$stickyEnabled.next(transformedValue);
450
- }
451
- ;
452
- get stickyEnabled() { return this._$stickyEnabled.getValue(); }
453
- _$snapToEndTransitionInstantOffset = new BehaviorSubject(DEFAULT_SNAP_TO_END_TRANSITION_INSTANT_OFFSET);
454
- $snapToEndTransitionInstantOffset = this._$snapToEndTransitionInstantOffset.asObservable();
455
- _snapToEndTransitionInstantOffsetTransform = (v) => {
456
- const valid = validateFloat(v);
457
- if (!valid) {
458
- console.error('The "snapToEndTransitionInstantOffset" parameter must be of type `number`.');
459
- return DEFAULT_SNAP_TO_END_TRANSITION_INSTANT_OFFSET;
460
- }
461
- return v;
462
- };
463
- /**
464
- * Sets the offset value; if the scroll area value is exceeded, the scroll animation will be disabled. Default value is "0".
465
- */
466
- set snapToEndTransitionInstantOffset(v) {
467
- if (this._$snapToEndTransitionInstantOffset.getValue() === v) {
468
- return;
469
- }
470
- const transformedValue = this._snapToEndTransitionInstantOffsetTransform(v);
471
- this._$snapToEndTransitionInstantOffset.next(transformedValue);
472
- }
473
- ;
474
- get snapToEndTransitionInstantOffset() { return this._$snapToEndTransitionInstantOffset.getValue(); }
475
- _$scrollStartOffset = new BehaviorSubject(0);
476
- $scrollStartOffset = this._$scrollStartOffset.asObservable();
477
- _scrollStartOffsetTransform = (v) => {
478
- const valid = validateFloat(v, true) || isPercentageValue(v);
479
- if (!valid) {
480
- console.error('The "scrollStartOffset" parameter must be one of type `number` or `string`.');
481
- return 0;
482
- }
483
- return v;
484
- };
485
- /**
486
- * Sets the scroll start offset value. Can be specified in absolute or percentage values.
487
- * Supports arithmetic expressions of addition `50% + 25` or subtraction `50% - 25`. Default value is "0".
488
- */
489
- set scrollStartOffset(v) {
490
- if (this._$scrollStartOffset.getValue() === v) {
491
- return;
492
- }
493
- const transformedValue = this._scrollStartOffsetTransform(v);
494
- this._$scrollStartOffset.next(transformedValue);
495
- }
496
- ;
497
- get scrollStartOffset() { return this._$scrollStartOffset.getValue(); }
498
- _$scrollEndOffset = new BehaviorSubject(0);
499
- $scrollEndOffset = this._$scrollEndOffset.asObservable();
500
- _scrollEndOffsetTransform = (v) => {
501
- const valid = validateFloat(v, true) || isPercentageValue(v);
502
- if (!valid) {
503
- console.error('The "scrollEndOffset" parameter must be one of type `number` or `string`.');
504
- return 0;
505
- }
506
- return v;
507
- };
508
- /**
509
- * Sets the scroll end offset value. Can be specified in absolute or percentage values.
510
- * Supports arithmetic expressions of addition `50% + 25` or subtraction `50% - 25`. Default value is "0".
511
- */
512
- set scrollEndOffset(v) {
513
- if (this._$scrollEndOffset.getValue() === v) {
514
- return;
515
- }
516
- const transformedValue = this._scrollEndOffsetTransform(v);
517
- this._$scrollEndOffset.next(transformedValue);
518
- }
519
- ;
520
- get scrollEndOffset() { return this._$scrollEndOffset.getValue(); }
521
- _$snapScrollToStart = new BehaviorSubject(DEFAULT_SNAP_SCROLLTO_START);
522
- $snapScrollToStart = this._$snapScrollToStart.asObservable();
523
- _snapScrollToStartTransform = (v) => {
524
- const valid = validateBoolean(v, true);
525
- if (!valid) {
526
- console.error('The "snapScrollToStart" parameter must be of type `boolean`.');
527
- return DEFAULT_SNAP_SCROLLTO_START;
528
- }
529
- return v;
530
- };
531
- /**
532
- * Determines whether the scroll will be anchored to the start of the list. Default value is "true".
533
- * This property takes precedence over the snapScrollToEnd property.
534
- * That is, if snapScrollToStart and snapScrollToEnd are enabled, the list will initially snap
535
- * to the beginning; if you move the scroll bar to the end, the list will snap to the end.
536
- * If snapScrollToStart is disabled and snapScrollToEnd is enabled, the list will snap to the end;
537
- * if you move the scroll bar to the beginning, the list will snap to the beginning.
538
- * If both snapScrollToStart and snapScrollToEnd are disabled, the list will never snap to the beginning or end.
539
- * In the `spreadingMode=SpreadingModes.INFINITY` mode, the `snapScrollToStart` property is automatically disabled, since the list has no beginning or end.
540
- */
541
- set snapScrollToStart(v) {
542
- if (this._$snapScrollToStart.getValue() === v) {
543
- return;
544
- }
545
- const transformedValue = this._snapScrollToStartTransform(v);
546
- this._$snapScrollToStart.next(transformedValue);
547
- }
548
- ;
549
- get snapScrollToStart() { return this._$snapScrollToStart.getValue(); }
550
- _$snapScrollToEnd = new BehaviorSubject(DEFAULT_SNAP_SCROLLTO_END);
551
- $snapScrollToEnd = this._$snapScrollToEnd.asObservable();
552
- _snapScrollToEndTransform = (v) => {
553
- const valid = validateBoolean(v, true);
554
- if (!valid) {
555
- console.error('The "snapScrollToEnd" parameter must be of type `boolean`.');
556
- return DEFAULT_SNAP_SCROLLTO_END;
557
- }
558
- return v;
559
- };
560
- /**
561
- * Determines whether the scroll will be anchored to the утв of the list. Default value is "true".
562
- * That is, if snapScrollToStart and snapScrollToEnd are enabled, the list will initially snap
563
- * to the beginning; if you move the scroll bar to the end, the list will snap to the end.
564
- * If snapScrollToStart is disabled and snapScrollToEnd is enabled, the list will snap to the end;
565
- * if you move the scroll bar to the beginning, the list will snap to the beginning.
566
- * If both snapScrollToStart and snapScrollToEnd are disabled, the list will never snap to the beginning or end.
567
- * In the `spreadingMode=SpreadingModes.INFINITY` mode, the `snapScrollToEnd` property is automatically disabled, since the list has no beginning or end.
568
- */
569
- set snapScrollToEnd(v) {
570
- if (this._$snapScrollToEnd.getValue() === v) {
571
- return;
572
- }
573
- const transformedValue = this._snapScrollToEndTransform(v);
574
- this._$snapScrollToEnd.next(transformedValue);
575
- }
576
- ;
577
- get snapScrollToEnd() { return this._$snapScrollToEnd.getValue(); }
578
- /**
579
- * @deprecated
580
- * The stopSnappingScrollToEnd property is deprecated. Use the snapScrollToEnd property.
581
- */
582
- set snapScrollToBottom(v) {
583
- throw Error('The stopSnappingScrollToEnd property is deprecated. Use the snapScrollToEnd property.');
584
- }
585
- _$scrollbarEnabled = new BehaviorSubject(DEFAULT_SCROLLBAR_ENABLED);
586
- $scrollbarEnabled = this._$scrollbarEnabled.asObservable();
587
- _scrollbarEnabledTransform = (v) => {
588
- const valid = validateBoolean(v, true);
589
- if (!valid) {
590
- console.error('The "scrollbarEnabled" parameter must be of type `boolean`.');
591
- return DEFAULT_SCROLLBAR_ENABLED;
592
- }
593
- return v;
594
- };
595
- /**
596
- * Determines whether the scrollbar is shown or not. The default value is "true".
597
- */
598
- set scrollbarEnabled(v) {
599
- if (this._$scrollbarEnabled.getValue() === v) {
600
- return;
601
- }
602
- const transformedValue = this._scrollbarEnabledTransform(v);
603
- this._$scrollbarEnabled.next(transformedValue);
604
- }
605
- ;
606
- get scrollbarEnabled() { return this._$scrollbarEnabled.getValue(); }
607
- _$scrollbarInteractive = new BehaviorSubject(DEFAULT_SCROLLBAR_INTERACTIVE);
608
- $scrollbarInteractive = this._$scrollbarInteractive.asObservable();
609
- _scrollbarInteractiveTransform = (v) => {
610
- const valid = validateBoolean(v, true);
611
- if (!valid) {
612
- console.error('The "scrollbarInteractive" parameter must be of type `boolean`.');
613
- return DEFAULT_SCROLLBAR_INTERACTIVE;
614
- }
615
- return v;
616
- };
617
- /**
618
- * Determines whether scrolling using the scrollbar will be possible. The default value is "true".
619
- */
620
- set scrollbarInteractive(v) {
621
- if (this._$scrollbarInteractive.getValue() === v) {
622
- return;
623
- }
624
- const transformedValue = this._scrollbarInteractiveTransform(v);
625
- this._$scrollbarInteractive.next(transformedValue);
626
- }
627
- ;
628
- get scrollbarInteractive() { return this._$scrollbarInteractive.getValue(); }
629
- _$overlappingScrollbar = new BehaviorSubject(DEFAULT_OVERLAPPING_SCROLLBAR);
630
- $overlappingScrollbar = this._$overlappingScrollbar.asObservable();
631
- _overlappingScrollbarTransform = (v) => {
632
- const valid = validateBoolean(v, true);
633
- if (!valid) {
634
- console.error('The "overlappingScrollbar" parameter must be of type `boolean`.');
635
- return DEFAULT_OVERLAPPING_SCROLLBAR;
636
- }
637
- return v;
638
- };
639
- /**
640
- * Determines whether the scroll bar will overlap the list. The default value is "false".
641
- */
642
- set overlappingScrollbar(v) {
643
- if (this._$overlappingScrollbar.getValue() === v) {
644
- return;
645
- }
646
- const transformedValue = this._overlappingScrollbarTransform(v);
647
- this._$overlappingScrollbar.next(transformedValue);
648
- }
649
- ;
650
- get overlappingScrollbar() { return this._$overlappingScrollbar.getValue(); }
651
- _$scrollBehavior = new BehaviorSubject(DEFAULT_SCROLL_BEHAVIOR);
652
- $scrollBehavior = this._$scrollBehavior.asObservable();
653
- _scrollBehaviorTransform = (v) => {
654
- const valid = validateString(v, true, true);
655
- if (!valid) {
656
- console.error('The "scrollBehavior" parameter must be of type `boolean`.');
657
- return DEFAULT_SCROLL_BEHAVIOR;
658
- }
659
- return v;
660
- };
661
- /**
662
- * Defines the scrolling behavior for any element on the page. The default value is "smooth".
663
- */
664
- set scrollBehavior(v) {
665
- if (this._$scrollBehavior.getValue() === v) {
666
- return;
667
- }
668
- const transformedValue = this._scrollBehaviorTransform(v);
669
- this._$scrollBehavior.next(transformedValue);
670
- }
671
- ;
672
- get scrollBehavior() { return this._$scrollBehavior.getValue(); }
673
- _$scrollingSettings = new BehaviorSubject(DEFAULT_SCROLLING_SETTINGS);
674
- $scrollingSettings = this._$scrollingSettings.asObservable();
675
- _scrollingSettingsTransform = (v) => {
676
- let valid = validateObject(v, true, true);
677
- if (valid && !!v) {
678
- const { frictionalForce, mass, maxDistance, maxDuration, speedScale, optimization } = v;
679
- valid = validateFloat(frictionalForce, true);
680
- if (!valid) {
681
- console.error('The "frictionalForce" parameter must be of type `number` or `undefined`.');
682
- return DEFAULT_SCROLLING_SETTINGS;
683
- }
684
- valid = validateFloat(mass, true);
685
- if (!valid) {
686
- console.error('The "mass" parameter must be of type `number` or `undefined`.');
687
- return DEFAULT_SCROLLING_SETTINGS;
688
- }
689
- valid = validateFloat(maxDistance, true);
690
- if (!valid) {
691
- console.error('The "maxDistance" parameter must be of type `number` or `undefined`.');
692
- return DEFAULT_SCROLLING_SETTINGS;
693
- }
694
- valid = validateFloat(maxDuration, true);
695
- if (!valid) {
696
- console.error('The "maxDuration" parameter must be of type `number` or `undefined`.');
697
- return DEFAULT_SCROLLING_SETTINGS;
698
- }
699
- valid = validateFloat(speedScale, true);
700
- if (!valid) {
701
- console.error('The "speedScale" parameter must be of type `number` or `undefined`.');
702
- return DEFAULT_SCROLLING_SETTINGS;
703
- }
704
- valid = validateBoolean(optimization, true);
705
- if (!valid) {
706
- console.error('The "optimization" parameter must be of type `boolean` or `undefined`.');
707
- return DEFAULT_SCROLLING_SETTINGS;
708
- }
709
- }
710
- if (!valid) {
711
- console.error('The "scrollingSettings" parameter must be of type `object` or null.');
712
- return DEFAULT_SCROLLING_SETTINGS;
713
- }
714
- return {
715
- frictionalForce: v.frictionalForce !== undefined && v.frictionalForce > 0 ? v.frictionalForce : DEFAULT_SCROLLING_SETTINGS.frictionalForce,
716
- mass: v.mass !== undefined && v.mass > 0 ? v.mass : DEFAULT_SCROLLING_SETTINGS.mass,
717
- maxDistance: v.maxDistance !== undefined && v.maxDistance > 0 ? v.maxDistance : DEFAULT_SCROLLING_SETTINGS.maxDistance,
718
- maxDuration: v.maxDuration !== undefined && v.maxDuration > 0 ? v.maxDuration : DEFAULT_SCROLLING_SETTINGS.maxDuration,
719
- speedScale: v.speedScale !== undefined && v.speedScale > 0 ? v.speedScale : DEFAULT_SCROLLING_SETTINGS.speedScale,
720
- optimization: v.optimization ?? DEFAULT_SCROLLING_SETTINGS.optimization,
721
- };
722
- };
723
- /**
724
- * Scrolling settings.
725
- * - frictionalForce - Frictional force. Default value is 0.035.
726
- * - mass - Mass. Default value is 0.005.
727
- * - maxDistance - Maximum scrolling distance. Default value is 100000.
728
- * - maxDuration - Maximum animation duration. Default value is 4000.
729
- * - speedScale - Speed scale. Default value is 10.
730
- * - optimization - Enables scrolling performance optimization. Default value is `true`.
731
- */
732
- set scrollingSettings(v) {
733
- if (this._$scrollingSettings.getValue() === v) {
734
- return;
735
- }
736
- const transformedValue = this._scrollingSettingsTransform(v);
737
- this._$scrollingSettings.next(transformedValue);
738
- }
739
- ;
740
- get scrollingSettings() { return this._$scrollingSettings.getValue(); }
741
- _$itemTransform = new BehaviorSubject(null);
742
- $itemTransform = this._$itemTransform.asObservable();
743
- _itemTransformTransform = (v) => {
744
- let valid = validateFunction(v, true, true);
745
- if (!valid) {
746
- console.error('The "itemTransform" parameter must be of type `ItemTransform` or `null`.');
747
- return null;
748
- }
749
- return v;
750
- };
751
- /**
752
- * Custom transformation of element's position, rotation, scale, opacity and zIndex. The default value is `null`.
753
- */
754
- set itemTransform(v) {
755
- if (this._$itemTransform.getValue() === v) {
756
- return;
757
- }
758
- const transformedValue = this._itemTransformTransform(v);
759
- this._$itemTransform.next(transformedValue);
760
- }
761
- ;
762
- get itemTransform() { return this._$itemTransform.getValue(); }
763
- _$snapToItem = new BehaviorSubject(DEFAULT_SNAP_TO_ITEM);
764
- $snapToItem = this._$snapToItem.asObservable();
765
- _snapToItemTransform = (v) => {
766
- const valid = validateBoolean(v);
767
- if (!valid) {
768
- console.error('The "snapToItem" parameter must be of type `boolean`.');
769
- return DEFAULT_SNAP_TO_ITEM;
770
- }
771
- return v;
772
- };
773
- /**
774
- * Snap to an item. The default value is `false`.
775
- */
776
- set snapToItem(v) {
777
- if (this._$snapToItem.getValue() === v) {
778
- return;
779
- }
780
- const transformedValue = this._snapToItemTransform(v);
781
- this._$snapToItem.next(transformedValue);
782
- }
783
- ;
784
- get snapToItem() { return this._$snapToItem.getValue(); }
785
- _$snapToItemAlign = new BehaviorSubject(DEFAULT_SNAP_TO_ITEM_ALIGN);
786
- $snapToItemAlign = this._$snapToItemAlign.asObservable();
787
- _snapToItemAlignTransform = (v) => {
788
- const valid = validateString(v) && (v === 'start' || v === 'center' || v === 'end');
789
- if (!valid) {
790
- console.error('The "snapToItemAlign" parameter must be one of `start`, `center` or `end`.');
791
- return DEFAULT_SNAP_TO_ITEM_ALIGN;
792
- }
793
- return v;
794
- };
795
- /**
796
- * Alignment for snapToItem. Available values ​​are `start`, `center`, and `end`. The default value is `center`.
797
- */
798
- set snapToItemAlign(v) {
799
- if (this._$snapToItemAlign.getValue() === v) {
800
- return;
801
- }
802
- const transformedValue = this._snapToItemAlignTransform(v);
803
- this._$snapToItemAlign.next(transformedValue);
804
- }
805
- ;
806
- get snapToItemAlign() { return this._$snapToItemAlign.getValue(); }
807
- _$snappingDistance = new BehaviorSubject(DEFAULT_SNAPPING_DISTANCE);
808
- $snappingDistance = this._$snappingDistance.asObservable();
809
- _snappingDistanceTransform = (v) => {
810
- const valid = validateString(v) || validateFloat(v);
811
- if (!valid) {
812
- console.error('The "snappingDistance" parameter must be of type `number` or `string`.');
813
- return DEFAULT_SNAPPING_DISTANCE;
814
- }
815
- return v;
816
- };
817
- /**
818
- * Snapping activation distance. Can be specified as a percentage of the element size or in absolute values.
819
- * The default value is `25%`.
820
- */
821
- set snappingDistance(v) {
822
- if (this._$snappingDistance.getValue() === v) {
823
- return;
824
- }
825
- const transformedValue = this._snappingDistanceTransform(v);
826
- this._$snappingDistance.next(transformedValue);
827
- }
828
- ;
829
- get snappingDistance() { return this._$snappingDistance.getValue(); }
830
- _$scrollingOneByOne = new BehaviorSubject(DEFAULT_SCROLLING_ONE_BY_ONE);
831
- $scrollingOneByOne = this._$scrollingOneByOne.asObservable();
832
- _scrollingOneByOneTransform = (v) => {
833
- const valid = validateBoolean(v);
834
- if (!valid) {
835
- console.error('The "scrollingOneByOne" parameter must be of type `boolean`.');
836
- return DEFAULT_SCROLLING_ONE_BY_ONE;
837
- }
838
- return v;
839
- };
840
- /**
841
- * Specifies whether to scroll one item at a time if true and the scrollToItem property is set. The default value is `false`.
842
- */
843
- set scrollingOneByOne(v) {
844
- if (this._$scrollingOneByOne.getValue() === v) {
845
- return;
846
- }
847
- const transformedValue = this._scrollingOneByOneTransform(v);
848
- this._$scrollingOneByOne.next(transformedValue);
849
- }
850
- ;
851
- get scrollingOneByOne() { return this._$scrollingOneByOne.getValue(); }
852
- _$alignment = new BehaviorSubject(DEFAULT_ALIGNMENT);
853
- $alignment = this._$alignment.asObservable();
854
- _alignmentTransform = (v) => {
855
- const valid = validateString(v) && (v === 'none' || v === 'center');
856
- if (!valid) {
857
- console.error('The "alignment" parameter must be one of `none` or `centert`.');
858
- return DEFAULT_ALIGNMENT;
859
- }
860
- return v;
861
- };
862
- /**
863
- * Determines the alignment of the list. Two modes are available: `none` and `center`. The `center` mode aligns the list items to the center of the viewport, ideal for use with the `itemTransform` property.
864
- * The `none` mode means no alignment. The default value is `none`.
865
- */
866
- set alignment(v) {
867
- if (this._$alignment.getValue() === v) {
868
- return;
869
- }
870
- const transformedValue = this._alignmentTransform(v);
871
- this._$alignment.next(transformedValue);
872
- }
873
- ;
874
- get alignment() { return this._$alignment.getValue(); }
875
- _$zIndexWhenSelecting = new BehaviorSubject(DEFAULT_ZINDEX_WHEN_SELECTING);
876
- $zIndexWhenSelecting = this._$zIndexWhenSelecting.asObservable();
877
- _zIndexWhenSelectingTransform = (v) => {
878
- const valid = validateString(v, true, true);
879
- if (!valid) {
880
- console.error('The "zIndexWhenSelecting" parameter must be of type `number` or `null`.');
881
- return DEFAULT_ZINDEX_WHEN_SELECTING;
882
- }
883
- return v ?? null;
884
- };
885
- /**
886
- * Defines the zIndex when a list item is selected. The default value is `null`.
887
- */
888
- set zIndexWhenSelecting(v) {
889
- if (this._$zIndexWhenSelecting.getValue() === v) {
890
- return;
891
- }
892
- const transformedValue = this._zIndexWhenSelectingTransform(v);
893
- this._$zIndexWhenSelecting.next(transformedValue);
894
- }
895
- ;
896
- get zIndexWhenSelecting() { return this._$zIndexWhenSelecting.getValue(); }
897
- _$spreadingMode = new BehaviorSubject(DEFAULT_SPREADING_MODE);
898
- $spreadingMode = this._$spreadingMode.asObservable();
899
- _spreadingModeTransform = (v) => {
900
- const valid = validateString(v) && (v === 'normal' || v === 'infinity');
901
- if (!valid) {
902
- console.error('The "spreadingMode" parameter must be one of `normal` or `infinity`.');
903
- return DEFAULT_SPREADING_MODE;
904
- }
905
- return v;
906
- };
907
- /**
908
- * The order of list elements. Available values ​​are `standard` and `infinity`.
909
- * `normal` — list elements are ordered according to the collection sequence.
910
- * `infinity` — list elements are ordered cyclically, forming an infinite list.
911
- * When set to `infinity`, the `alignment` property is forced to the value `Alignments.CENTER`, the `scrollbarEnabled` property is forced to the `false`
912
- * The default value is `standard`.
913
- */
914
- set spreadingMode(v) {
915
- if (this._$spreadingMode.getValue() === v) {
916
- return;
917
- }
918
- const transformedValue = this._spreadingModeTransform(v);
919
- this._$spreadingMode.next(transformedValue);
920
- }
921
- ;
922
- get spreadingMode() { return this._$spreadingMode.getValue(); }
923
- _$divides = new BehaviorSubject(DEFAULT_DIVIDES);
924
- $divides = this._$divides.asObservable();
925
- _dividesTransform = (v) => {
926
- const valid = validateFloat(v);
927
- if (!valid) {
928
- console.error('The "divides" parameter must be of type `number`.');
929
- return DEFAULT_DIVIDES;
930
- }
931
- return v <= 0 ? DEFAULT_DIVIDES : v;
932
- };
933
- /**
934
- * Column or row numbers. The default value is `1`.
935
- */
936
- set divides(v) {
937
- if (this._$divides.getValue() === v) {
938
- return;
939
- }
940
- const transformedValue = this._dividesTransform(v);
941
- this._$divides.next(transformedValue);
942
- }
943
- ;
944
- get divides() { return this._$divides.getValue(); }
945
- _$motionBlur = new BehaviorSubject(DEFAULT_MOTION_BLUR);
946
- $motionBlur = this._$motionBlur.asObservable();
947
- _motionBlurTransform = (v) => {
948
- const valid = validateFloat(v);
949
- if (!valid) {
950
- console.error('The "motionBlur" parameter must be of type `number`.');
951
- return DEFAULT_DIVIDES;
952
- }
953
- return v <= 0 ? DEFAULT_DIVIDES : v;
954
- };
955
- /**
956
- * Motion blur effect. The default value is `0.15`.
957
- */
958
- set motionBlur(v) {
959
- if (this._$motionBlur.getValue() === v) {
960
- return;
961
- }
962
- const transformedValue = this._motionBlurTransform(v);
963
- this._$motionBlur.next(transformedValue);
964
- }
965
- ;
966
- get motionBlur() { return this._$motionBlur.getValue(); }
967
- _$maxMotionBlur = new BehaviorSubject(DEFAULT_MAX_MOTION_BLUR);
968
- $maxMotionBlur = this._$maxMotionBlur.asObservable();
969
- _maxMotionBlurTransform = (v) => {
970
- const valid = validateFloat(v);
971
- if (!valid) {
972
- console.error('The "maxMotionBlur" parameter must be of type `number`.');
973
- return DEFAULT_MAX_MOTION_BLUR;
974
- }
975
- return v <= 0 ? DEFAULT_MAX_MOTION_BLUR : v;
976
- };
977
- /**
978
- * Maximum motion blur effect. The default value is `0.5`.
979
- */
980
- set maxMotionBlur(v) {
981
- if (this._$maxMotionBlur.getValue() === v) {
982
- return;
983
- }
984
- const transformedValue = this._maxMotionBlurTransform(v);
985
- this._$maxMotionBlur.next(transformedValue);
986
- }
987
- ;
988
- get maxMotionBlur() { return this._$maxMotionBlur.getValue(); }
989
- _$motionBlurEnabled = new BehaviorSubject(DEFAULT_MOTION_BLUR_ENABLED);
990
- $motionBlurEnabled = this._$motionBlurEnabled.asObservable();
991
- _motionBlurEnabledTransform = (v) => {
992
- const valid = validateBoolean(v);
993
- if (!valid) {
994
- console.error('The "motionBlurEnabled" parameter must be of type `boolean`.');
995
- return DEFAULT_MOTION_BLUR_ENABLED;
996
- }
997
- return v;
998
- };
999
- /**
1000
- * Determines whether to apply motion blur or not. The default value is `false`.
1001
- */
1002
- set motionBlurEnabled(v) {
1003
- if (this._$motionBlurEnabled.getValue() === v) {
1004
- return;
1005
- }
1006
- const transformedValue = this._motionBlurEnabledTransform(v);
1007
- this._$motionBlurEnabled.next(transformedValue);
1008
- }
1009
- ;
1010
- get motionBlurEnabled() { return this._$motionBlurEnabled.getValue(); }
1011
- _$animationParams = new BehaviorSubject(DEFAULT_ANIMATION_PARAMS);
1012
- $animationParams = this._$animationParams.asObservable();
1013
- _animationParamsTransform = (v) => {
1014
- const valid = validateObject(v, true, true);
1015
- if (!validateFloat(v.scrollToItem)) {
1016
- console.error('The "scrollToItem" parameter must be of type `number`.');
1017
- return DEFAULT_ANIMATION_PARAMS;
1018
- }
1019
- if (!validateFloat(v.snapToItem)) {
1020
- console.error('The "snapToItem" parameter must be of type `number`.');
1021
- return DEFAULT_ANIMATION_PARAMS;
1022
- }
1023
- if (!validateFloat(v.navigateByKeyboard)) {
1024
- console.error('The "navigateByKeyboard" parameter must be of type `number`.');
1025
- return DEFAULT_ANIMATION_PARAMS;
1026
- }
1027
- if (!validateFloat(v.navigateToItem)) {
1028
- console.error('The "navigateToItem" parameter must be of type `number`.');
1029
- return DEFAULT_ANIMATION_PARAMS;
1030
- }
1031
- if (!valid) {
1032
- console.error('The "animationParams" parameter must be of type `object`.');
1033
- return DEFAULT_ANIMATION_PARAMS;
1034
- }
1035
- return v;
1036
- };
1037
- /**
1038
- * Animation parameters. The default value is "{ scrollToItem: 50, snapToItem: 150, navigateToItem: 150, navigateByKeyboard: 50 }".
1039
- */
1040
- set animationParams(v) {
1041
- if (this._$animationParams.getValue() === v) {
1042
- return;
1043
- }
1044
- const transformedValue = this._animationParamsTransform(v);
1045
- this._$animationParams.next(transformedValue);
1046
- }
1047
- ;
1048
- get animationParams() { return this._$animationParams.getValue(); }
1049
- _$overscrollEnabled = new BehaviorSubject(DEFAULT_OVERSCROLL_ENABLED);
1050
- $overscrollEnabled = this._$overscrollEnabled.asObservable();
1051
- _overscrollEnabledTransform = (v) => {
1052
- const valid = validateBoolean(v, true);
1053
- if (!valid) {
1054
- console.error('The "overscrollEnabled" parameter must be of type `boolean`.');
1055
- return DEFAULT_OVERSCROLL_ENABLED;
1056
- }
1057
- return v;
1058
- };
1059
- /**
1060
- * Determines whether the overscroll (re-scroll) feature will work. The default value is "true".
1061
- */
1062
- set overscrollEnabled(v) {
1063
- if (this._$overscrollEnabled.getValue() === v) {
1064
- return;
1065
- }
1066
- const transformedValue = this._overscrollEnabledTransform(v);
1067
- this._$overscrollEnabled.next(transformedValue);
1068
- }
1069
- ;
1070
- get overscrollEnabled() { return this._$overscrollEnabled.getValue(); }
1071
- _$enabledBufferOptimization = new BehaviorSubject(DEFAULT_ENABLED_BUFFER_OPTIMIZATION);
1072
- $enabledBufferOptimization = this._$enabledBufferOptimization.asObservable();
1073
- _enabledBufferOptimizationTransform = (v) => {
1074
- const valid = validateBoolean(v);
1075
- if (!valid) {
1076
- console.error('The "enabledBufferOptimization" parameter must be of type `boolean`.');
1077
- return DEFAULT_ENABLED_BUFFER_OPTIMIZATION;
1078
- }
1079
- return v;
1080
- };
1081
- /**
1082
- * Experimental!
1083
- * Enables buffer optimization.
1084
- * Can only be used if items in the collection are not added or updated. Otherwise, artifacts in the form of twitching of the scroll area are possible.
1085
- * Works only if the property dynamic = true
1086
- */
1087
- set enabledBufferOptimization(v) {
1088
- if (this._$enabledBufferOptimization.getValue() === v) {
1089
- return;
1090
- }
1091
- const transformedValue = this._enabledBufferOptimizationTransform(v);
1092
- this._$enabledBufferOptimization.next(transformedValue);
1093
- }
1094
- ;
1095
- get enabledBufferOptimization() { return this._$enabledBufferOptimization.getValue(); }
1096
- _$itemRenderer = new BehaviorSubject(undefined);
1097
- $itemRenderer = this._$itemRenderer.asObservable();
1098
- _itemRendererTransform = (v) => {
1099
- let valid = validateObject(v);
1100
- if (v && !(typeof v.elementRef === 'object' && typeof v.createEmbeddedView === 'function')) {
1101
- valid = false;
1102
- }
1103
- if (!valid) {
1104
- throw Error('The "itemRenderer" parameter must be of type `TemplateRef`.');
1105
- }
1106
- return v;
1107
- };
1108
- /**
1109
- * Rendering element template.
1110
- */
1111
- set itemRenderer(v) {
1112
- if (this._$itemRenderer.getValue() === v) {
1113
- return;
1114
- }
1115
- const transformedValue = this._itemRendererTransform(v);
1116
- this._$itemRenderer.next(transformedValue);
1117
- }
1118
- ;
1119
- get itemRenderer() { return this._$itemRenderer.getValue(); }
1120
- _$itemConfigMap = new BehaviorSubject({});
1121
- $itemConfigMap = this._$itemConfigMap.asObservable();
1122
- _itemConfigMapTransform = (v) => {
1123
- let valid = validateObject(v);
1124
- if (valid) {
1125
- if (v) {
1126
- for (let id in v) {
1127
- const item = v[id];
1128
- if (!item ||
1129
- !validateBoolean(item.collapsable, true) ||
1130
- !validateBoolean(item.selectable, true) ||
1131
- !(item.sticky === undefined || item.sticky === 0 || item.sticky === 1 || item.sticky === 2)) {
1132
- valid = false;
1133
- break;
1134
- }
1135
- }
1136
- }
1137
- }
1138
- if (!valid) {
1139
- console.error('The "itemConfigMap" parameter must be of type `IVirtualListItemConfigMap`.');
1140
- return {};
1141
- }
1142
- return v;
1143
- };
1144
- /**
1145
- * Sets `sticky` position, `fullSize`, `collapsable` and `selectable` for the list item element. If `sticky` position is greater than `0`, then `sticky` position is applied.
1146
- * If the `sticky` value is greater than `0`, then the `sticky` position mode is enabled for the element. `1` - position start, `2` - position end.
1147
- * Default value is `0`.
1148
- * `selectable` determines whether an element can be selected or not. Default value is `true`.
1149
- * `collapsable` determines whether an element with a `sticky` property greater than zero can collapse and
1150
- * collapse elements in front that do not have a `sticky` property.
1151
- * `fullSize` determines the size of an element when rendering lists with cell divisions. If sticky is 1 or 2, fullSize automatically becomes true. The default value is false.
1152
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/models/item-config-map.model.ts
1153
- * @author Evgenii Alexandrovich Grebennikov
1154
- * @email djonnyx@gmail.com
1155
- */
1156
- set itemConfigMap(v) {
1157
- if (this._$itemConfigMap.getValue() === v) {
1158
- return;
1159
- }
1160
- const transformedValue = this._itemConfigMapTransform(v);
1161
- this._$itemConfigMap.next(transformedValue);
1162
- }
1163
- ;
1164
- get itemConfigMap() { return this._$itemConfigMap.getValue(); }
1165
- _$itemSize = new BehaviorSubject(DEFAULT_ITEM_SIZE);
1166
- $itemSize = this._$itemSize.asObservable();
1167
- _itemSizeTransform = (v) => {
1168
- const valid = validateFloat(v) || v === VIEWPORT;
1169
- if (!valid) {
1170
- console.error('The "itemSize" parameter must be one of `number`, `viewport` or `undefined`.');
1171
- return DEFAULT_ITEM_SIZE;
1172
- }
1173
- return v;
1174
- };
1175
- /**
1176
- * If direction = 'vertical', then the height of a typical element. If direction = 'horizontal', then the width of a typical element.
1177
- * If the `dynamicSize` property is true, the items in the list can have different sizes, and you must specify the `itemSize` property
1178
- * to adjust the sizes of the items in the unallocated area.
1179
- * If the value is 'viewport', the sizes of elements are automatically resized to fit the viewport size.
1180
- */
1181
- set itemSize(v) {
1182
- if (this._$itemSize.getValue() === v) {
1183
- return;
1184
- }
1185
- const transformedValue = this._itemSizeTransform(v);
1186
- this._$itemSize.next(transformedValue);
1187
- }
1188
- ;
1189
- get itemSize() { return this._$itemSize.getValue(); }
1190
- _$minItemSize = new BehaviorSubject(DEFAULT_ITEM_SIZE);
1191
- $minItemSize = this._$minItemSize.asObservable();
1192
- _minItemSizeTransform = (v) => {
1193
- const valid = validateFloat(v) || v === VIEWPORT;
1194
- if (!valid) {
1195
- console.error('The "minItemSize" parameter must be one of `number`, `viewport` or `undefined`.');
1196
- return DEFAULT_ITEM_SIZE;
1197
- }
1198
- return v;
1199
- };
1200
- /**
1201
- * If the `dynamicSize` property is enabled, the minimum size of the element is set.
1202
- * If the value is 'viewport', the sizes of elements are automatically resized to fit the viewport size.
1203
- */
1204
- set minItemSize(v) {
1205
- if (this._$minItemSize.getValue() === v) {
1206
- return;
1207
- }
1208
- const transformedValue = this._minItemSizeTransform(v);
1209
- this._$minItemSize.next(transformedValue);
1210
- }
1211
- ;
1212
- get minItemSize() { return this._$minItemSize.getValue(); }
1213
- _$maxItemSize = new BehaviorSubject(DEFAULT_MAX_ITEM_SIZE);
1214
- $maxItemSize = this._$maxItemSize.asObservable();
1215
- _maxItemSizeTransform = (v) => {
1216
- const valid = validateFloat(v) || v === VIEWPORT;
1217
- if (!valid) {
1218
- console.error('The "maxItemSize" parameter must be one of `number`, `viewport` or `undefined`.');
1219
- return DEFAULT_ITEM_SIZE;
1220
- }
1221
- return v;
1222
- };
1223
- /**
1224
- * If the `dynamicSize` property is enabled, the maximum size of the element is set.
1225
- * If the value is 'viewport', the sizes of elements are automatically resized to fit the viewport size.
1226
- */
1227
- set maxItemSize(v) {
1228
- if (this._$maxItemSize.getValue() === v) {
1229
- return;
1230
- }
1231
- const transformedValue = this._maxItemSizeTransform(v);
1232
- this._$maxItemSize.next(transformedValue);
1233
- }
1234
- ;
1235
- get maxItemSize() { return this._$maxItemSize.getValue(); }
1236
- _$dynamicSize = new BehaviorSubject(DEFAULT_DYNAMIC_SIZE);
1237
- $dynamicSize = this._$dynamicSize.asObservable();
1238
- _dynamicSizeTransform = (v) => {
1239
- const valid = validateBoolean(v);
1240
- if (!valid) {
1241
- console.error('The "dynamicSize" parameter must be of type `boolean`.');
1242
- return DEFAULT_DYNAMIC_SIZE;
1243
- }
1244
- return v;
1245
- };
1246
- /**
1247
- * If true, items in the list may have different sizes, and the itemSize property must be specified to adjust
1248
- * the sizes of items in the unallocated area.
1249
- * If false then the items in the list have a fixed size specified by the itemSize property. The default value is true.
1250
- */
1251
- set dynamicSize(v) {
1252
- if (this._$dynamicSize.getValue() === v) {
1253
- return;
1254
- }
1255
- const transformedValue = this._dynamicSizeTransform(v);
1256
- this._$dynamicSize.next(transformedValue);
1257
- }
1258
- ;
1259
- get dynamicSize() { return this._$dynamicSize.getValue(); }
1260
- _$direction = new BehaviorSubject(DEFAULT_DIRECTION);
1261
- $direction = this._$direction.asObservable();
1262
- _directionTransform = (v) => {
1263
- const valid = validateString(v) && (v === 'horizontal' || v === 'vertical');
1264
- if (!valid) {
1265
- console.error('The "direction" parameter must be one of `horizontal` or `vertical`.');
1266
- return DEFAULT_DIRECTION;
1267
- }
1268
- return v;
1269
- };
1270
- /**
1271
- * Determines the direction in which elements are placed. Default value is "vertical".
1272
- */
1273
- set direction(v) {
1274
- if (this._$direction.getValue() === v) {
1275
- return;
1276
- }
1277
- const transformedValue = this._directionTransform(v);
1278
- this._$direction.next(transformedValue);
1279
- }
1280
- ;
1281
- get direction() { return this._$direction.getValue(); }
1282
- _$collectionMode = new BehaviorSubject(DEFAULT_COLLECTION_MODE);
1283
- $collectionMode = this._$collectionMode.asObservable();
1284
- _collectionModeTransform = (v) => {
1285
- const valid = validateString(v) && (v === 'normal' || v === 'lazy');
1286
- if (!valid) {
1287
- console.error('The "direction" parameter must be one of `normal` or `lazy`.');
1288
- return DEFAULT_COLLECTION_MODE;
1289
- }
1290
- return v;
1291
- };
1292
- /**
1293
- * Determines the action modes for collection elements. Default value is "normal".
1294
- */
1295
- set collectionMode(v) {
1296
- if (this._$collectionMode.getValue() === v) {
1297
- return;
1298
- }
1299
- const transformedValue = this._collectionModeTransform(v);
1300
- this._$collectionMode.next(transformedValue);
1301
- }
1302
- ;
1303
- get collectionMode() { return this._$collectionMode.getValue(); }
1304
- _$bufferSize = new BehaviorSubject(DEFAULT_BUFFER_SIZE);
1305
- $bufferSize = this._$bufferSize.asObservable();
1306
- _bufferSizeTransform = (v) => {
1307
- const valid = validateInt(v);
1308
- if (!valid) {
1309
- console.error('The "bufferSize" parameter must be of type `number`.');
1310
- return DEFAULT_BUFFER_SIZE;
1311
- }
1312
- return v;
1313
- };
1314
- /**
1315
- * Number of elements outside the scope of visibility. Default value is 2.
1316
- */
1317
- set bufferSize(v) {
1318
- if (this._$bufferSize.getValue() === v) {
1319
- return;
1320
- }
1321
- const transformedValue = this._bufferSizeTransform(v);
1322
- this._$bufferSize.next(transformedValue);
1323
- }
1324
- ;
1325
- get bufferSize() { return this._$bufferSize.getValue(); }
1326
- _$maxBufferSize = new BehaviorSubject(DEFAULT_MAX_BUFFER_SIZE);
1327
- $maxBufferSize = this._$maxBufferSize.asObservable();
1328
- _maxBufferSizeTransform = (v) => {
1329
- let val = v;
1330
- const valid = validateInt(v, true);
1331
- if (!valid) {
1332
- console.error('The "maxBufferSize" parameter must be of type `number`.');
1333
- val = DEFAULT_MAX_BUFFER_SIZE;
1334
- }
1335
- const bufferSize = this.bufferSize;
1336
- if (val === undefined || val <= bufferSize) {
1337
- return bufferSize;
1338
- }
1339
- return val;
1340
- };
1341
- /**
1342
- * Maximum number of elements outside the scope of visibility. Default value is 100.
1343
- * If maxBufferSize is set to be greater than bufferSize, then adaptive buffer mode is enabled.
1344
- * The greater the scroll size, the more elements are allocated for rendering.
1345
- */
1346
- set maxBufferSize(v) {
1347
- const val = this._maxBufferSizeTransform(v);
1348
- if (this._$maxBufferSize.getValue() === val) {
1349
- return;
1350
- }
1351
- this._$maxBufferSize.next(val);
1352
- }
1353
- ;
1354
- get maxBufferSize() { return this._$maxBufferSize.getValue(); }
1355
- _$snappingMethod = new BehaviorSubject(DEFAULT_SNAPPING_METHOD);
1356
- $snappingMethod = this._$snappingMethod.asObservable();
1357
- _snappingMethodTransform = (v) => {
1358
- const valid = validateString(v) && (v === SnappingMethods.ADVANCED || v === SnappingMethods.STANDART);
1359
- if (!valid) {
1360
- console.error(`The "snappingMethod" parameter must have the value '${SnappingMethods.ADVANCED}' or '${SnappingMethods.STANDART}'.`);
1361
- return DEFAULT_SNAPPING_METHOD;
1362
- }
1363
- return v;
1364
- };
1365
- /**
1366
- * Snapping method. Default value is 'standart'.
1367
- * 'standart' - Classic group visualization.
1368
- * 'advanced' - A mask is applied to the viewport area so that the background is displayed underneath the attached group.
1369
- */
1370
- set snappingMethod(v) {
1371
- if (this._$snappingMethod.getValue() === v) {
1372
- return;
1373
- }
1374
- const transformedValue = this._snappingMethodTransform(v);
1375
- this._$snappingMethod.next(transformedValue);
1376
- }
1377
- ;
1378
- get snappingMethod() { return this._$snappingMethod.getValue(); }
1379
- _$collapsingMode = new BehaviorSubject(DEFAULT_COLLAPSING_MODES);
1380
- $collapsingMode = this._$collapsingMode.asObservable();
1381
- _collapsingModeTransform = (v) => {
1382
- const valid = validateString(v) && (v === CollapsingModes.NONE || v === CollapsingModes.MULTI_COLLAPSE || v === CollapsingModes.ACCORDION);
1383
- if (!valid) {
1384
- console.error(`The "collapsingMode" parameter must have the value '${SnappingMethods.ADVANCED}' or '${SnappingMethods.STANDART}'.`);
1385
- return DEFAULT_COLLAPSING_MODES;
1386
- }
1387
- return v;
1388
- };
1389
- /**
1390
- * Mode for collapsing list items.
1391
- * `none` - List items are not selectable.
1392
- * `multi-collapse` - List items are collapsed one by one.
1393
- * 'accordion' - Accordion collapsible list items.
1394
- * Default value is `multi-collapse
1395
- */
1396
- set collapsingMode(v) {
1397
- if (this._$collapsingMode.getValue() === v) {
1398
- return;
1399
- }
1400
- const transformedValue = this._collapsingModeTransform(v);
1401
- this._$collapsingMode.next(transformedValue);
1402
- }
1403
- ;
1404
- get collapsingMode() { return this._$collapsingMode.getValue(); }
1405
- /**
1406
- * @deprecated
1407
- * The "methodForSelecting" property is deprecated. Use the "selectMode" property.
1408
- */
1409
- set methodForSelecting(v) {
1410
- throw new Error('The "methodForSelecting" property is deprecated. Use the "selectMode" property instead.');
1411
- }
1412
- ;
1413
- _$selectingMode = new BehaviorSubject(DEFAULT_SELECTING_MODES);
1414
- $selectingMode = this._$selectingMode.asObservable();
1415
- _selectingModeTransform = (v) => {
1416
- const valid = validateString(v) && (v === 'none' || v === 'select' || v === 'multi-select');
1417
- if (!valid) {
1418
- console.error('The "selectingMode" parameter must be one of `none`, `select` or `multi-select`.');
1419
- return DEFAULT_SELECTING_MODES;
1420
- }
1421
- return v;
1422
- };
1423
- /**
1424
- * Method for selecting list items. Default value is 'none'.
1425
- * 'select' - List items are selected one by one.
1426
- * 'multi-select' - Multiple selection of list items.
1427
- * 'none' - List items are not selectable.
1428
- */
1429
- set selectingMode(v) {
1430
- if (this._$selectingMode.getValue() === v) {
1431
- return;
1432
- }
1433
- const transformedValue = this._selectingModeTransform(v);
1434
- this._$selectingMode.next(transformedValue);
1435
- }
1436
- ;
1437
- get selectingMode() { return this._$selectingMode.getValue(); }
1438
- _$trackBy = new BehaviorSubject(TRACK_BY_PROPERTY_NAME);
1439
- $trackBy = this._$trackBy.asObservable();
1440
- _trackByTransform = (v) => {
1441
- const valid = validateString(v);
1442
- if (!valid) {
1443
- console.error('The "trackBy" parameter must be of type `string`.');
1444
- return TRACK_BY_PROPERTY_NAME;
1445
- }
1446
- return v;
1447
- };
1448
- /**
1449
- * The name of the property by which tracking is performed
1450
- */
1451
- set trackBy(v) {
1452
- if (this._$trackBy.getValue() === v) {
1453
- return;
1454
- }
1455
- const transformedValue = this._trackByTransform(v);
1456
- this._$trackBy.next(transformedValue);
1457
- }
1458
- ;
1459
- get trackBy() { return this._$trackBy.getValue(); }
1460
- _$screenReaderMessage = new BehaviorSubject(DEFAULT_SCREEN_READER_MESSAGE);
1461
- $screenReaderMessage = this._$screenReaderMessage.asObservable();
1462
- _screenReaderMessageTransform = (v) => {
1463
- const valid = validateString(v);
1464
- if (!valid) {
1465
- console.error('The "screenReaderMessage" parameter must be of type `string`.');
1466
- return DEFAULT_SCREEN_READER_MESSAGE;
1467
- }
1468
- return v;
1469
- };
1470
- /**
1471
- * Message for screen reader.
1472
- * The message format is: "some text $1 some text $2",
1473
- * where $1 is the number of the first element of the screen collection,
1474
- * $2 is the number of the last element of the screen collection.
1475
- */
1476
- set screenReaderMessage(v) {
1477
- if (this._$screenReaderMessage.getValue() === v) {
1478
- return;
1479
- }
1480
- const transformedValue = this._screenReaderMessageTransform(v);
1481
- this._$screenReaderMessage.next(transformedValue);
1482
- }
1483
- ;
1484
- get screenReaderMessage() { return this._$screenReaderMessage.getValue(); }
1485
- _$screenReaderFormattedMessage = new BehaviorSubject(DEFAULT_SCREEN_READER_MESSAGE);
1486
- $screenReaderFormattedMessage = this._$screenReaderFormattedMessage.asObservable();
1487
- _$langTextDir = new BehaviorSubject(DEFAULT_LANG_TEXT_DIR);
1488
- $langTextDir = this._$langTextDir.asObservable();
1489
- _langTextDirTransform = (v) => {
1490
- const valid = validateString(v);
1491
- if (!valid) {
1492
- console.error('The "langTextDir" parameter must be of type `string`.');
1493
- return DEFAULT_LANG_TEXT_DIR;
1494
- }
1495
- return v;
1496
- };
1497
- /**
1498
- * A string indicating the direction of text for the locale.
1499
- * Can be either "ltr" (left-to-right) or "rtl" (right-to-left).
1500
- */
1501
- set langTextDir(v) {
1502
- if (this._$langTextDir.getValue() === v) {
1503
- return;
1504
- }
1505
- const transformedValue = this._langTextDirTransform(v);
1506
- this._$langTextDir.next(transformedValue);
1507
- }
1508
- ;
1509
- get langTextDir() { return this._$langTextDir.getValue(); }
1510
- _isSingleSelection = this.getIsSingleSelection();
1511
- _isMultiSelection = this.getIsMultiSelection();
1512
- _isMultipleCollapse = this.getIsMultipleCollapse();
1513
- _isAccordionCollapse = this.getIsAccordionCollapse();
1514
- _isSnappingMethodAdvanced = this.getIsSnappingMethodAdvanced();
1515
- _$isInfinity = new BehaviorSubject(false);
1516
- $isInfinity = this._$isInfinity.asObservable();
1517
- get isInfinity() {
1518
- return this._$isInfinity.getValue();
1519
- }
1520
- _isVertical = this.getIsVertical();
1521
- get isVertical() {
1522
- return this._isVertical;
1523
- }
1524
- _$isVertical = new BehaviorSubject(this.isVertical);
1525
- $isVertical = this._$isVertical.asObservable();
1526
- _$focusedElement = new BehaviorSubject(null);
1527
- $focusedElement = this._$focusedElement.asObservable();
1528
- _$classes = new BehaviorSubject({});
1529
- $classes = this._$classes.asObservable();
1530
- _$prerenderEnabled = new BehaviorSubject(false);
1531
- $prerenderEnabled = this._$prerenderEnabled.asObservable();
1532
- _$actualItems = new BehaviorSubject([]);
1533
- _$collapsedItemIds = new BehaviorSubject([]);
1534
- _displayComponents = [];
1535
- _snappedDisplayComponents = [];
1536
- _$bounds = new BehaviorSubject(null);
1537
- $bounds = this._$bounds.asObservable();
1538
- _$actualScrollbarEnabled = new BehaviorSubject(this.scrollbarEnabled);
1539
- $actualScrollbarEnabled = this._$actualScrollbarEnabled.asObservable();
1540
- _$actualAlignment = new BehaviorSubject(this.alignment);
1541
- $actualAlignment = this._$actualAlignment.asObservable();
1542
- get actualAlignment() { return this._$actualAlignment.getValue(); }
1543
- _$actualItemSize = new BehaviorSubject(0);
1544
- $actualItemSize = this._$actualItemSize.asObservable();
1545
- get actualItemSize() { return this._$actualItemSize.getValue(); }
1546
- _$actualMinItemSize = new BehaviorSubject(0);
1547
- $actualMinItemSize = this._$actualMinItemSize.asObservable();
1548
- get actualMinItemSize() { return this._$actualMinItemSize.getValue(); }
1549
- _$actualMaxItemSize = new BehaviorSubject(0);
1550
- $actualMaxItemSize = this._$actualMaxItemSize.asObservable();
1551
- get actualMaxItemSize() { return this._$actualMaxItemSize.getValue(); }
1552
- _$totalSize = new BehaviorSubject(0);
1553
- _$listBounds = new BehaviorSubject(null);
1554
- _$scrollSize = new BehaviorSubject(0);
1555
- $scrollSize = this._$scrollSize.asObservable();
1556
- _$isScrollStart = new BehaviorSubject(true);
1557
- _$isScrollEnd = new BehaviorSubject(false);
1558
- _$precalculatedScrollStartOffset = new BehaviorSubject(0);
1559
- _$precalculatedScrollEndOffset = new BehaviorSubject(0);
1560
- _$actualScrollStartOffset = new BehaviorSubject(0);
1561
- $actualScrollStartOffset = this._$actualScrollStartOffset.asObservable();
1562
- _$actualScrollEndOffset = new BehaviorSubject(0);
1563
- $actualScrollEndOffset = this._$actualScrollEndOffset.asObservable();
1564
- _$startOffset = new BehaviorSubject(0);
1565
- $startOffset = this._$startOffset.asObservable();
1566
- _$endOffset = new BehaviorSubject(0);
1567
- $endOffset = this._$endOffset.asObservable();
1568
- _$actualSnapScrollToStart = new BehaviorSubject(false);
1569
- _$actualSnapScrollToEnd = new BehaviorSubject(false);
1570
- _$alignmentScrollStartOffset = new BehaviorSubject(0);
1571
- $alignmentScrollStartOffset = this._$alignmentScrollStartOffset.asObservable();
1572
- _$alignmentScrollEndOffset = new BehaviorSubject(0);
1573
- $alignmentScrollEndOffset = this._$alignmentScrollEndOffset.asObservable();
1574
- _resizeSnappedComponentHandler = () => {
1575
- const list = this._$list.getValue(), scroller = this._$scroller.getValue(), bounds = this._$bounds.getValue(), snappedComponents = this._snappedDisplayComponents;
1576
- if (!!list && !!scroller && snappedComponents.length > 0) {
1577
- const isVertical = this._isVertical, listBounds = list.nativeElement.getBoundingClientRect();
1578
- for (const comp of snappedComponents) {
1579
- if (!!comp) {
1580
- comp.instance.regularLength = `${isVertical ? listBounds.width : listBounds.height}${PX}`;
1581
- }
1582
- }
1583
- const snappingMethod = this.snappingMethod;
1584
- if (snappingMethod === SnappingMethods.ADVANCED) {
1585
- const snappedComponent = snappedComponents?.[0]?.instance;
1586
- if (!!snappedComponent) {
1587
- const { width, height } = bounds ?? { width: 0, height: 0 }, langTextDir = this.langTextDir;
1588
- snappedComponent.element.style.clipPath = `path("M 0 0 L 0 ${snappedComponent.element.offsetHeight} L ${snappedComponent.element.offsetWidth} ${snappedComponent.element.offsetHeight} L ${snappedComponent.element.offsetWidth} 0 Z")`;
1589
- const { width: sWidth, height: sHeight } = snappedComponent.getBounds() ?? { width: 0, height: 0 }, scrollerElement = scroller.nativeElement, delta = snappedComponent.item?.measures.delta ?? 0, scrollBarSize = this.scrollbarThickness;
1590
- let right, top, bottom;
1591
- if (isVertical) {
1592
- right = width - scrollBarSize + 2;
1593
- top = sHeight;
1594
- bottom = height;
1595
- if (langTextDir === TextDirections.RTL) {
1596
- scrollerElement.style.clipPath = `path("M 0 0 L 0 ${height} L ${width} ${height} L ${width} ${top + delta} L ${scrollBarSize} ${top + delta} L ${scrollBarSize} 0 Z")`;
1597
- }
1598
- else {
1599
- scrollerElement.style.clipPath = `path("M 0 ${top + delta} L 0 ${height} L ${width} ${height} L ${width} 0 L ${right} 0 L ${right} ${top + delta} Z")`;
1600
- }
1601
- }
1602
- else {
1603
- right = width;
1604
- top = 0;
1605
- bottom = height - scrollBarSize;
1606
- scrollerElement.style.clipPath = `path("M ${width} 0 L ${width} ${bottom} L 0 ${bottom} L 0 0 L ${width} 0 Z")`;
1607
- }
1608
- }
1609
- }
1610
- }
1611
- };
1612
- _resizeSnappedObserver = null;
1613
- focusItem = (element, position, align = FocusAlignments.CENTER, behavior = BEHAVIOR_AUTO) => {
1614
- if (!this._readyForShow) {
1615
- return;
1616
- }
1617
- const scroller = this._scrollerComponent;
1618
- if (!!scroller) {
1619
- const { width, height } = this._$bounds.getValue(), { width: elementWidth, height: elementHeight } = element.getBoundingClientRect(), isVertical = this._isVertical, viewportSize = isVertical ? height : width, elementSize = isVertical ? elementHeight : elementWidth;
1620
- let pos = Number.NaN;
1621
- switch (align) {
1622
- case FocusAlignments.START: {
1623
- pos = position + scroller.startLayoutOffset;
1624
- break;
1625
- }
1626
- case FocusAlignments.CENTER: {
1627
- pos = position - (viewportSize - elementSize) * .5 + scroller.startLayoutOffset;
1628
- break;
1629
- }
1630
- case FocusAlignments.END: {
1631
- pos = position - (viewportSize - elementSize) + scroller.startLayoutOffset;
1632
- break;
1633
- }
1634
- case FocusAlignments.NONE:
1635
- default: {
1636
- break;
1637
- }
1638
- }
1639
- if (!Number.isNaN(pos)) {
1640
- this._trackBox.preventScrollSnapping(true);
1641
- const params = {
1642
- [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: pos, behavior, snap: false, normalize: true,
1643
- fireUpdate: false, blending: false, userAction: false,
1644
- duration: this.snapToItem ? Math.max(this.animationParams.scrollToItem, this.animationParams.navigateToItem) : this.animationParams.navigateToItem,
1645
- };
1646
- scroller.scrollTo(params);
1647
- }
1648
- }
1649
- };
1650
- _elementRef = inject(ElementRef);
1651
- /**
1652
- * Base class of the element component
1653
- */
1654
- _itemComponentClass = NgVirtualListItemComponent;
1655
- get itemComponentClass() { return this._itemComponentClass; }
1656
- /**
1657
- * Base class trackBox
1658
- */
1659
- _trackBoxClass = TrackBox;
1660
- /**
1661
- * Dictionary of element sizes by their id
1662
- */
1663
- _trackBox = new this._trackBoxClass(this.trackBy);
1664
- _$update = new Subject();
1665
- $update = this._$update.asObservable();
1666
- _$scrollTo = new Subject();
1667
- $scrollTo = this._$scrollTo.asObservable();
1668
- _$scrollToExecutor = new Subject();
1669
- $scrollToExecutor = this._$scrollToExecutor.asObservable();
1670
- _$scrollingTo = new BehaviorSubject(false);
1671
- _$scroll = new Subject();
1672
- $scroll = this._$scroll.asObservable();
1673
- _$tick = new Subject();
1674
- $tick = this._$tick.asObservable();
1675
- _$fireUpdate = new Subject();
1676
- $fireUpdate = this._$fireUpdate.asObservable();
1677
- _$fireUpdateNextFrame = new Subject();
1678
- $fireUpdateNextFrame = this._$fireUpdateNextFrame.asObservable();
1679
- _$preventScrollSnapping = new BehaviorSubject(false);
1680
- $preventScrollSnapping = this._$preventScrollSnapping.asObservable();
1681
- _updateId;
1682
- _readyForShow = false;
1683
- _cached = false;
1684
- _isLoading = false;
1685
- get cachable() {
1686
- return this._prerender?.active ?? false;
1687
- }
1688
- get prerenderable() {
1689
- return this.dynamicSize && (this._trackBox?.isSnappedToEnd ?? false);
1690
- }
1691
- _$viewInit = new BehaviorSubject(false);
1692
- $viewInit = this._$viewInit.asObservable();
1693
- _$destroy = new Subject();
1694
- $destroy = this._$destroy.asObservable();
1695
- constructor() {
1696
- super();
1697
- NgVirtualListComponent.__nextId = NgVirtualListComponent.__nextId + 1 === Number.MAX_SAFE_INTEGER
1698
- ? 0 : NgVirtualListComponent.__nextId + 1;
1699
- this._id = NgVirtualListComponent.__nextId;
1700
- this._service.initialize(this._id, this._trackBox);
1701
- const $dynamicSize = this.$dynamicSize, $snapScrollToEnd = this.$snapScrollToEnd;
1702
- combineLatest([$dynamicSize, $snapScrollToEnd]).pipe(takeUntil(this._$unsubscribe), tap(([dynamicSize, snapScrollToEnd]) => {
1703
- this._$prerenderEnabled.next(dynamicSize && snapScrollToEnd);
1704
- })).subscribe();
1705
- this.$animationParams.pipe(takeUntil(this._$unsubscribe), tap(v => {
1706
- this._service.animationParams = v;
1707
- })).subscribe();
1708
- this.$spreadingMode.pipe(takeUntil(this._$unsubscribe), tap(v => {
1709
- this._$isInfinity.next(isSpreadingMode(v, SpreadingModes.INFINITY));
1710
- })).subscribe();
1711
- this.$actualScrollStartOffset.pipe(takeUntil(this._$unsubscribe), debounceTime(0), tap(v => {
1712
- this._$startOffset.next(v);
1713
- })).subscribe();
1714
- this.$actualScrollEndOffset.pipe(takeUntil(this._$unsubscribe), debounceTime(0), tap(v => {
1715
- this._$endOffset.next(v);
1716
- })).subscribe();
1717
- const $isInfinity = this.$isInfinity;
1718
- $isInfinity.pipe(takeUntil(this._$unsubscribe), tap(v => {
1719
- this._trackBox.isInfinity = this._service.isInfinity = v;
1720
- })).subscribe();
1721
- const $zIndexWhenSelecting = this.$zIndexWhenSelecting;
1722
- $zIndexWhenSelecting.pipe(takeUntil(this._$unsubscribe), tap(v => {
1723
- this._service.zIndexWhenSelecting = v;
1724
- })).subscribe();
1725
- const $bounds = this._$bounds.asObservable().pipe(filter(b => !!b)), $rawScrollStartOffset = this.$scrollStartOffset, $rawScrollEndOffset = this.$scrollEndOffset;
1726
- combineLatest([$bounds, $rawScrollStartOffset]).pipe(takeUntil(this._$unsubscribe), filter(([v]) => !!v), tap(([bounds, value]) => {
1727
- const val = parseArithmeticExpression(value, this.isVertical ? bounds.height : bounds.width);
1728
- this._$precalculatedScrollStartOffset.next(val);
1729
- })).subscribe();
1730
- combineLatest([$bounds, $rawScrollEndOffset]).pipe(takeUntil(this._$unsubscribe), filter(([v]) => !!v), tap(([bounds, value]) => {
1731
- const val = parseArithmeticExpression(value, this.isVertical ? bounds.height : bounds.width);
1732
- this._$precalculatedScrollEndOffset.next(val);
1733
- })).subscribe();
1734
- this._service.$intersectionElementBySnapToItemAlign.pipe(takeUntil(this._$unsubscribe), filter(v => v !== null), tap(id => {
1735
- this.onSnapItem.emit(id);
1736
- })).subscribe();
1737
- this._service.$tick.pipe(takeUntil(this._$unsubscribe), tap(() => {
1738
- this._scrollerComponent?.tick();
1739
- })).subscribe();
1740
- this._service.$tick.pipe(takeUntil(this._$unsubscribe), filter(() => this.dynamicSize === true), tap(() => {
1741
- this.checkBoundsOfElements();
1742
- this._scrollerComponent?.tick();
1743
- })).subscribe();
1744
- }
1745
- ngAfterViewInit() {
1746
- const _$created = new BehaviorSubject(false), $created = _$created.asObservable();
1747
- combineLatest([$created, this.$show]).pipe(takeUntil(this._$unsubscribe), filter(([created, shown]) => created && shown), debounceTime(1), tap(v => {
1748
- this._$initialized.next(true);
1749
- })).subscribe();
1750
- this._$scroller.next(this._scrollerComponent?.scrollViewport);
1751
- this._$list.next(this._scrollerComponent?.scrollContent);
1752
- const $bounds = this._$bounds.asObservable().pipe(filter(b => !!b)), $scrollerComponent = of(this._scrollerComponent), $resizeViewport = $scrollerComponent.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), switchMap(scroller => scroller.$resizeViewport)), $resizeContent = $scrollerComponent.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), switchMap(scroller => scroller.$resizeContent));
1753
- $scrollerComponent.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), switchMap(scroller => scroller.$scrollDirection), tap(v => {
1754
- this._trackBox.scrollDirection = v;
1755
- })).subscribe();
1756
- $resizeViewport.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), tap(v => {
1757
- this._$bounds.next(v);
1758
- this.onAfterResize(true);
1759
- })).subscribe();
1760
- $resizeContent.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), tap(v => {
1761
- this._$listBounds.next(v);
1762
- this.onAfterResize();
1763
- })).subscribe();
1764
- const $trackBy = this.$trackBy;
1765
- $trackBy.pipe(takeUntil(this._$unsubscribe), tap(v => {
1766
- this._service.trackBy = this._trackBox.trackBy = v;
1767
- })).subscribe();
1768
- this._trackBox.displayComponents = this._displayComponents;
1769
- let hasUserAction = false;
1770
- const $itemSize = this.$itemSize.pipe(map(v => typeof v === 'number' && v <= 0 ? DEFAULT_ITEM_SIZE : v)), $minItemSize = this.$minItemSize.pipe(map(v => typeof v === 'number' && v <= 0 ? DEFAULT_MIN_ITEM_SIZE : v)), $maxItemSize = this.$maxItemSize.pipe(map(v => typeof v === 'number' && v <= 0 ? DEFAULT_MAX_ITEM_SIZE : v)), $scrollStartOffset = this.$actualScrollStartOffset.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged()), $scrollEndOffset = this.$actualScrollEndOffset.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged());
1771
- combineLatest([$minItemSize, $bounds, $scrollStartOffset, $scrollEndOffset]).pipe(takeUntil(this._$unsubscribe), switchMap(([v, bounds, startOffset, endOffset]) => {
1772
- if (v === VIEWPORT) {
1773
- const isVertical = this.isVertical, viewportBounds = bounds, result = (isVertical ? (viewportBounds?.height ?? 0) : (viewportBounds?.width ?? 0)) - startOffset - endOffset;
1774
- return of(result <= 0 ? 1 : result);
1775
- }
1776
- return of(v);
1777
- }), tap(v => {
1778
- this._$actualMinItemSize.next(v);
1779
- })).subscribe();
1780
- combineLatest([$maxItemSize, $bounds, $scrollStartOffset, $scrollEndOffset]).pipe(takeUntil(this._$unsubscribe), switchMap(([v, bounds, startOffset, endOffset]) => {
1781
- if (v === VIEWPORT) {
1782
- const isVertical = this.isVertical, viewportBounds = bounds, result = (isVertical ? (viewportBounds?.height ?? 0) : (viewportBounds?.width ?? 0)) - startOffset - endOffset;
1783
- return of(result <= 0 ? 1 : result);
1784
- }
1785
- return of(v);
1786
- }), tap(v => {
1787
- this._$actualMaxItemSize.next(v);
1788
- })).subscribe();
1789
- const $actualMinItemSize = this.$actualMinItemSize, $actualMaxItemSize = this.$actualMaxItemSize;
1790
- combineLatest([$itemSize, $bounds, $actualMinItemSize, $actualMaxItemSize, $scrollStartOffset, $scrollEndOffset]).pipe(takeUntil(this._$unsubscribe), switchMap(([v, bounds, min, max, startOffset, endOffset]) => {
1791
- if (v === VIEWPORT) {
1792
- const isVertical = this.isVertical, viewportBounds = bounds, result = (isVertical ? (viewportBounds?.height ?? 0) : (viewportBounds?.width ?? 0)) - startOffset - endOffset;
1793
- return of(result < min ? min : (result > max ? max : result));
1794
- }
1795
- return of(v < min ? min : (v > max ? max : v));
1796
- }), tap(v => {
1797
- this._$actualItemSize.next(v);
1798
- this._service.itemSize = v;
1799
- })).subscribe();
1800
- const $actualItemSize = this.$actualItemSize, $actualItems = this._$actualItems.asObservable().pipe(takeUntil(this._$unsubscribe), distinctUntilChanged());
1801
- this._service.$focusItem.pipe(takeUntil(this._$unsubscribe), tap(params => {
1802
- const { element, position, align, behavior } = params;
1803
- this.focusItem(element, position, align, behavior);
1804
- })).subscribe();
1805
- const $list = this.$list.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), map(v => v.nativeElement), take(1));
1806
- const preventKeyboardEvent = (event, isVertical) => {
1807
- const scroller = this._scrollerComponent;
1808
- if (!!scroller) {
1809
- const scrollStartOffset = this._$actualScrollStartOffset.getValue(), scrollable = scroller.scrollable ?? false, scrollSize = isVertical ? scroller.scrollTop : scroller.scrollLeft, scrollWeight = isVertical ? scroller.scrollHeight : scroller.scrollWidth;
1810
- if (scrollable || scrollSize <= scrollStartOffset || scrollSize >= scrollWeight) {
1811
- if (!!event && event.cancelable) {
1812
- event.stopImmediatePropagation();
1813
- event.preventDefault();
1814
- }
1815
- }
1816
- }
1817
- };
1818
- $list.pipe(takeUntil(this._$unsubscribe), filter(element => !!element), switchMap(element => {
1819
- return fromEvent(element, EVENT_KEY_DOWN).pipe(takeUntil(this._$unsubscribe), switchMap(e => {
1820
- switch (e.key) {
1821
- case KEY_ARR_LEFT:
1822
- if (!this.isVertical) {
1823
- preventKeyboardEvent(e, this.isVertical);
1824
- }
1825
- break;
1826
- case KEY_ARR_UP:
1827
- if (this.isVertical) {
1828
- preventKeyboardEvent(e, this.isVertical);
1829
- }
1830
- break;
1831
- case KEY_ARR_RIGHT:
1832
- if (!this.isVertical) {
1833
- preventKeyboardEvent(e, this.isVertical);
1834
- }
1835
- break;
1836
- case KEY_ARR_DOWN:
1837
- if (this.isVertical) {
1838
- preventKeyboardEvent(e, this.isVertical);
1839
- }
1840
- break;
1841
- }
1842
- return of(null);
1843
- }));
1844
- })).subscribe();
1845
- const $scrollbarThickness = this.$scrollbarThickness;
1846
- $scrollbarThickness.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), tap(scrollbarThickness => {
1847
- this._service.scrollBarSize = scrollbarThickness;
1848
- })).subscribe();
1849
- this.$fireUpdateNextFrame.pipe(takeUntil(this._$unsubscribe), debounceTime(0), tap(userAction => {
1850
- this._$fireUpdate.next(userAction);
1851
- })).subscribe();
1852
- const $scrollToItem = this.$scrollTo.pipe(takeUntil(this._$unsubscribe)), $mouseDown = fromEvent(this._elementRef.nativeElement, MOUSE_DOWN).pipe(takeUntil(this._$unsubscribe)), $touchStart = fromEvent(this._elementRef.nativeElement, TOUCH_START).pipe(takeUntil(this._$unsubscribe));
1853
- fromEvent(document, KEY_DOWN).pipe(takeUntil(this._$unsubscribe), filter(e => e.key === KEY_TAB), switchMap(e => {
1854
- return fromEvent(this._elementRef.nativeElement, FOCUS).pipe(takeUntil(this._$unsubscribe), delay(0), takeUntil($scrollToItem), takeUntil($mouseDown), takeUntil($touchStart), tap(e => {
1855
- this._service.focusFirstElement();
1856
- }));
1857
- })).subscribe();
1858
- this._service.$scrollToStart.pipe(takeUntil(this._$unsubscribe), tap(options => {
1859
- this.scrollToStart(null, options);
1860
- })).subscribe();
1861
- this._service.$scrollTo.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), tap(params => {
1862
- const { id, cb, options } = params;
1863
- this.scrollTo(id, cb, options);
1864
- })).subscribe();
1865
- this._service.$scrollToEnd.pipe(takeUntil(this._$unsubscribe), tap(options => {
1866
- this.scrollToEnd(null, options);
1867
- })).subscribe();
1868
- this.$langTextDir.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), tap(v => {
1869
- this._service.langTextDir = v;
1870
- })).subscribe();
1871
- this.$clickDistance.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), tap(v => {
1872
- this._service.clickDistance = v;
1873
- })).subscribe();
1874
- combineLatest([this.$snapScrollToStart, this.$isInfinity]).pipe(takeUntil(this._$unsubscribe), tap(([snapScrollToStart, isInfinity]) => {
1875
- this._$actualSnapScrollToStart.next(isInfinity ? false : snapScrollToStart);
1876
- })).subscribe();
1877
- combineLatest([this.$snapScrollToEnd, this.$isInfinity]).pipe(takeUntil(this._$unsubscribe), tap(([snapScrollToEnd, isInfinity]) => {
1878
- this._$actualSnapScrollToEnd.next(isInfinity ? false : snapScrollToEnd);
1879
- })).subscribe();
1880
- const $viewInit = this.$viewInit, $prerenderContainer = of(this._prerender);
1881
- const $prerender = $viewInit.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), switchMap(v => {
1882
- return $prerenderContainer.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), switchMap(v => v.$render));
1883
- }));
1884
- const $fireUpdate = this.$fireUpdate;
1885
- $fireUpdate.pipe(takeUntil(this._$unsubscribe), tap(userAction => {
1886
- hasUserAction = userAction;
1887
- })).subscribe();
1888
- const $update = this.$update, renderStabilizer = (options) => {
1889
- let renderStabilizerPrevScrollStateVersion = EMPTY_SCROLL_STATE_VERSION, renderStabilizerUpdateIterations = 0;
1890
- const prepareIterations = options?.prepareIterations ?? PREPARE_ITERATIONS, prepareReupdateLength = options?.prepareReupdateLength ?? PREPARATION_REUPDATE_LENGTH;
1891
- return of(null).pipe(takeUntil(this._$unsubscribe), switchMap(() => {
1892
- renderStabilizerPrevScrollStateVersion = EMPTY_SCROLL_STATE_VERSION;
1893
- renderStabilizerUpdateIterations = 0;
1894
- this._cached = false;
1895
- return $update.pipe(takeUntil(this._$unsubscribe), debounceTime(0), switchMap(v => {
1896
- if (((renderStabilizerPrevScrollStateVersion === EMPTY_SCROLL_STATE_VERSION) || (renderStabilizerPrevScrollStateVersion !== v)) &&
1897
- (renderStabilizerUpdateIterations < prepareIterations)) {
1898
- if (v !== EMPTY_SCROLL_STATE_VERSION) {
1899
- renderStabilizerPrevScrollStateVersion = v;
1900
- }
1901
- this._$fireUpdate.next(false);
1902
- return of(false);
1903
- }
1904
- if (renderStabilizerPrevScrollStateVersion === v) {
1905
- if (renderStabilizerUpdateIterations < prepareReupdateLength) {
1906
- renderStabilizerUpdateIterations++;
1907
- this._$fireUpdate.next(false);
1908
- return of(false);
1909
- }
1910
- }
1911
- renderStabilizerPrevScrollStateVersion = v;
1912
- return of(true);
1913
- }), filter(v => !!v), distinctUntilChanged());
1914
- }));
1915
- };
1916
- const $initialRenderStabilizer = renderStabilizer({
1917
- prepareIterations: PREPARE_ITERATIONS,
1918
- prepareReupdateLength: PREPARATION_REUPDATE_LENGTH,
1919
- }), $updateItemsRenderStabilizer = renderStabilizer({
1920
- prepareIterations: PREPARE_ITERATIONS_FOR_UPDATE_ITEMS,
1921
- prepareReupdateLength: PREPARATION_REUPDATE_LENGTH_FOR_UPDATE_ITEMS,
1922
- }), $chunkLoadingRenderStabilizer = renderStabilizer({
1923
- prepareIterations: PREPARE_ITERATIONS_FOR_UPDATE_ITEMS,
1924
- prepareReupdateLength: PREPARATION_REUPDATE_LENGTH_FOR_UPDATE_ITEMS,
1925
- }), $collapseItemsRenderStabilizer = renderStabilizer({
1926
- prepareIterations: PREPARE_ITERATIONS_FOR_COLLAPSE_ITEMS,
1927
- prepareReupdateLength: PREPARATION_REUPDATE_LENGTH_FOR_COLLAPSE_ITEMS,
1928
- }), $itemConfigMap = this.$itemConfigMap.pipe(map(v => !v ? {} : v)), $divides = this.$divides, $dynamicSize = this.$dynamicSize, $snapScrollToStart = this._$actualSnapScrollToStart.asObservable(), $snapScrollToEnd = this._$actualSnapScrollToEnd.asObservable(), $waitForPreparation = this.$waitForPreparation, $items = this.$items;
1929
- combineLatest([$viewInit, $prerenderContainer, $divides, $dynamicSize, $snapScrollToStart, $snapScrollToEnd, $waitForPreparation]).pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(([init, prerenderContainer]) => !!init && !!prerenderContainer), debounceTime(0), switchMap(([, prerenderContainer, divides, dynamicSize, snapScrollToStart, snapScrollToEnd, waitForPreparation]) => {
1930
- if (!!dynamicSize && !snapScrollToStart && !!snapScrollToEnd && !!waitForPreparation) {
1931
- const $collection = (divides > 1 ? $actualItems : $items);
1932
- return $collection.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged((p, c) => {
1933
- const pLength = p?.length ?? 0, cLength = c?.length ?? 0;
1934
- return !((cLength > 0) || (pLength !== cLength && (pLength === 0 || cLength === 0)));
1935
- }), tap(items => {
1936
- this._trackBox.resetCollection(items, this.actualItemSize);
1937
- }), switchMap(i => of((i ?? []).length > 0)), distinctUntilChanged(), tap(v => {
1938
- if (!v) {
1939
- this.cacheClean();
1940
- this.cleanup();
1941
- this._readyForShow = false;
1942
- if (!snapScrollToStart && snapScrollToEnd) {
1943
- this._trackBox.isScrollEnd = true;
1944
- }
1945
- const scrollerComponent = this._scrollerComponent;
1946
- if (!!scrollerComponent) {
1947
- scrollerComponent.prepared = false;
1948
- scrollerComponent.stopScrolling();
1949
- scrollerComponent.refresh();
1950
- }
1951
- this._$classes.next({ prepared: true });
1952
- this._$show.next(true);
1953
- }
1954
- else {
1955
- this._trackBox.isScrollEnd = true;
1956
- const waitForPreparation = this.waitForPreparation;
1957
- if (waitForPreparation) {
1958
- if (this.prerenderable) {
1959
- this._cached = false;
1960
- prerenderContainer.on(this.items);
1961
- }
1962
- }
1963
- this._$classes.next({ prepared: false });
1964
- this._$show.next(false);
1965
- }
1966
- }), switchMap(v => {
1967
- if (!v) {
1968
- if (this.prerenderable) {
1969
- prerenderContainer.off();
1970
- }
1971
- return of(false);
1972
- }
1973
- const waitForPreparation = this.waitForPreparation;
1974
- if (waitForPreparation) {
1975
- this._trackBox.isScrollEnd = true;
1976
- if (this.prerenderable) {
1977
- this._cached = false;
1978
- prerenderContainer.on(this.items);
1979
- }
1980
- return $initialRenderStabilizer.pipe(takeUntil(this._$unsubscribe), take(1), tap(() => {
1981
- this._trackBox.isScrollEnd = true;
1982
- if (this.prerenderable) {
1983
- prerenderContainer.off();
1984
- }
1985
- this._readyForShow = true;
1986
- const scrollerComponent = this._scrollerComponent;
1987
- if (!!scrollerComponent) {
1988
- scrollerComponent.prepared = true;
1989
- scrollerComponent.refresh();
1990
- }
1991
- this._$classes.next({ prepared: true });
1992
- this._$show.next(true);
1993
- }));
1994
- }
1995
- if (this.prerenderable) {
1996
- prerenderContainer.off();
1997
- }
1998
- this._readyForShow = true;
1999
- if (!snapScrollToStart && snapScrollToEnd) {
2000
- this._trackBox.isScrollEnd = true;
2001
- }
2002
- const scrollerComponent = this._scrollerComponent;
2003
- if (!!scrollerComponent) {
2004
- scrollerComponent.prepared = true;
2005
- scrollerComponent.refresh();
2006
- }
2007
- this._$classes.next({ prepared: true });
2008
- this._$show.next(true);
2009
- return of(false);
2010
- }));
2011
- }
2012
- else {
2013
- prerenderContainer.off();
2014
- const $collection = (divides > 1 ? $actualItems : $items);
2015
- return $collection.pipe(takeUntil(this._$unsubscribe), tap(items => {
2016
- if (!items || items.length === 0) {
2017
- this.cacheClean();
2018
- const scrollerComponent = this._scrollerComponent;
2019
- if (!!scrollerComponent) {
2020
- scrollerComponent.prepared = false;
2021
- }
2022
- this._$classes.next({ prepared: false });
2023
- this._$show.next(false);
2024
- }
2025
- this._trackBox.resetCollection(items, this.actualItemSize);
2026
- }), switchMap(i => of((i ?? []).length > 0)), distinctUntilChanged(), filter(v => !!v), tap(() => {
2027
- this._readyForShow = true;
2028
- if (snapScrollToStart) {
2029
- this._trackBox.isScrollStart = true;
2030
- }
2031
- else if (snapScrollToEnd) {
2032
- this._trackBox.isScrollEnd = true;
2033
- }
2034
- const scrollerComponent = this._scrollerComponent;
2035
- if (!!scrollerComponent) {
2036
- scrollerComponent.prepared = true;
2037
- scrollerComponent.refresh();
2038
- }
2039
- this._$classes.next({ prepared: true });
2040
- this._$show.next(true);
2041
- this._$fireUpdate.next(false);
2042
- }));
2043
- }
2044
- })).subscribe();
2045
- $items.pipe(map(v => v?.length > 0), distinctUntilChanged(), takeUntil(this._$unsubscribe), filter(v => !!v), tap(() => {
2046
- this._cached = false;
2047
- }), switchMap(() => {
2048
- return $prerender.pipe(takeUntil(this._$unsubscribe), debounceTime(0), take(1), tap(cache => {
2049
- if (!this._readyForShow) {
2050
- this._trackBox.refreshCache(cache);
2051
- this._cached = true;
2052
- this._$fireUpdate.next(true);
2053
- }
2054
- }));
2055
- })).subscribe();
2056
- this._service.$focusedId.pipe(takeUntil(this._$unsubscribe), tap(v => {
2057
- this._$focusedElement.next(v ?? null);
2058
- })).subscribe();
2059
- $list.pipe(takeUntil(this._$unsubscribe), filter(element => !!element), tap(element => {
2060
- this._service.listElement = element;
2061
- })).subscribe();
2062
- const $defaultItemValue = this.$defaultItemValue, $selectByClick = this.$selectByClick, $collapseByClick = this.$collapseByClick, $isScrollStart = this._$isScrollStart.asObservable(), $isScrollFinished = this._$isScrollEnd.asObservable(), $isVertical = this.$direction.pipe(map(v => this.getIsVertical(v || DEFAULT_DIRECTION)));
2063
- $snapScrollToStart.pipe(takeUntil(this._$unsubscribe), tap(v => {
2064
- this._service.snapScrollToStart = v;
2065
- })).subscribe();
2066
- $snapScrollToEnd.pipe(takeUntil(this._$unsubscribe), tap(v => {
2067
- this._service.snapScrollToEnd = v;
2068
- })).subscribe();
2069
- $isVertical.pipe(takeUntil(this._$unsubscribe), tap(v => {
2070
- this._service.isVertical = v;
2071
- })).subscribe();
2072
- $dynamicSize.pipe(takeUntil(this._$unsubscribe), tap(v => {
2073
- this._service.dynamic = v;
2074
- })).subscribe();
2075
- $defaultItemValue.pipe(takeUntil(this._$unsubscribe), tap(v => {
2076
- this._service.defaultItemValue = v;
2077
- })).subscribe();
2078
- $scrollStartOffset.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), tap(v => {
2079
- this._trackBox.scrollStartOffset = this._service.scrollStartOffset = v;
2080
- })).subscribe();
2081
- $scrollEndOffset.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), tap(v => {
2082
- this._trackBox.scrollEndOffset = this._service.scrollEndOffset = v;
2083
- })).subscribe();
2084
- $isScrollStart.pipe(takeUntil(this._$unsubscribe), skip(1), distinctUntilChanged(), debounceTime(0), filter(v => !!v && this._readyForShow), tap(() => {
2085
- if (this._scrollerComponent?.scrollable) {
2086
- this.onScrollReachStart.emit();
2087
- }
2088
- })).subscribe();
2089
- $isScrollFinished.pipe(takeUntil(this._$unsubscribe), skip(1), distinctUntilChanged(), debounceTime(0), filter(v => !!v && this._readyForShow), tap(v => {
2090
- if (this._scrollerComponent?.scrollable) {
2091
- this.onScrollReachEnd.emit();
2092
- }
2093
- })).subscribe();
2094
- $selectByClick.pipe(takeUntil(this._$unsubscribe), tap(v => {
2095
- this._service.selectByClick = v;
2096
- })).subscribe();
2097
- $collapseByClick.pipe(takeUntil(this._$unsubscribe), tap(v => {
2098
- this._service.collapseByClick = v;
2099
- })).subscribe();
2100
- $trackBy.pipe(takeUntil(this._$unsubscribe), tap(v => {
2101
- this._trackBox.trackingPropertyName = v;
2102
- })).subscribe();
2103
- $divides.pipe(takeUntil(this._$unsubscribe), tap(v => {
2104
- this._trackBox.divides = v;
2105
- })).subscribe();
2106
- combineLatest([this.$alignment, this.$isInfinity]).pipe(takeUntil(this._$unsubscribe), tap(([alignment, isInfinity]) => {
2107
- this._$actualAlignment.next(isInfinity ? Alignments.CENTER : alignment);
2108
- })).subscribe();
2109
- combineLatest([this.$scrollbarEnabled, this.$isInfinity]).pipe(takeUntil(this._$unsubscribe), debounceTime(0), tap(([scrollbarEnabled, isInfinity]) => {
2110
- this._$actualScrollbarEnabled.next(isInfinity ? false : scrollbarEnabled);
2111
- })).subscribe();
2112
- const $alignment = this.$actualAlignment, $precalculatedScrollStartOffset = this._$precalculatedScrollStartOffset.asObservable(), $precalculatedScrollEndOffset = this._$precalculatedScrollEndOffset.asObservable(), $listBounds = this._$listBounds.asObservable().pipe(filter(b => !!b)), $scrollSize = this._$scrollSize.asObservable(), $bufferSize = this.$bufferSize.pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = this.$maxBufferSize.pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $snapToItem = this.$snapToItem, $snapToItemAlign = this.$snapToItemAlign, $stickyEnabled = this.$stickyEnabled, $isLazy = this.$collectionMode.pipe(map(v => this.getIsLazy(v || DEFAULT_COLLECTION_MODE))), $enabledBufferOptimization = this.$enabledBufferOptimization, $snappingMethod = this.$snappingMethod.pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $collapsingMode = this.$collapsingMode, $selectingMode = this.$selectingMode, $selectedIds = this.$selectedIds, $collapsedIds = this.$collapsedIds.pipe(distinctUntilChanged(), map(v => Array.isArray(v) ? v : [])), $collapsedItemIds = this._$collapsedItemIds.asObservable().pipe(distinctUntilChanged(), map(v => Array.isArray(v) ? v : [])), $itemTransform = this.$itemTransform, $screenReaderMessage = this.$screenReaderMessage, $displayItems = this._service.$displayItems, $cacheVersion = this._service.$cacheVersion;
2113
- $snapToItem.pipe(takeUntil(this._$unsubscribe), tap(v => {
2114
- this._service.snapToItem = v;
2115
- })).subscribe();
2116
- $actualItems.pipe(takeUntil(this._$unsubscribe), tap(v => {
2117
- this._service.items = v;
2118
- })).subscribe();
2119
- combineLatest([$actualItems, $viewInit]).pipe(takeUntil(this._$unsubscribe), filter(([, init]) => init), debounceTime(0), tap(() => {
2120
- this._scrollerComponent?.snapIfNeed();
2121
- })).subscribe();
2122
- $itemConfigMap.pipe(takeUntil(this._$unsubscribe), tap(v => {
2123
- this._service.itemConfigMap = v;
2124
- })).subscribe();
2125
- $collapsedIds.pipe(takeUntil(this._$unsubscribe), tap(v => {
2126
- this._service.collapsedIds = v;
2127
- })).subscribe();
2128
- combineLatest([$displayItems, $screenReaderMessage, $isVertical, $scrollSize, $bounds]).pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), debounceTime(100), takeUntil(this._$unsubscribe), tap(([items, screenReaderMessage, isVertical, scrollSize, bounds]) => {
2129
- this._$screenReaderFormattedMessage.next(formatScreenReaderMessage(items, screenReaderMessage, scrollSize, isVertical, bounds));
2130
- })).subscribe();
2131
- $isLazy.pipe(takeUntil(this._$unsubscribe), tap(v => {
2132
- this._trackBox.isLazy = v;
2133
- })).subscribe();
2134
- const $itemsComposition = $items.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), switchMap(items => {
2135
- return combineLatest([$collapsedItemIds, $itemConfigMap, $trackBy, $divides]).pipe(takeUntil(this._$unsubscribe), debounceTime(0), switchMap(([collapsedIds, itemConfigMap, trackBy, divides]) => {
2136
- return of({ items, collapsedIds, itemConfigMap, trackBy, divides });
2137
- }));
2138
- }));
2139
- $itemsComposition.pipe(takeUntil(this._$unsubscribe), switchMap(({ items, collapsedIds, itemConfigMap, trackBy, divides }) => {
2140
- if (items.length === 0 || !this._readyForShow || !(this.cachable && !this._cached &&
2141
- !this._trackBox.isSnappedToStart && this._trackBox.isSnappedToEnd)) {
2142
- return of({ items, collapsedIds, itemConfigMap, trackBy, divides });
2143
- }
2144
- return $updateItemsRenderStabilizer.pipe(takeUntil(this._$unsubscribe), take(1), debounceTime(0), switchMap(() => {
2145
- return of({ items, collapsedIds, itemConfigMap, trackBy, divides });
2146
- }));
2147
- }), tap(({ items, collapsedIds, itemConfigMap, trackBy, divides }) => {
2148
- const hiddenItems = new CMap();
2149
- let isCollapsed = false;
2150
- for (let i = 0, l = items.length; i < l; i++) {
2151
- const item = items[i], id = item?.[trackBy];
2152
- if (!!item) {
2153
- const group = (itemConfigMap[id]?.sticky ?? 0) > 0, collapsed = collapsedIds.includes(id);
2154
- if (!!group) {
2155
- isCollapsed = collapsed;
2156
- }
2157
- else {
2158
- if (isCollapsed) {
2159
- hiddenItems.set(id, true);
2160
- }
2161
- }
2162
- }
2163
- }
2164
- const actualItems = [];
2165
- for (let i = 0, l = items.length; i < l; i++) {
2166
- const item = items[i], id = item?.[trackBy];
2167
- if (!!item && hiddenItems.has(id)) {
2168
- continue;
2169
- }
2170
- actualItems.push(item);
2171
- }
2172
- const normalizedCollection = normalizeCollection(actualItems, itemConfigMap, trackBy, divides);
2173
- this._$actualItems.next(normalizedCollection);
2174
- })).subscribe();
2175
- $isVertical.pipe(takeUntil(this._$unsubscribe), tap(v => {
2176
- this._isVertical = v;
2177
- const el = this._elementRef.nativeElement;
2178
- toggleClassName(el, v ? CLASS_LIST_VERTICAL : CLASS_LIST_HORIZONTAL, v ? CLASS_LIST_HORIZONTAL : CLASS_LIST_VERTICAL);
2179
- })).subscribe();
2180
- $snappingMethod.pipe(takeUntil(this._$unsubscribe), tap(v => {
2181
- this._isSnappingMethodAdvanced = this._trackBox.isSnappingMethodAdvanced = v;
2182
- })).subscribe();
2183
- $selectingMode.pipe(takeUntil(this._$unsubscribe), tap(v => {
2184
- const el = this._$list.getValue()?.nativeElement;
2185
- if (this.getIsMultiSelection(v || DEFAULT_SNAPPING_METHOD)) {
2186
- this._isMultiSelection = true;
2187
- this._isSingleSelection = false;
2188
- if (!!el) {
2189
- el.role = ROLE_LIST_BOX;
2190
- }
2191
- this._service.selectingMode = SelectingModesTypes.MULTI_SELECT;
2192
- }
2193
- else if (this.getIsSingleSelection(v || DEFAULT_SNAPPING_METHOD)) {
2194
- this._isSingleSelection = true;
2195
- this._isMultiSelection = false;
2196
- if (!!el) {
2197
- el.role = ROLE_LIST_BOX;
2198
- }
2199
- this._service.selectingMode = SelectingModesTypes.SELECT;
2200
- }
2201
- else if (this.getIsNoneSelection(v || DEFAULT_SNAPPING_METHOD)) {
2202
- this._isSingleSelection = this._isMultiSelection = false;
2203
- if (!!el) {
2204
- el.role = ROLE_LIST;
2205
- }
2206
- this._service.selectingMode = SelectingModesTypes.NONE;
2207
- }
2208
- })).subscribe();
2209
- $collapsingMode.pipe(takeUntil(this._$unsubscribe), tap(v => {
2210
- if (this.getIsNoneCollapse()) {
2211
- this._service.isNoneCollapse = true;
2212
- this._service.isAccordionCollapse = this._service.isMultipleCollapse = this._isAccordionCollapse = this._isMultipleCollapse = false;
2213
- }
2214
- else if (this.getIsMultipleCollapse()) {
2215
- this._service.isMultipleCollapse = this._isMultipleCollapse = true;
2216
- this._service.isAccordionCollapse = this._service.isNoneCollapse = this._isAccordionCollapse = false;
2217
- }
2218
- else if (this.getIsAccordionCollapse()) {
2219
- this._service.isAccordionCollapse = this._isAccordionCollapse = true;
2220
- this._service.isMultipleCollapse = this._service.isNoneCollapse = this._isMultipleCollapse = false;
2221
- }
2222
- })).subscribe();
2223
- const $preventScrollSnapping = this.$preventScrollSnapping;
2224
- $preventScrollSnapping.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), tap(() => {
2225
- if (this._readyForShow) {
2226
- this._trackBox.isScrollEnd;
2227
- this._trackBox.isScrollStart = this._trackBox.isScrollEnd = false;
2228
- this._$isScrollStart.next(false);
2229
- this._$isScrollEnd.next(false);
2230
- const scroller = this._scrollerComponent;
2231
- if (!!scroller) {
2232
- this._trackBox.preventScrollSnapping(true);
2233
- }
2234
- }
2235
- }), tap(() => {
2236
- if (this._readyForShow) {
2237
- this._$preventScrollSnapping.next(false);
2238
- }
2239
- })).subscribe();
2240
- $collapsedItemIds.pipe(takeUntil(this._$unsubscribe), filter(() => this._readyForShow), switchMap(() => {
2241
- return $collapseItemsRenderStabilizer.pipe(takeUntil(this._$unsubscribe), take(1), tap(() => {
2242
- this._$fireUpdate.next(true);
2243
- }));
2244
- })).subscribe();
2245
- let isChunkLoading = false;
2246
- const $loading = this.$loading;
2247
- $loading.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), skip(1), filter(v => !v), switchMap(() => {
2248
- isChunkLoading = true;
2249
- const scrollbar = this._scrollerComponent;
2250
- if (!!scrollbar) {
2251
- scrollbar.stopScrollbar();
2252
- scrollbar.refreshScrollbar();
2253
- }
2254
- return $actualItems.pipe(takeUntil(this._$unsubscribe), take(1), tap(() => {
2255
- this._$fireUpdateNextFrame.next(true);
2256
- }), switchMap(() => $chunkLoadingRenderStabilizer.pipe(takeUntil(this._$unsubscribe), take(1), tap(() => {
2257
- isChunkLoading = false;
2258
- this._trackBox.resetCacheChunkInfo();
2259
- const scrollbar = this._scrollerComponent;
2260
- if (!!scrollbar) {
2261
- scrollbar.stopScrollbar();
2262
- scrollbar.refreshScrollbar();
2263
- }
2264
- }))));
2265
- })).subscribe();
2266
- $loading.pipe(takeUntil(this._$unsubscribe), skip(1), distinctUntilChanged(), tap(v => {
2267
- if (v) {
2268
- this._isLoading = true;
2269
- }
2270
- }), filter(v => !v), tap(() => {
2271
- if (this._readyForShow) {
2272
- this._$preventScrollSnapping.next(true);
2273
- }
2274
- }), debounceTime(100), tap(() => {
2275
- this._isLoading = false;
2276
- })).subscribe();
2277
- const update = (params) => {
2278
- const { alignment, precalculatedScrollStartOffset, precalculatedScrollEndOffset, trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds, listBounds, scrollEndOffset, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, divides, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, enabledBufferOptimization, snapToItem, snapToItemAlign, cacheVersion, userAction, collapsedIds, itemTransform, } = params;
2279
- const scroller = this._scrollerComponent;
2280
- let totalSize = 0;
2281
- if (!!scroller) {
2282
- const isInfinity = this.isInfinity, collapsable = collapsedIds.length > 0, cachable = this.cachable, cached = this._cached, waitingCache = cachable && !cached, emitUpdate = !this._readyForShow || waitingCache || collapsable || isChunkLoading, fireUpdate = !this._readyForShow || this._$scrollingTo.getValue(), fireUpdateAtEdges = fireUpdate || !isInfinity;
2283
- if (this._readyForShow || (cachable && cached)) {
2284
- const currentScrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft);
2285
- let actualScrollSize = !this._readyForShow && snapScrollToEnd ? (isVertical ? scroller.scrollHeight : scroller.scrollWidth) :
2286
- (isVertical ? scroller.scrollTop : scroller.scrollLeft), leftLayoutOffset = 0, displayItems;
2287
- const { width, height } = bounds, viewportSize = (isVertical ? height : width), opts = {
2288
- bounds: { width, height }, dynamicSize, isVertical, itemSize, minItemSize, maxItemSize, bufferSize, maxBufferSize,
2289
- scrollSize: actualScrollSize, stickyEnabled, enabledBufferOptimization, snapToItem, snapToItemAlign, itemTransform,
2290
- };
2291
- if (snapScrollToEnd && !this._readyForShow) {
2292
- const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize1, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, { ...opts, scrollSize: actualScrollSize });
2293
- displayItems = calculatedDisplayItems;
2294
- totalSize = calculatedTotalSize1;
2295
- leftLayoutOffset = leftLayoutOffset1;
2296
- }
2297
- else {
2298
- const { displayItems: calculatedDisplayItems, totalSize: calculatedTotalSize, leftLayoutOffset: leftLayoutOffset1 } = this._trackBox.updateCollection(items, itemConfigMap, opts);
2299
- displayItems = calculatedDisplayItems;
2300
- totalSize = calculatedTotalSize;
2301
- leftLayoutOffset = leftLayoutOffset1;
2302
- }
2303
- scroller.totalSize = totalSize;
2304
- scroller.startLayoutOffset = leftLayoutOffset;
2305
- this._$totalSize.next(totalSize);
2306
- this._service.collection = displayItems;
2307
- this.resetBoundsSize(isVertical, totalSize);
2308
- this.createDisplayComponentsIfNeed(displayItems);
2309
- this.tracking();
2310
- this.snappingHandler();
2311
- if (!_$created.getValue()) {
2312
- _$created.next(true);
2313
- }
2314
- const delta = this._trackBox.delta, scrollPositionAfterUpdate = actualScrollSize + delta, roundedScrollPositionAfterUpdate = scrollPositionAfterUpdate, roundedMaxPositionAfterUpdate = isVertical ? scroller.scrollHeight : scroller.scrollWidth;
2315
- if (this._isSnappingMethodAdvanced) {
2316
- this.updateRegularRenderer();
2317
- }
2318
- switch (alignment) {
2319
- case Alignments.NONE: {
2320
- this._$actualScrollStartOffset.next(precalculatedScrollStartOffset);
2321
- this._$actualScrollEndOffset.next(precalculatedScrollEndOffset);
2322
- break;
2323
- }
2324
- case Alignments.CENTER: {
2325
- const firstItemId = items.length > 0 ? (items[0]?.[trackBy] ?? null) : null, endItemId = items.length > 0 ? (items?.[items.length - 1]?.[trackBy] ?? null) : null, alignmentStartOffset = viewportSize * .5 - (firstItemId !== null ? (isVertical ? (this._service.getItemBounds(firstItemId)?.height ?? 0) :
2326
- (this._service.getItemBounds(firstItemId)?.width ?? 0)) : 0) * (isInfinity ? 0 : .5), alignmentEndOffset = viewportSize * .5 - (endItemId !== null ? (isVertical ? (this._service.getItemBounds(endItemId)?.height ?? 0) :
2327
- (this._service.getItemBounds(endItemId)?.width ?? 0)) : 0) * (isInfinity ? 0 : .5);
2328
- this._$alignmentScrollStartOffset.next(alignmentStartOffset);
2329
- this._$alignmentScrollEndOffset.next(alignmentEndOffset);
2330
- this._$actualScrollStartOffset.next(precalculatedScrollStartOffset + alignmentStartOffset);
2331
- this._$actualScrollEndOffset.next(precalculatedScrollEndOffset + alignmentEndOffset);
2332
- break;
2333
- }
2334
- }
2335
- scroller.delta = delta;
2336
- if ((snapScrollToStart && this._trackBox.isSnappedToStart && scroller.scrollable) ||
2337
- (snapScrollToStart && currentScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
2338
- if (currentScrollSize !== roundedScrollPositionAfterUpdate) {
2339
- this._trackBox.clearDelta();
2340
- if (this._readyForShow) {
2341
- this.emitScrollEvent(true, false, userAction);
2342
- }
2343
- this._trackBox.isScrollEnd;
2344
- const params = {
2345
- [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: 0, userAction,
2346
- fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT,
2347
- blending: false, duration: this.animationParams.scrollToItem,
2348
- };
2349
- scroller?.scrollTo?.(params);
2350
- if (emitUpdate) {
2351
- this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
2352
- }
2353
- }
2354
- return;
2355
- }
2356
- if ((snapScrollToEnd && this._trackBox.isSnappedToEnd) || (snapScrollToEnd && !scroller.scrollable) ||
2357
- (scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING >= roundedMaxPositionAfterUpdate) ||
2358
- (roundedScrollPositionAfterUpdate >= scrollPositionAfterUpdate + MIN_PIXELS_FOR_PREVENT_SNAPPING)) {
2359
- this._trackBox.clearDelta();
2360
- if (!this._trackBox.isSnappedToEnd) {
2361
- this._trackBox.isScrollEnd = true;
2362
- this._trackBox.isScrollStart = false;
2363
- }
2364
- if (this._readyForShow) {
2365
- this.emitScrollEvent(true, false, false);
2366
- }
2367
- const params = {
2368
- [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: roundedMaxPositionAfterUpdate,
2369
- fireUpdate: fireUpdateAtEdges, behavior: BEHAVIOR_INSTANT, userAction: false,
2370
- blending: false, duration: this.animationParams.scrollToItem,
2371
- };
2372
- scroller?.scrollTo?.(params);
2373
- if (emitUpdate) {
2374
- this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
2375
- }
2376
- return;
2377
- }
2378
- if (scrollSize !== scrollPositionAfterUpdate &&
2379
- ((scrollPositionAfterUpdate >= 0 && scrollPositionAfterUpdate < roundedMaxPositionAfterUpdate) ||
2380
- (scrollSize !== roundedMaxPositionAfterUpdate || currentScrollSize !== scrollPositionAfterUpdate))) {
2381
- this._trackBox.clearDelta();
2382
- if (this._readyForShow) {
2383
- this.emitScrollEvent(true, false, userAction);
2384
- }
2385
- const params = {
2386
- [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollPositionAfterUpdate, blending: true, userAction,
2387
- fireUpdate, behavior: BEHAVIOR_INSTANT, duration: this.animationParams.scrollToItem,
2388
- };
2389
- scroller.scrollTo(params);
2390
- if (emitUpdate) {
2391
- this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
2392
- }
2393
- return;
2394
- }
2395
- }
2396
- if (emitUpdate) {
2397
- this._$update.next(getScrollStateVersion(totalSize, this._isVertical ? scroller.scrollTop : scroller.scrollLeft));
2398
- }
2399
- }
2400
- };
2401
- let prevItems = [];
2402
- const debouncedUpdate = debounce(update, 0, MAX_NUMBERS_OF_SKIPS_FOR_QUALITY_OPTIMIZATION_LVL1);
2403
- $viewInit.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), switchMap(() => {
2404
- return combineLatest([$trackBy, this.$isInfinity, $snapScrollToStart, $snapScrollToEnd, $bounds, $listBounds, $scrollEndOffset, $actualItems, $itemConfigMap, $scrollSize,
2405
- $actualItemSize, $actualMinItemSize, $actualMaxItemSize, $collapsedItemIds, $bufferSize, $maxBufferSize, $stickyEnabled, $isVertical,
2406
- $dynamicSize, $divides, $snapToItem, $snapToItemAlign, $enabledBufferOptimization, $itemTransform, $alignment,
2407
- $precalculatedScrollStartOffset, $precalculatedScrollEndOffset, $cacheVersion, this.$fireUpdate,
2408
- ]).pipe(takeUntil(this._$unsubscribe), tap(([trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds, listBounds, scrollEndOffset, items, itemConfigMap, scrollSize, itemSize, minItemSize, maxItemSize, collapsedIds, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, divides, snapToItem, snapToItemAlign, enabledBufferOptimization, itemTransform, alignment, precalculatedScrollStartOffset, precalculatedScrollEndOffset, cacheVersion,]) => {
2409
- let itemsChanged = false;
2410
- if (prevItems !== items) {
2411
- itemsChanged = true;
2412
- prevItems = items;
2413
- }
2414
- const enabledOptimization = this.scrollingSettings?.optimization ?? DEFAULT_SCROLLING_SETTINGS.optimization, velocity = this._scrollerComponent?.averageVelocity ?? 0, isScrolling = this._$scrollingTo.getValue(), useDebouncedUpdate = (dynamicSize && !itemTransform) && !(snapScrollToEnd && this._trackBox.isSnappedToEnd) && !itemsChanged && hasUserAction && !isScrolling &&
2415
- (velocity > 0 && velocity < MAX_VELOCITY_FOR_SCROLL_QUALITY_OPTIMIZATION_LVL1);
2416
- if (enabledOptimization) {
2417
- if (useDebouncedUpdate) {
2418
- debouncedUpdate.execute({
2419
- trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds: bounds, listBounds: listBounds, scrollEndOffset, items, itemConfigMap, scrollSize, itemSize, minItemSize,
2420
- maxItemSize, collapsedIds, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, divides, enabledBufferOptimization, itemTransform,
2421
- snapToItem, snapToItemAlign, alignment, precalculatedScrollStartOffset, precalculatedScrollEndOffset, cacheVersion, userAction: hasUserAction,
2422
- });
2423
- return;
2424
- }
2425
- debouncedUpdate.dispose();
2426
- }
2427
- if (!isScrolling) {
2428
- update({
2429
- trackBy, isInfinity, snapScrollToStart, snapScrollToEnd, bounds: bounds, listBounds: listBounds, scrollEndOffset, items, itemConfigMap, scrollSize, itemSize, minItemSize,
2430
- maxItemSize, collapsedIds, bufferSize, maxBufferSize, stickyEnabled, isVertical, dynamicSize, divides, enabledBufferOptimization, itemTransform,
2431
- snapToItem, snapToItemAlign, alignment, precalculatedScrollStartOffset, precalculatedScrollEndOffset, cacheVersion, userAction: hasUserAction,
2432
- });
2433
- }
2434
- }));
2435
- })).subscribe();
2436
- const $scroller = this.$scroller.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), map(v => v.nativeElement), take(1)), $scrollerScroll = $scrollerComponent.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), take(1), switchMap(scroller => scroller.$scroll)), $scrollerScrollEnd = $scrollerComponent.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), take(1), switchMap(scroller => scroller.$scrollEnd)), $scrollbarScroll = $scrollerComponent.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), take(1), switchMap(scroller => scroller.$scrollbarScroll));
2437
- const scrollHandler = (userAction = false) => {
2438
- const scroller = this._scrollerComponent;
2439
- if (!!scroller) {
2440
- const isVertical = this._isVertical, scrollSize = (isVertical ? scroller.scrollTop : scroller.scrollLeft), actualScrollSize = scrollSize;
2441
- if (this._readyForShow) {
2442
- if (userAction) {
2443
- this._$preventScrollSnapping.next(true);
2444
- }
2445
- }
2446
- this._$scrollSize.next(actualScrollSize);
2447
- }
2448
- };
2449
- $scroller.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), switchMap(scroller => {
2450
- return $scrollbarScroll.pipe(takeUntil(this._$unsubscribe), tap(userAction => {
2451
- const scrollerEl = this._$scroller.getValue()?.nativeElement, scrollerComponent = this._scrollerComponent;
2452
- if (!!scrollerEl && !!scrollerComponent) {
2453
- this.emitScrollEvent(false, this._readyForShow, hasUserAction);
2454
- }
2455
- if (this._readyForShow) {
2456
- if (userAction) {
2457
- if (this._trackBox.isSnappedToStart) {
2458
- this._$preventScrollSnapping.next(true);
2459
- }
2460
- if (this._trackBox.isSnappedToEnd) {
2461
- this._$preventScrollSnapping.next(true);
2462
- }
2463
- }
2464
- }
2465
- }));
2466
- })).subscribe();
2467
- $scroller.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), switchMap(scroller => {
2468
- return $scrollerScroll.pipe(takeUntil(this._$unsubscribe));
2469
- }), tap(userAction => {
2470
- hasUserAction = userAction;
2471
- const scrollerEl = this._$scroller.getValue()?.nativeElement, scrollerComponent = this._scrollerComponent;
2472
- if (!!scrollerEl && !!scrollerComponent) {
2473
- this.emitScrollEvent(false, this._readyForShow, userAction);
2474
- }
2475
- scrollHandler(userAction);
2476
- })).subscribe();
2477
- $scroller.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), switchMap(scroller => {
2478
- return $scrollerScrollEnd.pipe(takeUntil(this._$unsubscribe));
2479
- }), tap(userAction => {
2480
- hasUserAction = userAction;
2481
- const scrollerEl = this._$scroller.getValue()?.nativeElement, scrollerComponent = this._scrollerComponent;
2482
- if (!!scrollerEl && !!scrollerComponent) {
2483
- this.emitScrollEvent(true, this._readyForShow, userAction);
2484
- }
2485
- scrollHandler(userAction);
2486
- })).subscribe();
2487
- const $scrollTo = this.$scrollTo, $scrollToExecutor = this.$scrollToExecutor;
2488
- combineLatest([$scroller, $trackBy, $scrollTo]).pipe(filter(([scroller, , event]) => !!scroller && !!event), map(([scroller, trackBy, event]) => ({ scroller: scroller, trackBy, event })), switchMap(({ event }) => {
2489
- const d = event?.delay ?? 0;
2490
- if (d > 0) {
2491
- return of(event).pipe(takeUntil(this._$unsubscribe), delay(d));
2492
- }
2493
- return of(event);
2494
- }), tap(event => {
2495
- this._$scrollingTo.next(true);
2496
- this._$scrollToExecutor.next(event);
2497
- })).subscribe();
2498
- $scrollToExecutor.pipe(takeUntil(this._$unsubscribe), switchMap(event => {
2499
- const trackBy = this.trackBy, scrollerComponent = this._scrollerComponent, { id, iteration = 0, blending = false, isLastIteration = false, cb } = event;
2500
- const nextIteration = iteration + 1, finished = nextIteration >= MAX_SCROLL_TO_ITERATIONS, fireUpdate = false;
2501
- if (!this._readyForShow) {
2502
- return of([finished, { id, iteration: nextIteration, blending, cb }]).pipe(delay(0));
2503
- }
2504
- debouncedUpdate.dispose();
2505
- this._$preventScrollSnapping.next(true);
2506
- if (!!scrollerComponent) {
2507
- scrollerComponent.startScrollTo();
2508
- const items = this._$actualItems.getValue();
2509
- if (!!items && items.length) {
2510
- const dynamicSize = this.dynamicSize, itemSize = this.actualItemSize, minItemSize = this.actualMinItemSize, maxItemSize = this.actualMaxItemSize, snapScrollToEnd = this.snapScrollToEnd;
2511
- if (dynamicSize) {
2512
- const { width, height } = this._$bounds.getValue() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap, isVertical = this._isVertical, currentScrollSize = isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft, opts = {
2513
- bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize, minItemSize, maxItemSize,
2514
- bufferSize: this.bufferSize, maxBufferSize: this.maxBufferSize, itemTransform: this.itemTransform,
2515
- scrollSize: (isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft),
2516
- snapToItem: this.snapToItem, snapToItemAlign: this.snapToItemAlign,
2517
- stickyEnabled: this.stickyEnabled, fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization,
2518
- };
2519
- let scrollSize = snapScrollToEnd && this._trackBox.isSnappedToEnd ?
2520
- (isVertical ? scrollerComponent.scrollHeight : scrollerComponent.scrollWidth) :
2521
- this._trackBox.getItemPosition(id, itemConfigMap, opts);
2522
- if (scrollSize === -1) {
2523
- return of([finished, { id, blending, iteration: nextIteration, cb }]).pipe(delay(0));
2524
- }
2525
- this._trackBox.clearDelta();
2526
- const viewportSize = (isVertical ? height : width), { displayItems, totalSize, leftLayoutOffset } = this._trackBox.updateCollection(items, itemConfigMap, {
2527
- ...opts, scrollSize, fromItemId: isLastIteration ? undefined : id,
2528
- }), delta1 = this._trackBox.delta;
2529
- const normalizedTotalSize = totalSize < viewportSize ? viewportSize : totalSize;
2530
- scrollerComponent.startLayoutOffset = leftLayoutOffset;
2531
- scrollerComponent.totalSize = normalizedTotalSize;
2532
- this._service.collection = displayItems;
2533
- let actualScrollSize = scrollSize + delta1;
2534
- this.resetBoundsSize(isVertical, normalizedTotalSize);
2535
- this.createDisplayComponentsIfNeed(displayItems);
2536
- this.tracking();
2537
- this.snappingHandler();
2538
- scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, { ...opts, scrollSize: actualScrollSize, fromItemId: id });
2539
- if (this.isInfinity) {
2540
- if (this.snapToItem) {
2541
- const itemBounds = this._trackBox.getItemBounds(id);
2542
- if (!!itemBounds) {
2543
- const itemSize = isVertical ? itemBounds.height : itemBounds.width;
2544
- switch (this.snapToItemAlign) {
2545
- case SnapToItemAligns.CENTER: {
2546
- scrollSize += itemSize * .5;
2547
- break;
2548
- }
2549
- }
2550
- }
2551
- }
2552
- }
2553
- if (scrollSize === -1) {
2554
- return of([finished, { id, blending, iteration: nextIteration, cb }]).pipe(delay(0));
2555
- }
2556
- const notChanged = scrollSize === currentScrollSize;
2557
- if (!notChanged && iteration < MAX_SCROLL_TO_ITERATIONS) {
2558
- this._trackBox.clearDelta();
2559
- const params = {
2560
- [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior: BEHAVIOR_INSTANT,
2561
- fireUpdate, blending, force: true, snap: false, normalize: false,
2562
- };
2563
- scrollerComponent?.scrollTo?.(params);
2564
- return of([finished, {
2565
- id, iteration: nextIteration, blending,
2566
- isLastIteration: nextIteration < MAX_SCROLL_TO_ITERATIONS, cb
2567
- }]).pipe(delay(0));
2568
- }
2569
- else {
2570
- this._$scrollSize.next(actualScrollSize);
2571
- return of([true, { id, blending, iteration: nextIteration, cb }]).pipe(delay(0));
2572
- }
2573
- }
2574
- else {
2575
- const index = items.findIndex(item => item[trackBy] === id);
2576
- if (index > -1) {
2577
- const isVertical = this._isVertical, itemSize = this.actualItemSize;
2578
- let scrollSize = index * itemSize;
2579
- if (this.isInfinity) {
2580
- if (this.snapToItem) {
2581
- switch (this.snapToItemAlign) {
2582
- case SnapToItemAligns.CENTER: {
2583
- scrollSize += itemSize * .5;
2584
- break;
2585
- }
2586
- }
2587
- }
2588
- }
2589
- const { width, height } = this._$bounds.getValue() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap, items = this._$actualItems.getValue(), opts = {
2590
- bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize, minItemSize, maxItemSize,
2591
- bufferSize: this.bufferSize, maxBufferSize: this.maxBufferSize, itemTransform: this.itemTransform,
2592
- scrollSize: (isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft),
2593
- snapToItem: this.snapToItem, snapToItemAlign: this.snapToItemAlign,
2594
- stickyEnabled: this.stickyEnabled, fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization,
2595
- };
2596
- this._trackBox.clearDelta();
2597
- const viewportSize = (isVertical ? height : width), { displayItems, totalSize, leftLayoutOffset } = this._trackBox.updateCollection(items, itemConfigMap, {
2598
- ...opts, scrollSize, fromItemId: isLastIteration ? undefined : id,
2599
- });
2600
- const actualTotalSize = this.isInfinity ? (totalSize + viewportSize) : totalSize;
2601
- const normalizedTotalSize = actualTotalSize < viewportSize ? viewportSize : actualTotalSize;
2602
- scrollerComponent.startLayoutOffset = leftLayoutOffset;
2603
- scrollerComponent.totalSize = normalizedTotalSize;
2604
- this._service.collection = displayItems;
2605
- this.resetBoundsSize(isVertical, normalizedTotalSize);
2606
- this.createDisplayComponentsIfNeed(displayItems);
2607
- this.tracking();
2608
- this.snappingHandler();
2609
- this._$preventScrollSnapping.next(true);
2610
- const params = {
2611
- [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, fireUpdate: false,
2612
- behavior: BEHAVIOR_INSTANT, blending, force: true, snap: false, normalize: false,
2613
- };
2614
- scrollerComponent?.scrollTo?.(params);
2615
- return of([true, { id, blending, iteration: nextIteration, cb }]);
2616
- }
2617
- }
2618
- }
2619
- }
2620
- return of([finished, { id, iteration: nextIteration, blending, cb }]);
2621
- }), takeUntil(this._$unsubscribe), tap(([finished, params]) => {
2622
- if (!finished) {
2623
- this._$scrollToExecutor.next(params);
2624
- return;
2625
- }
2626
- if (this._readyForShow) {
2627
- this._trackBox.preventScrollSnapping(true);
2628
- }
2629
- this._$scrollingTo.next(false);
2630
- this._scrollerComponent?.finishedScrollTo();
2631
- this._$fireUpdate.next(true);
2632
- this.emitScrollEvent(true, false, true);
2633
- const scrollParams = params;
2634
- scrollParams?.cb?.();
2635
- }), delay(100), tap(([finished]) => {
2636
- if (finished) {
2637
- this._scrollerComponent?.snapIfNeed();
2638
- }
2639
- })).subscribe();
2640
- const $itemRenderer = this.$itemRenderer;
2641
- $itemRenderer.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(v => !!v), tap(v => {
2642
- this._$itemRenderer.next(v);
2643
- })).subscribe();
2644
- $bounds.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(v => !!v), tap(value => {
2645
- const size = { width: value.width, height: value.height };
2646
- this.onViewportChange.emit(objectAsReadonly(size));
2647
- })).subscribe();
2648
- this._service.$virtualClick.pipe(takeUntil(this._$unsubscribe), tap(v => {
2649
- this.onItemClick.emit(objectAsReadonly(v));
2650
- })).subscribe();
2651
- let isSelectedIdsFirstEmit = 0;
2652
- this._service.$selectedIds.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), tap(v => {
2653
- if (this._isSingleSelection || (this._isMultiSelection && isSelectedIdsFirstEmit >= 2)) {
2654
- const curr = this.selectedIds;
2655
- if ((this._isSingleSelection && JSON.stringify(v) !== JSON.stringify(curr)) ||
2656
- (isSelectedIdsFirstEmit === 2 && JSON.stringify(v) !== JSON.stringify(curr)) || isSelectedIdsFirstEmit > 2) {
2657
- this.onSelect.emit(copyValueAsReadonly(v));
2658
- }
2659
- }
2660
- if (isSelectedIdsFirstEmit < 3) {
2661
- isSelectedIdsFirstEmit++;
2662
- }
2663
- })).subscribe();
2664
- $selectedIds.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), tap(v => {
2665
- this._service.selectedIds = v;
2666
- })).subscribe();
2667
- $viewInit.pipe(takeUntil(this._$unsubscribe), filter(v => !!v), switchMap(() => {
2668
- return this._service.$collapsedIds.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), tap(v => {
2669
- const curr = this._$collapsedItemIds.getValue();
2670
- if ((this._isAccordionCollapse || this._isMultipleCollapse) && (JSON.stringify(v) !== JSON.stringify(curr))) {
2671
- this._$collapsedItemIds.next(v);
2672
- this.onCollapse.emit(copyValueAsReadonly(v));
2673
- }
2674
- }));
2675
- })).subscribe();
2676
- combineLatest([$collapsingMode, $items, $itemConfigMap, $trackBy]).pipe(takeUntil(this._$unsubscribe), tap(([collapsingMode, items, itemConfigMap, trackBy]) => {
2677
- const isAccordion = isCollapseMode(collapsingMode, CollapsingModes.ACCORDION);
2678
- if (isAccordion) {
2679
- const allGroups = [];
2680
- if (this._isAccordionCollapse) {
2681
- for (let i = 0, l = items.length; i < l; i++) {
2682
- const item = items[i], id = item[trackBy], collapsable = itemConfigMap?.[id]?.collapsable === true;
2683
- if (!collapsable) {
2684
- continue;
2685
- }
2686
- allGroups.push(id);
2687
- }
2688
- }
2689
- if ((this._isAccordionCollapse || this._isMultipleCollapse) && (JSON.stringify(this._$collapsedItemIds.getValue()) !== JSON.stringify(allGroups))) {
2690
- this._$collapsedItemIds.next(allGroups);
2691
- this.onCollapse.emit(copyValueAsReadonly(allGroups));
2692
- }
2693
- }
2694
- })).subscribe();
2695
- $collapsedItemIds.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), tap(v => {
2696
- this._service.collapsedIds = v;
2697
- })).subscribe();
2698
- this.$destroy.pipe(takeUntil(this._$unsubscribe), tap(() => {
2699
- debouncedUpdate.dispose();
2700
- })).subscribe();
2701
- this._$viewInit.next(true);
2702
- this._$fireUpdate.next(false);
2703
- }
2704
- onAfterResize(update = false) {
2705
- this.snappingHandler();
2706
- if (this._isSnappingMethodAdvanced) {
2707
- this.updateRegularRenderer();
2708
- }
2709
- if (this._readyForShow && update) {
2710
- const scroller = this._scrollerComponent;
2711
- if (!!scroller) {
2712
- const updatebale = this._readyForShow;
2713
- if (updatebale) {
2714
- this._$fireUpdate.next(false);
2715
- }
2716
- scroller.refresh(updatebale, updatebale);
2717
- }
2718
- }
2719
- }
2720
- checkBoundsOfElements() {
2721
- const changed = this._trackBox.checkBoundsOfElements();
2722
- if (changed) {
2723
- const readyForShow = this._readyForShow, isScrolling = this._$scrollingTo.getValue();
2724
- this._trackBox.changes(true, readyForShow && !isScrolling);
2725
- }
2726
- }
2727
- snappingHandler() {
2728
- const scroller = this._scrollerComponent;
2729
- if (!!scroller) {
2730
- const isVertical = this.isVertical, maxScrollSize = Math.round(isVertical ? scroller.scrollHeight ?? 0 : scroller.scrollWidth ?? 0), scrollSize = isVertical ? scroller.scrollTop ?? 0 : scroller.scrollLeft ?? 0, actualScrollSize = Math.round(scrollSize);
2731
- if (this._readyForShow && !this._isLoading) {
2732
- const isScrollEnd = (actualScrollSize >= (maxScrollSize - MIN_PIXELS_FOR_PREVENT_SNAPPING)) || !scroller.scrollable || this._trackBox.isScrollEnd;
2733
- if (isScrollEnd) {
2734
- this._$isScrollStart.next(false);
2735
- this._$isScrollEnd.next(true);
2736
- this._trackBox.isScrollStart = false;
2737
- this._trackBox.isScrollEnd = true;
2738
- }
2739
- else {
2740
- const isScrollStart = (actualScrollSize <= MIN_PIXELS_FOR_PREVENT_SNAPPING);
2741
- this._$isScrollStart.next(isScrollStart);
2742
- this._$isScrollEnd.next(false);
2743
- this._trackBox.isScrollStart = isScrollStart;
2744
- this._trackBox.isScrollEnd = false;
2745
- }
2746
- }
2747
- else if (!this._readyForShow) {
2748
- const snapScrollToStart = this._$actualSnapScrollToStart.getValue(), snapScrollToEnd = this._$actualSnapScrollToEnd.getValue();
2749
- if (!snapScrollToStart && snapScrollToEnd) {
2750
- this._$isScrollStart.next(false);
2751
- this._$isScrollEnd.next(true);
2752
- this._trackBox.isScrollStart = false;
2753
- this._trackBox.isScrollEnd = true;
2754
- }
2755
- else if (snapScrollToStart && snapScrollToEnd) {
2756
- this._$isScrollStart.next(true);
2757
- this._$isScrollEnd.next(false);
2758
- this._trackBox.isScrollStart = true;
2759
- this._trackBox.isScrollEnd = false;
2760
- }
2761
- else {
2762
- this._$isScrollStart.next(false);
2763
- this._$isScrollEnd.next(false);
2764
- this._trackBox.isScrollStart = false;
2765
- this._trackBox.isScrollEnd = false;
2766
- }
2767
- }
2768
- }
2769
- }
2770
- ;
2771
- emitScrollEvent(isScrollEnd = false, update = true, userAction = false) {
2772
- if (!this._readyForShow) {
2773
- return;
2774
- }
2775
- const scrollerEl = this._$scroller.getValue()?.nativeElement, scrollerComponent = this._scrollerComponent;
2776
- if (scrollerEl && scrollerComponent) {
2777
- const isVertical = this._isVertical, scrollSize = (isVertical ? scrollerComponent.scrollTop : scrollerComponent.scrollLeft), maxScrollSize = (isVertical ? scrollerComponent.scrollHeight : scrollerComponent.scrollWidth), bounds = this._$bounds.getValue() || { x: 0, y: 0, width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE };
2778
- const itemsRange = formatActualDisplayItems(this._service.displayItems, this._$actualScrollStartOffset.getValue(), this._$actualScrollEndOffset.getValue(), scrollSize, isVertical, bounds), event = new ScrollEvent({
2779
- direction: this._scrollerComponent?.scrollDirection ?? 0, container: scrollerEl,
2780
- list: this._$list.getValue().nativeElement, delta: this._trackBox.delta,
2781
- deltaOfNewItems: this._trackBox.deltaOfNewItems, isVertical,
2782
- scrollSize,
2783
- itemsRange,
2784
- isEnd: !scrollerComponent.scrollable || this._trackBox.isSnappedToEnd || (Math.round(scrollSize) === Math.round(maxScrollSize)),
2785
- userAction,
2786
- });
2787
- if (update) {
2788
- this._$scroll.next(event);
2789
- }
2790
- if (isScrollEnd) {
2791
- this.onScrollEnd.emit(event);
2792
- }
2793
- else {
2794
- this.onScroll.emit(event);
2795
- }
2796
- }
2797
- }
2798
- getIsSnappingMethodAdvanced(m) {
2799
- const method = m || this.snappingMethod;
2800
- return isSnappingMethodAdvenced(method);
2801
- }
2802
- getIsNoneSelection(m) {
2803
- const mode = m || this.selectingMode;
2804
- return isSelectMode(mode, SelectingModes.NONE);
2805
- }
2806
- getIsSingleSelection(m) {
2807
- const mode = m || this.selectingMode;
2808
- return isSelectMode(mode, SelectingModes.SELECT);
2809
- }
2810
- getIsMultiSelection(m) {
2811
- const mode = m || this.selectingMode;
2812
- return isSelectMode(mode, SelectingModes.MULTI_SELECT);
2813
- }
2814
- getIsNoneCollapse(m) {
2815
- const mode = m || this.collapsingMode;
2816
- return isCollapseMode(mode, CollapsingModes.NONE);
2817
- }
2818
- getIsMultipleCollapse(m) {
2819
- const mode = m || this.collapsingMode;
2820
- return isCollapseMode(mode, CollapsingModes.MULTI_COLLAPSE);
2821
- }
2822
- getIsAccordionCollapse(m) {
2823
- const mode = m || this.collapsingMode;
2824
- return isCollapseMode(mode, CollapsingModes.ACCORDION);
2825
- }
2826
- getIsVertical(d) {
2827
- const dir = d || this.direction;
2828
- return isDirection(dir, Directions.VERTICAL);
2829
- }
2830
- getIsLazy(m) {
2831
- const mode = m || this.collectionMode;
2832
- return isCollectionMode(mode, CollectionModes.LAZY);
2833
- }
2834
- createDisplayComponentsIfNeed(displayItems) {
2835
- if (!displayItems || !this._listContainerRef) {
2836
- this._trackBox.setDisplayObjectIndexMapById({});
2837
- return;
2838
- }
2839
- if (this._isSnappingMethodAdvanced && this.stickyEnabled) {
2840
- if (this._snappedDisplayComponents.length < MAX_REGULAR_SNAPED_COMPONENTS && !!this._snapContainerRef) {
2841
- while (this._snappedDisplayComponents.length < MAX_REGULAR_SNAPED_COMPONENTS) {
2842
- const comp = this._snapContainerRef.createComponent(this._itemComponentClass);
2843
- comp.instance.renderer = this._$itemRenderer.getValue();
2844
- comp.instance.regular = true;
2845
- this._snappedDisplayComponents.push(comp);
2846
- this._trackBox.snappedDisplayComponents = this._snappedDisplayComponents;
2847
- this._resizeSnappedObserver = new ResizeObserver(this._resizeSnappedComponentHandler);
2848
- this._resizeSnappedObserver.observe(comp.instance.element);
2849
- }
2850
- }
2851
- }
2852
- this._trackBox.items = displayItems;
2853
- const listContainerRef = this._listContainerRef;
2854
- const maxLength = displayItems.length, components = this._displayComponents;
2855
- if (!!listContainerRef) {
2856
- const doMap = {};
2857
- let i = 0;
2858
- for (let l = components.length; i < l; i++) {
2859
- const item = components[i];
2860
- if (!!item) {
2861
- const id = item.instance.id;
2862
- item.instance.renderer = this._$itemRenderer.getValue();
2863
- doMap[id] = i;
2864
- }
2865
- }
2866
- while (components.length < maxLength) {
2867
- const comp = listContainerRef.createComponent(this._itemComponentClass);
2868
- const id = comp.instance.id;
2869
- comp.instance.renderer = this._$itemRenderer.getValue();
2870
- doMap[id] = i;
2871
- components.push(comp);
2872
- i++;
2873
- }
2874
- this._trackBox.setDisplayObjectIndexMapById(doMap);
2875
- }
2876
- }
2877
- updateRegularRenderer() {
2878
- this._resizeSnappedComponentHandler();
2879
- }
2880
- /**
2881
- * Tracking by id
2882
- */
2883
- tracking() {
2884
- this._trackBox.track();
2885
- }
2886
- resetBoundsSize(isVertical, totalSize) {
2887
- const l = this._$list.getValue(), prop = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME, size = totalSize;
2888
- if (!!l && parseInt(l.nativeElement.style[prop]) !== size) {
2889
- l.nativeElement.style[prop] = `${size}${PX}`;
2890
- }
2891
- }
2892
- /**
2893
- * Returns the bounds of an element with a given id
2894
- */
2895
- getItemBounds(id) {
2896
- return this._service.getItemBounds(id);
2897
- }
2898
- /**
2899
- * Focus an list item by a given id.
2900
- */
2901
- focus(id, align = FocusAlignments.NONE) {
2902
- this._elementRef.nativeElement.focus();
2903
- this._service.focusById(id, align, this.scrollBehavior);
2904
- }
2905
- /**
2906
- * The method scrolls the list to the element with the given `id` and returns the value of the scrolled area.
2907
- */
2908
- scrollTo(id, cb = null, options = null) {
2909
- const behavior = options?.behavior ?? BEHAVIOR_INSTANT, blending = options?.blending ?? false, focused = options?.focused ?? true, delay = options?.delay ?? 0, iteration = options?.iteration ?? 0;
2910
- validateId(id);
2911
- validateScrollBehavior(behavior);
2912
- validateIteration(iteration);
2913
- const actualIteration = validateScrollIteration(iteration);
2914
- this._elementRef.nativeElement.focus();
2915
- if (!this._scrollerComponent?.scrollable && !this.isInfinity) {
2916
- this.scrollToFinalize(id, focused, cb);
2917
- return;
2918
- }
2919
- this._$scrollTo.next({
2920
- id, behavior, blending, delay, iteration: actualIteration, isLastIteration: actualIteration === MAX_SCROLL_TO_ITERATIONS, cb: () => {
2921
- this.scrollToFinalize(id, focused, cb);
2922
- }
2923
- });
2924
- }
2925
- /**
2926
- * Scrolls the scroll area to the first item in the collection.
2927
- */
2928
- scrollToStart(cb = null, options = null) {
2929
- const scroller = this._scrollerComponent;
2930
- if (!!scroller) {
2931
- const scrollSize = this.isVertical ? scroller.scrollTop : scroller.scrollLeft;
2932
- if (scrollSize === 0) {
2933
- return;
2934
- }
2935
- scroller.stopScrolling();
2936
- }
2937
- const behavior = options?.behavior ?? BEHAVIOR_INSTANT, blending = options?.blending ?? false, focused = options?.focused ?? true, delay = options?.delay ?? 0, iteration = options?.iteration ?? 0;
2938
- validateScrollBehavior(behavior);
2939
- validateIteration(iteration);
2940
- const trackBy = this.trackBy, items = this._$actualItems.getValue(), firstItem = items.length > 0 ? items[0] ?? null : null, id = firstItem?.[trackBy] ?? null, actualIteration = validateScrollIteration(iteration);
2941
- if (!!firstItem) {
2942
- this._elementRef.nativeElement.focus();
2943
- this._$scrollTo.next({
2944
- id, behavior, blending, delay, iteration: actualIteration, isLastIteration: actualIteration === MAX_SCROLL_TO_ITERATIONS, cb: () => {
2945
- this._$isScrollStart.next(true);
2946
- this._trackBox.isScrollStart = true;
2947
- this._trackBox.isScrollEnd = false;
2948
- this._$fireUpdate.next(true);
2949
- this.scrollToFinalize(id, focused, cb);
2950
- }
2951
- });
2952
- }
2953
- }
2954
- /**
2955
- * @deprecated
2956
- * The scrollToEndItem method is deprecated. Use the scrollToEnd method.
2957
- */
2958
- scrollToEndItem(cb, options) {
2959
- throw Error('The scrollToEndItem method is deprecated. Use the scrollToEnd method.');
2960
- }
2961
- /**
2962
- * Scrolls the list to the end of the content size.
2963
- */
2964
- scrollToEnd(cb = null, options = null) {
2965
- const scroller = this._scrollerComponent;
2966
- if (!!scroller) {
2967
- const isVertical = this.isVertical, scrollSize = isVertical ? scroller.scrollTop : scroller.scrollLeft, maxScrollSize = isVertical ? scroller.scrollHeight : scroller.scrollTop;
2968
- if (scrollSize === maxScrollSize) {
2969
- return;
2970
- }
2971
- scroller.stopScrolling();
2972
- }
2973
- const behavior = options?.behavior ?? BEHAVIOR_INSTANT, blending = options?.blending ?? false, focused = options?.focused ?? true, delay = options?.delay ?? 0, iteration = options?.iteration ?? 0;
2974
- validateScrollBehavior(behavior);
2975
- validateIteration(iteration);
2976
- const trackBy = this.trackBy, items = this._$actualItems.getValue(), latItem = items[items.length > 0 ? items.length - 1 : 0], id = latItem?.[trackBy] ?? null, actualIteration = validateScrollIteration(iteration);
2977
- if (latItem === null) {
2978
- return;
2979
- }
2980
- this._elementRef.nativeElement.focus();
2981
- if (!this._scrollerComponent?.scrollable) {
2982
- this.scrollToFinalize(id, focused, cb);
2983
- return;
2984
- }
2985
- this._$scrollTo.next({
2986
- id, behavior, blending, delay, iteration: actualIteration, isLastIteration: actualIteration === MAX_SCROLL_TO_ITERATIONS, cb: () => {
2987
- this._$isScrollEnd.next(true);
2988
- this._trackBox.isScrollStart = false;
2989
- this._trackBox.isScrollEnd = true;
2990
- this._$fireUpdate.next(true);
2991
- this.scrollToFinalize(id, focused, cb);
2992
- }
2993
- });
2994
- }
2995
- scrollToFinalize(id, focused, cb) {
2996
- if (focused) {
2997
- const el = this._service.getFocusedElementById(id);
2998
- if (!!el) {
2999
- this._service.focus(el, FocusAlignments.NONE);
3000
- }
3001
- }
3002
- if (typeof cb === 'function') {
3003
- cb?.();
3004
- }
3005
- }
3006
- cleanup() {
3007
- const displayItems = [];
3008
- this._service.collection = displayItems;
3009
- this.createDisplayComponentsIfNeed(displayItems);
3010
- this.tracking();
3011
- this.emitScrollEvent(true, false, false);
3012
- }
3013
- /**
3014
- * Force clearing the cache.
3015
- */
3016
- cacheClean() {
3017
- this._cached = false;
3018
- if (this.dynamicSize) {
3019
- this._trackBox.cacheClean();
3020
- }
3021
- const prerenderContainer = this._prerender;
3022
- if (!!prerenderContainer) {
3023
- prerenderContainer.clear();
3024
- prerenderContainer.off();
3025
- }
3026
- this._$collapsedItemIds.next([]);
3027
- this._$isScrollStart.next(true);
3028
- this._$isScrollEnd.next(false);
3029
- this._$totalSize.next(0);
3030
- this._$scrollSize.next(0);
3031
- const scroller = this._scrollerComponent;
3032
- if (!!scroller) {
3033
- scroller.reset();
3034
- }
3035
- }
3036
- /**
3037
- * @deprecated
3038
- * The stopSnappingScrollToEnd method is deprecated. Use the preventSnapping method.
3039
- */
3040
- stopSnappingScrollToEnd() {
3041
- throw Error('The stopSnappingScrollToEnd method is deprecated. Use the preventSnapping method.');
3042
- }
3043
- /**
3044
- * Prevents the list from snapping to its start or end edge.
3045
- */
3046
- preventSnapping() {
3047
- if (!this._readyForShow) {
3048
- return;
3049
- }
3050
- const scroller = this._scrollerComponent;
3051
- this._$isScrollStart.next(false);
3052
- this._$isScrollEnd.next(false);
3053
- this._trackBox.preventScrollSnapping(true);
3054
- if (scroller) {
3055
- scroller.stopScrolling();
3056
- }
3057
- }
3058
- ngOnDestroy() {
3059
- super.ngOnDestroy();
3060
- this.dispose();
3061
- }
3062
- dispose() {
3063
- this._$destroy.next();
3064
- const updateId = this._updateId;
3065
- if (updateId !== undefined) {
3066
- cancelAnimationFrame(updateId);
3067
- this._updateId = undefined;
3068
- }
3069
- if (this._service) {
3070
- this._service.dispose();
3071
- }
3072
- if (!!this._trackBox) {
3073
- this._trackBox.dispose();
3074
- }
3075
- if (!!this._resizeSnappedObserver) {
3076
- this._resizeSnappedObserver.disconnect();
3077
- }
3078
- if (!!this._snappedDisplayComponents) {
3079
- while (this._snappedDisplayComponents.length > 0) {
3080
- const comp = this._snappedDisplayComponents.shift();
3081
- comp?.destroy();
3082
- }
3083
- }
3084
- if (this._displayComponents) {
3085
- while (this._displayComponents.length > 0) {
3086
- const comp = this._displayComponents.shift();
3087
- comp?.destroy();
3088
- }
3089
- }
3090
- }
3091
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NgVirtualListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3092
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { scrollbarThickness: "scrollbarThickness", scrollbarMinSize: "scrollbarMinSize", scrollbarThumbRenderer: "scrollbarThumbRenderer", scrollbarThumbParams: "scrollbarThumbParams", loading: "loading", waitForPreparation: "waitForPreparation", clickDistance: "clickDistance", items: "items", selectedIds: "selectedIds", defaultItemValue: "defaultItemValue", collapsedIds: "collapsedIds", selectByClick: "selectByClick", collapseByClick: "collapseByClick", snap: "snap", stickyEnabled: "stickyEnabled", snapToEndTransitionInstantOffset: "snapToEndTransitionInstantOffset", scrollStartOffset: "scrollStartOffset", scrollEndOffset: "scrollEndOffset", snapScrollToStart: "snapScrollToStart", snapScrollToEnd: "snapScrollToEnd", snapScrollToBottom: "snapScrollToBottom", scrollbarEnabled: "scrollbarEnabled", scrollbarInteractive: "scrollbarInteractive", overlappingScrollbar: "overlappingScrollbar", scrollBehavior: "scrollBehavior", scrollingSettings: "scrollingSettings", itemTransform: "itemTransform", snapToItem: "snapToItem", snapToItemAlign: "snapToItemAlign", snappingDistance: "snappingDistance", scrollingOneByOne: "scrollingOneByOne", alignment: "alignment", zIndexWhenSelecting: "zIndexWhenSelecting", spreadingMode: "spreadingMode", divides: "divides", motionBlur: "motionBlur", maxMotionBlur: "maxMotionBlur", motionBlurEnabled: "motionBlurEnabled", animationParams: "animationParams", overscrollEnabled: "overscrollEnabled", enabledBufferOptimization: "enabledBufferOptimization", itemRenderer: "itemRenderer", itemConfigMap: "itemConfigMap", itemSize: "itemSize", minItemSize: "minItemSize", maxItemSize: "maxItemSize", dynamicSize: "dynamicSize", direction: "direction", collectionMode: "collectionMode", bufferSize: "bufferSize", maxBufferSize: "maxBufferSize", snappingMethod: "snappingMethod", collapsingMode: "collapsingMode", methodForSelecting: "methodForSelecting", selectingMode: "selectingMode", trackBy: "trackBy", screenReaderMessage: "screenReaderMessage", langTextDir: "langTextDir" }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd", onViewportChange: "onViewportChange", onSnapItem: "onSnapItem", onItemClick: "onItemClick", onSelect: "onSelect", onCollapse: "onCollapse", onScrollReachStart: "onScrollReachStart", onScrollReachEnd: "onScrollReachEnd" }, host: { styleAttribute: "position: relative;" }, providers: [NgVirtualListService, NgVirtualListPublicService], viewQueries: [{ propertyName: "_prerender", first: true, predicate: ["prerender"], descendants: true, read: NgPrerenderContainer }, { propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_scrollerComponent", first: true, predicate: ["scroller"], descendants: true, read: NgScrollerComponent }], usesInheritance: true, ngImport: i0, template: "<div aria-live=\"polite\" aria-atomic=\"true\" class=\"ngvl__screen-reader\">\r\n {{ $screenReaderFormattedMessage | async }}\r\n</div>\r\n\r\n<ng-prerender-container #prerender [bounds]=\"($bounds | async)!\" [direction]=\"($direction | async)!\"\r\n [dynamic]=\"($dynamicSize | async)!\" [divides]=\"($divides | async)!\" [isVertical]=\"($isVertical | async)!\"\r\n [itemSize]=\"($actualItemSize | async)!\" [trackBy]=\"($trackBy | async)!\" [itemRenderer]=\"($itemRenderer | async)!\"\r\n [startOffset]=\"($startOffset | async)!\" [endOffset]=\"($endOffset | async)!\"\r\n [scrollbarEnabled]=\"(scroller.$scrollbarShow | async)!\"\r\n [enabled]=\"($prerenderEnabled | async)!\"></ng-prerender-container>\r\n\r\n<ng-container *ngIf=\"($stickyEnabled | async)!\">\r\n <div localeSensitive [langTextDir]=\"($langTextDir | async)!\" #snappedContainer class=\"ngvl__snapped-container\"\r\n [ngClass]=\"($classes | async)\">\r\n <div #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>\r\n\r\n<ng-scroller #scroller class=\"ngvl__list-scroller\" [classes]=\"($classes | async)!\"\r\n [startOffset]=\"($startOffset | async)!\" [endOffset]=\"($endOffset | async)!\"\r\n [alignmentStartOffset]=\"($alignmentScrollStartOffset | async)!\"\r\n [alignmentEndOffset]=\"($alignmentScrollEndOffset | async)!\" [direction]=\"($direction | async)!\"\r\n [scrollbarThumbRenderer]=\"($scrollbarThumbRenderer | async)!\" [isInfinity]=\"($isInfinity | async)!\"\r\n [scrollbarThickness]=\"($scrollbarThickness | async)!\" [scrollbarThumbParams]=\"($scrollbarThumbParams | async)!\"\r\n [animationParams]=\"($animationParams | async)!\" [focusedElement]=\"($focusedElement | async)!\"\r\n [loading]=\"($loading | async)!\" [overscrollEnabled]=\"($overscrollEnabled | async)!\"\r\n [snappingDistance]=\"($snappingDistance | async)!\" [overlappingScrollbar]=\"($overlappingScrollbar | async)!\"\r\n [scrollbarEnabled]=\"($actualScrollbarEnabled | async)!\" [scrollbarInteractive]=\"($scrollbarInteractive | async)!\"\r\n [snapToItem]=\"($snapToItem | async)!\" [snapToItemAlign]=\"($snapToItemAlign | async)!\"\r\n [scrollbarMinSize]=\"($scrollbarMinSize | async)!\" [scrollBehavior]=\"($scrollBehavior | async)!\"\r\n [scrollingSettings]=\"($scrollingSettings | async)!\" [scrollingOneByOne]=\"($scrollingOneByOne | async)!\"\r\n [motionBlur]=\"($motionBlur | async)!\" [maxMotionBlur]=\"($maxMotionBlur | async)!\"\r\n [motionBlurEnabled]=\"($motionBlurEnabled | async)!\">\r\n <ng-container #renderersContainer></ng-container>\r\n</ng-scroller>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.vertical){height:320px}.ngvl__snapped-container{position:relative;width:100%;opacity:0}.ngvl__snapped-container.prepared{opacity:1}.ngvl__list-snapper{-webkit-tap-highlight-color:transparent;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list-scroller{-webkit-tap-highlight-color:transparent;position:absolute;left:0;top:0;width:100%;height:100%;z-index:0}.ngvl__screen-reader{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.NgScrollerComponent, selector: "ng-scroller", inputs: ["scrollbarEnabled", "scrollbarInteractive", "focusedElement", "overlappingScrollbar", "content", "loading", "classes", "scrollbarMinSize", "scrollbarThickness", "scrollbarThumbRenderer", "scrollbarThumbParams", "motionBlur", "maxMotionBlur", "motionBlurEnabled"], outputs: ["onScrollbarVisible"] }, { kind: "component", type: i3.NgPrerenderContainer, selector: "ng-prerender-container", inputs: ["enabled", "direction", "isVertical", "scrollbarEnabled", "startOffset", "endOffset", "bounds", "dynamic", "itemSize", "trackBy", "divides"] }, { kind: "directive", type: i4.LocaleSensitiveDirective, selector: "[localeSensitive]", inputs: ["langTextDir", "listDir"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
3093
- }
3094
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NgVirtualListComponent, decorators: [{
3095
- type: Component,
3096
- args: [{ selector: 'ng-virtual-list', host: {
3097
- 'style': 'position: relative;'
3098
- }, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, providers: [NgVirtualListService, NgVirtualListPublicService], template: "<div aria-live=\"polite\" aria-atomic=\"true\" class=\"ngvl__screen-reader\">\r\n {{ $screenReaderFormattedMessage | async }}\r\n</div>\r\n\r\n<ng-prerender-container #prerender [bounds]=\"($bounds | async)!\" [direction]=\"($direction | async)!\"\r\n [dynamic]=\"($dynamicSize | async)!\" [divides]=\"($divides | async)!\" [isVertical]=\"($isVertical | async)!\"\r\n [itemSize]=\"($actualItemSize | async)!\" [trackBy]=\"($trackBy | async)!\" [itemRenderer]=\"($itemRenderer | async)!\"\r\n [startOffset]=\"($startOffset | async)!\" [endOffset]=\"($endOffset | async)!\"\r\n [scrollbarEnabled]=\"(scroller.$scrollbarShow | async)!\"\r\n [enabled]=\"($prerenderEnabled | async)!\"></ng-prerender-container>\r\n\r\n<ng-container *ngIf=\"($stickyEnabled | async)!\">\r\n <div localeSensitive [langTextDir]=\"($langTextDir | async)!\" #snappedContainer class=\"ngvl__snapped-container\"\r\n [ngClass]=\"($classes | async)\">\r\n <div #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n </div>\r\n </div>\r\n</ng-container>\r\n\r\n<ng-scroller #scroller class=\"ngvl__list-scroller\" [classes]=\"($classes | async)!\"\r\n [startOffset]=\"($startOffset | async)!\" [endOffset]=\"($endOffset | async)!\"\r\n [alignmentStartOffset]=\"($alignmentScrollStartOffset | async)!\"\r\n [alignmentEndOffset]=\"($alignmentScrollEndOffset | async)!\" [direction]=\"($direction | async)!\"\r\n [scrollbarThumbRenderer]=\"($scrollbarThumbRenderer | async)!\" [isInfinity]=\"($isInfinity | async)!\"\r\n [scrollbarThickness]=\"($scrollbarThickness | async)!\" [scrollbarThumbParams]=\"($scrollbarThumbParams | async)!\"\r\n [animationParams]=\"($animationParams | async)!\" [focusedElement]=\"($focusedElement | async)!\"\r\n [loading]=\"($loading | async)!\" [overscrollEnabled]=\"($overscrollEnabled | async)!\"\r\n [snappingDistance]=\"($snappingDistance | async)!\" [overlappingScrollbar]=\"($overlappingScrollbar | async)!\"\r\n [scrollbarEnabled]=\"($actualScrollbarEnabled | async)!\" [scrollbarInteractive]=\"($scrollbarInteractive | async)!\"\r\n [snapToItem]=\"($snapToItem | async)!\" [snapToItemAlign]=\"($snapToItemAlign | async)!\"\r\n [scrollbarMinSize]=\"($scrollbarMinSize | async)!\" [scrollBehavior]=\"($scrollBehavior | async)!\"\r\n [scrollingSettings]=\"($scrollingSettings | async)!\" [scrollingOneByOne]=\"($scrollingOneByOne | async)!\"\r\n [motionBlur]=\"($motionBlur | async)!\" [maxMotionBlur]=\"($maxMotionBlur | async)!\"\r\n [motionBlurEnabled]=\"($motionBlurEnabled | async)!\">\r\n <ng-container #renderersContainer></ng-container>\r\n</ng-scroller>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.vertical){height:320px}.ngvl__snapped-container{position:relative;width:100%;opacity:0}.ngvl__snapped-container.prepared{opacity:1}.ngvl__list-snapper{-webkit-tap-highlight-color:transparent;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list-scroller{-webkit-tap-highlight-color:transparent;position:absolute;left:0;top:0;width:100%;height:100%;z-index:0}.ngvl__screen-reader{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
3099
- }], ctorParameters: () => [], propDecorators: { _prerender: [{
3100
- type: ViewChild,
3101
- args: ['prerender', { read: NgPrerenderContainer }]
3102
- }], _listContainerRef: [{
3103
- type: ViewChild,
3104
- args: ['renderersContainer', { read: ViewContainerRef }]
3105
- }], _snapContainerRef: [{
3106
- type: ViewChild,
3107
- args: ['snapRendererContainer', { read: ViewContainerRef }]
3108
- }], _scrollerComponent: [{
3109
- type: ViewChild,
3110
- args: ['scroller', { read: NgScrollerComponent }]
3111
- }], onScroll: [{
3112
- type: Output
3113
- }], onScrollEnd: [{
3114
- type: Output
3115
- }], onViewportChange: [{
3116
- type: Output
3117
- }], onSnapItem: [{
3118
- type: Output
3119
- }], onItemClick: [{
3120
- type: Output
3121
- }], onSelect: [{
3122
- type: Output
3123
- }], onCollapse: [{
3124
- type: Output
3125
- }], onScrollReachStart: [{
3126
- type: Output
3127
- }], onScrollReachEnd: [{
3128
- type: Output
3129
- }], scrollbarThickness: [{
3130
- type: Input
3131
- }], scrollbarMinSize: [{
3132
- type: Input
3133
- }], scrollbarThumbRenderer: [{
3134
- type: Input
3135
- }], scrollbarThumbParams: [{
3136
- type: Input
3137
- }], loading: [{
3138
- type: Input
3139
- }], waitForPreparation: [{
3140
- type: Input
3141
- }], clickDistance: [{
3142
- type: Input
3143
- }], items: [{
3144
- type: Input
3145
- }], selectedIds: [{
3146
- type: Input
3147
- }], defaultItemValue: [{
3148
- type: Input
3149
- }], collapsedIds: [{
3150
- type: Input
3151
- }], selectByClick: [{
3152
- type: Input
3153
- }], collapseByClick: [{
3154
- type: Input
3155
- }], snap: [{
3156
- type: Input
3157
- }], stickyEnabled: [{
3158
- type: Input
3159
- }], snapToEndTransitionInstantOffset: [{
3160
- type: Input
3161
- }], scrollStartOffset: [{
3162
- type: Input
3163
- }], scrollEndOffset: [{
3164
- type: Input
3165
- }], snapScrollToStart: [{
3166
- type: Input
3167
- }], snapScrollToEnd: [{
3168
- type: Input
3169
- }], snapScrollToBottom: [{
3170
- type: Input
3171
- }], scrollbarEnabled: [{
3172
- type: Input
3173
- }], scrollbarInteractive: [{
3174
- type: Input
3175
- }], overlappingScrollbar: [{
3176
- type: Input
3177
- }], scrollBehavior: [{
3178
- type: Input
3179
- }], scrollingSettings: [{
3180
- type: Input
3181
- }], itemTransform: [{
3182
- type: Input
3183
- }], snapToItem: [{
3184
- type: Input
3185
- }], snapToItemAlign: [{
3186
- type: Input
3187
- }], snappingDistance: [{
3188
- type: Input
3189
- }], scrollingOneByOne: [{
3190
- type: Input
3191
- }], alignment: [{
3192
- type: Input
3193
- }], zIndexWhenSelecting: [{
3194
- type: Input
3195
- }], spreadingMode: [{
3196
- type: Input
3197
- }], divides: [{
3198
- type: Input
3199
- }], motionBlur: [{
3200
- type: Input
3201
- }], maxMotionBlur: [{
3202
- type: Input
3203
- }], motionBlurEnabled: [{
3204
- type: Input
3205
- }], animationParams: [{
3206
- type: Input
3207
- }], overscrollEnabled: [{
3208
- type: Input
3209
- }], enabledBufferOptimization: [{
3210
- type: Input
3211
- }], itemRenderer: [{
3212
- type: Input
3213
- }], itemConfigMap: [{
3214
- type: Input
3215
- }], itemSize: [{
3216
- type: Input
3217
- }], minItemSize: [{
3218
- type: Input
3219
- }], maxItemSize: [{
3220
- type: Input
3221
- }], dynamicSize: [{
3222
- type: Input
3223
- }], direction: [{
3224
- type: Input
3225
- }], collectionMode: [{
3226
- type: Input
3227
- }], bufferSize: [{
3228
- type: Input
3229
- }], maxBufferSize: [{
3230
- type: Input
3231
- }], snappingMethod: [{
3232
- type: Input
3233
- }], collapsingMode: [{
3234
- type: Input
3235
- }], methodForSelecting: [{
3236
- type: Input
3237
- }], selectingMode: [{
3238
- type: Input
3239
- }], trackBy: [{
3240
- type: Input
3241
- }], screenReaderMessage: [{
3242
- type: Input
3243
- }], langTextDir: [{
3244
- type: Input
3245
- }] } });
3246
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctdmlydHVhbC1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25nLXZpcnR1YWwtbGlzdC9zcmMvbGliL25nLXZpcnR1YWwtbGlzdC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy12aXJ0dWFsLWxpc3Qvc3JjL2xpYi9uZy12aXJ0dWFsLWxpc3QuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUFFLFNBQVMsRUFBZ0IsVUFBVSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUM5RSxNQUFNLEVBQWUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixHQUMvRSxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsZUFBZSxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUVqRyxFQUFFLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxHQUFHLEdBQ25ELE1BQU0sTUFBTSxDQUFDO0FBQ2QsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sMERBQTBELENBQUM7QUFDdEcsT0FBTyxFQUNMLGdCQUFnQixFQUFFLHFCQUFxQixFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixFQUFFLG9CQUFvQixFQUNyRyxtQ0FBbUMsRUFBRSxpQkFBaUIsRUFBRSxtQkFBbUIsRUFBRSxpQkFBaUIsRUFBRSxzQkFBc0IsRUFBRSx1QkFBdUIsRUFDL0ksZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLHdCQUF3QixFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLHNCQUFzQixFQUFFLGVBQWUsRUFDN0gsdUJBQXVCLEVBQUUsdUJBQXVCLEVBQUUsdUJBQXVCLEVBQUUseUJBQXlCLEVBQUUsdUJBQXVCLEVBQzdILDZCQUE2QixFQUFFLDZDQUE2QyxFQUFFLHlCQUF5QixFQUFFLCtCQUErQixFQUN4SSxVQUFVLEVBQUUsV0FBVyxFQUFFLHFCQUFxQixFQUFFLHNCQUFzQixFQUFFLDRCQUE0QixFQUFFLDJCQUEyQixFQUNqSSwwQkFBMEIsRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFLHlCQUF5QixFQUFFLDZCQUE2QixFQUFFLDBCQUEwQixFQUN6SSx3QkFBd0IsRUFBRSx1QkFBdUIsRUFBRSwyQkFBMkIsRUFBRSwwQkFBMEIsRUFBRSw2QkFBNkIsRUFDekksa0JBQWtCLEVBQUUsMkJBQTJCLEVBQUUsYUFBYSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsaURBQWlELEVBQ3JJLG1DQUFtQyxFQUFFLDRDQUE0QyxFQUFFLHFDQUFxQyxFQUN4SCw4Q0FBOEMsRUFBRSxrREFBa0QsRUFBRSwwQkFBMEIsRUFDOUgsb0JBQW9CLEVBQUUsMEJBQTBCLEVBQUUsUUFBUSxFQUFFLG1CQUFtQixFQUFFLHVCQUF1QixFQUFFLDRCQUE0QixFQUN0SSwyQkFBMkIsRUFBRSxlQUFlLEVBQUUseUJBQXlCLEVBQUUscUJBQXFCLEVBQUUscUJBQXFCLEVBQ3JILGlCQUFpQixFQUFFLHdCQUF3QixFQUFFLHNCQUFzQixFQUFFLDZCQUE2QixFQUNsRyw2QkFBNkIsR0FDOUIsTUFBTSxTQUFTLENBQUM7QUFhakIsT0FBTyxFQUNMLFVBQVUsRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLGVBQWUsRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLGNBQWMsRUFBRSxjQUFjLEdBQzVJLE1BQU0sU0FBUyxDQUFDO0FBQ2pCLE9BQU8sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLGVBQWUsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHbkUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDMUQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDcEUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNwQyxPQUFPLEVBQ0wsYUFBYSxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLGNBQWMsRUFBRSxjQUFjLEdBQzdHLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0RBQWdELENBQUM7QUFFckYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0VBQXNFLENBQUM7QUFFNUcsT0FBTyxFQUFFLHdCQUF3QixFQUFFLHlCQUF5QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDdEcsT0FBTyxFQUFFLFVBQVUsRUFBRSxpQkFBaUIsRUFBRSxzQkFBc0IsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pILE9BQU8sRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDeEgsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDOUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDaEUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDaEYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbkUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUMxQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFNUQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDekUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sOEJBQThCLENBQUM7Ozs7OztBQUVuRTs7Ozs7OztHQU9HO0FBYUgsTUFBTSxPQUFPLHNCQUF1QixTQUFRLG1CQUFtQjtJQUNyRCxNQUFNLENBQUMsUUFBUSxHQUFXLENBQUMsQ0FBQztJQUU1QixHQUFHLEdBQVcsc0JBQXNCLENBQUMsUUFBUSxDQUFDO0lBRXREOztPQUVHO0lBQ0gsSUFBSSxFQUFFLEtBQUssT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUVyQixRQUFRLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFHeEMsVUFBVSxDQUFtQztJQUc3QyxpQkFBaUIsQ0FBK0I7SUFHaEQsaUJBQWlCLENBQStCO0lBR2hELGtCQUFrQixDQUFrQztJQUVwRCxVQUFVLEdBQUcsSUFBSSxlQUFlLENBQXlDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pFLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRXRELE1BQU0sR0FBRyxJQUFJLGVBQWUsQ0FBeUMsU0FBUyxDQUFDLENBQUM7SUFDckUsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFdEQ7O09BRUc7SUFFSCxRQUFRLEdBQUcsSUFBSSxZQUFZLEVBQWdCLENBQUM7SUFFNUM7O09BRUc7SUFFSCxXQUFXLEdBQUcsSUFBSSxZQUFZLEVBQWdCLENBQUM7SUFFL0M7O09BRUc7SUFFSCxnQkFBZ0IsR0FBRyxJQUFJLFlBQVksRUFBUyxDQUFDO0lBRTdDOztPQUVHO0lBRUgsVUFBVSxHQUFHLElBQUksWUFBWSxFQUFNLENBQUM7SUFFcEM7O09BRUc7SUFFSCxXQUFXLEdBQUcsSUFBSSxZQUFZLEVBQXNDLENBQUM7SUFFckU7O09BRUc7SUFFSCxRQUFRLEdBQUcsSUFBSSxZQUFZLEVBQXlCLENBQUM7SUFFckQ7O09BRUc7SUFFSCxVQUFVLEdBQUcsSUFBSSxZQUFZLEVBQWEsQ0FBQztJQUUzQzs7T0FFRztJQUVILGtCQUFrQixHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7SUFFOUM7O09BRUc7SUFFSCxnQkFBZ0IsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO0lBRXBDLE1BQU0sR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUM1QyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUVwQyxhQUFhLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDbkQsWUFBWSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFbEQsb0JBQW9CLEdBQUcsSUFBSSxlQUFlLENBQVMsMkJBQTJCLENBQUMsQ0FBQztJQUNyRSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFMUUsNEJBQTRCLEdBQUcsQ0FBQyxDQUFTLEVBQUUsRUFBRTtRQUNuRCxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRW5DLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsOERBQThELENBQUMsQ0FBQztZQUM5RSxPQUFPLDJCQUEyQixDQUFDO1FBQ3JDLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOztPQUVHO0lBQ0gsSUFDSSxrQkFBa0IsQ0FBQyxDQUFTO1FBQzlCLElBQUksSUFBSSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQy9DLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsNEJBQTRCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFOUQsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxrQkFBa0IsS0FBSyxPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFakUsa0JBQWtCLEdBQUcsSUFBSSxlQUFlLENBQVMsMEJBQTBCLENBQUMsQ0FBQztJQUNsRSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFdEUsMEJBQTBCLEdBQUcsQ0FBQyxDQUFTLEVBQUUsRUFBRTtRQUNqRCxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFN0IsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyw0REFBNEQsQ0FBQyxDQUFDO1lBQzVFLE9BQU8sMEJBQTBCLENBQUM7UUFDcEMsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7O09BRUc7SUFDSCxJQUNJLGdCQUFnQixDQUFDLENBQVM7UUFDNUIsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDN0MsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU1RCxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDakQsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLGdCQUFnQixLQUFLLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsRUFBWSxDQUFDLENBQUMsQ0FBQztJQUV2RSx3QkFBd0IsR0FBRyxJQUFJLGVBQWUsQ0FBMEIsSUFBSSxDQUFDLENBQUM7SUFDbkUsdUJBQXVCLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRWxGLGdDQUFnQyxHQUFHLENBQUMsQ0FBMEIsRUFBRSxFQUFFO1FBQ3hFLE1BQU0sS0FBSyxHQUFHLGNBQWMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTVDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsa0VBQWtFLENBQUMsQ0FBQztZQUNsRixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOztPQUVHO0lBQ0gsSUFDSSxzQkFBc0IsQ0FBQyxDQUEwQjtRQUNuRCxJQUFJLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNuRCxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGdDQUFnQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWxFLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksc0JBQXNCLEtBQUssT0FBTyxJQUFJLENBQUMsd0JBQXdCLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRXpFLHNCQUFzQixHQUFHLElBQUksZUFBZSxDQUFxQyxFQUFFLENBQUMsQ0FBQztJQUMxRSxxQkFBcUIsR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFOUUsOEJBQThCLEdBQUcsQ0FBQyxDQUFxQyxFQUFFLEVBQUU7UUFDakYsTUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFNUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyxnRUFBZ0UsQ0FBQyxDQUFDO1lBQ2hGLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7O09BRUc7SUFDSCxJQUNJLG9CQUFvQixDQUFDLENBQXFDO1FBQzVELElBQUksSUFBSSxDQUFDLHNCQUFzQixDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ2pELE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsOEJBQThCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFaEUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxvQkFBb0IsS0FBSyxPQUFPLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFckUsUUFBUSxHQUFHO1FBQ2pCLFNBQVMsRUFBRSxDQUFDLENBQVUsRUFBRSxFQUFFO1lBQ3hCLE1BQU0sS0FBSyxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUVqQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO2dCQUNwRSxPQUFPLEtBQUssQ0FBQztZQUNmLENBQUM7WUFDRCxPQUFPLENBQUMsQ0FBQztRQUNYLENBQUM7S0FDSyxDQUFDO0lBRUQsU0FBUyxHQUFHLElBQUksZUFBZSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBQ3JDLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRXBELGlCQUFpQixHQUFHLENBQUMsQ0FBVSxFQUFFLEVBQUU7UUFDekMsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWpDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztZQUNwRSxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOztPQUVHO0lBQ0gsSUFDSSxPQUFPLENBQUMsQ0FBVTtRQUNwQixJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDcEMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVuRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxPQUFPLEtBQUssT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBYSxDQUFDLENBQUMsQ0FBQztJQUV0RCxvQkFBb0IsR0FBRyxJQUFJLGVBQWUsQ0FBVSw0QkFBNEIsQ0FBQyxDQUFDO0lBQ3ZFLG1CQUFtQixHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUUxRSw0QkFBNEIsR0FBRyxDQUFDLENBQVUsRUFBRSxFQUFFO1FBQ3BELE1BQU0sS0FBSyxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVoQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLCtEQUErRCxDQUFDLENBQUM7WUFDL0UsT0FBTyw0QkFBNEIsQ0FBQztRQUN0QyxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7T0FFRztJQUNILElBQ0ksa0JBQWtCLENBQUMsQ0FBVTtRQUMvQixJQUFJLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMvQyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLDRCQUE0QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTlELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksa0JBQWtCLEtBQUssT0FBTyxJQUFJLENBQUMsb0JBQW9CLENBQUMsUUFBUSxFQUFhLENBQUMsQ0FBQyxDQUFDO0lBRTVFLGVBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBUyxzQkFBc0IsQ0FBQyxDQUFDO0lBQzNELGNBQWMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRWhFLHVCQUF1QixHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUU7UUFDOUMsTUFBTSxLQUFLLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTdCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMseURBQXlELENBQUMsQ0FBQztZQUN6RSxPQUFPLHNCQUFzQixDQUFDO1FBQ2hDLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOztPQUVHO0lBQ0gsSUFDSSxhQUFhLENBQUMsQ0FBUztRQUN6QixJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDMUMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV6RCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxhQUFhLEtBQUssT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBWSxDQUFDLENBQUMsQ0FBQztJQUVqRSxPQUFPLEdBQUcsSUFBSSxlQUFlLENBQXlCLEVBQUUsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRWhELGVBQWUsR0FBRyxDQUFDLENBQXlCLEVBQUUsRUFBRTtRQUN0RCxJQUFJLEtBQUssR0FBRyxhQUFhLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN6QyxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1YsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDTixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUM3QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7b0JBQ3pDLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDbEIsS0FBSyxHQUFHLGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO29CQUN6QyxJQUFJLEtBQUssRUFBRSxDQUFDO3dCQUNWLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFXLEVBQUUsSUFBSSxDQUFDLElBQUksY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDLE9BQU8sQ0FBVyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7NEJBQ3ZILEtBQUssR0FBRyxLQUFLLENBQUM7NEJBQ2QsTUFBTTt3QkFDUixDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQywyRUFBMkUsQ0FBQyxDQUFDO1lBQzNGLE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7O09BRUc7SUFDSCxJQUNJLEtBQUssQ0FBQyxDQUF5QjtRQUNqQyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDbEMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFakQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksS0FBSyxLQUFLLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQTRCLENBQUMsQ0FBQyxDQUFDO0lBRWpFLGFBQWEsR0FBRyxJQUFJLGVBQWUsQ0FBd0IsSUFBSSxDQUFDLENBQUM7SUFDdEQsWUFBWSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFNUQscUJBQXFCLEdBQUcsQ0FBQyxDQUF3QixFQUFFLEVBQUU7UUFDM0QsSUFBSSxLQUFLLEdBQUcsYUFBYSxDQUFDLENBQVEsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksY0FBYyxDQUFDLENBQVEsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksYUFBYSxDQUFDLENBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN6SCxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1YsSUFBSSxDQUFDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUMxQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7b0JBQ3pDLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDbEIsS0FBSyxHQUFHLGNBQWMsQ0FBQyxJQUFXLENBQUMsSUFBSSxhQUFhLENBQUMsSUFBVyxDQUFDLENBQUM7b0JBQ2xFLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQzt3QkFDWCxNQUFNO29CQUNSLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyx5RUFBeUUsQ0FBQyxDQUFDO1lBQ3pGLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUM1QyxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7T0FFRztJQUNILElBQ0ksV0FBVyxDQUFDLENBQXdCO1FBQ3RDLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN4QyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXZELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLFdBQVcsS0FBSyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRW5ELGtCQUFrQixHQUFHLElBQUksZUFBZSxDQUEwQixJQUFJLENBQUMsQ0FBQztJQUM3RCxpQkFBaUIsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFOUUsSUFDSSxnQkFBZ0IsQ0FBQyxDQUEwQjtRQUM3QyxJQUFJLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM3QyxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLGdCQUFnQixLQUFLLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUU3RCxjQUFjLEdBQUcsSUFBSSxlQUFlLENBQVksRUFBRSxDQUFDLENBQUM7SUFDekMsYUFBYSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFOUQsc0JBQXNCLEdBQUcsQ0FBQyxDQUFZLEVBQUUsRUFBRTtRQUNoRCxJQUFJLEtBQUssR0FBRyxhQUFhLENBQUMsQ0FBUSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNoRCxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1YsSUFBSSxDQUFDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUMxQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7b0JBQ3pDLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDbEIsS0FBSyxHQUFHLGNBQWMsQ0FBQyxJQUFXLENBQUMsSUFBSSxhQUFhLENBQUMsSUFBVyxDQUFDLENBQUM7b0JBQ2xFLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQzt3QkFDWCxNQUFNO29CQUNSLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQywyREFBMkQsQ0FBQyxDQUFDO1lBQzNFLE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7O09BRUc7SUFDSCxJQUNJLFlBQVksQ0FBQyxDQUFZO1FBQzNCLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN6QyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXhELElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLFlBQVksS0FBSyxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRXJELGVBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBVSx1QkFBdUIsQ0FBQyxDQUFDO0lBQzdELGNBQWMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRWhFLHVCQUF1QixHQUFHLENBQUMsQ0FBVSxFQUFFLEVBQUU7UUFDL0MsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWpDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsMERBQTBELENBQUMsQ0FBQztZQUMxRSxPQUFPLHVCQUF1QixDQUFDO1FBQ2pDLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOzs7T0FHRztJQUNILElBQ0ksYUFBYSxDQUFDLENBQVU7UUFDMUIsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzFDLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFekQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksYUFBYSxLQUFLLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFdkQsaUJBQWlCLEdBQUcsSUFBSSxlQUFlLENBQVUseUJBQXlCLENBQUMsQ0FBQztJQUNqRSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFcEUseUJBQXlCLEdBQUcsQ0FBQyxDQUFVLEVBQUUsRUFBRTtRQUNqRCxNQUFNLEtBQUssR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFakMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyw0REFBNEQsQ0FBQyxDQUFDO1lBQzVFLE9BQU8seUJBQXlCLENBQUM7UUFDbkMsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7OztPQUdHO0lBQ0gsSUFDSSxlQUFlLENBQUMsQ0FBVTtRQUM1QixJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM1QyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTNELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksZUFBZSxLQUFLLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUVuRTs7O09BR0c7SUFDSCxJQUNJLElBQUksQ0FBQyxDQUFVO1FBQ2pCLE1BQU0sS0FBSyxDQUFDLDBFQUEwRSxDQUFDLENBQUM7SUFDMUYsQ0FBQztJQUFBLENBQUM7SUFFTSxlQUFlLEdBQUcsSUFBSSxlQUFlLENBQVUsc0JBQXNCLENBQUMsQ0FBQztJQUM1RCxjQUFjLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUVoRSx1QkFBdUIsR0FBRyxDQUFDLENBQVUsRUFBRSxFQUFFO1FBQy9DLE1BQU0sS0FBSyxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVqQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLDBEQUEwRCxDQUFDLENBQUM7WUFDMUUsT0FBTyxzQkFBc0IsQ0FBQztRQUNoQyxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7T0FFRztJQUNILElBQ0ksYUFBYSxDQUFDLENBQVU7UUFDMUIsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzFDLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFekQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksYUFBYSxLQUFLLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFdkQsa0NBQWtDLEdBQUcsSUFBSSxlQUFlLENBQVMsNkNBQTZDLENBQUMsQ0FBQztJQUNyRyxpQ0FBaUMsR0FBRyxJQUFJLENBQUMsa0NBQWtDLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFdEcsMENBQTBDLEdBQUcsQ0FBQyxDQUFTLEVBQUUsRUFBRTtRQUNqRSxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFL0IsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyw0RUFBNEUsQ0FBQyxDQUFDO1lBQzVGLE9BQU8sNkNBQTZDLENBQUM7UUFDdkQsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7O09BRUc7SUFDSCxJQUNJLGdDQUFnQyxDQUFDLENBQVM7UUFDNUMsSUFBSSxJQUFJLENBQUMsa0NBQWtDLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDN0QsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU1RSxJQUFJLENBQUMsa0NBQWtDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDakUsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLGdDQUFnQyxLQUFLLE9BQU8sSUFBSSxDQUFDLGtDQUFrQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUU3RixtQkFBbUIsR0FBRyxJQUFJLGVBQWUsQ0FBdUIsQ0FBQyxDQUFDLENBQUM7SUFDeEQsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRXhFLDJCQUEyQixHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUU7UUFDbEQsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU3RCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLDZFQUE2RSxDQUFDLENBQUM7WUFDN0YsT0FBTyxDQUFDLENBQUM7UUFDWCxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7O09BR0c7SUFDSCxJQUNJLGlCQUFpQixDQUFDLENBQXVCO1FBQzNDLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzlDLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBUSxDQUFDLENBQUM7UUFFcEUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxpQkFBaUIsS0FBSyxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFL0QsaUJBQWlCLEdBQUcsSUFBSSxlQUFlLENBQXVCLENBQUMsQ0FBQyxDQUFDO0lBQ3RELGdCQUFnQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUVwRSx5QkFBeUIsR0FBRyxDQUFDLENBQVMsRUFBRSxFQUFFO1FBQ2hELE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFN0QsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQywyRUFBMkUsQ0FBQyxDQUFDO1lBQzNGLE9BQU8sQ0FBQyxDQUFDO1FBQ1gsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7OztPQUdHO0lBQ0gsSUFDSSxlQUFlLENBQUMsQ0FBdUI7UUFDekMsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDNUMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFRLENBQUMsQ0FBQztRQUVsRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLGVBQWUsS0FBSyxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFM0QsbUJBQW1CLEdBQUcsSUFBSSxlQUFlLENBQVUsMkJBQTJCLENBQUMsQ0FBQztJQUNyRSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFeEUsMkJBQTJCLEdBQUcsQ0FBQyxDQUFVLEVBQUUsRUFBRTtRQUNuRCxNQUFNLEtBQUssR0FBRyxlQUFlLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRXZDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsOERBQThELENBQUMsQ0FBQztZQUM5RSxPQUFPLDJCQUEyQixDQUFDO1FBQ3JDLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOzs7Ozs7Ozs7T0FTRztJQUNILElBQ0ksaUJBQWlCLENBQUMsQ0FBVTtRQUM5QixJQUFJLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM5QyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTdELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksaUJBQWlCLEtBQUssT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRS9ELGlCQUFpQixHQUFHLElBQUksZUFBZSxDQUFVLHlCQUF5QixDQUFDLENBQUM7SUFDakUsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRXBFLHlCQUF5QixHQUFHLENBQUMsQ0FBVSxFQUFFLEVBQUU7UUFDakQsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUV2QyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLDREQUE0RCxDQUFDLENBQUM7WUFDNUUsT0FBTyx5QkFBeUIsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7Ozs7Ozs7T0FRRztJQUNILElBQ0ksZUFBZSxDQUFDLENBQVU7UUFDNUIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDNUMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUzRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLGVBQWUsS0FBSyxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFbkU7OztPQUdHO0lBQ0gsSUFDSSxrQkFBa0IsQ0FBQyxDQUFVO1FBQy9CLE1BQU0sS0FBSyxDQUFDLHVGQUF1RixDQUFDLENBQUM7SUFDdkcsQ0FBQztJQUdPLGtCQUFrQixHQUFHLElBQUksZUFBZSxDQUFVLHlCQUF5QixDQUFDLENBQUM7SUFDbEUsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRXRFLDBCQUEwQixHQUFHLENBQUMsQ0FBVSxFQUFFLEVBQUU7UUFDbEQsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUV2QyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLDZEQUE2RCxDQUFDLENBQUM7WUFDN0UsT0FBTyx5QkFBeUIsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7T0FFRztJQUNILElBQ0ksZ0JBQWdCLENBQUMsQ0FBVTtRQUM3QixJQUFJLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM3QyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLDBCQUEwQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTVELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksZ0JBQWdCLEtBQUssT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRTdELHNCQUFzQixHQUFHLElBQUksZUFBZSxDQUFVLDZCQUE2QixDQUFDLENBQUM7SUFDMUUscUJBQXFCLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRTlFLDhCQUE4QixHQUFHLENBQUMsQ0FBVSxFQUFFLEVBQUU7UUFDdEQsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUV2QyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLGlFQUFpRSxDQUFDLENBQUM7WUFDakYsT0FBTyw2QkFBNkIsQ0FBQztRQUN2QyxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7T0FFRztJQUNILElBQ0ksb0JBQW9CLENBQUMsQ0FBVTtRQUNqQyxJQUFJLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNqRCxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLDhCQUE4QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWhFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksb0JBQW9CLEtBQUssT0FBTyxJQUFJLENBQUMsc0JBQXNCLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRXJFLHNCQUFzQixHQUFHLElBQUksZUFBZSxDQUFVLDZCQUE2QixDQUFDLENBQUM7SUFDMUUscUJBQXFCLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRTlFLDhCQUE4QixHQUFHLENBQUMsQ0FBVSxFQUFFLEVBQUU7UUFDdEQsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUV2QyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLGlFQUFpRSxDQUFDLENBQUM7WUFDakYsT0FBTyw2QkFBNkIsQ0FBQztRQUN2QyxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7T0FFRztJQUNILElBQ0ksb0JBQW9CLENBQUMsQ0FBVTtRQUNqQyxJQUFJLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNqRCxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLDhCQUE4QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWhFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksb0JBQW9CLEtBQUssT0FBTyxJQUFJLENBQUMsc0JBQXNCLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRXJFLGdCQUFnQixHQUFHLElBQUksZUFBZSxDQUFpQix1QkFBdUIsQ0FBQyxDQUFDO0lBQ3JFLGVBQWUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFbEUsd0JBQXdCLEdBQUcsQ0FBQyxDQUFpQixFQUFFLEVBQUU7UUFDdkQsTUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFNUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQywyREFBMkQsQ0FBQyxDQUFDO1lBQzNFLE9BQU8sdUJBQXVCLENBQUM7UUFDakMsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7O09BRUc7SUFDSCxJQUNJLGNBQWMsQ0FBQyxDQUFpQjtRQUNsQyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMzQyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTFELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksY0FBYyxLQUFLLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQU96RCxtQkFBbUIsR0FBRyxJQUFJLGVBQWUsQ0FBcUIsMEJBQTBCLENBQUMsQ0FBQztJQUMvRSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFeEUsMkJBQTJCLEdBQUcsQ0FBQyxDQUFxQixFQUFzQixFQUFFO1FBQ2xGLElBQUksS0FBSyxHQUFHLGNBQWMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzFDLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNqQixNQUFNLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDeEYsS0FBSyxHQUFHLGFBQWEsQ0FBQyxlQUFlLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsMEVBQTBFLENBQUMsQ0FBQztnQkFDMUYsT0FBTywwQkFBMEIsQ0FBQztZQUNwQyxDQUFDO1lBQ0QsS0FBSyxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDbEMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsK0RBQStELENBQUMsQ0FBQztnQkFDL0UsT0FBTywwQkFBMEIsQ0FBQztZQUNwQyxDQUFDO1lBQ0QsS0FBSyxHQUFHLGFBQWEsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsc0VBQXNFLENBQUMsQ0FBQztnQkFDdEYsT0FBTywwQkFBMEIsQ0FBQztZQUNwQyxDQUFDO1lBQ0QsS0FBSyxHQUFHLGFBQWEsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsc0VBQXNFLENBQUMsQ0FBQztnQkFDdEYsT0FBTywwQkFBMEIsQ0FBQztZQUNwQyxDQUFDO1lBQ0QsS0FBSyxHQUFHLGFBQWEsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDeEMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMscUVBQXFFLENBQUMsQ0FBQztnQkFDckYsT0FBTywwQkFBMEIsQ0FBQztZQUNwQyxDQUFDO1lBQ0QsS0FBSyxHQUFHLGVBQWUsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDNUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsd0VBQXdFLENBQUMsQ0FBQztnQkFDeEYsT0FBTywwQkFBMEIsQ0FBQztZQUNwQyxDQUFDO1FBQ0gsQ0FBQztRQUNELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMscUVBQXFFLENBQUMsQ0FBQztZQUNyRixPQUFPLDBCQUEwQixDQUFDO1FBQ3BDLENBQUM7UUFDRCxPQUFPO1lBQ0wsZUFBZSxFQUFFLENBQUMsQ0FBQyxlQUFlLEtBQUssU0FBUyxJQUFJLENBQUMsQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQywwQkFBMEIsQ0FBQyxlQUFlO1lBQzFJLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxLQUFLLFNBQVMsSUFBSSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsMEJBQTBCLENBQUMsSUFBSTtZQUNuRixXQUFXLEVBQUUsQ0FBQyxDQUFDLFdBQVcsS0FBSyxTQUFTLElBQUksQ0FBQyxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLDBCQUEwQixDQUFDLFdBQVc7WUFDdEgsV0FBVyxFQUFFLENBQUMsQ0FBQyxXQUFXLEtBQUssU0FBUyxJQUFJLENBQUMsQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQywwQkFBMEIsQ0FBQyxXQUFXO1lBQ3RILFVBQVUsRUFBRSxDQUFDLENBQUMsVUFBVSxLQUFLLFNBQVMsSUFBSSxDQUFDLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsMEJBQTBCLENBQUMsVUFBVTtZQUNqSCxZQUFZLEVBQUUsQ0FBQyxDQUFDLFlBQVksSUFBSSwwQkFBMEIsQ0FBQyxZQUFZO1NBQ3hFLENBQUM7SUFDSixDQUFDLENBQUM7SUFFRjs7Ozs7Ozs7T0FRRztJQUNILElBQ0ksaUJBQWlCLENBQUMsQ0FBcUI7UUFDekMsSUFBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDOUMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU3RCxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLGlCQUFpQixLQUFLLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUUvRCxlQUFlLEdBQUcsSUFBSSxlQUFlLENBQXVCLElBQUksQ0FBQyxDQUFDO0lBQ3ZELGNBQWMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRWhFLHVCQUF1QixHQUFHLENBQUMsQ0FBTSxFQUFFLEVBQUU7UUFDM0MsSUFBSSxLQUFLLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLDBFQUEwRSxDQUFDLENBQUM7WUFDMUYsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7T0FFRztJQUNILElBQ0ksYUFBYSxDQUFDLENBQXVCO1FBQ3ZDLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMxQyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXpELElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLGFBQWEsS0FBSyxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRXZELFlBQVksR0FBRyxJQUFJLGVBQWUsQ0FBVSxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3ZELFdBQVcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRTFELG9CQUFvQixHQUFHLENBQUMsQ0FBVSxFQUFFLEVBQUU7UUFDNUMsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWpDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsdURBQXVELENBQUMsQ0FBQztZQUN2RSxPQUFPLG9CQUFvQixDQUFDO1FBQzlCLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOztPQUVHO0lBQ0gsSUFDSSxVQUFVLENBQUMsQ0FBVTtRQUN2QixJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdkMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV0RCxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxVQUFVLEtBQUssT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUVqRCxpQkFBaUIsR0FBRyxJQUFJLGVBQWUsQ0FBa0IsMEJBQTBCLENBQUMsQ0FBQztJQUMxRSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFcEUseUJBQXlCLEdBQUcsQ0FBQyxDQUFrQixFQUFFLEVBQUU7UUFDekQsTUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLE9BQU8sSUFBSSxDQUFDLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQztRQUVwRixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLDRFQUE0RSxDQUFDLENBQUM7WUFDNUYsT0FBTywwQkFBMEIsQ0FBQztRQUNwQyxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7T0FFRztJQUNILElBQ0ksZUFBZSxDQUFDLENBQWtCO1FBQ3BDLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzVDLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFM0QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxlQUFlLEtBQUssT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRTNELGtCQUFrQixHQUFHLElBQUksZUFBZSxDQUFtQix5QkFBeUIsQ0FBQyxDQUFDO0lBQzNFLGlCQUFpQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUV0RSwwQkFBMEIsR0FBRyxDQUFDLENBQXlCLEVBQUUsRUFBRTtRQUNqRSxNQUFNLEtBQUssR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLElBQUksYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXBELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsd0VBQXdFLENBQUMsQ0FBQztZQUN4RixPQUFPLHlCQUF5QixDQUFDO1FBQ25DLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOzs7T0FHRztJQUNILElBQ0ksZ0JBQWdCLENBQUMsQ0FBbUI7UUFDdEMsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDN0MsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU1RCxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDakQsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLGdCQUFnQixLQUFLLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUU3RCxtQkFBbUIsR0FBRyxJQUFJLGVBQWUsQ0FBVSw0QkFBNEIsQ0FBQyxDQUFDO0lBQ3RFLGtCQUFrQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUV4RSwyQkFBMkIsR0FBRyxDQUFDLENBQU0sRUFBRSxFQUFFO1FBQy9DLE1BQU0sS0FBSyxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVqQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLDhEQUE4RCxDQUFDLENBQUM7WUFDOUUsT0FBTyw0QkFBNEIsQ0FBQztRQUN0QyxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7T0FFRztJQUNILElBQ0ksaUJBQWlCLENBQUMsQ0FBVTtRQUM5QixJQUFJLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM5QyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTdELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksaUJBQWlCLEtBQUssT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRS9ELFdBQVcsR0FBRyxJQUFJLGVBQWUsQ0FBWSxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3JELFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRXhELG1CQUFtQixHQUFHLENBQUMsQ0FBWSxFQUFFLEVBQUU7UUFDN0MsTUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLE1BQU0sSUFBSSxDQUFDLEtBQUssUUFBUSxDQUFDLENBQUM7UUFFcEUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQywrREFBK0QsQ0FBQyxDQUFDO1lBQy9FLE9BQU8saUJBQWlCLENBQUM7UUFDM0IsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7OztPQUdHO0lBQ0gsSUFDSSxTQUFTLENBQUMsQ0FBWTtRQUN4QixJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdEMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVyRCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxTQUFTLEtBQUssT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUUvQyxxQkFBcUIsR0FBRyxJQUFJLGVBQWUsQ0FBZ0IsNkJBQTZCLENBQUMsQ0FBQztJQUMvRSxvQkFBb0IsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFNUUsNkJBQTZCLEdBQUcsQ0FBQyxDQUFnQixFQUFFLEVBQUU7UUFDM0QsTUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFNUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyx5RUFBeUUsQ0FBQyxDQUFDO1lBQ3pGLE9BQU8sNkJBQTZCLENBQUM7UUFDdkMsQ0FBQztRQUNELE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQztJQUNuQixDQUFDLENBQUM7SUFFRjs7T0FFRztJQUNILElBQ0ksbUJBQW1CLENBQUMsQ0FBZ0I7UUFDdEMsSUFBSSxJQUFJLENBQUMscUJBQXFCLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDaEQsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUvRCxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLG1CQUFtQixLQUFLLE9BQU8sSUFBSSxDQUFDLHFCQUFxQixDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUVuRSxlQUFlLEdBQUcsSUFBSSxlQUFlLENBQWdCLHNCQUFzQixDQUFDLENBQUM7SUFDbEUsY0FBYyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFaEUsdUJBQXVCLEdBQUcsQ0FBQyxDQUFnQixFQUFFLEVBQUU7UUFDckQsTUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLFFBQVEsSUFBSSxDQUFDLEtBQUssVUFBVSxDQUFDLENBQUM7UUFFeEUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyxzRUFBc0UsQ0FBQyxDQUFDO1lBQ3RGLE9BQU8sc0JBQXNCLENBQUM7UUFDaEMsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7Ozs7OztPQU1HO0lBQ0gsSUFDSSxhQUFhLENBQUMsQ0FBZ0I7UUFDaEMsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzFDLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFekQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksYUFBYSxLQUFLLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFdkQsU0FBUyxHQUFHLElBQUksZUFBZSxDQUFTLGVBQWUsQ0FBQyxDQUFDO0lBQzlDLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRXBELGlCQUFpQixHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUU7UUFDeEMsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRS9CLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsbURBQW1ELENBQUMsQ0FBQztZQUNuRSxPQUFPLGVBQWUsQ0FBQztRQUN6QixDQUFDO1FBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0QyxDQUFDLENBQUM7SUFFRjs7T0FFRztJQUNILElBQ0ksT0FBTyxDQUFDLENBQVM7UUFDbkIsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3BDLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFbkQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksT0FBTyxLQUFLLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFM0MsWUFBWSxHQUFHLElBQUksZUFBZSxDQUFTLG1CQUFtQixDQUFDLENBQUM7SUFDckQsV0FBVyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFMUQsb0JBQW9CLEdBQUcsQ0FBQyxDQUFTLEVBQUUsRUFBRTtRQUMzQyxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFL0IsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyxzREFBc0QsQ0FBQyxDQUFDO1lBQ3RFLE9BQU8sZUFBZSxDQUFDO1FBQ3pCLENBQUM7UUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLENBQUMsQ0FBQztJQUVGOztPQUVHO0lBQ0gsSUFDSSxVQUFVLENBQUMsQ0FBUztRQUN0QixJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdkMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV0RCxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxVQUFVLEtBQUssT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUVqRCxlQUFlLEdBQUcsSUFBSSxlQUFlLENBQVMsdUJBQXVCLENBQUMsQ0FBQztJQUM1RCxjQUFjLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUVoRSx1QkFBdUIsR0FBRyxDQUFDLENBQVMsRUFBRSxFQUFFO1FBQzlDLE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUvQixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLHlEQUF5RCxDQUFDLENBQUM7WUFDekUsT0FBTyx1QkFBdUIsQ0FBQztRQUNqQyxDQUFDO1FBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzlDLENBQUMsQ0FBQztJQUVGOztPQUVHO0lBQ0gsSUFDSSxhQUFhLENBQUMsQ0FBUztRQUN6QixJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDMUMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV6RCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxhQUFhLEtBQUssT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUV2RCxtQkFBbUIsR0FBRyxJQUFJLGVBQWUsQ0FBVSwyQkFBMkIsQ0FBQyxDQUFDO0lBQ3JFLGtCQUFrQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUV4RSwyQkFBMkIsR0FBRyxDQUFDLENBQVUsRUFBRSxFQUFFO1FBQ25ELE1BQU0sS0FBSyxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVqQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLDhEQUE4RCxDQUFDLENBQUM7WUFDOUUsT0FBTywyQkFBMkIsQ0FBQztRQUNyQyxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7T0FFRztJQUNILElBQ0ksaUJBQWlCLENBQUMsQ0FBVTtRQUM5QixJQUFJLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM5QyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTdELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksaUJBQWlCLEtBQUssT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBSS9ELGlCQUFpQixHQUFHLElBQUksZUFBZSxDQUFtQix3QkFBd0IsQ0FBQyxDQUFDO0lBQ3pFLGdCQUFnQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUVwRSx5QkFBeUIsR0FBRyxDQUFDLENBQW1CLEVBQUUsRUFBRTtRQUMxRCxNQUFNLEtBQUssR0FBRyxjQUFjLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUU1QyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQ25DLE9BQU8sQ0FBQyxLQUFLLENBQUMsd0RBQXdELENBQUMsQ0FBQztZQUN4RSxPQUFPLHdCQUF3QixDQUFDO1FBQ2xDLENBQUM7UUFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ2pDLE9BQU8sQ0FBQyxLQUFLLENBQUMsc0RBQXNELENBQUMsQ0FBQztZQUN0RSxPQUFPLHdCQUF3QixDQUFDO1FBQ2xDLENBQUM7UUFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUM7WUFDekMsT0FBTyxDQUFDLEtBQUssQ0FBQyw4REFBOEQsQ0FBQyxDQUFDO1lBQzlFLE9BQU8sd0JBQXdCLENBQUM7UUFDbEMsQ0FBQztRQUNELElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7WUFDckMsT0FBTyxDQUFDLEtBQUssQ0FBQywwREFBMEQsQ0FBQyxDQUFDO1lBQzFFLE9BQU8sd0JBQXdCLENBQUM7UUFDbEMsQ0FBQztRQUNELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsMkRBQTJELENBQUMsQ0FBQztZQUMzRSxPQUFPLHdCQUF3QixDQUFDO1FBQ2xDLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOztPQUVHO0lBQ0gsSUFDSSxlQUFlLENBQUMsQ0FBbUI7UUFDckMsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDNUMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUzRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLGVBQWUsS0FBSyxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFM0QsbUJBQW1CLEdBQUcsSUFBSSxlQUFlLENBQVUsMEJBQTBCLENBQUMsQ0FBQztJQUNwRSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFeEUsMkJBQTJCLEdBQUcsQ0FBQyxDQUFVLEVBQUUsRUFBRTtRQUNuRCxNQUFNLEtBQUssR0FBRyxlQUFlLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRXZDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsOERBQThELENBQUMsQ0FBQztZQUM5RSxPQUFPLDBCQUEwQixDQUFDO1FBQ3BDLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOztPQUVHO0lBQ0gsSUFDSSxpQkFBaUIsQ0FBQyxDQUFVO1FBQzlCLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzlDLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFN0QsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxpQkFBaUIsS0FBSyxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFL0QsMkJBQTJCLEdBQUcsSUFBSSxlQUFlLENBQVUsbUNBQW1DLENBQUMsQ0FBQztJQUNyRiwwQkFBMEIsR0FBRyxJQUFJLENBQUMsMkJBQTJCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFeEYsbUNBQW1DLEdBQUcsQ0FBQyxDQUFVLEVBQUUsRUFBRTtRQUMzRCxNQUFNLEtBQUssR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFakMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyxzRUFBc0UsQ0FBQyxDQUFDO1lBQ3RGLE9BQU8sbUNBQW1DLENBQUM7UUFDN0MsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7Ozs7O09BS0c7SUFDSCxJQUNJLHlCQUF5QixDQUFDLENBQVU7UUFDdEMsSUFBSSxJQUFJLENBQUMsMkJBQTJCLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdEQsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVyRSxJQUFJLENBQUMsMkJBQTJCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLHlCQUF5QixLQUFLLE9BQU8sSUFBSSxDQUFDLDJCQUEyQixDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUUvRSxjQUFjLEdBQUcsSUFBSSxlQUFlLENBQStCLFNBQVMsQ0FBQyxDQUFDO0lBQ25FLGFBQWEsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRTlELHNCQUFzQixHQUFHLENBQUMsQ0FBbUIsRUFBRSxFQUFFO1FBQ3ZELElBQUksS0FBSyxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsVUFBVSxLQUFLLFFBQVEsSUFBSSxPQUFPLENBQUMsQ0FBQyxrQkFBa0IsS0FBSyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQzNGLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDaEIsQ0FBQztRQUVELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE1BQU0sS0FBSyxDQUFDLDZEQUE2RCxDQUFDLENBQUM7UUFDN0UsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7O09BRUc7SUFDSCxJQUNJLFlBQVksQ0FBQyxDQUFtQjtRQUNsQyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDekMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV4RCxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxZQUFZLEtBQUssT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBc0IsQ0FBQyxDQUFDLENBQUM7SUFFekUsZUFBZSxHQUFHLElBQUksZUFBZSxDQUE0QixFQUFFLENBQUMsQ0FBQztJQUMxRCxjQUFjLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUVoRSx1QkFBdUIsR0FBRyxDQUFDLENBQTRCLEVBQUUsRUFBRTtRQUNqRSxJQUFJLEtBQUssR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUIsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNWLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ04sS0FBSyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQztvQkFDakIsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO29CQUNuQixJQUFJLENBQUMsSUFBSTt3QkFDUCxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQzt3QkFDeEMsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUM7d0JBQ3ZDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxFQUMzRixDQUFDO3dCQUNELEtBQUssR0FBRyxLQUFLLENBQUM7d0JBQ2QsTUFBTTtvQkFDUixDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUNELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsNEVBQTRFLENBQUMsQ0FBQztZQUM1RixPQUFPLEVBQUUsQ0FBQztRQUNaLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOzs7Ozs7Ozs7OztPQVdHO0lBQ0gsSUFDSSxhQUFhLENBQUMsQ0FBNEI7UUFDNUMsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzFDLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFekQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksYUFBYSxLQUFLLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFdkQsVUFBVSxHQUFHLElBQUksZUFBZSxDQUFTLGlCQUFpQixDQUFDLENBQUM7SUFDakQsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFdEQsa0JBQWtCLEdBQUcsQ0FBQyxDQUFNLEVBQUUsRUFBRTtRQUN0QyxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLFFBQVEsQ0FBQztRQUNqRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLDhFQUE4RSxDQUFDLENBQUM7WUFDOUYsT0FBTyxpQkFBaUIsQ0FBQztRQUMzQixDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7Ozs7T0FLRztJQUNILElBQ0ksUUFBUSxDQUFDLENBQXNCO1FBQ2pDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNyQyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXBELElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDekMsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLFFBQVEsS0FBSyxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRTdDLGFBQWEsR0FBRyxJQUFJLGVBQWUsQ0FBUyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3BELFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRTVELHFCQUFxQixHQUFHLENBQUMsQ0FBTSxFQUFFLEVBQUU7UUFDekMsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxRQUFRLENBQUM7UUFDakQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyxpRkFBaUYsQ0FBQyxDQUFDO1lBQ2pHLE9BQU8saUJBQWlCLENBQUM7UUFDM0IsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7OztPQUdHO0lBQ0gsSUFDSSxXQUFXLENBQUMsQ0FBc0I7UUFDcEMsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3hDLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFdkQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksV0FBVyxLQUFLLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFbkQsYUFBYSxHQUFHLElBQUksZUFBZSxDQUFTLHFCQUFxQixDQUFDLENBQUM7SUFDeEQsWUFBWSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFNUQscUJBQXFCLEdBQUcsQ0FBQyxDQUFNLEVBQUUsRUFBRTtRQUN6QyxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLFFBQVEsQ0FBQztRQUNqRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLGlGQUFpRixDQUFDLENBQUM7WUFDakcsT0FBTyxpQkFBaUIsQ0FBQztRQUMzQixDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7O09BR0c7SUFDSCxJQUNJLFdBQVcsQ0FBQyxDQUFzQjtRQUNwQyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDeEMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV2RCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxXQUFXLEtBQUssT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUVuRCxhQUFhLEdBQUcsSUFBSSxlQUFlLENBQVUsb0JBQW9CLENBQUMsQ0FBQztJQUN4RCxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUU1RCxxQkFBcUIsR0FBRyxDQUFDLENBQVUsRUFBRSxFQUFFO1FBQzdDLE1BQU0sS0FBSyxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLHdEQUF3RCxDQUFDLENBQUM7WUFDeEUsT0FBTyxvQkFBb0IsQ0FBQztRQUM5QixDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7OztPQUlHO0lBQ0gsSUFDSSxXQUFXLENBQUMsQ0FBVTtRQUN4QixJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDeEMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV2RCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxXQUFXLEtBQUssT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUVuRCxXQUFXLEdBQUcsSUFBSSxlQUFlLENBQVksaUJBQWlCLENBQUMsQ0FBQztJQUNyRCxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUV4RCxtQkFBbUIsR0FBRyxDQUFDLENBQVksRUFBRSxFQUFFO1FBQzdDLE1BQU0sS0FBSyxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxZQUFZLElBQUksQ0FBQyxLQUFLLFVBQVUsQ0FBQyxDQUFDO1FBQzVFLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsc0VBQXNFLENBQUMsQ0FBQztZQUN0RixPQUFPLGlCQUFpQixDQUFDO1FBQzNCLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOztPQUVHO0lBQ0gsSUFDSSxTQUFTLENBQUMsQ0FBWTtRQUN4QixJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdEMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVyRCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxTQUFTLEtBQUssT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUUvQyxnQkFBZ0IsR0FBRyxJQUFJLGVBQWUsQ0FBaUIsdUJBQXVCLENBQUMsQ0FBQztJQUNyRSxlQUFlLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRWxFLHdCQUF3QixHQUFHLENBQUMsQ0FBaUIsRUFBRSxFQUFFO1FBQ3ZELE1BQU0sS0FBSyxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLE1BQU0sQ0FBQyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsOERBQThELENBQUMsQ0FBQztZQUM5RSxPQUFPLHVCQUF1QixDQUFDO1FBQ2pDLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOztPQUVHO0lBQ0gsSUFDSSxjQUFjLENBQUMsQ0FBaUI7UUFDbEMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDM0MsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUxRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLGNBQWMsS0FBSyxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFekQsWUFBWSxHQUFHLElBQUksZUFBZSxDQUFTLG1CQUFtQixDQUFDLENBQUM7SUFDckQsV0FBVyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFMUQsb0JBQW9CLEdBQUcsQ0FBQyxDQUFTLEVBQUUsRUFBRTtRQUMzQyxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0IsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyxzREFBc0QsQ0FBQyxDQUFDO1lBQ3RFLE9BQU8sbUJBQW1CLENBQUM7UUFDN0IsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7O09BRUc7SUFDSCxJQUNJLFVBQVUsQ0FBQyxDQUFTO1FBQ3RCLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN2QyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXRELElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLFVBQVUsS0FBSyxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRWpELGVBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBUyx1QkFBdUIsQ0FBQyxDQUFDO0lBQzVELGNBQWMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRWhFLHVCQUF1QixHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUU7UUFDOUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ1osTUFBTSxLQUFLLEdBQUcsV0FBVyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLHlEQUF5RCxDQUFDLENBQUM7WUFDekUsR0FBRyxHQUFHLHVCQUF1QixDQUFDO1FBQ2hDLENBQUM7UUFFRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQ25DLElBQUksR0FBRyxLQUFLLFNBQVMsSUFBSSxHQUFHLElBQUksVUFBVSxFQUFFLENBQUM7WUFDM0MsT0FBTyxVQUFVLENBQUM7UUFDcEIsQ0FBQztRQUNELE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQyxDQUFDO0lBRUY7Ozs7T0FJRztJQUNILElBQ0ksYUFBYSxDQUFDLENBQVM7UUFDekIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVDLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUM1QyxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxhQUFhLEtBQUssT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUV2RCxnQkFBZ0IsR0FBRyxJQUFJLGVBQWUsQ0FBaUIsdUJBQXVCLENBQUMsQ0FBQztJQUNyRSxlQUFlLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRWxFLHdCQUF3QixHQUFHLENBQUMsQ0FBaUIsRUFBRSxFQUFFO1FBQ3ZELE1BQU0sS0FBSyxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxlQUFlLENBQUMsUUFBUSxJQUFJLENBQUMsS0FBSyxlQUFlLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdEcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyx1REFBdUQsZUFBZSxDQUFDLFFBQVEsU0FBUyxlQUFlLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQztZQUNwSSxPQUFPLHVCQUF1QixDQUFDO1FBQ2pDLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOzs7O09BSUc7SUFDSCxJQUNJLGNBQWMsQ0FBQyxDQUFpQjtRQUNsQyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMzQyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTFELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksY0FBYyxLQUFLLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUV6RCxnQkFBZ0IsR0FBRyxJQUFJLGVBQWUsQ0FBaUIsd0JBQXdCLENBQUMsQ0FBQztJQUN0RSxlQUFlLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRWxFLHdCQUF3QixHQUFHLENBQUMsQ0FBaUIsRUFBRSxFQUFFO1FBQ3ZELE1BQU0sS0FBSyxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxlQUFlLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxlQUFlLENBQUMsY0FBYyxJQUFJLENBQUMsS0FBSyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0ksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyx1REFBdUQsZUFBZSxDQUFDLFFBQVEsU0FBUyxlQUFlLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQztZQUNwSSxPQUFPLHdCQUF3QixDQUFDO1FBQ2xDLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOzs7Ozs7T0FNRztJQUNILElBQ0ksY0FBYyxDQUFDLENBQWlCO1FBQ2xDLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzNDLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFMUQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxjQUFjLEtBQUssT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRWpFOzs7T0FHRztJQUNILElBQ0ksa0JBQWtCLENBQUMsQ0FBTTtRQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLHlGQUF5RixDQUFDLENBQUM7SUFDN0csQ0FBQztJQUFBLENBQUM7SUFFTSxlQUFlLEdBQUcsSUFBSSxlQUFlLENBQWdCLHVCQUF1QixDQUFDLENBQUM7SUFDbkUsY0FBYyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFaEUsdUJBQXVCLEdBQUcsQ0FBQyxDQUFnQixFQUFFLEVBQUU7UUFDckQsTUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLE1BQU0sSUFBSSxDQUFDLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxjQUFjLENBQUMsQ0FBQztRQUM1RixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLGtGQUFrRixDQUFDLENBQUM7WUFDbEcsT0FBTyx1QkFBdUIsQ0FBQztRQUNqQyxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7Ozs7T0FLRztJQUNILElBQ0ksYUFBYSxDQUFDLENBQWdCO1FBQ2hDLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMxQyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXpELElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUFBLENBQUM7SUFDRixJQUFJLGFBQWEsS0FBSyxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRXZELFNBQVMsR0FBRyxJQUFJLGVBQWUsQ0FBUyxzQkFBc0IsQ0FBQyxDQUFDO0lBQ3JELFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRXBELGlCQUFpQixHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUU7UUFDeEMsTUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsbURBQW1ELENBQUMsQ0FBQztZQUNuRSxPQUFPLHNCQUFzQixDQUFDO1FBQ2hDLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQztJQUVGOztPQUVHO0lBQ0gsSUFDSSxPQUFPLENBQUMsQ0FBUztRQUNuQixJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDcEMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVuRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFBQSxDQUFDO0lBQ0YsSUFBSSxPQUFPLEtBQUssT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUUzQyxxQkFBcUIsR0FBRyxJQUFJLGVBQWUsQ0FBUyw2QkFBNkIsQ0FBQyxDQUFDO0lBQ3hFLG9CQUFvQixHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUU1RSw2QkFBNkIsR0FBRyxDQUFDLENBQVMsRUFBRSxFQUFFO1FBQ3BELE1BQU0sS0FBSyxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLCtEQUErRCxDQUFDLENBQUM7WUFDL0UsT0FBTyw2QkFBNkIsQ0FBQztRQUN2QyxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDLENBQUM7SUFFRjs7Ozs7T0FLRztJQUNILElBQ2MsbUJBQW1CLENBQUMsQ0FBUztRQUN6QyxJQUFJLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNoRCxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRS9ELElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQWMsbUJBQW1CLEtBQUssT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRTdFLDhCQUE4QixHQUFHLElBQUksZUFBZSxDQUFTLDZCQUE2QixDQUFDLENBQUM7SUFDMUYsNkJBQTZCLEdBQUcsSUFBSSxDQUFDLDhCQUE4QixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRXJGLGFBQWEsR0FBRyxJQUFJLGVBQWUsQ0FBZ0IscUJBQXFCLENBQUMsQ0FBQztJQUMvRCxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUU1RCxxQkFBcUIsR0FBRyxDQUFDLENBQWdCLEVBQUUsRUFBRTtRQUNuRCxNQUFNLEtBQUssR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO1lBQ3ZFLE9BQU8scUJBQXFCLENBQUM7UUFDL0IsQ0FBQztRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQyxDQUFDO0lBRUY7OztPQUdHO0lBQ0gsSUFDSSxXQUFXLENBQUMsQ0FBZ0I7UUFDOUIsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3hDLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFdkQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBQUEsQ0FBQztJQUNGLElBQUksV0FBVyxLQUFLLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFbkQsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7SUFFakQsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFFL0MsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7SUFFbkQsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7SUFFckQseUJBQXlCLEdBQVksSUFBSSxDQUFDLDJCQUEyQixFQUFFLENBQUM7SUFFdEUsWUFBWSxHQUFHLElBQUksZUFBZSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBQ25ELFdBQVcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3pELElBQWMsVUFBVTtRQUN0QixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDdEMsQ0FBQztJQUVPLFdBQVcsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDM0MsSUFBYyxVQUFVO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUMxQixDQUFDO0lBRU8sWUFBWSxHQUFHLElBQUksZUFBZSxDQUFVLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMzRCxXQUFXLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUVqRCxnQkFBZ0IsR0FBRyxJQUFJLGVBQWUsQ0FBWSxJQUFJLENBQUMsQ0FBQztJQUN0RCxlQUFlLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRXpELFNBQVMsR0FBRyxJQUFJLGVBQWUsQ0FBK0IsRUFBRSxDQUFDLENBQUM7SUFDaEUsUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFM0Msa0JBQWtCLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDdkQsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRTdELGFBQWEsR0FBRyxJQUFJLGVBQWUsQ0FBeUIsRUFBRSxDQUFDLENBQUM7SUFFaEUsa0JBQWtCLEdBQUcsSUFBSSxlQUFlLENBQVksRUFBRSxDQUFDLENBQUM7SUFFeEQsa0JBQWtCLEdBQXNELEVBQUUsQ0FBQztJQUUzRSx5QkFBeUIsR0FBc0QsRUFBRSxDQUFDO0lBRWxGLFFBQVEsR0FBRyxJQUFJLGVBQWUsQ0FBZSxJQUFJLENBQUMsQ0FBQztJQUNqRCxPQUFPLEdBQTZCLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFbkUsd0JBQXdCLEdBQUcsSUFBSSxlQUFlLENBQVUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDN0UsdUJBQXVCLEdBQXdCLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUU5RixpQkFBaUIsR0FBRyxJQUFJLGVBQWUsQ0FBWSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDakUsZ0JBQWdCLEdBQTBCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMxRixJQUFjLGVBQWUsS0FBSyxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFckUsZ0JBQWdCLEdBQUcsSUFBSSxlQUFlLENBQVMsQ0FBQyxDQUFDLENBQUM7SUFDaEQsZUFBZSxHQUF1QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDckYsSUFBYyxjQUFjLEtBQUssT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRW5FLG1CQUFtQixHQUFHLElBQUksZUFBZSxDQUFTLENBQUMsQ0FBQyxDQUFDO0lBQ25ELGtCQUFrQixHQUF1QixJQUFJLENBQUMsbUJBQW1CLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDM0YsSUFBYyxpQkFBaUIsS0FBSyxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFekUsbUJBQW1CLEdBQUcsSUFBSSxlQUFlLENBQVMsQ0FBQyxDQUFDLENBQUM7SUFDbkQsa0JBQWtCLEdBQXVCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMzRixJQUFjLGlCQUFpQixLQUFLLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUV6RSxXQUFXLEdBQUcsSUFBSSxlQUFlLENBQVMsQ0FBQyxDQUFDLENBQUM7SUFFN0MsWUFBWSxHQUFHLElBQUksZUFBZSxDQUFlLElBQUksQ0FBQyxDQUFDO0lBRXZELFlBQVksR0FBRyxJQUFJLGVBQWUsQ0FBUyxDQUFDLENBQUMsQ0FBQztJQUNuQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUUxRCxlQUFlLEdBQUcsSUFBSSxlQUFlLENBQVUsSUFBSSxDQUFDLENBQUM7SUFFckQsYUFBYSxHQUFHLElBQUksZUFBZSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBRXBELGdDQUFnQyxHQUFHLElBQUksZUFBZSxDQUFTLENBQUMsQ0FBQyxDQUFDO0lBRWxFLDhCQUE4QixHQUFHLElBQUksZUFBZSxDQUFTLENBQUMsQ0FBQyxDQUFDO0lBRWhFLHlCQUF5QixHQUFHLElBQUksZUFBZSxDQUFTLENBQUMsQ0FBQyxDQUFDO0lBQ3pELHdCQUF3QixHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUUzRSx1QkFBdUIsR0FBRyxJQUFJLGVBQWUsQ0FBUyxDQUFDLENBQUMsQ0FBQztJQUN2RCxzQkFBc0IsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFdkUsYUFBYSxHQUFHLElBQUksZUFBZSxDQUFTLENBQUMsQ0FBQyxDQUFDO0lBQzdDLFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRW5ELFdBQVcsR0FBRyxJQUFJLGVBQWUsQ0FBUyxDQUFDLENBQUMsQ0FBQztJQUMzQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUUvQyx5QkFBeUIsR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUVoRSx1QkFBdUIsR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUU5RCw0QkFBNEIsR0FBRyxJQUFJLGVBQWUsQ0FBUyxDQUFDLENBQUMsQ0FBQztJQUM1RCwyQkFBMkIsR0FBRyxJQUFJLENBQUMsNEJBQTRCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFakYsMEJBQTBCLEdBQUcsSUFBSSxlQUFlLENBQVMsQ0FBQyxDQUFDLENBQUM7SUFDMUQseUJBQXlCLEdBQUcsSUFBSSxDQUFDLDBCQUEwQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRTdFLDhCQUE4QixHQUFHLEdBQUcsRUFBRTtRQUM1QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxFQUFFLGlCQUFpQixHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQztRQUNsSyxJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLFFBQVEsSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDekQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBRTdGLEtBQUssTUFBTSxJQUFJLElBQUksaUJBQWlCLEVBQUUsQ0FBQztnQkFDckMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQ1gsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEdBQUcsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsRUFBRSxFQUFFLENBQUM7Z0JBQzVGLENBQUM7WUFDSCxDQUFDO1lBRUQsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztZQUMzQyxJQUFJLGNBQWMsS0FBSyxlQUFlLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2hELE1BQU0sZ0JBQWdCLEdBQUcsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUM7Z0JBQzFELElBQUksQ0FBQyxDQUFDLGdCQUFnQixFQUFFLENBQUM7b0JBQ3ZCLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7b0JBRTVGLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLG1CQUFtQixnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsWUFBWSxNQUFNLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxXQUFXLElBQUksZ0JBQWdCLENBQUMsT0FBTyxDQUFDLFlBQVksTUFBTSxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsV0FBVyxRQUFRLENBQUM7b0JBRXhPLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUNoRyxlQUFlLEdBQUcsUUFBUSxDQUFDLGFBQWEsRUFBRSxLQUFLLEdBQUcsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxLQUFLLElBQUksQ0FBQyxFQUM1RixhQUFhLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO29CQUUxQyxJQUFJLEtBQWEsRUFBRSxHQUFXLEVBQUUsTUFBYyxDQUFDO29CQUMvQyxJQUFJLFVBQVUsRUFBRSxDQUFDO3dCQUNmLEtBQUssR0FBRyxLQUFLLEdBQUcsYUFBYSxHQUFHLENBQUMsQ0FBQzt3QkFDbEMsR0FBRyxHQUFHLE9BQU8sQ0FBQzt3QkFDZCxNQUFNLEdBQUcsTUFBTSxDQUFDO3dCQUNoQixJQUFJLFdBQVcsS0FBSyxjQUFjLENBQUMsR0FBRyxFQUFFLENBQUM7NEJBQ3ZDLGVBQWUsQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLG1CQUFtQixNQUFNLE1BQU0sS0FBSyxJQUFJLE1BQU0sTUFBTSxLQUFLLElBQUksR0FBRyxHQUFHLEtBQUssTUFBTSxhQUFhLElBQUksR0FBRyxHQUFHLEtBQUssTUFBTSxhQUFhLFFBQVEsQ0FBQzt3QkFDekssQ0FBQzs2QkFBTSxDQUFDOzRCQUNOLGVBQWUsQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLGFBQWEsR0FBRyxHQUFHLEtBQUssUUFBUSxNQUFNLE1BQU0sS0FBSyxJQUFJLE1BQU0sTUFBTSxLQUFLLFFBQVEsS0FBSyxRQUFRLEtBQUssSUFBSSxHQUFHLEdBQUcsS0FBSyxNQUFNLENBQUM7d0JBQ3pKLENBQUM7b0JBQ0gsQ0FBQzt5QkFBTSxDQUFDO3dCQUNOLEtBQUssR0FBRyxLQUFLLENBQUM7d0JBQ2QsR0FBRyxHQUFHLENBQUMsQ0FBQzt3QkFDUixNQUFNLEdBQUcsTUFBTSxHQUFHLGFBQWEsQ0FBQzt3QkFDaEMsZUFBZSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsV0FBVyxLQUFLLFFBQVEsS0FBSyxJQUFJLE1BQU0sUUFBUSxNQUFNLFlBQVksS0FBSyxRQUFRLENBQUM7b0JBQ2xILENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQyxDQUFDO0lBRU0sc0JBQXNCLEdBQTBCLElBQUksQ0FBQztJQUVyRCxTQUFTLEdBQUcsQ0FBQyxPQUFvQixFQUFFLFFBQWdCLEVBQUUsUUFBd0IsZUFBZSxDQUFDLE1BQU0sRUFDekcsV0FBMkIsYUFBYSxFQUFFLEVBQUU7UUFDNUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN4QixPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztRQUN6QyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNmLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUcsRUFBRSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxFQUNuSSxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFDN0IsWUFBWSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQzFDLFdBQVcsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDO1lBQzFELElBQUksR0FBRyxHQUFXLE1BQU0sQ0FBQyxHQUFHLENBQUM7WUFDN0IsUUFBUSxLQUFLLEVBQUUsQ0FBQztnQkFDZCxLQUFLLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO29CQUMzQixHQUFHLEdBQUcsUUFBUSxHQUFHLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQztvQkFDNUMsTUFBTTtnQkFDUixDQUFDO2dCQUNELEtBQUssZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7b0JBQzVCLEdBQUcsR0FBRyxRQUFRLEdBQUcsQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRSxHQUFHLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQztvQkFDaEYsTUFBTTtnQkFDUixDQUFDO2dCQUNELEtBQUssZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7b0JBQ3pCLEdBQUcsR0FBRyxRQUFRLEdBQUcsQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFDLEdBQUcsUUFBUSxDQUFDLGlCQUFpQixDQUFDO29CQUMzRSxNQUFNO2dCQUNSLENBQUM7Z0JBQ0QsS0FBSyxlQUFlLENBQUMsSUFBSSxDQUFDO2dCQUMxQixPQUFPLENBQUMsQ0FBQyxDQUFDO29CQUNSLE1BQU07Z0JBQ1IsQ0FBQztZQUNILENBQUM7WUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsU0FBUyxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUMzQyxNQUFNLE1BQU0sR0FBb0I7b0JBQzlCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLElBQUk7b0JBQ2hHLFVBQVUsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsS0FBSztvQkFDckQsUUFBUSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxjQUFjO2lCQUNuSixDQUFDO2dCQUNGLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDNUIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDLENBQUE7SUFFTyxXQUFXLEdBQUcsTUFBTSxDQUEwQixVQUFVLENBQUMsQ0FBQztJQUVsRTs7T0FFRztJQUNLLG1CQUFtQixHQUE4QywwQkFBMEIsQ0FBQztJQUNwRyxJQUFjLGtCQUFrQixLQUFLLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztJQUV2RTs7T0FFRztJQUNLLGNBQWMsR0FBMEIsUUFBUSxDQUFDO0lBRXpEOztPQUVHO0lBQ0ssU0FBUyxHQUFhLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFNUQsUUFBUSxHQUFHLElBQUksT0FBTyxFQUFVLENBQUM7SUFDdEIsT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFbEQsVUFBVSxHQUFHLElBQUksT0FBTyxFQUFpQixDQUFDO0lBQ3hDLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRTdDLGtCQUFrQixHQUFHLElBQUksT0FBTyxFQUFpQixDQUFDO0lBQ3ZDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUV0RSxhQUFhLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7SUFFcEQsUUFBUSxHQUFHLElBQUksT0FBTyxFQUFnQixDQUFDO0lBQ3RDLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRXhDLE1BQU0sR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO0lBQzVCLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRXBDLFlBQVksR0FBRyxJQUFJLE9BQU8sRUFBVyxDQUFDO0lBQzNCLFdBQVcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRTFELHFCQUFxQixHQUFHLElBQUksT0FBTyxFQUFXLENBQUM7SUFDcEMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBRTVFLHVCQUF1QixHQUFHLElBQUksZUFBZSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBQ25ELHNCQUFzQixHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUVoRixTQUFTLENBQXFCO0lBRTlCLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFFdEIsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUVoQixVQUFVLEdBQUcsS0FBSyxDQUFDO0lBRTNCLElBQWMsUUFBUTtRQUNwQixPQUFPLElBQUksQ0FBQyxVQUFVLEVBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQztJQUMxQyxDQUFDO0lBRUQsSUFBYyxhQUFhO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsY0FBYyxJQUFJLEtBQUssQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFTyxVQUFVLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7SUFDeEMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFcEQsU0FBUyxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7SUFDdkIsUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUM7SUFFMUQ7UUFDRSxLQUFLLEVBQUUsQ0FBQztRQUNSLHNCQUFzQixDQUFDLFFBQVEsR0FBRyxzQkFBc0IsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxLQUFLLE1BQU0sQ0FBQyxnQkFBZ0I7WUFDL0YsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsc0JBQXNCLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsR0FBRyxHQUFHLHNCQUFzQixDQUFDLFFBQVEsQ0FBQztRQUUzQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUVuRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxFQUNwQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7UUFDM0MsYUFBYSxDQUFDLENBQUMsWUFBWSxFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQ2xELFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLGVBQWUsQ0FBQyxFQUFFLEVBQUU7WUFDckMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksZUFBZSxDQUFDLENBQUM7UUFDL0QsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQ3hCLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxHQUFHLENBQUMsQ0FBQztRQUNwQyxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQ3RCLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEVBQUUsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDdEUsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQ2hDLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFDZixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FDOUIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUNmLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1FBQ3JDLFdBQVcsQ0FBQyxJQUFJLENBQ2QsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO1FBQzNELENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxNQUFNLG9CQUFvQixHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQztRQUN2RCxvQkFBb0IsQ0FBQyxJQUFJLENBQ3ZCLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO1FBQ3hDLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRSxDQUFDLElBQUksQ0FDL0MsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUNqQixFQUNDLHFCQUFxQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsRUFDL0MsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBRTlDLGFBQWEsQ0FBQyxDQUFDLE9BQU8sRUFBRSxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUNsRCxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ3BCLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUU7WUFDdEIsTUFBTSxHQUFHLEdBQUcseUJBQXlCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMvRixJQUFJLENBQUMsZ0NBQWdDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2xELENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxhQUFhLENBQUMsQ0FBQyxPQUFPLEVBQUUsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDaEQsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNwQixHQUFHLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFO1lBQ3RCLE1BQU0sR0FBRyxHQUFHLHlCQUF5QixDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxNQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDL0YsSUFBSSxDQUFDLDhCQUE4QixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNoRCxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxxQ0FBcUMsQ0FBQyxJQUFJLENBQ3RELFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsRUFDdkIsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQ1AsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRyxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksQ0FDdEIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLEdBQUcsRUFBRTtZQUNQLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUNsQyxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUN0QixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsS0FBSyxJQUFJLENBQUMsRUFDdkMsR0FBRyxDQUFDLEdBQUcsRUFBRTtZQUNQLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUNsQyxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxlQUFlO1FBQ2IsTUFBTSxTQUFTLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLEVBQ25ELFFBQVEsR0FBRyxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFdEMsYUFBYSxDQUFDLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDeEMsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsRUFDOUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUNmLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hDLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBRXpELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLENBQUMsSUFBSSxDQUMvQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ2pCLEVBQ0Msa0JBQWtCLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxFQUNoRCxlQUFlLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUN2QyxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ2hCLFNBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLFFBQVMsQ0FBQyxlQUFlLENBQUMsQ0FDakQsRUFDRCxjQUFjLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUN0QyxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ2hCLFNBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLFFBQVMsQ0FBQyxjQUFjLENBQUMsQ0FDaEQsQ0FBQztRQUVKLGtCQUFrQixDQUFDLElBQUksQ0FDckIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNoQixTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxRQUFTLENBQUMsZ0JBQWdCLENBQUMsRUFDakQsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxlQUFlLENBQUMsSUFBSSxDQUNsQixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ2hCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGNBQWMsQ0FBQyxJQUFJLENBQ2pCLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDaEIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3ZCLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQy9CLFFBQVEsQ0FBQyxJQUFJLENBQ1gsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO1FBQ3JELENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxJQUFJLENBQUMsU0FBUyxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztRQUUzRCxJQUFJLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFFMUIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQ25DLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ2xFLEVBQ0MsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUNuQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUN0RSxFQUNELFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FDbkMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDdEUsRUFDRCxrQkFBa0IsR0FBRyxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUNyRCxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixvQkFBb0IsRUFBRSxDQUN2QixFQUNELGdCQUFnQixHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQ2pELFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLG9CQUFvQixFQUFFLENBQ3ZCLENBQUM7UUFFSixhQUFhLENBQUMsQ0FBQyxZQUFZLEVBQUUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQy9FLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsU0FBUyxDQUFDLEVBQUUsRUFBRTtZQUNoRCxJQUFLLENBQVMsS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDNUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxjQUFjLEdBQUcsTUFBTSxFQUN6RCxNQUFNLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxFQUFFLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEVBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxHQUFHLFNBQVMsQ0FBQztnQkFDakgsT0FBTyxFQUFFLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QyxDQUFDO1lBQ0QsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDZixDQUFDLENBQUMsRUFDRixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25DLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxhQUFhLENBQUMsQ0FBQyxZQUFZLEVBQUUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQy9FLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsU0FBUyxDQUFDLEVBQUUsRUFBRTtZQUNoRCxJQUFLLENBQVMsS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDNUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxjQUFjLEdBQUcsTUFBTSxFQUN6RCxNQUFNLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxFQUFFLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEVBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxHQUFHLFNBQVMsQ0FBQztnQkFDakgsT0FBTyxFQUFFLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QyxDQUFDO1lBQ0QsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDZixDQUFDLENBQUMsRUFDRixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25DLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsRUFDaEQsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1FBRS9DLGFBQWEsQ0FBQyxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDcEgsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLFNBQVMsQ0FBQyxFQUFFLEVBQUU7WUFDMUQsSUFBSyxDQUFTLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQzVCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsY0FBYyxHQUFHLE1BQU0sRUFDekQsTUFBTSxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxFQUFFLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsR0FBRyxTQUFTLENBQUM7Z0JBQ2pILE9BQU8sRUFBRSxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDaEUsQ0FBQztZQUNELE9BQU8sRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakQsQ0FBQyxDQUFDLEVBQ0YsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7UUFDN0IsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxlQUFlLEVBQzFDLFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxDQUFDLElBQUksQ0FDbkQsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0Isb0JBQW9CLEVBQUUsQ0FDdkIsQ0FBQztRQUVKLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksQ0FDM0IsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ1gsTUFBTSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxHQUFHLE1BQU0sQ0FBQztZQUN0RCxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3JELENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FDM0IsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNoQixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFFLENBQUMsYUFBYSxDQUFDLEVBQzFCLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FDUixDQUFDO1FBRUYsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLEtBQW9CLEVBQUUsVUFBbUIsRUFBRSxFQUFFO1lBQ3pFLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztZQUN6QyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDZixNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxRQUFRLEVBQUUsRUFBRSxVQUFVLEdBQUcsUUFBUSxDQUFDLFVBQVUsSUFBSSxLQUFLLEVBQzVHLFVBQVUsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQ2xFLFlBQVksR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUM7Z0JBQzNFLElBQUksVUFBVSxJQUFJLFVBQVUsSUFBSSxpQkFBaUIsSUFBSSxVQUFVLElBQUksWUFBWSxFQUFFLENBQUM7b0JBQ2hGLElBQUksQ0FBQyxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7d0JBQ2hDLEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO3dCQUNqQyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7b0JBQ3pCLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDLENBQUM7UUFFRixLQUFLLENBQUMsSUFBSSxDQUNSLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFDNUIsU0FBUyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ2xCLE9BQU8sU0FBUyxDQUFnQixPQUFPLEVBQUUsY0FBYyxDQUFDLENBQUMsSUFBSSxDQUMzRCxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ1osUUFBUSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7b0JBQ2QsS0FBSyxZQUFZO3dCQUNmLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7NEJBQ3JCLG9CQUFvQixDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7d0JBQzNDLENBQUM7d0JBQ0QsTUFBTTtvQkFDUixLQUFLLFVBQVU7d0JBQ2IsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7NEJBQ3BCLG9CQUFvQixDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7d0JBQzNDLENBQUM7d0JBQ0QsTUFBTTtvQkFDUixLQUFLLGFBQWE7d0JBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7NEJBQ3JCLG9CQUFvQixDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7d0JBQzNDLENBQUM7d0JBQ0QsTUFBTTtvQkFDUixLQUFLLFlBQVk7d0JBQ2YsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7NEJBQ3BCLG9CQUFvQixDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7d0JBQzNDLENBQUM7d0JBQ0QsTUFBTTtnQkFDVixDQUFDO2dCQUNELE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xCLENBQUMsQ0FBQyxDQUNILENBQUM7UUFDSixDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUM7UUFDckQsbUJBQW1CLENBQUMsSUFBSSxDQUN0QixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ2hCLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxHQUFHLGtCQUFrQixDQUFDO1FBQ25ELENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUM1QixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQ2YsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQ2YsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUN2QyxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUM5QixFQUNDLFVBQVUsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUNyRSxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUM5QixFQUNELFdBQVcsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUN2RSxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUM5QixDQUFDO1FBRUosU0FBUyxDQUFnQixRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUMvQyxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLE9BQU8sQ0FBQyxFQUM5QixTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDWixPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQzFELFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFDUixTQUFTLENBQUMsYUFBYSxDQUFDLEVBQ3hCLFNBQVMsQ0FBQyxVQUFVLENBQUMsRUFDckIsU0FBUyxDQUFDLFdBQVcsQ0FBQyxFQUN0QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ04sSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3BDLENBQUMsQ0FBQyxDQUNILENBQUM7UUFDSixDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUMvQixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDWixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNwQyxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUMxQixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ2hCLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNYLE1BQU0sRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxHQUFHLE1BQU8sQ0FBQztZQUNwQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDakMsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLElBQUksQ0FDN0IsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1osSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDbEMsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUNwQixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixvQkFBb0IsRUFBRSxFQUN0QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUN0QixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixvQkFBb0IsRUFBRSxFQUN0QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUM7UUFDbEMsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGFBQWEsQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQzdELFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLEVBQUUsVUFBVSxDQUFDLEVBQUUsRUFBRTtZQUN0QyxJQUFJLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQzlFLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUMzRCxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixHQUFHLENBQUMsQ0FBQyxDQUFDLGVBQWUsRUFBRSxVQUFVLENBQUMsRUFBRSxFQUFFO1lBQ3BDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzFFLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUM5QixtQkFBbUIsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRTVDLE1BQU0sVUFBVSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQy9CLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDaEIsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ1osT0FBTyxtQkFBbUIsQ0FBQyxJQUFJLENBQzdCLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDaEIsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBRSxDQUFDLE9BQU8sQ0FBQyxDQUMzQixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUVGLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDckMsV0FBVyxDQUFDLElBQUksQ0FDZCxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDZixhQUFhLEdBQUcsVUFBVSxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxFQUMxQixnQkFBZ0IsR0FBRyxDQUFDLE9BQWtDLEVBQUUsRUFBRTtZQUN4RCxJQUFJLHNDQUFzQyxHQUFHLDBCQUEwQixFQUNyRSxnQ0FBZ0MsR0FBRyxDQUFDLENBQUM7WUFDdkMsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLEVBQUUsaUJBQWlCLElBQUksa0JBQWtCLEVBQ3hFLHFCQUFxQixHQUFHLE9BQU8sRUFBRSxxQkFBcUIsSUFBSSwyQkFBMkIsQ0FBQztZQUN4RixPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQ2xCLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLFNBQVMsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2Isc0NBQXNDLEdBQUcsMEJBQTBCLENBQUM7Z0JBQ3BFLGdDQUFnQyxHQUFHLENBQUMsQ0FBQztnQkFDckMsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7Z0JBQ3JCLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FDakIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUNmLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDWixJQUFJLENBQUMsQ0FBQyxzQ0FBc0MsS0FBSywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsc0NBQXNDLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQzdILENBQUMsZ0NBQWdDLEdBQUcsaUJBQWlCLENBQUMsRUFBRSxDQUFDO3dCQUN6RCxJQUFJLENBQUMsS0FBSywwQkFBMEIsRUFBRSxDQUFDOzRCQUNyQyxzQ0FBc0MsR0FBRyxDQUFDLENBQUM7d0JBQzdDLENBQUM7d0JBQ0QsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7d0JBQzlCLE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUNuQixDQUFDO29CQUNELElBQUksc0NBQXNDLEtBQUssQ0FBQyxFQUFFLENBQUM7d0JBQ2pELElBQUksZ0NBQWdDLEdBQUcscUJBQXFCLEVBQUUsQ0FBQzs0QkFDN0QsZ0NBQWdDLEVBQUUsQ0FBQzs0QkFDbkMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7NEJBQzlCLE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO3dCQUNuQixDQUFDO29CQUNILENBQUM7b0JBQ0Qsc0NBQXNDLEdBQUcsQ0FBQyxDQUFDO29CQUMzQyxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDbEIsQ0FBQyxDQUFDLEVBQ0YsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNoQixvQkFBb0IsRUFBRSxDQUN2QixDQUFBO1lBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQTtRQUNILENBQUMsQ0FBQztRQUNKLE1BQU0sd0JBQXdCLEdBQUcsZ0JBQWdCLENBQUM7WUFDaEQsaUJBQWlCLEVBQUUsa0JBQWtCO1lBQ3JDLHFCQUFxQixFQUFFLDJCQUEyQjtTQUNuRCxDQUFDLEVBQ0EsNEJBQTRCLEdBQUcsZ0JBQWdCLENBQUM7WUFDOUMsaUJBQWlCLEVBQUUsbUNBQW1DO1lBQ3RELHFCQUFxQixFQUFFLDRDQUE0QztTQUNwRSxDQUFDLEVBQ0YsNkJBQTZCLEdBQUcsZ0JBQWdCLENBQUM7WUFDL0MsaUJBQWlCLEVBQUUsbUNBQW1DO1lBQ3RELHFCQUFxQixFQUFFLDRDQUE0QztTQUNwRSxDQUFDLEVBQ0YsOEJBQThCLEdBQUcsZ0JBQWdCLENBQUM7WUFDaEQsaUJBQWlCLEVBQUUscUNBQXFDO1lBQ3hELHFCQUFxQixFQUFFLDhDQUE4QztTQUN0RSxDQUFDLEVBQ0YsY0FBYyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUN2QyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDdEIsRUFDRCxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFDeEIsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQ2hDLGtCQUFrQixHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxZQUFZLEVBQUUsRUFDbEUsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLFlBQVksRUFBRSxFQUM5RCxtQkFBbUIsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQzlDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBRXZCLGFBQWEsQ0FBQyxDQUFDLFNBQVMsRUFBRSxtQkFBbUIsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLGtCQUFrQixFQUFFLGdCQUFnQixFQUFFLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQ3JJLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLG9CQUFvQixFQUFFLEVBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLGtCQUFrQixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLGtCQUFrQixDQUFDLEVBQ3RFLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFDZixTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxlQUFlLEVBQUUsa0JBQWtCLENBQUMsRUFBRSxFQUFFO1lBQ2pILElBQUksQ0FBQyxDQUFDLFdBQVcsSUFBSSxDQUFDLGlCQUFpQixJQUFJLENBQUMsQ0FBQyxlQUFlLElBQUksQ0FBQyxDQUFDLGtCQUFrQixFQUFFLENBQUM7Z0JBQ3JGLE1BQU0sV0FBVyxHQUFHLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDMUQsT0FBTyxXQUFXLENBQUMsSUFBSSxDQUNyQixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixvQkFBb0IsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtvQkFDNUIsTUFBTSxPQUFPLEdBQUcsQ0FBQyxFQUFFLE1BQU0sSUFBSSxDQUFDLEVBQUUsT0FBTyxHQUFHLENBQUMsRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDO29CQUN6RCxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sS0FBSyxPQUFPLElBQUksQ0FBQyxPQUFPLEtBQUssQ0FBQyxJQUFJLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZGLENBQUMsQ0FBQyxFQUNGLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRTtvQkFDVixJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUM3RCxDQUFDLENBQUMsRUFDRixTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQ3hDLG9CQUFvQixFQUFFLEVBQ3RCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDTixJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7d0JBQ1AsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO3dCQUNsQixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7d0JBQ2YsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7d0JBQzNCLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxlQUFlLEVBQUUsQ0FBQzs0QkFDMUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO3dCQUNwQyxDQUFDO3dCQUNELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO3dCQUNsRCxJQUFJLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDOzRCQUN4QixpQkFBaUIsQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDOzRCQUNuQyxpQkFBaUIsQ0FBQyxhQUFhLEVBQUUsQ0FBQzs0QkFDbEMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLENBQUM7d0JBQzlCLENBQUM7d0JBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQzt3QkFDeEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ3pCLENBQUM7eUJBQU0sQ0FBQzt3QkFDTixJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7d0JBQ2xDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO3dCQUNuRCxJQUFJLGtCQUFrQixFQUFFLENBQUM7NEJBQ3ZCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dDQUN2QixJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztnQ0FDckIsa0JBQW1CLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzs0QkFDckMsQ0FBQzt3QkFDSCxDQUFDO3dCQUNELElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7d0JBQ3pDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUMxQixDQUFDO2dCQUNILENBQUMsQ0FBQyxFQUNGLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDWixJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7d0JBQ1AsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7NEJBQ3ZCLGtCQUFtQixDQUFDLEdBQUcsRUFBRSxDQUFDO3dCQUM1QixDQUFDO3dCQUNELE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUNuQixDQUFDO29CQUNELE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO29CQUNuRCxJQUFJLGtCQUFrQixFQUFFLENBQUM7d0JBQ3ZCLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQzt3QkFDbEMsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7NEJBQ3ZCLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDOzRCQUNyQixrQkFBbUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO3dCQUNyQyxDQUFDO3dCQUNELE9BQU8sd0JBQXdCLENBQUMsSUFBSSxDQUNsQyxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQ1AsR0FBRyxDQUFDLEdBQUcsRUFBRTs0QkFDUCxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7NEJBQ2xDLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dDQUN2QixrQkFBbUIsQ0FBQyxHQUFHLEVBQUUsQ0FBQzs0QkFDNUIsQ0FBQzs0QkFDRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQzs0QkFDMUIsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7NEJBQ2xELElBQUksQ0FBQyxDQUFDLGlCQUFpQixFQUFFLENBQUM7Z0NBQ3hCLGlCQUFpQixDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7Z0NBQ2xDLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxDQUFDOzRCQUM5QixDQUFDOzRCQUNELElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7NEJBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO3dCQUN6QixDQUFDLENBQUMsQ0FDSCxDQUFDO29CQUNKLENBQUM7b0JBQ0QsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7d0JBQ3ZCLGtCQUFtQixDQUFDLEdBQUcsRUFBRSxDQUFDO29CQUM1QixDQUFDO29CQUNELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO29CQUMxQixJQUFJLENBQUMsaUJBQWlCLElBQUksZUFBZSxFQUFFLENBQUM7d0JBQzFDLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztvQkFDcEMsQ0FBQztvQkFDRCxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztvQkFDbEQsSUFBSSxDQUFDLENBQUMsaUJBQWlCLEVBQUUsQ0FBQzt3QkFDeEIsaUJBQWlCLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQzt3QkFDbEMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLENBQUM7b0JBQzlCLENBQUM7b0JBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztvQkFDeEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ3ZCLE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNuQixDQUFDLENBQUMsQ0FDSCxDQUFDO1lBQ0osQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGtCQUFtQixDQUFDLEdBQUcsRUFBRSxDQUFDO2dCQUMxQixNQUFNLFdBQVcsR0FBRyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzFELE9BQU8sV0FBVyxDQUFDLElBQUksQ0FDckIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFO29CQUNWLElBQUksQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQzt3QkFDakMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO3dCQUNsQixNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQzt3QkFDbEQsSUFBSSxDQUFDLENBQUMsaUJBQWlCLEVBQUUsQ0FBQzs0QkFDeEIsaUJBQWlCLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQzt3QkFDckMsQ0FBQzt3QkFDRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO3dCQUN6QyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDMUIsQ0FBQztvQkFDRCxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUM3RCxDQUFDLENBQUMsRUFDRixTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQ3hDLG9CQUFvQixFQUFFLEVBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDaEIsR0FBRyxDQUFDLEdBQUcsRUFBRTtvQkFDUCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztvQkFDMUIsSUFBSSxpQkFBaUIsRUFBRSxDQUFDO3dCQUN0QixJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7b0JBQ3RDLENBQUM7eUJBQU0sSUFBSSxlQUFlLEVBQUUsQ0FBQzt3QkFDM0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO29CQUNwQyxDQUFDO29CQUNELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO29CQUNsRCxJQUFJLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO3dCQUN4QixpQkFBaUIsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO3dCQUNsQyxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDOUIsQ0FBQztvQkFDRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO29CQUN4QyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDdkIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2hDLENBQUMsQ0FBQyxDQUNILENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLE1BQU0sQ0FBQyxJQUFJLENBQ1QsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLE1BQU0sR0FBRyxDQUFDLENBQUMsRUFDdkIsb0JBQW9CLEVBQUUsRUFDdEIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNoQixHQUFHLENBQUMsR0FBRyxFQUFFO1lBQ1AsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDdkIsQ0FBQyxDQUFDLEVBQ0YsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNiLE9BQU8sVUFBVSxDQUFDLElBQUksQ0FDcEIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUNmLElBQUksQ0FBQyxDQUFDLENBQUMsRUFDUCxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQ1YsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztvQkFDeEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ25DLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO29CQUNwQixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDL0IsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUNILENBQUM7UUFDSixDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUMzQixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQztRQUN4QyxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsS0FBSyxDQUFDLElBQUksQ0FDUixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQzVCLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUNaLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQztRQUN0QyxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQzlDLGNBQWMsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUNwQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQ3hDLGNBQWMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxFQUNwRCxpQkFBaUIsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxFQUNyRCxXQUFXLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQ2hDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxJQUFJLGlCQUFpQixDQUFDLENBQUMsQ0FDckQsQ0FBQztRQUVKLGtCQUFrQixDQUFDLElBQUksQ0FDckIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGdCQUFnQixDQUFDLElBQUksQ0FDbkIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDO1FBQ3BDLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxXQUFXLENBQUMsSUFBSSxDQUNkLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztRQUMvQixDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsWUFBWSxDQUFDLElBQUksQ0FDZixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGlCQUFpQixDQUFDLElBQUksQ0FDcEIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGtCQUFrQixDQUFDLElBQUksQ0FDckIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0Isb0JBQW9CLEVBQUUsRUFDdEIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGlCQUFpQixHQUFHLENBQUMsQ0FBQztRQUN6RSxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsZ0JBQWdCLENBQUMsSUFBSSxDQUNuQixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixvQkFBb0IsRUFBRSxFQUN0QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsR0FBRyxDQUFDLENBQUM7UUFDckUsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGNBQWMsQ0FBQyxJQUFJLENBQ2pCLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLElBQUksQ0FBQyxDQUFDLENBQUMsRUFDUCxvQkFBb0IsRUFBRSxFQUN0QixZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQ2YsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQ3RDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDUCxJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxVQUFVLEVBQUUsQ0FBQztnQkFDeEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2pDLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsaUJBQWlCLENBQUMsSUFBSSxDQUNwQixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQ1Asb0JBQW9CLEVBQUUsRUFDdEIsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUNmLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUN0QyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxVQUFVLEVBQUUsQ0FBQztnQkFDeEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxDQUFDO1lBQy9CLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsY0FBYyxDQUFDLElBQUksQ0FDakIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDO1FBQ2xDLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxnQkFBZ0IsQ0FBQyxJQUFJLENBQ25CLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxHQUFHLENBQUMsQ0FBQztRQUNwQyxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsUUFBUSxDQUFDLElBQUksQ0FDWCxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLENBQUMsU0FBUyxDQUFDLG9CQUFvQixHQUFHLENBQUMsQ0FBQztRQUMxQyxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsUUFBUSxDQUFDLElBQUksQ0FDWCxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7UUFDN0IsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGFBQWEsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUNyRCxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixHQUFHLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsRUFBRSxFQUFFO1lBQzlCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMxRSxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsYUFBYSxDQUFDLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDNUQsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUNmLEdBQUcsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLEVBQUUsVUFBVSxDQUFDLEVBQUUsRUFBRTtZQUNyQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzVFLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQ3RDLCtCQUErQixHQUFHLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxZQUFZLEVBQUUsRUFDdEYsNkJBQTZCLEdBQUcsSUFBSSxDQUFDLDhCQUE4QixDQUFDLFlBQVksRUFBRSxFQUNsRixXQUFXLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxJQUFJLENBQ2pELE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDakIsRUFBRSxXQUFXLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsRUFDakQsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUNqQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQzFDLEVBQ0QsY0FBYyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUN2QyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQzFDLEVBQ0QsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQzlCLGdCQUFnQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFDeEMsY0FBYyxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQ3BDLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FDakMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksdUJBQXVCLENBQUMsQ0FBQyxDQUN2RCxFQUNELDBCQUEwQixHQUFHLElBQUksQ0FBQywwQkFBMEIsRUFDNUQsZUFBZSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUN6QyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxJQUFJLHVCQUF1QixDQUFDLENBQUMsQ0FDekUsRUFDRCxlQUFlLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFDdEMsY0FBYyxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQ3BDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxFQUNoQyxhQUFhLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQ3JDLG9CQUFvQixFQUFFLEVBQ3RCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQ3BDLEVBQ0QsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxDQUFDLElBQUksQ0FDN0Qsb0JBQW9CLEVBQUUsRUFDdEIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FDcEMsRUFDRCxjQUFjLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFDcEMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixFQUNoRCxhQUFhLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEVBQzNDLGFBQWEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQztRQUU5QyxXQUFXLENBQUMsSUFBSSxDQUNkLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztRQUMvQixDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsWUFBWSxDQUFDLElBQUksQ0FDZixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDMUIsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGFBQWEsQ0FBQyxDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDM0MsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFDMUIsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUNmLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDUCxJQUFJLENBQUMsa0JBQWtCLEVBQUUsVUFBVSxFQUFFLENBQUM7UUFDeEMsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGNBQWMsQ0FBQyxJQUFJLENBQ2pCLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQztRQUNsQyxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsYUFBYSxDQUFDLElBQUksQ0FDaEIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO1FBQ2pDLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxhQUFhLENBQUMsQ0FBQyxhQUFhLEVBQUUsb0JBQW9CLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDMUYsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0Isb0JBQW9CLEVBQUUsRUFDdEIsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUNqQixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQyxFQUFFLEVBQUU7WUFDbkUsSUFBSSxDQUFDLDhCQUE4QixDQUFDLElBQUksQ0FDdEMseUJBQXlCLENBQUMsS0FBSyxFQUFFLG1CQUFtQixFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTyxDQUFDLENBQ3ZGLENBQUM7UUFDSixDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsT0FBTyxDQUFDLElBQUksQ0FDVixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FDbkMsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0Isb0JBQW9CLEVBQUUsRUFDdEIsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ2hCLE9BQU8sYUFBYSxDQUFDLENBQUMsaUJBQWlCLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDaEYsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUNmLFNBQVMsQ0FBQyxDQUFDLENBQUMsWUFBWSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRTtnQkFDNUQsT0FBTyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN0RSxDQUFDLENBQUMsQ0FDSCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUVGLGlCQUFpQixDQUFDLElBQUksQ0FDcEIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsU0FBUyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRTtZQUNyRSxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO2dCQUMvRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO2dCQUNyRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1lBQ3RFLENBQUM7WUFDRCxPQUFPLDRCQUE0QixDQUFDLElBQUksQ0FDdEMsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFDZixTQUFTLENBQUMsR0FBRyxFQUFFO2dCQUNiLE9BQU8sRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDdEUsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUNKLENBQUMsQ0FBQyxFQUNGLEdBQUcsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUU7WUFDL0QsTUFBTSxXQUFXLEdBQUcsSUFBSSxJQUFJLEVBQWUsQ0FBQztZQUU1QyxJQUFJLFdBQVcsR0FBRyxLQUFLLENBQUM7WUFDeEIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUM3QyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUM1QyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDWCxNQUFNLEtBQUssR0FBRyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLFNBQVMsR0FBRyxZQUFZLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO29CQUMxRixJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQzt3QkFDWixXQUFXLEdBQUcsU0FBUyxDQUFDO29CQUMxQixDQUFDO3lCQUFNLENBQUM7d0JBQ04sSUFBSSxXQUFXLEVBQUUsQ0FBQzs0QkFDaEIsV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7d0JBQzVCLENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELE1BQU0sV0FBVyxHQUEyQixFQUFFLENBQUM7WUFDL0MsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUM3QyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUM1QyxJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO29CQUNsQyxTQUFTO2dCQUNYLENBQUM7Z0JBQ0QsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QixDQUFDO1lBRUQsTUFBTSxvQkFBb0IsR0FBRyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUUvRixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ2hELENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxXQUFXLENBQUMsSUFBSSxDQUNkLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLE1BQU0sRUFBRSxHQUFnQixJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQztZQUN2RCxlQUFlLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLHFCQUFxQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDeEgsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGVBQWUsQ0FBQyxJQUFJLENBQ2xCLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyx5QkFBeUIsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLHdCQUF3QixHQUFHLENBQUMsQ0FBQztRQUMvRSxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsY0FBYyxDQUFDLElBQUksQ0FDakIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsRUFBRSxhQUFhLENBQUM7WUFDakQsSUFBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxJQUFJLHVCQUF1QixDQUFDLEVBQUUsQ0FBQztnQkFDM0QsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztnQkFDOUIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQztnQkFDaEMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7b0JBQ1IsRUFBVSxDQUFDLElBQUksR0FBRyxhQUFhLENBQUM7Z0JBQ25DLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEdBQUcsbUJBQW1CLENBQUMsWUFBWSxDQUFDO1lBQ2pFLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxJQUFJLHVCQUF1QixDQUFDLEVBQUUsQ0FBQztnQkFDbkUsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztnQkFDL0IsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEtBQUssQ0FBQztnQkFDL0IsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7b0JBQ1IsRUFBVSxDQUFDLElBQUksR0FBRyxhQUFhLENBQUM7Z0JBQ25DLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxDQUFDO1lBQzNELENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxJQUFJLHVCQUF1QixDQUFDLEVBQUUsQ0FBQztnQkFDakUsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUM7Z0JBQ3pELElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO29CQUNSLEVBQVUsQ0FBQyxJQUFJLEdBQUcsU0FBUyxDQUFDO2dCQUMvQixDQUFDO2dCQUNELElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxHQUFHLG1CQUFtQixDQUFDLElBQUksQ0FBQztZQUN6RCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGVBQWUsQ0FBQyxJQUFJLENBQ2xCLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO2dCQUNwQyxJQUFJLENBQUMsUUFBUSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxLQUFLLENBQUM7WUFDdEksQ0FBQztpQkFBTSxJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxFQUFFLENBQUM7Z0JBQ3hDLElBQUksQ0FBQyxRQUFRLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQztnQkFDbkUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsS0FBSyxDQUFDO1lBQ3ZHLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsc0JBQXNCLEVBQUUsRUFBRSxDQUFDO2dCQUN6QyxJQUFJLENBQUMsUUFBUSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7Z0JBQ3JFLElBQUksQ0FBQyxRQUFRLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEtBQUssQ0FBQztZQUNyRyxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDO1FBRTNELHNCQUFzQixDQUFDLElBQUksQ0FDekIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNoQixHQUFHLENBQUMsR0FBRyxFQUFFO1lBQ1AsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDO2dCQUMzQixJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7Z0JBQ2xFLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNqQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDL0IsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO2dCQUN6QyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDZixJQUFJLENBQUMsU0FBUyxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUM3QyxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUMsQ0FBQyxFQUNGLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDUCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMzQyxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGlCQUFpQixDQUFDLElBQUksQ0FDcEIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDaEMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNiLE9BQU8sOEJBQThCLENBQUMsSUFBSSxDQUN4QyxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQ1AsR0FBRyxDQUFDLEdBQUcsRUFBRTtnQkFDUCxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMvQixDQUFDLENBQUMsQ0FDSCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLElBQUksY0FBYyxHQUFHLEtBQUssQ0FBQztRQUMzQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQy9CLFFBQVEsQ0FBQyxJQUFJLENBQ1gsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0Isb0JBQW9CLEVBQUUsRUFDdEIsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ2YsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNiLGNBQWMsR0FBRyxJQUFJLENBQUM7WUFDdEIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1lBQzFDLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNoQixTQUFTLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQzFCLFNBQVMsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQy9CLENBQUM7WUFDRCxPQUFPLFlBQVksQ0FBQyxJQUFJLENBQ3RCLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLElBQUksQ0FBQyxDQUFDLENBQUMsRUFDUCxHQUFHLENBQUMsR0FBRyxFQUFFO2dCQUNQLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDeEMsQ0FBQyxDQUFDLEVBQ0YsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FDaEQsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLEdBQUcsQ0FBQyxHQUFHLEVBQUU7Z0JBQ1AsY0FBYyxHQUFHLEtBQUssQ0FBQztnQkFDdkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO2dCQUNyQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7Z0JBQzFDLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDO29CQUNoQixTQUFTLENBQUMsYUFBYSxFQUFFLENBQUM7b0JBQzFCLFNBQVMsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO2dCQUMvQixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxDQUNILENBQUM7UUFDSixDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsUUFBUSxDQUFDLElBQUksQ0FDWCxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQ1Asb0JBQW9CLEVBQUUsRUFDdEIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDTixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztZQUN6QixDQUFDO1FBQ0gsQ0FBQyxDQUFDLEVBQ0YsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDZixHQUFHLENBQUMsR0FBRyxFQUFFO1lBQ1AsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUMsQ0FBQztRQUNILENBQUMsQ0FBQyxFQUNGLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFDakIsR0FBRyxDQUFDLEdBQUcsRUFBRTtZQUNQLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxNQUFNLE1BQU0sR0FBRyxDQUFDLE1BT2YsRUFBRSxFQUFFO1lBQ0gsTUFBTSxFQUNKLFNBQVMsRUFBRSw4QkFBOEIsRUFBRSw0QkFBNEIsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUM1RixpQkFBaUIsRUFBRSxlQUFlLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFDaEksV0FBVyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLHlCQUF5QixFQUFFLFVBQVUsRUFDOUgsZUFBZSxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLGFBQWEsR0FDdkUsR0FBRyxNQUFNLENBQUM7WUFDWCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7WUFDekMsSUFBSSxTQUFTLEdBQUcsQ0FBQyxDQUFDO1lBQ2xCLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUNmLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsV0FBVyxHQUFHLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLFlBQVksR0FBRyxRQUFRLElBQUksQ0FBQyxNQUFNLEVBQzVKLFVBQVUsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLElBQUksWUFBWSxJQUFJLFdBQVcsSUFBSSxjQUFjLEVBQ2pGLFVBQVUsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsRUFDakUsaUJBQWlCLEdBQUcsVUFBVSxJQUFJLENBQUMsVUFBVSxDQUFDO2dCQUNoRCxJQUFJLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxRQUFRLElBQUksTUFBTSxDQUFDLEVBQUUsQ0FBQztvQkFDL0MsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO29CQUNsRixJQUFJLGdCQUFnQixHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQzt3QkFDM0gsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFDdkQsZ0JBQWdCLEdBQUcsQ0FBQyxFQUNwQixZQUEwQyxDQUFDO29CQUU3QyxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sRUFBRSxZQUFZLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQzVFLElBQUksR0FBdUU7d0JBQ3pFLE1BQU0sRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxhQUFhO3dCQUNqSCxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLHlCQUF5QixFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQUUsYUFBYTtxQkFDbkgsQ0FBQztvQkFFSixJQUFJLGVBQWUsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQzt3QkFDM0MsTUFBTSxFQUFFLFlBQVksRUFBRSxzQkFBc0IsRUFBRSxTQUFTLEVBQUUsb0JBQW9CLEVBQUUsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQUUsR0FDbEgsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEVBQUUsR0FBRyxJQUFJLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLENBQUMsQ0FBQzt3QkFDbkcsWUFBWSxHQUFHLHNCQUFzQixDQUFDO3dCQUN0QyxTQUFTLEdBQUcsb0JBQW9CLENBQUM7d0JBQ2pDLGdCQUFnQixHQUFHLGlCQUFpQixDQUFDO29CQUN2QyxDQUFDO3lCQUFNLENBQUM7d0JBQ04sTUFBTSxFQUFFLFlBQVksRUFBRSxzQkFBc0IsRUFBRSxTQUFTLEVBQUUsbUJBQW1CLEVBQUUsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsSUFBSSxDQUFDLENBQUM7d0JBQ2xMLFlBQVksR0FBRyxzQkFBc0IsQ0FBQzt3QkFDdEMsU0FBUyxHQUFHLG1CQUFtQixDQUFDO3dCQUNoQyxnQkFBZ0IsR0FBRyxpQkFBaUIsQ0FBQztvQkFDdkMsQ0FBQztvQkFFRCxRQUFRLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztvQkFFL0IsUUFBUSxDQUFDLGlCQUFpQixHQUFHLGdCQUFnQixDQUFDO29CQUU5QyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFFakMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEdBQUcsWUFBWSxDQUFDO29CQUV4QyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztvQkFFNUMsSUFBSSxDQUFDLDZCQUE2QixDQUFDLFlBQVksQ0FBQyxDQUFDO29CQUVqRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBRWhCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFFdkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDO3dCQUMxQixTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUN2QixDQUFDO29CQUVELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUNoQyx5QkFBeUIsR0FBRyxnQkFBZ0IsR0FBRyxLQUFLLEVBQ3BELGdDQUFnQyxHQUFHLHlCQUF5QixFQUM1RCw2QkFBNkIsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUM7b0JBRTVGLElBQUksSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7d0JBQ25DLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO29CQUMvQixDQUFDO29CQUVELFFBQVEsU0FBUyxFQUFFLENBQUM7d0JBQ2xCLEtBQUssVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7NEJBQ3JCLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQUMsQ0FBQzs0QkFDcEUsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDOzRCQUNoRSxNQUFNO3dCQUNSLENBQUM7d0JBQ0QsS0FBSyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQzs0QkFDdkIsTUFBTSxXQUFXLEdBQWMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFDcEYsU0FBUyxHQUFjLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUMvRixvQkFBb0IsR0FBRyxZQUFZLEdBQUcsRUFBRSxHQUFHLENBQUMsV0FBVyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLEVBQUUsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0NBQ3hJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUN0RixrQkFBa0IsR0FBRyxZQUFZLEdBQUcsRUFBRSxHQUFHLENBQUMsU0FBUyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLEVBQUUsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0NBQ2xJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDOzRCQUV2RixJQUFJLENBQUMsNEJBQTRCLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7NEJBQzdELElBQUksQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQzs0QkFDekQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyw4QkFBOEIsR0FBRyxvQkFBb0IsQ0FBQyxDQUFDOzRCQUMzRixJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLDRCQUE0QixHQUFHLGtCQUFrQixDQUFDLENBQUM7NEJBQ3JGLE1BQU07d0JBQ1IsQ0FBQztvQkFDSCxDQUFDO29CQUVELFFBQVEsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO29CQUV2QixJQUFJLENBQUMsaUJBQWlCLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsSUFBSSxRQUFRLENBQUMsVUFBVSxDQUFDO3dCQUMvRSxDQUFDLGlCQUFpQixJQUFJLGlCQUFpQixJQUFJLCtCQUErQixDQUFDLEVBQUUsQ0FBQzt3QkFDOUUsSUFBSSxpQkFBaUIsS0FBSyxnQ0FBZ0MsRUFBRSxDQUFDOzRCQUMzRCxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDOzRCQUU1QixJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztnQ0FDdkIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDOzRCQUNoRCxDQUFDOzRCQUNELElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDOzRCQUMzQixNQUFNLE1BQU0sR0FBb0I7Z0NBQzlCLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsRUFBRSxVQUFVO2dDQUM1RCxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLGdCQUFnQjtnQ0FDekQsUUFBUSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZOzZCQUM3RCxDQUFDOzRCQUNGLFFBQVEsRUFBRSxRQUFRLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQzs0QkFDN0IsSUFBSSxVQUFVLEVBQUUsQ0FBQztnQ0FDZixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7NEJBQ3BILENBQUM7d0JBQ0gsQ0FBQzt3QkFDRCxPQUFPO29CQUNULENBQUM7b0JBRUQsSUFBSSxDQUFDLGVBQWUsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsZUFBZSxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQzt3QkFDakcsQ0FBQyx5QkFBeUIsR0FBRywrQkFBK0IsSUFBSSw2QkFBNkIsQ0FBQzt3QkFDOUYsQ0FBQyxnQ0FBZ0MsSUFBSSx5QkFBeUIsR0FBRywrQkFBK0IsQ0FBQyxFQUFFLENBQUM7d0JBQ3BHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLENBQUM7d0JBRTVCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxDQUFDOzRCQUNuQyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7NEJBQ2xDLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQzt3QkFDdkMsQ0FBQzt3QkFFRCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQzs0QkFDdkIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO3dCQUMzQyxDQUFDO3dCQUNELE1BQU0sTUFBTSxHQUFvQjs0QkFDOUIsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLEVBQUUsNkJBQTZCOzRCQUM1RSxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLFVBQVUsRUFBRSxLQUFLOzRCQUM1RSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVk7eUJBQzdELENBQUM7d0JBQ0YsUUFBUSxFQUFFLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDO3dCQUM3QixJQUFJLFVBQVUsRUFBRSxDQUFDOzRCQUNmLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQzt3QkFDcEgsQ0FBQzt3QkFDRCxPQUFPO29CQUNULENBQUM7b0JBRUQsSUFBSSxVQUFVLEtBQUsseUJBQXlCO3dCQUMxQyxDQUFDLENBQUMseUJBQXlCLElBQUksQ0FBQyxJQUFJLHlCQUF5QixHQUFHLDZCQUE2QixDQUFDOzRCQUM1RixDQUFDLFVBQVUsS0FBSyw2QkFBNkIsSUFBSSxpQkFBaUIsS0FBSyx5QkFBeUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQzt3QkFDdkcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQzt3QkFFNUIsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7NEJBQ3ZCLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQzt3QkFDaEQsQ0FBQzt3QkFDRCxNQUFNLE1BQU0sR0FBb0I7NEJBQzlCLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxFQUFFLHlCQUF5QixFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsVUFBVTs0QkFDcEcsVUFBVSxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZO3lCQUNwRixDQUFDO3dCQUNGLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7d0JBQzFCLElBQUksVUFBVSxFQUFFLENBQUM7NEJBQ2YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO3dCQUNwSCxDQUFDO3dCQUNELE9BQU87b0JBQ1QsQ0FBQztnQkFDSCxDQUFDO2dCQUNELElBQUksVUFBVSxFQUFFLENBQUM7b0JBQ2YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO2dCQUNwSCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUMsQ0FBQztRQUVGLElBQUksU0FBUyxHQUEyQixFQUFFLENBQUM7UUFDM0MsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsa0RBQWtELENBQUMsQ0FBQztRQUNoRyxTQUFTLENBQUMsSUFBSSxDQUNaLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDaEIsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNiLE9BQU8sYUFBYSxDQUFDLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLFdBQVc7Z0JBQ3ZLLGVBQWUsRUFBRSxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxXQUFXO2dCQUNwSSxZQUFZLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSwwQkFBMEIsRUFBRSxjQUFjLEVBQUUsVUFBVTtnQkFDN0csK0JBQStCLEVBQUUsNkJBQTZCLEVBQUUsYUFBYSxFQUFFLElBQUksQ0FBQyxXQUFXO2FBQ2hHLENBQUMsQ0FBQyxJQUFJLENBQ0wsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLENBQUMsQ0FDSCxPQUFPLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixFQUFFLGVBQWUsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUNySixXQUFXLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQ2xJLHlCQUF5QixFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsOEJBQThCLEVBQUUsNEJBQTRCLEVBQUUsWUFBWSxFQUNoSSxFQUFFLEVBQUU7Z0JBQ0gsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDO2dCQUN6QixJQUFJLFNBQVMsS0FBSyxLQUFLLEVBQUUsQ0FBQztvQkFDeEIsWUFBWSxHQUFHLElBQUksQ0FBQztvQkFDcEIsU0FBUyxHQUFHLEtBQUssQ0FBQztnQkFDcEIsQ0FBQztnQkFDRCxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxZQUFZLElBQUksMEJBQTBCLENBQUMsWUFBWSxFQUN6RyxRQUFRLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFLGVBQWUsSUFBSSxDQUFDLEVBQ3hELFdBQVcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxFQUMzQyxrQkFBa0IsR0FBRyxDQUFDLFdBQVcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxlQUFlLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxhQUFhLElBQUksQ0FBQyxXQUFXO29CQUMzSixDQUFDLFFBQVEsR0FBRyxDQUFDLElBQUksUUFBUSxHQUFHLGlEQUFpRCxDQUFDLENBQUM7Z0JBQ25GLElBQUksbUJBQW1CLEVBQUUsQ0FBQztvQkFDeEIsSUFBSSxrQkFBa0IsRUFBRSxDQUFDO3dCQUN2QixlQUFlLENBQUMsT0FBTyxDQUFDOzRCQUN0QixPQUFPLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixFQUFFLGVBQWUsRUFBRSxNQUFNLEVBQUUsTUFBTyxFQUFFLFVBQVUsRUFBRSxVQUFXLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxXQUFXOzRCQUMzSyxXQUFXLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLGFBQWE7NEJBQy9JLFVBQVUsRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFFLDhCQUE4QixFQUFFLDRCQUE0QixFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsYUFBYTt5QkFDOUksQ0FBQyxDQUFDO3dCQUNILE9BQU87b0JBQ1QsQ0FBQztvQkFFRCxlQUFlLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQzVCLENBQUM7Z0JBRUQsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO29CQUNqQixNQUFNLENBQUM7d0JBQ0wsT0FBTyxFQUFFLFVBQVUsRUFBRSxpQkFBaUIsRUFBRSxlQUFlLEVBQUUsTUFBTSxFQUFFLE1BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVyxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsV0FBVzt3QkFDM0ssV0FBVyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxhQUFhO3dCQUMvSSxVQUFVLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSw4QkFBOEIsRUFBRSw0QkFBNEIsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLGFBQWE7cUJBQzlJLENBQUMsQ0FBQztnQkFDTCxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FDbkMsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNoQixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFFLENBQUMsYUFBYSxDQUFDLEVBQzFCLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FDUixFQUNDLGVBQWUsR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQ3ZDLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDaEIsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLFNBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLFFBQVMsQ0FBQyxPQUFPLENBQUMsQ0FDekMsRUFDRCxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQzFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDaEIsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLFNBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLFFBQVMsQ0FBQyxVQUFVLENBQUMsQ0FDNUMsRUFDRCxnQkFBZ0IsR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQ3hDLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDaEIsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLFNBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLFFBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUNsRCxDQUFDO1FBRUosTUFBTSxhQUFhLEdBQUcsQ0FBQyxhQUFzQixLQUFLLEVBQUUsRUFBRTtZQUNwRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7WUFDekMsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2YsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFDakMsVUFBVSxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQ3BFLGdCQUFnQixHQUFHLFVBQVUsQ0FBQztnQkFFaEMsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7b0JBQ3ZCLElBQUksVUFBVSxFQUFFLENBQUM7d0JBQ2YsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDMUMsQ0FBQztnQkFDSCxDQUFDO2dCQUVELElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDM0MsQ0FBQztRQUNILENBQUMsQ0FBQztRQUVGLFNBQVMsQ0FBQyxJQUFJLENBQ1osU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0Isb0JBQW9CLEVBQUUsRUFDdEIsU0FBUyxDQUFDLFFBQVEsQ0FBQyxFQUFFO1lBQ25CLE9BQU8sZ0JBQWdCLENBQUMsSUFBSSxDQUMxQixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUU7Z0JBQ2YsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxhQUFhLEVBQUUsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO2dCQUMxRyxJQUFJLENBQUMsQ0FBQyxVQUFVLElBQUksQ0FBQyxDQUFDLGlCQUFpQixFQUFFLENBQUM7b0JBQ3hDLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsYUFBYSxDQUFDLENBQUM7Z0JBQ2pFLENBQUM7Z0JBQ0QsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7b0JBQ3ZCLElBQUksVUFBVSxFQUFFLENBQUM7d0JBQ2YsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixFQUFFLENBQUM7NEJBQ3BDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQzFDLENBQUM7d0JBQ0QsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxDQUFDOzRCQUNsQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO3dCQUMxQyxDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUNILENBQUM7UUFDSixDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsU0FBUyxDQUFDLElBQUksQ0FDWixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixvQkFBb0IsRUFBRSxFQUN0QixTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUU7WUFDbkIsT0FBTyxlQUFlLENBQUMsSUFBSSxDQUN6QixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUM5QixDQUFDO1FBQ0osQ0FBQyxDQUFDLEVBQ0YsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQ2YsYUFBYSxHQUFHLFVBQVUsQ0FBQztZQUMzQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxFQUFFLGFBQWEsRUFBRSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7WUFDMUcsSUFBSSxDQUFDLENBQUMsVUFBVSxJQUFJLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO2dCQUN4QyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQzlELENBQUM7WUFDRCxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLFNBQVMsQ0FBQyxJQUFJLENBQ1osU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0Isb0JBQW9CLEVBQUUsRUFDdEIsU0FBUyxDQUFDLFFBQVEsQ0FBQyxFQUFFO1lBQ25CLE9BQU8sa0JBQWtCLENBQUMsSUFBSSxDQUM1QixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUM5QixDQUFDO1FBQ0osQ0FBQyxDQUFDLEVBQ0YsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQ2YsYUFBYSxHQUFHLFVBQVUsQ0FBQztZQUMzQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxFQUFFLGFBQWEsRUFBRSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7WUFDMUcsSUFBSSxDQUFDLENBQUMsVUFBVSxJQUFJLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO2dCQUN4QyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQzdELENBQUM7WUFDRCxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQzlCLGlCQUFpQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztRQUU3QyxhQUFhLENBQUMsQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUNsRCxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxBQUFELEVBQUcsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUN0RCxHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEVBQzdFLFNBQVMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUN0QixNQUFNLENBQUMsR0FBRyxLQUFLLEVBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDVixPQUFPLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQ25CLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FDVCxDQUFDO1lBQ0osQ0FBQztZQUNELE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25CLENBQUMsQ0FBQyxFQUNGLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUNWLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzlCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGlCQUFpQixDQUFDLElBQUksQ0FDcEIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ2hCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUN2RSxFQUFFLEVBQUUsRUFBRSxTQUFTLEdBQUcsQ0FBQyxFQUFFLFFBQVEsR0FBRyxLQUFLLEVBQUUsZUFBZSxHQUFHLEtBQUssRUFBRSxFQUFFLEVBQUUsR0FBRyxLQUFLLENBQUM7WUFDL0UsTUFBTSxhQUFhLEdBQUcsU0FBUyxHQUFHLENBQUMsRUFBRSxRQUFRLEdBQUcsYUFBYSxJQUFJLHdCQUF3QixFQUFFLFVBQVUsR0FBRyxLQUFLLENBQUM7WUFFOUcsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztnQkFDeEIsT0FBTyxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN2RixDQUFDO1lBRUQsZUFBZSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFeEMsSUFBSSxDQUFDLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztnQkFDeEIsaUJBQWlCLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBRWxDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQzVDLElBQUksQ0FBQyxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7b0JBQzVCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsUUFBUSxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsV0FBVyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFDeEcsV0FBVyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxlQUFlLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQztvQkFFL0UsSUFBSSxXQUFXLEVBQUUsQ0FBQzt3QkFDaEIsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxFQUMzRyxhQUFhLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFDakUsaUJBQWlCLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLFVBQVUsRUFDM0YsSUFBSSxHQUFzRTs0QkFDeEUsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsV0FBVzs0QkFDM0gsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhOzRCQUNqRyxVQUFVLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDOzRCQUNyRixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxlQUFlLEVBQUUsSUFBSSxDQUFDLGVBQWU7NEJBQ2xFLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUseUJBQXlCLEVBQUUsSUFBSSxDQUFDLHlCQUF5Qjt5QkFDN0csQ0FBQzt3QkFFSixJQUFJLFVBQVUsR0FBRyxlQUFlLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsQ0FBQzs0QkFDakUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQzs0QkFDL0UsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsRUFBRSxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQzt3QkFFMUQsSUFBSSxVQUFVLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQzs0QkFDdEIsT0FBTyxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDdkYsQ0FBQzt3QkFFRCxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDO3dCQUU1QixNQUFNLFlBQVksR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFDaEQsRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFOzRCQUNwRyxHQUFHLElBQUksRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFO3lCQUNsRSxDQUFDLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDO3dCQUVwQyxNQUFNLG1CQUFtQixHQUFHLFNBQVMsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO3dCQUVoRixpQkFBaUIsQ0FBQyxpQkFBaUIsR0FBRyxnQkFBZ0IsQ0FBQzt3QkFFdkQsaUJBQWlCLENBQUMsU0FBUyxHQUFHLG1CQUFtQixDQUFDO3dCQUVsRCxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsR0FBRyxZQUFZLENBQUM7d0JBRXhDLElBQUksZ0JBQWdCLEdBQUcsVUFBVSxHQUFHLE1BQU0sQ0FBQzt3QkFFM0MsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEVBQUUsbUJBQW1CLENBQUMsQ0FBQzt3QkFFdEQsSUFBSSxDQUFDLDZCQUE2QixDQUFDLFlBQVksQ0FBQyxDQUFDO3dCQUVqRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7d0JBRWhCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQzt3QkFFdkIsVUFBVSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLEVBQUUsRUFBRSxhQUFhLEVBQUUsRUFBRSxHQUFHLElBQUksRUFBRSxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7d0JBRTFILElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDOzRCQUNwQixJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQ0FDcEIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUM7Z0NBQ3BELElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO29DQUNqQixNQUFNLFFBQVEsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUM7b0NBQ25FLFFBQVEsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO3dDQUM3QixLQUFLLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7NENBQzdCLFVBQVUsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDOzRDQUM1QixNQUFNO3dDQUNSLENBQUM7b0NBQ0gsQ0FBQztnQ0FDSCxDQUFDOzRCQUNILENBQUM7d0JBQ0gsQ0FBQzt3QkFFRCxJQUFJLFVBQVUsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDOzRCQUN0QixPQUFPLEVBQUUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUN2RixDQUFDO3dCQUNELE1BQU0sVUFBVSxHQUFHLFVBQVUsS0FBSyxpQkFBaUIsQ0FBQzt3QkFDcEQsSUFBSSxDQUFDLFVBQVUsSUFBSSxTQUFTLEdBQUcsd0JBQXdCLEVBQUUsQ0FBQzs0QkFDeEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQzs0QkFDNUIsTUFBTSxNQUFNLEdBQW9CO2dDQUM5QixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLGdCQUFrQztnQ0FDdkcsVUFBVSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEtBQUs7NkJBQ2pFLENBQUM7NEJBQ0YsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUM7NEJBQ3RDLE9BQU8sRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFO29DQUNuQixFQUFFLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxRQUFRO29DQUN0QyxlQUFlLEVBQUUsYUFBYSxHQUFHLHdCQUF3QixFQUFFLEVBQUU7aUNBQzlELENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDckIsQ0FBQzs2QkFBTSxDQUFDOzRCQUNOLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7NEJBQ3pDLE9BQU8sRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQ25GLENBQUM7b0JBQ0gsQ0FBQzt5QkFBTSxDQUFDO3dCQUNOLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7d0JBQzVELElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7NEJBQ2YsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQzs0QkFDcEUsSUFBSSxVQUFVLEdBQUcsS0FBSyxHQUFHLFFBQVEsQ0FBQzs0QkFFbEMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Z0NBQ3BCLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO29DQUNwQixRQUFRLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQzt3Q0FDN0IsS0FBSyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDOzRDQUM3QixVQUFVLElBQUksUUFBUSxHQUFHLEVBQUUsQ0FBQzs0Q0FDNUIsTUFBTTt3Q0FDUixDQUFDO29DQUNILENBQUM7Z0NBQ0gsQ0FBQzs0QkFDSCxDQUFDOzRCQUVELE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsaUJBQWlCLEVBQUUsRUFDM0csYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLEVBQ3pFLElBQUksR0FBc0U7Z0NBQ3hFLE1BQU0sRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLFdBQVc7Z0NBQzNILFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYTtnQ0FDakcsVUFBVSxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQztnQ0FDckYsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsZUFBZSxFQUFFLElBQUksQ0FBQyxlQUFlO2dDQUNsRSxhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLHlCQUF5QixFQUFFLElBQUksQ0FBQyx5QkFBeUI7NkJBQzdHLENBQUM7NEJBRUosSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQzs0QkFFNUIsTUFBTSxZQUFZLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQ2hELEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRTtnQ0FDcEcsR0FBRyxJQUFJLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRTs2QkFDbEUsQ0FBQyxDQUFDOzRCQUVMLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7NEJBRWpGLE1BQU0sbUJBQW1CLEdBQUcsZUFBZSxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUM7NEJBRTVGLGlCQUFpQixDQUFDLGlCQUFpQixHQUFHLGdCQUFnQixDQUFDOzRCQUV2RCxpQkFBaUIsQ0FBQyxTQUFTLEdBQUcsbUJBQW1CLENBQUM7NEJBRWxELElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxHQUFHLFlBQVksQ0FBQzs0QkFFeEMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLEVBQUUsbUJBQW1CLENBQUMsQ0FBQzs0QkFFdEQsSUFBSSxDQUFDLDZCQUE2QixDQUFDLFlBQVksQ0FBQyxDQUFDOzRCQUVqRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7NEJBRWhCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQzs0QkFFdkIsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzs0QkFFeEMsTUFBTSxNQUFNLEdBQW9CO2dDQUM5QixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxLQUFLO2dDQUNsRixRQUFRLEVBQUUsZ0JBQWtDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsS0FBSzs2QkFDbkcsQ0FBQzs0QkFDRixpQkFBaUIsRUFBRSxRQUFRLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQzs0QkFDdEMsT0FBTyxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO3dCQUNwRSxDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFDRCxPQUFPLEVBQUUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDeEUsQ0FBQyxDQUFDLEVBQ0YsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLEVBQUUsRUFBRTtZQUN6QixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2QsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxNQUF1QixDQUFDLENBQUM7Z0JBQ3RELE9BQU87WUFDVCxDQUFDO1lBRUQsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxTQUFTLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDN0MsQ0FBQztZQUVELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDO1lBQzVDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzdCLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztZQUN4QyxNQUFNLFlBQVksR0FBRyxNQUFvRCxDQUFDO1lBQzFFLFlBQVksRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQ3ZCLENBQUMsQ0FBQyxFQUNGLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFDVixHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUU7WUFDakIsSUFBSSxRQUFRLEVBQUUsQ0FBQztnQkFDYixJQUFJLENBQUMsa0JBQWtCLEVBQUUsVUFBVSxFQUFFLENBQUM7WUFDeEMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBRXpDLGFBQWEsQ0FBQyxJQUFJLENBQ2hCLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLG9CQUFvQixFQUFFLEVBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDaEIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUIsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLE9BQU8sQ0FBQyxJQUFJLENBQ1YsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0Isb0JBQW9CLEVBQUUsRUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNoQixHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDVixNQUFNLElBQUksR0FBVSxFQUFFLEtBQUssRUFBRSxLQUFNLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDbkUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3JELENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQzlCLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0MsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLElBQUksc0JBQXNCLEdBQUcsQ0FBQyxDQUFDO1FBRS9CLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLElBQUksQ0FDN0IsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0Isb0JBQW9CLEVBQUUsRUFDdEIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxJQUFJLENBQUMsa0JBQWtCLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLElBQUksc0JBQXNCLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDdkYsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztnQkFDOUIsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ3pFLENBQUMsc0JBQXNCLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLHNCQUFzQixHQUFHLENBQUMsRUFBRSxDQUFDO29CQUM3RyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM3QyxDQUFDO1lBQ0gsQ0FBQztZQUNELElBQUksc0JBQXNCLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQy9CLHNCQUFzQixFQUFFLENBQUM7WUFDM0IsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxZQUFZLENBQUMsSUFBSSxDQUNmLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQzdCLG9CQUFvQixFQUFFLEVBQ3RCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQztRQUNoQyxDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsU0FBUyxDQUFDLElBQUksQ0FDWixTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ2hCLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDYixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLElBQUksQ0FDckMsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0Isb0JBQW9CLEVBQUUsRUFDdEIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNOLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDaEQsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsSUFBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQzVHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ2hDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQy9DLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FDSCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGFBQWEsQ0FBQyxDQUFDLGVBQWUsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUNyRSxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUM3QixHQUFHLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUU7WUFDdEQsTUFBTSxXQUFXLEdBQUcsY0FBYyxDQUFDLGNBQWMsRUFBRSxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDOUUsSUFBSSxXQUFXLEVBQUUsQ0FBQztnQkFDaEIsTUFBTSxTQUFTLEdBQWMsRUFBRSxDQUFDO2dCQUNoQyxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO29CQUM5QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7d0JBQzdDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLFdBQVcsR0FBRyxhQUFhLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxXQUFXLEtBQUssSUFBSSxDQUFDO3dCQUNuRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7NEJBQ2pCLFNBQVM7d0JBQ1gsQ0FBQzt3QkFDRCxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO29CQUNyQixDQUFDO2dCQUNILENBQUM7Z0JBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsSUFBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsRUFBRSxDQUFDLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQ2xKLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBQ3hDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZELENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVkLGlCQUFpQixDQUFDLElBQUksQ0FDcEIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0Isb0JBQW9CLEVBQUUsRUFDdEIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO1FBQ2pDLENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FDaEIsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFDN0IsR0FBRyxDQUFDLEdBQUcsRUFBRTtZQUNQLGVBQWUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FDSCxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFM0IsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVPLGFBQWEsQ0FBQyxNQUFNLEdBQUcsS0FBSztRQUNsQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFdkIsSUFBSSxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztZQUNuQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUMvQixDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ2pDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztZQUN6QyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDZixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO2dCQUN0QyxJQUFJLFVBQVUsRUFBRSxDQUFDO29CQUNmLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNoQyxDQUFDO2dCQUNELFFBQVEsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQzNDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVPLHFCQUFxQjtRQUMzQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDdkQsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQ3JDLFdBQVcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzlDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxZQUFZLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUM3RCxDQUFDO0lBQ0gsQ0FBQztJQUVPLGVBQWU7UUFDckIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1FBQ3pDLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2YsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFDaEMsYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsWUFBWSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsSUFBSSxDQUFDLENBQUMsRUFDL0YsVUFBVSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVLElBQUksQ0FBQyxFQUM1RSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzVDLElBQUksSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDM0MsTUFBTSxXQUFXLEdBQUcsQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLGFBQWEsR0FBRywrQkFBK0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDO2dCQUNsSixJQUFJLFdBQVcsRUFBRSxDQUFDO29CQUNoQixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDakMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQzlCLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztvQkFDckMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO2dCQUNwQyxDQUFDO3FCQUFNLENBQUM7b0JBQ04sTUFBTSxhQUFhLEdBQUcsQ0FBQyxnQkFBZ0IsSUFBSSwrQkFBK0IsQ0FBQyxDQUFDO29CQUM1RSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztvQkFDekMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQy9CLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztvQkFDN0MsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO2dCQUNyQyxDQUFDO1lBQ0gsQ0FBQztpQkFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUMvQixNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxRQUFRLEVBQUUsRUFBRSxlQUFlLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUMvSCxJQUFJLENBQUMsaUJBQWlCLElBQUksZUFBZSxFQUFFLENBQUM7b0JBQzFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUNqQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDOUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO29CQUNyQyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7Z0JBQ3BDLENBQUM7cUJBQU0sSUFBSSxpQkFBaUIsSUFBSSxlQUFlLEVBQUUsQ0FBQztvQkFDaEQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ2hDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUMvQixJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7b0JBQ3BDLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztnQkFDckMsQ0FBQztxQkFBTSxDQUFDO29CQUNOLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUNqQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDL0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO29CQUNyQyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7Z0JBQ3JDLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFBQSxDQUFDO0lBRU0sZUFBZSxDQUFDLGNBQXVCLEtBQUssRUFBRSxTQUFrQixJQUFJLEVBQUUsYUFBc0IsS0FBSztRQUN2RyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3hCLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxhQUFhLEVBQUUsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1FBQzFHLElBQUksVUFBVSxJQUFJLGlCQUFpQixFQUFFLENBQUM7WUFDcEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxVQUFVLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDLEVBQ3pILGFBQWEsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsRUFDN0YsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxDQUFDO1lBQzNHLE1BQU0sVUFBVSxHQUFHLHdCQUF3QixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxRQUFRLEVBQUUsRUFBRSxJQUFJLENBQUMsdUJBQXVCLENBQUMsUUFBUSxFQUFFLEVBQ3hKLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxDQUFDLEVBQy9CLEtBQUssR0FBRyxJQUFJLFdBQVcsQ0FBQztnQkFDdEIsU0FBUyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxlQUFlLElBQUksQ0FBQyxFQUFFLFNBQVMsRUFBRSxVQUFVO2dCQUMvRSxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUcsQ0FBQyxhQUFhLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSztnQkFDeEUsZUFBZSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLFVBQVU7Z0JBQzNELFVBQVU7Z0JBQ1YsVUFBVTtnQkFDVixLQUFLLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQy9ILFVBQVU7YUFDWCxDQUFDLENBQUM7WUFDTCxJQUFJLE1BQU0sRUFBRSxDQUFDO2dCQUNYLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzVCLENBQUM7WUFFRCxJQUFJLFdBQVcsRUFBRSxDQUFDO2dCQUNoQixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMvQixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8sMkJBQTJCLENBQUMsQ0FBa0I7UUFDcEQsTUFBTSxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDeEMsT0FBTyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRU8sa0JBQWtCLENBQUMsQ0FBaUI7UUFDMUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDckMsT0FBTyxZQUFZLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRU8sb0JBQW9CLENBQUMsQ0FBaUI7UUFDNUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDckMsT0FBTyxZQUFZLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRU8sbUJBQW1CLENBQUMsQ0FBaUI7UUFDM0MsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDckMsT0FBTyxZQUFZLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRU8saUJBQWlCLENBQUMsQ0FBa0I7UUFDMUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDdEMsT0FBTyxjQUFjLENBQUMsSUFBSSxFQUFFLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRU8scUJBQXFCLENBQUMsQ0FBa0I7UUFDOUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDdEMsT0FBTyxjQUFjLENBQUMsSUFBSSxFQUFFLGVBQWUsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRU8sc0JBQXNCLENBQUMsQ0FBa0I7UUFDL0MsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDdEMsT0FBTyxjQUFjLENBQUMsSUFBSSxFQUFFLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRU8sYUFBYSxDQUFDLENBQWE7UUFDakMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDaEMsT0FBTyxXQUFXLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRU8sU0FBUyxDQUFDLENBQWtCO1FBQ2xDLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDO1FBQ3RDLE9BQU8sZ0JBQWdCLENBQUMsSUFBSSxFQUFFLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRU8sNkJBQTZCLENBQUMsWUFBaUQ7UUFDckYsSUFBSSxDQUFDLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzdDLElBQUksQ0FBQyxTQUFTLENBQUMsNEJBQTRCLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDaEQsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyx5QkFBeUIsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDekQsSUFBSSxJQUFJLENBQUMseUJBQXlCLENBQUMsTUFBTSxHQUFHLDZCQUE2QixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztnQkFDdEcsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsTUFBTSxHQUFHLDZCQUE2QixFQUFFLENBQUM7b0JBQzdFLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7b0JBQzlFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBQ3hELElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztvQkFDN0IsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDMUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyx3QkFBd0IsR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUM7b0JBQ3pFLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLGNBQWMsQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQUMsQ0FBQztvQkFDdEYsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUM3RCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxZQUFZLENBQUM7UUFFcEMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUM7UUFFaEQsTUFBTSxTQUFTLEdBQUcsWUFBWSxDQUFDLE1BQU0sRUFBRSxVQUFVLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1FBRTVFLElBQUksQ0FBQyxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDdkIsTUFBTSxLQUFLLEdBQTZCLEVBQUUsQ0FBQztZQUMzQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDVixLQUFLLElBQUksQ0FBQyxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUMzQyxNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNCLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO29CQUNYLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO29CQUM1QixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUN4RCxLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNoQixDQUFDO1lBQ0gsQ0FBQztZQUNELE9BQU8sVUFBVSxDQUFDLE1BQU0sR0FBRyxTQUFTLEVBQUUsQ0FBQztnQkFDckMsTUFBTSxJQUFJLEdBQUcsZ0JBQWdCLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO2dCQUN4RSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDeEQsS0FBSyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDZCxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN0QixDQUFDLEVBQUUsQ0FBQztZQUNOLENBQUM7WUFDRCxJQUFJLENBQUMsU0FBUyxDQUFDLDRCQUE0QixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JELENBQUM7SUFDSCxDQUFDO0lBRU8scUJBQXFCO1FBQzNCLElBQUksQ0FBQyw4QkFBOEIsRUFBRSxDQUFDO0lBQ3hDLENBQUM7SUFFRDs7T0FFRztJQUNLLFFBQVE7UUFDZCxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFTyxlQUFlLENBQUMsVUFBbUIsRUFBRSxTQUFpQjtRQUM1RCxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFLElBQUksR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxlQUFlLEVBQ3RGLElBQUksR0FBRyxTQUFTLENBQUM7UUFDbkIsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQzFELENBQUMsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQUUsRUFBRSxDQUFDO1FBQy9DLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxhQUFhLENBQUMsRUFBTTtRQUNsQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxFQUFNLEVBQUUsUUFBd0IsZUFBZSxDQUFDLElBQUk7UUFDeEQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsUUFBUSxDQUFDLEVBQU0sRUFBRSxLQUEwQixJQUFJLEVBQUUsVUFBaUMsSUFBSTtRQUNwRixNQUFNLFFBQVEsR0FBRyxPQUFPLEVBQUUsUUFBUSxJQUFJLGdCQUFnQixFQUNwRCxRQUFRLEdBQUcsT0FBTyxFQUFFLFFBQVEsSUFBSSxLQUFLLEVBQ3JDLE9BQU8sR0FBRyxPQUFPLEVBQUUsT0FBTyxJQUFJLElBQUksRUFDbEMsS0FBSyxHQUFHLE9BQU8sRUFBRSxLQUFLLElBQUksQ0FBQyxFQUMzQixTQUFTLEdBQUcsT0FBTyxFQUFFLFNBQVMsSUFBSSxDQUFDLENBQUM7UUFDdEMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2Ysc0JBQXNCLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDakMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDN0IsTUFBTSxlQUFlLEdBQUcsdUJBQXVCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDN0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdkMsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztZQUNuQixFQUFFLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsZUFBZSxLQUFLLHdCQUF3QixFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUU7Z0JBQ2pJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3pDLENBQUM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxhQUFhLENBQUMsS0FBMEIsSUFBSSxFQUFFLFVBQWlDLElBQUk7UUFDakYsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1FBQ3pDLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2YsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQztZQUM5RSxJQUFJLFVBQVUsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDckIsT0FBTztZQUNULENBQUM7WUFDRCxRQUFRLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDM0IsQ0FBQztRQUNELE1BQU0sUUFBUSxHQUFHLE9BQU8sRUFBRSxRQUFRLElBQUksZ0JBQWdCLEVBQ3BELFFBQVEsR0FBRyxPQUFPLEVBQUUsUUFBUSxJQUFJLEtBQUssRUFDckMsT0FBTyxHQUFHLE9BQU8sRUFBRSxPQUFPLElBQUksSUFBSSxFQUNsQyxLQUFLLEdBQUcsT0FBTyxFQUFFLEtBQUssSUFBSSxDQUFDLEVBQzNCLFNBQVMsR0FBRyxPQUFPLEVBQUUsU0FBUyxJQUFJLENBQUMsQ0FBQztRQUN0QyxzQkFBc0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNqQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM3QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxFQUFFLFNBQVMsR0FBRyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsR0FBRyxTQUFTLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLEVBQzVKLGVBQWUsR0FBRyx1QkFBdUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNoQixJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN2QyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztnQkFDbkIsRUFBRSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLGVBQWUsS0FBSyx3QkFBd0IsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFO29CQUNqSSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDaEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO29CQUNwQyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7b0JBQ25DLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUM3QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDekMsQ0FBQzthQUNGLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsZUFBZSxDQUFDLEVBQWUsRUFBRSxPQUF3QjtRQUN2RCxNQUFNLEtBQUssQ0FBQyx1RUFBdUUsQ0FBQyxDQUFDO0lBQ3ZGLENBQUM7SUFFRDs7T0FFRztJQUNILFdBQVcsQ0FBQyxLQUEwQixJQUFJLEVBQUUsVUFBaUMsSUFBSTtRQUMvRSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7UUFDekMsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDZixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUNoQyxVQUFVLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUNsRSxhQUFhLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDO1lBQzFFLElBQUksVUFBVSxLQUFLLGFBQWEsRUFBRSxDQUFDO2dCQUNqQyxPQUFPO1lBQ1QsQ0FBQztZQUNELFFBQVEsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMzQixDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsT0FBTyxFQUFFLFFBQVEsSUFBSSxnQkFBZ0IsRUFDcEQsUUFBUSxHQUFHLE9BQU8sRUFBRSxRQUFRLElBQUksS0FBSyxFQUNyQyxPQUFPLEdBQUcsT0FBTyxFQUFFLE9BQU8sSUFBSSxJQUFJLEVBQ2xDLEtBQUssR0FBRyxPQUFPLEVBQUUsS0FBSyxJQUFJLENBQUMsRUFDM0IsU0FBUyxHQUFHLE9BQU8sRUFBRSxTQUFTLElBQUksQ0FBQyxDQUFDO1FBQ3RDLHNCQUFzQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2pDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzdCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLEVBQUUsT0FBTyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLEVBQzVKLGVBQWUsR0FBRyx1QkFBdUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN2RCxJQUFJLE9BQU8sS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNyQixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsVUFBVSxFQUFFLENBQUM7WUFDekMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdkMsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztZQUNuQixFQUFFLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsZUFBZSxLQUFLLHdCQUF3QixFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUU7Z0JBQ2pJLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUM5QixJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7Z0JBQ3JDLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztnQkFDbEMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3pDLENBQUM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sZ0JBQWdCLENBQUMsRUFBTSxFQUFFLE9BQWdCLEVBQUUsRUFBdUI7UUFDeEUsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMscUJBQXFCLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDbkQsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ1QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNoRCxDQUFDO1FBQ0gsQ0FBQztRQUNELElBQUksT0FBTyxFQUFFLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDN0IsRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUNULENBQUM7SUFDSCxDQUFDO0lBRVMsT0FBTztRQUNmLE1BQU0sWUFBWSxHQUFpQyxFQUFFLENBQUM7UUFDdEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEdBQUcsWUFBWSxDQUFDO1FBQ3hDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDaEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRDs7T0FFRztJQUNPLFVBQVU7UUFDbEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDckIsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUM5QixDQUFDO1FBQ0QsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQzNDLElBQUksQ0FBQyxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDekIsa0JBQWtCLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDM0Isa0JBQWtCLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDM0IsQ0FBQztRQUNELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDMUIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDO1FBQ3pDLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2YsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ25CLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsdUJBQXVCO1FBQ3JCLE1BQU0sS0FBSyxDQUFDLG1GQUFtRixDQUFDLENBQUM7SUFDbkcsQ0FBQztJQUVEOztPQUVHO0lBQ0gsZUFBZTtRQUNiLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDeEIsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUM7UUFDekMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzQyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ2IsUUFBUSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzNCLENBQUM7SUFDSCxDQUFDO0lBRVEsV0FBVztRQUNsQixLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2pCLENBQUM7SUFFTyxPQUFPO1FBQ2IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUV0QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQ2hDLElBQUksUUFBUSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzNCLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1FBQzdCLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzFCLENBQUM7UUFFRCxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMzQixDQUFDO1FBRUQsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzNDLENBQUM7UUFFRCxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztZQUNyQyxPQUFPLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2pELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDcEQsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDO1lBQ2xCLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUM1QixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzFDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDN0MsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDO1lBQ2xCLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQzt3R0EzdElVLHNCQUFzQjs0RkFBdEIsc0JBQXNCLHMxRUFGdEIsQ0FBQyxvQkFBb0IsRUFBRSwwQkFBMEIsQ0FBQyw4R0FjN0Isb0JBQW9CLGtIQUdYLGdCQUFnQixxSEFHYixnQkFBZ0IseUdBRzdCLG1CQUFtQixvRENwSHBELCttRkFvQ2M7OzRGRDJERCxzQkFBc0I7a0JBWmxDLFNBQVM7K0JBQ0UsaUJBQWlCLFFBR3JCO3dCQUNKLE9BQU8sRUFBRSxxQkFBcUI7cUJBQy9CLGNBQ1csS0FBSyxtQkFDQSx1QkFBdUIsQ0FBQyxNQUFNLGlCQUNoQyxpQkFBaUIsQ0FBQyxTQUFTLGFBQy9CLENBQUMsb0JBQW9CLEVBQUUsMEJBQTBCLENBQUM7d0RBZXJELFVBQVU7c0JBRGpCLFNBQVM7dUJBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLG9CQUFvQixFQUFFO2dCQUk5QyxpQkFBaUI7c0JBRHhCLFNBQVM7dUJBQUMsb0JBQW9CLEVBQUUsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBSW5ELGlCQUFpQjtzQkFEeEIsU0FBUzt1QkFBQyx1QkFBdUIsRUFBRSxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRTtnQkFJdEQsa0JBQWtCO3NCQUR6QixTQUFTO3VCQUFDLFVBQVUsRUFBRSxFQUFFLElBQUksRUFBRSxtQkFBbUIsRUFBRTtnQkFhcEQsUUFBUTtzQkFEUCxNQUFNO2dCQU9QLFdBQVc7c0JBRFYsTUFBTTtnQkFPUCxnQkFBZ0I7c0JBRGYsTUFBTTtnQkFPUCxVQUFVO3NCQURULE1BQU07Z0JBT1AsV0FBVztzQkFEVixNQUFNO2dCQU9QLFFBQVE7c0JBRFAsTUFBTTtnQkFPUCxVQUFVO3NCQURULE1BQU07Z0JBT1Asa0JBQWtCO3NCQURqQixNQUFNO2dCQU9QLGdCQUFnQjtzQkFEZixNQUFNO2dCQTBCSCxrQkFBa0I7c0JBRHJCLEtBQUs7Z0JBNkJGLGdCQUFnQjtzQkFEbkIsS0FBSztnQkE2QkYsc0JBQXNCO3NCQUR6QixLQUFLO2dCQTZCRixvQkFBb0I7c0JBRHZCLEtBQUs7Z0JBeUNGLE9BQU87c0JBRFYsS0FBSztnQkE2QkYsa0JBQWtCO3NCQURyQixLQUFLO2dCQTZCRixhQUFhO3NCQURoQixLQUFLO2dCQTRDRixLQUFLO3NCQURSLEtBQUs7Z0JBd0NGLFdBQVc7c0JBRGQsS0FBSztnQkFnQkYsZ0JBQWdCO3NCQURuQixLQUFLO2dCQXNDRixZQUFZO3NCQURmLEtBQUs7Z0JBOEJGLGFBQWE7c0JBRGhCLEtBQUs7Z0JBOEJGLGVBQWU7c0JBRGxCLEtBQUs7Z0JBaUJGLElBQUk7c0JBRFAsS0FBSztnQkFzQkYsYUFBYTtzQkFEaEIsS0FBSztnQkE2QkYsZ0NBQWdDO3NCQURuQyxLQUFLO2dCQThCRixpQkFBaUI7c0JBRHBCLEtBQUs7Z0JBOEJGLGVBQWU7c0JBRGxCLEtBQUs7Z0JBb0NGLGlCQUFpQjtzQkFEcEIsS0FBSztnQkFtQ0YsZUFBZTtzQkFEbEIsS0FBSztnQkFpQkYsa0JBQWtCO3NCQURyQixLQUFLO2dCQXVCRixnQkFBZ0I7c0JBRG5CLEtBQUs7Z0JBNkJGLG9CQUFvQjtzQkFEdkIsS0FBSztnQkE2QkYsb0JBQW9CO3NCQUR2QixLQUFLO2dCQTZCRixjQUFjO3NCQURqQixLQUFLO2dCQStFRixpQkFBaUI7c0JBRHBCLEtBQUs7Z0JBNEJGLGFBQWE7c0JBRGhCLEtBQUs7Z0JBNkJGLFVBQVU7c0JBRGIsS0FBSztnQkE2QkYsZUFBZTtzQkFEbEIsS0FBSztnQkE4QkYsZ0JBQWdCO3NCQURuQixLQUFLO2dCQTZCRixpQkFBaUI7c0JBRHBCLEtBQUs7Z0JBOEJGLFNBQVM7c0JBRFosS0FBSztnQkE2QkYsbUJBQW1CO3NCQUR0QixLQUFLO2dCQWlDRixhQUFhO3NCQURoQixLQUFLO2dCQTZCRixPQUFPO3NCQURWLEtBQUs7Z0JBNkJGLFVBQVU7c0JBRGIsS0FBSztnQkE2QkYsYUFBYTtzQkFEaEIsS0FBSztnQkE2QkYsaUJBQWlCO3NCQURwQixLQUFLO2dCQStDRixlQUFlO3NCQURsQixLQUFLO2dCQTZCRixpQkFBaUI7c0JBRHBCLEtBQUs7Z0JBZ0NGLHlCQUF5QjtzQkFENUIsS0FBSztnQkErQkYsWUFBWTtzQkFEZixLQUFLO2dCQW9ERixhQUFhO3NCQURoQixLQUFLO2dCQStCRixRQUFRO3NCQURYLEtBQUs7Z0JBNkJGLFdBQVc7c0JBRGQsS0FBSztnQkE2QkYsV0FBVztzQkFEZCxLQUFLO2dCQThCRixXQUFXO3NCQURkLEtBQUs7Z0JBNEJGLFNBQVM7c0JBRFosS0FBSztnQkE0QkYsY0FBYztzQkFEakIsS0FBSztnQkE0QkYsVUFBVTtzQkFEYixLQUFLO2dCQW9DRixhQUFhO3NCQURoQixLQUFLO2dCQTZCRixjQUFjO3NCQURqQixLQUFLO2dCQWdDRixjQUFjO3NCQURqQixLQUFLO2dCQWlCRixrQkFBa0I7c0JBRHJCLEtBQUs7Z0JBd0JGLGFBQWE7c0JBRGhCLEtBQUs7Z0JBNEJGLE9BQU87c0JBRFYsS0FBSztnQkErQlEsbUJBQW1CO3NCQURoQyxLQUFLO2dCQWdDRixXQUFXO3NCQURkLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIENvbXBvbmVudFJlZiwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBpbmplY3QsIElucHV0LFxyXG4gIE9uRGVzdHJveSwgT3V0cHV0LCBUZW1wbGF0ZVJlZiwgVmlld0NoaWxkLCBWaWV3Q29udGFpbmVyUmVmLCBWaWV3RW5jYXBzdWxhdGlvbixcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtcclxuICBCZWhhdmlvclN1YmplY3QsIGNvbWJpbmVMYXRlc3QsIGRlYm91bmNlVGltZSwgZGVsYXksIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBmaWx0ZXIsIGZyb21FdmVudCwgbWFwLFxyXG4gIE9ic2VydmFibGUsXHJcbiAgb2YsIHNraXAsIFN1YmplY3QsIHN3aXRjaE1hcCwgdGFrZSwgdGFrZVVudGlsLCB0YXAsXHJcbn0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IE5nVmlydHVhbExpc3RJdGVtQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL25nLWxpc3QtaXRlbS9uZy12aXJ0dWFsLWxpc3QtaXRlbS5jb21wb25lbnQnO1xyXG5pbXBvcnQge1xyXG4gIEJFSEFWSU9SX0lOU1RBTlQsIENMQVNTX0xJU1RfSE9SSVpPTlRBTCwgQ0xBU1NfTElTVF9WRVJUSUNBTCwgREVGQVVMVF9ESVJFQ1RJT04sIERFRkFVTFRfRFlOQU1JQ19TSVpFLFxyXG4gIERFRkFVTFRfRU5BQkxFRF9CVUZGRVJfT1BUSU1JWkFUSU9OLCBERUZBVUxUX0lURU1fU0laRSwgREVGQVVMVF9CVUZGRVJfU0laRSwgREVGQVVMVF9MSVNUX1NJWkUsIERFRkFVTFRfU1RJQ0tZX0VOQUJMRUQsIERFRkFVTFRfU05BUFBJTkdfTUVUSE9ELFxyXG4gIEhFSUdIVF9QUk9QX05BTUUsIExFRlRfUFJPUF9OQU1FLCBNQVhfU0NST0xMX1RPX0lURVJBVElPTlMsIFBYLCBGT0NVUywgVE9QX1BST1BfTkFNRSwgVFJBQ0tfQllfUFJPUEVSVFlfTkFNRSwgV0lEVEhfUFJPUF9OQU1FLFxyXG4gIERFRkFVTFRfTUFYX0JVRkZFUl9TSVpFLCBERUZBVUxUX1NFTEVDVElOR19NT0RFUywgREVGQVVMVF9TRUxFQ1RfQllfQ0xJQ0ssIERFRkFVTFRfQ09MTEFQU0VfQllfQ0xJQ0ssIERFRkFVTFRfQ09MTEVDVElPTl9NT0RFLFxyXG4gIERFRkFVTFRfU0NSRUVOX1JFQURFUl9NRVNTQUdFLCBERUZBVUxUX1NOQVBfVE9fRU5EX1RSQU5TSVRJT05fSU5TVEFOVF9PRkZTRVQsIERFRkFVTFRfU05BUF9TQ1JPTExUT19FTkQsIE1JTl9QSVhFTFNfRk9SX1BSRVZFTlRfU05BUFBJTkcsXHJcbiAgTU9VU0VfRE9XTiwgVE9VQ0hfU1RBUlQsIERFRkFVTFRfTEFOR19URVhUX0RJUiwgREVGQVVMVF9DTElDS19ESVNUQU5DRSwgREVGQVVMVF9XQUlUX0ZPUl9QUkVQQVJBVElPTiwgREVGQVVMVF9TQ1JPTExCQVJfVEhJQ0tORVNTLFxyXG4gIERFRkFVTFRfU0NST0xMQkFSX01JTl9TSVpFLCBLRVlfRE9XTiwgQkVIQVZJT1JfQVVUTywgREVGQVVMVF9TQ1JPTExCQVJfRU5BQkxFRCwgREVGQVVMVF9TQ1JPTExCQVJfSU5URVJBQ1RJVkUsIERFRkFVTFRfT1ZFUlNDUk9MTF9FTkFCTEVELFxyXG4gIERFRkFVTFRfQU5JTUFUSU9OX1BBUkFNUywgREVGQVVMVF9TQ1JPTExfQkVIQVZJT1IsIERFRkFVTFRfU05BUF9TQ1JPTExUT19TVEFSVCwgRU1QVFlfU0NST0xMX1NUQVRFX1ZFUlNJT04sIE1BWF9SRUdVTEFSX1NOQVBFRF9DT01QT05FTlRTLFxyXG4gIFBSRVBBUkVfSVRFUkFUSU9OUywgUFJFUEFSQVRJT05fUkVVUERBVEVfTEVOR1RILCBST0xFX0xJU1RfQk9YLCBST0xFX0xJU1QsIEtFWV9UQUIsIE1BWF9WRUxPQ0lUWV9GT1JfU0NST0xMX1FVQUxJVFlfT1BUSU1JWkFUSU9OX0xWTDEsXHJcbiAgUFJFUEFSRV9JVEVSQVRJT05TX0ZPUl9VUERBVEVfSVRFTVMsIFBSRVBBUkFUSU9OX1JFVVBEQVRFX0xFTkdUSF9GT1JfVVBEQVRFX0lURU1TLCBQUkVQQVJFX0lURVJBVElPTlNfRk9SX0NPTExBUFNFX0lURU1TLFxyXG4gIFBSRVBBUkFUSU9OX1JFVVBEQVRFX0xFTkdUSF9GT1JfQ09MTEFQU0VfSVRFTVMsIE1BWF9OVU1CRVJTX09GX1NLSVBTX0ZPUl9RVUFMSVRZX09QVElNSVpBVElPTl9MVkwxLCBERUZBVUxUX1NDUk9MTElOR19TRVRUSU5HUyxcclxuICBERUZBVUxUX1NOQVBfVE9fSVRFTSwgREVGQVVMVF9TTkFQX1RPX0lURU1fQUxJR04sIFZJRVdQT1JULCBERUZBVUxUX01PVElPTl9CTFVSLCBERUZBVUxUX01BWF9NT1RJT05fQkxVUiwgREVGQVVMVF9TQ1JPTExJTkdfT05FX0JZX09ORSxcclxuICBERUZBVUxUX01PVElPTl9CTFVSX0VOQUJMRUQsIERFRkFVTFRfRElWSURFUywgREVGQVVMVF9TTkFQUElOR19ESVNUQU5DRSwgREVGQVVMVF9NQVhfSVRFTV9TSVpFLCBERUZBVUxUX01JTl9JVEVNX1NJWkUsXHJcbiAgREVGQVVMVF9BTElHTk1FTlQsIERFRkFVTFRfQ09MTEFQU0lOR19NT0RFUywgREVGQVVMVF9TUFJFQURJTkdfTU9ERSwgREVGQVVMVF9aSU5ERVhfV0hFTl9TRUxFQ1RJTkcsXHJcbiAgREVGQVVMVF9PVkVSTEFQUElOR19TQ1JPTExCQVIsXHJcbn0gZnJvbSAnLi9jb25zdCc7XHJcbmltcG9ydCB7XHJcbiAgSVJlbmRlclZpcnR1YWxMaXN0SXRlbSwgSVZpcnR1YWxMaXN0Q29sbGVjdGlvbiwgSVZpcnR1YWxMaXN0SXRlbSwgSVZpcnR1YWxMaXN0SXRlbUNvbmZpZ01hcCxcclxufSBmcm9tICcuL21vZGVscyc7XHJcbmltcG9ydCB7XHJcbiAgSVNjcm9sbEV2ZW50LCBJU2Nyb2xsT3B0aW9ucywgSUFuaW1hdGlvblBhcmFtcywgSVNpemUsIElSZW5kZXJTdGFiaWxpemVyT3B0aW9ucywgSVNjcm9sbGluZ1NldHRpbmdzLFxyXG59IGZyb20gJy4vaW50ZXJmYWNlcyc7XHJcbmltcG9ydCB7XHJcbiAgQWxpZ25tZW50LCBBcml0aG1ldGljRXhwcmVzc2lvbiwgRm9jdXNBbGlnbm1lbnQsIElkLCBJdGVtVHJhbnNmb3JtLCBTbmFwcGluZ0Rpc3RhbmNlLCBDb2xsZWN0aW9uTW9kZSwgRGlyZWN0aW9uLCBTZWxlY3RpbmdNb2RlLFxyXG4gIFNuYXBwaW5nTWV0aG9kLCBTbmFwVG9JdGVtQWxpZ24sIFRleHREaXJlY3Rpb24sIENvbGxhcHNpbmdNb2RlLFxyXG4gIFNwcmVhZGluZ01vZGUsXHJcbn0gZnJvbSAnLi90eXBlcyc7XHJcbmltcG9ydCB7IElSZW5kZXJWaXJ0dWFsTGlzdENvbGxlY3Rpb24gfSBmcm9tICcuL21vZGVscy9yZW5kZXItY29sbGVjdGlvbi5tb2RlbCc7XHJcbmltcG9ydCB7XHJcbiAgQWxpZ25tZW50cywgQ29sbGVjdGlvbk1vZGVzLCBEaXJlY3Rpb25zLCBGb2N1c0FsaWdubWVudHMsIFNlbGVjdGluZ01vZGVzLCBTbmFwcGluZ01ldGhvZHMsIFNuYXBUb0l0ZW1BbGlnbnMsIFNwcmVhZGluZ01vZGVzLCBUZXh0RGlyZWN0aW9ucyxcclxufSBmcm9tICcuL2VudW1zJztcclxuaW1wb3J0IHsgZGVib3VuY2UsIFNjcm9sbEV2ZW50LCB0b2dnbGVDbGFzc05hbWUgfSBmcm9tICcuL3V0aWxzJztcclxuaW1wb3J0IHsgVHJhY2tCb3ggfSBmcm9tICcuL2NvcmUvdHJhY2stYm94JztcclxuaW1wb3J0IHsgaXNTbmFwcGluZ01ldGhvZEFkdmVuY2VkIH0gZnJvbSAnLi91dGlscy9zbmFwcGluZy1tZXRob2QnO1xyXG5pbXBvcnQgeyBCYXNlVmlydHVhbExpc3RJdGVtQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL25nLWxpc3QtaXRlbS9iYXNlJztcclxuaW1wb3J0IHsgQ29tcG9uZW50JDEgfSBmcm9tICcuL21vZGVscy9jb21wb25lbnQubW9kZWwnO1xyXG5pbXBvcnQgeyBpc0RpcmVjdGlvbiB9IGZyb20gJy4vdXRpbHMvaXMtZGlyZWN0aW9uJztcclxuaW1wb3J0IHsgTmdWaXJ0dWFsTGlzdFNlcnZpY2UgfSBmcm9tICcuL25nLXZpcnR1YWwtbGlzdC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgaXNTZWxlY3RNb2RlIH0gZnJvbSAnLi91dGlscy9pcy1zZWxlY3QtbW9kZSc7XHJcbmltcG9ydCB7IGlzQ29sbGFwc2VNb2RlIH0gZnJvbSAnLi91dGlscy9pcy1jb2xsYXBzZS1tb2RlJztcclxuaW1wb3J0IHsgU2VsZWN0aW5nTW9kZXNUeXBlcyB9IGZyb20gJy4vZW51bXMvc2VsZWN0aW5nLW1vZGVzLXR5cGVzJztcclxuaW1wb3J0IHsgQ01hcCB9IGZyb20gJy4vdXRpbHMvY21hcCc7XHJcbmltcG9ydCB7XHJcbiAgdmFsaWRhdGVBcnJheSwgdmFsaWRhdGVCb29sZWFuLCB2YWxpZGF0ZUZsb2F0LCB2YWxpZGF0ZUZ1bmN0aW9uLCB2YWxpZGF0ZUludCwgdmFsaWRhdGVPYmplY3QsIHZhbGlkYXRlU3RyaW5nLFxyXG59IGZyb20gJy4vdXRpbHMvdmFsaWRhdGlvbic7XHJcbmltcG9ydCB7IGNvcHlWYWx1ZUFzUmVhZG9ubHksIG9iamVjdEFzUmVhZG9ubHkgfSBmcm9tICcuL3V0aWxzL29iamVjdCc7XHJcbmltcG9ydCB7IGlzQ29sbGVjdGlvbk1vZGUgfSBmcm9tICcuL3V0aWxzL2lzLWNvbGxlY3Rpb24tbW9kZSc7XHJcbmltcG9ydCB7IE5nU2Nyb2xsZXJDb21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvbmctc2Nyb2xsZXIvbmctc2Nyb2xsZXIuY29tcG9uZW50JztcclxuaW1wb3J0IHsgSVNjcm9sbFRvUGFyYW1zIH0gZnJvbSAnLi9jb21wb25lbnRzL25nLXNjcm9sbC12aWV3JztcclxuaW1wb3J0IHsgTmdQcmVyZW5kZXJDb250YWluZXIgfSBmcm9tICcuL2NvbXBvbmVudHMvbmctcHJlcmVuZGVyLWNvbnRhaW5lci9uZy1wcmVyZW5kZXItY29udGFpbmVyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IElTY3JvbGxQYXJhbXMgfSBmcm9tICcuL2ludGVyZmFjZXMnO1xyXG5pbXBvcnQgeyBmb3JtYXRBY3R1YWxEaXNwbGF5SXRlbXMsIGZvcm1hdFNjcmVlblJlYWRlck1lc3NhZ2UgfSBmcm9tICcuL3V0aWxzL3NjcmVlbi1yZWFkZXItZm9ybWF0dGVyJztcclxuaW1wb3J0IHsgdmFsaWRhdGVJZCwgdmFsaWRhdGVJdGVyYXRpb24sIHZhbGlkYXRlU2Nyb2xsQmVoYXZpb3IsIHZhbGlkYXRlU2Nyb2xsSXRlcmF0aW9uIH0gZnJvbSAnLi91dGlscy9saXN0LXZhbGlkYXRvcnMnO1xyXG5pbXBvcnQgeyBFVkVOVF9LRVlfRE9XTiwgS0VZX0FSUl9ET1dOLCBLRVlfQVJSX0xFRlQsIEtFWV9BUlJfUklHSFQsIEtFWV9BUlJfVVAgfSBmcm9tICcuL2NvbXBvbmVudHMvbmctbGlzdC1pdGVtL2NvbnN0JztcclxuaW1wb3J0IHsgTmdWaXJ0dWFsTGlzdFB1YmxpY1NlcnZpY2UgfSBmcm9tICcuL25nLXZpcnR1YWwtbGlzdC1wdWJsaWMuc2VydmljZSc7XHJcbmltcG9ydCB7IGlzUGVyY2VudGFnZVZhbHVlIH0gZnJvbSAnLi91dGlscy9pcy1wZXJzZW50YWdlLXZhbHVlJztcclxuaW1wb3J0IHsgcGFyc2VBcml0aG1ldGljRXhwcmVzc2lvbiB9IGZyb20gJy4vdXRpbHMvcGFyc2UtYXJpdGhtZXRpYy1leHByZXNzaW9uJztcclxuaW1wb3J0IHsgbm9ybWFsaXplQ29sbGVjdGlvbiB9IGZyb20gJy4vdXRpbHMvbm9ybWFsaXplLWNvbGxlY3Rpb24nO1xyXG5pbXBvcnQgeyBDb2xsYXBzaW5nTW9kZXMgfSBmcm9tICcuL2VudW1zJztcclxuaW1wb3J0IHsgaXNTcHJlYWRpbmdNb2RlIH0gZnJvbSAnLi91dGlscy9pcy1zcHJlYWRpbmctbW9kZSc7XHJcbmltcG9ydCB7IElHZXRJdGVtUG9zaXRpb25PcHRpb25zLCBJVXBkYXRlQ29sbGVjdGlvbk9wdGlvbnMgfSBmcm9tICcuL2NvcmUvaW50ZXJmYWNlcyc7XHJcbmltcG9ydCB7IGdldFNjcm9sbFN0YXRlVmVyc2lvbiB9IGZyb20gJy4vdXRpbHMvZ2V0LXNjcm9sbC1zdGF0ZS12ZXJzaW9uJztcclxuaW1wb3J0IHsgRGlzcG9zYWJsZUNvbXBvbmVudCB9IGZyb20gJy4vdXRpbHMvZGlzcG9zYWJsZS1jb21wb25lbnQnO1xyXG5cclxuLyoqXHJcbiAqIFZpcnR1YWwgbGlzdCBjb21wb25lbnQuXHJcbiAqIE1heGltdW0gcGVyZm9ybWFuY2UgZm9yIGV4dHJlbWVseSBsYXJnZSBsaXN0cy5cclxuICogSXQgaXMgYmFzZWQgb24gYWxnb3JpdGhtcyBmb3IgdmlydHVhbGl6YXRpb24gb2Ygc2NyZWVuIG9iamVjdHMuXHJcbiAqIEBsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9Eam9ubnlYL25nLXZpcnR1YWwtbGlzdC9ibG9iLzE0LngvcHJvamVjdHMvbmctdmlydHVhbC1saXN0L3NyYy9saWIvbmctdmlydHVhbC1saXN0LmNvbXBvbmVudC50c1xyXG4gKiBAYXV0aG9yIEV2Z2VuaWkgQWxleGFuZHJvdmljaCBHcmViZW5uaWtvdlxyXG4gKiBAZW1haWwgZGpvbm55eEBnbWFpbC5jb21cclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbmctdmlydHVhbC1saXN0JyxcclxuICB0ZW1wbGF0ZVVybDogJy4vbmctdmlydHVhbC1saXN0LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9uZy12aXJ0dWFsLWxpc3QuY29tcG9uZW50LnNjc3MnXSxcclxuICBob3N0OiB7XHJcbiAgICAnc3R5bGUnOiAncG9zaXRpb246IHJlbGF0aXZlOydcclxuICB9LFxyXG4gIHN0YW5kYWxvbmU6IGZhbHNlLFxyXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxyXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLlNoYWRvd0RvbSxcclxuICBwcm92aWRlcnM6IFtOZ1ZpcnR1YWxMaXN0U2VydmljZSwgTmdWaXJ0dWFsTGlzdFB1YmxpY1NlcnZpY2VdLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgTmdWaXJ0dWFsTGlzdENvbXBvbmVudCBleHRlbmRzIERpc3Bvc2FibGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xyXG4gIHByaXZhdGUgc3RhdGljIF9fbmV4dElkOiBudW1iZXIgPSAwO1xyXG5cclxuICBwcml2YXRlIF9pZDogbnVtYmVyID0gTmdWaXJ0dWFsTGlzdENvbXBvbmVudC5fX25leHRJZDtcclxuXHJcbiAgLyoqXHJcbiAgICogUmVhZG9ubHkuIFJldHVybnMgdGhlIHVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBjb21wb25lbnQuXHJcbiAgICovXHJcbiAgZ2V0IGlkKCkgeyByZXR1cm4gdGhpcy5faWQ7IH1cclxuXHJcbiAgcHJpdmF0ZSBfc2VydmljZSA9IGluamVjdChOZ1ZpcnR1YWxMaXN0U2VydmljZSk7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ3ByZXJlbmRlcicsIHsgcmVhZDogTmdQcmVyZW5kZXJDb250YWluZXIgfSlcclxuICBwcml2YXRlIF9wcmVyZW5kZXI6IE5nUHJlcmVuZGVyQ29udGFpbmVyIHwgdW5kZWZpbmVkO1xyXG5cclxuICBAVmlld0NoaWxkKCdyZW5kZXJlcnNDb250YWluZXInLCB7IHJlYWQ6IFZpZXdDb250YWluZXJSZWYgfSlcclxuICBwcml2YXRlIF9saXN0Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmIHwgdW5kZWZpbmVkO1xyXG5cclxuICBAVmlld0NoaWxkKCdzbmFwUmVuZGVyZXJDb250YWluZXInLCB7IHJlYWQ6IFZpZXdDb250YWluZXJSZWYgfSlcclxuICBwcml2YXRlIF9zbmFwQ29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmIHwgdW5kZWZpbmVkO1xyXG5cclxuICBAVmlld0NoaWxkKCdzY3JvbGxlcicsIHsgcmVhZDogTmdTY3JvbGxlckNvbXBvbmVudCB9KVxyXG4gIHByaXZhdGUgX3Njcm9sbGVyQ29tcG9uZW50OiBOZ1Njcm9sbGVyQ29tcG9uZW50IHwgdW5kZWZpbmVkO1xyXG5cclxuICBwcml2YXRlIF8kc2Nyb2xsZXIgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+IHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkc2Nyb2xsZXIgPSB0aGlzLl8kc2Nyb2xsZXIuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgXyRsaXN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PiB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJGxpc3QgPSB0aGlzLl8kbGlzdC5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRmlyZXMgd2hlbiB0aGUgbGlzdCBoYXMgYmVlbiBzY3JvbGxlZC5cclxuICAgKi9cclxuICBAT3V0cHV0KClcclxuICBvblNjcm9sbCA9IG5ldyBFdmVudEVtaXR0ZXI8SVNjcm9sbEV2ZW50PigpO1xyXG5cclxuICAvKipcclxuICAgKiBGaXJlcyB3aGVuIHRoZSBsaXN0IGhhcyBjb21wbGV0ZWQgc2Nyb2xsaW5nLlxyXG4gICAqL1xyXG4gIEBPdXRwdXQoKVxyXG4gIG9uU2Nyb2xsRW5kID0gbmV3IEV2ZW50RW1pdHRlcjxJU2Nyb2xsRXZlbnQ+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVzIHdoZW4gdGhlIHZpZXdwb3J0IHNpemUgaXMgY2hhbmdlZC5cclxuICAgKi9cclxuICBAT3V0cHV0KClcclxuICBvblZpZXdwb3J0Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxJU2l6ZT4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRW1pdCB0aGUgY29tcG9uZW50IElEIHdoZW4gYW4gZWxlbWVudCBjcm9zc2VzIHRoZSBhbGlnbm1lbnQgbGluZSBzcGVjaWZpZWQgYnkgdGhlIHNuYXBUb0l0ZW1BbGlnbiBwcm9wZXJ0eS5cclxuICAgKi9cclxuICBAT3V0cHV0KClcclxuICBvblNuYXBJdGVtID0gbmV3IEV2ZW50RW1pdHRlcjxJZD4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRmlyZXMgd2hlbiBhbiBlbGVtZW50IGlzIGNsaWNrZWQuXHJcbiAgICovXHJcbiAgQE91dHB1dCgpXHJcbiAgb25JdGVtQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPElSZW5kZXJWaXJ0dWFsTGlzdEl0ZW08YW55PiB8IG51bGw+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVzIHdoZW4gZWxlbWVudHMgYXJlIHNlbGVjdGVkLlxyXG4gICAqL1xyXG4gIEBPdXRwdXQoKVxyXG4gIG9uU2VsZWN0ID0gbmV3IEV2ZW50RW1pdHRlcjxBcnJheTxJZD4gfCBJZCB8IG51bGw+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVzIHdoZW4gZWxlbWVudHMgYXJlIGNvbGxhcHNlZC5cclxuICAgKi9cclxuICBAT3V0cHV0KClcclxuICBvbkNvbGxhcHNlID0gbmV3IEV2ZW50RW1pdHRlcjxBcnJheTxJZD4+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVzIHdoZW4gdGhlIHNjcm9sbCByZWFjaGVzIHRoZSBzdGFydC5cclxuICAgKi9cclxuICBAT3V0cHV0KClcclxuICBvblNjcm9sbFJlYWNoU3RhcnQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVzIHdoZW4gdGhlIHNjcm9sbCByZWFjaGVzIHRoZSBlbmQuXHJcbiAgICovXHJcbiAgQE91dHB1dCgpXHJcbiAgb25TY3JvbGxSZWFjaEVuZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcclxuXHJcbiAgcHJpdmF0ZSBfJHNob3cgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcclxuICByZWFkb25seSAkc2hvdyA9IHRoaXMuXyRzaG93LmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF8kaW5pdGlhbGl6ZWQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcclxuICByZWFkb25seSAkaW5pdGlhbGl6ZWQgPSB0aGlzLl8kaW5pdGlhbGl6ZWQuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgXyRzY3JvbGxiYXJUaGlja25lc3MgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oREVGQVVMVF9TQ1JPTExCQVJfVEhJQ0tORVNTKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJHNjcm9sbGJhclRoaWNrbmVzcyA9IHRoaXMuXyRzY3JvbGxiYXJUaGlja25lc3MuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX3Njcm9sbGJhclRoaWNrbmVzc1RyYW5zZm9ybSA9ICh2OiBudW1iZXIpID0+IHtcclxuICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVJbnQodiwgdHJ1ZSk7XHJcblxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJzY3JvbGxiYXJUaGlja25lc3NcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBudW1iZXJgLicpO1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9TQ1JPTExCQVJfVEhJQ0tORVNTO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogU2Nyb2xsYmFyIHRoaWNrbmVzcy5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBzY3JvbGxiYXJUaGlja25lc3ModjogbnVtYmVyKSB7XHJcbiAgICBpZiAodGhpcy5fJHNjcm9sbGJhclRoaWNrbmVzcy5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fc2Nyb2xsYmFyVGhpY2tuZXNzVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRzY3JvbGxiYXJUaGlja25lc3MubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBzY3JvbGxiYXJUaGlja25lc3MoKSB7IHJldHVybiB0aGlzLl8kc2Nyb2xsYmFyVGhpY2tuZXNzLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJHNjcm9sbGJhck1pblNpemUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oREVGQVVMVF9TQ1JPTExCQVJfTUlOX1NJWkUpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkc2Nyb2xsYmFyTWluU2l6ZSA9IHRoaXMuXyRzY3JvbGxiYXJNaW5TaXplLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF9zY3JvbGxiYXJNaW5TaXplVHJhbnNmb3JtID0gKHY6IG51bWJlcikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUludCh2KTtcclxuXHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcInNjcm9sbGJhck1pblNpemVcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBudW1iZXJgLicpO1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9TQ1JPTExCQVJfTUlOX1NJWkU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBNaW5pbXVtIHNjcm9sbGJhciBzaXplLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNjcm9sbGJhck1pblNpemUodjogbnVtYmVyKSB7XHJcbiAgICBpZiAodGhpcy5fJHNjcm9sbGJhck1pblNpemUuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX3Njcm9sbGJhck1pblNpemVUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJHNjcm9sbGJhck1pblNpemUubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBzY3JvbGxiYXJNaW5TaXplKCkgeyByZXR1cm4gdGhpcy5fJHNjcm9sbGJhck1pblNpemUuZ2V0VmFsdWUoKSBhcyBudW1iZXI7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJHNjcm9sbGJhclRodW1iUmVuZGVyZXIgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFRlbXBsYXRlUmVmPGFueT4gfCBudWxsPihudWxsKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJHNjcm9sbGJhclRodW1iUmVuZGVyZXIgPSB0aGlzLl8kc2Nyb2xsYmFyVGh1bWJSZW5kZXJlci5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfc2Nyb2xsYmFyVGh1bWJSZW5kZXJlclRyYW5zZm9ybSA9ICh2OiBUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbCkgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZU9iamVjdCh2LCB0cnVlLCB0cnVlKTtcclxuXHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcInNjcm9sbGJhclRodW1iUmVuZGVyZXJcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBvYmplY3RgLicpO1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIFNjcm9sbGJhciBjdXN0b21pemF0aW9uIHRlbXBsYXRlLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNjcm9sbGJhclRodW1iUmVuZGVyZXIodjogVGVtcGxhdGVSZWY8YW55PiB8IG51bGwpIHtcclxuICAgIGlmICh0aGlzLl8kc2Nyb2xsYmFyVGh1bWJSZW5kZXJlci5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fc2Nyb2xsYmFyVGh1bWJSZW5kZXJlclRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kc2Nyb2xsYmFyVGh1bWJSZW5kZXJlci5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IHNjcm9sbGJhclRodW1iUmVuZGVyZXIoKSB7IHJldHVybiB0aGlzLl8kc2Nyb2xsYmFyVGh1bWJSZW5kZXJlci5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRzY3JvbGxiYXJUaHVtYlBhcmFtcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8eyBbcHJvcE5hbWU6IHN0cmluZ106IGFueSB9IHwgbnVsbD4oe30pO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkc2Nyb2xsYmFyVGh1bWJQYXJhbXMgPSB0aGlzLl8kc2Nyb2xsYmFyVGh1bWJQYXJhbXMuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX3Njcm9sbGJhclRodW1iUGFyYW1zVHJhbnNmb3JtID0gKHY6IHsgW3Byb3BOYW1lOiBzdHJpbmddOiBhbnkgfSB8IG51bGwpID0+IHtcclxuICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVPYmplY3QodiwgdHJ1ZSwgdHJ1ZSk7XHJcblxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJzY3JvbGxiYXJUaHVtYlBhcmFtc1wiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYG9iamVjdGAuJyk7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogQWRkaXRpb25hbCBvcHRpb25zIGZvciB0aGUgc2Nyb2xsYmFyLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNjcm9sbGJhclRodW1iUGFyYW1zKHY6IHsgW3Byb3BOYW1lOiBzdHJpbmddOiBhbnkgfSB8IG51bGwpIHtcclxuICAgIGlmICh0aGlzLl8kc2Nyb2xsYmFyVGh1bWJQYXJhbXMuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX3Njcm9sbGJhclRodW1iUGFyYW1zVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRzY3JvbGxiYXJUaHVtYlBhcmFtcy5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IHNjcm9sbGJhclRodW1iUGFyYW1zKCkgeyByZXR1cm4gdGhpcy5fJHNjcm9sbGJhclRodW1iUGFyYW1zLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfbG9hZGluZyA9IHtcclxuICAgIHRyYW5zZm9ybTogKHY6IGJvb2xlYW4pID0+IHtcclxuICAgICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUJvb2xlYW4odik7XHJcblxyXG4gICAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcignVGhlIFwibG9hZGluZ1wiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYGJvb2xlYW5gLicpO1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdjtcclxuICAgIH0sXHJcbiAgfSBhcyBhbnk7XHJcblxyXG4gIHByaXZhdGUgXyRsb2FkaW5nID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRsb2FkaW5nID0gdGhpcy5fJGxvYWRpbmcuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX2xvYWRpbmdUcmFuc2Zvcm0gPSAodjogYm9vbGVhbikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUJvb2xlYW4odik7XHJcblxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJsb2FkaW5nXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgYm9vbGVhbmAuJyk7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIElmIGB0cnVlYCwgdGhlIHNjcm9sbEJhciBnb2VzIGludG8gbG9hZGluZyBzdGF0ZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgYGZhbHNlYC5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBsb2FkaW5nKHY6IGJvb2xlYW4pIHtcclxuICAgIGlmICh0aGlzLl8kbG9hZGluZy5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fbG9hZGluZ1RyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kbG9hZGluZy5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IGxvYWRpbmcoKSB7IHJldHVybiB0aGlzLl8kbG9hZGluZy5nZXRWYWx1ZSgpIGFzIGJvb2xlYW47IH1cclxuXHJcbiAgcHJpdmF0ZSBfJHdhaXRGb3JQcmVwYXJhdGlvbiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oREVGQVVMVF9XQUlUX0ZPUl9QUkVQQVJBVElPTik7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICR3YWl0Rm9yUHJlcGFyYXRpb24gPSB0aGlzLl8kd2FpdEZvclByZXBhcmF0aW9uLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF93YWl0Rm9yUHJlcGFyYXRpb25UcmFuc2Zvcm0gPSAodjogYm9vbGVhbikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZU9iamVjdCh2KTtcclxuXHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcIndhaXRGb3JQcmVwYXJhdGlvblwiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYGJvb2xlYW5gLicpO1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9XQUlUX0ZPUl9QUkVQQVJBVElPTjtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIElmIHRydWUsIGl0IHdpbGwgd2FpdCB1bnRpbCB0aGUgbGlzdCBpdGVtcyBhcmUgZnVsbHkgcHJlcGFyZWQgYmVmb3JlIGRpc3BsYXlpbmcgdGhlbS4uIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGB0cnVlYC5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCB3YWl0Rm9yUHJlcGFyYXRpb24odjogYm9vbGVhbikge1xyXG4gICAgaWYgKHRoaXMuXyR3YWl0Rm9yUHJlcGFyYXRpb24uZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX3dhaXRGb3JQcmVwYXJhdGlvblRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kd2FpdEZvclByZXBhcmF0aW9uLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgd2FpdEZvclByZXBhcmF0aW9uKCkgeyByZXR1cm4gdGhpcy5fJHdhaXRGb3JQcmVwYXJhdGlvbi5nZXRWYWx1ZSgpIGFzIGJvb2xlYW47IH1cclxuXHJcbiAgcHJpdmF0ZSBfJGNsaWNrRGlzdGFuY2UgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oREVGQVVMVF9DTElDS19ESVNUQU5DRSk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRjbGlja0Rpc3RhbmNlID0gdGhpcy5fJGNsaWNrRGlzdGFuY2UuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX2NsaWNrRGlzdGFuY2VUcmFuc2Zvcm0gPSAodjogbnVtYmVyKSA9PiB7XHJcbiAgICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlSW50KHYpO1xyXG5cclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwiY2xpY2tEaXN0YW5jZVwiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYG51bWJlcmAuJyk7XHJcbiAgICAgIHJldHVybiBERUZBVUxUX0NMSUNLX0RJU1RBTkNFO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIG1heGltdW0gc2Nyb2xsIGRpc3RhbmNlIGF0IHdoaWNoIGEgY2xpY2sgZXZlbnQgaXMgdHJpZ2dlcmVkLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGNsaWNrRGlzdGFuY2UodjogbnVtYmVyKSB7XHJcbiAgICBpZiAodGhpcy5fJGNsaWNrRGlzdGFuY2UuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX2NsaWNrRGlzdGFuY2VUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJGNsaWNrRGlzdGFuY2UubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBjbGlja0Rpc3RhbmNlKCkgeyByZXR1cm4gdGhpcy5fJGNsaWNrRGlzdGFuY2UuZ2V0VmFsdWUoKSBhcyBudW1iZXI7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJGl0ZW1zID0gbmV3IEJlaGF2aW9yU3ViamVjdDxJVmlydHVhbExpc3RDb2xsZWN0aW9uPihbXSk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRpdGVtcyA9IHRoaXMuXyRpdGVtcy5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfaXRlbXNUcmFuc2Zvcm0gPSAodjogSVZpcnR1YWxMaXN0Q29sbGVjdGlvbikgPT4ge1xyXG4gICAgbGV0IHZhbGlkID0gdmFsaWRhdGVBcnJheSh2LCB0cnVlLCB0cnVlKTtcclxuICAgIGlmICh2YWxpZCkge1xyXG4gICAgICBpZiAodikge1xyXG4gICAgICAgIGNvbnN0IHRyYWNrQnkgPSB0aGlzLnRyYWNrQnk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSB2Lmxlbmd0aDsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgICAgY29uc3QgaXRlbSA9IHZbaV07XHJcbiAgICAgICAgICB2YWxpZCA9IHZhbGlkYXRlT2JqZWN0KGl0ZW0sIHRydWUsIHRydWUpO1xyXG4gICAgICAgICAgaWYgKHZhbGlkKSB7XHJcbiAgICAgICAgICAgIGlmIChpdGVtICYmICEodmFsaWRhdGVGbG9hdChpdGVtPy5bdHJhY2tCeV0gYXMgbnVtYmVyLCB0cnVlKSB8fCB2YWxpZGF0ZVN0cmluZyhpdGVtPy5bdHJhY2tCeV0gYXMgc3RyaW5nLCB0cnVlLCB0cnVlKSkpIHtcclxuICAgICAgICAgICAgICB2YWxpZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJpdGVtc1wiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYElWaXJ0dWFsTGlzdENvbGxlY3Rpb25gIG9yIGBudWxsYC4nKTtcclxuICAgICAgcmV0dXJuIFtdO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogQ29sbGVjdGlvbiBvZiBsaXN0IGl0ZW1zLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGl0ZW1zKHY6IElWaXJ0dWFsTGlzdENvbGxlY3Rpb24pIHtcclxuICAgIGlmICh0aGlzLl8kaXRlbXMuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX2l0ZW1zVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRpdGVtcy5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IGl0ZW1zKCkgeyByZXR1cm4gdGhpcy5fJGl0ZW1zLmdldFZhbHVlKCkgYXMgSVZpcnR1YWxMaXN0Q29sbGVjdGlvbjsgfVxyXG5cclxuICBwcml2YXRlIF8kc2VsZWN0ZWRJZHMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEFycmF5PElkPiB8IElkIHwgbnVsbD4obnVsbCk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRzZWxlY3RlZElkcyA9IHRoaXMuXyRzZWxlY3RlZElkcy5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfc2VsZWN0ZWRJZHNUcmFuc2Zvcm0gPSAodjogQXJyYXk8SWQ+IHwgSWQgfCBudWxsKSA9PiB7XHJcbiAgICBsZXQgdmFsaWQgPSB2YWxpZGF0ZUFycmF5KHYgYXMgYW55LCB0cnVlLCB0cnVlKSB8fCB2YWxpZGF0ZVN0cmluZyh2IGFzIGFueSwgdHJ1ZSwgdHJ1ZSkgfHwgdmFsaWRhdGVGbG9hdCh2IGFzIGFueSwgdHJ1ZSk7XHJcbiAgICBpZiAodmFsaWQpIHtcclxuICAgICAgaWYgKHYgJiYgQXJyYXkuaXNBcnJheSh2KSkge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsID0gdi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICAgIGNvbnN0IGl0ZW0gPSB2W2ldO1xyXG4gICAgICAgICAgdmFsaWQgPSB2YWxpZGF0ZVN0cmluZyhpdGVtIGFzIGFueSkgfHwgdmFsaWRhdGVGbG9hdChpdGVtIGFzIGFueSk7XHJcbiAgICAgICAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwic2VsZWN0ZWRJZHNcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBBcnJheTxJZD4gfCBJZGAgb3IgYG51bGxgLicpO1xyXG4gICAgICByZXR1cm4gdGhpcy5faXNNdWx0aVNlbGVjdGlvbiA/IFtdIDogbnVsbDtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIFNldHMgdGhlIHNlbGVjdGVkIGl0ZW1zLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNlbGVjdGVkSWRzKHY6IEFycmF5PElkPiB8IElkIHwgbnVsbCkge1xyXG4gICAgaWYgKHRoaXMuXyRzZWxlY3RlZElkcy5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fc2VsZWN0ZWRJZHNUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJHNlbGVjdGVkSWRzLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgc2VsZWN0ZWRJZHMoKSB7IHJldHVybiB0aGlzLl8kc2VsZWN0ZWRJZHMuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF8kZGVmYXVsdEl0ZW1WYWx1ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SVZpcnR1YWxMaXN0SXRlbSB8IG51bGw+KG51bGwpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkZGVmYXVsdEl0ZW1WYWx1ZSA9IHRoaXMuXyRkZWZhdWx0SXRlbVZhbHVlLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHNldCBkZWZhdWx0SXRlbVZhbHVlKHY6IElWaXJ0dWFsTGlzdEl0ZW0gfCBudWxsKSB7XHJcbiAgICBpZiAodGhpcy5fJGRlZmF1bHRJdGVtVmFsdWUuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fJGRlZmF1bHRJdGVtVmFsdWUubmV4dCh2KTtcclxuICB9O1xyXG4gIGdldCBkZWZhdWx0SXRlbVZhbHVlKCkgeyByZXR1cm4gdGhpcy5fJGRlZmF1bHRJdGVtVmFsdWUuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF8kY29sbGFwc2VkSWRzID0gbmV3IEJlaGF2aW9yU3ViamVjdDxBcnJheTxJZD4+KFtdKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJGNvbGxhcHNlZElkcyA9IHRoaXMuXyRjb2xsYXBzZWRJZHMuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX2NvbGxhcHNlZElkc1RyYW5zZm9ybSA9ICh2OiBBcnJheTxJZD4pID0+IHtcclxuICAgIGxldCB2YWxpZCA9IHZhbGlkYXRlQXJyYXkodiBhcyBhbnksIHRydWUsIHRydWUpO1xyXG4gICAgaWYgKHZhbGlkKSB7XHJcbiAgICAgIGlmICh2ICYmIEFycmF5LmlzQXJyYXkodikpIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbCA9IHYubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgICBjb25zdCBpdGVtID0gdltpXTtcclxuICAgICAgICAgIHZhbGlkID0gdmFsaWRhdGVTdHJpbmcoaXRlbSBhcyBhbnkpIHx8IHZhbGlkYXRlRmxvYXQoaXRlbSBhcyBhbnkpO1xyXG4gICAgICAgICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcImNvbGxhcHNlZElkc1wiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYEFycmF5PElkPmAuJyk7XHJcbiAgICAgIHJldHVybiBbXTtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIFNldHMgdGhlIGNvbGxhcHNlZCBpdGVtcy5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBjb2xsYXBzZWRJZHModjogQXJyYXk8SWQ+KSB7XHJcbiAgICBpZiAodGhpcy5fJGNvbGxhcHNlZElkcy5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fY29sbGFwc2VkSWRzVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRjb2xsYXBzZWRJZHMubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBjb2xsYXBzZWRJZHMoKSB7IHJldHVybiB0aGlzLl8kY29sbGFwc2VkSWRzLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJHNlbGVjdEJ5Q2xpY2sgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KERFRkFVTFRfU0VMRUNUX0JZX0NMSUNLKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJHNlbGVjdEJ5Q2xpY2sgPSB0aGlzLl8kc2VsZWN0QnlDbGljay5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfc2VsZWN0QnlDbGlja1RyYW5zZm9ybSA9ICh2OiBib29sZWFuKSA9PiB7XHJcbiAgICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlQm9vbGVhbih2KTtcclxuXHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcInNlbGVjdEJ5Q2xpY2tcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBib29sZWFuYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfU0VMRUNUX0JZX0NMSUNLO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogSWYgYGZhbHNlYCwgdGhlIGVsZW1lbnQgaXMgc2VsZWN0ZWQgdXNpbmcgdGhlIGNvbmZpZy5hcGkgbWV0aG9kIHBhc3NlZCB0byB0aGUgdGVtcGxhdGU7IFxyXG4gICAqIGlmIGB0cnVlYCwgdGhlIGVsZW1lbnQgaXMgc2VsZWN0ZWQgYnkgY2xpY2tpbmcgb24gaXQuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGB0cnVlYC5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBzZWxlY3RCeUNsaWNrKHY6IGJvb2xlYW4pIHtcclxuICAgIGlmICh0aGlzLl8kc2VsZWN0QnlDbGljay5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fc2VsZWN0QnlDbGlja1RyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kc2VsZWN0QnlDbGljay5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IHNlbGVjdEJ5Q2xpY2soKSB7IHJldHVybiB0aGlzLl8kc2VsZWN0QnlDbGljay5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRjb2xsYXBzZUJ5Q2xpY2sgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KERFRkFVTFRfQ09MTEFQU0VfQllfQ0xJQ0spO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkY29sbGFwc2VCeUNsaWNrID0gdGhpcy5fJGNvbGxhcHNlQnlDbGljay5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfY29sbGFwc2VCeUNsaWNrVHJhbnNmb3JtID0gKHY6IGJvb2xlYW4pID0+IHtcclxuICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVCb29sZWFuKHYpO1xyXG5cclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwiY29sbGFwc2VCeUNsaWNrXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgYm9vbGVhbmAuJyk7XHJcbiAgICAgIHJldHVybiBERUZBVUxUX0NPTExBUFNFX0JZX0NMSUNLO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogSWYgYGZhbHNlYCwgdGhlIGVsZW1lbnQgaXMgY29sbGFwc2VkIHVzaW5nIHRoZSBjb25maWcuY29sbGFwc2UgbWV0aG9kIHBhc3NlZCB0byB0aGUgdGVtcGxhdGU7IFxyXG4gICAqIGlmIGB0cnVlYCwgdGhlIGVsZW1lbnQgaXMgY29sbGFwc2VkIGJ5IGNsaWNraW5nIG9uIGl0LiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgdHJ1ZWAuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgY29sbGFwc2VCeUNsaWNrKHY6IGJvb2xlYW4pIHtcclxuICAgIGlmICh0aGlzLl8kY29sbGFwc2VCeUNsaWNrLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9jb2xsYXBzZUJ5Q2xpY2tUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJGNvbGxhcHNlQnlDbGljay5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IGNvbGxhcHNlQnlDbGljaygpIHsgcmV0dXJuIHRoaXMuXyRjb2xsYXBzZUJ5Q2xpY2suZ2V0VmFsdWUoKTsgfVxyXG5cclxuICAvKipcclxuICAgKiBAZGVwcmVjYXRlZFxyXG4gICAqIFVzZSB0aGUgYHN0aWNreUVuYWJsZWRgIHByb3BlcnR5IGluc3RlYWQuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgc25hcCh2OiBib29sZWFuKSB7XHJcbiAgICB0aHJvdyBFcnJvcihgUHJvcGVydHkgc25hcCBpcyBkZXByZWNhdGVkLiBVc2UgdGhlIFxcYHN0aWNreUVuYWJsZWRcXGAgcHJvcGVydHkgaW5zdGVhZC5gKTtcclxuICB9O1xyXG5cclxuICBwcml2YXRlIF8kc3RpY2t5RW5hYmxlZCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oREVGQVVMVF9TVElDS1lfRU5BQkxFRCk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRzdGlja3lFbmFibGVkID0gdGhpcy5fJHN0aWNreUVuYWJsZWQuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX3N0aWNreUVuYWJsZWRUcmFuc2Zvcm0gPSAodjogYm9vbGVhbikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUJvb2xlYW4odik7XHJcblxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJzdGlja3lFbmFibGVkXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgYm9vbGVhbmAuJyk7XHJcbiAgICAgIHJldHVybiBERUZBVUxUX1NUSUNLWV9FTkFCTEVEO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGl0ZW1zIHdpdGggdGhlIGdpdmVuIGBzdGlja3lgIGluIGBpdGVtQ29uZmlnTWFwYCB3aWxsIHN0aWNrIHRvIHRoZSBlZGdlcy4gRGVmYXVsdCB2YWx1ZSBpcyBcInRydWVcIi5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBzdGlja3lFbmFibGVkKHY6IGJvb2xlYW4pIHtcclxuICAgIGlmICh0aGlzLl8kc3RpY2t5RW5hYmxlZC5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fc3RpY2t5RW5hYmxlZFRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kc3RpY2t5RW5hYmxlZC5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IHN0aWNreUVuYWJsZWQoKSB7IHJldHVybiB0aGlzLl8kc3RpY2t5RW5hYmxlZC5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRzbmFwVG9FbmRUcmFuc2l0aW9uSW5zdGFudE9mZnNldCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPihERUZBVUxUX1NOQVBfVE9fRU5EX1RSQU5TSVRJT05fSU5TVEFOVF9PRkZTRVQpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkc25hcFRvRW5kVHJhbnNpdGlvbkluc3RhbnRPZmZzZXQgPSB0aGlzLl8kc25hcFRvRW5kVHJhbnNpdGlvbkluc3RhbnRPZmZzZXQuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX3NuYXBUb0VuZFRyYW5zaXRpb25JbnN0YW50T2Zmc2V0VHJhbnNmb3JtID0gKHY6IG51bWJlcikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUZsb2F0KHYpO1xyXG5cclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwic25hcFRvRW5kVHJhbnNpdGlvbkluc3RhbnRPZmZzZXRcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBudW1iZXJgLicpO1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9TTkFQX1RPX0VORF9UUkFOU0lUSU9OX0lOU1RBTlRfT0ZGU0VUO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogU2V0cyB0aGUgb2Zmc2V0IHZhbHVlOyBpZiB0aGUgc2Nyb2xsIGFyZWEgdmFsdWUgaXMgZXhjZWVkZWQsIHRoZSBzY3JvbGwgYW5pbWF0aW9uIHdpbGwgYmUgZGlzYWJsZWQuIERlZmF1bHQgdmFsdWUgaXMgXCIwXCIuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgc25hcFRvRW5kVHJhbnNpdGlvbkluc3RhbnRPZmZzZXQodjogbnVtYmVyKSB7XHJcbiAgICBpZiAodGhpcy5fJHNuYXBUb0VuZFRyYW5zaXRpb25JbnN0YW50T2Zmc2V0LmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9zbmFwVG9FbmRUcmFuc2l0aW9uSW5zdGFudE9mZnNldFRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kc25hcFRvRW5kVHJhbnNpdGlvbkluc3RhbnRPZmZzZXQubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBzbmFwVG9FbmRUcmFuc2l0aW9uSW5zdGFudE9mZnNldCgpIHsgcmV0dXJuIHRoaXMuXyRzbmFwVG9FbmRUcmFuc2l0aW9uSW5zdGFudE9mZnNldC5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRzY3JvbGxTdGFydE9mZnNldCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8QXJpdGhtZXRpY0V4cHJlc3Npb24+KDApO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkc2Nyb2xsU3RhcnRPZmZzZXQgPSB0aGlzLl8kc2Nyb2xsU3RhcnRPZmZzZXQuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX3Njcm9sbFN0YXJ0T2Zmc2V0VHJhbnNmb3JtID0gKHY6IG51bWJlcikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUZsb2F0KHYsIHRydWUpIHx8IGlzUGVyY2VudGFnZVZhbHVlKHYpO1xyXG5cclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwic2Nyb2xsU3RhcnRPZmZzZXRcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvbmUgb2YgdHlwZSBgbnVtYmVyYCBvciBgc3RyaW5nYC4nKTtcclxuICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBTZXRzIHRoZSBzY3JvbGwgc3RhcnQgb2Zmc2V0IHZhbHVlLiBDYW4gYmUgc3BlY2lmaWVkIGluIGFic29sdXRlIG9yIHBlcmNlbnRhZ2UgdmFsdWVzLlxyXG4gICAqIFN1cHBvcnRzIGFyaXRobWV0aWMgZXhwcmVzc2lvbnMgb2YgYWRkaXRpb24gYDUwJSArIDI1YCBvciBzdWJ0cmFjdGlvbiBgNTAlIC0gMjVgLiBEZWZhdWx0IHZhbHVlIGlzIFwiMFwiLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNjcm9sbFN0YXJ0T2Zmc2V0KHY6IEFyaXRobWV0aWNFeHByZXNzaW9uKSB7XHJcbiAgICBpZiAodGhpcy5fJHNjcm9sbFN0YXJ0T2Zmc2V0LmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9zY3JvbGxTdGFydE9mZnNldFRyYW5zZm9ybSh2IGFzIGFueSk7XHJcblxyXG4gICAgdGhpcy5fJHNjcm9sbFN0YXJ0T2Zmc2V0Lm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgc2Nyb2xsU3RhcnRPZmZzZXQoKSB7IHJldHVybiB0aGlzLl8kc2Nyb2xsU3RhcnRPZmZzZXQuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF8kc2Nyb2xsRW5kT2Zmc2V0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxBcml0aG1ldGljRXhwcmVzc2lvbj4oMCk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRzY3JvbGxFbmRPZmZzZXQgPSB0aGlzLl8kc2Nyb2xsRW5kT2Zmc2V0LmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF9zY3JvbGxFbmRPZmZzZXRUcmFuc2Zvcm0gPSAodjogbnVtYmVyKSA9PiB7XHJcbiAgICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlRmxvYXQodiwgdHJ1ZSkgfHwgaXNQZXJjZW50YWdlVmFsdWUodik7XHJcblxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJzY3JvbGxFbmRPZmZzZXRcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvbmUgb2YgdHlwZSBgbnVtYmVyYCBvciBgc3RyaW5nYC4nKTtcclxuICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBTZXRzIHRoZSBzY3JvbGwgZW5kIG9mZnNldCB2YWx1ZS4gQ2FuIGJlIHNwZWNpZmllZCBpbiBhYnNvbHV0ZSBvciBwZXJjZW50YWdlIHZhbHVlcy5cclxuICAgKiBTdXBwb3J0cyBhcml0aG1ldGljIGV4cHJlc3Npb25zIG9mIGFkZGl0aW9uIGA1MCUgKyAyNWAgb3Igc3VidHJhY3Rpb24gYDUwJSAtIDI1YC4gRGVmYXVsdCB2YWx1ZSBpcyBcIjBcIi5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBzY3JvbGxFbmRPZmZzZXQodjogQXJpdGhtZXRpY0V4cHJlc3Npb24pIHtcclxuICAgIGlmICh0aGlzLl8kc2Nyb2xsRW5kT2Zmc2V0LmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9zY3JvbGxFbmRPZmZzZXRUcmFuc2Zvcm0odiBhcyBhbnkpO1xyXG5cclxuICAgIHRoaXMuXyRzY3JvbGxFbmRPZmZzZXQubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBzY3JvbGxFbmRPZmZzZXQoKSB7IHJldHVybiB0aGlzLl8kc2Nyb2xsRW5kT2Zmc2V0LmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJHNuYXBTY3JvbGxUb1N0YXJ0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihERUZBVUxUX1NOQVBfU0NST0xMVE9fU1RBUlQpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkc25hcFNjcm9sbFRvU3RhcnQgPSB0aGlzLl8kc25hcFNjcm9sbFRvU3RhcnQuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX3NuYXBTY3JvbGxUb1N0YXJ0VHJhbnNmb3JtID0gKHY6IGJvb2xlYW4pID0+IHtcclxuICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVCb29sZWFuKHYsIHRydWUpO1xyXG5cclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwic25hcFNjcm9sbFRvU3RhcnRcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBib29sZWFuYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfU05BUF9TQ1JPTExUT19TVEFSVDtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIERldGVybWluZXMgd2hldGhlciB0aGUgc2Nyb2xsIHdpbGwgYmUgYW5jaG9yZWQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBsaXN0LiBEZWZhdWx0IHZhbHVlIGlzIFwidHJ1ZVwiLlxyXG4gICAqIFRoaXMgcHJvcGVydHkgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIHRoZSBzbmFwU2Nyb2xsVG9FbmQgcHJvcGVydHkuXHJcbiAgICogVGhhdCBpcywgaWYgc25hcFNjcm9sbFRvU3RhcnQgYW5kIHNuYXBTY3JvbGxUb0VuZCBhcmUgZW5hYmxlZCwgdGhlIGxpc3Qgd2lsbCBpbml0aWFsbHkgc25hcCBcclxuICAgKiB0byB0aGUgYmVnaW5uaW5nOyBpZiB5b3UgbW92ZSB0aGUgc2Nyb2xsIGJhciB0byB0aGUgZW5kLCB0aGUgbGlzdCB3aWxsIHNuYXAgdG8gdGhlIGVuZC4gXHJcbiAgICogSWYgc25hcFNjcm9sbFRvU3RhcnQgaXMgZGlzYWJsZWQgYW5kIHNuYXBTY3JvbGxUb0VuZCBpcyBlbmFibGVkLCB0aGUgbGlzdCB3aWxsIHNuYXAgdG8gdGhlIGVuZDsgXHJcbiAgICogaWYgeW91IG1vdmUgdGhlIHNjcm9sbCBiYXIgdG8gdGhlIGJlZ2lubmluZywgdGhlIGxpc3Qgd2lsbCBzbmFwIHRvIHRoZSBiZWdpbm5pbmcuIFxyXG4gICAqIElmIGJvdGggc25hcFNjcm9sbFRvU3RhcnQgYW5kIHNuYXBTY3JvbGxUb0VuZCBhcmUgZGlzYWJsZWQsIHRoZSBsaXN0IHdpbGwgbmV2ZXIgc25hcCB0byB0aGUgYmVnaW5uaW5nIG9yIGVuZC5cclxuICAgKiBJbiB0aGUgYHNwcmVhZGluZ01vZGU9U3ByZWFkaW5nTW9kZXMuSU5GSU5JVFlgIG1vZGUsIHRoZSBgc25hcFNjcm9sbFRvU3RhcnRgIHByb3BlcnR5IGlzIGF1dG9tYXRpY2FsbHkgZGlzYWJsZWQsIHNpbmNlIHRoZSBsaXN0IGhhcyBubyBiZWdpbm5pbmcgb3IgZW5kLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNuYXBTY3JvbGxUb1N0YXJ0KHY6IGJvb2xlYW4pIHtcclxuICAgIGlmICh0aGlzLl8kc25hcFNjcm9sbFRvU3RhcnQuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX3NuYXBTY3JvbGxUb1N0YXJ0VHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRzbmFwU2Nyb2xsVG9TdGFydC5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IHNuYXBTY3JvbGxUb1N0YXJ0KCkgeyByZXR1cm4gdGhpcy5fJHNuYXBTY3JvbGxUb1N0YXJ0LmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJHNuYXBTY3JvbGxUb0VuZCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oREVGQVVMVF9TTkFQX1NDUk9MTFRPX0VORCk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRzbmFwU2Nyb2xsVG9FbmQgPSB0aGlzLl8kc25hcFNjcm9sbFRvRW5kLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF9zbmFwU2Nyb2xsVG9FbmRUcmFuc2Zvcm0gPSAodjogYm9vbGVhbikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUJvb2xlYW4odiwgdHJ1ZSk7XHJcblxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJzbmFwU2Nyb2xsVG9FbmRcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBib29sZWFuYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfU05BUF9TQ1JPTExUT19FTkQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHNjcm9sbCB3aWxsIGJlIGFuY2hvcmVkIHRvIHRoZSDRg9GC0LIgb2YgdGhlIGxpc3QuIERlZmF1bHQgdmFsdWUgaXMgXCJ0cnVlXCIuXHJcbiAgICogVGhhdCBpcywgaWYgc25hcFNjcm9sbFRvU3RhcnQgYW5kIHNuYXBTY3JvbGxUb0VuZCBhcmUgZW5hYmxlZCwgdGhlIGxpc3Qgd2lsbCBpbml0aWFsbHkgc25hcCBcclxuICAgKiB0byB0aGUgYmVnaW5uaW5nOyBpZiB5b3UgbW92ZSB0aGUgc2Nyb2xsIGJhciB0byB0aGUgZW5kLCB0aGUgbGlzdCB3aWxsIHNuYXAgdG8gdGhlIGVuZC4gXHJcbiAgICogSWYgc25hcFNjcm9sbFRvU3RhcnQgaXMgZGlzYWJsZWQgYW5kIHNuYXBTY3JvbGxUb0VuZCBpcyBlbmFibGVkLCB0aGUgbGlzdCB3aWxsIHNuYXAgdG8gdGhlIGVuZDsgXHJcbiAgICogaWYgeW91IG1vdmUgdGhlIHNjcm9sbCBiYXIgdG8gdGhlIGJlZ2lubmluZywgdGhlIGxpc3Qgd2lsbCBzbmFwIHRvIHRoZSBiZWdpbm5pbmcuIFxyXG4gICAqIElmIGJvdGggc25hcFNjcm9sbFRvU3RhcnQgYW5kIHNuYXBTY3JvbGxUb0VuZCBhcmUgZGlzYWJsZWQsIHRoZSBsaXN0IHdpbGwgbmV2ZXIgc25hcCB0byB0aGUgYmVnaW5uaW5nIG9yIGVuZC5cclxuICAgKiBJbiB0aGUgYHNwcmVhZGluZ01vZGU9U3ByZWFkaW5nTW9kZXMuSU5GSU5JVFlgIG1vZGUsIHRoZSBgc25hcFNjcm9sbFRvRW5kYCBwcm9wZXJ0eSBpcyBhdXRvbWF0aWNhbGx5IGRpc2FibGVkLCBzaW5jZSB0aGUgbGlzdCBoYXMgbm8gYmVnaW5uaW5nIG9yIGVuZC5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBzbmFwU2Nyb2xsVG9FbmQodjogYm9vbGVhbikge1xyXG4gICAgaWYgKHRoaXMuXyRzbmFwU2Nyb2xsVG9FbmQuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX3NuYXBTY3JvbGxUb0VuZFRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kc25hcFNjcm9sbFRvRW5kLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgc25hcFNjcm9sbFRvRW5kKCkgeyByZXR1cm4gdGhpcy5fJHNuYXBTY3JvbGxUb0VuZC5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEBkZXByZWNhdGVkXHJcbiAgICogVGhlIHN0b3BTbmFwcGluZ1Njcm9sbFRvRW5kIHByb3BlcnR5IGlzIGRlcHJlY2F0ZWQuIFVzZSB0aGUgc25hcFNjcm9sbFRvRW5kIHByb3BlcnR5LlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNuYXBTY3JvbGxUb0JvdHRvbSh2OiBib29sZWFuKSB7XHJcbiAgICB0aHJvdyBFcnJvcignVGhlIHN0b3BTbmFwcGluZ1Njcm9sbFRvRW5kIHByb3BlcnR5IGlzIGRlcHJlY2F0ZWQuIFVzZSB0aGUgc25hcFNjcm9sbFRvRW5kIHByb3BlcnR5LicpO1xyXG4gIH1cclxuXHJcblxyXG4gIHByaXZhdGUgXyRzY3JvbGxiYXJFbmFibGVkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihERUZBVUxUX1NDUk9MTEJBUl9FTkFCTEVEKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJHNjcm9sbGJhckVuYWJsZWQgPSB0aGlzLl8kc2Nyb2xsYmFyRW5hYmxlZC5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfc2Nyb2xsYmFyRW5hYmxlZFRyYW5zZm9ybSA9ICh2OiBib29sZWFuKSA9PiB7XHJcbiAgICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlQm9vbGVhbih2LCB0cnVlKTtcclxuXHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcInNjcm9sbGJhckVuYWJsZWRcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBib29sZWFuYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfU0NST0xMQkFSX0VOQUJMRUQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHNjcm9sbGJhciBpcyBzaG93biBvciBub3QuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIFwidHJ1ZVwiLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNjcm9sbGJhckVuYWJsZWQodjogYm9vbGVhbikge1xyXG4gICAgaWYgKHRoaXMuXyRzY3JvbGxiYXJFbmFibGVkLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9zY3JvbGxiYXJFbmFibGVkVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRzY3JvbGxiYXJFbmFibGVkLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgc2Nyb2xsYmFyRW5hYmxlZCgpIHsgcmV0dXJuIHRoaXMuXyRzY3JvbGxiYXJFbmFibGVkLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJHNjcm9sbGJhckludGVyYWN0aXZlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihERUZBVUxUX1NDUk9MTEJBUl9JTlRFUkFDVElWRSk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRzY3JvbGxiYXJJbnRlcmFjdGl2ZSA9IHRoaXMuXyRzY3JvbGxiYXJJbnRlcmFjdGl2ZS5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfc2Nyb2xsYmFySW50ZXJhY3RpdmVUcmFuc2Zvcm0gPSAodjogYm9vbGVhbikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUJvb2xlYW4odiwgdHJ1ZSk7XHJcblxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJzY3JvbGxiYXJJbnRlcmFjdGl2ZVwiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYGJvb2xlYW5gLicpO1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9TQ1JPTExCQVJfSU5URVJBQ1RJVkU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgc2Nyb2xsaW5nIHVzaW5nIHRoZSBzY3JvbGxiYXIgd2lsbCBiZSBwb3NzaWJsZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgXCJ0cnVlXCIuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgc2Nyb2xsYmFySW50ZXJhY3RpdmUodjogYm9vbGVhbikge1xyXG4gICAgaWYgKHRoaXMuXyRzY3JvbGxiYXJJbnRlcmFjdGl2ZS5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fc2Nyb2xsYmFySW50ZXJhY3RpdmVUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJHNjcm9sbGJhckludGVyYWN0aXZlLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgc2Nyb2xsYmFySW50ZXJhY3RpdmUoKSB7IHJldHVybiB0aGlzLl8kc2Nyb2xsYmFySW50ZXJhY3RpdmUuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF8kb3ZlcmxhcHBpbmdTY3JvbGxiYXIgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KERFRkFVTFRfT1ZFUkxBUFBJTkdfU0NST0xMQkFSKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJG92ZXJsYXBwaW5nU2Nyb2xsYmFyID0gdGhpcy5fJG92ZXJsYXBwaW5nU2Nyb2xsYmFyLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF9vdmVybGFwcGluZ1Njcm9sbGJhclRyYW5zZm9ybSA9ICh2OiBib29sZWFuKSA9PiB7XHJcbiAgICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlQm9vbGVhbih2LCB0cnVlKTtcclxuXHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcIm92ZXJsYXBwaW5nU2Nyb2xsYmFyXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgYm9vbGVhbmAuJyk7XHJcbiAgICAgIHJldHVybiBERUZBVUxUX09WRVJMQVBQSU5HX1NDUk9MTEJBUjtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIERldGVybWluZXMgd2hldGhlciB0aGUgc2Nyb2xsIGJhciB3aWxsIG92ZXJsYXAgdGhlIGxpc3QuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIFwiZmFsc2VcIi5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBvdmVybGFwcGluZ1Njcm9sbGJhcih2OiBib29sZWFuKSB7XHJcbiAgICBpZiAodGhpcy5fJG92ZXJsYXBwaW5nU2Nyb2xsYmFyLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9vdmVybGFwcGluZ1Njcm9sbGJhclRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kb3ZlcmxhcHBpbmdTY3JvbGxiYXIubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBvdmVybGFwcGluZ1Njcm9sbGJhcigpIHsgcmV0dXJuIHRoaXMuXyRvdmVybGFwcGluZ1Njcm9sbGJhci5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRzY3JvbGxCZWhhdmlvciA9IG5ldyBCZWhhdmlvclN1YmplY3Q8U2Nyb2xsQmVoYXZpb3I+KERFRkFVTFRfU0NST0xMX0JFSEFWSU9SKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJHNjcm9sbEJlaGF2aW9yID0gdGhpcy5fJHNjcm9sbEJlaGF2aW9yLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF9zY3JvbGxCZWhhdmlvclRyYW5zZm9ybSA9ICh2OiBTY3JvbGxCZWhhdmlvcikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZVN0cmluZyh2LCB0cnVlLCB0cnVlKTtcclxuXHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcInNjcm9sbEJlaGF2aW9yXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgYm9vbGVhbmAuJyk7XHJcbiAgICAgIHJldHVybiBERUZBVUxUX1NDUk9MTF9CRUhBVklPUjtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIERlZmluZXMgdGhlIHNjcm9sbGluZyBiZWhhdmlvciBmb3IgYW55IGVsZW1lbnQgb24gdGhlIHBhZ2UuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIFwic21vb3RoXCIuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgc2Nyb2xsQmVoYXZpb3IodjogU2Nyb2xsQmVoYXZpb3IpIHtcclxuICAgIGlmICh0aGlzLl8kc2Nyb2xsQmVoYXZpb3IuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX3Njcm9sbEJlaGF2aW9yVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRzY3JvbGxCZWhhdmlvci5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IHNjcm9sbEJlaGF2aW9yKCkgeyByZXR1cm4gdGhpcy5fJHNjcm9sbEJlaGF2aW9yLmdldFZhbHVlKCk7IH1cclxuXHJcblxyXG5cclxuXHJcblxyXG5cclxuICBwcml2YXRlIF8kc2Nyb2xsaW5nU2V0dGluZ3MgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PElTY3JvbGxpbmdTZXR0aW5ncz4oREVGQVVMVF9TQ1JPTExJTkdfU0VUVElOR1MpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkc2Nyb2xsaW5nU2V0dGluZ3MgPSB0aGlzLl8kc2Nyb2xsaW5nU2V0dGluZ3MuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX3Njcm9sbGluZ1NldHRpbmdzVHJhbnNmb3JtID0gKHY6IElTY3JvbGxpbmdTZXR0aW5ncyk6IElTY3JvbGxpbmdTZXR0aW5ncyA9PiB7XHJcbiAgICBsZXQgdmFsaWQgPSB2YWxpZGF0ZU9iamVjdCh2LCB0cnVlLCB0cnVlKTtcclxuICAgIGlmICh2YWxpZCAmJiAhIXYpIHtcclxuICAgICAgY29uc3QgeyBmcmljdGlvbmFsRm9yY2UsIG1hc3MsIG1heERpc3RhbmNlLCBtYXhEdXJhdGlvbiwgc3BlZWRTY2FsZSwgb3B0aW1pemF0aW9uIH0gPSB2O1xyXG4gICAgICB2YWxpZCA9IHZhbGlkYXRlRmxvYXQoZnJpY3Rpb25hbEZvcmNlLCB0cnVlKTtcclxuICAgICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcImZyaWN0aW9uYWxGb3JjZVwiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYG51bWJlcmAgb3IgYHVuZGVmaW5lZGAuJyk7XHJcbiAgICAgICAgcmV0dXJuIERFRkFVTFRfU0NST0xMSU5HX1NFVFRJTkdTO1xyXG4gICAgICB9XHJcbiAgICAgIHZhbGlkID0gdmFsaWRhdGVGbG9hdChtYXNzLCB0cnVlKTtcclxuICAgICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcIm1hc3NcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBudW1iZXJgIG9yIGB1bmRlZmluZWRgLicpO1xyXG4gICAgICAgIHJldHVybiBERUZBVUxUX1NDUk9MTElOR19TRVRUSU5HUztcclxuICAgICAgfVxyXG4gICAgICB2YWxpZCA9IHZhbGlkYXRlRmxvYXQobWF4RGlzdGFuY2UsIHRydWUpO1xyXG4gICAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcignVGhlIFwibWF4RGlzdGFuY2VcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBudW1iZXJgIG9yIGB1bmRlZmluZWRgLicpO1xyXG4gICAgICAgIHJldHVybiBERUZBVUxUX1NDUk9MTElOR19TRVRUSU5HUztcclxuICAgICAgfVxyXG4gICAgICB2YWxpZCA9IHZhbGlkYXRlRmxvYXQobWF4RHVyYXRpb24sIHRydWUpO1xyXG4gICAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcignVGhlIFwibWF4RHVyYXRpb25cIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBudW1iZXJgIG9yIGB1bmRlZmluZWRgLicpO1xyXG4gICAgICAgIHJldHVybiBERUZBVUxUX1NDUk9MTElOR19TRVRUSU5HUztcclxuICAgICAgfVxyXG4gICAgICB2YWxpZCA9IHZhbGlkYXRlRmxvYXQoc3BlZWRTY2FsZSwgdHJ1ZSk7XHJcbiAgICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJzcGVlZFNjYWxlXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgbnVtYmVyYCBvciBgdW5kZWZpbmVkYC4nKTtcclxuICAgICAgICByZXR1cm4gREVGQVVMVF9TQ1JPTExJTkdfU0VUVElOR1M7XHJcbiAgICAgIH1cclxuICAgICAgdmFsaWQgPSB2YWxpZGF0ZUJvb2xlYW4ob3B0aW1pemF0aW9uLCB0cnVlKTtcclxuICAgICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcIm9wdGltaXphdGlvblwiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYGJvb2xlYW5gIG9yIGB1bmRlZmluZWRgLicpO1xyXG4gICAgICAgIHJldHVybiBERUZBVUxUX1NDUk9MTElOR19TRVRUSU5HUztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJzY3JvbGxpbmdTZXR0aW5nc1wiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYG9iamVjdGAgb3IgbnVsbC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfU0NST0xMSU5HX1NFVFRJTkdTO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgZnJpY3Rpb25hbEZvcmNlOiB2LmZyaWN0aW9uYWxGb3JjZSAhPT0gdW5kZWZpbmVkICYmIHYuZnJpY3Rpb25hbEZvcmNlID4gMCA/IHYuZnJpY3Rpb25hbEZvcmNlIDogREVGQVVMVF9TQ1JPTExJTkdfU0VUVElOR1MuZnJpY3Rpb25hbEZvcmNlLFxyXG4gICAgICBtYXNzOiB2Lm1hc3MgIT09IHVuZGVmaW5lZCAmJiB2Lm1hc3MgPiAwID8gdi5tYXNzIDogREVGQVVMVF9TQ1JPTExJTkdfU0VUVElOR1MubWFzcyxcclxuICAgICAgbWF4RGlzdGFuY2U6IHYubWF4RGlzdGFuY2UgIT09IHVuZGVmaW5lZCAmJiB2Lm1heERpc3RhbmNlID4gMCA/IHYubWF4RGlzdGFuY2UgOiBERUZBVUxUX1NDUk9MTElOR19TRVRUSU5HUy5tYXhEaXN0YW5jZSxcclxuICAgICAgbWF4RHVyYXRpb246IHYubWF4RHVyYXRpb24gIT09IHVuZGVmaW5lZCAmJiB2Lm1heER1cmF0aW9uID4gMCA/IHYubWF4RHVyYXRpb24gOiBERUZBVUxUX1NDUk9MTElOR19TRVRUSU5HUy5tYXhEdXJhdGlvbixcclxuICAgICAgc3BlZWRTY2FsZTogdi5zcGVlZFNjYWxlICE9PSB1bmRlZmluZWQgJiYgdi5zcGVlZFNjYWxlID4gMCA/IHYuc3BlZWRTY2FsZSA6IERFRkFVTFRfU0NST0xMSU5HX1NFVFRJTkdTLnNwZWVkU2NhbGUsXHJcbiAgICAgIG9wdGltaXphdGlvbjogdi5vcHRpbWl6YXRpb24gPz8gREVGQVVMVF9TQ1JPTExJTkdfU0VUVElOR1Mub3B0aW1pemF0aW9uLFxyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBTY3JvbGxpbmcgc2V0dGluZ3MuXHJcbiAgICogLSBmcmljdGlvbmFsRm9yY2UgLSBGcmljdGlvbmFsIGZvcmNlLiBEZWZhdWx0IHZhbHVlIGlzIDAuMDM1LlxyXG4gICAqIC0gbWFzcyAtIE1hc3MuIERlZmF1bHQgdmFsdWUgaXMgMC4wMDUuXHJcbiAgICogLSBtYXhEaXN0YW5jZSAtIE1heGltdW0gc2Nyb2xsaW5nIGRpc3RhbmNlLiBEZWZhdWx0IHZhbHVlIGlzIDEwMDAwMC5cclxuICAgKiAtIG1heER1cmF0aW9uIC0gTWF4aW11bSBhbmltYXRpb24gZHVyYXRpb24uIERlZmF1bHQgdmFsdWUgaXMgNDAwMC5cclxuICAgKiAtIHNwZWVkU2NhbGUgLSBTcGVlZCBzY2FsZS4gRGVmYXVsdCB2YWx1ZSBpcyAxMC5cclxuICAgKiAtIG9wdGltaXphdGlvbiAtIEVuYWJsZXMgc2Nyb2xsaW5nIHBlcmZvcm1hbmNlIG9wdGltaXphdGlvbi4gRGVmYXVsdCB2YWx1ZSBpcyBgdHJ1ZWAuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgc2Nyb2xsaW5nU2V0dGluZ3ModjogSVNjcm9sbGluZ1NldHRpbmdzKSB7XHJcbiAgICBpZiAodGhpcy5fJHNjcm9sbGluZ1NldHRpbmdzLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9zY3JvbGxpbmdTZXR0aW5nc1RyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kc2Nyb2xsaW5nU2V0dGluZ3MubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBzY3JvbGxpbmdTZXR0aW5ncygpIHsgcmV0dXJuIHRoaXMuXyRzY3JvbGxpbmdTZXR0aW5ncy5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRpdGVtVHJhbnNmb3JtID0gbmV3IEJlaGF2aW9yU3ViamVjdDxJdGVtVHJhbnNmb3JtIHwgbnVsbD4obnVsbCk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRpdGVtVHJhbnNmb3JtID0gdGhpcy5fJGl0ZW1UcmFuc2Zvcm0uYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX2l0ZW1UcmFuc2Zvcm1UcmFuc2Zvcm0gPSAodjogYW55KSA9PiB7XHJcbiAgICBsZXQgdmFsaWQgPSB2YWxpZGF0ZUZ1bmN0aW9uKHYsIHRydWUsIHRydWUpO1xyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJpdGVtVHJhbnNmb3JtXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgSXRlbVRyYW5zZm9ybWAgb3IgYG51bGxgLicpO1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIEN1c3RvbSB0cmFuc2Zvcm1hdGlvbiBvZiBlbGVtZW50J3MgcG9zaXRpb24sIHJvdGF0aW9uLCBzY2FsZSwgb3BhY2l0eSBhbmQgekluZGV4LiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgbnVsbGAuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgaXRlbVRyYW5zZm9ybSh2OiBJdGVtVHJhbnNmb3JtIHwgbnVsbCkge1xyXG4gICAgaWYgKHRoaXMuXyRpdGVtVHJhbnNmb3JtLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9pdGVtVHJhbnNmb3JtVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRpdGVtVHJhbnNmb3JtLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgaXRlbVRyYW5zZm9ybSgpIHsgcmV0dXJuIHRoaXMuXyRpdGVtVHJhbnNmb3JtLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJHNuYXBUb0l0ZW0gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KERFRkFVTFRfU05BUF9UT19JVEVNKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJHNuYXBUb0l0ZW0gPSB0aGlzLl8kc25hcFRvSXRlbS5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfc25hcFRvSXRlbVRyYW5zZm9ybSA9ICh2OiBib29sZWFuKSA9PiB7XHJcbiAgICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlQm9vbGVhbih2KTtcclxuXHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcInNuYXBUb0l0ZW1cIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBib29sZWFuYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfU05BUF9UT19JVEVNO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogU25hcCB0byBhbiBpdGVtLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgZmFsc2VgLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNuYXBUb0l0ZW0odjogYm9vbGVhbikge1xyXG4gICAgaWYgKHRoaXMuXyRzbmFwVG9JdGVtLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9zbmFwVG9JdGVtVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRzbmFwVG9JdGVtLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgc25hcFRvSXRlbSgpIHsgcmV0dXJuIHRoaXMuXyRzbmFwVG9JdGVtLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJHNuYXBUb0l0ZW1BbGlnbiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8U25hcFRvSXRlbUFsaWduPihERUZBVUxUX1NOQVBfVE9fSVRFTV9BTElHTik7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRzbmFwVG9JdGVtQWxpZ24gPSB0aGlzLl8kc25hcFRvSXRlbUFsaWduLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF9zbmFwVG9JdGVtQWxpZ25UcmFuc2Zvcm0gPSAodjogU25hcFRvSXRlbUFsaWduKSA9PiB7XHJcbiAgICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlU3RyaW5nKHYpICYmICh2ID09PSAnc3RhcnQnIHx8IHYgPT09ICdjZW50ZXInIHx8IHYgPT09ICdlbmQnKTtcclxuXHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcInNuYXBUb0l0ZW1BbGlnblwiIHBhcmFtZXRlciBtdXN0IGJlIG9uZSBvZiBgc3RhcnRgLCBgY2VudGVyYCBvciBgZW5kYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfU05BUF9UT19JVEVNX0FMSUdOO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogQWxpZ25tZW50IGZvciBzbmFwVG9JdGVtLiBBdmFpbGFibGUgdmFsdWVzIOKAi+KAi2FyZSBgc3RhcnRgLCBgY2VudGVyYCwgYW5kIGBlbmRgLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgY2VudGVyYC5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBzbmFwVG9JdGVtQWxpZ24odjogU25hcFRvSXRlbUFsaWduKSB7XHJcbiAgICBpZiAodGhpcy5fJHNuYXBUb0l0ZW1BbGlnbi5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fc25hcFRvSXRlbUFsaWduVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRzbmFwVG9JdGVtQWxpZ24ubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBzbmFwVG9JdGVtQWxpZ24oKSB7IHJldHVybiB0aGlzLl8kc25hcFRvSXRlbUFsaWduLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJHNuYXBwaW5nRGlzdGFuY2UgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFNuYXBwaW5nRGlzdGFuY2U+KERFRkFVTFRfU05BUFBJTkdfRElTVEFOQ0UpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkc25hcHBpbmdEaXN0YW5jZSA9IHRoaXMuXyRzbmFwcGluZ0Rpc3RhbmNlLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF9zbmFwcGluZ0Rpc3RhbmNlVHJhbnNmb3JtID0gKHY6IFNuYXBwaW5nRGlzdGFuY2UgfCBhbnkpID0+IHtcclxuICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVTdHJpbmcodikgfHwgdmFsaWRhdGVGbG9hdCh2KTtcclxuXHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcInNuYXBwaW5nRGlzdGFuY2VcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBudW1iZXJgIG9yIGBzdHJpbmdgLicpO1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9TTkFQUElOR19ESVNUQU5DRTtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIFNuYXBwaW5nIGFjdGl2YXRpb24gZGlzdGFuY2UuIENhbiBiZSBzcGVjaWZpZWQgYXMgYSBwZXJjZW50YWdlIG9mIHRoZSBlbGVtZW50IHNpemUgb3IgaW4gYWJzb2x1dGUgdmFsdWVzLlxyXG4gICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGAyNSVgLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNuYXBwaW5nRGlzdGFuY2UodjogU25hcHBpbmdEaXN0YW5jZSkge1xyXG4gICAgaWYgKHRoaXMuXyRzbmFwcGluZ0Rpc3RhbmNlLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9zbmFwcGluZ0Rpc3RhbmNlVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRzbmFwcGluZ0Rpc3RhbmNlLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgc25hcHBpbmdEaXN0YW5jZSgpIHsgcmV0dXJuIHRoaXMuXyRzbmFwcGluZ0Rpc3RhbmNlLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJHNjcm9sbGluZ09uZUJ5T25lID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihERUZBVUxUX1NDUk9MTElOR19PTkVfQllfT05FKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJHNjcm9sbGluZ09uZUJ5T25lID0gdGhpcy5fJHNjcm9sbGluZ09uZUJ5T25lLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF9zY3JvbGxpbmdPbmVCeU9uZVRyYW5zZm9ybSA9ICh2OiBhbnkpID0+IHtcclxuICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVCb29sZWFuKHYpO1xyXG5cclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwic2Nyb2xsaW5nT25lQnlPbmVcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBib29sZWFuYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfU0NST0xMSU5HX09ORV9CWV9PTkU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBTcGVjaWZpZXMgd2hldGhlciB0byBzY3JvbGwgb25lIGl0ZW0gYXQgYSB0aW1lIGlmIHRydWUgYW5kIHRoZSBzY3JvbGxUb0l0ZW0gcHJvcGVydHkgaXMgc2V0LiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgZmFsc2VgLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNjcm9sbGluZ09uZUJ5T25lKHY6IGJvb2xlYW4pIHtcclxuICAgIGlmICh0aGlzLl8kc2Nyb2xsaW5nT25lQnlPbmUuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX3Njcm9sbGluZ09uZUJ5T25lVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRzY3JvbGxpbmdPbmVCeU9uZS5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IHNjcm9sbGluZ09uZUJ5T25lKCkgeyByZXR1cm4gdGhpcy5fJHNjcm9sbGluZ09uZUJ5T25lLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJGFsaWdubWVudCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8QWxpZ25tZW50PihERUZBVUxUX0FMSUdOTUVOVCk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRhbGlnbm1lbnQgPSB0aGlzLl8kYWxpZ25tZW50LmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF9hbGlnbm1lbnRUcmFuc2Zvcm0gPSAodjogQWxpZ25tZW50KSA9PiB7XHJcbiAgICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlU3RyaW5nKHYpICYmICh2ID09PSAnbm9uZScgfHwgdiA9PT0gJ2NlbnRlcicpO1xyXG5cclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwiYWxpZ25tZW50XCIgcGFyYW1ldGVyIG11c3QgYmUgb25lIG9mIGBub25lYCBvciBgY2VudGVydGAuJyk7XHJcbiAgICAgIHJldHVybiBERUZBVUxUX0FMSUdOTUVOVDtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIERldGVybWluZXMgdGhlIGFsaWdubWVudCBvZiB0aGUgbGlzdC4gVHdvIG1vZGVzIGFyZSBhdmFpbGFibGU6IGBub25lYCBhbmQgYGNlbnRlcmAuIFRoZSBgY2VudGVyYCBtb2RlIGFsaWducyB0aGUgbGlzdCBpdGVtcyB0byB0aGUgY2VudGVyIG9mIHRoZSB2aWV3cG9ydCwgaWRlYWwgZm9yIHVzZSB3aXRoIHRoZSBgaXRlbVRyYW5zZm9ybWAgcHJvcGVydHkuXHJcbiAgICogVGhlIGBub25lYCBtb2RlIG1lYW5zIG5vIGFsaWdubWVudC4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgYG5vbmVgLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGFsaWdubWVudCh2OiBBbGlnbm1lbnQpIHtcclxuICAgIGlmICh0aGlzLl8kYWxpZ25tZW50LmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9hbGlnbm1lbnRUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJGFsaWdubWVudC5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IGFsaWdubWVudCgpIHsgcmV0dXJuIHRoaXMuXyRhbGlnbm1lbnQuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF8kekluZGV4V2hlblNlbGVjdGluZyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nIHwgbnVsbD4oREVGQVVMVF9aSU5ERVhfV0hFTl9TRUxFQ1RJTkcpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkekluZGV4V2hlblNlbGVjdGluZyA9IHRoaXMuXyR6SW5kZXhXaGVuU2VsZWN0aW5nLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF96SW5kZXhXaGVuU2VsZWN0aW5nVHJhbnNmb3JtID0gKHY6IHN0cmluZyB8IG51bGwpID0+IHtcclxuICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVTdHJpbmcodiwgdHJ1ZSwgdHJ1ZSk7XHJcblxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJ6SW5kZXhXaGVuU2VsZWN0aW5nXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgbnVtYmVyYCBvciBgbnVsbGAuJyk7XHJcbiAgICAgIHJldHVybiBERUZBVUxUX1pJTkRFWF9XSEVOX1NFTEVDVElORztcclxuICAgIH1cclxuICAgIHJldHVybiB2ID8/IG51bGw7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogRGVmaW5lcyB0aGUgekluZGV4IHdoZW4gYSBsaXN0IGl0ZW0gaXMgc2VsZWN0ZWQuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGBudWxsYC5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCB6SW5kZXhXaGVuU2VsZWN0aW5nKHY6IHN0cmluZyB8IG51bGwpIHtcclxuICAgIGlmICh0aGlzLl8kekluZGV4V2hlblNlbGVjdGluZy5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fekluZGV4V2hlblNlbGVjdGluZ1RyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kekluZGV4V2hlblNlbGVjdGluZy5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IHpJbmRleFdoZW5TZWxlY3RpbmcoKSB7IHJldHVybiB0aGlzLl8kekluZGV4V2hlblNlbGVjdGluZy5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRzcHJlYWRpbmdNb2RlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxTcHJlYWRpbmdNb2RlPihERUZBVUxUX1NQUkVBRElOR19NT0RFKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJHNwcmVhZGluZ01vZGUgPSB0aGlzLl8kc3ByZWFkaW5nTW9kZS5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfc3ByZWFkaW5nTW9kZVRyYW5zZm9ybSA9ICh2OiBTcHJlYWRpbmdNb2RlKSA9PiB7XHJcbiAgICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlU3RyaW5nKHYpICYmICh2ID09PSAnbm9ybWFsJyB8fCB2ID09PSAnaW5maW5pdHknKTtcclxuXHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcInNwcmVhZGluZ01vZGVcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvbmUgb2YgYG5vcm1hbGAgb3IgYGluZmluaXR5YC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfU1BSRUFESU5HX01PREU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgb3JkZXIgb2YgbGlzdCBlbGVtZW50cy4gQXZhaWxhYmxlIHZhbHVlcyDigIvigIthcmUgYHN0YW5kYXJkYCBhbmQgYGluZmluaXR5YC5cclxuICAgKiBgbm9ybWFsYCDigJQgbGlzdCBlbGVtZW50cyBhcmUgb3JkZXJlZCBhY2NvcmRpbmcgdG8gdGhlIGNvbGxlY3Rpb24gc2VxdWVuY2UuXHJcbiAgICogYGluZmluaXR5YCDigJQgbGlzdCBlbGVtZW50cyBhcmUgb3JkZXJlZCBjeWNsaWNhbGx5LCBmb3JtaW5nIGFuIGluZmluaXRlIGxpc3QuXHJcbiAgICogV2hlbiBzZXQgdG8gYGluZmluaXR5YCwgdGhlIGBhbGlnbm1lbnRgIHByb3BlcnR5IGlzIGZvcmNlZCB0byB0aGUgdmFsdWUgYEFsaWdubWVudHMuQ0VOVEVSYCwgdGhlIGBzY3JvbGxiYXJFbmFibGVkYCBwcm9wZXJ0eSBpcyBmb3JjZWQgdG8gdGhlIGBmYWxzZWBcclxuICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgc3RhbmRhcmRgLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNwcmVhZGluZ01vZGUodjogU3ByZWFkaW5nTW9kZSkge1xyXG4gICAgaWYgKHRoaXMuXyRzcHJlYWRpbmdNb2RlLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9zcHJlYWRpbmdNb2RlVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRzcHJlYWRpbmdNb2RlLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgc3ByZWFkaW5nTW9kZSgpIHsgcmV0dXJuIHRoaXMuXyRzcHJlYWRpbmdNb2RlLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJGRpdmlkZXMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oREVGQVVMVF9ESVZJREVTKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJGRpdmlkZXMgPSB0aGlzLl8kZGl2aWRlcy5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfZGl2aWRlc1RyYW5zZm9ybSA9ICh2OiBudW1iZXIpID0+IHtcclxuICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVGbG9hdCh2KTtcclxuXHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcImRpdmlkZXNcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBudW1iZXJgLicpO1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9ESVZJREVTO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHYgPD0gMCA/IERFRkFVTFRfRElWSURFUyA6IHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogQ29sdW1uIG9yIHJvdyBudW1iZXJzLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgMWAuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgZGl2aWRlcyh2OiBudW1iZXIpIHtcclxuICAgIGlmICh0aGlzLl8kZGl2aWRlcy5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fZGl2aWRlc1RyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kZGl2aWRlcy5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IGRpdmlkZXMoKSB7IHJldHVybiB0aGlzLl8kZGl2aWRlcy5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRtb3Rpb25CbHVyID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KERFRkFVTFRfTU9USU9OX0JMVVIpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkbW90aW9uQmx1ciA9IHRoaXMuXyRtb3Rpb25CbHVyLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF9tb3Rpb25CbHVyVHJhbnNmb3JtID0gKHY6IG51bWJlcikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUZsb2F0KHYpO1xyXG5cclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwibW90aW9uQmx1clwiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYG51bWJlcmAuJyk7XHJcbiAgICAgIHJldHVybiBERUZBVUxUX0RJVklERVM7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdiA8PSAwID8gREVGQVVMVF9ESVZJREVTIDogdjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBNb3Rpb24gYmx1ciBlZmZlY3QuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGAwLjE1YC5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBtb3Rpb25CbHVyKHY6IG51bWJlcikge1xyXG4gICAgaWYgKHRoaXMuXyRtb3Rpb25CbHVyLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9tb3Rpb25CbHVyVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRtb3Rpb25CbHVyLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgbW90aW9uQmx1cigpIHsgcmV0dXJuIHRoaXMuXyRtb3Rpb25CbHVyLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJG1heE1vdGlvbkJsdXIgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oREVGQVVMVF9NQVhfTU9USU9OX0JMVVIpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkbWF4TW90aW9uQmx1ciA9IHRoaXMuXyRtYXhNb3Rpb25CbHVyLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF9tYXhNb3Rpb25CbHVyVHJhbnNmb3JtID0gKHY6IG51bWJlcikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUZsb2F0KHYpO1xyXG5cclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwibWF4TW90aW9uQmx1clwiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYG51bWJlcmAuJyk7XHJcbiAgICAgIHJldHVybiBERUZBVUxUX01BWF9NT1RJT05fQkxVUjtcclxuICAgIH1cclxuICAgIHJldHVybiB2IDw9IDAgPyBERUZBVUxUX01BWF9NT1RJT05fQkxVUiA6IHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogTWF4aW11bSBtb3Rpb24gYmx1ciBlZmZlY3QuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGAwLjVgLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IG1heE1vdGlvbkJsdXIodjogbnVtYmVyKSB7XHJcbiAgICBpZiAodGhpcy5fJG1heE1vdGlvbkJsdXIuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX21heE1vdGlvbkJsdXJUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJG1heE1vdGlvbkJsdXIubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBtYXhNb3Rpb25CbHVyKCkgeyByZXR1cm4gdGhpcy5fJG1heE1vdGlvbkJsdXIuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF8kbW90aW9uQmx1ckVuYWJsZWQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KERFRkFVTFRfTU9USU9OX0JMVVJfRU5BQkxFRCk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRtb3Rpb25CbHVyRW5hYmxlZCA9IHRoaXMuXyRtb3Rpb25CbHVyRW5hYmxlZC5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfbW90aW9uQmx1ckVuYWJsZWRUcmFuc2Zvcm0gPSAodjogYm9vbGVhbikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUJvb2xlYW4odik7XHJcblxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJtb3Rpb25CbHVyRW5hYmxlZFwiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYGJvb2xlYW5gLicpO1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9NT1RJT05fQkxVUl9FTkFCTEVEO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRvIGFwcGx5IG1vdGlvbiBibHVyIG9yIG5vdC4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgYGZhbHNlYC5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBtb3Rpb25CbHVyRW5hYmxlZCh2OiBib29sZWFuKSB7XHJcbiAgICBpZiAodGhpcy5fJG1vdGlvbkJsdXJFbmFibGVkLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9tb3Rpb25CbHVyRW5hYmxlZFRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kbW90aW9uQmx1ckVuYWJsZWQubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBtb3Rpb25CbHVyRW5hYmxlZCgpIHsgcmV0dXJuIHRoaXMuXyRtb3Rpb25CbHVyRW5hYmxlZC5nZXRWYWx1ZSgpOyB9XHJcblxyXG5cclxuXHJcbiAgcHJpdmF0ZSBfJGFuaW1hdGlvblBhcmFtcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SUFuaW1hdGlvblBhcmFtcz4oREVGQVVMVF9BTklNQVRJT05fUEFSQU1TKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJGFuaW1hdGlvblBhcmFtcyA9IHRoaXMuXyRhbmltYXRpb25QYXJhbXMuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX2FuaW1hdGlvblBhcmFtc1RyYW5zZm9ybSA9ICh2OiBJQW5pbWF0aW9uUGFyYW1zKSA9PiB7XHJcbiAgICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlT2JqZWN0KHYsIHRydWUsIHRydWUpO1xyXG5cclxuICAgIGlmICghdmFsaWRhdGVGbG9hdCh2LnNjcm9sbFRvSXRlbSkpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwic2Nyb2xsVG9JdGVtXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgbnVtYmVyYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfQU5JTUFUSU9OX1BBUkFNUztcclxuICAgIH1cclxuICAgIGlmICghdmFsaWRhdGVGbG9hdCh2LnNuYXBUb0l0ZW0pKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcInNuYXBUb0l0ZW1cIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBudW1iZXJgLicpO1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9BTklNQVRJT05fUEFSQU1TO1xyXG4gICAgfVxyXG4gICAgaWYgKCF2YWxpZGF0ZUZsb2F0KHYubmF2aWdhdGVCeUtleWJvYXJkKSkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJuYXZpZ2F0ZUJ5S2V5Ym9hcmRcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBudW1iZXJgLicpO1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9BTklNQVRJT05fUEFSQU1TO1xyXG4gICAgfVxyXG4gICAgaWYgKCF2YWxpZGF0ZUZsb2F0KHYubmF2aWdhdGVUb0l0ZW0pKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcIm5hdmlnYXRlVG9JdGVtXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgbnVtYmVyYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfQU5JTUFUSU9OX1BBUkFNUztcclxuICAgIH1cclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwiYW5pbWF0aW9uUGFyYW1zXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgb2JqZWN0YC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfQU5JTUFUSU9OX1BBUkFNUztcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIEFuaW1hdGlvbiBwYXJhbWV0ZXJzLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBcInsgc2Nyb2xsVG9JdGVtOiA1MCwgc25hcFRvSXRlbTogMTUwLCBuYXZpZ2F0ZVRvSXRlbTogMTUwLCBuYXZpZ2F0ZUJ5S2V5Ym9hcmQ6IDUwIH1cIi5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBhbmltYXRpb25QYXJhbXModjogSUFuaW1hdGlvblBhcmFtcykge1xyXG4gICAgaWYgKHRoaXMuXyRhbmltYXRpb25QYXJhbXMuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX2FuaW1hdGlvblBhcmFtc1RyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kYW5pbWF0aW9uUGFyYW1zLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgYW5pbWF0aW9uUGFyYW1zKCkgeyByZXR1cm4gdGhpcy5fJGFuaW1hdGlvblBhcmFtcy5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRvdmVyc2Nyb2xsRW5hYmxlZCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oREVGQVVMVF9PVkVSU0NST0xMX0VOQUJMRUQpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkb3ZlcnNjcm9sbEVuYWJsZWQgPSB0aGlzLl8kb3ZlcnNjcm9sbEVuYWJsZWQuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX292ZXJzY3JvbGxFbmFibGVkVHJhbnNmb3JtID0gKHY6IGJvb2xlYW4pID0+IHtcclxuICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVCb29sZWFuKHYsIHRydWUpO1xyXG5cclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwib3ZlcnNjcm9sbEVuYWJsZWRcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBib29sZWFuYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfT1ZFUlNDUk9MTF9FTkFCTEVEO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBvdmVyc2Nyb2xsIChyZS1zY3JvbGwpIGZlYXR1cmUgd2lsbCB3b3JrLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBcInRydWVcIi5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBvdmVyc2Nyb2xsRW5hYmxlZCh2OiBib29sZWFuKSB7XHJcbiAgICBpZiAodGhpcy5fJG92ZXJzY3JvbGxFbmFibGVkLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9vdmVyc2Nyb2xsRW5hYmxlZFRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kb3ZlcnNjcm9sbEVuYWJsZWQubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBvdmVyc2Nyb2xsRW5hYmxlZCgpIHsgcmV0dXJuIHRoaXMuXyRvdmVyc2Nyb2xsRW5hYmxlZC5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihERUZBVUxUX0VOQUJMRURfQlVGRkVSX09QVElNSVpBVElPTik7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uID0gdGhpcy5fJGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24uYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX2VuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb25UcmFuc2Zvcm0gPSAodjogYm9vbGVhbikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUJvb2xlYW4odik7XHJcblxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgYm9vbGVhbmAuJyk7XHJcbiAgICAgIHJldHVybiBERUZBVUxUX0VOQUJMRURfQlVGRkVSX09QVElNSVpBVElPTjtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIEV4cGVyaW1lbnRhbCFcclxuICAgKiBFbmFibGVzIGJ1ZmZlciBvcHRpbWl6YXRpb24uXHJcbiAgICogQ2FuIG9ubHkgYmUgdXNlZCBpZiBpdGVtcyBpbiB0aGUgY29sbGVjdGlvbiBhcmUgbm90IGFkZGVkIG9yIHVwZGF0ZWQuIE90aGVyd2lzZSwgYXJ0aWZhY3RzIGluIHRoZSBmb3JtIG9mIHR3aXRjaGluZyBvZiB0aGUgc2Nyb2xsIGFyZWEgYXJlIHBvc3NpYmxlLlxyXG4gICAqIFdvcmtzIG9ubHkgaWYgdGhlIHByb3BlcnR5IGR5bmFtaWMgPSB0cnVlXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgZW5hYmxlZEJ1ZmZlck9wdGltaXphdGlvbih2OiBib29sZWFuKSB7XHJcbiAgICBpZiAodGhpcy5fJGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24uZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX2VuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb25UcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24ubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uKCkgeyByZXR1cm4gdGhpcy5fJGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24uZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF8kaXRlbVJlbmRlcmVyID0gbmV3IEJlaGF2aW9yU3ViamVjdDxUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkaXRlbVJlbmRlcmVyID0gdGhpcy5fJGl0ZW1SZW5kZXJlci5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfaXRlbVJlbmRlcmVyVHJhbnNmb3JtID0gKHY6IFRlbXBsYXRlUmVmPGFueT4pID0+IHtcclxuICAgIGxldCB2YWxpZCA9IHZhbGlkYXRlT2JqZWN0KHYpO1xyXG4gICAgaWYgKHYgJiYgISh0eXBlb2Ygdi5lbGVtZW50UmVmID09PSAnb2JqZWN0JyAmJiB0eXBlb2Ygdi5jcmVhdGVFbWJlZGRlZFZpZXcgPT09ICdmdW5jdGlvbicpKSB7XHJcbiAgICAgIHZhbGlkID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICB0aHJvdyBFcnJvcignVGhlIFwiaXRlbVJlbmRlcmVyXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgVGVtcGxhdGVSZWZgLicpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogUmVuZGVyaW5nIGVsZW1lbnQgdGVtcGxhdGUuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgaXRlbVJlbmRlcmVyKHY6IFRlbXBsYXRlUmVmPGFueT4pIHtcclxuICAgIGlmICh0aGlzLl8kaXRlbVJlbmRlcmVyLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9pdGVtUmVuZGVyZXJUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJGl0ZW1SZW5kZXJlci5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IGl0ZW1SZW5kZXJlcigpIHsgcmV0dXJuIHRoaXMuXyRpdGVtUmVuZGVyZXIuZ2V0VmFsdWUoKSBhcyBUZW1wbGF0ZVJlZjxhbnk+OyB9XHJcblxyXG4gIHByaXZhdGUgXyRpdGVtQ29uZmlnTWFwID0gbmV3IEJlaGF2aW9yU3ViamVjdDxJVmlydHVhbExpc3RJdGVtQ29uZmlnTWFwPih7fSk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRpdGVtQ29uZmlnTWFwID0gdGhpcy5fJGl0ZW1Db25maWdNYXAuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX2l0ZW1Db25maWdNYXBUcmFuc2Zvcm0gPSAodjogSVZpcnR1YWxMaXN0SXRlbUNvbmZpZ01hcCkgPT4ge1xyXG4gICAgbGV0IHZhbGlkID0gdmFsaWRhdGVPYmplY3Qodik7XHJcbiAgICBpZiAodmFsaWQpIHtcclxuICAgICAgaWYgKHYpIHtcclxuICAgICAgICBmb3IgKGxldCBpZCBpbiB2KSB7XHJcbiAgICAgICAgICBjb25zdCBpdGVtID0gdltpZF07XHJcbiAgICAgICAgICBpZiAoIWl0ZW0gfHxcclxuICAgICAgICAgICAgIXZhbGlkYXRlQm9vbGVhbihpdGVtLmNvbGxhcHNhYmxlLCB0cnVlKSB8fFxyXG4gICAgICAgICAgICAhdmFsaWRhdGVCb29sZWFuKGl0ZW0uc2VsZWN0YWJsZSwgdHJ1ZSkgfHxcclxuICAgICAgICAgICAgIShpdGVtLnN0aWNreSA9PT0gdW5kZWZpbmVkIHx8IGl0ZW0uc3RpY2t5ID09PSAwIHx8IGl0ZW0uc3RpY2t5ID09PSAxIHx8IGl0ZW0uc3RpY2t5ID09PSAyKVxyXG4gICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIHZhbGlkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJpdGVtQ29uZmlnTWFwXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgSVZpcnR1YWxMaXN0SXRlbUNvbmZpZ01hcGAuJyk7XHJcbiAgICAgIHJldHVybiB7fTtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIFNldHMgYHN0aWNreWAgcG9zaXRpb24sIGBmdWxsU2l6ZWAsIGBjb2xsYXBzYWJsZWAgYW5kIGBzZWxlY3RhYmxlYCBmb3IgdGhlIGxpc3QgaXRlbSBlbGVtZW50LiBJZiBgc3RpY2t5YCBwb3NpdGlvbiBpcyBncmVhdGVyIHRoYW4gYDBgLCB0aGVuIGBzdGlja3lgIHBvc2l0aW9uIGlzIGFwcGxpZWQuIFxyXG4gICAqIElmIHRoZSBgc3RpY2t5YCB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gYDBgLCB0aGVuIHRoZSBgc3RpY2t5YCBwb3NpdGlvbiBtb2RlIGlzIGVuYWJsZWQgZm9yIHRoZSBlbGVtZW50LiBgMWAgLSBwb3NpdGlvbiBzdGFydCwgYDJgIC0gcG9zaXRpb24gZW5kLlxyXG4gICAqICBEZWZhdWx0IHZhbHVlIGlzIGAwYC5cclxuICAgKiBgc2VsZWN0YWJsZWAgZGV0ZXJtaW5lcyB3aGV0aGVyIGFuIGVsZW1lbnQgY2FuIGJlIHNlbGVjdGVkIG9yIG5vdC4gRGVmYXVsdCB2YWx1ZSBpcyBgdHJ1ZWAuXHJcbiAgICogYGNvbGxhcHNhYmxlYCBkZXRlcm1pbmVzIHdoZXRoZXIgYW4gZWxlbWVudCB3aXRoIGEgYHN0aWNreWAgcHJvcGVydHkgZ3JlYXRlciB0aGFuIHplcm8gY2FuIGNvbGxhcHNlIGFuZFxyXG4gICAqICBjb2xsYXBzZSBlbGVtZW50cyBpbiBmcm9udCB0aGF0IGRvIG5vdCBoYXZlIGEgYHN0aWNreWAgcHJvcGVydHkuXHJcbiAgICogYGZ1bGxTaXplYCBkZXRlcm1pbmVzIHRoZSBzaXplIG9mIGFuIGVsZW1lbnQgd2hlbiByZW5kZXJpbmcgbGlzdHMgd2l0aCBjZWxsIGRpdmlzaW9ucy4gSWYgc3RpY2t5IGlzIDEgb3IgMiwgZnVsbFNpemUgYXV0b21hdGljYWxseSBiZWNvbWVzIHRydWUuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGZhbHNlLlxyXG4gICAqIEBsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9Eam9ubnlYL25nLXZpcnR1YWwtbGlzdC9ibG9iLzE0LngvcHJvamVjdHMvbmctdmlydHVhbC1saXN0L3NyYy9saWIvbW9kZWxzL2l0ZW0tY29uZmlnLW1hcC5tb2RlbC50c1xyXG4gICAqIEBhdXRob3IgRXZnZW5paSBBbGV4YW5kcm92aWNoIEdyZWJlbm5pa292XHJcbiAgICogQGVtYWlsIGRqb25ueXhAZ21haWwuY29tXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgaXRlbUNvbmZpZ01hcCh2OiBJVmlydHVhbExpc3RJdGVtQ29uZmlnTWFwKSB7XHJcbiAgICBpZiAodGhpcy5fJGl0ZW1Db25maWdNYXAuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX2l0ZW1Db25maWdNYXBUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJGl0ZW1Db25maWdNYXAubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBpdGVtQ29uZmlnTWFwKCkgeyByZXR1cm4gdGhpcy5fJGl0ZW1Db25maWdNYXAuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF8kaXRlbVNpemUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oREVGQVVMVF9JVEVNX1NJWkUpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkaXRlbVNpemUgPSB0aGlzLl8kaXRlbVNpemUuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX2l0ZW1TaXplVHJhbnNmb3JtID0gKHY6IGFueSkgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUZsb2F0KHYpIHx8IHYgPT09IFZJRVdQT1JUO1xyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJpdGVtU2l6ZVwiIHBhcmFtZXRlciBtdXN0IGJlIG9uZSBvZiBgbnVtYmVyYCwgYHZpZXdwb3J0YCBvciBgdW5kZWZpbmVkYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfSVRFTV9TSVpFO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogSWYgZGlyZWN0aW9uID0gJ3ZlcnRpY2FsJywgdGhlbiB0aGUgaGVpZ2h0IG9mIGEgdHlwaWNhbCBlbGVtZW50LiBJZiBkaXJlY3Rpb24gPSAnaG9yaXpvbnRhbCcsIHRoZW4gdGhlIHdpZHRoIG9mIGEgdHlwaWNhbCBlbGVtZW50LlxyXG4gICAqIElmIHRoZSBgZHluYW1pY1NpemVgIHByb3BlcnR5IGlzIHRydWUsIHRoZSBpdGVtcyBpbiB0aGUgbGlzdCBjYW4gaGF2ZSBkaWZmZXJlbnQgc2l6ZXMsIGFuZCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBgaXRlbVNpemVgIHByb3BlcnR5IFxyXG4gICAqIHRvIGFkanVzdCB0aGUgc2l6ZXMgb2YgdGhlIGl0ZW1zIGluIHRoZSB1bmFsbG9jYXRlZCBhcmVhLlxyXG4gICAqIElmIHRoZSB2YWx1ZSBpcyAndmlld3BvcnQnLCB0aGUgc2l6ZXMgb2YgZWxlbWVudHMgYXJlIGF1dG9tYXRpY2FsbHkgcmVzaXplZCB0byBmaXQgdGhlIHZpZXdwb3J0IHNpemUuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgaXRlbVNpemUodjogbnVtYmVyIHwgJ3ZpZXdwb3J0Jykge1xyXG4gICAgaWYgKHRoaXMuXyRpdGVtU2l6ZS5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5faXRlbVNpemVUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJGl0ZW1TaXplLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgaXRlbVNpemUoKSB7IHJldHVybiB0aGlzLl8kaXRlbVNpemUuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF8kbWluSXRlbVNpemUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oREVGQVVMVF9JVEVNX1NJWkUpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkbWluSXRlbVNpemUgPSB0aGlzLl8kbWluSXRlbVNpemUuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX21pbkl0ZW1TaXplVHJhbnNmb3JtID0gKHY6IGFueSkgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUZsb2F0KHYpIHx8IHYgPT09IFZJRVdQT1JUO1xyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJtaW5JdGVtU2l6ZVwiIHBhcmFtZXRlciBtdXN0IGJlIG9uZSBvZiBgbnVtYmVyYCwgYHZpZXdwb3J0YCBvciBgdW5kZWZpbmVkYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfSVRFTV9TSVpFO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogSWYgdGhlIGBkeW5hbWljU2l6ZWAgcHJvcGVydHkgaXMgZW5hYmxlZCwgdGhlIG1pbmltdW0gc2l6ZSBvZiB0aGUgZWxlbWVudCBpcyBzZXQuXHJcbiAgICogSWYgdGhlIHZhbHVlIGlzICd2aWV3cG9ydCcsIHRoZSBzaXplcyBvZiBlbGVtZW50cyBhcmUgYXV0b21hdGljYWxseSByZXNpemVkIHRvIGZpdCB0aGUgdmlld3BvcnQgc2l6ZS5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBtaW5JdGVtU2l6ZSh2OiBudW1iZXIgfCAndmlld3BvcnQnKSB7XHJcbiAgICBpZiAodGhpcy5fJG1pbkl0ZW1TaXplLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9taW5JdGVtU2l6ZVRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kbWluSXRlbVNpemUubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBtaW5JdGVtU2l6ZSgpIHsgcmV0dXJuIHRoaXMuXyRtaW5JdGVtU2l6ZS5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRtYXhJdGVtU2l6ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPihERUZBVUxUX01BWF9JVEVNX1NJWkUpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkbWF4SXRlbVNpemUgPSB0aGlzLl8kbWF4SXRlbVNpemUuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX21heEl0ZW1TaXplVHJhbnNmb3JtID0gKHY6IGFueSkgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZUZsb2F0KHYpIHx8IHYgPT09IFZJRVdQT1JUO1xyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJtYXhJdGVtU2l6ZVwiIHBhcmFtZXRlciBtdXN0IGJlIG9uZSBvZiBgbnVtYmVyYCwgYHZpZXdwb3J0YCBvciBgdW5kZWZpbmVkYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfSVRFTV9TSVpFO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogSWYgdGhlIGBkeW5hbWljU2l6ZWAgcHJvcGVydHkgaXMgZW5hYmxlZCwgdGhlIG1heGltdW0gc2l6ZSBvZiB0aGUgZWxlbWVudCBpcyBzZXQuXHJcbiAgICogSWYgdGhlIHZhbHVlIGlzICd2aWV3cG9ydCcsIHRoZSBzaXplcyBvZiBlbGVtZW50cyBhcmUgYXV0b21hdGljYWxseSByZXNpemVkIHRvIGZpdCB0aGUgdmlld3BvcnQgc2l6ZS5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBtYXhJdGVtU2l6ZSh2OiBudW1iZXIgfCAndmlld3BvcnQnKSB7XHJcbiAgICBpZiAodGhpcy5fJG1heEl0ZW1TaXplLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9tYXhJdGVtU2l6ZVRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kbWF4SXRlbVNpemUubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBtYXhJdGVtU2l6ZSgpIHsgcmV0dXJuIHRoaXMuXyRtYXhJdGVtU2l6ZS5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRkeW5hbWljU2l6ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oREVGQVVMVF9EWU5BTUlDX1NJWkUpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkZHluYW1pY1NpemUgPSB0aGlzLl8kZHluYW1pY1NpemUuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX2R5bmFtaWNTaXplVHJhbnNmb3JtID0gKHY6IGJvb2xlYW4pID0+IHtcclxuICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVCb29sZWFuKHYpO1xyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJkeW5hbWljU2l6ZVwiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYGJvb2xlYW5gLicpO1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9EWU5BTUlDX1NJWkU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBJZiB0cnVlLCBpdGVtcyBpbiB0aGUgbGlzdCBtYXkgaGF2ZSBkaWZmZXJlbnQgc2l6ZXMsIGFuZCB0aGUgaXRlbVNpemUgcHJvcGVydHkgbXVzdCBiZSBzcGVjaWZpZWQgdG8gYWRqdXN0XHJcbiAgICogdGhlIHNpemVzIG9mIGl0ZW1zIGluIHRoZSB1bmFsbG9jYXRlZCBhcmVhLlxyXG4gICAqIElmIGZhbHNlIHRoZW4gdGhlIGl0ZW1zIGluIHRoZSBsaXN0IGhhdmUgYSBmaXhlZCBzaXplIHNwZWNpZmllZCBieSB0aGUgaXRlbVNpemUgcHJvcGVydHkuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIHRydWUuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgZHluYW1pY1NpemUodjogYm9vbGVhbikge1xyXG4gICAgaWYgKHRoaXMuXyRkeW5hbWljU2l6ZS5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fZHluYW1pY1NpemVUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJGR5bmFtaWNTaXplLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgZHluYW1pY1NpemUoKSB7IHJldHVybiB0aGlzLl8kZHluYW1pY1NpemUuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF8kZGlyZWN0aW9uID0gbmV3IEJlaGF2aW9yU3ViamVjdDxEaXJlY3Rpb24+KERFRkFVTFRfRElSRUNUSU9OKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJGRpcmVjdGlvbiA9IHRoaXMuXyRkaXJlY3Rpb24uYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX2RpcmVjdGlvblRyYW5zZm9ybSA9ICh2OiBEaXJlY3Rpb24pID0+IHtcclxuICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVTdHJpbmcodikgJiYgKHYgPT09ICdob3Jpem9udGFsJyB8fCB2ID09PSAndmVydGljYWwnKTtcclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwiZGlyZWN0aW9uXCIgcGFyYW1ldGVyIG11c3QgYmUgb25lIG9mIGBob3Jpem9udGFsYCBvciBgdmVydGljYWxgLicpO1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9ESVJFQ1RJT047XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBEZXRlcm1pbmVzIHRoZSBkaXJlY3Rpb24gaW4gd2hpY2ggZWxlbWVudHMgYXJlIHBsYWNlZC4gRGVmYXVsdCB2YWx1ZSBpcyBcInZlcnRpY2FsXCIuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgZGlyZWN0aW9uKHY6IERpcmVjdGlvbikge1xyXG4gICAgaWYgKHRoaXMuXyRkaXJlY3Rpb24uZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX2RpcmVjdGlvblRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kZGlyZWN0aW9uLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgZGlyZWN0aW9uKCkgeyByZXR1cm4gdGhpcy5fJGRpcmVjdGlvbi5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRjb2xsZWN0aW9uTW9kZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Q29sbGVjdGlvbk1vZGU+KERFRkFVTFRfQ09MTEVDVElPTl9NT0RFKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJGNvbGxlY3Rpb25Nb2RlID0gdGhpcy5fJGNvbGxlY3Rpb25Nb2RlLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF9jb2xsZWN0aW9uTW9kZVRyYW5zZm9ybSA9ICh2OiBDb2xsZWN0aW9uTW9kZSkgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZVN0cmluZyh2KSAmJiAodiA9PT0gJ25vcm1hbCcgfHwgdiA9PT0gJ2xhenknKTtcclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwiZGlyZWN0aW9uXCIgcGFyYW1ldGVyIG11c3QgYmUgb25lIG9mIGBub3JtYWxgIG9yIGBsYXp5YC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfQ09MTEVDVElPTl9NT0RFO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogRGV0ZXJtaW5lcyB0aGUgYWN0aW9uIG1vZGVzIGZvciBjb2xsZWN0aW9uIGVsZW1lbnRzLiBEZWZhdWx0IHZhbHVlIGlzIFwibm9ybWFsXCIuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgY29sbGVjdGlvbk1vZGUodjogQ29sbGVjdGlvbk1vZGUpIHtcclxuICAgIGlmICh0aGlzLl8kY29sbGVjdGlvbk1vZGUuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX2NvbGxlY3Rpb25Nb2RlVHJhbnNmb3JtKHYpO1xyXG5cclxuICAgIHRoaXMuXyRjb2xsZWN0aW9uTW9kZS5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IGNvbGxlY3Rpb25Nb2RlKCkgeyByZXR1cm4gdGhpcy5fJGNvbGxlY3Rpb25Nb2RlLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJGJ1ZmZlclNpemUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oREVGQVVMVF9CVUZGRVJfU0laRSk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRidWZmZXJTaXplID0gdGhpcy5fJGJ1ZmZlclNpemUuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX2J1ZmZlclNpemVUcmFuc2Zvcm0gPSAodjogbnVtYmVyKSA9PiB7XHJcbiAgICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlSW50KHYpO1xyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJidWZmZXJTaXplXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgbnVtYmVyYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfQlVGRkVSX1NJWkU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBOdW1iZXIgb2YgZWxlbWVudHMgb3V0c2lkZSB0aGUgc2NvcGUgb2YgdmlzaWJpbGl0eS4gRGVmYXVsdCB2YWx1ZSBpcyAyLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGJ1ZmZlclNpemUodjogbnVtYmVyKSB7XHJcbiAgICBpZiAodGhpcy5fJGJ1ZmZlclNpemUuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX2J1ZmZlclNpemVUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJGJ1ZmZlclNpemUubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBidWZmZXJTaXplKCkgeyByZXR1cm4gdGhpcy5fJGJ1ZmZlclNpemUuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF8kbWF4QnVmZmVyU2l6ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPihERUZBVUxUX01BWF9CVUZGRVJfU0laRSk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRtYXhCdWZmZXJTaXplID0gdGhpcy5fJG1heEJ1ZmZlclNpemUuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX21heEJ1ZmZlclNpemVUcmFuc2Zvcm0gPSAodjogbnVtYmVyKSA9PiB7XHJcbiAgICBsZXQgdmFsID0gdjtcclxuICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVJbnQodiwgdHJ1ZSk7XHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1RoZSBcIm1heEJ1ZmZlclNpemVcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBudW1iZXJgLicpO1xyXG4gICAgICB2YWwgPSBERUZBVUxUX01BWF9CVUZGRVJfU0laRTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBidWZmZXJTaXplID0gdGhpcy5idWZmZXJTaXplO1xyXG4gICAgaWYgKHZhbCA9PT0gdW5kZWZpbmVkIHx8IHZhbCA8PSBidWZmZXJTaXplKSB7XHJcbiAgICAgIHJldHVybiBidWZmZXJTaXplO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZhbDtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBNYXhpbXVtIG51bWJlciBvZiBlbGVtZW50cyBvdXRzaWRlIHRoZSBzY29wZSBvZiB2aXNpYmlsaXR5LiBEZWZhdWx0IHZhbHVlIGlzIDEwMC5cclxuICAgKiBJZiBtYXhCdWZmZXJTaXplIGlzIHNldCB0byBiZSBncmVhdGVyIHRoYW4gYnVmZmVyU2l6ZSwgdGhlbiBhZGFwdGl2ZSBidWZmZXIgbW9kZSBpcyBlbmFibGVkLlxyXG4gICAqIFRoZSBncmVhdGVyIHRoZSBzY3JvbGwgc2l6ZSwgdGhlIG1vcmUgZWxlbWVudHMgYXJlIGFsbG9jYXRlZCBmb3IgcmVuZGVyaW5nLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IG1heEJ1ZmZlclNpemUodjogbnVtYmVyKSB7XHJcbiAgICBjb25zdCB2YWwgPSB0aGlzLl9tYXhCdWZmZXJTaXplVHJhbnNmb3JtKHYpO1xyXG4gICAgaWYgKHRoaXMuXyRtYXhCdWZmZXJTaXplLmdldFZhbHVlKCkgPT09IHZhbCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fJG1heEJ1ZmZlclNpemUubmV4dCh2YWwpO1xyXG4gIH07XHJcbiAgZ2V0IG1heEJ1ZmZlclNpemUoKSB7IHJldHVybiB0aGlzLl8kbWF4QnVmZmVyU2l6ZS5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRzbmFwcGluZ01ldGhvZCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8U25hcHBpbmdNZXRob2Q+KERFRkFVTFRfU05BUFBJTkdfTUVUSE9EKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJHNuYXBwaW5nTWV0aG9kID0gdGhpcy5fJHNuYXBwaW5nTWV0aG9kLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF9zbmFwcGluZ01ldGhvZFRyYW5zZm9ybSA9ICh2OiBTbmFwcGluZ01ldGhvZCkgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZVN0cmluZyh2KSAmJiAodiA9PT0gU25hcHBpbmdNZXRob2RzLkFEVkFOQ0VEIHx8IHYgPT09IFNuYXBwaW5nTWV0aG9kcy5TVEFOREFSVCk7XHJcbiAgICBpZiAoIXZhbGlkKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFRoZSBcInNuYXBwaW5nTWV0aG9kXCIgcGFyYW1ldGVyIG11c3QgaGF2ZSB0aGUgdmFsdWUgJyR7U25hcHBpbmdNZXRob2RzLkFEVkFOQ0VEfScgb3IgJyR7U25hcHBpbmdNZXRob2RzLlNUQU5EQVJUfScuYCk7XHJcbiAgICAgIHJldHVybiBERUZBVUxUX1NOQVBQSU5HX01FVEhPRDtcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIFNuYXBwaW5nIG1ldGhvZC4gRGVmYXVsdCB2YWx1ZSBpcyAnc3RhbmRhcnQnLlxyXG4gICAqICdzdGFuZGFydCcgLSBDbGFzc2ljIGdyb3VwIHZpc3VhbGl6YXRpb24uXHJcbiAgICogJ2FkdmFuY2VkJyAtIEEgbWFzayBpcyBhcHBsaWVkIHRvIHRoZSB2aWV3cG9ydCBhcmVhIHNvIHRoYXQgdGhlIGJhY2tncm91bmQgaXMgZGlzcGxheWVkIHVuZGVybmVhdGggdGhlIGF0dGFjaGVkIGdyb3VwLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNuYXBwaW5nTWV0aG9kKHY6IFNuYXBwaW5nTWV0aG9kKSB7XHJcbiAgICBpZiAodGhpcy5fJHNuYXBwaW5nTWV0aG9kLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9zbmFwcGluZ01ldGhvZFRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kc25hcHBpbmdNZXRob2QubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBzbmFwcGluZ01ldGhvZCgpIHsgcmV0dXJuIHRoaXMuXyRzbmFwcGluZ01ldGhvZC5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRjb2xsYXBzaW5nTW9kZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Q29sbGFwc2luZ01vZGU+KERFRkFVTFRfQ09MTEFQU0lOR19NT0RFUyk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRjb2xsYXBzaW5nTW9kZSA9IHRoaXMuXyRjb2xsYXBzaW5nTW9kZS5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfY29sbGFwc2luZ01vZGVUcmFuc2Zvcm0gPSAodjogQ29sbGFwc2luZ01vZGUpID0+IHtcclxuICAgIGNvbnN0IHZhbGlkID0gdmFsaWRhdGVTdHJpbmcodikgJiYgKHYgPT09IENvbGxhcHNpbmdNb2Rlcy5OT05FIHx8IHYgPT09IENvbGxhcHNpbmdNb2Rlcy5NVUxUSV9DT0xMQVBTRSB8fCB2ID09PSBDb2xsYXBzaW5nTW9kZXMuQUNDT1JESU9OKTtcclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcihgVGhlIFwiY29sbGFwc2luZ01vZGVcIiBwYXJhbWV0ZXIgbXVzdCBoYXZlIHRoZSB2YWx1ZSAnJHtTbmFwcGluZ01ldGhvZHMuQURWQU5DRUR9JyBvciAnJHtTbmFwcGluZ01ldGhvZHMuU1RBTkRBUlR9Jy5gKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfQ09MTEFQU0lOR19NT0RFUztcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIE1vZGUgZm9yIGNvbGxhcHNpbmcgbGlzdCBpdGVtcy4gXHJcbiAgICogYG5vbmVgIC0gTGlzdCBpdGVtcyBhcmUgbm90IHNlbGVjdGFibGUuXHJcbiAgICogYG11bHRpLWNvbGxhcHNlYCAtIExpc3QgaXRlbXMgYXJlIGNvbGxhcHNlZCBvbmUgYnkgb25lLlxyXG4gICAqICdhY2NvcmRpb24nIC0gQWNjb3JkaW9uIGNvbGxhcHNpYmxlIGxpc3QgaXRlbXMuXHJcbiAgICogRGVmYXVsdCB2YWx1ZSBpcyBgbXVsdGktY29sbGFwc2VcclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBjb2xsYXBzaW5nTW9kZSh2OiBDb2xsYXBzaW5nTW9kZSkge1xyXG4gICAgaWYgKHRoaXMuXyRjb2xsYXBzaW5nTW9kZS5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fY29sbGFwc2luZ01vZGVUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJGNvbGxhcHNpbmdNb2RlLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcbiAgfTtcclxuICBnZXQgY29sbGFwc2luZ01vZGUoKSB7IHJldHVybiB0aGlzLl8kY29sbGFwc2luZ01vZGUuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICAvKipcclxuICAgKiBAZGVwcmVjYXRlZFxyXG4gICAqIFRoZSBcIm1ldGhvZEZvclNlbGVjdGluZ1wiIHByb3BlcnR5IGlzIGRlcHJlY2F0ZWQuIFVzZSB0aGUgXCJzZWxlY3RNb2RlXCIgcHJvcGVydHkuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgbWV0aG9kRm9yU2VsZWN0aW5nKHY6IGFueSkge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgXCJtZXRob2RGb3JTZWxlY3RpbmdcIiBwcm9wZXJ0eSBpcyBkZXByZWNhdGVkLiBVc2UgdGhlIFwic2VsZWN0TW9kZVwiIHByb3BlcnR5IGluc3RlYWQuJyk7XHJcbiAgfTtcclxuXHJcbiAgcHJpdmF0ZSBfJHNlbGVjdGluZ01vZGUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFNlbGVjdGluZ01vZGU+KERFRkFVTFRfU0VMRUNUSU5HX01PREVTKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJHNlbGVjdGluZ01vZGUgPSB0aGlzLl8kc2VsZWN0aW5nTW9kZS5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfc2VsZWN0aW5nTW9kZVRyYW5zZm9ybSA9ICh2OiBTZWxlY3RpbmdNb2RlKSA9PiB7XHJcbiAgICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlU3RyaW5nKHYpICYmICh2ID09PSAnbm9uZScgfHwgdiA9PT0gJ3NlbGVjdCcgfHwgdiA9PT0gJ211bHRpLXNlbGVjdCcpO1xyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJzZWxlY3RpbmdNb2RlXCIgcGFyYW1ldGVyIG11c3QgYmUgb25lIG9mIGBub25lYCwgYHNlbGVjdGAgb3IgYG11bHRpLXNlbGVjdGAuJyk7XHJcbiAgICAgIHJldHVybiBERUZBVUxUX1NFTEVDVElOR19NT0RFUztcclxuICAgIH1cclxuICAgIHJldHVybiB2O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqICBNZXRob2QgZm9yIHNlbGVjdGluZyBsaXN0IGl0ZW1zLiBEZWZhdWx0IHZhbHVlIGlzICdub25lJy5cclxuICAgKiAnc2VsZWN0JyAtIExpc3QgaXRlbXMgYXJlIHNlbGVjdGVkIG9uZSBieSBvbmUuXHJcbiAgICogJ211bHRpLXNlbGVjdCcgLSBNdWx0aXBsZSBzZWxlY3Rpb24gb2YgbGlzdCBpdGVtcy5cclxuICAgKiAnbm9uZScgLSBMaXN0IGl0ZW1zIGFyZSBub3Qgc2VsZWN0YWJsZS5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBzZWxlY3RpbmdNb2RlKHY6IFNlbGVjdGluZ01vZGUpIHtcclxuICAgIGlmICh0aGlzLl8kc2VsZWN0aW5nTW9kZS5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5fc2VsZWN0aW5nTW9kZVRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kc2VsZWN0aW5nTW9kZS5uZXh0KHRyYW5zZm9ybWVkVmFsdWUpO1xyXG4gIH07XHJcbiAgZ2V0IHNlbGVjdGluZ01vZGUoKSB7IHJldHVybiB0aGlzLl8kc2VsZWN0aW5nTW9kZS5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyR0cmFja0J5ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KFRSQUNLX0JZX1BST1BFUlRZX05BTUUpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkdHJhY2tCeSA9IHRoaXMuXyR0cmFja0J5LmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF90cmFja0J5VHJhbnNmb3JtID0gKHY6IHN0cmluZykgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZVN0cmluZyh2KTtcclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwidHJhY2tCeVwiIHBhcmFtZXRlciBtdXN0IGJlIG9mIHR5cGUgYHN0cmluZ2AuJyk7XHJcbiAgICAgIHJldHVybiBUUkFDS19CWV9QUk9QRVJUWV9OQU1FO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IGJ5IHdoaWNoIHRyYWNraW5nIGlzIHBlcmZvcm1lZFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHRyYWNrQnkodjogc3RyaW5nKSB7XHJcbiAgICBpZiAodGhpcy5fJHRyYWNrQnkuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX3RyYWNrQnlUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJHRyYWNrQnkubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCB0cmFja0J5KCkgeyByZXR1cm4gdGhpcy5fJHRyYWNrQnkuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF8kc2NyZWVuUmVhZGVyTWVzc2FnZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPihERUZBVUxUX1NDUkVFTl9SRUFERVJfTUVTU0FHRSk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRzY3JlZW5SZWFkZXJNZXNzYWdlID0gdGhpcy5fJHNjcmVlblJlYWRlck1lc3NhZ2UuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX3NjcmVlblJlYWRlck1lc3NhZ2VUcmFuc2Zvcm0gPSAodjogc3RyaW5nKSA9PiB7XHJcbiAgICBjb25zdCB2YWxpZCA9IHZhbGlkYXRlU3RyaW5nKHYpO1xyXG4gICAgaWYgKCF2YWxpZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdUaGUgXCJzY3JlZW5SZWFkZXJNZXNzYWdlXCIgcGFyYW1ldGVyIG11c3QgYmUgb2YgdHlwZSBgc3RyaW5nYC4nKTtcclxuICAgICAgcmV0dXJuIERFRkFVTFRfU0NSRUVOX1JFQURFUl9NRVNTQUdFO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogTWVzc2FnZSBmb3Igc2NyZWVuIHJlYWRlci5cclxuICAgKiBUaGUgbWVzc2FnZSBmb3JtYXQgaXM6IFwic29tZSB0ZXh0ICQxIHNvbWUgdGV4dCAkMlwiLFxyXG4gICAqIHdoZXJlICQxIGlzIHRoZSBudW1iZXIgb2YgdGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhlIHNjcmVlbiBjb2xsZWN0aW9uLFxyXG4gICAqICQyIGlzIHRoZSBudW1iZXIgb2YgdGhlIGxhc3QgZWxlbWVudCBvZiB0aGUgc2NyZWVuIGNvbGxlY3Rpb24uXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBwcm90ZWN0ZWQgc2V0IHNjcmVlblJlYWRlck1lc3NhZ2Uodjogc3RyaW5nKSB7XHJcbiAgICBpZiAodGhpcy5fJHNjcmVlblJlYWRlck1lc3NhZ2UuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRWYWx1ZSA9IHRoaXMuX3NjcmVlblJlYWRlck1lc3NhZ2VUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJHNjcmVlblJlYWRlck1lc3NhZ2UubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIHByb3RlY3RlZCBnZXQgc2NyZWVuUmVhZGVyTWVzc2FnZSgpIHsgcmV0dXJuIHRoaXMuXyRzY3JlZW5SZWFkZXJNZXNzYWdlLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJHNjcmVlblJlYWRlckZvcm1hdHRlZE1lc3NhZ2UgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4oREVGQVVMVF9TQ1JFRU5fUkVBREVSX01FU1NBR0UpO1xyXG4gIHByb3RlY3RlZCAkc2NyZWVuUmVhZGVyRm9ybWF0dGVkTWVzc2FnZSA9IHRoaXMuXyRzY3JlZW5SZWFkZXJGb3JtYXR0ZWRNZXNzYWdlLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF8kbGFuZ1RleHREaXIgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFRleHREaXJlY3Rpb24+KERFRkFVTFRfTEFOR19URVhUX0RJUik7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRsYW5nVGV4dERpciA9IHRoaXMuXyRsYW5nVGV4dERpci5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfbGFuZ1RleHREaXJUcmFuc2Zvcm0gPSAodjogVGV4dERpcmVjdGlvbikgPT4ge1xyXG4gICAgY29uc3QgdmFsaWQgPSB2YWxpZGF0ZVN0cmluZyh2KTtcclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignVGhlIFwibGFuZ1RleHREaXJcIiBwYXJhbWV0ZXIgbXVzdCBiZSBvZiB0eXBlIGBzdHJpbmdgLicpO1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9MQU5HX1RFWFRfRElSO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogQSBzdHJpbmcgaW5kaWNhdGluZyB0aGUgZGlyZWN0aW9uIG9mIHRleHQgZm9yIHRoZSBsb2NhbGUuXHJcbiAgICogQ2FuIGJlIGVpdGhlciBcImx0clwiIChsZWZ0LXRvLXJpZ2h0KSBvciBcInJ0bFwiIChyaWdodC10by1sZWZ0KS5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBsYW5nVGV4dERpcih2OiBUZXh0RGlyZWN0aW9uKSB7XHJcbiAgICBpZiAodGhpcy5fJGxhbmdUZXh0RGlyLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyYW5zZm9ybWVkVmFsdWUgPSB0aGlzLl9sYW5nVGV4dERpclRyYW5zZm9ybSh2KTtcclxuXHJcbiAgICB0aGlzLl8kbGFuZ1RleHREaXIubmV4dCh0cmFuc2Zvcm1lZFZhbHVlKTtcclxuICB9O1xyXG4gIGdldCBsYW5nVGV4dERpcigpIHsgcmV0dXJuIHRoaXMuXyRsYW5nVGV4dERpci5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgX2lzU2luZ2xlU2VsZWN0aW9uID0gdGhpcy5nZXRJc1NpbmdsZVNlbGVjdGlvbigpO1xyXG5cclxuICBwcml2YXRlIF9pc011bHRpU2VsZWN0aW9uID0gdGhpcy5nZXRJc011bHRpU2VsZWN0aW9uKCk7XHJcblxyXG4gIHByaXZhdGUgX2lzTXVsdGlwbGVDb2xsYXBzZSA9IHRoaXMuZ2V0SXNNdWx0aXBsZUNvbGxhcHNlKCk7XHJcblxyXG4gIHByaXZhdGUgX2lzQWNjb3JkaW9uQ29sbGFwc2UgPSB0aGlzLmdldElzQWNjb3JkaW9uQ29sbGFwc2UoKTtcclxuXHJcbiAgcHJpdmF0ZSBfaXNTbmFwcGluZ01ldGhvZEFkdmFuY2VkOiBib29sZWFuID0gdGhpcy5nZXRJc1NuYXBwaW5nTWV0aG9kQWR2YW5jZWQoKTtcclxuXHJcbiAgcHJvdGVjdGVkIF8kaXNJbmZpbml0eSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIHByb3RlY3RlZCAkaXNJbmZpbml0eSA9IHRoaXMuXyRpc0luZmluaXR5LmFzT2JzZXJ2YWJsZSgpO1xyXG4gIHByb3RlY3RlZCBnZXQgaXNJbmZpbml0eSgpIHtcclxuICAgIHJldHVybiB0aGlzLl8kaXNJbmZpbml0eS5nZXRWYWx1ZSgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaXNWZXJ0aWNhbCA9IHRoaXMuZ2V0SXNWZXJ0aWNhbCgpO1xyXG4gIHByb3RlY3RlZCBnZXQgaXNWZXJ0aWNhbCgpIHtcclxuICAgIHJldHVybiB0aGlzLl9pc1ZlcnRpY2FsO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfJGlzVmVydGljYWwgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KHRoaXMuaXNWZXJ0aWNhbCk7XHJcbiAgcHJvdGVjdGVkICRpc1ZlcnRpY2FsID0gdGhpcy5fJGlzVmVydGljYWwuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgXyRmb2N1c2VkRWxlbWVudCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SWQgfCBudWxsPihudWxsKTtcclxuICBwcm90ZWN0ZWQgJGZvY3VzZWRFbGVtZW50ID0gdGhpcy5fJGZvY3VzZWRFbGVtZW50LmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF8kY2xhc3NlcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8eyBbY05hbWU6IHN0cmluZ106IGJvb2xlYW4gfT4oe30pO1xyXG4gIHByb3RlY3RlZCAkY2xhc3NlcyA9IHRoaXMuXyRjbGFzc2VzLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF8kcHJlcmVuZGVyRW5hYmxlZCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIHByb3RlY3RlZCAkcHJlcmVuZGVyRW5hYmxlZCA9IHRoaXMuXyRwcmVyZW5kZXJFbmFibGVkLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF8kYWN0dWFsSXRlbXMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PElWaXJ0dWFsTGlzdENvbGxlY3Rpb24+KFtdKTtcclxuXHJcbiAgcHJpdmF0ZSBfJGNvbGxhcHNlZEl0ZW1JZHMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEFycmF5PElkPj4oW10pO1xyXG5cclxuICBwcml2YXRlIF9kaXNwbGF5Q29tcG9uZW50czogQXJyYXk8Q29tcG9uZW50UmVmPEJhc2VWaXJ0dWFsTGlzdEl0ZW1Db21wb25lbnQ+PiA9IFtdO1xyXG5cclxuICBwcml2YXRlIF9zbmFwcGVkRGlzcGxheUNvbXBvbmVudHM6IEFycmF5PENvbXBvbmVudFJlZjxCYXNlVmlydHVhbExpc3RJdGVtQ29tcG9uZW50Pj4gPSBbXTtcclxuXHJcbiAgcHJpdmF0ZSBfJGJvdW5kcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SVNpemUgfCBudWxsPihudWxsKTtcclxuICBwcm90ZWN0ZWQgJGJvdW5kczogT2JzZXJ2YWJsZTxJU2l6ZSB8IG51bGw+ID0gdGhpcy5fJGJvdW5kcy5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfJGFjdHVhbFNjcm9sbGJhckVuYWJsZWQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KHRoaXMuc2Nyb2xsYmFyRW5hYmxlZCk7XHJcbiAgcHJvdGVjdGVkICRhY3R1YWxTY3JvbGxiYXJFbmFibGVkOiBPYnNlcnZhYmxlPGJvb2xlYW4+ID0gdGhpcy5fJGFjdHVhbFNjcm9sbGJhckVuYWJsZWQuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgXyRhY3R1YWxBbGlnbm1lbnQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEFsaWdubWVudD4odGhpcy5hbGlnbm1lbnQpO1xyXG4gIHByb3RlY3RlZCAkYWN0dWFsQWxpZ25tZW50OiBPYnNlcnZhYmxlPEFsaWdubWVudD4gPSB0aGlzLl8kYWN0dWFsQWxpZ25tZW50LmFzT2JzZXJ2YWJsZSgpO1xyXG4gIHByb3RlY3RlZCBnZXQgYWN0dWFsQWxpZ25tZW50KCkgeyByZXR1cm4gdGhpcy5fJGFjdHVhbEFsaWdubWVudC5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRhY3R1YWxJdGVtU2l6ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPigwKTtcclxuICBwcm90ZWN0ZWQgJGFjdHVhbEl0ZW1TaXplOiBPYnNlcnZhYmxlPG51bWJlcj4gPSB0aGlzLl8kYWN0dWFsSXRlbVNpemUuYXNPYnNlcnZhYmxlKCk7XHJcbiAgcHJvdGVjdGVkIGdldCBhY3R1YWxJdGVtU2l6ZSgpIHsgcmV0dXJuIHRoaXMuXyRhY3R1YWxJdGVtU2l6ZS5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRhY3R1YWxNaW5JdGVtU2l6ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPigwKTtcclxuICBwcm90ZWN0ZWQgJGFjdHVhbE1pbkl0ZW1TaXplOiBPYnNlcnZhYmxlPG51bWJlcj4gPSB0aGlzLl8kYWN0dWFsTWluSXRlbVNpemUuYXNPYnNlcnZhYmxlKCk7XHJcbiAgcHJvdGVjdGVkIGdldCBhY3R1YWxNaW5JdGVtU2l6ZSgpIHsgcmV0dXJuIHRoaXMuXyRhY3R1YWxNaW5JdGVtU2l6ZS5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRhY3R1YWxNYXhJdGVtU2l6ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPigwKTtcclxuICBwcm90ZWN0ZWQgJGFjdHVhbE1heEl0ZW1TaXplOiBPYnNlcnZhYmxlPG51bWJlcj4gPSB0aGlzLl8kYWN0dWFsTWF4SXRlbVNpemUuYXNPYnNlcnZhYmxlKCk7XHJcbiAgcHJvdGVjdGVkIGdldCBhY3R1YWxNYXhJdGVtU2l6ZSgpIHsgcmV0dXJuIHRoaXMuXyRhY3R1YWxNYXhJdGVtU2l6ZS5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyR0b3RhbFNpemUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oMCk7XHJcblxyXG4gIHByaXZhdGUgXyRsaXN0Qm91bmRzID0gbmV3IEJlaGF2aW9yU3ViamVjdDxJU2l6ZSB8IG51bGw+KG51bGwpO1xyXG5cclxuICBwcml2YXRlIF8kc2Nyb2xsU2l6ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPigwKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJHNjcm9sbFNpemUgPSB0aGlzLl8kc2Nyb2xsU2l6ZS5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfJGlzU2Nyb2xsU3RhcnQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KHRydWUpO1xyXG5cclxuICBwcml2YXRlIF8kaXNTY3JvbGxFbmQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcclxuXHJcbiAgcHJpdmF0ZSBfJHByZWNhbGN1bGF0ZWRTY3JvbGxTdGFydE9mZnNldCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPigwKTtcclxuXHJcbiAgcHJpdmF0ZSBfJHByZWNhbGN1bGF0ZWRTY3JvbGxFbmRPZmZzZXQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oMCk7XHJcblxyXG4gIHByaXZhdGUgXyRhY3R1YWxTY3JvbGxTdGFydE9mZnNldCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPigwKTtcclxuICBwcm90ZWN0ZWQgJGFjdHVhbFNjcm9sbFN0YXJ0T2Zmc2V0ID0gdGhpcy5fJGFjdHVhbFNjcm9sbFN0YXJ0T2Zmc2V0LmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF8kYWN0dWFsU2Nyb2xsRW5kT2Zmc2V0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KDApO1xyXG4gIHByb3RlY3RlZCAkYWN0dWFsU2Nyb2xsRW5kT2Zmc2V0ID0gdGhpcy5fJGFjdHVhbFNjcm9sbEVuZE9mZnNldC5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfJHN0YXJ0T2Zmc2V0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KDApO1xyXG4gIHByb3RlY3RlZCAkc3RhcnRPZmZzZXQgPSB0aGlzLl8kc3RhcnRPZmZzZXQuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgXyRlbmRPZmZzZXQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oMCk7XHJcbiAgcHJvdGVjdGVkICRlbmRPZmZzZXQgPSB0aGlzLl8kZW5kT2Zmc2V0LmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF8kYWN0dWFsU25hcFNjcm9sbFRvU3RhcnQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcclxuXHJcbiAgcHJpdmF0ZSBfJGFjdHVhbFNuYXBTY3JvbGxUb0VuZCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xyXG5cclxuICBwcml2YXRlIF8kYWxpZ25tZW50U2Nyb2xsU3RhcnRPZmZzZXQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oMCk7XHJcbiAgcHJvdGVjdGVkICRhbGlnbm1lbnRTY3JvbGxTdGFydE9mZnNldCA9IHRoaXMuXyRhbGlnbm1lbnRTY3JvbGxTdGFydE9mZnNldC5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfJGFsaWdubWVudFNjcm9sbEVuZE9mZnNldCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPigwKTtcclxuICBwcm90ZWN0ZWQgJGFsaWdubWVudFNjcm9sbEVuZE9mZnNldCA9IHRoaXMuXyRhbGlnbm1lbnRTY3JvbGxFbmRPZmZzZXQuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX3Jlc2l6ZVNuYXBwZWRDb21wb25lbnRIYW5kbGVyID0gKCkgPT4ge1xyXG4gICAgY29uc3QgbGlzdCA9IHRoaXMuXyRsaXN0LmdldFZhbHVlKCksIHNjcm9sbGVyID0gdGhpcy5fJHNjcm9sbGVyLmdldFZhbHVlKCksIGJvdW5kcyA9IHRoaXMuXyRib3VuZHMuZ2V0VmFsdWUoKSwgc25hcHBlZENvbXBvbmVudHMgPSB0aGlzLl9zbmFwcGVkRGlzcGxheUNvbXBvbmVudHM7XHJcbiAgICBpZiAoISFsaXN0ICYmICEhc2Nyb2xsZXIgJiYgc25hcHBlZENvbXBvbmVudHMubGVuZ3RoID4gMCkge1xyXG4gICAgICBjb25zdCBpc1ZlcnRpY2FsID0gdGhpcy5faXNWZXJ0aWNhbCwgbGlzdEJvdW5kcyA9IGxpc3QubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuXHJcbiAgICAgIGZvciAoY29uc3QgY29tcCBvZiBzbmFwcGVkQ29tcG9uZW50cykge1xyXG4gICAgICAgIGlmICghIWNvbXApIHtcclxuICAgICAgICAgIGNvbXAuaW5zdGFuY2UucmVndWxhckxlbmd0aCA9IGAke2lzVmVydGljYWwgPyBsaXN0Qm91bmRzLndpZHRoIDogbGlzdEJvdW5kcy5oZWlnaHR9JHtQWH1gO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgY29uc3Qgc25hcHBpbmdNZXRob2QgPSB0aGlzLnNuYXBwaW5nTWV0aG9kO1xyXG4gICAgICBpZiAoc25hcHBpbmdNZXRob2QgPT09IFNuYXBwaW5nTWV0aG9kcy5BRFZBTkNFRCkge1xyXG4gICAgICAgIGNvbnN0IHNuYXBwZWRDb21wb25lbnQgPSBzbmFwcGVkQ29tcG9uZW50cz8uWzBdPy5pbnN0YW5jZTtcclxuICAgICAgICBpZiAoISFzbmFwcGVkQ29tcG9uZW50KSB7XHJcbiAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGJvdW5kcyA/PyB7IHdpZHRoOiAwLCBoZWlnaHQ6IDAgfSwgbGFuZ1RleHREaXIgPSB0aGlzLmxhbmdUZXh0RGlyO1xyXG5cclxuICAgICAgICAgIHNuYXBwZWRDb21wb25lbnQuZWxlbWVudC5zdHlsZS5jbGlwUGF0aCA9IGBwYXRoKFwiTSAwIDAgTCAwICR7c25hcHBlZENvbXBvbmVudC5lbGVtZW50Lm9mZnNldEhlaWdodH0gTCAke3NuYXBwZWRDb21wb25lbnQuZWxlbWVudC5vZmZzZXRXaWR0aH0gJHtzbmFwcGVkQ29tcG9uZW50LmVsZW1lbnQub2Zmc2V0SGVpZ2h0fSBMICR7c25hcHBlZENvbXBvbmVudC5lbGVtZW50Lm9mZnNldFdpZHRofSAwIFpcIilgO1xyXG5cclxuICAgICAgICAgIGNvbnN0IHsgd2lkdGg6IHNXaWR0aCwgaGVpZ2h0OiBzSGVpZ2h0IH0gPSBzbmFwcGVkQ29tcG9uZW50LmdldEJvdW5kcygpID8/IHsgd2lkdGg6IDAsIGhlaWdodDogMCB9LFxyXG4gICAgICAgICAgICBzY3JvbGxlckVsZW1lbnQgPSBzY3JvbGxlci5uYXRpdmVFbGVtZW50LCBkZWx0YSA9IHNuYXBwZWRDb21wb25lbnQuaXRlbT8ubWVhc3VyZXMuZGVsdGEgPz8gMCxcclxuICAgICAgICAgICAgc2Nyb2xsQmFyU2l6ZSA9IHRoaXMuc2Nyb2xsYmFyVGhpY2tuZXNzO1xyXG5cclxuICAgICAgICAgIGxldCByaWdodDogbnVtYmVyLCB0b3A6IG51bWJlciwgYm90dG9tOiBudW1iZXI7XHJcbiAgICAgICAgICBpZiAoaXNWZXJ0aWNhbCkge1xyXG4gICAgICAgICAgICByaWdodCA9IHdpZHRoIC0gc2Nyb2xsQmFyU2l6ZSArIDI7XHJcbiAgICAgICAgICAgIHRvcCA9IHNIZWlnaHQ7XHJcbiAgICAgICAgICAgIGJvdHRvbSA9IGhlaWdodDtcclxuICAgICAgICAgICAgaWYgKGxhbmdUZXh0RGlyID09PSBUZXh0RGlyZWN0aW9ucy5SVEwpIHtcclxuICAgICAgICAgICAgICBzY3JvbGxlckVsZW1lbnQuc3R5bGUuY2xpcFBhdGggPSBgcGF0aChcIk0gMCAwIEwgMCAke2hlaWdodH0gTCAke3dpZHRofSAke2hlaWdodH0gTCAke3dpZHRofSAke3RvcCArIGRlbHRhfSBMICR7c2Nyb2xsQmFyU2l6ZX0gJHt0b3AgKyBkZWx0YX0gTCAke3Njcm9sbEJhclNpemV9IDAgWlwiKWA7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgc2Nyb2xsZXJFbGVtZW50LnN0eWxlLmNsaXBQYXRoID0gYHBhdGgoXCJNIDAgJHt0b3AgKyBkZWx0YX0gTCAwICR7aGVpZ2h0fSBMICR7d2lkdGh9ICR7aGVpZ2h0fSBMICR7d2lkdGh9IDAgTCAke3JpZ2h0fSAwIEwgJHtyaWdodH0gJHt0b3AgKyBkZWx0YX0gWlwiKWA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJpZ2h0ID0gd2lkdGg7XHJcbiAgICAgICAgICAgIHRvcCA9IDA7XHJcbiAgICAgICAgICAgIGJvdHRvbSA9IGhlaWdodCAtIHNjcm9sbEJhclNpemU7XHJcbiAgICAgICAgICAgIHNjcm9sbGVyRWxlbWVudC5zdHlsZS5jbGlwUGF0aCA9IGBwYXRoKFwiTSAke3dpZHRofSAwIEwgJHt3aWR0aH0gJHtib3R0b219IEwgMCAke2JvdHRvbX0gTCAwIDAgTCAke3dpZHRofSAwIFpcIilgO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIHByaXZhdGUgX3Jlc2l6ZVNuYXBwZWRPYnNlcnZlcjogUmVzaXplT2JzZXJ2ZXIgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgcHJpdmF0ZSBmb2N1c0l0ZW0gPSAoZWxlbWVudDogSFRNTEVsZW1lbnQsIHBvc2l0aW9uOiBudW1iZXIsIGFsaWduOiBGb2N1c0FsaWdubWVudCA9IEZvY3VzQWxpZ25tZW50cy5DRU5URVIsXHJcbiAgICBiZWhhdmlvcjogU2Nyb2xsQmVoYXZpb3IgPSBCRUhBVklPUl9BVVRPKSA9PiB7XHJcbiAgICBpZiAoIXRoaXMuX3JlYWR5Rm9yU2hvdykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCBzY3JvbGxlciA9IHRoaXMuX3Njcm9sbGVyQ29tcG9uZW50O1xyXG4gICAgaWYgKCEhc2Nyb2xsZXIpIHtcclxuICAgICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSB0aGlzLl8kYm91bmRzLmdldFZhbHVlKCkhLCB7IHdpZHRoOiBlbGVtZW50V2lkdGgsIGhlaWdodDogZWxlbWVudEhlaWdodCB9ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxcclxuICAgICAgICBpc1ZlcnRpY2FsID0gdGhpcy5faXNWZXJ0aWNhbCxcclxuICAgICAgICB2aWV3cG9ydFNpemUgPSBpc1ZlcnRpY2FsID8gaGVpZ2h0IDogd2lkdGgsXHJcbiAgICAgICAgZWxlbWVudFNpemUgPSBpc1ZlcnRpY2FsID8gZWxlbWVudEhlaWdodCA6IGVsZW1lbnRXaWR0aDtcclxuICAgICAgbGV0IHBvczogbnVtYmVyID0gTnVtYmVyLk5hTjtcclxuICAgICAgc3dpdGNoIChhbGlnbikge1xyXG4gICAgICAgIGNhc2UgRm9jdXNBbGlnbm1lbnRzLlNUQVJUOiB7XHJcbiAgICAgICAgICBwb3MgPSBwb3NpdGlvbiArIHNjcm9sbGVyLnN0YXJ0TGF5b3V0T2Zmc2V0O1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhc2UgRm9jdXNBbGlnbm1lbnRzLkNFTlRFUjoge1xyXG4gICAgICAgICAgcG9zID0gcG9zaXRpb24gLSAodmlld3BvcnRTaXplIC0gZWxlbWVudFNpemUpICogLjUgKyBzY3JvbGxlci5zdGFydExheW91dE9mZnNldDtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXNlIEZvY3VzQWxpZ25tZW50cy5FTkQ6IHtcclxuICAgICAgICAgIHBvcyA9IHBvc2l0aW9uIC0gKHZpZXdwb3J0U2l6ZSAtIGVsZW1lbnRTaXplKSArIHNjcm9sbGVyLnN0YXJ0TGF5b3V0T2Zmc2V0O1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhc2UgRm9jdXNBbGlnbm1lbnRzLk5PTkU6XHJcbiAgICAgICAgZGVmYXVsdDoge1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGlmICghTnVtYmVyLmlzTmFOKHBvcykpIHtcclxuICAgICAgICB0aGlzLl90cmFja0JveC5wcmV2ZW50U2Nyb2xsU25hcHBpbmcodHJ1ZSk7XHJcbiAgICAgICAgY29uc3QgcGFyYW1zOiBJU2Nyb2xsVG9QYXJhbXMgPSB7XHJcbiAgICAgICAgICBbdGhpcy5faXNWZXJ0aWNhbCA/IFRPUF9QUk9QX05BTUUgOiBMRUZUX1BST1BfTkFNRV06IHBvcywgYmVoYXZpb3IsIHNuYXA6IGZhbHNlLCBub3JtYWxpemU6IHRydWUsXHJcbiAgICAgICAgICBmaXJlVXBkYXRlOiBmYWxzZSwgYmxlbmRpbmc6IGZhbHNlLCB1c2VyQWN0aW9uOiBmYWxzZSxcclxuICAgICAgICAgIGR1cmF0aW9uOiB0aGlzLnNuYXBUb0l0ZW0gPyBNYXRoLm1heCh0aGlzLmFuaW1hdGlvblBhcmFtcy5zY3JvbGxUb0l0ZW0sIHRoaXMuYW5pbWF0aW9uUGFyYW1zLm5hdmlnYXRlVG9JdGVtKSA6IHRoaXMuYW5pbWF0aW9uUGFyYW1zLm5hdmlnYXRlVG9JdGVtLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgc2Nyb2xsZXIuc2Nyb2xsVG8ocGFyYW1zKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfZWxlbWVudFJlZiA9IGluamVjdDxFbGVtZW50UmVmPEhUTUxFbGVtZW50Pj4oRWxlbWVudFJlZik7XHJcblxyXG4gIC8qKlxyXG4gICAqIEJhc2UgY2xhc3Mgb2YgdGhlIGVsZW1lbnQgY29tcG9uZW50XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfaXRlbUNvbXBvbmVudENsYXNzOiBDb21wb25lbnQkMTxCYXNlVmlydHVhbExpc3RJdGVtQ29tcG9uZW50PiA9IE5nVmlydHVhbExpc3RJdGVtQ29tcG9uZW50O1xyXG4gIHByb3RlY3RlZCBnZXQgaXRlbUNvbXBvbmVudENsYXNzKCkgeyByZXR1cm4gdGhpcy5faXRlbUNvbXBvbmVudENsYXNzOyB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEJhc2UgY2xhc3MgdHJhY2tCb3hcclxuICAgKi9cclxuICBwcml2YXRlIF90cmFja0JveENsYXNzOiBDb21wb25lbnQkMTxUcmFja0JveD4gPSBUcmFja0JveDtcclxuXHJcbiAgLyoqXHJcbiAgICogRGljdGlvbmFyeSBvZiBlbGVtZW50IHNpemVzIGJ5IHRoZWlyIGlkXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfdHJhY2tCb3g6IFRyYWNrQm94ID0gbmV3IHRoaXMuX3RyYWNrQm94Q2xhc3ModGhpcy50cmFja0J5KTtcclxuXHJcbiAgcHJpdmF0ZSBfJHVwZGF0ZSA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJHVwZGF0ZSA9IHRoaXMuXyR1cGRhdGUuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgXyRzY3JvbGxUbyA9IG5ldyBTdWJqZWN0PElTY3JvbGxQYXJhbXM+KCk7XHJcbiAgcHJvdGVjdGVkICRzY3JvbGxUbyA9IHRoaXMuXyRzY3JvbGxUby5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfJHNjcm9sbFRvRXhlY3V0b3IgPSBuZXcgU3ViamVjdDxJU2Nyb2xsUGFyYW1zPigpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkc2Nyb2xsVG9FeGVjdXRvciA9IHRoaXMuXyRzY3JvbGxUb0V4ZWN1dG9yLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF8kc2Nyb2xsaW5nVG8gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcclxuXHJcbiAgcHJpdmF0ZSBfJHNjcm9sbCA9IG5ldyBTdWJqZWN0PElTY3JvbGxFdmVudD4oKTtcclxuICByZWFkb25seSAkc2Nyb2xsID0gdGhpcy5fJHNjcm9sbC5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfJHRpY2sgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG4gIHJlYWRvbmx5ICR0aWNrID0gdGhpcy5fJHRpY2suYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgXyRmaXJlVXBkYXRlID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgJGZpcmVVcGRhdGUgPSB0aGlzLl8kZmlyZVVwZGF0ZS5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfJGZpcmVVcGRhdGVOZXh0RnJhbWUgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xyXG4gIHByb3RlY3RlZCByZWFkb25seSAkZmlyZVVwZGF0ZU5leHRGcmFtZSA9IHRoaXMuXyRmaXJlVXBkYXRlTmV4dEZyYW1lLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF8kcHJldmVudFNjcm9sbFNuYXBwaW5nID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5ICRwcmV2ZW50U2Nyb2xsU25hcHBpbmcgPSB0aGlzLl8kcHJldmVudFNjcm9sbFNuYXBwaW5nLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF91cGRhdGVJZDogbnVtYmVyIHwgdW5kZWZpbmVkO1xyXG5cclxuICBwcml2YXRlIF9yZWFkeUZvclNob3cgPSBmYWxzZTtcclxuXHJcbiAgcHJpdmF0ZSBfY2FjaGVkID0gZmFsc2U7XHJcblxyXG4gIHByaXZhdGUgX2lzTG9hZGluZyA9IGZhbHNlO1xyXG5cclxuICBwcm90ZWN0ZWQgZ2V0IGNhY2hhYmxlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX3ByZXJlbmRlcj8uYWN0aXZlID8/IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGdldCBwcmVyZW5kZXJhYmxlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuZHluYW1pY1NpemUgJiYgKHRoaXMuX3RyYWNrQm94Py5pc1NuYXBwZWRUb0VuZCA/PyBmYWxzZSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF8kdmlld0luaXQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcclxuICBwcml2YXRlIHJlYWRvbmx5ICR2aWV3SW5pdCA9IHRoaXMuXyR2aWV3SW5pdC5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBfJGRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgJGRlc3Ryb3kgPSB0aGlzLl8kZGVzdHJveS5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7XHJcbiAgICBzdXBlcigpO1xyXG4gICAgTmdWaXJ0dWFsTGlzdENvbXBvbmVudC5fX25leHRJZCA9IE5nVmlydHVhbExpc3RDb21wb25lbnQuX19uZXh0SWQgKyAxID09PSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUlxyXG4gICAgICA/IDAgOiBOZ1ZpcnR1YWxMaXN0Q29tcG9uZW50Ll9fbmV4dElkICsgMTtcclxuICAgIHRoaXMuX2lkID0gTmdWaXJ0dWFsTGlzdENvbXBvbmVudC5fX25leHRJZDtcclxuXHJcbiAgICB0aGlzLl9zZXJ2aWNlLmluaXRpYWxpemUodGhpcy5faWQsIHRoaXMuX3RyYWNrQm94KTtcclxuXHJcbiAgICBjb25zdCAkZHluYW1pY1NpemUgPSB0aGlzLiRkeW5hbWljU2l6ZSxcclxuICAgICAgJHNuYXBTY3JvbGxUb0VuZCA9IHRoaXMuJHNuYXBTY3JvbGxUb0VuZDtcclxuICAgIGNvbWJpbmVMYXRlc3QoWyRkeW5hbWljU2l6ZSwgJHNuYXBTY3JvbGxUb0VuZF0pLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICB0YXAoKFtkeW5hbWljU2l6ZSwgc25hcFNjcm9sbFRvRW5kXSkgPT4ge1xyXG4gICAgICAgIHRoaXMuXyRwcmVyZW5kZXJFbmFibGVkLm5leHQoZHluYW1pY1NpemUgJiYgc25hcFNjcm9sbFRvRW5kKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIHRoaXMuJGFuaW1hdGlvblBhcmFtcy5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX3NlcnZpY2UuYW5pbWF0aW9uUGFyYW1zID0gdjtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIHRoaXMuJHNwcmVhZGluZ01vZGUucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl8kaXNJbmZpbml0eS5uZXh0KGlzU3ByZWFkaW5nTW9kZSh2LCBTcHJlYWRpbmdNb2Rlcy5JTkZJTklUWSkpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgdGhpcy4kYWN0dWFsU2Nyb2xsU3RhcnRPZmZzZXQucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGRlYm91bmNlVGltZSgwKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuXyRzdGFydE9mZnNldC5uZXh0KHYpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgdGhpcy4kYWN0dWFsU2Nyb2xsRW5kT2Zmc2V0LnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBkZWJvdW5jZVRpbWUoMCksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl8kZW5kT2Zmc2V0Lm5leHQodik7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICBjb25zdCAkaXNJbmZpbml0eSA9IHRoaXMuJGlzSW5maW5pdHk7XHJcbiAgICAkaXNJbmZpbml0eS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX3RyYWNrQm94LmlzSW5maW5pdHkgPSB0aGlzLl9zZXJ2aWNlLmlzSW5maW5pdHkgPSB2O1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgY29uc3QgJHpJbmRleFdoZW5TZWxlY3RpbmcgPSB0aGlzLiR6SW5kZXhXaGVuU2VsZWN0aW5nO1xyXG4gICAgJHpJbmRleFdoZW5TZWxlY3RpbmcucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl9zZXJ2aWNlLnpJbmRleFdoZW5TZWxlY3RpbmcgPSB2O1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgY29uc3QgJGJvdW5kcyA9IHRoaXMuXyRib3VuZHMuYXNPYnNlcnZhYmxlKCkucGlwZShcclxuICAgICAgZmlsdGVyKGIgPT4gISFiKSxcclxuICAgICksXHJcbiAgICAgICRyYXdTY3JvbGxTdGFydE9mZnNldCA9IHRoaXMuJHNjcm9sbFN0YXJ0T2Zmc2V0LFxyXG4gICAgICAkcmF3U2Nyb2xsRW5kT2Zmc2V0ID0gdGhpcy4kc2Nyb2xsRW5kT2Zmc2V0O1xyXG5cclxuICAgIGNvbWJpbmVMYXRlc3QoWyRib3VuZHMsICRyYXdTY3JvbGxTdGFydE9mZnNldF0pLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBmaWx0ZXIoKFt2XSkgPT4gISF2KSxcclxuICAgICAgdGFwKChbYm91bmRzLCB2YWx1ZV0pID0+IHtcclxuICAgICAgICBjb25zdCB2YWwgPSBwYXJzZUFyaXRobWV0aWNFeHByZXNzaW9uKHZhbHVlLCB0aGlzLmlzVmVydGljYWwgPyBib3VuZHMhLmhlaWdodCA6IGJvdW5kcyEud2lkdGgpO1xyXG4gICAgICAgIHRoaXMuXyRwcmVjYWxjdWxhdGVkU2Nyb2xsU3RhcnRPZmZzZXQubmV4dCh2YWwpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgY29tYmluZUxhdGVzdChbJGJvdW5kcywgJHJhd1Njcm9sbEVuZE9mZnNldF0pLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBmaWx0ZXIoKFt2XSkgPT4gISF2KSxcclxuICAgICAgdGFwKChbYm91bmRzLCB2YWx1ZV0pID0+IHtcclxuICAgICAgICBjb25zdCB2YWwgPSBwYXJzZUFyaXRobWV0aWNFeHByZXNzaW9uKHZhbHVlLCB0aGlzLmlzVmVydGljYWwgPyBib3VuZHMhLmhlaWdodCA6IGJvdW5kcyEud2lkdGgpO1xyXG4gICAgICAgIHRoaXMuXyRwcmVjYWxjdWxhdGVkU2Nyb2xsRW5kT2Zmc2V0Lm5leHQodmFsKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIHRoaXMuX3NlcnZpY2UuJGludGVyc2VjdGlvbkVsZW1lbnRCeVNuYXBUb0l0ZW1BbGlnbi5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZmlsdGVyKHYgPT4gdiAhPT0gbnVsbCksXHJcbiAgICAgIHRhcChpZCA9PiB7XHJcbiAgICAgICAgdGhpcy5vblNuYXBJdGVtLmVtaXQoaWQhKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIHRoaXMuX3NlcnZpY2UuJHRpY2sucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcCgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5fc2Nyb2xsZXJDb21wb25lbnQ/LnRpY2soKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIHRoaXMuX3NlcnZpY2UuJHRpY2sucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGZpbHRlcigoKSA9PiB0aGlzLmR5bmFtaWNTaXplID09PSB0cnVlKSxcclxuICAgICAgdGFwKCgpID0+IHtcclxuICAgICAgICB0aGlzLmNoZWNrQm91bmRzT2ZFbGVtZW50cygpO1xyXG4gICAgICAgIHRoaXMuX3Njcm9sbGVyQ29tcG9uZW50Py50aWNrKCk7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIGNvbnN0IF8kY3JlYXRlZCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpLFxyXG4gICAgICAkY3JlYXRlZCA9IF8kY3JlYXRlZC5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgICBjb21iaW5lTGF0ZXN0KFskY3JlYXRlZCwgdGhpcy4kc2hvd10pLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBmaWx0ZXIoKFtjcmVhdGVkLCBzaG93bl0pID0+IGNyZWF0ZWQgJiYgc2hvd24pLFxyXG4gICAgICBkZWJvdW5jZVRpbWUoMSksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl8kaW5pdGlhbGl6ZWQubmV4dCh0cnVlKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIHRoaXMuXyRzY3JvbGxlci5uZXh0KHRoaXMuX3Njcm9sbGVyQ29tcG9uZW50Py5zY3JvbGxWaWV3cG9ydCk7XHJcbiAgICB0aGlzLl8kbGlzdC5uZXh0KHRoaXMuX3Njcm9sbGVyQ29tcG9uZW50Py5zY3JvbGxDb250ZW50KTtcclxuXHJcbiAgICBjb25zdCAkYm91bmRzID0gdGhpcy5fJGJvdW5kcy5hc09ic2VydmFibGUoKS5waXBlKFxyXG4gICAgICBmaWx0ZXIoYiA9PiAhIWIpLFxyXG4gICAgKSxcclxuICAgICAgJHNjcm9sbGVyQ29tcG9uZW50ID0gb2YodGhpcy5fc2Nyb2xsZXJDb21wb25lbnQpLFxyXG4gICAgICAkcmVzaXplVmlld3BvcnQgPSAkc2Nyb2xsZXJDb21wb25lbnQucGlwZShcclxuICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICBmaWx0ZXIodiA9PiAhIXYpLFxyXG4gICAgICAgIHN3aXRjaE1hcChzY3JvbGxlciA9PiBzY3JvbGxlciEuJHJlc2l6ZVZpZXdwb3J0KSxcclxuICAgICAgKSxcclxuICAgICAgJHJlc2l6ZUNvbnRlbnQgPSAkc2Nyb2xsZXJDb21wb25lbnQucGlwZShcclxuICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICBmaWx0ZXIodiA9PiAhIXYpLFxyXG4gICAgICAgIHN3aXRjaE1hcChzY3JvbGxlciA9PiBzY3JvbGxlciEuJHJlc2l6ZUNvbnRlbnQpLFxyXG4gICAgICApO1xyXG5cclxuICAgICRzY3JvbGxlckNvbXBvbmVudC5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZmlsdGVyKHYgPT4gISF2KSxcclxuICAgICAgc3dpdGNoTWFwKHNjcm9sbGVyID0+IHNjcm9sbGVyIS4kc2Nyb2xsRGlyZWN0aW9uKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX3RyYWNrQm94LnNjcm9sbERpcmVjdGlvbiA9IHY7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAkcmVzaXplVmlld3BvcnQucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGZpbHRlcih2ID0+ICEhdiksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl8kYm91bmRzLm5leHQodik7XHJcbiAgICAgICAgdGhpcy5vbkFmdGVyUmVzaXplKHRydWUpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgJHJlc2l6ZUNvbnRlbnQucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGZpbHRlcih2ID0+ICEhdiksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl8kbGlzdEJvdW5kcy5uZXh0KHYpO1xyXG4gICAgICAgIHRoaXMub25BZnRlclJlc2l6ZSgpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgY29uc3QgJHRyYWNrQnkgPSB0aGlzLiR0cmFja0J5O1xyXG4gICAgJHRyYWNrQnkucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl9zZXJ2aWNlLnRyYWNrQnkgPSB0aGlzLl90cmFja0JveC50cmFja0J5ID0gdjtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIHRoaXMuX3RyYWNrQm94LmRpc3BsYXlDb21wb25lbnRzID0gdGhpcy5fZGlzcGxheUNvbXBvbmVudHM7XHJcblxyXG4gICAgbGV0IGhhc1VzZXJBY3Rpb24gPSBmYWxzZTtcclxuXHJcbiAgICBjb25zdCAkaXRlbVNpemUgPSB0aGlzLiRpdGVtU2l6ZS5waXBlKFxyXG4gICAgICBtYXAodiA9PiB0eXBlb2YgdiA9PT0gJ251bWJlcicgJiYgdiA8PSAwID8gREVGQVVMVF9JVEVNX1NJWkUgOiB2KSxcclxuICAgICksXHJcbiAgICAgICRtaW5JdGVtU2l6ZSA9IHRoaXMuJG1pbkl0ZW1TaXplLnBpcGUoXHJcbiAgICAgICAgbWFwKHYgPT4gdHlwZW9mIHYgPT09ICdudW1iZXInICYmIHYgPD0gMCA/IERFRkFVTFRfTUlOX0lURU1fU0laRSA6IHYpLFxyXG4gICAgICApLFxyXG4gICAgICAkbWF4SXRlbVNpemUgPSB0aGlzLiRtYXhJdGVtU2l6ZS5waXBlKFxyXG4gICAgICAgIG1hcCh2ID0+IHR5cGVvZiB2ID09PSAnbnVtYmVyJyAmJiB2IDw9IDAgPyBERUZBVUxUX01BWF9JVEVNX1NJWkUgOiB2KSxcclxuICAgICAgKSxcclxuICAgICAgJHNjcm9sbFN0YXJ0T2Zmc2V0ID0gdGhpcy4kYWN0dWFsU2Nyb2xsU3RhcnRPZmZzZXQucGlwZShcclxuICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICApLFxyXG4gICAgICAkc2Nyb2xsRW5kT2Zmc2V0ID0gdGhpcy4kYWN0dWFsU2Nyb2xsRW5kT2Zmc2V0LnBpcGUoXHJcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgKTtcclxuXHJcbiAgICBjb21iaW5lTGF0ZXN0KFskbWluSXRlbVNpemUsICRib3VuZHMsICRzY3JvbGxTdGFydE9mZnNldCwgJHNjcm9sbEVuZE9mZnNldF0pLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBzd2l0Y2hNYXAoKFt2LCBib3VuZHMsIHN0YXJ0T2Zmc2V0LCBlbmRPZmZzZXRdKSA9PiB7XHJcbiAgICAgICAgaWYgKCh2IGFzIGFueSkgPT09IFZJRVdQT1JUKSB7XHJcbiAgICAgICAgICBjb25zdCBpc1ZlcnRpY2FsID0gdGhpcy5pc1ZlcnRpY2FsLCB2aWV3cG9ydEJvdW5kcyA9IGJvdW5kcyxcclxuICAgICAgICAgICAgcmVzdWx0ID0gKGlzVmVydGljYWwgPyAodmlld3BvcnRCb3VuZHM/LmhlaWdodCA/PyAwKSA6ICh2aWV3cG9ydEJvdW5kcz8ud2lkdGggPz8gMCkpIC0gc3RhcnRPZmZzZXQgLSBlbmRPZmZzZXQ7XHJcbiAgICAgICAgICByZXR1cm4gb2YocmVzdWx0IDw9IDAgPyAxIDogcmVzdWx0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9mKHYpO1xyXG4gICAgICB9KSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuXyRhY3R1YWxNaW5JdGVtU2l6ZS5uZXh0KHYpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgY29tYmluZUxhdGVzdChbJG1heEl0ZW1TaXplLCAkYm91bmRzLCAkc2Nyb2xsU3RhcnRPZmZzZXQsICRzY3JvbGxFbmRPZmZzZXRdKS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgc3dpdGNoTWFwKChbdiwgYm91bmRzLCBzdGFydE9mZnNldCwgZW5kT2Zmc2V0XSkgPT4ge1xyXG4gICAgICAgIGlmICgodiBhcyBhbnkpID09PSBWSUVXUE9SVCkge1xyXG4gICAgICAgICAgY29uc3QgaXNWZXJ0aWNhbCA9IHRoaXMuaXNWZXJ0aWNhbCwgdmlld3BvcnRCb3VuZHMgPSBib3VuZHMsXHJcbiAgICAgICAgICAgIHJlc3VsdCA9IChpc1ZlcnRpY2FsID8gKHZpZXdwb3J0Qm91bmRzPy5oZWlnaHQgPz8gMCkgOiAodmlld3BvcnRCb3VuZHM/LndpZHRoID8/IDApKSAtIHN0YXJ0T2Zmc2V0IC0gZW5kT2Zmc2V0O1xyXG4gICAgICAgICAgcmV0dXJuIG9mKHJlc3VsdCA8PSAwID8gMSA6IHJlc3VsdCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvZih2KTtcclxuICAgICAgfSksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl8kYWN0dWFsTWF4SXRlbVNpemUubmV4dCh2KTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIGNvbnN0ICRhY3R1YWxNaW5JdGVtU2l6ZSA9IHRoaXMuJGFjdHVhbE1pbkl0ZW1TaXplLFxyXG4gICAgICAkYWN0dWFsTWF4SXRlbVNpemUgPSB0aGlzLiRhY3R1YWxNYXhJdGVtU2l6ZTtcclxuXHJcbiAgICBjb21iaW5lTGF0ZXN0KFskaXRlbVNpemUsICRib3VuZHMsICRhY3R1YWxNaW5JdGVtU2l6ZSwgJGFjdHVhbE1heEl0ZW1TaXplLCAkc2Nyb2xsU3RhcnRPZmZzZXQsICRzY3JvbGxFbmRPZmZzZXRdKS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgc3dpdGNoTWFwKChbdiwgYm91bmRzLCBtaW4sIG1heCwgc3RhcnRPZmZzZXQsIGVuZE9mZnNldF0pID0+IHtcclxuICAgICAgICBpZiAoKHYgYXMgYW55KSA9PT0gVklFV1BPUlQpIHtcclxuICAgICAgICAgIGNvbnN0IGlzVmVydGljYWwgPSB0aGlzLmlzVmVydGljYWwsIHZpZXdwb3J0Qm91bmRzID0gYm91bmRzLFxyXG4gICAgICAgICAgICByZXN1bHQgPSAoaXNWZXJ0aWNhbCA/ICh2aWV3cG9ydEJvdW5kcz8uaGVpZ2h0ID8/IDApIDogKHZpZXdwb3J0Qm91bmRzPy53aWR0aCA/PyAwKSkgLSBzdGFydE9mZnNldCAtIGVuZE9mZnNldDtcclxuICAgICAgICAgIHJldHVybiBvZihyZXN1bHQgPCBtaW4gPyBtaW4gOiAocmVzdWx0ID4gbWF4ID8gbWF4IDogcmVzdWx0KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvZih2IDwgbWluID8gbWluIDogKHYgPiBtYXggPyBtYXggOiB2KSk7XHJcbiAgICAgIH0pLFxyXG4gICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgdGhpcy5fJGFjdHVhbEl0ZW1TaXplLm5leHQodik7XHJcbiAgICAgICAgdGhpcy5fc2VydmljZS5pdGVtU2l6ZSA9IHY7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICBjb25zdCAkYWN0dWFsSXRlbVNpemUgPSB0aGlzLiRhY3R1YWxJdGVtU2l6ZSxcclxuICAgICAgJGFjdHVhbEl0ZW1zID0gdGhpcy5fJGFjdHVhbEl0ZW1zLmFzT2JzZXJ2YWJsZSgpLnBpcGUoXHJcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgKTtcclxuXHJcbiAgICB0aGlzLl9zZXJ2aWNlLiRmb2N1c0l0ZW0ucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcChwYXJhbXMgPT4ge1xyXG4gICAgICAgIGNvbnN0IHsgZWxlbWVudCwgcG9zaXRpb24sIGFsaWduLCBiZWhhdmlvciB9ID0gcGFyYW1zO1xyXG4gICAgICAgIHRoaXMuZm9jdXNJdGVtKGVsZW1lbnQsIHBvc2l0aW9uLCBhbGlnbiwgYmVoYXZpb3IpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgY29uc3QgJGxpc3QgPSB0aGlzLiRsaXN0LnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBmaWx0ZXIodiA9PiAhIXYpLFxyXG4gICAgICBtYXAodiA9PiB2IS5uYXRpdmVFbGVtZW50KSxcclxuICAgICAgdGFrZSgxKSxcclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgcHJldmVudEtleWJvYXJkRXZlbnQgPSAoZXZlbnQ6IEtleWJvYXJkRXZlbnQsIGlzVmVydGljYWw6IGJvb2xlYW4pID0+IHtcclxuICAgICAgY29uc3Qgc2Nyb2xsZXIgPSB0aGlzLl9zY3JvbGxlckNvbXBvbmVudDtcclxuICAgICAgaWYgKCEhc2Nyb2xsZXIpIHtcclxuICAgICAgICBjb25zdCBzY3JvbGxTdGFydE9mZnNldCA9IHRoaXMuXyRhY3R1YWxTY3JvbGxTdGFydE9mZnNldC5nZXRWYWx1ZSgpLCBzY3JvbGxhYmxlID0gc2Nyb2xsZXIuc2Nyb2xsYWJsZSA/PyBmYWxzZSxcclxuICAgICAgICAgIHNjcm9sbFNpemUgPSBpc1ZlcnRpY2FsID8gc2Nyb2xsZXIuc2Nyb2xsVG9wIDogc2Nyb2xsZXIuc2Nyb2xsTGVmdCxcclxuICAgICAgICAgIHNjcm9sbFdlaWdodCA9IGlzVmVydGljYWwgPyBzY3JvbGxlci5zY3JvbGxIZWlnaHQgOiBzY3JvbGxlci5zY3JvbGxXaWR0aDtcclxuICAgICAgICBpZiAoc2Nyb2xsYWJsZSB8fCBzY3JvbGxTaXplIDw9IHNjcm9sbFN0YXJ0T2Zmc2V0IHx8IHNjcm9sbFNpemUgPj0gc2Nyb2xsV2VpZ2h0KSB7XHJcbiAgICAgICAgICBpZiAoISFldmVudCAmJiBldmVudC5jYW5jZWxhYmxlKSB7XHJcbiAgICAgICAgICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAkbGlzdC5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZmlsdGVyKGVsZW1lbnQgPT4gISFlbGVtZW50KSxcclxuICAgICAgc3dpdGNoTWFwKGVsZW1lbnQgPT4ge1xyXG4gICAgICAgIHJldHVybiBmcm9tRXZlbnQ8S2V5Ym9hcmRFdmVudD4oZWxlbWVudCwgRVZFTlRfS0VZX0RPV04pLnBpcGUoXHJcbiAgICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICAgIHN3aXRjaE1hcChlID0+IHtcclxuICAgICAgICAgICAgc3dpdGNoIChlLmtleSkge1xyXG4gICAgICAgICAgICAgIGNhc2UgS0VZX0FSUl9MRUZUOlxyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzVmVydGljYWwpIHtcclxuICAgICAgICAgICAgICAgICAgcHJldmVudEtleWJvYXJkRXZlbnQoZSwgdGhpcy5pc1ZlcnRpY2FsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgIGNhc2UgS0VZX0FSUl9VUDpcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzVmVydGljYWwpIHtcclxuICAgICAgICAgICAgICAgICAgcHJldmVudEtleWJvYXJkRXZlbnQoZSwgdGhpcy5pc1ZlcnRpY2FsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgIGNhc2UgS0VZX0FSUl9SSUdIVDpcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc1ZlcnRpY2FsKSB7XHJcbiAgICAgICAgICAgICAgICAgIHByZXZlbnRLZXlib2FyZEV2ZW50KGUsIHRoaXMuaXNWZXJ0aWNhbCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICBjYXNlIEtFWV9BUlJfRE9XTjpcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzVmVydGljYWwpIHtcclxuICAgICAgICAgICAgICAgICAgcHJldmVudEtleWJvYXJkRXZlbnQoZSwgdGhpcy5pc1ZlcnRpY2FsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcclxuICAgICAgICAgIH0pLFxyXG4gICAgICAgICk7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICBjb25zdCAkc2Nyb2xsYmFyVGhpY2tuZXNzID0gdGhpcy4kc2Nyb2xsYmFyVGhpY2tuZXNzO1xyXG4gICAgJHNjcm9sbGJhclRoaWNrbmVzcy5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZmlsdGVyKHYgPT4gISF2KSxcclxuICAgICAgdGFwKHNjcm9sbGJhclRoaWNrbmVzcyA9PiB7XHJcbiAgICAgICAgdGhpcy5fc2VydmljZS5zY3JvbGxCYXJTaXplID0gc2Nyb2xsYmFyVGhpY2tuZXNzO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgdGhpcy4kZmlyZVVwZGF0ZU5leHRGcmFtZS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZGVib3VuY2VUaW1lKDApLFxyXG4gICAgICB0YXAodXNlckFjdGlvbiA9PiB7XHJcbiAgICAgICAgdGhpcy5fJGZpcmVVcGRhdGUubmV4dCh1c2VyQWN0aW9uKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIGNvbnN0ICRzY3JvbGxUb0l0ZW0gPSB0aGlzLiRzY3JvbGxUby5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICksXHJcbiAgICAgICRtb3VzZURvd24gPSBmcm9tRXZlbnQodGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCBNT1VTRV9ET1dOKS5waXBlKFxyXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICApLFxyXG4gICAgICAkdG91Y2hTdGFydCA9IGZyb21FdmVudCh0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsIFRPVUNIX1NUQVJUKS5waXBlKFxyXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICApO1xyXG5cclxuICAgIGZyb21FdmVudDxLZXlib2FyZEV2ZW50Pihkb2N1bWVudCwgS0VZX0RPV04pLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBmaWx0ZXIoZSA9PiBlLmtleSA9PT0gS0VZX1RBQiksXHJcbiAgICAgIHN3aXRjaE1hcChlID0+IHtcclxuICAgICAgICByZXR1cm4gZnJvbUV2ZW50KHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgRk9DVVMpLnBpcGUoXHJcbiAgICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICAgIGRlbGF5KDApLFxyXG4gICAgICAgICAgdGFrZVVudGlsKCRzY3JvbGxUb0l0ZW0pLFxyXG4gICAgICAgICAgdGFrZVVudGlsKCRtb3VzZURvd24pLFxyXG4gICAgICAgICAgdGFrZVVudGlsKCR0b3VjaFN0YXJ0KSxcclxuICAgICAgICAgIHRhcChlID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fc2VydmljZS5mb2N1c0ZpcnN0RWxlbWVudCgpO1xyXG4gICAgICAgICAgfSksXHJcbiAgICAgICAgKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIHRoaXMuX3NlcnZpY2UuJHNjcm9sbFRvU3RhcnQucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcChvcHRpb25zID0+IHtcclxuICAgICAgICB0aGlzLnNjcm9sbFRvU3RhcnQobnVsbCwgb3B0aW9ucyk7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICB0aGlzLl9zZXJ2aWNlLiRzY3JvbGxUby5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZmlsdGVyKHYgPT4gISF2KSxcclxuICAgICAgdGFwKHBhcmFtcyA9PiB7XHJcbiAgICAgICAgY29uc3QgeyBpZCwgY2IsIG9wdGlvbnMgfSA9IHBhcmFtcyE7XHJcbiAgICAgICAgdGhpcy5zY3JvbGxUbyhpZCwgY2IsIG9wdGlvbnMpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgdGhpcy5fc2VydmljZS4kc2Nyb2xsVG9FbmQucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcChvcHRpb25zID0+IHtcclxuICAgICAgICB0aGlzLnNjcm9sbFRvRW5kKG51bGwsIG9wdGlvbnMpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgdGhpcy4kbGFuZ1RleHREaXIucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl9zZXJ2aWNlLmxhbmdUZXh0RGlyID0gdjtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIHRoaXMuJGNsaWNrRGlzdGFuY2UucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl9zZXJ2aWNlLmNsaWNrRGlzdGFuY2UgPSB2O1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgY29tYmluZUxhdGVzdChbdGhpcy4kc25hcFNjcm9sbFRvU3RhcnQsIHRoaXMuJGlzSW5maW5pdHldKS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKChbc25hcFNjcm9sbFRvU3RhcnQsIGlzSW5maW5pdHldKSA9PiB7XHJcbiAgICAgICAgdGhpcy5fJGFjdHVhbFNuYXBTY3JvbGxUb1N0YXJ0Lm5leHQoaXNJbmZpbml0eSA/IGZhbHNlIDogc25hcFNjcm9sbFRvU3RhcnQpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgY29tYmluZUxhdGVzdChbdGhpcy4kc25hcFNjcm9sbFRvRW5kLCB0aGlzLiRpc0luZmluaXR5XSkucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcCgoW3NuYXBTY3JvbGxUb0VuZCwgaXNJbmZpbml0eV0pID0+IHtcclxuICAgICAgICB0aGlzLl8kYWN0dWFsU25hcFNjcm9sbFRvRW5kLm5leHQoaXNJbmZpbml0eSA/IGZhbHNlIDogc25hcFNjcm9sbFRvRW5kKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIGNvbnN0ICR2aWV3SW5pdCA9IHRoaXMuJHZpZXdJbml0LFxyXG4gICAgICAkcHJlcmVuZGVyQ29udGFpbmVyID0gb2YodGhpcy5fcHJlcmVuZGVyKTtcclxuXHJcbiAgICBjb25zdCAkcHJlcmVuZGVyID0gJHZpZXdJbml0LnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBmaWx0ZXIodiA9PiAhIXYpLFxyXG4gICAgICBzd2l0Y2hNYXAodiA9PiB7XHJcbiAgICAgICAgcmV0dXJuICRwcmVyZW5kZXJDb250YWluZXIucGlwZShcclxuICAgICAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICAgICAgZmlsdGVyKHYgPT4gISF2KSxcclxuICAgICAgICAgIHN3aXRjaE1hcCh2ID0+IHYhLiRyZW5kZXIpLFxyXG4gICAgICAgICk7XHJcbiAgICAgIH0pLFxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCAkZmlyZVVwZGF0ZSA9IHRoaXMuJGZpcmVVcGRhdGU7XHJcbiAgICAkZmlyZVVwZGF0ZS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHVzZXJBY3Rpb24gPT4ge1xyXG4gICAgICAgIGhhc1VzZXJBY3Rpb24gPSB1c2VyQWN0aW9uO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgY29uc3QgJHVwZGF0ZSA9IHRoaXMuJHVwZGF0ZSxcclxuICAgICAgcmVuZGVyU3RhYmlsaXplciA9IChvcHRpb25zPzogSVJlbmRlclN0YWJpbGl6ZXJPcHRpb25zKSA9PiB7XHJcbiAgICAgICAgbGV0IHJlbmRlclN0YWJpbGl6ZXJQcmV2U2Nyb2xsU3RhdGVWZXJzaW9uID0gRU1QVFlfU0NST0xMX1NUQVRFX1ZFUlNJT04sXHJcbiAgICAgICAgICByZW5kZXJTdGFiaWxpemVyVXBkYXRlSXRlcmF0aW9ucyA9IDA7XHJcbiAgICAgICAgY29uc3QgcHJlcGFyZUl0ZXJhdGlvbnMgPSBvcHRpb25zPy5wcmVwYXJlSXRlcmF0aW9ucyA/PyBQUkVQQVJFX0lURVJBVElPTlMsXHJcbiAgICAgICAgICBwcmVwYXJlUmV1cGRhdGVMZW5ndGggPSBvcHRpb25zPy5wcmVwYXJlUmV1cGRhdGVMZW5ndGggPz8gUFJFUEFSQVRJT05fUkVVUERBVEVfTEVOR1RIO1xyXG4gICAgICAgIHJldHVybiBvZihudWxsKS5waXBlKFxyXG4gICAgICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgICAgICBzd2l0Y2hNYXAoKCkgPT4ge1xyXG4gICAgICAgICAgICByZW5kZXJTdGFiaWxpemVyUHJldlNjcm9sbFN0YXRlVmVyc2lvbiA9IEVNUFRZX1NDUk9MTF9TVEFURV9WRVJTSU9OO1xyXG4gICAgICAgICAgICByZW5kZXJTdGFiaWxpemVyVXBkYXRlSXRlcmF0aW9ucyA9IDA7XHJcbiAgICAgICAgICAgIHRoaXMuX2NhY2hlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICByZXR1cm4gJHVwZGF0ZS5waXBlKFxyXG4gICAgICAgICAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICAgICAgICAgIGRlYm91bmNlVGltZSgwKSxcclxuICAgICAgICAgICAgICBzd2l0Y2hNYXAodiA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoKChyZW5kZXJTdGFiaWxpemVyUHJldlNjcm9sbFN0YXRlVmVyc2lvbiA9PT0gRU1QVFlfU0NST0xMX1NUQVRFX1ZFUlNJT04pIHx8IChyZW5kZXJTdGFiaWxpemVyUHJldlNjcm9sbFN0YXRlVmVyc2lvbiAhPT0gdikpICYmXHJcbiAgICAgICAgICAgICAgICAgIChyZW5kZXJTdGFiaWxpemVyVXBkYXRlSXRlcmF0aW9ucyA8IHByZXBhcmVJdGVyYXRpb25zKSkge1xyXG4gICAgICAgICAgICAgICAgICBpZiAodiAhPT0gRU1QVFlfU0NST0xMX1NUQVRFX1ZFUlNJT04pIHtcclxuICAgICAgICAgICAgICAgICAgICByZW5kZXJTdGFiaWxpemVyUHJldlNjcm9sbFN0YXRlVmVyc2lvbiA9IHY7XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgdGhpcy5fJGZpcmVVcGRhdGUubmV4dChmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgIHJldHVybiBvZihmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyU3RhYmlsaXplclByZXZTY3JvbGxTdGF0ZVZlcnNpb24gPT09IHYpIHtcclxuICAgICAgICAgICAgICAgICAgaWYgKHJlbmRlclN0YWJpbGl6ZXJVcGRhdGVJdGVyYXRpb25zIDwgcHJlcGFyZVJldXBkYXRlTGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyU3RhYmlsaXplclVwZGF0ZUl0ZXJhdGlvbnMrKztcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl8kZmlyZVVwZGF0ZS5uZXh0KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZW5kZXJTdGFiaWxpemVyUHJldlNjcm9sbFN0YXRlVmVyc2lvbiA9IHY7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gb2YodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgfSksXHJcbiAgICAgICAgICAgICAgZmlsdGVyKHYgPT4gISF2KSxcclxuICAgICAgICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICAgICAgICApXHJcbiAgICAgICAgICB9KSxcclxuICAgICAgICApXHJcbiAgICAgIH07XHJcbiAgICBjb25zdCAkaW5pdGlhbFJlbmRlclN0YWJpbGl6ZXIgPSByZW5kZXJTdGFiaWxpemVyKHtcclxuICAgICAgcHJlcGFyZUl0ZXJhdGlvbnM6IFBSRVBBUkVfSVRFUkFUSU9OUyxcclxuICAgICAgcHJlcGFyZVJldXBkYXRlTGVuZ3RoOiBQUkVQQVJBVElPTl9SRVVQREFURV9MRU5HVEgsXHJcbiAgICB9KSxcclxuICAgICAgJHVwZGF0ZUl0ZW1zUmVuZGVyU3RhYmlsaXplciA9IHJlbmRlclN0YWJpbGl6ZXIoe1xyXG4gICAgICAgIHByZXBhcmVJdGVyYXRpb25zOiBQUkVQQVJFX0lURVJBVElPTlNfRk9SX1VQREFURV9JVEVNUyxcclxuICAgICAgICBwcmVwYXJlUmV1cGRhdGVMZW5ndGg6IFBSRVBBUkFUSU9OX1JFVVBEQVRFX0xFTkdUSF9GT1JfVVBEQVRFX0lURU1TLFxyXG4gICAgICB9KSxcclxuICAgICAgJGNodW5rTG9hZGluZ1JlbmRlclN0YWJpbGl6ZXIgPSByZW5kZXJTdGFiaWxpemVyKHtcclxuICAgICAgICBwcmVwYXJlSXRlcmF0aW9uczogUFJFUEFSRV9JVEVSQVRJT05TX0ZPUl9VUERBVEVfSVRFTVMsXHJcbiAgICAgICAgcHJlcGFyZVJldXBkYXRlTGVuZ3RoOiBQUkVQQVJBVElPTl9SRVVQREFURV9MRU5HVEhfRk9SX1VQREFURV9JVEVNUyxcclxuICAgICAgfSksXHJcbiAgICAgICRjb2xsYXBzZUl0ZW1zUmVuZGVyU3RhYmlsaXplciA9IHJlbmRlclN0YWJpbGl6ZXIoe1xyXG4gICAgICAgIHByZXBhcmVJdGVyYXRpb25zOiBQUkVQQVJFX0lURVJBVElPTlNfRk9SX0NPTExBUFNFX0lURU1TLFxyXG4gICAgICAgIHByZXBhcmVSZXVwZGF0ZUxlbmd0aDogUFJFUEFSQVRJT05fUkVVUERBVEVfTEVOR1RIX0ZPUl9DT0xMQVBTRV9JVEVNUyxcclxuICAgICAgfSksXHJcbiAgICAgICRpdGVtQ29uZmlnTWFwID0gdGhpcy4kaXRlbUNvbmZpZ01hcC5waXBlKFxyXG4gICAgICAgIG1hcCh2ID0+ICF2ID8ge30gOiB2KSxcclxuICAgICAgKSxcclxuICAgICAgJGRpdmlkZXMgPSB0aGlzLiRkaXZpZGVzLFxyXG4gICAgICAkZHluYW1pY1NpemUgPSB0aGlzLiRkeW5hbWljU2l6ZSxcclxuICAgICAgJHNuYXBTY3JvbGxUb1N0YXJ0ID0gdGhpcy5fJGFjdHVhbFNuYXBTY3JvbGxUb1N0YXJ0LmFzT2JzZXJ2YWJsZSgpLFxyXG4gICAgICAkc25hcFNjcm9sbFRvRW5kID0gdGhpcy5fJGFjdHVhbFNuYXBTY3JvbGxUb0VuZC5hc09ic2VydmFibGUoKSxcclxuICAgICAgJHdhaXRGb3JQcmVwYXJhdGlvbiA9IHRoaXMuJHdhaXRGb3JQcmVwYXJhdGlvbixcclxuICAgICAgJGl0ZW1zID0gdGhpcy4kaXRlbXM7XHJcblxyXG4gICAgY29tYmluZUxhdGVzdChbJHZpZXdJbml0LCAkcHJlcmVuZGVyQ29udGFpbmVyLCAkZGl2aWRlcywgJGR5bmFtaWNTaXplLCAkc25hcFNjcm9sbFRvU3RhcnQsICRzbmFwU2Nyb2xsVG9FbmQsICR3YWl0Rm9yUHJlcGFyYXRpb25dKS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgZmlsdGVyKChbaW5pdCwgcHJlcmVuZGVyQ29udGFpbmVyXSkgPT4gISFpbml0ICYmICEhcHJlcmVuZGVyQ29udGFpbmVyKSxcclxuICAgICAgZGVib3VuY2VUaW1lKDApLFxyXG4gICAgICBzd2l0Y2hNYXAoKFssIHByZXJlbmRlckNvbnRhaW5lciwgZGl2aWRlcywgZHluYW1pY1NpemUsIHNuYXBTY3JvbGxUb1N0YXJ0LCBzbmFwU2Nyb2xsVG9FbmQsIHdhaXRGb3JQcmVwYXJhdGlvbl0pID0+IHtcclxuICAgICAgICBpZiAoISFkeW5hbWljU2l6ZSAmJiAhc25hcFNjcm9sbFRvU3RhcnQgJiYgISFzbmFwU2Nyb2xsVG9FbmQgJiYgISF3YWl0Rm9yUHJlcGFyYXRpb24pIHtcclxuICAgICAgICAgIGNvbnN0ICRjb2xsZWN0aW9uID0gKGRpdmlkZXMgPiAxID8gJGFjdHVhbEl0ZW1zIDogJGl0ZW1zKTtcclxuICAgICAgICAgIHJldHVybiAkY29sbGVjdGlvbi5waXBlKFxyXG4gICAgICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKHAsIGMpID0+IHtcclxuICAgICAgICAgICAgICBjb25zdCBwTGVuZ3RoID0gcD8ubGVuZ3RoID8/IDAsIGNMZW5ndGggPSBjPy5sZW5ndGggPz8gMDtcclxuICAgICAgICAgICAgICByZXR1cm4gISgoY0xlbmd0aCA+IDApIHx8IChwTGVuZ3RoICE9PSBjTGVuZ3RoICYmIChwTGVuZ3RoID09PSAwIHx8IGNMZW5ndGggPT09IDApKSk7XHJcbiAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgICB0YXAoaXRlbXMgPT4ge1xyXG4gICAgICAgICAgICAgIHRoaXMuX3RyYWNrQm94LnJlc2V0Q29sbGVjdGlvbihpdGVtcywgdGhpcy5hY3R1YWxJdGVtU2l6ZSk7XHJcbiAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgICBzd2l0Y2hNYXAoaSA9PiBvZigoaSA/PyBbXSkubGVuZ3RoID4gMCkpLFxyXG4gICAgICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICAgICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgICAgICAgaWYgKCF2KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNhY2hlQ2xlYW4oKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2xlYW51cCgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fcmVhZHlGb3JTaG93ID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXNuYXBTY3JvbGxUb1N0YXJ0ICYmIHNuYXBTY3JvbGxUb0VuZCkge1xyXG4gICAgICAgICAgICAgICAgICB0aGlzLl90cmFja0JveC5pc1Njcm9sbEVuZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzY3JvbGxlckNvbXBvbmVudCA9IHRoaXMuX3Njcm9sbGVyQ29tcG9uZW50O1xyXG4gICAgICAgICAgICAgICAgaWYgKCEhc2Nyb2xsZXJDb21wb25lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgc2Nyb2xsZXJDb21wb25lbnQucHJlcGFyZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgc2Nyb2xsZXJDb21wb25lbnQuc3RvcFNjcm9sbGluZygpO1xyXG4gICAgICAgICAgICAgICAgICBzY3JvbGxlckNvbXBvbmVudC5yZWZyZXNoKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLl8kY2xhc3Nlcy5uZXh0KHsgcHJlcGFyZWQ6IHRydWUgfSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl8kc2hvdy5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl90cmFja0JveC5pc1Njcm9sbEVuZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB3YWl0Rm9yUHJlcGFyYXRpb24gPSB0aGlzLndhaXRGb3JQcmVwYXJhdGlvbjtcclxuICAgICAgICAgICAgICAgIGlmICh3YWl0Rm9yUHJlcGFyYXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucHJlcmVuZGVyYWJsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHByZXJlbmRlckNvbnRhaW5lciEub24odGhpcy5pdGVtcyk7XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMuXyRjbGFzc2VzLm5leHQoeyBwcmVwYXJlZDogZmFsc2UgfSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl8kc2hvdy5uZXh0KGZhbHNlKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgICBzd2l0Y2hNYXAodiA9PiB7XHJcbiAgICAgICAgICAgICAgaWYgKCF2KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcmVyZW5kZXJhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgIHByZXJlbmRlckNvbnRhaW5lciEub2ZmKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gb2YoZmFsc2UpO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBjb25zdCB3YWl0Rm9yUHJlcGFyYXRpb24gPSB0aGlzLndhaXRGb3JQcmVwYXJhdGlvbjtcclxuICAgICAgICAgICAgICBpZiAod2FpdEZvclByZXBhcmF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl90cmFja0JveC5pc1Njcm9sbEVuZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcmVyZW5kZXJhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuX2NhY2hlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICBwcmVyZW5kZXJDb250YWluZXIhLm9uKHRoaXMuaXRlbXMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICRpbml0aWFsUmVuZGVyU3RhYmlsaXplci5waXBlKFxyXG4gICAgICAgICAgICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICAgICAgICAgICAgdGFrZSgxKSxcclxuICAgICAgICAgICAgICAgICAgdGFwKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmFja0JveC5pc1Njcm9sbEVuZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucHJlcmVuZGVyYWJsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgcHJlcmVuZGVyQ29udGFpbmVyIS5vZmYoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVhZHlGb3JTaG93ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzY3JvbGxlckNvbXBvbmVudCA9IHRoaXMuX3Njcm9sbGVyQ29tcG9uZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghIXNjcm9sbGVyQ29tcG9uZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxlckNvbXBvbmVudC5wcmVwYXJlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxlckNvbXBvbmVudC5yZWZyZXNoKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuXyRjbGFzc2VzLm5leHQoeyBwcmVwYXJlZDogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl8kc2hvdy5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICB9KSxcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGlmICh0aGlzLnByZXJlbmRlcmFibGUpIHtcclxuICAgICAgICAgICAgICAgIHByZXJlbmRlckNvbnRhaW5lciEub2ZmKCk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIHRoaXMuX3JlYWR5Rm9yU2hvdyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgaWYgKCFzbmFwU2Nyb2xsVG9TdGFydCAmJiBzbmFwU2Nyb2xsVG9FbmQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RyYWNrQm94LmlzU2Nyb2xsRW5kID0gdHJ1ZTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgY29uc3Qgc2Nyb2xsZXJDb21wb25lbnQgPSB0aGlzLl9zY3JvbGxlckNvbXBvbmVudDtcclxuICAgICAgICAgICAgICBpZiAoISFzY3JvbGxlckNvbXBvbmVudCkge1xyXG4gICAgICAgICAgICAgICAgc2Nyb2xsZXJDb21wb25lbnQucHJlcGFyZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgc2Nyb2xsZXJDb21wb25lbnQucmVmcmVzaCgpO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB0aGlzLl8kY2xhc3Nlcy5uZXh0KHsgcHJlcGFyZWQ6IHRydWUgfSk7XHJcbiAgICAgICAgICAgICAgdGhpcy5fJHNob3cubmV4dCh0cnVlKTtcclxuICAgICAgICAgICAgICByZXR1cm4gb2YoZmFsc2UpO1xyXG4gICAgICAgICAgICB9KSxcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHByZXJlbmRlckNvbnRhaW5lciEub2ZmKCk7XHJcbiAgICAgICAgICBjb25zdCAkY29sbGVjdGlvbiA9IChkaXZpZGVzID4gMSA/ICRhY3R1YWxJdGVtcyA6ICRpdGVtcyk7XHJcbiAgICAgICAgICByZXR1cm4gJGNvbGxlY3Rpb24ucGlwZShcclxuICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgICAgICAgIHRhcChpdGVtcyA9PiB7XHJcbiAgICAgICAgICAgICAgaWYgKCFpdGVtcyB8fCBpdGVtcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2FjaGVDbGVhbigpO1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Nyb2xsZXJDb21wb25lbnQgPSB0aGlzLl9zY3JvbGxlckNvbXBvbmVudDtcclxuICAgICAgICAgICAgICAgIGlmICghIXNjcm9sbGVyQ29tcG9uZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgIHNjcm9sbGVyQ29tcG9uZW50LnByZXBhcmVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLl8kY2xhc3Nlcy5uZXh0KHsgcHJlcGFyZWQ6IGZhbHNlIH0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fJHNob3cubmV4dChmYWxzZSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIHRoaXMuX3RyYWNrQm94LnJlc2V0Q29sbGVjdGlvbihpdGVtcywgdGhpcy5hY3R1YWxJdGVtU2l6ZSk7XHJcbiAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgICBzd2l0Y2hNYXAoaSA9PiBvZigoaSA/PyBbXSkubGVuZ3RoID4gMCkpLFxyXG4gICAgICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICAgICAgICBmaWx0ZXIodiA9PiAhIXYpLFxyXG4gICAgICAgICAgICB0YXAoKCkgPT4ge1xyXG4gICAgICAgICAgICAgIHRoaXMuX3JlYWR5Rm9yU2hvdyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgaWYgKHNuYXBTY3JvbGxUb1N0YXJ0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl90cmFja0JveC5pc1Njcm9sbFN0YXJ0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNuYXBTY3JvbGxUb0VuZCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdHJhY2tCb3guaXNTY3JvbGxFbmQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBjb25zdCBzY3JvbGxlckNvbXBvbmVudCA9IHRoaXMuX3Njcm9sbGVyQ29tcG9uZW50O1xyXG4gICAgICAgICAgICAgIGlmICghIXNjcm9sbGVyQ29tcG9uZW50KSB7XHJcbiAgICAgICAgICAgICAgICBzY3JvbGxlckNvbXBvbmVudC5wcmVwYXJlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBzY3JvbGxlckNvbXBvbmVudC5yZWZyZXNoKCk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIHRoaXMuXyRjbGFzc2VzLm5leHQoeyBwcmVwYXJlZDogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgICB0aGlzLl8kc2hvdy5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgICAgIHRoaXMuXyRmaXJlVXBkYXRlLm5leHQoZmFsc2UpO1xyXG4gICAgICAgICAgICB9KSxcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgJGl0ZW1zLnBpcGUoXHJcbiAgICAgIG1hcCh2ID0+IHY/Lmxlbmd0aCA+IDApLFxyXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZmlsdGVyKHYgPT4gISF2KSxcclxuICAgICAgdGFwKCgpID0+IHtcclxuICAgICAgICB0aGlzLl9jYWNoZWQgPSBmYWxzZTtcclxuICAgICAgfSksXHJcbiAgICAgIHN3aXRjaE1hcCgoKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuICRwcmVyZW5kZXIucGlwZShcclxuICAgICAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICAgICAgZGVib3VuY2VUaW1lKDApLFxyXG4gICAgICAgICAgdGFrZSgxKSxcclxuICAgICAgICAgIHRhcChjYWNoZSA9PiB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5fcmVhZHlGb3JTaG93KSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5fdHJhY2tCb3gucmVmcmVzaENhY2hlKGNhY2hlKTtcclxuICAgICAgICAgICAgICB0aGlzLl9jYWNoZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgIHRoaXMuXyRmaXJlVXBkYXRlLm5leHQodHJ1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pLFxyXG4gICAgICAgICk7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICB0aGlzLl9zZXJ2aWNlLiRmb2N1c2VkSWQucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl8kZm9jdXNlZEVsZW1lbnQubmV4dCh2ID8/IG51bGwpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgJGxpc3QucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGZpbHRlcihlbGVtZW50ID0+ICEhZWxlbWVudCksXHJcbiAgICAgIHRhcChlbGVtZW50ID0+IHtcclxuICAgICAgICB0aGlzLl9zZXJ2aWNlLmxpc3RFbGVtZW50ID0gZWxlbWVudDtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIGNvbnN0ICRkZWZhdWx0SXRlbVZhbHVlID0gdGhpcy4kZGVmYXVsdEl0ZW1WYWx1ZSxcclxuICAgICAgJHNlbGVjdEJ5Q2xpY2sgPSB0aGlzLiRzZWxlY3RCeUNsaWNrLFxyXG4gICAgICAkY29sbGFwc2VCeUNsaWNrID0gdGhpcy4kY29sbGFwc2VCeUNsaWNrLFxyXG4gICAgICAkaXNTY3JvbGxTdGFydCA9IHRoaXMuXyRpc1Njcm9sbFN0YXJ0LmFzT2JzZXJ2YWJsZSgpLFxyXG4gICAgICAkaXNTY3JvbGxGaW5pc2hlZCA9IHRoaXMuXyRpc1Njcm9sbEVuZC5hc09ic2VydmFibGUoKSxcclxuICAgICAgJGlzVmVydGljYWwgPSB0aGlzLiRkaXJlY3Rpb24ucGlwZShcclxuICAgICAgICBtYXAodiA9PiB0aGlzLmdldElzVmVydGljYWwodiB8fCBERUZBVUxUX0RJUkVDVElPTikpLFxyXG4gICAgICApO1xyXG5cclxuICAgICRzbmFwU2Nyb2xsVG9TdGFydC5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX3NlcnZpY2Uuc25hcFNjcm9sbFRvU3RhcnQgPSB2O1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgJHNuYXBTY3JvbGxUb0VuZC5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX3NlcnZpY2Uuc25hcFNjcm9sbFRvRW5kID0gdjtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRpc1ZlcnRpY2FsLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgdGhpcy5fc2VydmljZS5pc1ZlcnRpY2FsID0gdjtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRkeW5hbWljU2l6ZS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX3NlcnZpY2UuZHluYW1pYyA9IHY7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAkZGVmYXVsdEl0ZW1WYWx1ZS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX3NlcnZpY2UuZGVmYXVsdEl0ZW1WYWx1ZSA9IHY7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAkc2Nyb2xsU3RhcnRPZmZzZXQucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl90cmFja0JveC5zY3JvbGxTdGFydE9mZnNldCA9IHRoaXMuX3NlcnZpY2Uuc2Nyb2xsU3RhcnRPZmZzZXQgPSB2O1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgJHNjcm9sbEVuZE9mZnNldC5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX3RyYWNrQm94LnNjcm9sbEVuZE9mZnNldCA9IHRoaXMuX3NlcnZpY2Uuc2Nyb2xsRW5kT2Zmc2V0ID0gdjtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRpc1Njcm9sbFN0YXJ0LnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBza2lwKDEpLFxyXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICBkZWJvdW5jZVRpbWUoMCksXHJcbiAgICAgIGZpbHRlcih2ID0+ICEhdiAmJiB0aGlzLl9yZWFkeUZvclNob3cpLFxyXG4gICAgICB0YXAoKCkgPT4ge1xyXG4gICAgICAgIGlmICh0aGlzLl9zY3JvbGxlckNvbXBvbmVudD8uc2Nyb2xsYWJsZSkge1xyXG4gICAgICAgICAgdGhpcy5vblNjcm9sbFJlYWNoU3RhcnQuZW1pdCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRpc1Njcm9sbEZpbmlzaGVkLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBza2lwKDEpLFxyXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICBkZWJvdW5jZVRpbWUoMCksXHJcbiAgICAgIGZpbHRlcih2ID0+ICEhdiAmJiB0aGlzLl9yZWFkeUZvclNob3cpLFxyXG4gICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuX3Njcm9sbGVyQ29tcG9uZW50Py5zY3JvbGxhYmxlKSB7XHJcbiAgICAgICAgICB0aGlzLm9uU2Nyb2xsUmVhY2hFbmQuZW1pdCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRzZWxlY3RCeUNsaWNrLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgdGhpcy5fc2VydmljZS5zZWxlY3RCeUNsaWNrID0gdjtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRjb2xsYXBzZUJ5Q2xpY2sucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl9zZXJ2aWNlLmNvbGxhcHNlQnlDbGljayA9IHY7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAkdHJhY2tCeS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX3RyYWNrQm94LnRyYWNraW5nUHJvcGVydHlOYW1lID0gdjtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRkaXZpZGVzLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgdGhpcy5fdHJhY2tCb3guZGl2aWRlcyA9IHY7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICBjb21iaW5lTGF0ZXN0KFt0aGlzLiRhbGlnbm1lbnQsIHRoaXMuJGlzSW5maW5pdHldKS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKChbYWxpZ25tZW50LCBpc0luZmluaXR5XSkgPT4ge1xyXG4gICAgICAgIHRoaXMuXyRhY3R1YWxBbGlnbm1lbnQubmV4dChpc0luZmluaXR5ID8gQWxpZ25tZW50cy5DRU5URVIgOiBhbGlnbm1lbnQpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgY29tYmluZUxhdGVzdChbdGhpcy4kc2Nyb2xsYmFyRW5hYmxlZCwgdGhpcy4kaXNJbmZpbml0eV0pLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBkZWJvdW5jZVRpbWUoMCksXHJcbiAgICAgIHRhcCgoW3Njcm9sbGJhckVuYWJsZWQsIGlzSW5maW5pdHldKSA9PiB7XHJcbiAgICAgICAgdGhpcy5fJGFjdHVhbFNjcm9sbGJhckVuYWJsZWQubmV4dChpc0luZmluaXR5ID8gZmFsc2UgOiBzY3JvbGxiYXJFbmFibGVkKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIGNvbnN0ICRhbGlnbm1lbnQgPSB0aGlzLiRhY3R1YWxBbGlnbm1lbnQsXHJcbiAgICAgICRwcmVjYWxjdWxhdGVkU2Nyb2xsU3RhcnRPZmZzZXQgPSB0aGlzLl8kcHJlY2FsY3VsYXRlZFNjcm9sbFN0YXJ0T2Zmc2V0LmFzT2JzZXJ2YWJsZSgpLFxyXG4gICAgICAkcHJlY2FsY3VsYXRlZFNjcm9sbEVuZE9mZnNldCA9IHRoaXMuXyRwcmVjYWxjdWxhdGVkU2Nyb2xsRW5kT2Zmc2V0LmFzT2JzZXJ2YWJsZSgpLFxyXG4gICAgICAkbGlzdEJvdW5kcyA9IHRoaXMuXyRsaXN0Qm91bmRzLmFzT2JzZXJ2YWJsZSgpLnBpcGUoXHJcbiAgICAgICAgZmlsdGVyKGIgPT4gISFiKSxcclxuICAgICAgKSwgJHNjcm9sbFNpemUgPSB0aGlzLl8kc2Nyb2xsU2l6ZS5hc09ic2VydmFibGUoKSxcclxuICAgICAgJGJ1ZmZlclNpemUgPSB0aGlzLiRidWZmZXJTaXplLnBpcGUoXHJcbiAgICAgICAgbWFwKHYgPT4gdiA8IDAgPyBERUZBVUxUX0JVRkZFUl9TSVpFIDogdiksXHJcbiAgICAgICksXHJcbiAgICAgICRtYXhCdWZmZXJTaXplID0gdGhpcy4kbWF4QnVmZmVyU2l6ZS5waXBlKFxyXG4gICAgICAgIG1hcCh2ID0+IHYgPCAwID8gREVGQVVMVF9CVUZGRVJfU0laRSA6IHYpLFxyXG4gICAgICApLFxyXG4gICAgICAkc25hcFRvSXRlbSA9IHRoaXMuJHNuYXBUb0l0ZW0sXHJcbiAgICAgICRzbmFwVG9JdGVtQWxpZ24gPSB0aGlzLiRzbmFwVG9JdGVtQWxpZ24sXHJcbiAgICAgICRzdGlja3lFbmFibGVkID0gdGhpcy4kc3RpY2t5RW5hYmxlZCxcclxuICAgICAgJGlzTGF6eSA9IHRoaXMuJGNvbGxlY3Rpb25Nb2RlLnBpcGUoXHJcbiAgICAgICAgbWFwKHYgPT4gdGhpcy5nZXRJc0xhenkodiB8fCBERUZBVUxUX0NPTExFQ1RJT05fTU9ERSkpLFxyXG4gICAgICApLFxyXG4gICAgICAkZW5hYmxlZEJ1ZmZlck9wdGltaXphdGlvbiA9IHRoaXMuJGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24sXHJcbiAgICAgICRzbmFwcGluZ01ldGhvZCA9IHRoaXMuJHNuYXBwaW5nTWV0aG9kLnBpcGUoXHJcbiAgICAgICAgbWFwKHYgPT4gdGhpcy5nZXRJc1NuYXBwaW5nTWV0aG9kQWR2YW5jZWQodiB8fCBERUZBVUxUX1NOQVBQSU5HX01FVEhPRCkpLFxyXG4gICAgICApLFxyXG4gICAgICAkY29sbGFwc2luZ01vZGUgPSB0aGlzLiRjb2xsYXBzaW5nTW9kZSxcclxuICAgICAgJHNlbGVjdGluZ01vZGUgPSB0aGlzLiRzZWxlY3RpbmdNb2RlLFxyXG4gICAgICAkc2VsZWN0ZWRJZHMgPSB0aGlzLiRzZWxlY3RlZElkcyxcclxuICAgICAgJGNvbGxhcHNlZElkcyA9IHRoaXMuJGNvbGxhcHNlZElkcy5waXBlKFxyXG4gICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXHJcbiAgICAgICAgbWFwKHYgPT4gQXJyYXkuaXNBcnJheSh2KSA/IHYgOiBbXSksXHJcbiAgICAgICksXHJcbiAgICAgICRjb2xsYXBzZWRJdGVtSWRzID0gdGhpcy5fJGNvbGxhcHNlZEl0ZW1JZHMuYXNPYnNlcnZhYmxlKCkucGlwZShcclxuICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICAgIG1hcCh2ID0+IEFycmF5LmlzQXJyYXkodikgPyB2IDogW10pLFxyXG4gICAgICApLFxyXG4gICAgICAkaXRlbVRyYW5zZm9ybSA9IHRoaXMuJGl0ZW1UcmFuc2Zvcm0sXHJcbiAgICAgICRzY3JlZW5SZWFkZXJNZXNzYWdlID0gdGhpcy4kc2NyZWVuUmVhZGVyTWVzc2FnZSxcclxuICAgICAgJGRpc3BsYXlJdGVtcyA9IHRoaXMuX3NlcnZpY2UuJGRpc3BsYXlJdGVtcyxcclxuICAgICAgJGNhY2hlVmVyc2lvbiA9IHRoaXMuX3NlcnZpY2UuJGNhY2hlVmVyc2lvbjtcclxuXHJcbiAgICAkc25hcFRvSXRlbS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX3NlcnZpY2Uuc25hcFRvSXRlbSA9IHY7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAkYWN0dWFsSXRlbXMucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl9zZXJ2aWNlLml0ZW1zID0gdjtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIGNvbWJpbmVMYXRlc3QoWyRhY3R1YWxJdGVtcywgJHZpZXdJbml0XSkucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGZpbHRlcigoWywgaW5pdF0pID0+IGluaXQpLFxyXG4gICAgICBkZWJvdW5jZVRpbWUoMCksXHJcbiAgICAgIHRhcCgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5fc2Nyb2xsZXJDb21wb25lbnQ/LnNuYXBJZk5lZWQoKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRpdGVtQ29uZmlnTWFwLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgdGhpcy5fc2VydmljZS5pdGVtQ29uZmlnTWFwID0gdjtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRjb2xsYXBzZWRJZHMucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl9zZXJ2aWNlLmNvbGxhcHNlZElkcyA9IHY7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICBjb21iaW5lTGF0ZXN0KFskZGlzcGxheUl0ZW1zLCAkc2NyZWVuUmVhZGVyTWVzc2FnZSwgJGlzVmVydGljYWwsICRzY3JvbGxTaXplLCAkYm91bmRzXSkucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXHJcbiAgICAgIGRlYm91bmNlVGltZSgxMDApLFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKChbaXRlbXMsIHNjcmVlblJlYWRlck1lc3NhZ2UsIGlzVmVydGljYWwsIHNjcm9sbFNpemUsIGJvdW5kc10pID0+IHtcclxuICAgICAgICB0aGlzLl8kc2NyZWVuUmVhZGVyRm9ybWF0dGVkTWVzc2FnZS5uZXh0KFxyXG4gICAgICAgICAgZm9ybWF0U2NyZWVuUmVhZGVyTWVzc2FnZShpdGVtcywgc2NyZWVuUmVhZGVyTWVzc2FnZSwgc2Nyb2xsU2l6ZSwgaXNWZXJ0aWNhbCwgYm91bmRzISlcclxuICAgICAgICApO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgJGlzTGF6eS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX3RyYWNrQm94LmlzTGF6eSA9IHY7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICBjb25zdCAkaXRlbXNDb21wb3NpdGlvbiA9ICRpdGVtcy5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgc3dpdGNoTWFwKGl0ZW1zID0+IHtcclxuICAgICAgICByZXR1cm4gY29tYmluZUxhdGVzdChbJGNvbGxhcHNlZEl0ZW1JZHMsICRpdGVtQ29uZmlnTWFwLCAkdHJhY2tCeSwgJGRpdmlkZXNdKS5waXBlKFxyXG4gICAgICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgICAgICBkZWJvdW5jZVRpbWUoMCksXHJcbiAgICAgICAgICBzd2l0Y2hNYXAoKFtjb2xsYXBzZWRJZHMsIGl0ZW1Db25maWdNYXAsIHRyYWNrQnksIGRpdmlkZXNdKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBvZih7IGl0ZW1zLCBjb2xsYXBzZWRJZHMsIGl0ZW1Db25maWdNYXAsIHRyYWNrQnksIGRpdmlkZXMgfSk7XHJcbiAgICAgICAgICB9KSxcclxuICAgICAgICApO1xyXG4gICAgICB9KSxcclxuICAgICk7XHJcblxyXG4gICAgJGl0ZW1zQ29tcG9zaXRpb24ucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHN3aXRjaE1hcCgoeyBpdGVtcywgY29sbGFwc2VkSWRzLCBpdGVtQ29uZmlnTWFwLCB0cmFja0J5LCBkaXZpZGVzIH0pID0+IHtcclxuICAgICAgICBpZiAoaXRlbXMubGVuZ3RoID09PSAwIHx8ICF0aGlzLl9yZWFkeUZvclNob3cgfHwgISh0aGlzLmNhY2hhYmxlICYmICF0aGlzLl9jYWNoZWQgJiZcclxuICAgICAgICAgICF0aGlzLl90cmFja0JveC5pc1NuYXBwZWRUb1N0YXJ0ICYmIHRoaXMuX3RyYWNrQm94LmlzU25hcHBlZFRvRW5kKSkge1xyXG4gICAgICAgICAgcmV0dXJuIG9mKHsgaXRlbXMsIGNvbGxhcHNlZElkcywgaXRlbUNvbmZpZ01hcCwgdHJhY2tCeSwgZGl2aWRlcyB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuICR1cGRhdGVJdGVtc1JlbmRlclN0YWJpbGl6ZXIucGlwZShcclxuICAgICAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICAgICAgdGFrZSgxKSxcclxuICAgICAgICAgIGRlYm91bmNlVGltZSgwKSxcclxuICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBvZih7IGl0ZW1zLCBjb2xsYXBzZWRJZHMsIGl0ZW1Db25maWdNYXAsIHRyYWNrQnksIGRpdmlkZXMgfSk7XHJcbiAgICAgICAgICB9KSxcclxuICAgICAgICApO1xyXG4gICAgICB9KSxcclxuICAgICAgdGFwKCh7IGl0ZW1zLCBjb2xsYXBzZWRJZHMsIGl0ZW1Db25maWdNYXAsIHRyYWNrQnksIGRpdmlkZXMgfSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGhpZGRlbkl0ZW1zID0gbmV3IENNYXA8SWQsIGJvb2xlYW4+KCk7XHJcblxyXG4gICAgICAgIGxldCBpc0NvbGxhcHNlZCA9IGZhbHNlO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsID0gaXRlbXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgICBjb25zdCBpdGVtID0gaXRlbXNbaV0sIGlkID0gaXRlbT8uW3RyYWNrQnldO1xyXG4gICAgICAgICAgaWYgKCEhaXRlbSkge1xyXG4gICAgICAgICAgICBjb25zdCBncm91cCA9IChpdGVtQ29uZmlnTWFwW2lkXT8uc3RpY2t5ID8/IDApID4gMCwgY29sbGFwc2VkID0gY29sbGFwc2VkSWRzLmluY2x1ZGVzKGlkKTtcclxuICAgICAgICAgICAgaWYgKCEhZ3JvdXApIHtcclxuICAgICAgICAgICAgICBpc0NvbGxhcHNlZCA9IGNvbGxhcHNlZDtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBpZiAoaXNDb2xsYXBzZWQpIHtcclxuICAgICAgICAgICAgICAgIGhpZGRlbkl0ZW1zLnNldChpZCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBhY3R1YWxJdGVtczogSVZpcnR1YWxMaXN0Q29sbGVjdGlvbiA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsID0gaXRlbXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgICBjb25zdCBpdGVtID0gaXRlbXNbaV0sIGlkID0gaXRlbT8uW3RyYWNrQnldO1xyXG4gICAgICAgICAgaWYgKCEhaXRlbSAmJiBoaWRkZW5JdGVtcy5oYXMoaWQpKSB7XHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgYWN0dWFsSXRlbXMucHVzaChpdGVtKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRDb2xsZWN0aW9uID0gbm9ybWFsaXplQ29sbGVjdGlvbihhY3R1YWxJdGVtcywgaXRlbUNvbmZpZ01hcCwgdHJhY2tCeSwgZGl2aWRlcyk7XHJcblxyXG4gICAgICAgIHRoaXMuXyRhY3R1YWxJdGVtcy5uZXh0KG5vcm1hbGl6ZWRDb2xsZWN0aW9uKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRpc1ZlcnRpY2FsLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgdGhpcy5faXNWZXJ0aWNhbCA9IHY7XHJcbiAgICAgICAgY29uc3QgZWw6IEhUTUxFbGVtZW50ID0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgICAgIHRvZ2dsZUNsYXNzTmFtZShlbCwgdiA/IENMQVNTX0xJU1RfVkVSVElDQUwgOiBDTEFTU19MSVNUX0hPUklaT05UQUwsIHYgPyBDTEFTU19MSVNUX0hPUklaT05UQUwgOiBDTEFTU19MSVNUX1ZFUlRJQ0FMKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRzbmFwcGluZ01ldGhvZC5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX2lzU25hcHBpbmdNZXRob2RBZHZhbmNlZCA9IHRoaXMuX3RyYWNrQm94LmlzU25hcHBpbmdNZXRob2RBZHZhbmNlZCA9IHY7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAkc2VsZWN0aW5nTW9kZS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIGNvbnN0IGVsID0gdGhpcy5fJGxpc3QuZ2V0VmFsdWUoKT8ubmF0aXZlRWxlbWVudDtcclxuICAgICAgICBpZiAodGhpcy5nZXRJc011bHRpU2VsZWN0aW9uKHYgfHwgREVGQVVMVF9TTkFQUElOR19NRVRIT0QpKSB7XHJcbiAgICAgICAgICB0aGlzLl9pc011bHRpU2VsZWN0aW9uID0gdHJ1ZTtcclxuICAgICAgICAgIHRoaXMuX2lzU2luZ2xlU2VsZWN0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgICBpZiAoISFlbCkge1xyXG4gICAgICAgICAgICAoZWwgYXMgYW55KS5yb2xlID0gUk9MRV9MSVNUX0JPWDtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHRoaXMuX3NlcnZpY2Uuc2VsZWN0aW5nTW9kZSA9IFNlbGVjdGluZ01vZGVzVHlwZXMuTVVMVElfU0VMRUNUO1xyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5nZXRJc1NpbmdsZVNlbGVjdGlvbih2IHx8IERFRkFVTFRfU05BUFBJTkdfTUVUSE9EKSkge1xyXG4gICAgICAgICAgdGhpcy5faXNTaW5nbGVTZWxlY3Rpb24gPSB0cnVlO1xyXG4gICAgICAgICAgdGhpcy5faXNNdWx0aVNlbGVjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgaWYgKCEhZWwpIHtcclxuICAgICAgICAgICAgKGVsIGFzIGFueSkucm9sZSA9IFJPTEVfTElTVF9CT1g7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICB0aGlzLl9zZXJ2aWNlLnNlbGVjdGluZ01vZGUgPSBTZWxlY3RpbmdNb2Rlc1R5cGVzLlNFTEVDVDtcclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZ2V0SXNOb25lU2VsZWN0aW9uKHYgfHwgREVGQVVMVF9TTkFQUElOR19NRVRIT0QpKSB7XHJcbiAgICAgICAgICB0aGlzLl9pc1NpbmdsZVNlbGVjdGlvbiA9IHRoaXMuX2lzTXVsdGlTZWxlY3Rpb24gPSBmYWxzZTtcclxuICAgICAgICAgIGlmICghIWVsKSB7XHJcbiAgICAgICAgICAgIChlbCBhcyBhbnkpLnJvbGUgPSBST0xFX0xJU1Q7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICB0aGlzLl9zZXJ2aWNlLnNlbGVjdGluZ01vZGUgPSBTZWxlY3RpbmdNb2Rlc1R5cGVzLk5PTkU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgJGNvbGxhcHNpbmdNb2RlLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuZ2V0SXNOb25lQ29sbGFwc2UoKSkge1xyXG4gICAgICAgICAgdGhpcy5fc2VydmljZS5pc05vbmVDb2xsYXBzZSA9IHRydWU7XHJcbiAgICAgICAgICB0aGlzLl9zZXJ2aWNlLmlzQWNjb3JkaW9uQ29sbGFwc2UgPSB0aGlzLl9zZXJ2aWNlLmlzTXVsdGlwbGVDb2xsYXBzZSA9IHRoaXMuX2lzQWNjb3JkaW9uQ29sbGFwc2UgPSB0aGlzLl9pc011bHRpcGxlQ29sbGFwc2UgPSBmYWxzZTtcclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZ2V0SXNNdWx0aXBsZUNvbGxhcHNlKCkpIHtcclxuICAgICAgICAgIHRoaXMuX3NlcnZpY2UuaXNNdWx0aXBsZUNvbGxhcHNlID0gdGhpcy5faXNNdWx0aXBsZUNvbGxhcHNlID0gdHJ1ZTtcclxuICAgICAgICAgIHRoaXMuX3NlcnZpY2UuaXNBY2NvcmRpb25Db2xsYXBzZSA9IHRoaXMuX3NlcnZpY2UuaXNOb25lQ29sbGFwc2UgPSB0aGlzLl9pc0FjY29yZGlvbkNvbGxhcHNlID0gZmFsc2U7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmdldElzQWNjb3JkaW9uQ29sbGFwc2UoKSkge1xyXG4gICAgICAgICAgdGhpcy5fc2VydmljZS5pc0FjY29yZGlvbkNvbGxhcHNlID0gdGhpcy5faXNBY2NvcmRpb25Db2xsYXBzZSA9IHRydWU7XHJcbiAgICAgICAgICB0aGlzLl9zZXJ2aWNlLmlzTXVsdGlwbGVDb2xsYXBzZSA9IHRoaXMuX3NlcnZpY2UuaXNOb25lQ29sbGFwc2UgPSB0aGlzLl9pc011bHRpcGxlQ29sbGFwc2UgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICBjb25zdCAkcHJldmVudFNjcm9sbFNuYXBwaW5nID0gdGhpcy4kcHJldmVudFNjcm9sbFNuYXBwaW5nO1xyXG5cclxuICAgICRwcmV2ZW50U2Nyb2xsU25hcHBpbmcucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGZpbHRlcih2ID0+ICEhdiksXHJcbiAgICAgIHRhcCgoKSA9PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuX3JlYWR5Rm9yU2hvdykge1xyXG4gICAgICAgICAgdGhpcy5fdHJhY2tCb3guaXNTY3JvbGxFbmQ7XHJcbiAgICAgICAgICB0aGlzLl90cmFja0JveC5pc1Njcm9sbFN0YXJ0ID0gdGhpcy5fdHJhY2tCb3guaXNTY3JvbGxFbmQgPSBmYWxzZTtcclxuICAgICAgICAgIHRoaXMuXyRpc1Njcm9sbFN0YXJ0Lm5leHQoZmFsc2UpO1xyXG4gICAgICAgICAgdGhpcy5fJGlzU2Nyb2xsRW5kLm5leHQoZmFsc2UpO1xyXG4gICAgICAgICAgY29uc3Qgc2Nyb2xsZXIgPSB0aGlzLl9zY3JvbGxlckNvbXBvbmVudDtcclxuICAgICAgICAgIGlmICghIXNjcm9sbGVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3RyYWNrQm94LnByZXZlbnRTY3JvbGxTbmFwcGluZyh0cnVlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0pLFxyXG4gICAgICB0YXAoKCkgPT4ge1xyXG4gICAgICAgIGlmICh0aGlzLl9yZWFkeUZvclNob3cpIHtcclxuICAgICAgICAgIHRoaXMuXyRwcmV2ZW50U2Nyb2xsU25hcHBpbmcubmV4dChmYWxzZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgJGNvbGxhcHNlZEl0ZW1JZHMucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGZpbHRlcigoKSA9PiB0aGlzLl9yZWFkeUZvclNob3cpLFxyXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4ge1xyXG4gICAgICAgIHJldHVybiAkY29sbGFwc2VJdGVtc1JlbmRlclN0YWJpbGl6ZXIucGlwZShcclxuICAgICAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICAgICAgdGFrZSgxKSxcclxuICAgICAgICAgIHRhcCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuXyRmaXJlVXBkYXRlLm5leHQodHJ1ZSk7XHJcbiAgICAgICAgICB9KSxcclxuICAgICAgICApO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgbGV0IGlzQ2h1bmtMb2FkaW5nID0gZmFsc2U7XHJcbiAgICBjb25zdCAkbG9hZGluZyA9IHRoaXMuJGxvYWRpbmc7XHJcbiAgICAkbG9hZGluZy5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgc2tpcCgxKSxcclxuICAgICAgZmlsdGVyKHYgPT4gIXYpLFxyXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4ge1xyXG4gICAgICAgIGlzQ2h1bmtMb2FkaW5nID0gdHJ1ZTtcclxuICAgICAgICBjb25zdCBzY3JvbGxiYXIgPSB0aGlzLl9zY3JvbGxlckNvbXBvbmVudDtcclxuICAgICAgICBpZiAoISFzY3JvbGxiYXIpIHtcclxuICAgICAgICAgIHNjcm9sbGJhci5zdG9wU2Nyb2xsYmFyKCk7XHJcbiAgICAgICAgICBzY3JvbGxiYXIucmVmcmVzaFNjcm9sbGJhcigpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gJGFjdHVhbEl0ZW1zLnBpcGUoXHJcbiAgICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICAgIHRha2UoMSksXHJcbiAgICAgICAgICB0YXAoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl8kZmlyZVVwZGF0ZU5leHRGcmFtZS5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgfSksXHJcbiAgICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gJGNodW5rTG9hZGluZ1JlbmRlclN0YWJpbGl6ZXIucGlwZShcclxuICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgICAgICAgIHRha2UoMSksXHJcbiAgICAgICAgICAgIHRhcCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgaXNDaHVua0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICB0aGlzLl90cmFja0JveC5yZXNldENhY2hlQ2h1bmtJbmZvKCk7XHJcbiAgICAgICAgICAgICAgY29uc3Qgc2Nyb2xsYmFyID0gdGhpcy5fc2Nyb2xsZXJDb21wb25lbnQ7XHJcbiAgICAgICAgICAgICAgaWYgKCEhc2Nyb2xsYmFyKSB7XHJcbiAgICAgICAgICAgICAgICBzY3JvbGxiYXIuc3RvcFNjcm9sbGJhcigpO1xyXG4gICAgICAgICAgICAgICAgc2Nyb2xsYmFyLnJlZnJlc2hTY3JvbGxiYXIoKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgKSksXHJcbiAgICAgICAgKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRsb2FkaW5nLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBza2lwKDEpLFxyXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgaWYgKHYpIHtcclxuICAgICAgICAgIHRoaXMuX2lzTG9hZGluZyA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KSxcclxuICAgICAgZmlsdGVyKHYgPT4gIXYpLFxyXG4gICAgICB0YXAoKCkgPT4ge1xyXG4gICAgICAgIGlmICh0aGlzLl9yZWFkeUZvclNob3cpIHtcclxuICAgICAgICAgIHRoaXMuXyRwcmV2ZW50U2Nyb2xsU25hcHBpbmcubmV4dCh0cnVlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pLFxyXG4gICAgICBkZWJvdW5jZVRpbWUoMTAwKSxcclxuICAgICAgdGFwKCgpID0+IHtcclxuICAgICAgICB0aGlzLl9pc0xvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIGNvbnN0IHVwZGF0ZSA9IChwYXJhbXM6IHtcclxuICAgICAgYWxpZ25tZW50OiBBbGlnbm1lbnQ7IHByZWNhbGN1bGF0ZWRTY3JvbGxTdGFydE9mZnNldDogbnVtYmVyOyBwcmVjYWxjdWxhdGVkU2Nyb2xsRW5kT2Zmc2V0OiBudW1iZXI7IHRyYWNrQnk6IHN0cmluZzsgaXNJbmZpbml0eTogYm9vbGVhbjtcclxuICAgICAgc25hcFNjcm9sbFRvU3RhcnQ6IGJvb2xlYW4sIHNuYXBTY3JvbGxUb0VuZDogYm9vbGVhbjsgYm91bmRzOiBJU2l6ZTsgbGlzdEJvdW5kczogSVNpemU7IHNjcm9sbEVuZE9mZnNldDogbnVtYmVyO1xyXG4gICAgICBpdGVtczogSVZpcnR1YWxMaXN0Q29sbGVjdGlvbjxPYmplY3Q+OyBpdGVtQ29uZmlnTWFwOiBJVmlydHVhbExpc3RJdGVtQ29uZmlnTWFwOyBzY3JvbGxTaXplOiBudW1iZXI7IGl0ZW1TaXplOiBudW1iZXI7XHJcbiAgICAgIG1pbkl0ZW1TaXplOiBudW1iZXI7IG1heEl0ZW1TaXplOiBudW1iZXI7IGJ1ZmZlclNpemU6IG51bWJlcjsgbWF4QnVmZmVyU2l6ZTogbnVtYmVyOyBzdGlja3lFbmFibGVkOiBib29sZWFuOyBpc1ZlcnRpY2FsOiBib29sZWFuO1xyXG4gICAgICBkeW5hbWljU2l6ZTogYm9vbGVhbjsgZGl2aWRlczogbnVtYmVyOyBlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uOiBib29sZWFuOyBjYWNoZVZlcnNpb246IG51bWJlcjsgdXNlckFjdGlvbjogYm9vbGVhbjtcclxuICAgICAgc25hcFRvSXRlbTogYm9vbGVhbiwgc25hcFRvSXRlbUFsaWduOiBTbmFwVG9JdGVtQWxpZ24sIGNvbGxhcHNlZElkczogQXJyYXk8SWQ+OyBpdGVtVHJhbnNmb3JtOiBJdGVtVHJhbnNmb3JtIHwgbnVsbDtcclxuICAgIH0pID0+IHtcclxuICAgICAgY29uc3Qge1xyXG4gICAgICAgIGFsaWdubWVudCwgcHJlY2FsY3VsYXRlZFNjcm9sbFN0YXJ0T2Zmc2V0LCBwcmVjYWxjdWxhdGVkU2Nyb2xsRW5kT2Zmc2V0LCB0cmFja0J5LCBpc0luZmluaXR5LFxyXG4gICAgICAgIHNuYXBTY3JvbGxUb1N0YXJ0LCBzbmFwU2Nyb2xsVG9FbmQsIGJvdW5kcywgbGlzdEJvdW5kcywgc2Nyb2xsRW5kT2Zmc2V0LCBpdGVtcywgaXRlbUNvbmZpZ01hcCwgc2Nyb2xsU2l6ZSwgaXRlbVNpemUsIG1pbkl0ZW1TaXplLFxyXG4gICAgICAgIG1heEl0ZW1TaXplLCBkaXZpZGVzLCBidWZmZXJTaXplLCBtYXhCdWZmZXJTaXplLCBzdGlja3lFbmFibGVkLCBpc1ZlcnRpY2FsLCBkeW5hbWljU2l6ZSwgZW5hYmxlZEJ1ZmZlck9wdGltaXphdGlvbiwgc25hcFRvSXRlbSxcclxuICAgICAgICBzbmFwVG9JdGVtQWxpZ24sIGNhY2hlVmVyc2lvbiwgdXNlckFjdGlvbiwgY29sbGFwc2VkSWRzLCBpdGVtVHJhbnNmb3JtLFxyXG4gICAgICB9ID0gcGFyYW1zO1xyXG4gICAgICBjb25zdCBzY3JvbGxlciA9IHRoaXMuX3Njcm9sbGVyQ29tcG9uZW50O1xyXG4gICAgICBsZXQgdG90YWxTaXplID0gMDtcclxuICAgICAgaWYgKCEhc2Nyb2xsZXIpIHtcclxuICAgICAgICBjb25zdCBpc0luZmluaXR5ID0gdGhpcy5pc0luZmluaXR5LCBjb2xsYXBzYWJsZSA9IGNvbGxhcHNlZElkcy5sZW5ndGggPiAwLCBjYWNoYWJsZSA9IHRoaXMuY2FjaGFibGUsIGNhY2hlZCA9IHRoaXMuX2NhY2hlZCwgd2FpdGluZ0NhY2hlID0gY2FjaGFibGUgJiYgIWNhY2hlZCxcclxuICAgICAgICAgIGVtaXRVcGRhdGUgPSAhdGhpcy5fcmVhZHlGb3JTaG93IHx8IHdhaXRpbmdDYWNoZSB8fCBjb2xsYXBzYWJsZSB8fCBpc0NodW5rTG9hZGluZyxcclxuICAgICAgICAgIGZpcmVVcGRhdGUgPSAhdGhpcy5fcmVhZHlGb3JTaG93IHx8IHRoaXMuXyRzY3JvbGxpbmdUby5nZXRWYWx1ZSgpLFxyXG4gICAgICAgICAgZmlyZVVwZGF0ZUF0RWRnZXMgPSBmaXJlVXBkYXRlIHx8ICFpc0luZmluaXR5O1xyXG4gICAgICAgIGlmICh0aGlzLl9yZWFkeUZvclNob3cgfHwgKGNhY2hhYmxlICYmIGNhY2hlZCkpIHtcclxuICAgICAgICAgIGNvbnN0IGN1cnJlbnRTY3JvbGxTaXplID0gKGlzVmVydGljYWwgPyBzY3JvbGxlci5zY3JvbGxUb3AgOiBzY3JvbGxlci5zY3JvbGxMZWZ0KTtcclxuICAgICAgICAgIGxldCBhY3R1YWxTY3JvbGxTaXplID0gIXRoaXMuX3JlYWR5Rm9yU2hvdyAmJiBzbmFwU2Nyb2xsVG9FbmQgPyAoaXNWZXJ0aWNhbCA/IHNjcm9sbGVyLnNjcm9sbEhlaWdodCA6IHNjcm9sbGVyLnNjcm9sbFdpZHRoKSA6XHJcbiAgICAgICAgICAgIChpc1ZlcnRpY2FsID8gc2Nyb2xsZXIuc2Nyb2xsVG9wIDogc2Nyb2xsZXIuc2Nyb2xsTGVmdCksXHJcbiAgICAgICAgICAgIGxlZnRMYXlvdXRPZmZzZXQgPSAwLFxyXG4gICAgICAgICAgICBkaXNwbGF5SXRlbXM6IElSZW5kZXJWaXJ0dWFsTGlzdENvbGxlY3Rpb247XHJcblxyXG4gICAgICAgICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSBib3VuZHMsIHZpZXdwb3J0U2l6ZSA9IChpc1ZlcnRpY2FsID8gaGVpZ2h0IDogd2lkdGgpLFxyXG4gICAgICAgICAgICBvcHRzOiBJVXBkYXRlQ29sbGVjdGlvbk9wdGlvbnM8SVZpcnR1YWxMaXN0SXRlbSwgSVZpcnR1YWxMaXN0Q29sbGVjdGlvbj4gPSB7XHJcbiAgICAgICAgICAgICAgYm91bmRzOiB7IHdpZHRoLCBoZWlnaHQgfSwgZHluYW1pY1NpemUsIGlzVmVydGljYWwsIGl0ZW1TaXplLCBtaW5JdGVtU2l6ZSwgbWF4SXRlbVNpemUsIGJ1ZmZlclNpemUsIG1heEJ1ZmZlclNpemUsXHJcbiAgICAgICAgICAgICAgc2Nyb2xsU2l6ZTogYWN0dWFsU2Nyb2xsU2l6ZSwgc3RpY2t5RW5hYmxlZCwgZW5hYmxlZEJ1ZmZlck9wdGltaXphdGlvbiwgc25hcFRvSXRlbSwgc25hcFRvSXRlbUFsaWduLCBpdGVtVHJhbnNmb3JtLFxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgIGlmIChzbmFwU2Nyb2xsVG9FbmQgJiYgIXRoaXMuX3JlYWR5Rm9yU2hvdykge1xyXG4gICAgICAgICAgICBjb25zdCB7IGRpc3BsYXlJdGVtczogY2FsY3VsYXRlZERpc3BsYXlJdGVtcywgdG90YWxTaXplOiBjYWxjdWxhdGVkVG90YWxTaXplMSwgbGVmdExheW91dE9mZnNldDogbGVmdExheW91dE9mZnNldDEgfSA9XHJcbiAgICAgICAgICAgICAgdGhpcy5fdHJhY2tCb3gudXBkYXRlQ29sbGVjdGlvbihpdGVtcywgaXRlbUNvbmZpZ01hcCwgeyAuLi5vcHRzLCBzY3JvbGxTaXplOiBhY3R1YWxTY3JvbGxTaXplIH0pO1xyXG4gICAgICAgICAgICBkaXNwbGF5SXRlbXMgPSBjYWxjdWxhdGVkRGlzcGxheUl0ZW1zO1xyXG4gICAgICAgICAgICB0b3RhbFNpemUgPSBjYWxjdWxhdGVkVG90YWxTaXplMTtcclxuICAgICAgICAgICAgbGVmdExheW91dE9mZnNldCA9IGxlZnRMYXlvdXRPZmZzZXQxO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgeyBkaXNwbGF5SXRlbXM6IGNhbGN1bGF0ZWREaXNwbGF5SXRlbXMsIHRvdGFsU2l6ZTogY2FsY3VsYXRlZFRvdGFsU2l6ZSwgbGVmdExheW91dE9mZnNldDogbGVmdExheW91dE9mZnNldDEgfSA9IHRoaXMuX3RyYWNrQm94LnVwZGF0ZUNvbGxlY3Rpb24oaXRlbXMsIGl0ZW1Db25maWdNYXAsIG9wdHMpO1xyXG4gICAgICAgICAgICBkaXNwbGF5SXRlbXMgPSBjYWxjdWxhdGVkRGlzcGxheUl0ZW1zO1xyXG4gICAgICAgICAgICB0b3RhbFNpemUgPSBjYWxjdWxhdGVkVG90YWxTaXplO1xyXG4gICAgICAgICAgICBsZWZ0TGF5b3V0T2Zmc2V0ID0gbGVmdExheW91dE9mZnNldDE7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgc2Nyb2xsZXIudG90YWxTaXplID0gdG90YWxTaXplO1xyXG5cclxuICAgICAgICAgIHNjcm9sbGVyLnN0YXJ0TGF5b3V0T2Zmc2V0ID0gbGVmdExheW91dE9mZnNldDtcclxuXHJcbiAgICAgICAgICB0aGlzLl8kdG90YWxTaXplLm5leHQodG90YWxTaXplKTtcclxuXHJcbiAgICAgICAgICB0aGlzLl9zZXJ2aWNlLmNvbGxlY3Rpb24gPSBkaXNwbGF5SXRlbXM7XHJcblxyXG4gICAgICAgICAgdGhpcy5yZXNldEJvdW5kc1NpemUoaXNWZXJ0aWNhbCwgdG90YWxTaXplKTtcclxuXHJcbiAgICAgICAgICB0aGlzLmNyZWF0ZURpc3BsYXlDb21wb25lbnRzSWZOZWVkKGRpc3BsYXlJdGVtcyk7XHJcblxyXG4gICAgICAgICAgdGhpcy50cmFja2luZygpO1xyXG5cclxuICAgICAgICAgIHRoaXMuc25hcHBpbmdIYW5kbGVyKCk7XHJcblxyXG4gICAgICAgICAgaWYgKCFfJGNyZWF0ZWQuZ2V0VmFsdWUoKSkge1xyXG4gICAgICAgICAgICBfJGNyZWF0ZWQubmV4dCh0cnVlKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBjb25zdCBkZWx0YSA9IHRoaXMuX3RyYWNrQm94LmRlbHRhLFxyXG4gICAgICAgICAgICBzY3JvbGxQb3NpdGlvbkFmdGVyVXBkYXRlID0gYWN0dWFsU2Nyb2xsU2l6ZSArIGRlbHRhLFxyXG4gICAgICAgICAgICByb3VuZGVkU2Nyb2xsUG9zaXRpb25BZnRlclVwZGF0ZSA9IHNjcm9sbFBvc2l0aW9uQWZ0ZXJVcGRhdGUsXHJcbiAgICAgICAgICAgIHJvdW5kZWRNYXhQb3NpdGlvbkFmdGVyVXBkYXRlID0gaXNWZXJ0aWNhbCA/IHNjcm9sbGVyLnNjcm9sbEhlaWdodCA6IHNjcm9sbGVyLnNjcm9sbFdpZHRoO1xyXG5cclxuICAgICAgICAgIGlmICh0aGlzLl9pc1NuYXBwaW5nTWV0aG9kQWR2YW5jZWQpIHtcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVSZWd1bGFyUmVuZGVyZXIoKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBzd2l0Y2ggKGFsaWdubWVudCkge1xyXG4gICAgICAgICAgICBjYXNlIEFsaWdubWVudHMuTk9ORToge1xyXG4gICAgICAgICAgICAgIHRoaXMuXyRhY3R1YWxTY3JvbGxTdGFydE9mZnNldC5uZXh0KHByZWNhbGN1bGF0ZWRTY3JvbGxTdGFydE9mZnNldCk7XHJcbiAgICAgICAgICAgICAgdGhpcy5fJGFjdHVhbFNjcm9sbEVuZE9mZnNldC5uZXh0KHByZWNhbGN1bGF0ZWRTY3JvbGxFbmRPZmZzZXQpO1xyXG4gICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgQWxpZ25tZW50cy5DRU5URVI6IHtcclxuICAgICAgICAgICAgICBjb25zdCBmaXJzdEl0ZW1JZDogSWQgfCBudWxsID0gaXRlbXMubGVuZ3RoID4gMCA/IChpdGVtc1swXT8uW3RyYWNrQnldID8/IG51bGwpIDogbnVsbCxcclxuICAgICAgICAgICAgICAgIGVuZEl0ZW1JZDogSWQgfCBudWxsID0gaXRlbXMubGVuZ3RoID4gMCA/IChpdGVtcz8uW2l0ZW1zLmxlbmd0aCAtIDFdPy5bdHJhY2tCeV0gPz8gbnVsbCkgOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgYWxpZ25tZW50U3RhcnRPZmZzZXQgPSB2aWV3cG9ydFNpemUgKiAuNSAtIChmaXJzdEl0ZW1JZCAhPT0gbnVsbCA/IChpc1ZlcnRpY2FsID8gKHRoaXMuX3NlcnZpY2UuZ2V0SXRlbUJvdW5kcyhmaXJzdEl0ZW1JZCk/LmhlaWdodCA/PyAwKSA6XHJcbiAgICAgICAgICAgICAgICAgICh0aGlzLl9zZXJ2aWNlLmdldEl0ZW1Cb3VuZHMoZmlyc3RJdGVtSWQpPy53aWR0aCA/PyAwKSkgOiAwKSAqIChpc0luZmluaXR5ID8gMCA6IC41KSxcclxuICAgICAgICAgICAgICAgIGFsaWdubWVudEVuZE9mZnNldCA9IHZpZXdwb3J0U2l6ZSAqIC41IC0gKGVuZEl0ZW1JZCAhPT0gbnVsbCA/IChpc1ZlcnRpY2FsID8gKHRoaXMuX3NlcnZpY2UuZ2V0SXRlbUJvdW5kcyhlbmRJdGVtSWQpPy5oZWlnaHQgPz8gMCkgOlxyXG4gICAgICAgICAgICAgICAgICAodGhpcy5fc2VydmljZS5nZXRJdGVtQm91bmRzKGVuZEl0ZW1JZCk/LndpZHRoID8/IDApKSA6IDApICogKGlzSW5maW5pdHkgPyAwIDogLjUpO1xyXG5cclxuICAgICAgICAgICAgICB0aGlzLl8kYWxpZ25tZW50U2Nyb2xsU3RhcnRPZmZzZXQubmV4dChhbGlnbm1lbnRTdGFydE9mZnNldCk7XHJcbiAgICAgICAgICAgICAgdGhpcy5fJGFsaWdubWVudFNjcm9sbEVuZE9mZnNldC5uZXh0KGFsaWdubWVudEVuZE9mZnNldCk7XHJcbiAgICAgICAgICAgICAgdGhpcy5fJGFjdHVhbFNjcm9sbFN0YXJ0T2Zmc2V0Lm5leHQocHJlY2FsY3VsYXRlZFNjcm9sbFN0YXJ0T2Zmc2V0ICsgYWxpZ25tZW50U3RhcnRPZmZzZXQpO1xyXG4gICAgICAgICAgICAgIHRoaXMuXyRhY3R1YWxTY3JvbGxFbmRPZmZzZXQubmV4dChwcmVjYWxjdWxhdGVkU2Nyb2xsRW5kT2Zmc2V0ICsgYWxpZ25tZW50RW5kT2Zmc2V0KTtcclxuICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIHNjcm9sbGVyLmRlbHRhID0gZGVsdGE7XHJcblxyXG4gICAgICAgICAgaWYgKChzbmFwU2Nyb2xsVG9TdGFydCAmJiB0aGlzLl90cmFja0JveC5pc1NuYXBwZWRUb1N0YXJ0ICYmIHNjcm9sbGVyLnNjcm9sbGFibGUpIHx8XHJcbiAgICAgICAgICAgIChzbmFwU2Nyb2xsVG9TdGFydCAmJiBjdXJyZW50U2Nyb2xsU2l6ZSA8PSBNSU5fUElYRUxTX0ZPUl9QUkVWRU5UX1NOQVBQSU5HKSkge1xyXG4gICAgICAgICAgICBpZiAoY3VycmVudFNjcm9sbFNpemUgIT09IHJvdW5kZWRTY3JvbGxQb3NpdGlvbkFmdGVyVXBkYXRlKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5fdHJhY2tCb3guY2xlYXJEZWx0YSgpO1xyXG5cclxuICAgICAgICAgICAgICBpZiAodGhpcy5fcmVhZHlGb3JTaG93KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRTY3JvbGxFdmVudCh0cnVlLCBmYWxzZSwgdXNlckFjdGlvbik7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIHRoaXMuX3RyYWNrQm94LmlzU2Nyb2xsRW5kO1xyXG4gICAgICAgICAgICAgIGNvbnN0IHBhcmFtczogSVNjcm9sbFRvUGFyYW1zID0ge1xyXG4gICAgICAgICAgICAgICAgW2lzVmVydGljYWwgPyBUT1BfUFJPUF9OQU1FIDogTEVGVF9QUk9QX05BTUVdOiAwLCB1c2VyQWN0aW9uLFxyXG4gICAgICAgICAgICAgICAgZmlyZVVwZGF0ZTogZmlyZVVwZGF0ZUF0RWRnZXMsIGJlaGF2aW9yOiBCRUhBVklPUl9JTlNUQU5ULFxyXG4gICAgICAgICAgICAgICAgYmxlbmRpbmc6IGZhbHNlLCBkdXJhdGlvbjogdGhpcy5hbmltYXRpb25QYXJhbXMuc2Nyb2xsVG9JdGVtLFxyXG4gICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgc2Nyb2xsZXI/LnNjcm9sbFRvPy4ocGFyYW1zKTtcclxuICAgICAgICAgICAgICBpZiAoZW1pdFVwZGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fJHVwZGF0ZS5uZXh0KGdldFNjcm9sbFN0YXRlVmVyc2lvbih0b3RhbFNpemUsIHRoaXMuX2lzVmVydGljYWwgPyBzY3JvbGxlci5zY3JvbGxUb3AgOiBzY3JvbGxlci5zY3JvbGxMZWZ0KSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAoKHNuYXBTY3JvbGxUb0VuZCAmJiB0aGlzLl90cmFja0JveC5pc1NuYXBwZWRUb0VuZCkgfHwgKHNuYXBTY3JvbGxUb0VuZCAmJiAhc2Nyb2xsZXIuc2Nyb2xsYWJsZSkgfHxcclxuICAgICAgICAgICAgKHNjcm9sbFBvc2l0aW9uQWZ0ZXJVcGRhdGUgKyBNSU5fUElYRUxTX0ZPUl9QUkVWRU5UX1NOQVBQSU5HID49IHJvdW5kZWRNYXhQb3NpdGlvbkFmdGVyVXBkYXRlKSB8fFxyXG4gICAgICAgICAgICAocm91bmRlZFNjcm9sbFBvc2l0aW9uQWZ0ZXJVcGRhdGUgPj0gc2Nyb2xsUG9zaXRpb25BZnRlclVwZGF0ZSArIE1JTl9QSVhFTFNfRk9SX1BSRVZFTlRfU05BUFBJTkcpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3RyYWNrQm94LmNsZWFyRGVsdGEoKTtcclxuXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5fdHJhY2tCb3guaXNTbmFwcGVkVG9FbmQpIHtcclxuICAgICAgICAgICAgICB0aGlzLl90cmFja0JveC5pc1Njcm9sbEVuZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgdGhpcy5fdHJhY2tCb3guaXNTY3JvbGxTdGFydCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5fcmVhZHlGb3JTaG93KSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5lbWl0U2Nyb2xsRXZlbnQodHJ1ZSwgZmFsc2UsIGZhbHNlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBwYXJhbXM6IElTY3JvbGxUb1BhcmFtcyA9IHtcclxuICAgICAgICAgICAgICBbaXNWZXJ0aWNhbCA/IFRPUF9QUk9QX05BTUUgOiBMRUZUX1BST1BfTkFNRV06IHJvdW5kZWRNYXhQb3NpdGlvbkFmdGVyVXBkYXRlLFxyXG4gICAgICAgICAgICAgIGZpcmVVcGRhdGU6IGZpcmVVcGRhdGVBdEVkZ2VzLCBiZWhhdmlvcjogQkVIQVZJT1JfSU5TVEFOVCwgdXNlckFjdGlvbjogZmFsc2UsXHJcbiAgICAgICAgICAgICAgYmxlbmRpbmc6IGZhbHNlLCBkdXJhdGlvbjogdGhpcy5hbmltYXRpb25QYXJhbXMuc2Nyb2xsVG9JdGVtLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBzY3JvbGxlcj8uc2Nyb2xsVG8/LihwYXJhbXMpO1xyXG4gICAgICAgICAgICBpZiAoZW1pdFVwZGF0ZSkge1xyXG4gICAgICAgICAgICAgIHRoaXMuXyR1cGRhdGUubmV4dChnZXRTY3JvbGxTdGF0ZVZlcnNpb24odG90YWxTaXplLCB0aGlzLl9pc1ZlcnRpY2FsID8gc2Nyb2xsZXIuc2Nyb2xsVG9wIDogc2Nyb2xsZXIuc2Nyb2xsTGVmdCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAoc2Nyb2xsU2l6ZSAhPT0gc2Nyb2xsUG9zaXRpb25BZnRlclVwZGF0ZSAmJlxyXG4gICAgICAgICAgICAoKHNjcm9sbFBvc2l0aW9uQWZ0ZXJVcGRhdGUgPj0gMCAmJiBzY3JvbGxQb3NpdGlvbkFmdGVyVXBkYXRlIDwgcm91bmRlZE1heFBvc2l0aW9uQWZ0ZXJVcGRhdGUpIHx8XHJcbiAgICAgICAgICAgICAgKHNjcm9sbFNpemUgIT09IHJvdW5kZWRNYXhQb3NpdGlvbkFmdGVyVXBkYXRlIHx8IGN1cnJlbnRTY3JvbGxTaXplICE9PSBzY3JvbGxQb3NpdGlvbkFmdGVyVXBkYXRlKSkpIHtcclxuICAgICAgICAgICAgdGhpcy5fdHJhY2tCb3guY2xlYXJEZWx0YSgpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuX3JlYWR5Rm9yU2hvdykge1xyXG4gICAgICAgICAgICAgIHRoaXMuZW1pdFNjcm9sbEV2ZW50KHRydWUsIGZhbHNlLCB1c2VyQWN0aW9uKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBwYXJhbXM6IElTY3JvbGxUb1BhcmFtcyA9IHtcclxuICAgICAgICAgICAgICBbaXNWZXJ0aWNhbCA/IFRPUF9QUk9QX05BTUUgOiBMRUZUX1BST1BfTkFNRV06IHNjcm9sbFBvc2l0aW9uQWZ0ZXJVcGRhdGUsIGJsZW5kaW5nOiB0cnVlLCB1c2VyQWN0aW9uLFxyXG4gICAgICAgICAgICAgIGZpcmVVcGRhdGUsIGJlaGF2aW9yOiBCRUhBVklPUl9JTlNUQU5ULCBkdXJhdGlvbjogdGhpcy5hbmltYXRpb25QYXJhbXMuc2Nyb2xsVG9JdGVtLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBzY3JvbGxlci5zY3JvbGxUbyhwYXJhbXMpO1xyXG4gICAgICAgICAgICBpZiAoZW1pdFVwZGF0ZSkge1xyXG4gICAgICAgICAgICAgIHRoaXMuXyR1cGRhdGUubmV4dChnZXRTY3JvbGxTdGF0ZVZlcnNpb24odG90YWxTaXplLCB0aGlzLl9pc1ZlcnRpY2FsID8gc2Nyb2xsZXIuc2Nyb2xsVG9wIDogc2Nyb2xsZXIuc2Nyb2xsTGVmdCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGVtaXRVcGRhdGUpIHtcclxuICAgICAgICAgIHRoaXMuXyR1cGRhdGUubmV4dChnZXRTY3JvbGxTdGF0ZVZlcnNpb24odG90YWxTaXplLCB0aGlzLl9pc1ZlcnRpY2FsID8gc2Nyb2xsZXIuc2Nyb2xsVG9wIDogc2Nyb2xsZXIuc2Nyb2xsTGVmdCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBsZXQgcHJldkl0ZW1zOiBJVmlydHVhbExpc3RDb2xsZWN0aW9uID0gW107XHJcbiAgICBjb25zdCBkZWJvdW5jZWRVcGRhdGUgPSBkZWJvdW5jZSh1cGRhdGUsIDAsIE1BWF9OVU1CRVJTX09GX1NLSVBTX0ZPUl9RVUFMSVRZX09QVElNSVpBVElPTl9MVkwxKTtcclxuICAgICR2aWV3SW5pdC5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZmlsdGVyKHYgPT4gISF2KSxcclxuICAgICAgc3dpdGNoTWFwKCgpID0+IHtcclxuICAgICAgICByZXR1cm4gY29tYmluZUxhdGVzdChbJHRyYWNrQnksIHRoaXMuJGlzSW5maW5pdHksICRzbmFwU2Nyb2xsVG9TdGFydCwgJHNuYXBTY3JvbGxUb0VuZCwgJGJvdW5kcywgJGxpc3RCb3VuZHMsICRzY3JvbGxFbmRPZmZzZXQsICRhY3R1YWxJdGVtcywgJGl0ZW1Db25maWdNYXAsICRzY3JvbGxTaXplLFxyXG4gICAgICAgICAgJGFjdHVhbEl0ZW1TaXplLCAkYWN0dWFsTWluSXRlbVNpemUsICRhY3R1YWxNYXhJdGVtU2l6ZSwgJGNvbGxhcHNlZEl0ZW1JZHMsICRidWZmZXJTaXplLCAkbWF4QnVmZmVyU2l6ZSwgJHN0aWNreUVuYWJsZWQsICRpc1ZlcnRpY2FsLFxyXG4gICAgICAgICAgJGR5bmFtaWNTaXplLCAkZGl2aWRlcywgJHNuYXBUb0l0ZW0sICRzbmFwVG9JdGVtQWxpZ24sICRlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uLCAkaXRlbVRyYW5zZm9ybSwgJGFsaWdubWVudCxcclxuICAgICAgICAgICRwcmVjYWxjdWxhdGVkU2Nyb2xsU3RhcnRPZmZzZXQsICRwcmVjYWxjdWxhdGVkU2Nyb2xsRW5kT2Zmc2V0LCAkY2FjaGVWZXJzaW9uLCB0aGlzLiRmaXJlVXBkYXRlLFxyXG4gICAgICAgIF0pLnBpcGUoXHJcbiAgICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICAgIHRhcCgoW1xyXG4gICAgICAgICAgICB0cmFja0J5LCBpc0luZmluaXR5LCBzbmFwU2Nyb2xsVG9TdGFydCwgc25hcFNjcm9sbFRvRW5kLCBib3VuZHMsIGxpc3RCb3VuZHMsIHNjcm9sbEVuZE9mZnNldCwgaXRlbXMsIGl0ZW1Db25maWdNYXAsIHNjcm9sbFNpemUsIGl0ZW1TaXplLCBtaW5JdGVtU2l6ZSxcclxuICAgICAgICAgICAgbWF4SXRlbVNpemUsIGNvbGxhcHNlZElkcywgYnVmZmVyU2l6ZSwgbWF4QnVmZmVyU2l6ZSwgc3RpY2t5RW5hYmxlZCwgaXNWZXJ0aWNhbCwgZHluYW1pY1NpemUsIGRpdmlkZXMsIHNuYXBUb0l0ZW0sIHNuYXBUb0l0ZW1BbGlnbixcclxuICAgICAgICAgICAgZW5hYmxlZEJ1ZmZlck9wdGltaXphdGlvbiwgaXRlbVRyYW5zZm9ybSwgYWxpZ25tZW50LCBwcmVjYWxjdWxhdGVkU2Nyb2xsU3RhcnRPZmZzZXQsIHByZWNhbGN1bGF0ZWRTY3JvbGxFbmRPZmZzZXQsIGNhY2hlVmVyc2lvbixcclxuICAgICAgICAgIF0pID0+IHtcclxuICAgICAgICAgICAgbGV0IGl0ZW1zQ2hhbmdlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBpZiAocHJldkl0ZW1zICE9PSBpdGVtcykge1xyXG4gICAgICAgICAgICAgIGl0ZW1zQ2hhbmdlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgcHJldkl0ZW1zID0gaXRlbXM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgZW5hYmxlZE9wdGltaXphdGlvbiA9IHRoaXMuc2Nyb2xsaW5nU2V0dGluZ3M/Lm9wdGltaXphdGlvbiA/PyBERUZBVUxUX1NDUk9MTElOR19TRVRUSU5HUy5vcHRpbWl6YXRpb24sXHJcbiAgICAgICAgICAgICAgdmVsb2NpdHkgPSB0aGlzLl9zY3JvbGxlckNvbXBvbmVudD8uYXZlcmFnZVZlbG9jaXR5ID8/IDAsXHJcbiAgICAgICAgICAgICAgaXNTY3JvbGxpbmcgPSB0aGlzLl8kc2Nyb2xsaW5nVG8uZ2V0VmFsdWUoKSxcclxuICAgICAgICAgICAgICB1c2VEZWJvdW5jZWRVcGRhdGUgPSAoZHluYW1pY1NpemUgJiYgIWl0ZW1UcmFuc2Zvcm0pICYmICEoc25hcFNjcm9sbFRvRW5kICYmIHRoaXMuX3RyYWNrQm94LmlzU25hcHBlZFRvRW5kKSAmJiAhaXRlbXNDaGFuZ2VkICYmIGhhc1VzZXJBY3Rpb24gJiYgIWlzU2Nyb2xsaW5nICYmXHJcbiAgICAgICAgICAgICAgICAodmVsb2NpdHkgPiAwICYmIHZlbG9jaXR5IDwgTUFYX1ZFTE9DSVRZX0ZPUl9TQ1JPTExfUVVBTElUWV9PUFRJTUlaQVRJT05fTFZMMSk7XHJcbiAgICAgICAgICAgIGlmIChlbmFibGVkT3B0aW1pemF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgaWYgKHVzZURlYm91bmNlZFVwZGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgZGVib3VuY2VkVXBkYXRlLmV4ZWN1dGUoe1xyXG4gICAgICAgICAgICAgICAgICB0cmFja0J5LCBpc0luZmluaXR5LCBzbmFwU2Nyb2xsVG9TdGFydCwgc25hcFNjcm9sbFRvRW5kLCBib3VuZHM6IGJvdW5kcyEsIGxpc3RCb3VuZHM6IGxpc3RCb3VuZHMhLCBzY3JvbGxFbmRPZmZzZXQsIGl0ZW1zLCBpdGVtQ29uZmlnTWFwLCBzY3JvbGxTaXplLCBpdGVtU2l6ZSwgbWluSXRlbVNpemUsXHJcbiAgICAgICAgICAgICAgICAgIG1heEl0ZW1TaXplLCBjb2xsYXBzZWRJZHMsIGJ1ZmZlclNpemUsIG1heEJ1ZmZlclNpemUsIHN0aWNreUVuYWJsZWQsIGlzVmVydGljYWwsIGR5bmFtaWNTaXplLCBkaXZpZGVzLCBlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uLCBpdGVtVHJhbnNmb3JtLFxyXG4gICAgICAgICAgICAgICAgICBzbmFwVG9JdGVtLCBzbmFwVG9JdGVtQWxpZ24sIGFsaWdubWVudCwgcHJlY2FsY3VsYXRlZFNjcm9sbFN0YXJ0T2Zmc2V0LCBwcmVjYWxjdWxhdGVkU2Nyb2xsRW5kT2Zmc2V0LCBjYWNoZVZlcnNpb24sIHVzZXJBY3Rpb246IGhhc1VzZXJBY3Rpb24sXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgIGRlYm91bmNlZFVwZGF0ZS5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghaXNTY3JvbGxpbmcpIHtcclxuICAgICAgICAgICAgICB1cGRhdGUoe1xyXG4gICAgICAgICAgICAgICAgdHJhY2tCeSwgaXNJbmZpbml0eSwgc25hcFNjcm9sbFRvU3RhcnQsIHNuYXBTY3JvbGxUb0VuZCwgYm91bmRzOiBib3VuZHMhLCBsaXN0Qm91bmRzOiBsaXN0Qm91bmRzISwgc2Nyb2xsRW5kT2Zmc2V0LCBpdGVtcywgaXRlbUNvbmZpZ01hcCwgc2Nyb2xsU2l6ZSwgaXRlbVNpemUsIG1pbkl0ZW1TaXplLFxyXG4gICAgICAgICAgICAgICAgbWF4SXRlbVNpemUsIGNvbGxhcHNlZElkcywgYnVmZmVyU2l6ZSwgbWF4QnVmZmVyU2l6ZSwgc3RpY2t5RW5hYmxlZCwgaXNWZXJ0aWNhbCwgZHluYW1pY1NpemUsIGRpdmlkZXMsIGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24sIGl0ZW1UcmFuc2Zvcm0sXHJcbiAgICAgICAgICAgICAgICBzbmFwVG9JdGVtLCBzbmFwVG9JdGVtQWxpZ24sIGFsaWdubWVudCwgcHJlY2FsY3VsYXRlZFNjcm9sbFN0YXJ0T2Zmc2V0LCBwcmVjYWxjdWxhdGVkU2Nyb2xsRW5kT2Zmc2V0LCBjYWNoZVZlcnNpb24sIHVzZXJBY3Rpb246IGhhc1VzZXJBY3Rpb24sXHJcbiAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pLFxyXG4gICAgICAgICk7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICBjb25zdCAkc2Nyb2xsZXIgPSB0aGlzLiRzY3JvbGxlci5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZmlsdGVyKHYgPT4gISF2KSxcclxuICAgICAgbWFwKHYgPT4gdiEubmF0aXZlRWxlbWVudCksXHJcbiAgICAgIHRha2UoMSksXHJcbiAgICApLFxyXG4gICAgICAkc2Nyb2xsZXJTY3JvbGwgPSAkc2Nyb2xsZXJDb21wb25lbnQucGlwZShcclxuICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICBmaWx0ZXIodiA9PiAhIXYpLFxyXG4gICAgICAgIHRha2UoMSksXHJcbiAgICAgICAgc3dpdGNoTWFwKHNjcm9sbGVyID0+IHNjcm9sbGVyIS4kc2Nyb2xsKSxcclxuICAgICAgKSxcclxuICAgICAgJHNjcm9sbGVyU2Nyb2xsRW5kID0gJHNjcm9sbGVyQ29tcG9uZW50LnBpcGUoXHJcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgICAgZmlsdGVyKHYgPT4gISF2KSxcclxuICAgICAgICB0YWtlKDEpLFxyXG4gICAgICAgIHN3aXRjaE1hcChzY3JvbGxlciA9PiBzY3JvbGxlciEuJHNjcm9sbEVuZCksXHJcbiAgICAgICksXHJcbiAgICAgICRzY3JvbGxiYXJTY3JvbGwgPSAkc2Nyb2xsZXJDb21wb25lbnQucGlwZShcclxuICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICBmaWx0ZXIodiA9PiAhIXYpLFxyXG4gICAgICAgIHRha2UoMSksXHJcbiAgICAgICAgc3dpdGNoTWFwKHNjcm9sbGVyID0+IHNjcm9sbGVyIS4kc2Nyb2xsYmFyU2Nyb2xsKSxcclxuICAgICAgKTtcclxuXHJcbiAgICBjb25zdCBzY3JvbGxIYW5kbGVyID0gKHVzZXJBY3Rpb246IGJvb2xlYW4gPSBmYWxzZSkgPT4ge1xyXG4gICAgICBjb25zdCBzY3JvbGxlciA9IHRoaXMuX3Njcm9sbGVyQ29tcG9uZW50O1xyXG4gICAgICBpZiAoISFzY3JvbGxlcikge1xyXG4gICAgICAgIGNvbnN0IGlzVmVydGljYWwgPSB0aGlzLl9pc1ZlcnRpY2FsLFxyXG4gICAgICAgICAgc2Nyb2xsU2l6ZSA9IChpc1ZlcnRpY2FsID8gc2Nyb2xsZXIuc2Nyb2xsVG9wIDogc2Nyb2xsZXIuc2Nyb2xsTGVmdCksXHJcbiAgICAgICAgICBhY3R1YWxTY3JvbGxTaXplID0gc2Nyb2xsU2l6ZTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX3JlYWR5Rm9yU2hvdykge1xyXG4gICAgICAgICAgaWYgKHVzZXJBY3Rpb24pIHtcclxuICAgICAgICAgICAgdGhpcy5fJHByZXZlbnRTY3JvbGxTbmFwcGluZy5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fJHNjcm9sbFNpemUubmV4dChhY3R1YWxTY3JvbGxTaXplKTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAkc2Nyb2xsZXIucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXHJcbiAgICAgIHN3aXRjaE1hcChzY3JvbGxlciA9PiB7XHJcbiAgICAgICAgcmV0dXJuICRzY3JvbGxiYXJTY3JvbGwucGlwZShcclxuICAgICAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICAgICAgdGFwKHVzZXJBY3Rpb24gPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBzY3JvbGxlckVsID0gdGhpcy5fJHNjcm9sbGVyLmdldFZhbHVlKCk/Lm5hdGl2ZUVsZW1lbnQsIHNjcm9sbGVyQ29tcG9uZW50ID0gdGhpcy5fc2Nyb2xsZXJDb21wb25lbnQ7XHJcbiAgICAgICAgICAgIGlmICghIXNjcm9sbGVyRWwgJiYgISFzY3JvbGxlckNvbXBvbmVudCkge1xyXG4gICAgICAgICAgICAgIHRoaXMuZW1pdFNjcm9sbEV2ZW50KGZhbHNlLCB0aGlzLl9yZWFkeUZvclNob3csIGhhc1VzZXJBY3Rpb24pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9yZWFkeUZvclNob3cpIHtcclxuICAgICAgICAgICAgICBpZiAodXNlckFjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3RyYWNrQm94LmlzU25hcHBlZFRvU3RhcnQpIHtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5fJHByZXZlbnRTY3JvbGxTbmFwcGluZy5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3RyYWNrQm94LmlzU25hcHBlZFRvRW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuXyRwcmV2ZW50U2Nyb2xsU25hcHBpbmcubmV4dCh0cnVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pLFxyXG4gICAgICAgICk7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAkc2Nyb2xsZXIucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXHJcbiAgICAgIHN3aXRjaE1hcChzY3JvbGxlciA9PiB7XHJcbiAgICAgICAgcmV0dXJuICRzY3JvbGxlclNjcm9sbC5waXBlKFxyXG4gICAgICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgICAgKTtcclxuICAgICAgfSksXHJcbiAgICAgIHRhcCh1c2VyQWN0aW9uID0+IHtcclxuICAgICAgICBoYXNVc2VyQWN0aW9uID0gdXNlckFjdGlvbjtcclxuICAgICAgICBjb25zdCBzY3JvbGxlckVsID0gdGhpcy5fJHNjcm9sbGVyLmdldFZhbHVlKCk/Lm5hdGl2ZUVsZW1lbnQsIHNjcm9sbGVyQ29tcG9uZW50ID0gdGhpcy5fc2Nyb2xsZXJDb21wb25lbnQ7XHJcbiAgICAgICAgaWYgKCEhc2Nyb2xsZXJFbCAmJiAhIXNjcm9sbGVyQ29tcG9uZW50KSB7XHJcbiAgICAgICAgICB0aGlzLmVtaXRTY3JvbGxFdmVudChmYWxzZSwgdGhpcy5fcmVhZHlGb3JTaG93LCB1c2VyQWN0aW9uKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgc2Nyb2xsSGFuZGxlcih1c2VyQWN0aW9uKTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRzY3JvbGxlci5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgc3dpdGNoTWFwKHNjcm9sbGVyID0+IHtcclxuICAgICAgICByZXR1cm4gJHNjcm9sbGVyU2Nyb2xsRW5kLnBpcGUoXHJcbiAgICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICApO1xyXG4gICAgICB9KSxcclxuICAgICAgdGFwKHVzZXJBY3Rpb24gPT4ge1xyXG4gICAgICAgIGhhc1VzZXJBY3Rpb24gPSB1c2VyQWN0aW9uO1xyXG4gICAgICAgIGNvbnN0IHNjcm9sbGVyRWwgPSB0aGlzLl8kc2Nyb2xsZXIuZ2V0VmFsdWUoKT8ubmF0aXZlRWxlbWVudCwgc2Nyb2xsZXJDb21wb25lbnQgPSB0aGlzLl9zY3JvbGxlckNvbXBvbmVudDtcclxuICAgICAgICBpZiAoISFzY3JvbGxlckVsICYmICEhc2Nyb2xsZXJDb21wb25lbnQpIHtcclxuICAgICAgICAgIHRoaXMuZW1pdFNjcm9sbEV2ZW50KHRydWUsIHRoaXMuX3JlYWR5Rm9yU2hvdywgdXNlckFjdGlvbik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNjcm9sbEhhbmRsZXIodXNlckFjdGlvbik7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICBjb25zdCAkc2Nyb2xsVG8gPSB0aGlzLiRzY3JvbGxUbyxcclxuICAgICAgJHNjcm9sbFRvRXhlY3V0b3IgPSB0aGlzLiRzY3JvbGxUb0V4ZWN1dG9yO1xyXG5cclxuICAgIGNvbWJpbmVMYXRlc3QoWyRzY3JvbGxlciwgJHRyYWNrQnksICRzY3JvbGxUb10pLnBpcGUoXHJcbiAgICAgIGZpbHRlcigoW3Njcm9sbGVyLCAsIGV2ZW50XSkgPT4gISFzY3JvbGxlciAmJiAhIWV2ZW50KSxcclxuICAgICAgbWFwKChbc2Nyb2xsZXIsIHRyYWNrQnksIGV2ZW50XSkgPT4gKHsgc2Nyb2xsZXI6IHNjcm9sbGVyLCB0cmFja0J5LCBldmVudCB9KSksXHJcbiAgICAgIHN3aXRjaE1hcCgoeyBldmVudCB9KSA9PiB7XHJcbiAgICAgICAgY29uc3QgZCA9IGV2ZW50Py5kZWxheSA/PyAwO1xyXG4gICAgICAgIGlmIChkID4gMCkge1xyXG4gICAgICAgICAgcmV0dXJuIG9mKGV2ZW50KS5waXBlKFxyXG4gICAgICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICAgICAgZGVsYXkoZCksXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb2YoZXZlbnQpO1xyXG4gICAgICB9KSxcclxuICAgICAgdGFwKGV2ZW50ID0+IHtcclxuICAgICAgICB0aGlzLl8kc2Nyb2xsaW5nVG8ubmV4dCh0cnVlKTtcclxuICAgICAgICB0aGlzLl8kc2Nyb2xsVG9FeGVjdXRvci5uZXh0KGV2ZW50KTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRzY3JvbGxUb0V4ZWN1dG9yLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBzd2l0Y2hNYXAoZXZlbnQgPT4ge1xyXG4gICAgICAgIGNvbnN0IHRyYWNrQnkgPSB0aGlzLnRyYWNrQnksIHNjcm9sbGVyQ29tcG9uZW50ID0gdGhpcy5fc2Nyb2xsZXJDb21wb25lbnQsXHJcbiAgICAgICAgICB7IGlkLCBpdGVyYXRpb24gPSAwLCBibGVuZGluZyA9IGZhbHNlLCBpc0xhc3RJdGVyYXRpb24gPSBmYWxzZSwgY2IgfSA9IGV2ZW50O1xyXG4gICAgICAgIGNvbnN0IG5leHRJdGVyYXRpb24gPSBpdGVyYXRpb24gKyAxLCBmaW5pc2hlZCA9IG5leHRJdGVyYXRpb24gPj0gTUFYX1NDUk9MTF9UT19JVEVSQVRJT05TLCBmaXJlVXBkYXRlID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5fcmVhZHlGb3JTaG93KSB7XHJcbiAgICAgICAgICByZXR1cm4gb2YoW2ZpbmlzaGVkLCB7IGlkLCBpdGVyYXRpb246IG5leHRJdGVyYXRpb24sIGJsZW5kaW5nLCBjYiB9XSkucGlwZShkZWxheSgwKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBkZWJvdW5jZWRVcGRhdGUuZGlzcG9zZSgpO1xyXG4gICAgICAgIHRoaXMuXyRwcmV2ZW50U2Nyb2xsU25hcHBpbmcubmV4dCh0cnVlKTtcclxuXHJcbiAgICAgICAgaWYgKCEhc2Nyb2xsZXJDb21wb25lbnQpIHtcclxuICAgICAgICAgIHNjcm9sbGVyQ29tcG9uZW50LnN0YXJ0U2Nyb2xsVG8oKTtcclxuXHJcbiAgICAgICAgICBjb25zdCBpdGVtcyA9IHRoaXMuXyRhY3R1YWxJdGVtcy5nZXRWYWx1ZSgpO1xyXG4gICAgICAgICAgaWYgKCEhaXRlbXMgJiYgaXRlbXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGR5bmFtaWNTaXplID0gdGhpcy5keW5hbWljU2l6ZSwgaXRlbVNpemUgPSB0aGlzLmFjdHVhbEl0ZW1TaXplLCBtaW5JdGVtU2l6ZSA9IHRoaXMuYWN0dWFsTWluSXRlbVNpemUsXHJcbiAgICAgICAgICAgICAgbWF4SXRlbVNpemUgPSB0aGlzLmFjdHVhbE1heEl0ZW1TaXplLCBzbmFwU2Nyb2xsVG9FbmQgPSB0aGlzLnNuYXBTY3JvbGxUb0VuZDtcclxuXHJcbiAgICAgICAgICAgIGlmIChkeW5hbWljU2l6ZSkge1xyXG4gICAgICAgICAgICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gdGhpcy5fJGJvdW5kcy5nZXRWYWx1ZSgpIHx8IHsgd2lkdGg6IERFRkFVTFRfTElTVF9TSVpFLCBoZWlnaHQ6IERFRkFVTFRfTElTVF9TSVpFIH0sXHJcbiAgICAgICAgICAgICAgICBpdGVtQ29uZmlnTWFwID0gdGhpcy5pdGVtQ29uZmlnTWFwLCBpc1ZlcnRpY2FsID0gdGhpcy5faXNWZXJ0aWNhbCxcclxuICAgICAgICAgICAgICAgIGN1cnJlbnRTY3JvbGxTaXplID0gaXNWZXJ0aWNhbCA/IHNjcm9sbGVyQ29tcG9uZW50LnNjcm9sbFRvcCA6IHNjcm9sbGVyQ29tcG9uZW50LnNjcm9sbExlZnQsXHJcbiAgICAgICAgICAgICAgICBvcHRzOiBJR2V0SXRlbVBvc2l0aW9uT3B0aW9uczxJVmlydHVhbExpc3RJdGVtLCBJVmlydHVhbExpc3RDb2xsZWN0aW9uPiA9IHtcclxuICAgICAgICAgICAgICAgICAgYm91bmRzOiB7IHdpZHRoLCBoZWlnaHQgfSwgY29sbGVjdGlvbjogaXRlbXMsIGR5bmFtaWNTaXplLCBpc1ZlcnRpY2FsOiB0aGlzLl9pc1ZlcnRpY2FsLCBpdGVtU2l6ZSwgbWluSXRlbVNpemUsIG1heEl0ZW1TaXplLFxyXG4gICAgICAgICAgICAgICAgICBidWZmZXJTaXplOiB0aGlzLmJ1ZmZlclNpemUsIG1heEJ1ZmZlclNpemU6IHRoaXMubWF4QnVmZmVyU2l6ZSwgaXRlbVRyYW5zZm9ybTogdGhpcy5pdGVtVHJhbnNmb3JtLFxyXG4gICAgICAgICAgICAgICAgICBzY3JvbGxTaXplOiAoaXNWZXJ0aWNhbCA/IHNjcm9sbGVyQ29tcG9uZW50LnNjcm9sbFRvcCA6IHNjcm9sbGVyQ29tcG9uZW50LnNjcm9sbExlZnQpLFxyXG4gICAgICAgICAgICAgICAgICBzbmFwVG9JdGVtOiB0aGlzLnNuYXBUb0l0ZW0sIHNuYXBUb0l0ZW1BbGlnbjogdGhpcy5zbmFwVG9JdGVtQWxpZ24sXHJcbiAgICAgICAgICAgICAgICAgIHN0aWNreUVuYWJsZWQ6IHRoaXMuc3RpY2t5RW5hYmxlZCwgZnJvbUl0ZW1JZDogaWQsIGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb246IHRoaXMuZW5hYmxlZEJ1ZmZlck9wdGltaXphdGlvbixcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgIGxldCBzY3JvbGxTaXplID0gc25hcFNjcm9sbFRvRW5kICYmIHRoaXMuX3RyYWNrQm94LmlzU25hcHBlZFRvRW5kID9cclxuICAgICAgICAgICAgICAgIChpc1ZlcnRpY2FsID8gc2Nyb2xsZXJDb21wb25lbnQuc2Nyb2xsSGVpZ2h0IDogc2Nyb2xsZXJDb21wb25lbnQuc2Nyb2xsV2lkdGgpIDpcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RyYWNrQm94LmdldEl0ZW1Qb3NpdGlvbihpZCwgaXRlbUNvbmZpZ01hcCwgb3B0cyk7XHJcblxyXG4gICAgICAgICAgICAgIGlmIChzY3JvbGxTaXplID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9mKFtmaW5pc2hlZCwgeyBpZCwgYmxlbmRpbmcsIGl0ZXJhdGlvbjogbmV4dEl0ZXJhdGlvbiwgY2IgfV0pLnBpcGUoZGVsYXkoMCkpO1xyXG4gICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgdGhpcy5fdHJhY2tCb3guY2xlYXJEZWx0YSgpO1xyXG5cclxuICAgICAgICAgICAgICBjb25zdCB2aWV3cG9ydFNpemUgPSAoaXNWZXJ0aWNhbCA/IGhlaWdodCA6IHdpZHRoKSxcclxuICAgICAgICAgICAgICAgIHsgZGlzcGxheUl0ZW1zLCB0b3RhbFNpemUsIGxlZnRMYXlvdXRPZmZzZXQgfSA9IHRoaXMuX3RyYWNrQm94LnVwZGF0ZUNvbGxlY3Rpb24oaXRlbXMsIGl0ZW1Db25maWdNYXAsIHtcclxuICAgICAgICAgICAgICAgICAgLi4ub3B0cywgc2Nyb2xsU2l6ZSwgZnJvbUl0ZW1JZDogaXNMYXN0SXRlcmF0aW9uID8gdW5kZWZpbmVkIDogaWQsXHJcbiAgICAgICAgICAgICAgICB9KSwgZGVsdGExID0gdGhpcy5fdHJhY2tCb3guZGVsdGE7XHJcblxyXG4gICAgICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRUb3RhbFNpemUgPSB0b3RhbFNpemUgPCB2aWV3cG9ydFNpemUgPyB2aWV3cG9ydFNpemUgOiB0b3RhbFNpemU7XHJcblxyXG4gICAgICAgICAgICAgIHNjcm9sbGVyQ29tcG9uZW50LnN0YXJ0TGF5b3V0T2Zmc2V0ID0gbGVmdExheW91dE9mZnNldDtcclxuXHJcbiAgICAgICAgICAgICAgc2Nyb2xsZXJDb21wb25lbnQudG90YWxTaXplID0gbm9ybWFsaXplZFRvdGFsU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgdGhpcy5fc2VydmljZS5jb2xsZWN0aW9uID0gZGlzcGxheUl0ZW1zO1xyXG5cclxuICAgICAgICAgICAgICBsZXQgYWN0dWFsU2Nyb2xsU2l6ZSA9IHNjcm9sbFNpemUgKyBkZWx0YTE7XHJcblxyXG4gICAgICAgICAgICAgIHRoaXMucmVzZXRCb3VuZHNTaXplKGlzVmVydGljYWwsIG5vcm1hbGl6ZWRUb3RhbFNpemUpO1xyXG5cclxuICAgICAgICAgICAgICB0aGlzLmNyZWF0ZURpc3BsYXlDb21wb25lbnRzSWZOZWVkKGRpc3BsYXlJdGVtcyk7XHJcblxyXG4gICAgICAgICAgICAgIHRoaXMudHJhY2tpbmcoKTtcclxuXHJcbiAgICAgICAgICAgICAgdGhpcy5zbmFwcGluZ0hhbmRsZXIoKTtcclxuXHJcbiAgICAgICAgICAgICAgc2Nyb2xsU2l6ZSA9IHRoaXMuX3RyYWNrQm94LmdldEl0ZW1Qb3NpdGlvbihpZCwgaXRlbUNvbmZpZ01hcCwgeyAuLi5vcHRzLCBzY3JvbGxTaXplOiBhY3R1YWxTY3JvbGxTaXplLCBmcm9tSXRlbUlkOiBpZCB9KTtcclxuXHJcbiAgICAgICAgICAgICAgaWYgKHRoaXMuaXNJbmZpbml0eSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc25hcFRvSXRlbSkge1xyXG4gICAgICAgICAgICAgICAgICBjb25zdCBpdGVtQm91bmRzID0gdGhpcy5fdHJhY2tCb3guZ2V0SXRlbUJvdW5kcyhpZCk7XHJcbiAgICAgICAgICAgICAgICAgIGlmICghIWl0ZW1Cb3VuZHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpdGVtU2l6ZSA9IGlzVmVydGljYWwgPyBpdGVtQm91bmRzLmhlaWdodCA6IGl0ZW1Cb3VuZHMud2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0aGlzLnNuYXBUb0l0ZW1BbGlnbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgY2FzZSBTbmFwVG9JdGVtQWxpZ25zLkNFTlRFUjoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxTaXplICs9IGl0ZW1TaXplICogLjU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgaWYgKHNjcm9sbFNpemUgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gb2YoW2ZpbmlzaGVkLCB7IGlkLCBibGVuZGluZywgaXRlcmF0aW9uOiBuZXh0SXRlcmF0aW9uLCBjYiB9XSkucGlwZShkZWxheSgwKSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGNvbnN0IG5vdENoYW5nZWQgPSBzY3JvbGxTaXplID09PSBjdXJyZW50U2Nyb2xsU2l6ZTtcclxuICAgICAgICAgICAgICBpZiAoIW5vdENoYW5nZWQgJiYgaXRlcmF0aW9uIDwgTUFYX1NDUk9MTF9UT19JVEVSQVRJT05TKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl90cmFja0JveC5jbGVhckRlbHRhKCk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJhbXM6IElTY3JvbGxUb1BhcmFtcyA9IHtcclxuICAgICAgICAgICAgICAgICAgW2lzVmVydGljYWwgPyBUT1BfUFJPUF9OQU1FIDogTEVGVF9QUk9QX05BTUVdOiBzY3JvbGxTaXplLCBiZWhhdmlvcjogQkVIQVZJT1JfSU5TVEFOVCBhcyBTY3JvbGxCZWhhdmlvcixcclxuICAgICAgICAgICAgICAgICAgZmlyZVVwZGF0ZSwgYmxlbmRpbmcsIGZvcmNlOiB0cnVlLCBzbmFwOiBmYWxzZSwgbm9ybWFsaXplOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICBzY3JvbGxlckNvbXBvbmVudD8uc2Nyb2xsVG8/LihwYXJhbXMpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9mKFtmaW5pc2hlZCwge1xyXG4gICAgICAgICAgICAgICAgICBpZCwgaXRlcmF0aW9uOiBuZXh0SXRlcmF0aW9uLCBibGVuZGluZyxcclxuICAgICAgICAgICAgICAgICAgaXNMYXN0SXRlcmF0aW9uOiBuZXh0SXRlcmF0aW9uIDwgTUFYX1NDUk9MTF9UT19JVEVSQVRJT05TLCBjYlxyXG4gICAgICAgICAgICAgICAgfV0pLnBpcGUoZGVsYXkoMCkpO1xyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl8kc2Nyb2xsU2l6ZS5uZXh0KGFjdHVhbFNjcm9sbFNpemUpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9mKFt0cnVlLCB7IGlkLCBibGVuZGluZywgaXRlcmF0aW9uOiBuZXh0SXRlcmF0aW9uLCBjYiB9XSkucGlwZShkZWxheSgwKSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gaXRlbXMuZmluZEluZGV4KGl0ZW0gPT4gaXRlbVt0cmFja0J5XSA9PT0gaWQpO1xyXG4gICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpc1ZlcnRpY2FsID0gdGhpcy5faXNWZXJ0aWNhbCwgaXRlbVNpemUgPSB0aGlzLmFjdHVhbEl0ZW1TaXplO1xyXG4gICAgICAgICAgICAgICAgbGV0IHNjcm9sbFNpemUgPSBpbmRleCAqIGl0ZW1TaXplO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzSW5maW5pdHkpIHtcclxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc25hcFRvSXRlbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodGhpcy5zbmFwVG9JdGVtQWxpZ24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU25hcFRvSXRlbUFsaWducy5DRU5URVI6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsU2l6ZSArPSBpdGVtU2l6ZSAqIC41O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IHRoaXMuXyRib3VuZHMuZ2V0VmFsdWUoKSB8fCB7IHdpZHRoOiBERUZBVUxUX0xJU1RfU0laRSwgaGVpZ2h0OiBERUZBVUxUX0xJU1RfU0laRSB9LFxyXG4gICAgICAgICAgICAgICAgICBpdGVtQ29uZmlnTWFwID0gdGhpcy5pdGVtQ29uZmlnTWFwLCBpdGVtcyA9IHRoaXMuXyRhY3R1YWxJdGVtcy5nZXRWYWx1ZSgpLFxyXG4gICAgICAgICAgICAgICAgICBvcHRzOiBJR2V0SXRlbVBvc2l0aW9uT3B0aW9uczxJVmlydHVhbExpc3RJdGVtLCBJVmlydHVhbExpc3RDb2xsZWN0aW9uPiA9IHtcclxuICAgICAgICAgICAgICAgICAgICBib3VuZHM6IHsgd2lkdGgsIGhlaWdodCB9LCBjb2xsZWN0aW9uOiBpdGVtcywgZHluYW1pY1NpemUsIGlzVmVydGljYWw6IHRoaXMuX2lzVmVydGljYWwsIGl0ZW1TaXplLCBtaW5JdGVtU2l6ZSwgbWF4SXRlbVNpemUsXHJcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyU2l6ZTogdGhpcy5idWZmZXJTaXplLCBtYXhCdWZmZXJTaXplOiB0aGlzLm1heEJ1ZmZlclNpemUsIGl0ZW1UcmFuc2Zvcm06IHRoaXMuaXRlbVRyYW5zZm9ybSxcclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxTaXplOiAoaXNWZXJ0aWNhbCA/IHNjcm9sbGVyQ29tcG9uZW50LnNjcm9sbFRvcCA6IHNjcm9sbGVyQ29tcG9uZW50LnNjcm9sbExlZnQpLFxyXG4gICAgICAgICAgICAgICAgICAgIHNuYXBUb0l0ZW06IHRoaXMuc25hcFRvSXRlbSwgc25hcFRvSXRlbUFsaWduOiB0aGlzLnNuYXBUb0l0ZW1BbGlnbixcclxuICAgICAgICAgICAgICAgICAgICBzdGlja3lFbmFibGVkOiB0aGlzLnN0aWNreUVuYWJsZWQsIGZyb21JdGVtSWQ6IGlkLCBlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uOiB0aGlzLmVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24sXHJcbiAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5fdHJhY2tCb3guY2xlYXJEZWx0YSgpO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHZpZXdwb3J0U2l6ZSA9IChpc1ZlcnRpY2FsID8gaGVpZ2h0IDogd2lkdGgpLFxyXG4gICAgICAgICAgICAgICAgICB7IGRpc3BsYXlJdGVtcywgdG90YWxTaXplLCBsZWZ0TGF5b3V0T2Zmc2V0IH0gPSB0aGlzLl90cmFja0JveC51cGRhdGVDb2xsZWN0aW9uKGl0ZW1zLCBpdGVtQ29uZmlnTWFwLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgLi4ub3B0cywgc2Nyb2xsU2l6ZSwgZnJvbUl0ZW1JZDogaXNMYXN0SXRlcmF0aW9uID8gdW5kZWZpbmVkIDogaWQsXHJcbiAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGFjdHVhbFRvdGFsU2l6ZSA9IHRoaXMuaXNJbmZpbml0eSA/ICh0b3RhbFNpemUgKyB2aWV3cG9ydFNpemUpIDogdG90YWxTaXplO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRUb3RhbFNpemUgPSBhY3R1YWxUb3RhbFNpemUgPCB2aWV3cG9ydFNpemUgPyB2aWV3cG9ydFNpemUgOiBhY3R1YWxUb3RhbFNpemU7XHJcblxyXG4gICAgICAgICAgICAgICAgc2Nyb2xsZXJDb21wb25lbnQuc3RhcnRMYXlvdXRPZmZzZXQgPSBsZWZ0TGF5b3V0T2Zmc2V0O1xyXG5cclxuICAgICAgICAgICAgICAgIHNjcm9sbGVyQ29tcG9uZW50LnRvdGFsU2l6ZSA9IG5vcm1hbGl6ZWRUb3RhbFNpemU7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2VydmljZS5jb2xsZWN0aW9uID0gZGlzcGxheUl0ZW1zO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMucmVzZXRCb3VuZHNTaXplKGlzVmVydGljYWwsIG5vcm1hbGl6ZWRUb3RhbFNpemUpO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlRGlzcGxheUNvbXBvbmVudHNJZk5lZWQoZGlzcGxheUl0ZW1zKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLnRyYWNraW5nKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5zbmFwcGluZ0hhbmRsZXIoKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl8kcHJldmVudFNjcm9sbFNuYXBwaW5nLm5leHQodHJ1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgcGFyYW1zOiBJU2Nyb2xsVG9QYXJhbXMgPSB7XHJcbiAgICAgICAgICAgICAgICAgIFt0aGlzLl9pc1ZlcnRpY2FsID8gVE9QX1BST1BfTkFNRSA6IExFRlRfUFJPUF9OQU1FXTogc2Nyb2xsU2l6ZSwgZmlyZVVwZGF0ZTogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgIGJlaGF2aW9yOiBCRUhBVklPUl9JTlNUQU5UIGFzIFNjcm9sbEJlaGF2aW9yLCBibGVuZGluZywgZm9yY2U6IHRydWUsIHNuYXA6IGZhbHNlLCBub3JtYWxpemU6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHNjcm9sbGVyQ29tcG9uZW50Py5zY3JvbGxUbz8uKHBhcmFtcyk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gb2YoW3RydWUsIHsgaWQsIGJsZW5kaW5nLCBpdGVyYXRpb246IG5leHRJdGVyYXRpb24sIGNiIH1dKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9mKFtmaW5pc2hlZCwgeyBpZCwgaXRlcmF0aW9uOiBuZXh0SXRlcmF0aW9uLCBibGVuZGluZywgY2IgfV0pO1xyXG4gICAgICB9KSxcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcCgoW2ZpbmlzaGVkLCBwYXJhbXNdKSA9PiB7XHJcbiAgICAgICAgaWYgKCFmaW5pc2hlZCkge1xyXG4gICAgICAgICAgdGhpcy5fJHNjcm9sbFRvRXhlY3V0b3IubmV4dChwYXJhbXMgYXMgSVNjcm9sbFBhcmFtcyk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5fcmVhZHlGb3JTaG93KSB7XHJcbiAgICAgICAgICB0aGlzLl90cmFja0JveC5wcmV2ZW50U2Nyb2xsU25hcHBpbmcodHJ1ZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl8kc2Nyb2xsaW5nVG8ubmV4dChmYWxzZSk7XHJcbiAgICAgICAgdGhpcy5fc2Nyb2xsZXJDb21wb25lbnQ/LmZpbmlzaGVkU2Nyb2xsVG8oKTtcclxuICAgICAgICB0aGlzLl8kZmlyZVVwZGF0ZS5uZXh0KHRydWUpO1xyXG4gICAgICAgIHRoaXMuZW1pdFNjcm9sbEV2ZW50KHRydWUsIGZhbHNlLCB0cnVlKTtcclxuICAgICAgICBjb25zdCBzY3JvbGxQYXJhbXMgPSBwYXJhbXMgYXMgSVNjcm9sbFBhcmFtcyAmIHsgc2Nyb2xsQ2FsbGVkOiBib29sZWFuOyB9O1xyXG4gICAgICAgIHNjcm9sbFBhcmFtcz8uY2I/LigpO1xyXG4gICAgICB9KSxcclxuICAgICAgZGVsYXkoMTAwKSxcclxuICAgICAgdGFwKChbZmluaXNoZWRdKSA9PiB7XHJcbiAgICAgICAgaWYgKGZpbmlzaGVkKSB7XHJcbiAgICAgICAgICB0aGlzLl9zY3JvbGxlckNvbXBvbmVudD8uc25hcElmTmVlZCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIGNvbnN0ICRpdGVtUmVuZGVyZXIgPSB0aGlzLiRpdGVtUmVuZGVyZXI7XHJcblxyXG4gICAgJGl0ZW1SZW5kZXJlci5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgZmlsdGVyKHYgPT4gISF2KSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuXyRpdGVtUmVuZGVyZXIubmV4dCh2KTtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRib3VuZHMucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXHJcbiAgICAgIGZpbHRlcih2ID0+ICEhdiksXHJcbiAgICAgIHRhcCh2YWx1ZSA9PiB7XHJcbiAgICAgICAgY29uc3Qgc2l6ZTogSVNpemUgPSB7IHdpZHRoOiB2YWx1ZSEud2lkdGgsIGhlaWdodDogdmFsdWUhLmhlaWdodCB9O1xyXG4gICAgICAgIHRoaXMub25WaWV3cG9ydENoYW5nZS5lbWl0KG9iamVjdEFzUmVhZG9ubHkoc2l6ZSkpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgdGhpcy5fc2VydmljZS4kdmlydHVhbENsaWNrLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgdGhpcy5vbkl0ZW1DbGljay5lbWl0KG9iamVjdEFzUmVhZG9ubHkodikpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgbGV0IGlzU2VsZWN0ZWRJZHNGaXJzdEVtaXQgPSAwO1xyXG5cclxuICAgIHRoaXMuX3NlcnZpY2UuJHNlbGVjdGVkSWRzLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2lzU2luZ2xlU2VsZWN0aW9uIHx8ICh0aGlzLl9pc011bHRpU2VsZWN0aW9uICYmIGlzU2VsZWN0ZWRJZHNGaXJzdEVtaXQgPj0gMikpIHtcclxuICAgICAgICAgIGNvbnN0IGN1cnIgPSB0aGlzLnNlbGVjdGVkSWRzO1xyXG4gICAgICAgICAgaWYgKCh0aGlzLl9pc1NpbmdsZVNlbGVjdGlvbiAmJiBKU09OLnN0cmluZ2lmeSh2KSAhPT0gSlNPTi5zdHJpbmdpZnkoY3VycikpIHx8XHJcbiAgICAgICAgICAgIChpc1NlbGVjdGVkSWRzRmlyc3RFbWl0ID09PSAyICYmIEpTT04uc3RyaW5naWZ5KHYpICE9PSBKU09OLnN0cmluZ2lmeShjdXJyKSkgfHwgaXNTZWxlY3RlZElkc0ZpcnN0RW1pdCA+IDIpIHtcclxuICAgICAgICAgICAgdGhpcy5vblNlbGVjdC5lbWl0KGNvcHlWYWx1ZUFzUmVhZG9ubHkodikpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoaXNTZWxlY3RlZElkc0ZpcnN0RW1pdCA8IDMpIHtcclxuICAgICAgICAgIGlzU2VsZWN0ZWRJZHNGaXJzdEVtaXQrKztcclxuICAgICAgICB9XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAkc2VsZWN0ZWRJZHMucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl9zZXJ2aWNlLnNlbGVjdGVkSWRzID0gdjtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICR2aWV3SW5pdC5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZmlsdGVyKHYgPT4gISF2KSxcclxuICAgICAgc3dpdGNoTWFwKCgpID0+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2VydmljZS4kY29sbGFwc2VkSWRzLnBpcGUoXHJcbiAgICAgICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXHJcbiAgICAgICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGN1cnIgPSB0aGlzLl8kY29sbGFwc2VkSXRlbUlkcy5nZXRWYWx1ZSgpO1xyXG4gICAgICAgICAgICBpZiAoKHRoaXMuX2lzQWNjb3JkaW9uQ29sbGFwc2UgfHwgdGhpcy5faXNNdWx0aXBsZUNvbGxhcHNlKSAmJiAoSlNPTi5zdHJpbmdpZnkodikgIT09IEpTT04uc3RyaW5naWZ5KGN1cnIpKSkge1xyXG4gICAgICAgICAgICAgIHRoaXMuXyRjb2xsYXBzZWRJdGVtSWRzLm5leHQodik7XHJcbiAgICAgICAgICAgICAgdGhpcy5vbkNvbGxhcHNlLmVtaXQoY29weVZhbHVlQXNSZWFkb25seSh2KSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pLFxyXG4gICAgICAgICk7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICBjb21iaW5lTGF0ZXN0KFskY29sbGFwc2luZ01vZGUsICRpdGVtcywgJGl0ZW1Db25maWdNYXAsICR0cmFja0J5XSkucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcCgoW2NvbGxhcHNpbmdNb2RlLCBpdGVtcywgaXRlbUNvbmZpZ01hcCwgdHJhY2tCeV0pID0+IHtcclxuICAgICAgICBjb25zdCBpc0FjY29yZGlvbiA9IGlzQ29sbGFwc2VNb2RlKGNvbGxhcHNpbmdNb2RlLCBDb2xsYXBzaW5nTW9kZXMuQUNDT1JESU9OKTtcclxuICAgICAgICBpZiAoaXNBY2NvcmRpb24pIHtcclxuICAgICAgICAgIGNvbnN0IGFsbEdyb3VwczogQXJyYXk8SWQ+ID0gW107XHJcbiAgICAgICAgICBpZiAodGhpcy5faXNBY2NvcmRpb25Db2xsYXBzZSkge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbCA9IGl0ZW1zLmxlbmd0aDsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtc1tpXSwgaWQgPSBpdGVtW3RyYWNrQnldLCBjb2xsYXBzYWJsZSA9IGl0ZW1Db25maWdNYXA/LltpZF0/LmNvbGxhcHNhYmxlID09PSB0cnVlO1xyXG4gICAgICAgICAgICAgIGlmICghY29sbGFwc2FibGUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBhbGxHcm91cHMucHVzaChpZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmICgodGhpcy5faXNBY2NvcmRpb25Db2xsYXBzZSB8fCB0aGlzLl9pc011bHRpcGxlQ29sbGFwc2UpICYmIChKU09OLnN0cmluZ2lmeSh0aGlzLl8kY29sbGFwc2VkSXRlbUlkcy5nZXRWYWx1ZSgpKSAhPT0gSlNPTi5zdHJpbmdpZnkoYWxsR3JvdXBzKSkpIHtcclxuICAgICAgICAgICAgdGhpcy5fJGNvbGxhcHNlZEl0ZW1JZHMubmV4dChhbGxHcm91cHMpO1xyXG4gICAgICAgICAgICB0aGlzLm9uQ29sbGFwc2UuZW1pdChjb3B5VmFsdWVBc1JlYWRvbmx5KGFsbEdyb3VwcykpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgICRjb2xsYXBzZWRJdGVtSWRzLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgdGhpcy5fc2VydmljZS5jb2xsYXBzZWRJZHMgPSB2O1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgdGhpcy4kZGVzdHJveS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKCgpID0+IHtcclxuICAgICAgICBkZWJvdW5jZWRVcGRhdGUuZGlzcG9zZSgpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgdGhpcy5fJHZpZXdJbml0Lm5leHQodHJ1ZSk7XHJcblxyXG4gICAgdGhpcy5fJGZpcmVVcGRhdGUubmV4dChmYWxzZSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIG9uQWZ0ZXJSZXNpemUodXBkYXRlID0gZmFsc2UpIHtcclxuICAgIHRoaXMuc25hcHBpbmdIYW5kbGVyKCk7XHJcblxyXG4gICAgaWYgKHRoaXMuX2lzU25hcHBpbmdNZXRob2RBZHZhbmNlZCkge1xyXG4gICAgICB0aGlzLnVwZGF0ZVJlZ3VsYXJSZW5kZXJlcigpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9yZWFkeUZvclNob3cgJiYgdXBkYXRlKSB7XHJcbiAgICAgIGNvbnN0IHNjcm9sbGVyID0gdGhpcy5fc2Nyb2xsZXJDb21wb25lbnQ7XHJcbiAgICAgIGlmICghIXNjcm9sbGVyKSB7XHJcbiAgICAgICAgY29uc3QgdXBkYXRlYmFsZSA9IHRoaXMuX3JlYWR5Rm9yU2hvdztcclxuICAgICAgICBpZiAodXBkYXRlYmFsZSkge1xyXG4gICAgICAgICAgdGhpcy5fJGZpcmVVcGRhdGUubmV4dChmYWxzZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNjcm9sbGVyLnJlZnJlc2godXBkYXRlYmFsZSwgdXBkYXRlYmFsZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2hlY2tCb3VuZHNPZkVsZW1lbnRzKCkge1xyXG4gICAgY29uc3QgY2hhbmdlZCA9IHRoaXMuX3RyYWNrQm94LmNoZWNrQm91bmRzT2ZFbGVtZW50cygpO1xyXG4gICAgaWYgKGNoYW5nZWQpIHtcclxuICAgICAgY29uc3QgcmVhZHlGb3JTaG93ID0gdGhpcy5fcmVhZHlGb3JTaG93LFxyXG4gICAgICAgIGlzU2Nyb2xsaW5nID0gdGhpcy5fJHNjcm9sbGluZ1RvLmdldFZhbHVlKCk7XHJcbiAgICAgIHRoaXMuX3RyYWNrQm94LmNoYW5nZXModHJ1ZSwgcmVhZHlGb3JTaG93ICYmICFpc1Njcm9sbGluZyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNuYXBwaW5nSGFuZGxlcigpIHtcclxuICAgIGNvbnN0IHNjcm9sbGVyID0gdGhpcy5fc2Nyb2xsZXJDb21wb25lbnQ7XHJcbiAgICBpZiAoISFzY3JvbGxlcikge1xyXG4gICAgICBjb25zdCBpc1ZlcnRpY2FsID0gdGhpcy5pc1ZlcnRpY2FsLFxyXG4gICAgICAgIG1heFNjcm9sbFNpemUgPSBNYXRoLnJvdW5kKGlzVmVydGljYWwgPyBzY3JvbGxlci5zY3JvbGxIZWlnaHQgPz8gMCA6IHNjcm9sbGVyLnNjcm9sbFdpZHRoID8/IDApLFxyXG4gICAgICAgIHNjcm9sbFNpemUgPSBpc1ZlcnRpY2FsID8gc2Nyb2xsZXIuc2Nyb2xsVG9wID8/IDAgOiBzY3JvbGxlci5zY3JvbGxMZWZ0ID8/IDAsXHJcbiAgICAgICAgYWN0dWFsU2Nyb2xsU2l6ZSA9IE1hdGgucm91bmQoc2Nyb2xsU2l6ZSk7XHJcbiAgICAgIGlmICh0aGlzLl9yZWFkeUZvclNob3cgJiYgIXRoaXMuX2lzTG9hZGluZykge1xyXG4gICAgICAgIGNvbnN0IGlzU2Nyb2xsRW5kID0gKGFjdHVhbFNjcm9sbFNpemUgPj0gKG1heFNjcm9sbFNpemUgLSBNSU5fUElYRUxTX0ZPUl9QUkVWRU5UX1NOQVBQSU5HKSkgfHwgIXNjcm9sbGVyLnNjcm9sbGFibGUgfHwgdGhpcy5fdHJhY2tCb3guaXNTY3JvbGxFbmQ7XHJcbiAgICAgICAgaWYgKGlzU2Nyb2xsRW5kKSB7XHJcbiAgICAgICAgICB0aGlzLl8kaXNTY3JvbGxTdGFydC5uZXh0KGZhbHNlKTtcclxuICAgICAgICAgIHRoaXMuXyRpc1Njcm9sbEVuZC5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgdGhpcy5fdHJhY2tCb3guaXNTY3JvbGxTdGFydCA9IGZhbHNlO1xyXG4gICAgICAgICAgdGhpcy5fdHJhY2tCb3guaXNTY3JvbGxFbmQgPSB0cnVlO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjb25zdCBpc1Njcm9sbFN0YXJ0ID0gKGFjdHVhbFNjcm9sbFNpemUgPD0gTUlOX1BJWEVMU19GT1JfUFJFVkVOVF9TTkFQUElORyk7XHJcbiAgICAgICAgICB0aGlzLl8kaXNTY3JvbGxTdGFydC5uZXh0KGlzU2Nyb2xsU3RhcnQpO1xyXG4gICAgICAgICAgdGhpcy5fJGlzU2Nyb2xsRW5kLm5leHQoZmFsc2UpO1xyXG4gICAgICAgICAgdGhpcy5fdHJhY2tCb3guaXNTY3JvbGxTdGFydCA9IGlzU2Nyb2xsU3RhcnQ7XHJcbiAgICAgICAgICB0aGlzLl90cmFja0JveC5pc1Njcm9sbEVuZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIGlmICghdGhpcy5fcmVhZHlGb3JTaG93KSB7XHJcbiAgICAgICAgY29uc3Qgc25hcFNjcm9sbFRvU3RhcnQgPSB0aGlzLl8kYWN0dWFsU25hcFNjcm9sbFRvU3RhcnQuZ2V0VmFsdWUoKSwgc25hcFNjcm9sbFRvRW5kID0gdGhpcy5fJGFjdHVhbFNuYXBTY3JvbGxUb0VuZC5nZXRWYWx1ZSgpO1xyXG4gICAgICAgIGlmICghc25hcFNjcm9sbFRvU3RhcnQgJiYgc25hcFNjcm9sbFRvRW5kKSB7XHJcbiAgICAgICAgICB0aGlzLl8kaXNTY3JvbGxTdGFydC5uZXh0KGZhbHNlKTtcclxuICAgICAgICAgIHRoaXMuXyRpc1Njcm9sbEVuZC5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgdGhpcy5fdHJhY2tCb3guaXNTY3JvbGxTdGFydCA9IGZhbHNlO1xyXG4gICAgICAgICAgdGhpcy5fdHJhY2tCb3guaXNTY3JvbGxFbmQgPSB0cnVlO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoc25hcFNjcm9sbFRvU3RhcnQgJiYgc25hcFNjcm9sbFRvRW5kKSB7XHJcbiAgICAgICAgICB0aGlzLl8kaXNTY3JvbGxTdGFydC5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgdGhpcy5fJGlzU2Nyb2xsRW5kLm5leHQoZmFsc2UpO1xyXG4gICAgICAgICAgdGhpcy5fdHJhY2tCb3guaXNTY3JvbGxTdGFydCA9IHRydWU7XHJcbiAgICAgICAgICB0aGlzLl90cmFja0JveC5pc1Njcm9sbEVuZCA9IGZhbHNlO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0aGlzLl8kaXNTY3JvbGxTdGFydC5uZXh0KGZhbHNlKTtcclxuICAgICAgICAgIHRoaXMuXyRpc1Njcm9sbEVuZC5uZXh0KGZhbHNlKTtcclxuICAgICAgICAgIHRoaXMuX3RyYWNrQm94LmlzU2Nyb2xsU3RhcnQgPSBmYWxzZTtcclxuICAgICAgICAgIHRoaXMuX3RyYWNrQm94LmlzU2Nyb2xsRW5kID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgcHJpdmF0ZSBlbWl0U2Nyb2xsRXZlbnQoaXNTY3JvbGxFbmQ6IGJvb2xlYW4gPSBmYWxzZSwgdXBkYXRlOiBib29sZWFuID0gdHJ1ZSwgdXNlckFjdGlvbjogYm9vbGVhbiA9IGZhbHNlKSB7XHJcbiAgICBpZiAoIXRoaXMuX3JlYWR5Rm9yU2hvdykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCBzY3JvbGxlckVsID0gdGhpcy5fJHNjcm9sbGVyLmdldFZhbHVlKCk/Lm5hdGl2ZUVsZW1lbnQsIHNjcm9sbGVyQ29tcG9uZW50ID0gdGhpcy5fc2Nyb2xsZXJDb21wb25lbnQ7XHJcbiAgICBpZiAoc2Nyb2xsZXJFbCAmJiBzY3JvbGxlckNvbXBvbmVudCkge1xyXG4gICAgICBjb25zdCBpc1ZlcnRpY2FsID0gdGhpcy5faXNWZXJ0aWNhbCwgc2Nyb2xsU2l6ZSA9IChpc1ZlcnRpY2FsID8gc2Nyb2xsZXJDb21wb25lbnQuc2Nyb2xsVG9wIDogc2Nyb2xsZXJDb21wb25lbnQuc2Nyb2xsTGVmdCksXHJcbiAgICAgICAgbWF4U2Nyb2xsU2l6ZSA9IChpc1ZlcnRpY2FsID8gc2Nyb2xsZXJDb21wb25lbnQuc2Nyb2xsSGVpZ2h0IDogc2Nyb2xsZXJDb21wb25lbnQuc2Nyb2xsV2lkdGgpLFxyXG4gICAgICAgIGJvdW5kcyA9IHRoaXMuXyRib3VuZHMuZ2V0VmFsdWUoKSB8fCB7IHg6IDAsIHk6IDAsIHdpZHRoOiBERUZBVUxUX0xJU1RfU0laRSwgaGVpZ2h0OiBERUZBVUxUX0xJU1RfU0laRSB9O1xyXG4gICAgICBjb25zdCBpdGVtc1JhbmdlID0gZm9ybWF0QWN0dWFsRGlzcGxheUl0ZW1zKHRoaXMuX3NlcnZpY2UuZGlzcGxheUl0ZW1zLCB0aGlzLl8kYWN0dWFsU2Nyb2xsU3RhcnRPZmZzZXQuZ2V0VmFsdWUoKSwgdGhpcy5fJGFjdHVhbFNjcm9sbEVuZE9mZnNldC5nZXRWYWx1ZSgpLFxyXG4gICAgICAgIHNjcm9sbFNpemUsIGlzVmVydGljYWwsIGJvdW5kcyksXHJcbiAgICAgICAgZXZlbnQgPSBuZXcgU2Nyb2xsRXZlbnQoe1xyXG4gICAgICAgICAgZGlyZWN0aW9uOiB0aGlzLl9zY3JvbGxlckNvbXBvbmVudD8uc2Nyb2xsRGlyZWN0aW9uID8/IDAsIGNvbnRhaW5lcjogc2Nyb2xsZXJFbCxcclxuICAgICAgICAgIGxpc3Q6IHRoaXMuXyRsaXN0LmdldFZhbHVlKCkhLm5hdGl2ZUVsZW1lbnQsIGRlbHRhOiB0aGlzLl90cmFja0JveC5kZWx0YSxcclxuICAgICAgICAgIGRlbHRhT2ZOZXdJdGVtczogdGhpcy5fdHJhY2tCb3guZGVsdGFPZk5ld0l0ZW1zLCBpc1ZlcnRpY2FsLFxyXG4gICAgICAgICAgc2Nyb2xsU2l6ZSxcclxuICAgICAgICAgIGl0ZW1zUmFuZ2UsXHJcbiAgICAgICAgICBpc0VuZDogIXNjcm9sbGVyQ29tcG9uZW50LnNjcm9sbGFibGUgfHwgdGhpcy5fdHJhY2tCb3guaXNTbmFwcGVkVG9FbmQgfHwgKE1hdGgucm91bmQoc2Nyb2xsU2l6ZSkgPT09IE1hdGgucm91bmQobWF4U2Nyb2xsU2l6ZSkpLFxyXG4gICAgICAgICAgdXNlckFjdGlvbixcclxuICAgICAgICB9KTtcclxuICAgICAgaWYgKHVwZGF0ZSkge1xyXG4gICAgICAgIHRoaXMuXyRzY3JvbGwubmV4dChldmVudCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChpc1Njcm9sbEVuZCkge1xyXG4gICAgICAgIHRoaXMub25TY3JvbGxFbmQuZW1pdChldmVudCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5vblNjcm9sbC5lbWl0KGV2ZW50KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRJc1NuYXBwaW5nTWV0aG9kQWR2YW5jZWQobT86IFNuYXBwaW5nTWV0aG9kKSB7XHJcbiAgICBjb25zdCBtZXRob2QgPSBtIHx8IHRoaXMuc25hcHBpbmdNZXRob2Q7XHJcbiAgICByZXR1cm4gaXNTbmFwcGluZ01ldGhvZEFkdmVuY2VkKG1ldGhvZCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldElzTm9uZVNlbGVjdGlvbihtPzogU2VsZWN0aW5nTW9kZSkge1xyXG4gICAgY29uc3QgbW9kZSA9IG0gfHwgdGhpcy5zZWxlY3RpbmdNb2RlO1xyXG4gICAgcmV0dXJuIGlzU2VsZWN0TW9kZShtb2RlLCBTZWxlY3RpbmdNb2Rlcy5OT05FKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0SXNTaW5nbGVTZWxlY3Rpb24obT86IFNlbGVjdGluZ01vZGUpIHtcclxuICAgIGNvbnN0IG1vZGUgPSBtIHx8IHRoaXMuc2VsZWN0aW5nTW9kZTtcclxuICAgIHJldHVybiBpc1NlbGVjdE1vZGUobW9kZSwgU2VsZWN0aW5nTW9kZXMuU0VMRUNUKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0SXNNdWx0aVNlbGVjdGlvbihtPzogU2VsZWN0aW5nTW9kZSkge1xyXG4gICAgY29uc3QgbW9kZSA9IG0gfHwgdGhpcy5zZWxlY3RpbmdNb2RlO1xyXG4gICAgcmV0dXJuIGlzU2VsZWN0TW9kZShtb2RlLCBTZWxlY3RpbmdNb2Rlcy5NVUxUSV9TRUxFQ1QpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRJc05vbmVDb2xsYXBzZShtPzogQ29sbGFwc2luZ01vZGUpIHtcclxuICAgIGNvbnN0IG1vZGUgPSBtIHx8IHRoaXMuY29sbGFwc2luZ01vZGU7XHJcbiAgICByZXR1cm4gaXNDb2xsYXBzZU1vZGUobW9kZSwgQ29sbGFwc2luZ01vZGVzLk5PTkUpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRJc011bHRpcGxlQ29sbGFwc2UobT86IENvbGxhcHNpbmdNb2RlKSB7XHJcbiAgICBjb25zdCBtb2RlID0gbSB8fCB0aGlzLmNvbGxhcHNpbmdNb2RlO1xyXG4gICAgcmV0dXJuIGlzQ29sbGFwc2VNb2RlKG1vZGUsIENvbGxhcHNpbmdNb2Rlcy5NVUxUSV9DT0xMQVBTRSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldElzQWNjb3JkaW9uQ29sbGFwc2UobT86IENvbGxhcHNpbmdNb2RlKSB7XHJcbiAgICBjb25zdCBtb2RlID0gbSB8fCB0aGlzLmNvbGxhcHNpbmdNb2RlO1xyXG4gICAgcmV0dXJuIGlzQ29sbGFwc2VNb2RlKG1vZGUsIENvbGxhcHNpbmdNb2Rlcy5BQ0NPUkRJT04pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRJc1ZlcnRpY2FsKGQ/OiBEaXJlY3Rpb24pIHtcclxuICAgIGNvbnN0IGRpciA9IGQgfHwgdGhpcy5kaXJlY3Rpb247XHJcbiAgICByZXR1cm4gaXNEaXJlY3Rpb24oZGlyLCBEaXJlY3Rpb25zLlZFUlRJQ0FMKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0SXNMYXp5KG0/OiBDb2xsZWN0aW9uTW9kZSkge1xyXG4gICAgY29uc3QgbW9kZSA9IG0gfHwgdGhpcy5jb2xsZWN0aW9uTW9kZTtcclxuICAgIHJldHVybiBpc0NvbGxlY3Rpb25Nb2RlKG1vZGUsIENvbGxlY3Rpb25Nb2Rlcy5MQVpZKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY3JlYXRlRGlzcGxheUNvbXBvbmVudHNJZk5lZWQoZGlzcGxheUl0ZW1zOiBJUmVuZGVyVmlydHVhbExpc3RDb2xsZWN0aW9uIHwgbnVsbCkge1xyXG4gICAgaWYgKCFkaXNwbGF5SXRlbXMgfHwgIXRoaXMuX2xpc3RDb250YWluZXJSZWYpIHtcclxuICAgICAgdGhpcy5fdHJhY2tCb3guc2V0RGlzcGxheU9iamVjdEluZGV4TWFwQnlJZCh7fSk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5faXNTbmFwcGluZ01ldGhvZEFkdmFuY2VkICYmIHRoaXMuc3RpY2t5RW5hYmxlZCkge1xyXG4gICAgICBpZiAodGhpcy5fc25hcHBlZERpc3BsYXlDb21wb25lbnRzLmxlbmd0aCA8IE1BWF9SRUdVTEFSX1NOQVBFRF9DT01QT05FTlRTICYmICEhdGhpcy5fc25hcENvbnRhaW5lclJlZikge1xyXG4gICAgICAgIHdoaWxlICh0aGlzLl9zbmFwcGVkRGlzcGxheUNvbXBvbmVudHMubGVuZ3RoIDwgTUFYX1JFR1VMQVJfU05BUEVEX0NPTVBPTkVOVFMpIHtcclxuICAgICAgICAgIGNvbnN0IGNvbXAgPSB0aGlzLl9zbmFwQ29udGFpbmVyUmVmLmNyZWF0ZUNvbXBvbmVudCh0aGlzLl9pdGVtQ29tcG9uZW50Q2xhc3MpO1xyXG4gICAgICAgICAgY29tcC5pbnN0YW5jZS5yZW5kZXJlciA9IHRoaXMuXyRpdGVtUmVuZGVyZXIuZ2V0VmFsdWUoKTtcclxuICAgICAgICAgIGNvbXAuaW5zdGFuY2UucmVndWxhciA9IHRydWU7XHJcbiAgICAgICAgICB0aGlzLl9zbmFwcGVkRGlzcGxheUNvbXBvbmVudHMucHVzaChjb21wKTtcclxuICAgICAgICAgIHRoaXMuX3RyYWNrQm94LnNuYXBwZWREaXNwbGF5Q29tcG9uZW50cyA9IHRoaXMuX3NuYXBwZWREaXNwbGF5Q29tcG9uZW50cztcclxuICAgICAgICAgIHRoaXMuX3Jlc2l6ZVNuYXBwZWRPYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcih0aGlzLl9yZXNpemVTbmFwcGVkQ29tcG9uZW50SGFuZGxlcik7XHJcbiAgICAgICAgICB0aGlzLl9yZXNpemVTbmFwcGVkT2JzZXJ2ZXIub2JzZXJ2ZShjb21wLmluc3RhbmNlLmVsZW1lbnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX3RyYWNrQm94Lml0ZW1zID0gZGlzcGxheUl0ZW1zO1xyXG5cclxuICAgIGNvbnN0IGxpc3RDb250YWluZXJSZWYgPSB0aGlzLl9saXN0Q29udGFpbmVyUmVmO1xyXG5cclxuICAgIGNvbnN0IG1heExlbmd0aCA9IGRpc3BsYXlJdGVtcy5sZW5ndGgsIGNvbXBvbmVudHMgPSB0aGlzLl9kaXNwbGF5Q29tcG9uZW50cztcclxuXHJcbiAgICBpZiAoISFsaXN0Q29udGFpbmVyUmVmKSB7XHJcbiAgICAgIGNvbnN0IGRvTWFwOiB7IFtpZDogbnVtYmVyXTogbnVtYmVyIH0gPSB7fTtcclxuICAgICAgbGV0IGkgPSAwO1xyXG4gICAgICBmb3IgKGxldCBsID0gY29tcG9uZW50cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICBjb25zdCBpdGVtID0gY29tcG9uZW50c1tpXTtcclxuICAgICAgICBpZiAoISFpdGVtKSB7XHJcbiAgICAgICAgICBjb25zdCBpZCA9IGl0ZW0uaW5zdGFuY2UuaWQ7XHJcbiAgICAgICAgICBpdGVtLmluc3RhbmNlLnJlbmRlcmVyID0gdGhpcy5fJGl0ZW1SZW5kZXJlci5nZXRWYWx1ZSgpO1xyXG4gICAgICAgICAgZG9NYXBbaWRdID0gaTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgd2hpbGUgKGNvbXBvbmVudHMubGVuZ3RoIDwgbWF4TGVuZ3RoKSB7XHJcbiAgICAgICAgY29uc3QgY29tcCA9IGxpc3RDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KHRoaXMuX2l0ZW1Db21wb25lbnRDbGFzcyk7XHJcbiAgICAgICAgY29uc3QgaWQgPSBjb21wLmluc3RhbmNlLmlkO1xyXG4gICAgICAgIGNvbXAuaW5zdGFuY2UucmVuZGVyZXIgPSB0aGlzLl8kaXRlbVJlbmRlcmVyLmdldFZhbHVlKCk7XHJcbiAgICAgICAgZG9NYXBbaWRdID0gaTtcclxuICAgICAgICBjb21wb25lbnRzLnB1c2goY29tcCk7XHJcbiAgICAgICAgaSsrO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuX3RyYWNrQm94LnNldERpc3BsYXlPYmplY3RJbmRleE1hcEJ5SWQoZG9NYXApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVSZWd1bGFyUmVuZGVyZXIoKSB7XHJcbiAgICB0aGlzLl9yZXNpemVTbmFwcGVkQ29tcG9uZW50SGFuZGxlcigpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVHJhY2tpbmcgYnkgaWRcclxuICAgKi9cclxuICBwcml2YXRlIHRyYWNraW5nKCkge1xyXG4gICAgdGhpcy5fdHJhY2tCb3gudHJhY2soKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVzZXRCb3VuZHNTaXplKGlzVmVydGljYWw6IGJvb2xlYW4sIHRvdGFsU2l6ZTogbnVtYmVyKSB7XHJcbiAgICBjb25zdCBsID0gdGhpcy5fJGxpc3QuZ2V0VmFsdWUoKSwgcHJvcCA9IGlzVmVydGljYWwgPyBIRUlHSFRfUFJPUF9OQU1FIDogV0lEVEhfUFJPUF9OQU1FLFxyXG4gICAgICBzaXplID0gdG90YWxTaXplO1xyXG4gICAgaWYgKCEhbCAmJiBwYXJzZUludChsLm5hdGl2ZUVsZW1lbnQuc3R5bGVbcHJvcF0pICE9PSBzaXplKSB7XHJcbiAgICAgIGwubmF0aXZlRWxlbWVudC5zdHlsZVtwcm9wXSA9IGAke3NpemV9JHtQWH1gO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJucyB0aGUgYm91bmRzIG9mIGFuIGVsZW1lbnQgd2l0aCBhIGdpdmVuIGlkXHJcbiAgICovXHJcbiAgZ2V0SXRlbUJvdW5kcyhpZDogSWQpOiBJU2l6ZSB8IG51bGwge1xyXG4gICAgcmV0dXJuIHRoaXMuX3NlcnZpY2UuZ2V0SXRlbUJvdW5kcyhpZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBGb2N1cyBhbiBsaXN0IGl0ZW0gYnkgYSBnaXZlbiBpZC5cclxuICAgKi9cclxuICBmb2N1cyhpZDogSWQsIGFsaWduOiBGb2N1c0FsaWdubWVudCA9IEZvY3VzQWxpZ25tZW50cy5OT05FKSB7XHJcbiAgICB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcclxuICAgIHRoaXMuX3NlcnZpY2UuZm9jdXNCeUlkKGlkLCBhbGlnbiwgdGhpcy5zY3JvbGxCZWhhdmlvcik7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUaGUgbWV0aG9kIHNjcm9sbHMgdGhlIGxpc3QgdG8gdGhlIGVsZW1lbnQgd2l0aCB0aGUgZ2l2ZW4gYGlkYCBhbmQgcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIHNjcm9sbGVkIGFyZWEuXHJcbiAgICovXHJcbiAgc2Nyb2xsVG8oaWQ6IElkLCBjYjogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGwsIG9wdGlvbnM6IElTY3JvbGxPcHRpb25zIHwgbnVsbCA9IG51bGwpIHtcclxuICAgIGNvbnN0IGJlaGF2aW9yID0gb3B0aW9ucz8uYmVoYXZpb3IgPz8gQkVIQVZJT1JfSU5TVEFOVCxcclxuICAgICAgYmxlbmRpbmcgPSBvcHRpb25zPy5ibGVuZGluZyA/PyBmYWxzZSxcclxuICAgICAgZm9jdXNlZCA9IG9wdGlvbnM/LmZvY3VzZWQgPz8gdHJ1ZSxcclxuICAgICAgZGVsYXkgPSBvcHRpb25zPy5kZWxheSA/PyAwLFxyXG4gICAgICBpdGVyYXRpb24gPSBvcHRpb25zPy5pdGVyYXRpb24gPz8gMDtcclxuICAgIHZhbGlkYXRlSWQoaWQpO1xyXG4gICAgdmFsaWRhdGVTY3JvbGxCZWhhdmlvcihiZWhhdmlvcik7XHJcbiAgICB2YWxpZGF0ZUl0ZXJhdGlvbihpdGVyYXRpb24pO1xyXG4gICAgY29uc3QgYWN0dWFsSXRlcmF0aW9uID0gdmFsaWRhdGVTY3JvbGxJdGVyYXRpb24oaXRlcmF0aW9uKTtcclxuICAgIHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5mb2N1cygpO1xyXG4gICAgaWYgKCF0aGlzLl9zY3JvbGxlckNvbXBvbmVudD8uc2Nyb2xsYWJsZSAmJiAhdGhpcy5pc0luZmluaXR5KSB7XHJcbiAgICAgIHRoaXMuc2Nyb2xsVG9GaW5hbGl6ZShpZCwgZm9jdXNlZCwgY2IpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLl8kc2Nyb2xsVG8ubmV4dCh7XHJcbiAgICAgIGlkLCBiZWhhdmlvciwgYmxlbmRpbmcsIGRlbGF5LCBpdGVyYXRpb246IGFjdHVhbEl0ZXJhdGlvbiwgaXNMYXN0SXRlcmF0aW9uOiBhY3R1YWxJdGVyYXRpb24gPT09IE1BWF9TQ1JPTExfVE9fSVRFUkFUSU9OUywgY2I6ICgpID0+IHtcclxuICAgICAgICB0aGlzLnNjcm9sbFRvRmluYWxpemUoaWQsIGZvY3VzZWQsIGNiKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTY3JvbGxzIHRoZSBzY3JvbGwgYXJlYSB0byB0aGUgZmlyc3QgaXRlbSBpbiB0aGUgY29sbGVjdGlvbi5cclxuICAgKi9cclxuICBzY3JvbGxUb1N0YXJ0KGNiOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbCwgb3B0aW9uczogSVNjcm9sbE9wdGlvbnMgfCBudWxsID0gbnVsbCkge1xyXG4gICAgY29uc3Qgc2Nyb2xsZXIgPSB0aGlzLl9zY3JvbGxlckNvbXBvbmVudDtcclxuICAgIGlmICghIXNjcm9sbGVyKSB7XHJcbiAgICAgIGNvbnN0IHNjcm9sbFNpemUgPSB0aGlzLmlzVmVydGljYWwgPyBzY3JvbGxlci5zY3JvbGxUb3AgOiBzY3JvbGxlci5zY3JvbGxMZWZ0O1xyXG4gICAgICBpZiAoc2Nyb2xsU2l6ZSA9PT0gMCkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgICBzY3JvbGxlci5zdG9wU2Nyb2xsaW5nKCk7XHJcbiAgICB9XHJcbiAgICBjb25zdCBiZWhhdmlvciA9IG9wdGlvbnM/LmJlaGF2aW9yID8/IEJFSEFWSU9SX0lOU1RBTlQsXHJcbiAgICAgIGJsZW5kaW5nID0gb3B0aW9ucz8uYmxlbmRpbmcgPz8gZmFsc2UsXHJcbiAgICAgIGZvY3VzZWQgPSBvcHRpb25zPy5mb2N1c2VkID8/IHRydWUsXHJcbiAgICAgIGRlbGF5ID0gb3B0aW9ucz8uZGVsYXkgPz8gMCxcclxuICAgICAgaXRlcmF0aW9uID0gb3B0aW9ucz8uaXRlcmF0aW9uID8/IDA7XHJcbiAgICB2YWxpZGF0ZVNjcm9sbEJlaGF2aW9yKGJlaGF2aW9yKTtcclxuICAgIHZhbGlkYXRlSXRlcmF0aW9uKGl0ZXJhdGlvbik7XHJcbiAgICBjb25zdCB0cmFja0J5ID0gdGhpcy50cmFja0J5LCBpdGVtcyA9IHRoaXMuXyRhY3R1YWxJdGVtcy5nZXRWYWx1ZSgpLCBmaXJzdEl0ZW0gPSBpdGVtcy5sZW5ndGggPiAwID8gaXRlbXNbMF0gPz8gbnVsbCA6IG51bGwsIGlkID0gZmlyc3RJdGVtPy5bdHJhY2tCeV0gPz8gbnVsbCxcclxuICAgICAgYWN0dWFsSXRlcmF0aW9uID0gdmFsaWRhdGVTY3JvbGxJdGVyYXRpb24oaXRlcmF0aW9uKTtcclxuICAgIGlmICghIWZpcnN0SXRlbSkge1xyXG4gICAgICB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcclxuICAgICAgdGhpcy5fJHNjcm9sbFRvLm5leHQoe1xyXG4gICAgICAgIGlkLCBiZWhhdmlvciwgYmxlbmRpbmcsIGRlbGF5LCBpdGVyYXRpb246IGFjdHVhbEl0ZXJhdGlvbiwgaXNMYXN0SXRlcmF0aW9uOiBhY3R1YWxJdGVyYXRpb24gPT09IE1BWF9TQ1JPTExfVE9fSVRFUkFUSU9OUywgY2I6ICgpID0+IHtcclxuICAgICAgICAgIHRoaXMuXyRpc1Njcm9sbFN0YXJ0Lm5leHQodHJ1ZSk7XHJcbiAgICAgICAgICB0aGlzLl90cmFja0JveC5pc1Njcm9sbFN0YXJ0ID0gdHJ1ZTtcclxuICAgICAgICAgIHRoaXMuX3RyYWNrQm94LmlzU2Nyb2xsRW5kID0gZmFsc2U7XHJcbiAgICAgICAgICB0aGlzLl8kZmlyZVVwZGF0ZS5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgdGhpcy5zY3JvbGxUb0ZpbmFsaXplKGlkLCBmb2N1c2VkLCBjYik7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEBkZXByZWNhdGVkXHJcbiAgICogVGhlIHNjcm9sbFRvRW5kSXRlbSBtZXRob2QgaXMgZGVwcmVjYXRlZC4gVXNlIHRoZSBzY3JvbGxUb0VuZCBtZXRob2QuXHJcbiAgICovXHJcbiAgc2Nyb2xsVG9FbmRJdGVtKGNiPzogKCkgPT4gdm9pZCwgb3B0aW9ucz86IElTY3JvbGxPcHRpb25zKSB7XHJcbiAgICB0aHJvdyBFcnJvcignVGhlIHNjcm9sbFRvRW5kSXRlbSBtZXRob2QgaXMgZGVwcmVjYXRlZC4gVXNlIHRoZSBzY3JvbGxUb0VuZCBtZXRob2QuJyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTY3JvbGxzIHRoZSBsaXN0IHRvIHRoZSBlbmQgb2YgdGhlIGNvbnRlbnQgc2l6ZS5cclxuICAgKi9cclxuICBzY3JvbGxUb0VuZChjYjogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGwsIG9wdGlvbnM6IElTY3JvbGxPcHRpb25zIHwgbnVsbCA9IG51bGwpIHtcclxuICAgIGNvbnN0IHNjcm9sbGVyID0gdGhpcy5fc2Nyb2xsZXJDb21wb25lbnQ7XHJcbiAgICBpZiAoISFzY3JvbGxlcikge1xyXG4gICAgICBjb25zdCBpc1ZlcnRpY2FsID0gdGhpcy5pc1ZlcnRpY2FsLFxyXG4gICAgICAgIHNjcm9sbFNpemUgPSBpc1ZlcnRpY2FsID8gc2Nyb2xsZXIuc2Nyb2xsVG9wIDogc2Nyb2xsZXIuc2Nyb2xsTGVmdCxcclxuICAgICAgICBtYXhTY3JvbGxTaXplID0gaXNWZXJ0aWNhbCA/IHNjcm9sbGVyLnNjcm9sbEhlaWdodCA6IHNjcm9sbGVyLnNjcm9sbFRvcDtcclxuICAgICAgaWYgKHNjcm9sbFNpemUgPT09IG1heFNjcm9sbFNpemUpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgc2Nyb2xsZXIuc3RvcFNjcm9sbGluZygpO1xyXG4gICAgfVxyXG4gICAgY29uc3QgYmVoYXZpb3IgPSBvcHRpb25zPy5iZWhhdmlvciA/PyBCRUhBVklPUl9JTlNUQU5ULFxyXG4gICAgICBibGVuZGluZyA9IG9wdGlvbnM/LmJsZW5kaW5nID8/IGZhbHNlLFxyXG4gICAgICBmb2N1c2VkID0gb3B0aW9ucz8uZm9jdXNlZCA/PyB0cnVlLFxyXG4gICAgICBkZWxheSA9IG9wdGlvbnM/LmRlbGF5ID8/IDAsXHJcbiAgICAgIGl0ZXJhdGlvbiA9IG9wdGlvbnM/Lml0ZXJhdGlvbiA/PyAwO1xyXG4gICAgdmFsaWRhdGVTY3JvbGxCZWhhdmlvcihiZWhhdmlvcik7XHJcbiAgICB2YWxpZGF0ZUl0ZXJhdGlvbihpdGVyYXRpb24pO1xyXG4gICAgY29uc3QgdHJhY2tCeSA9IHRoaXMudHJhY2tCeSwgaXRlbXMgPSB0aGlzLl8kYWN0dWFsSXRlbXMuZ2V0VmFsdWUoKSwgbGF0SXRlbSA9IGl0ZW1zW2l0ZW1zLmxlbmd0aCA+IDAgPyBpdGVtcy5sZW5ndGggLSAxIDogMF0sIGlkID0gbGF0SXRlbT8uW3RyYWNrQnldID8/IG51bGwsXHJcbiAgICAgIGFjdHVhbEl0ZXJhdGlvbiA9IHZhbGlkYXRlU2Nyb2xsSXRlcmF0aW9uKGl0ZXJhdGlvbik7XHJcbiAgICBpZiAobGF0SXRlbSA9PT0gbnVsbCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcclxuICAgIGlmICghdGhpcy5fc2Nyb2xsZXJDb21wb25lbnQ/LnNjcm9sbGFibGUpIHtcclxuICAgICAgdGhpcy5zY3JvbGxUb0ZpbmFsaXplKGlkLCBmb2N1c2VkLCBjYik7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMuXyRzY3JvbGxUby5uZXh0KHtcclxuICAgICAgaWQsIGJlaGF2aW9yLCBibGVuZGluZywgZGVsYXksIGl0ZXJhdGlvbjogYWN0dWFsSXRlcmF0aW9uLCBpc0xhc3RJdGVyYXRpb246IGFjdHVhbEl0ZXJhdGlvbiA9PT0gTUFYX1NDUk9MTF9UT19JVEVSQVRJT05TLCBjYjogKCkgPT4ge1xyXG4gICAgICAgIHRoaXMuXyRpc1Njcm9sbEVuZC5uZXh0KHRydWUpO1xyXG4gICAgICAgIHRoaXMuX3RyYWNrQm94LmlzU2Nyb2xsU3RhcnQgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLl90cmFja0JveC5pc1Njcm9sbEVuZCA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fJGZpcmVVcGRhdGUubmV4dCh0cnVlKTtcclxuICAgICAgICB0aGlzLnNjcm9sbFRvRmluYWxpemUoaWQsIGZvY3VzZWQsIGNiKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNjcm9sbFRvRmluYWxpemUoaWQ6IElkLCBmb2N1c2VkOiBib29sZWFuLCBjYjogKCgpID0+IHZvaWQpIHwgbnVsbCkge1xyXG4gICAgaWYgKGZvY3VzZWQpIHtcclxuICAgICAgY29uc3QgZWwgPSB0aGlzLl9zZXJ2aWNlLmdldEZvY3VzZWRFbGVtZW50QnlJZChpZCk7XHJcbiAgICAgIGlmICghIWVsKSB7XHJcbiAgICAgICAgdGhpcy5fc2VydmljZS5mb2N1cyhlbCwgRm9jdXNBbGlnbm1lbnRzLk5PTkUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZW9mIGNiID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIGNiPy4oKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBjbGVhbnVwKCkge1xyXG4gICAgY29uc3QgZGlzcGxheUl0ZW1zOiBJUmVuZGVyVmlydHVhbExpc3RDb2xsZWN0aW9uID0gW107XHJcbiAgICB0aGlzLl9zZXJ2aWNlLmNvbGxlY3Rpb24gPSBkaXNwbGF5SXRlbXM7XHJcbiAgICB0aGlzLmNyZWF0ZURpc3BsYXlDb21wb25lbnRzSWZOZWVkKGRpc3BsYXlJdGVtcyk7XHJcbiAgICB0aGlzLnRyYWNraW5nKCk7XHJcbiAgICB0aGlzLmVtaXRTY3JvbGxFdmVudCh0cnVlLCBmYWxzZSwgZmFsc2UpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRm9yY2UgY2xlYXJpbmcgdGhlIGNhY2hlLlxyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBjYWNoZUNsZWFuKCkge1xyXG4gICAgdGhpcy5fY2FjaGVkID0gZmFsc2U7XHJcbiAgICBpZiAodGhpcy5keW5hbWljU2l6ZSkge1xyXG4gICAgICB0aGlzLl90cmFja0JveC5jYWNoZUNsZWFuKCk7XHJcbiAgICB9XHJcbiAgICBjb25zdCBwcmVyZW5kZXJDb250YWluZXIgPSB0aGlzLl9wcmVyZW5kZXI7XHJcbiAgICBpZiAoISFwcmVyZW5kZXJDb250YWluZXIpIHtcclxuICAgICAgcHJlcmVuZGVyQ29udGFpbmVyLmNsZWFyKCk7XHJcbiAgICAgIHByZXJlbmRlckNvbnRhaW5lci5vZmYoKTtcclxuICAgIH1cclxuICAgIHRoaXMuXyRjb2xsYXBzZWRJdGVtSWRzLm5leHQoW10pO1xyXG4gICAgdGhpcy5fJGlzU2Nyb2xsU3RhcnQubmV4dCh0cnVlKTtcclxuICAgIHRoaXMuXyRpc1Njcm9sbEVuZC5uZXh0KGZhbHNlKTtcclxuICAgIHRoaXMuXyR0b3RhbFNpemUubmV4dCgwKTtcclxuICAgIHRoaXMuXyRzY3JvbGxTaXplLm5leHQoMCk7XHJcbiAgICBjb25zdCBzY3JvbGxlciA9IHRoaXMuX3Njcm9sbGVyQ29tcG9uZW50O1xyXG4gICAgaWYgKCEhc2Nyb2xsZXIpIHtcclxuICAgICAgc2Nyb2xsZXIucmVzZXQoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEBkZXByZWNhdGVkXHJcbiAgICogVGhlIHN0b3BTbmFwcGluZ1Njcm9sbFRvRW5kIG1ldGhvZCBpcyBkZXByZWNhdGVkLiBVc2UgdGhlIHByZXZlbnRTbmFwcGluZyBtZXRob2QuXHJcbiAgICovXHJcbiAgc3RvcFNuYXBwaW5nU2Nyb2xsVG9FbmQoKSB7XHJcbiAgICB0aHJvdyBFcnJvcignVGhlIHN0b3BTbmFwcGluZ1Njcm9sbFRvRW5kIG1ldGhvZCBpcyBkZXByZWNhdGVkLiBVc2UgdGhlIHByZXZlbnRTbmFwcGluZyBtZXRob2QuJyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBQcmV2ZW50cyB0aGUgbGlzdCBmcm9tIHNuYXBwaW5nIHRvIGl0cyBzdGFydCBvciBlbmQgZWRnZS5cclxuICAgKi9cclxuICBwcmV2ZW50U25hcHBpbmcoKSB7XHJcbiAgICBpZiAoIXRoaXMuX3JlYWR5Rm9yU2hvdykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCBzY3JvbGxlciA9IHRoaXMuX3Njcm9sbGVyQ29tcG9uZW50O1xyXG4gICAgdGhpcy5fJGlzU2Nyb2xsU3RhcnQubmV4dChmYWxzZSk7XHJcbiAgICB0aGlzLl8kaXNTY3JvbGxFbmQubmV4dChmYWxzZSk7XHJcbiAgICB0aGlzLl90cmFja0JveC5wcmV2ZW50U2Nyb2xsU25hcHBpbmcodHJ1ZSk7XHJcbiAgICBpZiAoc2Nyb2xsZXIpIHtcclxuICAgICAgc2Nyb2xsZXIuc3RvcFNjcm9sbGluZygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgb3ZlcnJpZGUgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICBzdXBlci5uZ09uRGVzdHJveSgpO1xyXG4gICAgdGhpcy5kaXNwb3NlKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGRpc3Bvc2UoKSB7XHJcbiAgICB0aGlzLl8kZGVzdHJveS5uZXh0KCk7XHJcblxyXG4gICAgY29uc3QgdXBkYXRlSWQgPSB0aGlzLl91cGRhdGVJZDtcclxuICAgIGlmICh1cGRhdGVJZCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHVwZGF0ZUlkKTtcclxuICAgICAgdGhpcy5fdXBkYXRlSWQgPSB1bmRlZmluZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuX3NlcnZpY2UpIHtcclxuICAgICAgdGhpcy5fc2VydmljZS5kaXNwb3NlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCEhdGhpcy5fdHJhY2tCb3gpIHtcclxuICAgICAgdGhpcy5fdHJhY2tCb3guZGlzcG9zZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghIXRoaXMuX3Jlc2l6ZVNuYXBwZWRPYnNlcnZlcikge1xyXG4gICAgICB0aGlzLl9yZXNpemVTbmFwcGVkT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghIXRoaXMuX3NuYXBwZWREaXNwbGF5Q29tcG9uZW50cykge1xyXG4gICAgICB3aGlsZSAodGhpcy5fc25hcHBlZERpc3BsYXlDb21wb25lbnRzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICBjb25zdCBjb21wID0gdGhpcy5fc25hcHBlZERpc3BsYXlDb21wb25lbnRzLnNoaWZ0KCk7XHJcbiAgICAgICAgY29tcD8uZGVzdHJveSgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuX2Rpc3BsYXlDb21wb25lbnRzKSB7XHJcbiAgICAgIHdoaWxlICh0aGlzLl9kaXNwbGF5Q29tcG9uZW50cy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgY29uc3QgY29tcCA9IHRoaXMuX2Rpc3BsYXlDb21wb25lbnRzLnNoaWZ0KCk7XHJcbiAgICAgICAgY29tcD8uZGVzdHJveSgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgYXJpYS1saXZlPVwicG9saXRlXCIgYXJpYS1hdG9taWM9XCJ0cnVlXCIgY2xhc3M9XCJuZ3ZsX19zY3JlZW4tcmVhZGVyXCI+XHJcbiAge3sgJHNjcmVlblJlYWRlckZvcm1hdHRlZE1lc3NhZ2UgfCBhc3luYyB9fVxyXG48L2Rpdj5cclxuXHJcbjxuZy1wcmVyZW5kZXItY29udGFpbmVyICNwcmVyZW5kZXIgW2JvdW5kc109XCIoJGJvdW5kcyB8IGFzeW5jKSFcIiBbZGlyZWN0aW9uXT1cIigkZGlyZWN0aW9uIHwgYXN5bmMpIVwiXHJcbiAgW2R5bmFtaWNdPVwiKCRkeW5hbWljU2l6ZSB8IGFzeW5jKSFcIiBbZGl2aWRlc109XCIoJGRpdmlkZXMgfCBhc3luYykhXCIgW2lzVmVydGljYWxdPVwiKCRpc1ZlcnRpY2FsIHwgYXN5bmMpIVwiXHJcbiAgW2l0ZW1TaXplXT1cIigkYWN0dWFsSXRlbVNpemUgfCBhc3luYykhXCIgW3RyYWNrQnldPVwiKCR0cmFja0J5IHwgYXN5bmMpIVwiIFtpdGVtUmVuZGVyZXJdPVwiKCRpdGVtUmVuZGVyZXIgfCBhc3luYykhXCJcclxuICBbc3RhcnRPZmZzZXRdPVwiKCRzdGFydE9mZnNldCB8IGFzeW5jKSFcIiBbZW5kT2Zmc2V0XT1cIigkZW5kT2Zmc2V0IHwgYXN5bmMpIVwiXHJcbiAgW3Njcm9sbGJhckVuYWJsZWRdPVwiKHNjcm9sbGVyLiRzY3JvbGxiYXJTaG93IHwgYXN5bmMpIVwiXHJcbiAgW2VuYWJsZWRdPVwiKCRwcmVyZW5kZXJFbmFibGVkIHwgYXN5bmMpIVwiPjwvbmctcHJlcmVuZGVyLWNvbnRhaW5lcj5cclxuXHJcbjxuZy1jb250YWluZXIgKm5nSWY9XCIoJHN0aWNreUVuYWJsZWQgfCBhc3luYykhXCI+XHJcbiAgPGRpdiBsb2NhbGVTZW5zaXRpdmUgW2xhbmdUZXh0RGlyXT1cIigkbGFuZ1RleHREaXIgfCBhc3luYykhXCIgI3NuYXBwZWRDb250YWluZXIgY2xhc3M9XCJuZ3ZsX19zbmFwcGVkLWNvbnRhaW5lclwiXHJcbiAgICBbbmdDbGFzc109XCIoJGNsYXNzZXMgfCBhc3luYylcIj5cclxuICAgIDxkaXYgI3NuYXBwZWQgcGFydD1cInNuYXBwZWQtaXRlbVwiIGNsYXNzPVwibmd2bF9fbGlzdC1zbmFwcGVyXCI+XHJcbiAgICAgIDxuZy1jb250YWluZXIgI3NuYXBSZW5kZXJlckNvbnRhaW5lcj48L25nLWNvbnRhaW5lcj5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG48L25nLWNvbnRhaW5lcj5cclxuXHJcbjxuZy1zY3JvbGxlciAjc2Nyb2xsZXIgY2xhc3M9XCJuZ3ZsX19saXN0LXNjcm9sbGVyXCIgW2NsYXNzZXNdPVwiKCRjbGFzc2VzIHwgYXN5bmMpIVwiXHJcbiAgW3N0YXJ0T2Zmc2V0XT1cIigkc3RhcnRPZmZzZXQgfCBhc3luYykhXCIgW2VuZE9mZnNldF09XCIoJGVuZE9mZnNldCB8IGFzeW5jKSFcIlxyXG4gIFthbGlnbm1lbnRTdGFydE9mZnNldF09XCIoJGFsaWdubWVudFNjcm9sbFN0YXJ0T2Zmc2V0IHwgYXN5bmMpIVwiXHJcbiAgW2FsaWdubWVudEVuZE9mZnNldF09XCIoJGFsaWdubWVudFNjcm9sbEVuZE9mZnNldCB8IGFzeW5jKSFcIiBbZGlyZWN0aW9uXT1cIigkZGlyZWN0aW9uIHwgYXN5bmMpIVwiXHJcbiAgW3Njcm9sbGJhclRodW1iUmVuZGVyZXJdPVwiKCRzY3JvbGxiYXJUaHVtYlJlbmRlcmVyIHwgYXN5bmMpIVwiIFtpc0luZmluaXR5XT1cIigkaXNJbmZpbml0eSB8IGFzeW5jKSFcIlxyXG4gIFtzY3JvbGxiYXJUaGlja25lc3NdPVwiKCRzY3JvbGxiYXJUaGlja25lc3MgfCBhc3luYykhXCIgW3Njcm9sbGJhclRodW1iUGFyYW1zXT1cIigkc2Nyb2xsYmFyVGh1bWJQYXJhbXMgfCBhc3luYykhXCJcclxuICBbYW5pbWF0aW9uUGFyYW1zXT1cIigkYW5pbWF0aW9uUGFyYW1zIHwgYXN5bmMpIVwiIFtmb2N1c2VkRWxlbWVudF09XCIoJGZvY3VzZWRFbGVtZW50IHwgYXN5bmMpIVwiXHJcbiAgW2xvYWRpbmddPVwiKCRsb2FkaW5nIHwgYXN5bmMpIVwiIFtvdmVyc2Nyb2xsRW5hYmxlZF09XCIoJG92ZXJzY3JvbGxFbmFibGVkIHwgYXN5bmMpIVwiXHJcbiAgW3NuYXBwaW5nRGlzdGFuY2VdPVwiKCRzbmFwcGluZ0Rpc3RhbmNlIHwgYXN5bmMpIVwiIFtvdmVybGFwcGluZ1Njcm9sbGJhcl09XCIoJG92ZXJsYXBwaW5nU2Nyb2xsYmFyIHwgYXN5bmMpIVwiXHJcbiAgW3Njcm9sbGJhckVuYWJsZWRdPVwiKCRhY3R1YWxTY3JvbGxiYXJFbmFibGVkIHwgYXN5bmMpIVwiIFtzY3JvbGxiYXJJbnRlcmFjdGl2ZV09XCIoJHNjcm9sbGJhckludGVyYWN0aXZlIHwgYXN5bmMpIVwiXHJcbiAgW3NuYXBUb0l0ZW1dPVwiKCRzbmFwVG9JdGVtIHwgYXN5bmMpIVwiIFtzbmFwVG9JdGVtQWxpZ25dPVwiKCRzbmFwVG9JdGVtQWxpZ24gfCBhc3luYykhXCJcclxuICBbc2Nyb2xsYmFyTWluU2l6ZV09XCIoJHNjcm9sbGJhck1pblNpemUgfCBhc3luYykhXCIgW3Njcm9sbEJlaGF2aW9yXT1cIigkc2Nyb2xsQmVoYXZpb3IgfCBhc3luYykhXCJcclxuICBbc2Nyb2xsaW5nU2V0dGluZ3NdPVwiKCRzY3JvbGxpbmdTZXR0aW5ncyB8IGFzeW5jKSFcIiBbc2Nyb2xsaW5nT25lQnlPbmVdPVwiKCRzY3JvbGxpbmdPbmVCeU9uZSB8IGFzeW5jKSFcIlxyXG4gIFttb3Rpb25CbHVyXT1cIigkbW90aW9uQmx1ciB8IGFzeW5jKSFcIiBbbWF4TW90aW9uQmx1cl09XCIoJG1heE1vdGlvbkJsdXIgfCBhc3luYykhXCJcclxuICBbbW90aW9uQmx1ckVuYWJsZWRdPVwiKCRtb3Rpb25CbHVyRW5hYmxlZCB8IGFzeW5jKSFcIj5cclxuICA8bmctY29udGFpbmVyICNyZW5kZXJlcnNDb250YWluZXI+PC9uZy1jb250YWluZXI+XHJcbjwvbmctc2Nyb2xsZXI+Il19