@seniorsistemas/data-seniorx-core 2.3.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/core/constants/autocomplete.const.d.ts +4 -0
  2. package/core/constants/context-selector.const.d.ts +1 -0
  3. package/core/constants/gantt.const.d.ts +7 -0
  4. package/core/constants/hyperlink.const.d.ts +1 -0
  5. package/core/constants/inline-edit.const.d.ts +4 -0
  6. package/core/constants/kanban.const.d.ts +2 -0
  7. package/core/constants/pin-code-field.const.d.ts +5 -0
  8. package/core/constants/rating-scale.const.d.ts +1 -0
  9. package/core/constants/spotlight.const.d.ts +8 -0
  10. package/core/constants/star-rating.const.d.ts +4 -0
  11. package/core/constants/stepper.const.d.ts +1 -0
  12. package/core/constants/tiered-menu.const.d.ts +3 -0
  13. package/core/types/autocomplete.type.d.ts +9 -0
  14. package/core/types/chat.type.d.ts +12 -0
  15. package/core/types/checkbox-list.type.d.ts +12 -0
  16. package/core/types/gantt.type.d.ts +22 -0
  17. package/core/types/grid-menu.type.d.ts +13 -0
  18. package/core/types/hyperlink.type.d.ts +1 -0
  19. package/core/types/image-cropper.type.d.ts +20 -0
  20. package/core/types/inline-edit.type.d.ts +26 -0
  21. package/core/types/kanban.type.d.ts +36 -0
  22. package/core/types/panel.type.d.ts +16 -0
  23. package/core/types/profile-picture-picker.type.d.ts +9 -0
  24. package/core/types/rating-scale.type.d.ts +5 -0
  25. package/core/types/select-button.type.d.ts +1 -0
  26. package/core/types/spotlight.type.d.ts +34 -0
  27. package/core/types/star-rating.type.d.ts +1 -0
  28. package/core/types/stepper.type.d.ts +20 -0
  29. package/core/types/table-column.type.d.ts +3 -1
  30. package/core/types/table-options.type.d.ts +8 -2
  31. package/core/types/table.type.d.ts +1 -1
  32. package/core/types/tiered-menu.type.d.ts +16 -0
  33. package/core/types/tree.type.d.ts +25 -0
  34. package/core/types/workspace-switch.type.d.ts +6 -0
  35. package/core/utils/body-scroll.util.d.ts +2 -0
  36. package/core/utils/roving-focus.util.d.ts +2 -0
  37. package/core/utils/selection.util.d.ts +3 -0
  38. package/core/utils/tree.util.d.ts +4 -0
  39. package/esm2022/core/constants/autocomplete.const.mjs +5 -0
  40. package/esm2022/core/constants/context-selector.const.mjs +2 -0
  41. package/esm2022/core/constants/gantt.const.mjs +7 -0
  42. package/esm2022/core/constants/hyperlink.const.mjs +2 -1
  43. package/esm2022/core/constants/inline-edit.const.mjs +5 -0
  44. package/esm2022/core/constants/kanban.const.mjs +3 -0
  45. package/esm2022/core/constants/pin-code-field.const.mjs +6 -0
  46. package/esm2022/core/constants/rating-scale.const.mjs +2 -0
  47. package/esm2022/core/constants/spotlight.const.mjs +9 -0
  48. package/esm2022/core/constants/star-rating.const.mjs +5 -0
  49. package/esm2022/core/constants/stepper.const.mjs +2 -0
  50. package/esm2022/core/constants/table.const.mjs +2 -2
  51. package/esm2022/core/constants/tiered-menu.const.mjs +4 -0
  52. package/esm2022/core/types/autocomplete.type.mjs +2 -0
  53. package/esm2022/core/types/chat.type.mjs +2 -0
  54. package/esm2022/core/types/checkbox-list.type.mjs +2 -0
  55. package/esm2022/core/types/gantt.type.mjs +2 -0
  56. package/esm2022/core/types/grid-menu.type.mjs +2 -0
  57. package/esm2022/core/types/hyperlink.type.mjs +1 -1
  58. package/esm2022/core/types/image-cropper.type.mjs +2 -0
  59. package/esm2022/core/types/inline-edit.type.mjs +2 -0
  60. package/esm2022/core/types/kanban.type.mjs +2 -0
  61. package/esm2022/core/types/panel.type.mjs +9 -0
  62. package/esm2022/core/types/profile-picture-picker.type.mjs +2 -0
  63. package/esm2022/core/types/rating-scale.type.mjs +2 -0
  64. package/esm2022/core/types/select-button.type.mjs +1 -1
  65. package/esm2022/core/types/spotlight.type.mjs +2 -0
  66. package/esm2022/core/types/star-rating.type.mjs +2 -0
  67. package/esm2022/core/types/stepper.type.mjs +7 -0
  68. package/esm2022/core/types/table-column.type.mjs +1 -1
  69. package/esm2022/core/types/table-options.type.mjs +1 -1
  70. package/esm2022/core/types/table.type.mjs +1 -1
  71. package/esm2022/core/types/tiered-menu.type.mjs +2 -0
  72. package/esm2022/core/types/tree.type.mjs +2 -0
  73. package/esm2022/core/types/workspace-switch.type.mjs +2 -0
  74. package/esm2022/core/utils/body-scroll.util.mjs +19 -0
  75. package/esm2022/core/utils/combobox.util.mjs +3 -2
  76. package/esm2022/core/utils/roving-focus.util.mjs +20 -0
  77. package/esm2022/core/utils/selection.util.mjs +13 -0
  78. package/esm2022/core/utils/string.util.mjs +8 -3
  79. package/esm2022/core/utils/tree.util.mjs +23 -0
  80. package/esm2022/features/accordion/accordion.component.mjs +2 -2
  81. package/esm2022/features/accordion/{accordion-item.component.mjs → components/accordion-item/accordion-item.component.mjs} +7 -7
  82. package/esm2022/features/autocomplete/autocomplete.component.mjs +501 -0
  83. package/esm2022/features/autocomplete/components/autocomplete-chip/autocomplete-chip.component.mjs +30 -0
  84. package/esm2022/features/breadcrumb/breadcrumb.component.mjs +2 -2
  85. package/esm2022/features/card-list/card/card.component.mjs +63 -99
  86. package/esm2022/features/chat/chat.component.mjs +126 -0
  87. package/esm2022/features/checkbox-list/checkbox-list.component.mjs +125 -0
  88. package/esm2022/features/combobox/combobox.component.mjs +20 -8
  89. package/esm2022/features/context-selector/context-selector.component.mjs +198 -0
  90. package/esm2022/features/filters/filters.component.mjs +1 -1
  91. package/esm2022/features/gantt/components/gantt-side-table/gantt-side-table.component.mjs +17 -0
  92. package/esm2022/features/gantt/gantt-date.utils.mjs +97 -0
  93. package/esm2022/features/gantt/gantt.component.mjs +89 -0
  94. package/esm2022/features/gantt/gantt.engine.mjs +662 -0
  95. package/esm2022/features/grid-menu/grid-menu.component.mjs +104 -0
  96. package/esm2022/features/hyperlink/hyperlink.component.mjs +7 -4
  97. package/esm2022/features/icon-picker/icon-picker.component.mjs +3 -3
  98. package/esm2022/features/image-cropper/image-cropper.component.mjs +218 -0
  99. package/esm2022/features/image-cropper/services/image-cropper.service.mjs +50 -0
  100. package/esm2022/features/infinite-scroll/infinite-scroll.directive.mjs +89 -0
  101. package/esm2022/features/info-sign/info-sign.component.mjs +3 -3
  102. package/esm2022/features/inline-edit/components/fields/inline-edit-number/inline-edit-number.component.mjs +38 -0
  103. package/esm2022/features/inline-edit/components/fields/inline-edit-text/inline-edit-text.component.mjs +29 -0
  104. package/esm2022/features/inline-edit/components/fields/inline-edit-textarea/inline-edit-textarea.component.mjs +29 -0
  105. package/esm2022/features/inline-edit/components/inline-edit-item/inline-edit-item.component.mjs +131 -0
  106. package/esm2022/features/inline-edit/fields/inline-edit-field.mjs +17 -0
  107. package/esm2022/features/inline-edit/fields/inline-edit-number-field.mjs +15 -0
  108. package/esm2022/features/inline-edit/fields/inline-edit-text-field.mjs +11 -0
  109. package/esm2022/features/inline-edit/fields/inline-edit-textarea-field.mjs +15 -0
  110. package/esm2022/features/inline-edit/inline-edit.component.mjs +27 -0
  111. package/esm2022/features/interactive-content/interactive-content.directive.mjs +140 -0
  112. package/esm2022/features/kanban/components/kanban-column/kanban-column.component.mjs +88 -0
  113. package/esm2022/features/kanban/components/kanban-item/kanban-item.component.mjs +72 -0
  114. package/esm2022/features/kanban/components/kanban-item-dragging/kanban-item-dragging.component.mjs +19 -0
  115. package/esm2022/features/kanban/directives/kanban-template.directive.mjs +22 -0
  116. package/esm2022/features/kanban/kanban.component.mjs +198 -0
  117. package/esm2022/features/kanban/services/kanban-event.service.mjs +27 -0
  118. package/esm2022/features/loading-state/loading-state.component.mjs +3 -62
  119. package/esm2022/features/mouse-events/directives/double-click.directive.mjs +34 -0
  120. package/esm2022/features/mouse-events/directives/long-press.directive.mjs +61 -0
  121. package/esm2022/features/paginator/paginator.component.mjs +8 -3
  122. package/esm2022/features/panel/panel.component.mjs +43 -11
  123. package/esm2022/features/pin-code-field/pin-code-field.component.mjs +234 -0
  124. package/esm2022/features/profile-picture-picker/profile-picture-picker.component.mjs +330 -0
  125. package/esm2022/features/rating-scale/rating-scale.component.mjs +86 -0
  126. package/esm2022/features/row-card-list/row-card/row-card.component.mjs +3 -3
  127. package/esm2022/features/scaffold/scaffold.component.mjs +4 -6
  128. package/esm2022/features/select-button/select-button.component.mjs +7 -4
  129. package/esm2022/features/speech-recognition/services/speech-recognition.service.mjs +148 -0
  130. package/esm2022/features/speech-recognition/services/text-to-speech.service.mjs +88 -0
  131. package/esm2022/features/speech-recognition/speech-recognition.component.mjs +243 -0
  132. package/esm2022/features/spotlight/components/spotlight-overlay/spotlight-overlay.component.mjs +521 -0
  133. package/esm2022/features/spotlight/directives/spotlight-step.directive.mjs +38 -0
  134. package/esm2022/features/spotlight/services/spotlight-tour.service.mjs +179 -0
  135. package/esm2022/features/spotlight/spotlight.component.mjs +160 -0
  136. package/esm2022/features/star-rating/star-rating.component.mjs +95 -0
  137. package/esm2022/features/stepper/stepper.component.mjs +86 -0
  138. package/esm2022/features/switch/switch.component.mjs +12 -8
  139. package/esm2022/features/tab/{tab-item.component.mjs → components/tab-item/tab-item.component.mjs} +1 -1
  140. package/esm2022/features/tab/tab.component.mjs +4 -4
  141. package/esm2022/features/table/components/table-cell-content.component.mjs +14 -5
  142. package/esm2022/features/table/table.component.mjs +220 -29
  143. package/esm2022/features/table/utils/table-data.util.mjs +71 -8
  144. package/esm2022/features/table/utils/table-layout.util.mjs +21 -1
  145. package/esm2022/features/tiered-menu/components/tiered-menu/tiered-menu.component.mjs +367 -0
  146. package/esm2022/features/tiered-menu/components/tiered-menu-divider/tiered-menu-divider.component.mjs +11 -0
  147. package/esm2022/features/tiered-menu/components/tiered-menu-item/tiered-menu-item.component.mjs +97 -0
  148. package/esm2022/features/tiered-menu/components/tiered-menu-nested/tiered-menu-nested.component.mjs +181 -0
  149. package/esm2022/features/tiered-menu/directives/tiered-menu.directive.mjs +246 -0
  150. package/esm2022/features/tiered-menu/services/tiered-menu.event.service.mjs +16 -0
  151. package/esm2022/features/tiered-menu/services/tiered-menu.global.service.mjs +12 -0
  152. package/esm2022/features/tiered-menu/services/tiered-menu.service.mjs +49 -0
  153. package/esm2022/features/tree/components/tree-node-item/tree-node-item.component.mjs +169 -0
  154. package/esm2022/features/tree/tree.component.mjs +211 -0
  155. package/esm2022/features/visual-sql-editor/components/visual-sql-editor-field-modal/visual-sql-editor-field-modal.component.mjs +41 -0
  156. package/esm2022/features/visual-sql-editor/components/visual-sql-editor-filter-modal/visual-sql-editor-filter-modal.component.mjs +38 -0
  157. package/esm2022/features/visual-sql-editor/components/visual-sql-editor-join-modal/visual-sql-editor-join-modal.component.mjs +29 -0
  158. package/esm2022/features/visual-sql-editor/components/visual-sql-editor-sort-modal/visual-sql-editor-sort-modal.component.mjs +29 -0
  159. package/esm2022/features/visual-sql-editor/components/visual-sql-editor-source-modal/visual-sql-editor-source-modal.component.mjs +35 -0
  160. package/esm2022/features/visual-sql-editor/services/visual-sql-editor-flow.service.mjs +106 -0
  161. package/esm2022/features/visual-sql-editor/services/visual-sql-editor-state.service.mjs +230 -0
  162. package/esm2022/features/visual-sql-editor/types/visual-sql-editor.types.mjs +2 -0
  163. package/esm2022/features/visual-sql-editor/utils/visual-sql-editor-sanitize.util.mjs +72 -0
  164. package/esm2022/features/visual-sql-editor/utils/visual-sql-editor-sql.util.mjs +281 -0
  165. package/esm2022/features/visual-sql-editor/utils/visual-sql-editor-text.util.mjs +37 -0
  166. package/esm2022/features/visual-sql-editor/utils/visual-sql-editor.constants.mjs +89 -0
  167. package/esm2022/features/visual-sql-editor/visual-sql-editor.component.mjs +172 -630
  168. package/esm2022/locales/en.json +351 -3
  169. package/esm2022/locales/es-CO.json +351 -3
  170. package/esm2022/locales/pt.json +351 -3
  171. package/esm2022/providers/features.provider.mjs +40 -4
  172. package/esm2022/public-api.mjs +56 -3
  173. package/features/accordion/accordion.component.d.ts +1 -1
  174. package/features/accordion/{accordion-item.component.d.ts → components/accordion-item/accordion-item.component.d.ts} +1 -1
  175. package/features/autocomplete/autocomplete.component.d.ts +102 -0
  176. package/features/autocomplete/components/autocomplete-chip/autocomplete-chip.component.d.ts +11 -0
  177. package/features/card-list/card/card.component.d.ts +14 -34
  178. package/features/chat/chat.component.d.ts +31 -0
  179. package/features/checkbox-list/checkbox-list.component.d.ts +26 -0
  180. package/features/combobox/combobox.component.d.ts +2 -1
  181. package/features/context-selector/context-selector.component.d.ts +37 -0
  182. package/features/gantt/components/gantt-side-table/gantt-side-table.component.d.ts +8 -0
  183. package/features/gantt/gantt-date.utils.d.ts +36 -0
  184. package/features/gantt/gantt.component.d.ts +24 -0
  185. package/features/gantt/gantt.engine.d.ts +52 -0
  186. package/features/grid-menu/grid-menu.component.d.ts +29 -0
  187. package/features/hyperlink/hyperlink.component.d.ts +2 -1
  188. package/features/image-cropper/image-cropper.component.d.ts +43 -0
  189. package/features/image-cropper/services/image-cropper.service.d.ts +13 -0
  190. package/features/infinite-scroll/infinite-scroll.directive.d.ts +25 -0
  191. package/features/inline-edit/components/fields/inline-edit-number/inline-edit-number.component.d.ts +13 -0
  192. package/features/inline-edit/components/fields/inline-edit-text/inline-edit-text.component.d.ts +13 -0
  193. package/features/inline-edit/components/fields/inline-edit-textarea/inline-edit-textarea.component.d.ts +13 -0
  194. package/features/inline-edit/components/inline-edit-item/inline-edit-item.component.d.ts +37 -0
  195. package/features/inline-edit/fields/inline-edit-field.d.ts +12 -0
  196. package/features/inline-edit/fields/inline-edit-number-field.d.ts +9 -0
  197. package/features/inline-edit/fields/inline-edit-text-field.d.ts +7 -0
  198. package/features/inline-edit/fields/inline-edit-textarea-field.d.ts +9 -0
  199. package/features/inline-edit/inline-edit.component.d.ts +13 -0
  200. package/features/interactive-content/interactive-content.directive.d.ts +31 -0
  201. package/features/kanban/components/kanban-column/kanban-column.component.d.ts +22 -0
  202. package/features/kanban/components/kanban-item/kanban-item.component.d.ts +23 -0
  203. package/features/kanban/components/kanban-item-dragging/kanban-item-dragging.component.d.ts +8 -0
  204. package/features/kanban/directives/kanban-template.directive.d.ts +10 -0
  205. package/features/kanban/kanban.component.d.ts +32 -0
  206. package/features/kanban/services/kanban-event.service.d.ts +15 -0
  207. package/features/loading-state/loading-state.component.d.ts +0 -2
  208. package/features/mouse-events/directives/double-click.directive.d.ts +11 -0
  209. package/features/mouse-events/directives/long-press.directive.d.ts +14 -0
  210. package/features/panel/panel.component.d.ts +12 -3
  211. package/features/pin-code-field/pin-code-field.component.d.ts +44 -0
  212. package/features/profile-picture-picker/profile-picture-picker.component.d.ts +77 -0
  213. package/features/rating-scale/rating-scale.component.d.ts +24 -0
  214. package/features/select-button/select-button.component.d.ts +2 -1
  215. package/features/speech-recognition/services/speech-recognition.service.d.ts +29 -0
  216. package/features/speech-recognition/services/text-to-speech.service.d.ts +24 -0
  217. package/features/speech-recognition/speech-recognition.component.d.ts +50 -0
  218. package/features/spotlight/components/spotlight-overlay/spotlight-overlay.component.d.ts +59 -0
  219. package/features/spotlight/directives/spotlight-step.directive.d.ts +13 -0
  220. package/features/spotlight/services/spotlight-tour.service.d.ts +46 -0
  221. package/features/spotlight/spotlight.component.d.ts +59 -0
  222. package/features/star-rating/star-rating.component.d.ts +26 -0
  223. package/features/stepper/stepper.component.d.ts +23 -0
  224. package/features/switch/switch.component.d.ts +2 -1
  225. package/features/tab/tab.component.d.ts +1 -1
  226. package/features/table/components/table-cell-content.component.d.ts +4 -3
  227. package/features/table/table.component.d.ts +40 -5
  228. package/features/table/utils/table-data.util.d.ts +1 -0
  229. package/features/table/utils/table-layout.util.d.ts +1 -0
  230. package/features/tiered-menu/components/tiered-menu/tiered-menu.component.d.ts +49 -0
  231. package/features/tiered-menu/components/tiered-menu-divider/tiered-menu-divider.component.d.ts +5 -0
  232. package/features/tiered-menu/components/tiered-menu-item/tiered-menu-item.component.d.ts +19 -0
  233. package/features/tiered-menu/components/tiered-menu-nested/tiered-menu-nested.component.d.ts +26 -0
  234. package/features/tiered-menu/directives/tiered-menu.directive.d.ts +44 -0
  235. package/features/tiered-menu/services/tiered-menu.event.service.d.ts +13 -0
  236. package/features/tiered-menu/services/tiered-menu.global.service.d.ts +7 -0
  237. package/features/tiered-menu/services/tiered-menu.service.d.ts +14 -0
  238. package/features/tree/components/tree-node-item/tree-node-item.component.d.ts +37 -0
  239. package/features/tree/tree.component.d.ts +37 -0
  240. package/features/visual-sql-editor/components/visual-sql-editor-field-modal/visual-sql-editor-field-modal.component.d.ts +18 -0
  241. package/features/visual-sql-editor/components/visual-sql-editor-filter-modal/visual-sql-editor-filter-modal.component.d.ts +17 -0
  242. package/features/visual-sql-editor/components/visual-sql-editor-join-modal/visual-sql-editor-join-modal.component.d.ts +13 -0
  243. package/features/visual-sql-editor/components/visual-sql-editor-sort-modal/visual-sql-editor-sort-modal.component.d.ts +13 -0
  244. package/features/visual-sql-editor/components/visual-sql-editor-source-modal/visual-sql-editor-source-modal.component.d.ts +15 -0
  245. package/features/visual-sql-editor/services/visual-sql-editor-flow.service.d.ts +26 -0
  246. package/features/visual-sql-editor/services/visual-sql-editor-state.service.d.ts +72 -0
  247. package/features/visual-sql-editor/types/visual-sql-editor.types.d.ts +182 -0
  248. package/features/visual-sql-editor/utils/visual-sql-editor-sanitize.util.d.ts +14 -0
  249. package/features/visual-sql-editor/utils/visual-sql-editor-sql.util.d.ts +81 -0
  250. package/features/visual-sql-editor/utils/visual-sql-editor-text.util.d.ts +15 -0
  251. package/features/visual-sql-editor/utils/visual-sql-editor.constants.d.ts +36 -0
  252. package/features/visual-sql-editor/visual-sql-editor.component.d.ts +37 -199
  253. package/fesm2022/seniorsistemas-data-seniorx-core.mjs +14883 -6353
  254. package/fesm2022/seniorsistemas-data-seniorx-core.mjs.map +1 -1
  255. package/package.json +8 -8
  256. package/public-api.d.ts +72 -2
  257. package/src/locales/en.json +353 -15
  258. package/src/locales/es-CO.json +352 -14
  259. package/src/locales/pt.json +352 -14
  260. package/styles/sdc-global-variables.scss +1 -1
  261. package/styles.css +1 -1
  262. /package/features/tab/{tab-item.component.d.ts → components/tab-item/tab-item.component.d.ts} +0 -0
@@ -0,0 +1,662 @@
1
+ import { GANTT_BAR_HEIGHT, GANTT_DEFAULT_BAR_COLOR, GANTT_HEADER_HEIGHT, GANTT_ROW_HEIGHT, } from '../../core/constants/gantt.const';
2
+ import { addDays, addHours, diffDays, diffHours, formatDayMonth, formatHourLabel, formatMonthLabel, formatWeekLabel, isWeekend, isSameDay, startOfDay, startOfHour, startOfMonth, startOfWeek, } from './gantt-date.utils';
3
+ // ---------------------------------------------------------------------------
4
+ // Public types & Constants
5
+ // ---------------------------------------------------------------------------
6
+ const RX_VALUE = 3;
7
+ const DATE_RANGE_SAFETY_LIMIT = 5000;
8
+ const DAYS_IN_WEEK = 7;
9
+ const HEADER_LABEL_VERTICAL_OFFSET = 5;
10
+ const HANDLE_WIDTH = 6;
11
+ const TASK_LABEL_HORIZONTAL_PADDING = 6;
12
+ const DRAG_MIN_HANDLE_FACTOR = 2;
13
+ const POPUP_AUTO_REMOVE_DELAY_MS = 3000;
14
+ const MONTHS_IN_YEAR = 12;
15
+ const BAR_SELECTOR = '.sdc-gantt-bar';
16
+ var DragMode;
17
+ (function (DragMode) {
18
+ DragMode[DragMode["Move"] = 0] = "Move";
19
+ DragMode[DragMode["ResizeLeft"] = 1] = "ResizeLeft";
20
+ DragMode[DragMode["ResizeRight"] = 2] = "ResizeRight";
21
+ })(DragMode || (DragMode = {}));
22
+ // ---------------------------------------------------------------------------
23
+ // GanttEngine – pure TypeScript class, no Angular decorators
24
+ // ---------------------------------------------------------------------------
25
+ const SVG_NS = 'http://www.w3.org/2000/svg';
26
+ export class GanttEngine {
27
+ svg;
28
+ tasks;
29
+ options;
30
+ // Layout constants – kept in sync with SCSS tokens
31
+ HEADER_HEIGHT = GANTT_HEADER_HEIGHT;
32
+ ROW_HEIGHT = GANTT_ROW_HEIGHT;
33
+ BAR_HEIGHT = GANTT_BAR_HEIGHT;
34
+ PADDING = 12;
35
+ COLUMN_WIDTHS = {
36
+ hour: 50,
37
+ day: 50,
38
+ week: 140,
39
+ month: 120,
40
+ };
41
+ // Popup element managed by the engine
42
+ popup = null;
43
+ // Active drag state
44
+ drag = null;
45
+ // Bound global handlers (kept so we can remove them on destroy)
46
+ boundMouseMove;
47
+ boundMouseUp;
48
+ constructor(svg, tasks, options) {
49
+ this.svg = svg;
50
+ this.tasks = tasks;
51
+ this.options = options;
52
+ this.boundMouseMove = this.onMouseMove.bind(this);
53
+ this.boundMouseUp = this.onMouseUp.bind(this);
54
+ document.addEventListener('mousemove', this.boundMouseMove);
55
+ document.addEventListener('mouseup', this.boundMouseUp);
56
+ this.render();
57
+ }
58
+ // ---------------------------------------------------------------------------
59
+ // Public API
60
+ // ---------------------------------------------------------------------------
61
+ refresh(tasks) {
62
+ this.tasks = tasks;
63
+ this.render();
64
+ }
65
+ updateOptions(options) {
66
+ this.options = { ...this.options, ...options };
67
+ this.render();
68
+ }
69
+ changeViewMode(mode) {
70
+ this.updateOptions({ viewMode: mode });
71
+ }
72
+ destroy() {
73
+ document.removeEventListener('mousemove', this.boundMouseMove);
74
+ document.removeEventListener('mouseup', this.boundMouseUp);
75
+ this.removePopup();
76
+ this.clearSvg();
77
+ }
78
+ // ---------------------------------------------------------------------------
79
+ // Render pipeline
80
+ // ---------------------------------------------------------------------------
81
+ render() {
82
+ this.clearSvg();
83
+ this.removePopup();
84
+ this.drag = null;
85
+ if (this.tasks.length === 0) {
86
+ return;
87
+ }
88
+ const { dates } = this.computeDateRange();
89
+ const colW = this.COLUMN_WIDTHS[this.options.viewMode];
90
+ const totalWidth = dates.length * colW;
91
+ const totalHeight = this.HEADER_HEIGHT + this.tasks.length * this.ROW_HEIGHT;
92
+ this.svg.setAttribute('width', String(totalWidth));
93
+ this.svg.setAttribute('height', String(totalHeight));
94
+ this.svg.setAttribute('viewBox', `0 0 ${totalWidth} ${totalHeight}`);
95
+ this.drawGrid(dates, colW, totalWidth, totalHeight);
96
+ this.drawBars(dates[0], colW);
97
+ }
98
+ // ---------------------------------------------------------------------------
99
+ // Date range computation
100
+ // ---------------------------------------------------------------------------
101
+ computeDateRange() {
102
+ const mode = this.options.viewMode;
103
+ let minDate = this.tasks[0].start;
104
+ let maxDate = this.tasks[0].end;
105
+ for (const task of this.tasks) {
106
+ if (task.start < minDate) {
107
+ minDate = task.start;
108
+ }
109
+ if (task.end > maxDate) {
110
+ maxDate = task.end;
111
+ }
112
+ }
113
+ // Add margin
114
+ const marginedMax = addDays(maxDate, 1);
115
+ const start = this.slotStart(minDate, mode);
116
+ const end = this.slotStart(addDays(marginedMax, 1), mode);
117
+ const dates = [];
118
+ let cursor = new Date(start);
119
+ // Safety limit to avoid infinite loops
120
+ let safety = 0;
121
+ while (cursor < end && safety < DATE_RANGE_SAFETY_LIMIT) {
122
+ dates.push(new Date(cursor));
123
+ cursor = this.nextSlot(cursor, mode);
124
+ safety++;
125
+ }
126
+ return { start, end, dates };
127
+ }
128
+ slotStart(date, mode) {
129
+ switch (mode) {
130
+ case 'hour':
131
+ return startOfHour(date);
132
+ case 'day':
133
+ return startOfDay(date);
134
+ case 'week':
135
+ return startOfWeek(date);
136
+ case 'month':
137
+ return startOfMonth(date);
138
+ default:
139
+ return startOfDay(date);
140
+ }
141
+ }
142
+ nextSlot(date, mode) {
143
+ switch (mode) {
144
+ case 'hour':
145
+ return addHours(date, 1);
146
+ case 'day':
147
+ return addDays(date, 1);
148
+ case 'week':
149
+ return addDays(date, DAYS_IN_WEEK);
150
+ case 'month': {
151
+ const d = new Date(date);
152
+ d.setMonth(d.getMonth() + 1);
153
+ return d;
154
+ }
155
+ default:
156
+ return addDays(date, 1);
157
+ }
158
+ }
159
+ // ---------------------------------------------------------------------------
160
+ // Grid drawing
161
+ // ---------------------------------------------------------------------------
162
+ drawGrid(dates, colW, totalWidth, totalHeight) {
163
+ const mode = this.options.viewMode;
164
+ // Row backgrounds
165
+ for (let i = 0; i < this.tasks.length; i++) {
166
+ const y = this.HEADER_HEIGHT + i * this.ROW_HEIGHT;
167
+ const bg = this.createSvgElement('rect');
168
+ bg.setAttribute('x', '0');
169
+ bg.setAttribute('y', String(y));
170
+ bg.setAttribute('width', String(totalWidth));
171
+ bg.setAttribute('height', String(this.ROW_HEIGHT));
172
+ bg.setAttribute('class', `sdc-gantt-row-bg ${i % 2 === 0 ? 'sdc-gantt-row-bg--even' : 'sdc-gantt-row-bg--odd'}`);
173
+ this.svg.appendChild(bg);
174
+ }
175
+ // Column slots – backgrounds + separators + labels
176
+ const today = startOfDay(new Date());
177
+ for (let i = 0; i < dates.length; i++) {
178
+ const x = i * colW;
179
+ const date = dates[i];
180
+ // Weekend highlight (day/hour modes)
181
+ if ((mode === 'day' || mode === 'hour') && isWeekend(date)) {
182
+ const wkRect = this.createSvgElement('rect');
183
+ wkRect.setAttribute('x', String(x));
184
+ wkRect.setAttribute('y', String(this.HEADER_HEIGHT));
185
+ wkRect.setAttribute('width', String(colW));
186
+ wkRect.setAttribute('height', String(this.tasks.length * this.ROW_HEIGHT));
187
+ wkRect.setAttribute('class', 'sdc-gantt-weekend');
188
+ this.svg.appendChild(wkRect);
189
+ }
190
+ // Today highlight
191
+ if (mode === 'day' && isSameDay(date, today)) {
192
+ const todayRect = this.createSvgElement('rect');
193
+ todayRect.setAttribute('x', String(x));
194
+ todayRect.setAttribute('y', '0');
195
+ todayRect.setAttribute('width', String(colW));
196
+ todayRect.setAttribute('height', String(totalHeight));
197
+ todayRect.setAttribute('class', 'sdc-gantt-today');
198
+ this.svg.appendChild(todayRect);
199
+ }
200
+ // Vertical grid line
201
+ const line = this.createSvgElement('line');
202
+ line.setAttribute('x1', String(x));
203
+ line.setAttribute('y1', String(this.HEADER_HEIGHT));
204
+ line.setAttribute('x2', String(x));
205
+ line.setAttribute('y2', String(totalHeight));
206
+ line.setAttribute('class', 'sdc-gantt-grid-line');
207
+ this.svg.appendChild(line);
208
+ // Header background
209
+ const hdrRect = this.createSvgElement('rect');
210
+ hdrRect.setAttribute('x', String(x));
211
+ hdrRect.setAttribute('y', '0');
212
+ hdrRect.setAttribute('width', String(colW));
213
+ hdrRect.setAttribute('height', String(this.HEADER_HEIGHT));
214
+ hdrRect.setAttribute('class', 'sdc-gantt-header-cell');
215
+ this.svg.appendChild(hdrRect);
216
+ // Header label
217
+ const label = this.createSvgElement('text');
218
+ label.setAttribute('x', String(x + colW / 2));
219
+ label.setAttribute('y', String(this.HEADER_HEIGHT / 2 + HEADER_LABEL_VERTICAL_OFFSET));
220
+ label.setAttribute('text-anchor', 'middle');
221
+ label.setAttribute('class', 'sdc-gantt-header-label');
222
+ label.textContent = this.formatColumnLabel(date, mode);
223
+ this.svg.appendChild(label);
224
+ }
225
+ // Bottom header border line
226
+ const hdrBorder = this.createSvgElement('line');
227
+ hdrBorder.setAttribute('x1', '0');
228
+ hdrBorder.setAttribute('y1', String(this.HEADER_HEIGHT));
229
+ hdrBorder.setAttribute('x2', String(totalWidth));
230
+ hdrBorder.setAttribute('y2', String(this.HEADER_HEIGHT));
231
+ hdrBorder.setAttribute('class', 'sdc-gantt-header-border');
232
+ this.svg.appendChild(hdrBorder);
233
+ // Horizontal row separators
234
+ for (let i = 1; i <= this.tasks.length; i++) {
235
+ const y = this.HEADER_HEIGHT + i * this.ROW_HEIGHT;
236
+ const hLine = this.createSvgElement('line');
237
+ hLine.setAttribute('x1', '0');
238
+ hLine.setAttribute('y1', String(y));
239
+ hLine.setAttribute('x2', String(totalWidth));
240
+ hLine.setAttribute('y2', String(y));
241
+ hLine.setAttribute('class', 'sdc-gantt-grid-line sdc-gantt-grid-line--horizontal');
242
+ this.svg.appendChild(hLine);
243
+ }
244
+ // Right border line
245
+ const rightLine = this.createSvgElement('line');
246
+ rightLine.setAttribute('x1', String(totalWidth));
247
+ rightLine.setAttribute('y1', '0');
248
+ rightLine.setAttribute('x2', String(totalWidth));
249
+ rightLine.setAttribute('y2', String(totalHeight));
250
+ rightLine.setAttribute('class', 'sdc-gantt-grid-line');
251
+ this.svg.appendChild(rightLine);
252
+ }
253
+ formatColumnLabel(date, mode) {
254
+ switch (mode) {
255
+ case 'hour':
256
+ return formatHourLabel(date);
257
+ case 'day':
258
+ return formatDayMonth(date);
259
+ case 'week':
260
+ return formatWeekLabel(date);
261
+ case 'month':
262
+ return formatMonthLabel(date);
263
+ default:
264
+ return formatDayMonth(date);
265
+ }
266
+ }
267
+ // ---------------------------------------------------------------------------
268
+ // Bar drawing
269
+ // ---------------------------------------------------------------------------
270
+ drawBars(rangeStart, colW) {
271
+ for (let i = 0; i < this.tasks.length; i++) {
272
+ this.drawBarElement(this.tasks[i], i, rangeStart, colW);
273
+ }
274
+ }
275
+ drawBarElement(task, rowIndex, rangeStart, colW) {
276
+ const barX = this.computeBarX(task.start, rangeStart, colW);
277
+ const barW = Math.max(this.computeBarWidth(task, colW), 4);
278
+ const barY = this.HEADER_HEIGHT + rowIndex * this.ROW_HEIGHT + (this.ROW_HEIGHT - this.BAR_HEIGHT) / 2;
279
+ const color = task.color ?? GANTT_DEFAULT_BAR_COLOR;
280
+ const group = this.createSvgElement('g');
281
+ group.setAttribute('class', `sdc-gantt-bar-group${task.customClass ? ' ' + task.customClass : ''}`);
282
+ group.setAttribute('data-task-id', task.id);
283
+ group.style.cursor = this.options.allowMovement ? 'grab' : 'pointer';
284
+ // Main bar rectangle
285
+ const rect = this.createSvgElement('rect');
286
+ rect.setAttribute('x', String(barX));
287
+ rect.setAttribute('y', String(barY));
288
+ rect.setAttribute('width', String(barW));
289
+ rect.setAttribute('height', String(this.BAR_HEIGHT));
290
+ rect.setAttribute('rx', String(RX_VALUE));
291
+ rect.setAttribute('ry', String(RX_VALUE));
292
+ rect.setAttribute('fill', color);
293
+ rect.setAttribute('class', 'sdc-gantt-bar');
294
+ group.appendChild(rect);
295
+ // Task name inside bar
296
+ if (task.showTaskName) {
297
+ const textEl = this.createSvgElement('text');
298
+ textEl.setAttribute('x', String(barX + TASK_LABEL_HORIZONTAL_PADDING));
299
+ textEl.setAttribute('y', String(barY + this.BAR_HEIGHT / 2 + 4));
300
+ textEl.setAttribute('class', 'sdc-gantt-bar-label');
301
+ textEl.setAttribute('clip-path', `url(#clip-${task.id})`);
302
+ textEl.textContent = task.name;
303
+ group.appendChild(textEl);
304
+ // Clip path so text stays inside the bar
305
+ const defs = this.createSvgElement('defs');
306
+ const clip = this.createSvgElement('clipPath');
307
+ clip.setAttribute('id', `clip-${task.id}`);
308
+ const clipRect = this.createSvgElement('rect');
309
+ clipRect.setAttribute('x', String(barX + 2));
310
+ clipRect.setAttribute('y', String(barY));
311
+ clipRect.setAttribute('width', String(Math.max(barW - 4, 0)));
312
+ clipRect.setAttribute('height', String(this.BAR_HEIGHT));
313
+ clip.appendChild(clipRect);
314
+ defs.appendChild(clip);
315
+ this.svg.insertBefore(defs, this.svg.firstChild);
316
+ }
317
+ // Resize handles (only when movement is allowed)
318
+ if (this.options.allowMovement) {
319
+ const leftHandle = this.createSvgElement('rect');
320
+ leftHandle.setAttribute('x', String(barX));
321
+ leftHandle.setAttribute('y', String(barY));
322
+ leftHandle.setAttribute('width', String(HANDLE_WIDTH));
323
+ leftHandle.setAttribute('height', String(this.BAR_HEIGHT));
324
+ leftHandle.setAttribute('rx', String(RX_VALUE));
325
+ leftHandle.setAttribute('fill', 'rgba(0,0,0,0.2)');
326
+ leftHandle.setAttribute('class', 'sdc-gantt-bar-handle sdc-gantt-bar-handle--left');
327
+ leftHandle.style.cursor = 'ew-resize';
328
+ leftHandle.addEventListener('mousedown', (e) => {
329
+ e.stopPropagation();
330
+ this.startDrag(e, task, group, DragMode.ResizeLeft, {
331
+ rangeStart,
332
+ colW,
333
+ rowIndex,
334
+ clientX: e.clientX,
335
+ });
336
+ });
337
+ group.appendChild(leftHandle);
338
+ const rightHandle = this.createSvgElement('rect');
339
+ rightHandle.setAttribute('x', String(barX + barW - HANDLE_WIDTH));
340
+ rightHandle.setAttribute('y', String(barY));
341
+ rightHandle.setAttribute('width', String(HANDLE_WIDTH));
342
+ rightHandle.setAttribute('height', String(this.BAR_HEIGHT));
343
+ rightHandle.setAttribute('rx', String(RX_VALUE));
344
+ rightHandle.setAttribute('fill', 'rgba(0,0,0,0.2)');
345
+ rightHandle.setAttribute('class', 'sdc-gantt-bar-handle sdc-gantt-bar-handle--right');
346
+ rightHandle.style.cursor = 'ew-resize';
347
+ rightHandle.addEventListener('mousedown', (e) => {
348
+ e.stopPropagation();
349
+ this.startDrag(e, task, group, DragMode.ResizeRight, {
350
+ rangeStart,
351
+ colW,
352
+ rowIndex,
353
+ clientX: e.clientX,
354
+ });
355
+ });
356
+ group.appendChild(rightHandle);
357
+ }
358
+ // Click / drag on main bar
359
+ rect.addEventListener('mousedown', (e) => {
360
+ if (this.options.allowMovement) {
361
+ this.startDrag(e, task, group, DragMode.Move, {
362
+ rangeStart,
363
+ colW,
364
+ rowIndex,
365
+ clientX: e.clientX,
366
+ });
367
+ }
368
+ });
369
+ rect.addEventListener('click', (e) => {
370
+ // Only fire click if not dragging
371
+ if (this.drag) {
372
+ return;
373
+ }
374
+ if (this.options.hasPopup) {
375
+ this.showPopup(task, e.clientX, e.clientY);
376
+ }
377
+ this.options.onTaskClick?.(task);
378
+ });
379
+ this.svg.appendChild(group);
380
+ }
381
+ // ---------------------------------------------------------------------------
382
+ // Drag-and-drop
383
+ // ---------------------------------------------------------------------------
384
+ startDrag(e, task, barGroup, mode, seed) {
385
+ e.preventDefault();
386
+ const bar = barGroup.querySelector(BAR_SELECTOR);
387
+ if (!bar) {
388
+ return;
389
+ }
390
+ this.drag = this.createDragState(task, barGroup, bar, mode, seed);
391
+ this.updateBarVisualForDrag(bar, barGroup);
392
+ }
393
+ createDragState(task, barGroup, bar, mode, seed) {
394
+ const startX = seed.clientX;
395
+ const columnWidth = seed.colW;
396
+ const dragRangeStart = seed.rangeStart;
397
+ const dragRowIndex = seed.rowIndex;
398
+ return {
399
+ startX,
400
+ task,
401
+ barGroup,
402
+ mode,
403
+ originalX: parseFloat(bar.getAttribute('x') ?? '0'),
404
+ originalWidth: parseFloat(bar.getAttribute('width') ?? '0'),
405
+ colW: columnWidth,
406
+ rangeStart: dragRangeStart,
407
+ rowIndex: dragRowIndex,
408
+ };
409
+ }
410
+ updateBarVisualForDrag(bar, barGroup) {
411
+ barGroup.style.cursor = 'grabbing';
412
+ bar.setAttribute('stroke', 'var(--sdc-gantt-bar-selected-stroke, #212533)');
413
+ bar.setAttribute('stroke-width', '2');
414
+ }
415
+ onMouseMove(e) {
416
+ const drag = this.drag;
417
+ if (!drag) {
418
+ return;
419
+ }
420
+ const dx = e.clientX - drag.startX;
421
+ const bar = drag.barGroup.querySelector(BAR_SELECTOR);
422
+ if (!bar) {
423
+ return;
424
+ }
425
+ const { mode, originalX, originalWidth } = drag;
426
+ if (mode === DragMode.Move) {
427
+ this.handleDragMove(drag, originalX, originalWidth, bar, dx);
428
+ }
429
+ else if (mode === DragMode.ResizeRight) {
430
+ this.handleDragResizeRight(drag, originalX, originalWidth, bar, dx);
431
+ }
432
+ else if (mode === DragMode.ResizeLeft) {
433
+ this.handleDragResizeLeft(drag, originalX, originalWidth, bar, dx);
434
+ }
435
+ else {
436
+ // Drag mode is exhaustive by type, this guards future changes.
437
+ }
438
+ }
439
+ handleDragMove(drag, originalX, originalWidth, bar, dx) {
440
+ const newX = Math.max(0, originalX + dx);
441
+ bar.setAttribute('x', String(newX));
442
+ const leftHandle = drag.barGroup.querySelector('.sdc-gantt-bar-handle--left');
443
+ const rightHandle = drag.barGroup.querySelector('.sdc-gantt-bar-handle--right');
444
+ if (leftHandle) {
445
+ leftHandle.setAttribute('x', String(newX));
446
+ }
447
+ if (rightHandle) {
448
+ rightHandle.setAttribute('x', String(newX + originalWidth - HANDLE_WIDTH));
449
+ }
450
+ const clipRect = this.svg.querySelector(`#clip-${drag.task.id} rect`);
451
+ if (clipRect) {
452
+ clipRect.setAttribute('x', String(newX + 2));
453
+ }
454
+ const label = drag.barGroup.querySelector('.sdc-gantt-bar-label');
455
+ if (label) {
456
+ label.setAttribute('x', String(newX + TASK_LABEL_HORIZONTAL_PADDING));
457
+ }
458
+ }
459
+ handleDragResizeRight(drag, originalX, originalWidth, bar, dx) {
460
+ const newWidth = Math.max(drag.colW / DRAG_MIN_HANDLE_FACTOR, originalWidth + dx);
461
+ bar.setAttribute('width', String(newWidth));
462
+ const rightHandle = drag.barGroup.querySelector('.sdc-gantt-bar-handle--right');
463
+ if (rightHandle) {
464
+ rightHandle.setAttribute('x', String(originalX + newWidth - HANDLE_WIDTH));
465
+ }
466
+ const clipRect = this.svg.querySelector(`#clip-${drag.task.id} rect`);
467
+ if (clipRect) {
468
+ clipRect.setAttribute('width', String(Math.max(newWidth - 4, 0)));
469
+ }
470
+ }
471
+ handleDragResizeLeft(drag, originalX, originalWidth, bar, dx) {
472
+ const newWidth = Math.max(drag.colW / DRAG_MIN_HANDLE_FACTOR, originalWidth - dx);
473
+ const newX = originalX + (originalWidth - newWidth);
474
+ bar.setAttribute('x', String(newX));
475
+ bar.setAttribute('width', String(newWidth));
476
+ const leftHandle = drag.barGroup.querySelector('.sdc-gantt-bar-handle--left');
477
+ if (leftHandle) {
478
+ leftHandle.setAttribute('x', String(newX));
479
+ }
480
+ const clipRect = this.svg.querySelector(`#clip-${drag.task.id} rect`);
481
+ if (clipRect) {
482
+ clipRect.setAttribute('x', String(newX + 2));
483
+ clipRect.setAttribute('width', String(Math.max(newWidth - 4, 0)));
484
+ }
485
+ const label = drag.barGroup.querySelector('.sdc-gantt-bar-label');
486
+ if (label) {
487
+ label.setAttribute('x', String(newX + TASK_LABEL_HORIZONTAL_PADDING));
488
+ }
489
+ }
490
+ onMouseUp(e) {
491
+ if (!this.drag) {
492
+ return;
493
+ }
494
+ const { task, barGroup, rangeStart, colW, mode } = this.drag;
495
+ const bar = barGroup.querySelector(BAR_SELECTOR);
496
+ if (!bar) {
497
+ this.drag = null;
498
+ return;
499
+ }
500
+ const finalX = parseFloat(bar.getAttribute('x') ?? '0');
501
+ const finalW = parseFloat(bar.getAttribute('width') ?? '0');
502
+ const dx = e.clientX - this.drag.startX;
503
+ this.emitDateChangeIfSignificantMovement(task, finalX, finalW, dx, rangeStart, colW, mode);
504
+ // Reset visual states
505
+ bar.removeAttribute('stroke');
506
+ bar.removeAttribute('stroke-width');
507
+ barGroup.style.cursor = 'grab';
508
+ this.drag = null;
509
+ }
510
+ emitDateChangeIfSignificantMovement(task, finalX, finalW, dx, rangeStart, colW, mode) {
511
+ // Only emit if there was meaningful movement
512
+ if (Math.abs(dx) > 2 && this.options.onDateChange) {
513
+ const { newStart, newEnd } = this.calculateNewDates(task, finalX, finalW, rangeStart, colW, mode);
514
+ this.options.onDateChange(task, newStart, newEnd);
515
+ }
516
+ }
517
+ calculateNewDates(task, finalX, finalW, rangeStart, colW, mode) {
518
+ const durationMs = task.end.getTime() - task.start.getTime();
519
+ let newStart;
520
+ let newEnd;
521
+ if (mode === DragMode.Move) {
522
+ newStart = this.xToDate(finalX, rangeStart, colW);
523
+ newEnd = new Date(newStart.getTime() + durationMs);
524
+ }
525
+ else if (mode === DragMode.ResizeRight) {
526
+ newStart = task.start;
527
+ newEnd = this.xToDate(finalX + finalW, rangeStart, colW);
528
+ }
529
+ else {
530
+ // resize-left
531
+ newStart = this.xToDate(finalX, rangeStart, colW);
532
+ newEnd = task.end;
533
+ }
534
+ return { newStart, newEnd };
535
+ }
536
+ // ---------------------------------------------------------------------------
537
+ // Popup
538
+ // ---------------------------------------------------------------------------
539
+ showPopup(task, clientX, clientY) {
540
+ this.removePopup();
541
+ const div = document.createElement('div');
542
+ div.className = 'sdc-gantt-popup';
543
+ div.style.cssText = `
544
+ position: fixed;
545
+ z-index: 9999;
546
+ background: #fff;
547
+ border: 1px solid #ccc;
548
+ border-radius: 4px;
549
+ padding: 8px 12px;
550
+ box-shadow: 0 2px 8px rgba(0,0,0,.2);
551
+ font-size: 13px;
552
+ pointer-events: none;
553
+ white-space: nowrap;
554
+ `;
555
+ const formatOpts = { day: '2-digit', month: 'short', year: 'numeric' };
556
+ const start = task.start.toLocaleDateString('pt-BR', formatOpts);
557
+ const end = task.end.toLocaleDateString('pt-BR', formatOpts);
558
+ const title = document.createElement('strong');
559
+ title.style.display = 'block';
560
+ title.style.marginBottom = '4px';
561
+ title.textContent = task.name;
562
+ const startLabel = document.createElement('span');
563
+ startLabel.textContent = `Inicio: ${start}`;
564
+ const lineBreak = document.createElement('br');
565
+ const endLabel = document.createElement('span');
566
+ endLabel.textContent = `Fim: ${end}`;
567
+ div.replaceChildren(title, startLabel, lineBreak, endLabel); /*
568
+ <strong style="display:block;margin-bottom:4px;">${task.name}</strong>
569
+ <span>Início: ${start}</span><br>
570
+ <span>Fim: ${end}</span>
571
+ */
572
+ div.style.left = `${clientX + this.PADDING}px`;
573
+ div.style.top = `${clientY - 10}px`;
574
+ document.body.appendChild(div);
575
+ this.popup = div;
576
+ // Auto-remove after 3 s
577
+ setTimeout(() => this.removePopup(), POPUP_AUTO_REMOVE_DELAY_MS);
578
+ // Remove on next click anywhere
579
+ const removeOnClick = () => {
580
+ this.removePopup();
581
+ document.removeEventListener('click', removeOnClick, true);
582
+ };
583
+ document.addEventListener('click', removeOnClick, true);
584
+ }
585
+ removePopup() {
586
+ if (this.popup?.parentNode) {
587
+ this.popup.parentNode.removeChild(this.popup);
588
+ }
589
+ this.popup = null;
590
+ }
591
+ // ---------------------------------------------------------------------------
592
+ // Position / dimension helpers
593
+ // ---------------------------------------------------------------------------
594
+ computeBarX(taskStart, rangeStart, colW) {
595
+ const mode = this.options.viewMode;
596
+ switch (mode) {
597
+ case 'hour':
598
+ return diffHours(rangeStart, taskStart) * colW;
599
+ case 'day':
600
+ return diffDays(rangeStart, taskStart) * colW;
601
+ case 'week':
602
+ return (diffDays(rangeStart, taskStart) / DAYS_IN_WEEK) * colW;
603
+ case 'month': {
604
+ const monthDiff = (taskStart.getFullYear() - rangeStart.getFullYear()) * MONTHS_IN_YEAR +
605
+ (taskStart.getMonth() - rangeStart.getMonth());
606
+ const dayFraction = (taskStart.getDate() - 1) / new Date(taskStart.getFullYear(), taskStart.getMonth() + 1, 0).getDate();
607
+ return (monthDiff + dayFraction) * colW;
608
+ }
609
+ default:
610
+ return diffDays(rangeStart, taskStart) * colW;
611
+ }
612
+ }
613
+ computeBarWidth(task, colW) {
614
+ const mode = this.options.viewMode;
615
+ switch (mode) {
616
+ case 'hour':
617
+ return diffHours(task.start, task.end) * colW;
618
+ case 'day':
619
+ return diffDays(task.start, task.end) * colW;
620
+ case 'week':
621
+ return (diffDays(task.start, task.end) / DAYS_IN_WEEK) * colW;
622
+ case 'month': {
623
+ const daysInRange = diffDays(task.start, task.end);
624
+ const daysInMonth = new Date(task.start.getFullYear(), task.start.getMonth() + 1, 0).getDate();
625
+ return (daysInRange / daysInMonth) * colW;
626
+ }
627
+ default:
628
+ return diffDays(task.start, task.end) * colW;
629
+ }
630
+ }
631
+ xToDate(x, rangeStart, colW) {
632
+ const mode = this.options.viewMode;
633
+ const slots = x / colW;
634
+ switch (mode) {
635
+ case 'hour':
636
+ return addHours(rangeStart, Math.round(slots));
637
+ case 'day':
638
+ return addDays(rangeStart, Math.round(slots));
639
+ case 'week':
640
+ return addDays(rangeStart, Math.round(slots * DAYS_IN_WEEK));
641
+ case 'month': {
642
+ const d = new Date(rangeStart);
643
+ d.setMonth(d.getMonth() + Math.floor(slots));
644
+ return d;
645
+ }
646
+ default:
647
+ return addDays(rangeStart, Math.round(slots));
648
+ }
649
+ }
650
+ // ---------------------------------------------------------------------------
651
+ // SVG helpers
652
+ // ---------------------------------------------------------------------------
653
+ clearSvg() {
654
+ while (this.svg.firstChild) {
655
+ this.svg.removeChild(this.svg.firstChild);
656
+ }
657
+ }
658
+ createSvgElement(tag) {
659
+ return document.createElementNS(SVG_NS, tag);
660
+ }
661
+ }
662
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FudHQuZW5naW5lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGliL3NyYy9mZWF0dXJlcy9nYW50dC9nYW50dC5lbmdpbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLGdCQUFnQixFQUNoQix1QkFBdUIsRUFDdkIsbUJBQW1CLEVBQ25CLGdCQUFnQixHQUNqQixNQUFNLGtDQUFrQyxDQUFDO0FBRTFDLE9BQU8sRUFDTCxPQUFPLEVBQ1AsUUFBUSxFQUNSLFFBQVEsRUFDUixTQUFTLEVBQ1QsY0FBYyxFQUNkLGVBQWUsRUFDZixnQkFBZ0IsRUFDaEIsZUFBZSxFQUNmLFNBQVMsRUFDVCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFdBQVcsRUFDWCxZQUFZLEVBQ1osV0FBVyxHQUNaLE1BQU0sb0JBQW9CLENBQUM7QUFFNUIsOEVBQThFO0FBQzlFLDJCQUEyQjtBQUMzQiw4RUFBOEU7QUFFOUUsTUFBTSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBQ25CLE1BQU0sdUJBQXVCLEdBQUcsSUFBSSxDQUFDO0FBQ3JDLE1BQU0sWUFBWSxHQUFHLENBQUMsQ0FBQztBQUN2QixNQUFNLDRCQUE0QixHQUFHLENBQUMsQ0FBQztBQUN2QyxNQUFNLFlBQVksR0FBRyxDQUFDLENBQUM7QUFDdkIsTUFBTSw2QkFBNkIsR0FBRyxDQUFDLENBQUM7QUFDeEMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLENBQUM7QUFDakMsTUFBTSwwQkFBMEIsR0FBRyxJQUFJLENBQUM7QUFDeEMsTUFBTSxjQUFjLEdBQUcsRUFBRSxDQUFDO0FBQzFCLE1BQU0sWUFBWSxHQUFHLGdCQUFnQixDQUFDO0FBRXRDLElBQUssUUFJSjtBQUpELFdBQUssUUFBUTtJQUNYLHVDQUFJLENBQUE7SUFDSixtREFBVSxDQUFBO0lBQ1YscURBQVcsQ0FBQTtBQUNiLENBQUMsRUFKSSxRQUFRLEtBQVIsUUFBUSxRQUlaO0FBNkJELDhFQUE4RTtBQUM5RSw2REFBNkQ7QUFDN0QsOEVBQThFO0FBRTlFLE1BQU0sTUFBTSxHQUFHLDRCQUE0QixDQUFDO0FBRTVDLE1BQU0sT0FBTyxXQUFXO0lBQ0wsR0FBRyxDQUFhO0lBQ3pCLEtBQUssQ0FBYztJQUNuQixPQUFPLENBQXFCO0lBRXBDLG1EQUFtRDtJQUNsQyxhQUFhLEdBQUcsbUJBQW1CLENBQUM7SUFDcEMsVUFBVSxHQUFHLGdCQUFnQixDQUFDO0lBQzlCLFVBQVUsR0FBRyxnQkFBZ0IsQ0FBQztJQUM5QixPQUFPLEdBQUcsRUFBRSxDQUFDO0lBRWIsYUFBYSxHQUFrQztRQUM5RCxJQUFJLEVBQUUsRUFBRTtRQUNSLEdBQUcsRUFBRSxFQUFFO1FBQ1AsSUFBSSxFQUFFLEdBQUc7UUFDVCxLQUFLLEVBQUUsR0FBRztLQUNYLENBQUM7SUFFRixzQ0FBc0M7SUFDOUIsS0FBSyxHQUEwQixJQUFJLENBQUM7SUFFNUMsb0JBQW9CO0lBQ1osSUFBSSxHQUFxQixJQUFJLENBQUM7SUFFdEMsZ0VBQWdFO0lBQy9DLGNBQWMsQ0FBMEI7SUFDeEMsWUFBWSxDQUEwQjtJQUV2RCxZQUFZLEdBQWUsRUFBRSxLQUFrQixFQUFFLE9BQTJCO1FBQzFFLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO1FBQ2YsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFFdkIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTlDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzVELFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRXhELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBRUQsOEVBQThFO0lBQzlFLGFBQWE7SUFDYiw4RUFBOEU7SUFFdkUsT0FBTyxDQUFDLEtBQWtCO1FBQy9CLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBRU0sYUFBYSxDQUFDLE9BQW9DO1FBQ3ZELElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQztRQUMvQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDaEIsQ0FBQztJQUVNLGNBQWMsQ0FBQyxJQUFtQjtRQUN2QyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVNLE9BQU87UUFDWixRQUFRLENBQUMsbUJBQW1CLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUMvRCxRQUFRLENBQUMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2xCLENBQUM7SUFFRCw4RUFBOEU7SUFDOUUsa0JBQWtCO0lBQ2xCLDhFQUE4RTtJQUV0RSxNQUFNO1FBQ1osSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2hCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUVqQixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzVCLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQzFDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN2RCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUN2QyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7UUFFN0UsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUUsT0FBTyxVQUFVLElBQUksV0FBVyxFQUFFLENBQUMsQ0FBQztRQUVyRSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRCw4RUFBOEU7SUFDOUUseUJBQXlCO0lBQ3pCLDhFQUE4RTtJQUV0RSxnQkFBZ0I7UUFDdEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFFbkMsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7UUFDbEMsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFFaEMsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDOUIsSUFBSSxJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sRUFBRSxDQUFDO2dCQUN6QixPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUN2QixDQUFDO1lBRUQsSUFBSSxJQUFJLENBQUMsR0FBRyxHQUFHLE9BQU8sRUFBRSxDQUFDO2dCQUN2QixPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztZQUNyQixDQUFDO1FBQ0gsQ0FBQztRQUVELGFBQWE7UUFDYixNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRXhDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzVDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMxRCxNQUFNLEtBQUssR0FBVyxFQUFFLENBQUM7UUFFekIsSUFBSSxNQUFNLEdBQUcsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0IsdUNBQXVDO1FBQ3ZDLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztRQUNmLE9BQU8sTUFBTSxHQUFHLEdBQUcsSUFBSSxNQUFNLEdBQUcsdUJBQXVCLEVBQUUsQ0FBQztZQUN4RCxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDN0IsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sRUFBRSxDQUFDO1FBQ1gsQ0FBQztRQUVELE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFTyxTQUFTLENBQUMsSUFBVSxFQUFFLElBQW1CO1FBQy9DLFFBQVEsSUFBSSxFQUFFLENBQUM7WUFDYixLQUFLLE1BQU07Z0JBQ1QsT0FBTyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDM0IsS0FBSyxLQUFLO2dCQUNSLE9BQU8sVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzFCLEtBQUssTUFBTTtnQkFDVCxPQUFPLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMzQixLQUFLLE9BQU87Z0JBQ1YsT0FBTyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDNUI7Z0JBQ0UsT0FBTyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUIsQ0FBQztJQUNILENBQUM7SUFFTyxRQUFRLENBQUMsSUFBVSxFQUFFLElBQW1CO1FBQzlDLFFBQVEsSUFBSSxFQUFFLENBQUM7WUFDYixLQUFLLE1BQU07Z0JBQ1QsT0FBTyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzNCLEtBQUssS0FBSztnQkFDUixPQUFPLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDMUIsS0FBSyxNQUFNO2dCQUNULE9BQU8sT0FBTyxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQztZQUNyQyxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQ2IsTUFBTSxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3pCLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUM3QixPQUFPLENBQUMsQ0FBQztZQUNYLENBQUM7WUFDRDtnQkFDRSxPQUFPLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDNUIsQ0FBQztJQUNILENBQUM7SUFFRCw4RUFBOEU7SUFDOUUsZUFBZTtJQUNmLDhFQUE4RTtJQUV0RSxRQUFRLENBQUMsS0FBYSxFQUFFLElBQVksRUFBRSxVQUFrQixFQUFFLFdBQW1CO1FBQ25GLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBRW5DLGtCQUFrQjtRQUNsQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUMzQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQ25ELE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN6QyxFQUFFLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUMxQixFQUFFLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNoQyxFQUFFLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUM3QyxFQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDbkQsRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsb0JBQW9CLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxDQUFDO1lBQ2pILElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzNCLENBQUM7UUFFRCxtREFBbUQ7UUFDbkQsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztRQUVyQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3RDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDbkIsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRXRCLHFDQUFxQztZQUNyQyxJQUFJLENBQUMsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssTUFBTSxDQUFDLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQzNELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDN0MsTUFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BDLE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztnQkFDckQsTUFBTSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQzNDLE1BQU0sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztnQkFDM0UsTUFBTSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztnQkFDbEQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDL0IsQ0FBQztZQUVELGtCQUFrQjtZQUNsQixJQUFJLElBQUksS0FBSyxLQUFLLElBQUksU0FBUyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUM3QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ2hELFNBQVMsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN2QyxTQUFTLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDakMsU0FBUyxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQzlDLFNBQVMsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO2dCQUN0RCxTQUFTLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO2dCQUNuRCxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNsQyxDQUFDO1lBRUQscUJBQXFCO1lBQ3JCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMzQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7WUFDcEQsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbkMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUscUJBQXFCLENBQUMsQ0FBQztZQUNsRCxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUUzQixvQkFBb0I7WUFDcEIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzlDLE9BQU8sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3JDLE9BQU8sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQy9CLE9BQU8sQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzVDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztZQUMzRCxPQUFPLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO1lBQ3ZELElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRTlCLGVBQWU7WUFDZixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDNUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QyxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLEdBQUcsNEJBQTRCLENBQUMsQ0FBQyxDQUFDO1lBQ3ZGLEtBQUssQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzVDLEtBQUssQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLHdCQUF3QixDQUFDLENBQUM7WUFDdEQsS0FBSyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3ZELElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlCLENBQUM7UUFFRCw0QkFBNEI7UUFDNUIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hELFNBQVMsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2xDLFNBQVMsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztRQUN6RCxTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUNqRCxTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7UUFDekQsU0FBUyxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUseUJBQXlCLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUVoQyw0QkFBNEI7UUFDNUIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDNUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUNuRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDNUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDOUIsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEMsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDN0MsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEMsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUscURBQXFELENBQUMsQ0FBQztZQUNuRixJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QixDQUFDO1FBRUQsb0JBQW9CO1FBQ3BCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoRCxTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUNqRCxTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNsQyxTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUNqRCxTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUNsRCxTQUFTLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFTyxpQkFBaUIsQ0FBQyxJQUFVLEVBQUUsSUFBbUI7UUFDdkQsUUFBUSxJQUFJLEVBQUUsQ0FBQztZQUNiLEtBQUssTUFBTTtnQkFDVCxPQUFPLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMvQixLQUFLLEtBQUs7Z0JBQ1IsT0FBTyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDOUIsS0FBSyxNQUFNO2dCQUNULE9BQU8sZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQy9CLEtBQUssT0FBTztnQkFDVixPQUFPLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2hDO2dCQUNFLE9BQU8sY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hDLENBQUM7SUFDSCxDQUFDO0lBRUQsOEVBQThFO0lBQzlFLGNBQWM7SUFDZCw4RUFBOEU7SUFFdEUsUUFBUSxDQUFDLFVBQWdCLEVBQUUsSUFBWTtRQUM3QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUMzQyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMxRCxDQUFDO0lBQ0gsQ0FBQztJQUVPLGNBQWMsQ0FBQyxJQUFlLEVBQUUsUUFBZ0IsRUFBRSxVQUFnQixFQUFFLElBQVk7UUFDdEYsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM1RCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzNELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLEdBQUcsUUFBUSxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkcsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssSUFBSSx1QkFBdUIsQ0FBQztRQUVwRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekMsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsc0JBQXNCLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3BHLEtBQUssQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM1QyxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFFckUscUJBQXFCO1FBQ3JCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN6QyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDNUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV4Qix1QkFBdUI7UUFDdkIsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzdDLE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxJQUFJLEdBQUcsNkJBQTZCLENBQUMsQ0FBQyxDQUFDO1lBQ3ZFLE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqRSxNQUFNLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO1lBQ3BELE1BQU0sQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLGFBQWEsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDMUQsTUFBTSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQy9CLEtBQUssQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFMUIseUNBQXlDO1lBQ3pDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMzQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDL0MsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUMzQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDL0MsUUFBUSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdDLFFBQVEsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLFFBQVEsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlELFFBQVEsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzNCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbkQsQ0FBQztRQUVELGlEQUFpRDtRQUNqRCxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDL0IsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2pELFVBQVUsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzNDLFVBQVUsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzNDLFVBQVUsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO1lBQ3ZELFVBQVUsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUMzRCxVQUFVLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUNoRCxVQUFVLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1lBQ25ELFVBQVUsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLGlEQUFpRCxDQUFDLENBQUM7WUFDcEYsVUFBVSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDO1lBQ3RDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFhLEVBQUUsRUFBRTtnQkFDekQsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUNwQixJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxVQUFVLEVBQUU7b0JBQ2xELFVBQVU7b0JBQ1YsSUFBSTtvQkFDSixRQUFRO29CQUNSLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTztpQkFDbkIsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7WUFDSCxLQUFLLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRTlCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNsRCxXQUFXLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsSUFBSSxHQUFHLElBQUksR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDO1lBQ2xFLFdBQVcsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzVDLFdBQVcsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO1lBQ3hELFdBQVcsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUM1RCxXQUFXLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUNqRCxXQUFXLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1lBQ3BELFdBQVcsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLGtEQUFrRCxDQUFDLENBQUM7WUFDdEYsV0FBVyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDO1lBQ3ZDLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFhLEVBQUUsRUFBRTtnQkFDMUQsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUNwQixJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxXQUFXLEVBQUU7b0JBQ25ELFVBQVU7b0JBQ1YsSUFBSTtvQkFDSixRQUFRO29CQUNSLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTztpQkFDbkIsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7WUFDSCxLQUFLLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2pDLENBQUM7UUFFRCwyQkFBMkI7UUFDM0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxDQUFDLENBQWEsRUFBRSxFQUFFO1lBQ25ELElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQztnQkFDL0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsSUFBSSxFQUFFO29CQUM1QyxVQUFVO29CQUNWLElBQUk7b0JBQ0osUUFBUTtvQkFDUixPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU87aUJBQ25CLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFhLEVBQUUsRUFBRTtZQUMvQyxrQ0FBa0M7WUFDbEMsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2QsT0FBTztZQUNULENBQUM7WUFDRCxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQzFCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzdDLENBQUM7WUFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25DLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVELDhFQUE4RTtJQUM5RSxnQkFBZ0I7SUFDaEIsOEVBQThFO0lBRXRFLFNBQVMsQ0FDZixDQUFhLEVBQ2IsSUFBZSxFQUNmLFFBQXFCLEVBQ3JCLElBQWMsRUFDZCxJQUFtQjtRQUVuQixDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDbkIsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBaUIsWUFBWSxDQUFDLENBQUM7UUFDakUsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ1QsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2xFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVPLGVBQWUsQ0FDckIsSUFBZSxFQUNmLFFBQXFCLEVBQ3JCLEdBQW1CLEVBQ25CLElBQWMsRUFDZCxJQUFtQjtRQUVuQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQzVCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDOUIsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUN2QyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBRW5DLE9BQU87WUFDTCxNQUFNO1lBQ04sSUFBSTtZQUNKLFFBQVE7WUFDUixJQUFJO1lBQ0osU0FBUyxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQztZQUNuRCxhQUFhLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxDQUFDO1lBQzNELElBQUksRUFBRSxXQUFXO1lBQ2pCLFVBQVUsRUFBRSxjQUFjO1lBQzFCLFFBQVEsRUFBRSxZQUFZO1NBQ3ZCLENBQUM7SUFDSixDQUFDO0lBRU8sc0JBQXNCLENBQUMsR0FBbUIsRUFBRSxRQUFxQjtRQUN2RSxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUM7UUFDbkMsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsK0NBQStDLENBQUMsQ0FBQztRQUM1RSxHQUFHLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRU8sV0FBVyxDQUFDLENBQWE7UUFDL0IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDVixPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNuQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBaUIsWUFBWSxDQUFDLENBQUM7UUFDdEUsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ1QsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFFaEQsSUFBSSxJQUFJLEtBQUssUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQy9ELENBQUM7YUFBTSxJQUFJLElBQUksS0FBSyxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDekMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN0RSxDQUFDO2FBQU0sSUFBSSxJQUFJLEtBQUssUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3hDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDckUsQ0FBQzthQUFNLENBQUM7WUFDTiwrREFBK0Q7UUFDakUsQ0FBQztJQUNILENBQUM7SUFFTyxjQUFjLENBQUMsSUFBZSxFQUFFLFNBQWlCLEVBQUUsYUFBcUIsRUFBRSxHQUFtQixFQUFFLEVBQVU7UUFDL0csTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsU0FBUyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3pDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBRXBDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFpQiw2QkFBNkIsQ0FBQyxDQUFDO1FBQzlGLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFpQiw4QkFBOEIsQ0FBQyxDQUFDO1FBQ2hHLElBQUksVUFBVSxFQUFFLENBQUM7WUFDZixVQUFVLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUM3QyxDQUFDO1FBRUQsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNoQixXQUFXLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsSUFBSSxHQUFHLGFBQWEsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBQzdFLENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBaUIsU0FBUyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDdEYsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUNiLFFBQVEsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvQyxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQWlCLHNCQUFzQixDQUFDLENBQUM7UUFDbEYsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNWLEtBQUssQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxJQUFJLEdBQUcsNkJBQTZCLENBQUMsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7SUFDSCxDQUFDO0lBRU8scUJBQXFCLENBQUMsSUFBZSxFQUFFLFNBQWlCLEVBQUUsYUFBcUIsRUFBRSxHQUFtQixFQUFFLEVBQVU7UUFDdEgsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLHNCQUFzQixFQUFFLGFBQWEsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUNsRixHQUFHLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUU1QyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBaUIsOEJBQThCLENBQUMsQ0FBQztRQUNoRyxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ2hCLFdBQVcsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxTQUFTLEdBQUcsUUFBUSxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDN0UsQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFpQixTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN0RixJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ2IsUUFBUSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEUsQ0FBQztJQUNILENBQUM7SUFFTyxvQkFBb0IsQ0FBQyxJQUFlLEVBQUUsU0FBaUIsRUFBRSxhQUFxQixFQUFFLEdBQW1CLEVBQUUsRUFBVTtRQUNySCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsc0JBQXNCLEVBQUUsYUFBYSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ2xGLE1BQU0sSUFBSSxHQUFHLFNBQVMsR0FBRyxDQUFDLGFBQWEsR0FBRyxRQUFRLENBQUMsQ0FBQztRQUNwRCxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNwQyxHQUFHLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUU1QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBaUIsNkJBQTZCLENBQUMsQ0FBQztRQUM5RixJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2YsVUFBVSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDN0MsQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFpQixTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN0RixJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ2IsUUFBUSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdDLFFBQVEsQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7UUFFRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBaUIsc0JBQXNCLENBQUMsQ0FBQztRQUNsRixJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1YsS0FBSyxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLElBQUksR0FBRyw2QkFBNkIsQ0FBQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztJQUNILENBQUM7SUFFTyxTQUFTLENBQUMsQ0FBYTtRQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2YsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDN0QsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBaUIsWUFBWSxDQUFDLENBQUM7UUFDakUsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ1QsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7WUFDakIsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztRQUN4RCxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztRQUM1RCxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBRXhDLElBQUksQ0FBQyxtQ0FBbUMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUUzRixzQkFBc0I7UUFDdEIsR0FBRyxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM5QixHQUFHLENBQUMsZUFBZSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3BDLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUUvQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNuQixDQUFDO0lBRU8sbUNBQW1DLENBQ3pDLElBQWUsRUFDZixNQUFjLEVBQ2QsTUFBYyxFQUNkLEVBQVUsRUFDVixVQUFnQixFQUNoQixJQUFZLEVBQ1osSUFBYztRQUVkLDZDQUE2QztRQUM3QyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDbEQsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNsRyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3BELENBQUM7SUFDSCxDQUFDO0lBRU8saUJBQWlCLENBQ3ZCLElBQWUsRUFDZixNQUFjLEVBQ2QsTUFBYyxFQUNkLFVBQWdCLEVBQ2hCLElBQVksRUFDWixJQUFjO1FBRWQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzdELElBQUksUUFBYyxDQUFDO1FBQ25CLElBQUksTUFBWSxDQUFDO1FBRWpCLElBQUksSUFBSSxLQUFLLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUMzQixRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2xELE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLEdBQUcsVUFBVSxDQUFDLENBQUM7UUFDckQsQ0FBQzthQUFNLElBQUksSUFBSSxLQUFLLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN6QyxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUN0QixNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsTUFBTSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMzRCxDQUFDO2FBQU0sQ0FBQztZQUNOLGNBQWM7WUFDZCxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2xELE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQ3BCLENBQUM7UUFFRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFRCw4RUFBOEU7SUFDOUUsUUFBUTtJQUNSLDhFQUE4RTtJQUV0RSxTQUFTLENBQUMsSUFBZSxFQUFFLE9BQWUsRUFBRSxPQUFlO1FBQ2pFLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUVuQixNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFDLEdBQUcsQ0FBQyxTQUFTLEdBQUcsaUJBQWlCLENBQUM7UUFDbEMsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUc7Ozs7Ozs7Ozs7O0tBV25CLENBQUM7UUFFRixNQUFNLFVBQVUsR0FBK0IsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxDQUFDO1FBQ25HLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBRTdELE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDL0MsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQzlCLEtBQUssQ0FBQyxLQUFLLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUNqQyxLQUFLLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFFOUIsTUFBTSxVQUFVLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsRCxVQUFVLENBQUMsV0FBVyxHQUFHLFdBQVcsS0FBSyxFQUFFLENBQUM7UUFFNUMsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUUvQyxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hELFFBQVEsQ0FBQyxXQUFXLEdBQUcsUUFBUSxHQUFHLEVBQUUsQ0FBQztRQUVyQyxHQUFHLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7Ozs7VUFJM0Q7UUFFRixHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxHQUFHLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUM7UUFDL0MsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsR0FBRyxPQUFPLEdBQUcsRUFBRSxJQUFJLENBQUM7UUFFcEMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUM7UUFFakIsd0JBQXdCO1FBQ3hCLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztRQUVqRSxnQ0FBZ0M7UUFDaEMsTUFBTSxhQUFhLEdBQUcsR0FBUyxFQUFFO1lBQy9CLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNuQixRQUFRLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM3RCxDQUFDLENBQUM7UUFDRixRQUFRLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRU8sV0FBVztRQUNqQixJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoRCxDQUFDO1FBRUQsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7SUFDcEIsQ0FBQztJQUVELDhFQUE4RTtJQUM5RSwrQkFBK0I7SUFDL0IsOEVBQThFO0lBRXRFLFdBQVcsQ0FBQyxTQUFlLEVBQUUsVUFBZ0IsRUFBRSxJQUFZO1FBQ2pFLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQ25DLFFBQVEsSUFBSSxFQUFFLENBQUM7WUFDYixLQUFLLE1BQU07Z0JBQ1QsT0FBTyxTQUFTLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxHQUFHLElBQUksQ0FBQztZQUNqRCxLQUFLLEtBQUs7Z0JBQ1IsT0FBTyxRQUFRLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxHQUFHLElBQUksQ0FBQztZQUNoRCxLQUFLLE1BQU07Z0JBQ1QsT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLEdBQUcsWUFBWSxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQ2pFLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQztnQkFDYixNQUFNLFNBQVMsR0FDYixDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxVQUFVLENBQUMsV0FBVyxFQUFFLENBQUMsR0FBRyxjQUFjO29CQUNyRSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsR0FBRyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztnQkFDakQsTUFBTSxXQUFXLEdBQUcsQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRSxFQUFFLFNBQVMsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3pILE9BQU8sQ0FBQyxTQUFTLEdBQUcsV0FBVyxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQzFDLENBQUM7WUFDRDtnQkFDRSxPQUFPLFFBQVEsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ2xELENBQUM7SUFDSCxDQUFDO0lBRU8sZUFBZSxDQUFDLElBQWUsRUFBRSxJQUFZO1FBQ25ELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQ25DLFFBQVEsSUFBSSxFQUFFLENBQUM7WUFDYixLQUFLLE1BQU07Z0JBQ1QsT0FBTyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQ2hELEtBQUssS0FBSztnQkFDUixPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDL0MsS0FBSyxNQUFNO2dCQUNULE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsWUFBWSxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQ2hFLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQztnQkFDYixNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ25ELE1BQU0sV0FBVyxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQy9GLE9BQU8sQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQzVDLENBQUM7WUFDRDtnQkFDRSxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUM7UUFDakQsQ0FBQztJQUNILENBQUM7SUFFTyxPQUFPLENBQUMsQ0FBUyxFQUFFLFVBQWdCLEVBQUUsSUFBWTtRQUN2RCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQztRQUNuQyxNQUFNLEtBQUssR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLFFBQVEsSUFBSSxFQUFFLENBQUM7WUFDYixLQUFLLE1BQU07Z0JBQ1QsT0FBTyxRQUFRLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNqRCxLQUFLLEtBQUs7Z0JBQ1IsT0FBTyxPQUFPLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNoRCxLQUFLLE1BQU07Z0JBQ1QsT0FBTyxPQUFPLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUM7WUFDL0QsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDO2dCQUNiLE1BQU0sQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUMvQixDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQzdDLE9BQU8sQ0FBQyxDQUFDO1lBQ1gsQ0FBQztZQUNEO2dCQUNFLE9BQU8sT0FBTyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDbEQsQ0FBQztJQUNILENBQUM7SUFFRCw4RUFBOEU7SUFDOUUsY0FBYztJQUNkLDhFQUE4RTtJQUV0RSxRQUFRO1FBQ2QsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDNUMsQ0FBQztJQUNILENBQUM7SUFFTyxnQkFBZ0IsQ0FBdUMsR0FBTTtRQUNuRSxPQUFPLFFBQVEsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQy9DLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEdBTlRUX0JBUl9IRUlHSFQsXG4gIEdBTlRUX0RFRkFVTFRfQkFSX0NPTE9SLFxuICBHQU5UVF9IRUFERVJfSEVJR0hULFxuICBHQU5UVF9ST1dfSEVJR0hULFxufSBmcm9tICcuLi8uLi9jb3JlL2NvbnN0YW50cy9nYW50dC5jb25zdCc7XG5pbXBvcnQgdHlwZSB7IEdhbnR0VGFzaywgR2FudHRWaWV3TW9kZSB9IGZyb20gJy4uLy4uL2NvcmUvdHlwZXMvZ2FudHQudHlwZSc7XG5pbXBvcnQge1xuICBhZGREYXlzLFxuICBhZGRIb3VycyxcbiAgZGlmZkRheXMsXG4gIGRpZmZIb3VycyxcbiAgZm9ybWF0RGF5TW9udGgsXG4gIGZvcm1hdEhvdXJMYWJlbCxcbiAgZm9ybWF0TW9udGhMYWJlbCxcbiAgZm9ybWF0V2Vla0xhYmVsLFxuICBpc1dlZWtlbmQsXG4gIGlzU2FtZURheSxcbiAgc3RhcnRPZkRheSxcbiAgc3RhcnRPZkhvdXIsXG4gIHN0YXJ0T2ZNb250aCxcbiAgc3RhcnRPZldlZWssXG59IGZyb20gJy4vZ2FudHQtZGF0ZS51dGlscyc7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUHVibGljIHR5cGVzICYgQ29uc3RhbnRzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuY29uc3QgUlhfVkFMVUUgPSAzO1xuY29uc3QgREFURV9SQU5HRV9TQUZFVFlfTElNSVQgPSA1MDAwO1xuY29uc3QgREFZU19JTl9XRUVLID0gNztcbmNvbnN0IEhFQURFUl9MQUJFTF9WRVJUSUNBTF9PRkZTRVQgPSA1O1xuY29uc3QgSEFORExFX1dJRFRIID0gNjtcbmNvbnN0IFRBU0tfTEFCRUxfSE9SSVpPTlRBTF9QQURESU5HID0gNjtcbmNvbnN0IERSQUdfTUlOX0hBTkRMRV9GQUNUT1IgPSAyO1xuY29uc3QgUE9QVVBfQVVUT19SRU1PVkVfREVMQVlfTVMgPSAzMDAwO1xuY29uc3QgTU9OVEhTX0lOX1lFQVIgPSAxMjtcbmNvbnN0IEJBUl9TRUxFQ1RPUiA9ICcuc2RjLWdhbnR0LWJhcic7XG5cbmVudW0gRHJhZ01vZGUge1xuICBNb3ZlLFxuICBSZXNpemVMZWZ0LFxuICBSZXNpemVSaWdodCxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHYW50dEVuZ2luZU9wdGlvbnMge1xuICB2aWV3TW9kZTogR2FudHRWaWV3TW9kZTtcbiAgYWxsb3dNb3ZlbWVudDogYm9vbGVhbjtcbiAgaGFzUG9wdXA6IGJvb2xlYW47XG4gIG9uVGFza0NsaWNrPzogKHRhc2s6IEdhbnR0VGFzaykgPT4gdm9pZDtcbiAgb25EYXRlQ2hhbmdlPzogKHRhc2s6IEdhbnR0VGFzaywgc3RhcnQ6IERhdGUsIGVuZDogRGF0ZSkgPT4gdm9pZDtcbn1cblxuaW50ZXJmYWNlIERyYWdTdGF0ZSB7XG4gIHRhc2s6IEdhbnR0VGFzaztcbiAgYmFyR3JvdXA6IFNWR0dFbGVtZW50O1xuICBzdGFydFg6IG51bWJlcjtcbiAgb3JpZ2luYWxYOiBudW1iZXI7XG4gIG9yaWdpbmFsV2lkdGg6IG51bWJlcjtcbiAgY29sVzogbnVtYmVyO1xuICByYW5nZVN0YXJ0OiBEYXRlO1xuICByb3dJbmRleDogbnVtYmVyO1xuICBtb2RlOiBEcmFnTW9kZTtcbn1cblxuaW50ZXJmYWNlIERyYWdTdGF0ZVNlZWQge1xuICBjbGllbnRYOiBudW1iZXI7XG4gIHJhbmdlU3RhcnQ6IERhdGU7XG4gIGNvbFc6IG51bWJlcjtcbiAgcm93SW5kZXg6IG51bWJlcjtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBHYW50dEVuZ2luZSDigJMgcHVyZSBUeXBlU2NyaXB0IGNsYXNzLCBubyBBbmd1bGFyIGRlY29yYXRvcnNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5jb25zdCBTVkdfTlMgPSAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnO1xuXG5leHBvcnQgY2xhc3MgR2FudHRFbmdpbmUge1xuICBwcml2YXRlIHJlYWRvbmx5IHN2ZzogU1ZHRWxlbWVudDtcbiAgcHJpdmF0ZSB0YXNrczogR2FudHRUYXNrW107XG4gIHByaXZhdGUgb3B0aW9uczogR2FudHRFbmdpbmVPcHRpb25zO1xuXG4gIC8vIExheW91dCBjb25zdGFudHMg4oCTIGtlcHQgaW4gc3luYyB3aXRoIFNDU1MgdG9rZW5zXG4gIHByaXZhdGUgcmVhZG9ubHkgSEVBREVSX0hFSUdIVCA9IEdBTlRUX0hFQURFUl9IRUlHSFQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgUk9XX0hFSUdIVCA9IEdBTlRUX1JPV19IRUlHSFQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgQkFSX0hFSUdIVCA9IEdBTlRUX0JBUl9IRUlHSFQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgUEFERElORyA9IDEyO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgQ09MVU1OX1dJRFRIUzogUmVjb3JkPEdhbnR0Vmlld01vZGUsIG51bWJlcj4gPSB7XG4gICAgaG91cjogNTAsXG4gICAgZGF5OiA1MCxcbiAgICB3ZWVrOiAxNDAsXG4gICAgbW9udGg6IDEyMCxcbiAgfTtcblxuICAvLyBQb3B1cCBlbGVtZW50IG1hbmFnZWQgYnkgdGhlIGVuZ2luZVxuICBwcml2YXRlIHBvcHVwOiBIVE1MRGl2RWxlbWVudCB8IG51bGwgPSBudWxsO1xuXG4gIC8vIEFjdGl2ZSBkcmFnIHN0YXRlXG4gIHByaXZhdGUgZHJhZzogRHJhZ1N0YXRlIHwgbnVsbCA9IG51bGw7XG5cbiAgLy8gQm91bmQgZ2xvYmFsIGhhbmRsZXJzIChrZXB0IHNvIHdlIGNhbiByZW1vdmUgdGhlbSBvbiBkZXN0cm95KVxuICBwcml2YXRlIHJlYWRvbmx5IGJvdW5kTW91c2VNb3ZlOiAoZTogTW91c2VFdmVudCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSByZWFkb25seSBib3VuZE1vdXNlVXA6IChlOiBNb3VzZUV2ZW50KSA9PiB2b2lkO1xuXG4gIGNvbnN0cnVjdG9yKHN2ZzogU1ZHRWxlbWVudCwgdGFza3M6IEdhbnR0VGFza1tdLCBvcHRpb25zOiBHYW50dEVuZ2luZU9wdGlvbnMpIHtcbiAgICB0aGlzLnN2ZyA9IHN2ZztcbiAgICB0aGlzLnRhc2tzID0gdGFza3M7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcblxuICAgIHRoaXMuYm91bmRNb3VzZU1vdmUgPSB0aGlzLm9uTW91c2VNb3ZlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5ib3VuZE1vdXNlVXAgPSB0aGlzLm9uTW91c2VVcC5iaW5kKHRoaXMpO1xuXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5ib3VuZE1vdXNlTW92ZSk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuYm91bmRNb3VzZVVwKTtcblxuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gUHVibGljIEFQSVxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBwdWJsaWMgcmVmcmVzaCh0YXNrczogR2FudHRUYXNrW10pOiB2b2lkIHtcbiAgICB0aGlzLnRhc2tzID0gdGFza3M7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHB1YmxpYyB1cGRhdGVPcHRpb25zKG9wdGlvbnM6IFBhcnRpYWw8R2FudHRFbmdpbmVPcHRpb25zPik6IHZvaWQge1xuICAgIHRoaXMub3B0aW9ucyA9IHsgLi4udGhpcy5vcHRpb25zLCAuLi5vcHRpb25zIH07XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHB1YmxpYyBjaGFuZ2VWaWV3TW9kZShtb2RlOiBHYW50dFZpZXdNb2RlKTogdm9pZCB7XG4gICAgdGhpcy51cGRhdGVPcHRpb25zKHsgdmlld01vZGU6IG1vZGUgfSk7XG4gIH1cblxuICBwdWJsaWMgZGVzdHJveSgpOiB2b2lkIHtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLmJvdW5kTW91c2VNb3ZlKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5ib3VuZE1vdXNlVXApO1xuICAgIHRoaXMucmVtb3ZlUG9wdXAoKTtcbiAgICB0aGlzLmNsZWFyU3ZnKCk7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gUmVuZGVyIHBpcGVsaW5lXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHByaXZhdGUgcmVuZGVyKCk6IHZvaWQge1xuICAgIHRoaXMuY2xlYXJTdmcoKTtcbiAgICB0aGlzLnJlbW92ZVBvcHVwKCk7XG4gICAgdGhpcy5kcmFnID0gbnVsbDtcblxuICAgIGlmICh0aGlzLnRhc2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgZGF0ZXMgfSA9IHRoaXMuY29tcHV0ZURhdGVSYW5nZSgpO1xuICAgIGNvbnN0IGNvbFcgPSB0aGlzLkNPTFVNTl9XSURUSFNbdGhpcy5vcHRpb25zLnZpZXdNb2RlXTtcbiAgICBjb25zdCB0b3RhbFdpZHRoID0gZGF0ZXMubGVuZ3RoICogY29sVztcbiAgICBjb25zdCB0b3RhbEhlaWdodCA9IHRoaXMuSEVBREVSX0hFSUdIVCArIHRoaXMudGFza3MubGVuZ3RoICogdGhpcy5ST1dfSEVJR0hUO1xuXG4gICAgdGhpcy5zdmcuc2V0QXR0cmlidXRlKCd3aWR0aCcsIFN0cmluZyh0b3RhbFdpZHRoKSk7XG4gICAgdGhpcy5zdmcuc2V0QXR0cmlidXRlKCdoZWlnaHQnLCBTdHJpbmcodG90YWxIZWlnaHQpKTtcbiAgICB0aGlzLnN2Zy5zZXRBdHRyaWJ1dGUoJ3ZpZXdCb3gnLCBgMCAwICR7dG90YWxXaWR0aH0gJHt0b3RhbEhlaWdodH1gKTtcblxuICAgIHRoaXMuZHJhd0dyaWQoZGF0ZXMsIGNvbFcsIHRvdGFsV2lkdGgsIHRvdGFsSGVpZ2h0KTtcbiAgICB0aGlzLmRyYXdCYXJzKGRhdGVzWzBdLCBjb2xXKTtcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBEYXRlIHJhbmdlIGNvbXB1dGF0aW9uXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHByaXZhdGUgY29tcHV0ZURhdGVSYW5nZSgpOiB7IHN0YXJ0OiBEYXRlOyBlbmQ6IERhdGU7IGRhdGVzOiBEYXRlW10gfSB7XG4gICAgY29uc3QgbW9kZSA9IHRoaXMub3B0aW9ucy52aWV3TW9kZTtcblxuICAgIGxldCBtaW5EYXRlID0gdGhpcy50YXNrc1swXS5zdGFydDtcbiAgICBsZXQgbWF4RGF0ZSA9IHRoaXMudGFza3NbMF0uZW5kO1xuXG4gICAgZm9yIChjb25zdCB0YXNrIG9mIHRoaXMudGFza3MpIHtcbiAgICAgIGlmICh0YXNrLnN0YXJ0IDwgbWluRGF0ZSkge1xuICAgICAgICBtaW5EYXRlID0gdGFzay5zdGFydDtcbiAgICAgIH1cblxuICAgICAgaWYgKHRhc2suZW5kID4gbWF4RGF0ZSkge1xuICAgICAgICBtYXhEYXRlID0gdGFzay5lbmQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWRkIG1hcmdpblxuICAgIGNvbnN0IG1hcmdpbmVkTWF4ID0gYWRkRGF5cyhtYXhEYXRlLCAxKTtcblxuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5zbG90U3RhcnQobWluRGF0ZSwgbW9kZSk7XG4gICAgY29uc3QgZW5kID0gdGhpcy5zbG90U3RhcnQoYWRkRGF5cyhtYXJnaW5lZE1heCwgMSksIG1vZGUpO1xuICAgIGNvbnN0IGRhdGVzOiBEYXRlW10gPSBbXTtcblxuICAgIGxldCBjdXJzb3IgPSBuZXcgRGF0ZShzdGFydCk7XG4gICAgLy8gU2FmZXR5IGxpbWl0IHRvIGF2b2lkIGluZmluaXRlIGxvb3BzXG4gICAgbGV0IHNhZmV0eSA9IDA7XG4gICAgd2hpbGUgKGN1cnNvciA8IGVuZCAmJiBzYWZldHkgPCBEQVRFX1JBTkdFX1NBRkVUWV9MSU1JVCkge1xuICAgICAgZGF0ZXMucHVzaChuZXcgRGF0ZShjdXJzb3IpKTtcbiAgICAgIGN1cnNvciA9IHRoaXMubmV4dFNsb3QoY3Vyc29yLCBtb2RlKTtcbiAgICAgIHNhZmV0eSsrO1xuICAgIH1cblxuICAgIHJldHVybiB7IHN0YXJ0LCBlbmQsIGRhdGVzIH07XG4gIH1cblxuICBwcml2YXRlIHNsb3RTdGFydChkYXRlOiBEYXRlLCBtb2RlOiBHYW50dFZpZXdNb2RlKTogRGF0ZSB7XG4gICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgcmV0dXJuIHN0YXJ0T2ZIb3VyKGRhdGUpO1xuICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgcmV0dXJuIHN0YXJ0T2ZEYXkoZGF0ZSk7XG4gICAgICBjYXNlICd3ZWVrJzpcbiAgICAgICAgcmV0dXJuIHN0YXJ0T2ZXZWVrKGRhdGUpO1xuICAgICAgY2FzZSAnbW9udGgnOlxuICAgICAgICByZXR1cm4gc3RhcnRPZk1vbnRoKGRhdGUpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHN0YXJ0T2ZEYXkoZGF0ZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBuZXh0U2xvdChkYXRlOiBEYXRlLCBtb2RlOiBHYW50dFZpZXdNb2RlKTogRGF0ZSB7XG4gICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgcmV0dXJuIGFkZEhvdXJzKGRhdGUsIDEpO1xuICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgcmV0dXJuIGFkZERheXMoZGF0ZSwgMSk7XG4gICAgICBjYXNlICd3ZWVrJzpcbiAgICAgICAgcmV0dXJuIGFkZERheXMoZGF0ZSwgREFZU19JTl9XRUVLKTtcbiAgICAgIGNhc2UgJ21vbnRoJzoge1xuICAgICAgICBjb25zdCBkID0gbmV3IERhdGUoZGF0ZSk7XG4gICAgICAgIGQuc2V0TW9udGgoZC5nZXRNb250aCgpICsgMSk7XG4gICAgICAgIHJldHVybiBkO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGFkZERheXMoZGF0ZSwgMSk7XG4gICAgfVxuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIEdyaWQgZHJhd2luZ1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBwcml2YXRlIGRyYXdHcmlkKGRhdGVzOiBEYXRlW10sIGNvbFc6IG51bWJlciwgdG90YWxXaWR0aDogbnVtYmVyLCB0b3RhbEhlaWdodDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgbW9kZSA9IHRoaXMub3B0aW9ucy52aWV3TW9kZTtcblxuICAgIC8vIFJvdyBiYWNrZ3JvdW5kc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy50YXNrcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgeSA9IHRoaXMuSEVBREVSX0hFSUdIVCArIGkgKiB0aGlzLlJPV19IRUlHSFQ7XG4gICAgICBjb25zdCBiZyA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgncmVjdCcpO1xuICAgICAgYmcuc2V0QXR0cmlidXRlKCd4JywgJzAnKTtcbiAgICAgIGJnLnNldEF0dHJpYnV0ZSgneScsIFN0cmluZyh5KSk7XG4gICAgICBiZy5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgU3RyaW5nKHRvdGFsV2lkdGgpKTtcbiAgICAgIGJnLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgU3RyaW5nKHRoaXMuUk9XX0hFSUdIVCkpO1xuICAgICAgYmcuc2V0QXR0cmlidXRlKCdjbGFzcycsIGBzZGMtZ2FudHQtcm93LWJnICR7aSAlIDIgPT09IDAgPyAnc2RjLWdhbnR0LXJvdy1iZy0tZXZlbicgOiAnc2RjLWdhbnR0LXJvdy1iZy0tb2RkJ31gKTtcbiAgICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKGJnKTtcbiAgICB9XG5cbiAgICAvLyBDb2x1bW4gc2xvdHMg4oCTIGJhY2tncm91bmRzICsgc2VwYXJhdG9ycyArIGxhYmVsc1xuICAgIGNvbnN0IHRvZGF5ID0gc3RhcnRPZkRheShuZXcgRGF0ZSgpKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHggPSBpICogY29sVztcbiAgICAgIGNvbnN0IGRhdGUgPSBkYXRlc1tpXTtcblxuICAgICAgLy8gV2Vla2VuZCBoaWdobGlnaHQgKGRheS9ob3VyIG1vZGVzKVxuICAgICAgaWYgKChtb2RlID09PSAnZGF5JyB8fCBtb2RlID09PSAnaG91cicpICYmIGlzV2Vla2VuZChkYXRlKSkge1xuICAgICAgICBjb25zdCB3a1JlY3QgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ3JlY3QnKTtcbiAgICAgICAgd2tSZWN0LnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyh4KSk7XG4gICAgICAgIHdrUmVjdC5zZXRBdHRyaWJ1dGUoJ3knLCBTdHJpbmcodGhpcy5IRUFERVJfSEVJR0hUKSk7XG4gICAgICAgIHdrUmVjdC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgU3RyaW5nKGNvbFcpKTtcbiAgICAgICAgd2tSZWN0LnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgU3RyaW5nKHRoaXMudGFza3MubGVuZ3RoICogdGhpcy5ST1dfSEVJR0hUKSk7XG4gICAgICAgIHdrUmVjdC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ3NkYy1nYW50dC13ZWVrZW5kJyk7XG4gICAgICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKHdrUmVjdCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFRvZGF5IGhpZ2hsaWdodFxuICAgICAgaWYgKG1vZGUgPT09ICdkYXknICYmIGlzU2FtZURheShkYXRlLCB0b2RheSkpIHtcbiAgICAgICAgY29uc3QgdG9kYXlSZWN0ID0gdGhpcy5jcmVhdGVTdmdFbGVtZW50KCdyZWN0Jyk7XG4gICAgICAgIHRvZGF5UmVjdC5zZXRBdHRyaWJ1dGUoJ3gnLCBTdHJpbmcoeCkpO1xuICAgICAgICB0b2RheVJlY3Quc2V0QXR0cmlidXRlKCd5JywgJzAnKTtcbiAgICAgICAgdG9kYXlSZWN0LnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBTdHJpbmcoY29sVykpO1xuICAgICAgICB0b2RheVJlY3Quc2V0QXR0cmlidXRlKCdoZWlnaHQnLCBTdHJpbmcodG90YWxIZWlnaHQpKTtcbiAgICAgICAgdG9kYXlSZWN0LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnc2RjLWdhbnR0LXRvZGF5Jyk7XG4gICAgICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKHRvZGF5UmVjdCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFZlcnRpY2FsIGdyaWQgbGluZVxuICAgICAgY29uc3QgbGluZSA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgnbGluZScpO1xuICAgICAgbGluZS5zZXRBdHRyaWJ1dGUoJ3gxJywgU3RyaW5nKHgpKTtcbiAgICAgIGxpbmUuc2V0QXR0cmlidXRlKCd5MScsIFN0cmluZyh0aGlzLkhFQURFUl9IRUlHSFQpKTtcbiAgICAgIGxpbmUuc2V0QXR0cmlidXRlKCd4MicsIFN0cmluZyh4KSk7XG4gICAgICBsaW5lLnNldEF0dHJpYnV0ZSgneTInLCBTdHJpbmcodG90YWxIZWlnaHQpKTtcbiAgICAgIGxpbmUuc2V0QXR0cmlidXRlKCdjbGFzcycsICdzZGMtZ2FudHQtZ3JpZC1saW5lJyk7XG4gICAgICB0aGlzLnN2Zy5hcHBlbmRDaGlsZChsaW5lKTtcblxuICAgICAgLy8gSGVhZGVyIGJhY2tncm91bmRcbiAgICAgIGNvbnN0IGhkclJlY3QgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ3JlY3QnKTtcbiAgICAgIGhkclJlY3Quc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKHgpKTtcbiAgICAgIGhkclJlY3Quc2V0QXR0cmlidXRlKCd5JywgJzAnKTtcbiAgICAgIGhkclJlY3Quc2V0QXR0cmlidXRlKCd3aWR0aCcsIFN0cmluZyhjb2xXKSk7XG4gICAgICBoZHJSZWN0LnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgU3RyaW5nKHRoaXMuSEVBREVSX0hFSUdIVCkpO1xuICAgICAgaGRyUmVjdC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ3NkYy1nYW50dC1oZWFkZXItY2VsbCcpO1xuICAgICAgdGhpcy5zdmcuYXBwZW5kQ2hpbGQoaGRyUmVjdCk7XG5cbiAgICAgIC8vIEhlYWRlciBsYWJlbFxuICAgICAgY29uc3QgbGFiZWwgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ3RleHQnKTtcbiAgICAgIGxhYmVsLnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyh4ICsgY29sVyAvIDIpKTtcbiAgICAgIGxhYmVsLnNldEF0dHJpYnV0ZSgneScsIFN0cmluZyh0aGlzLkhFQURFUl9IRUlHSFQgLyAyICsgSEVBREVSX0xBQkVMX1ZFUlRJQ0FMX09GRlNFVCkpO1xuICAgICAgbGFiZWwuc2V0QXR0cmlidXRlKCd0ZXh0LWFuY2hvcicsICdtaWRkbGUnKTtcbiAgICAgIGxhYmVsLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnc2RjLWdhbnR0LWhlYWRlci1sYWJlbCcpO1xuICAgICAgbGFiZWwudGV4dENvbnRlbnQgPSB0aGlzLmZvcm1hdENvbHVtbkxhYmVsKGRhdGUsIG1vZGUpO1xuICAgICAgdGhpcy5zdmcuYXBwZW5kQ2hpbGQobGFiZWwpO1xuICAgIH1cblxuICAgIC8vIEJvdHRvbSBoZWFkZXIgYm9yZGVyIGxpbmVcbiAgICBjb25zdCBoZHJCb3JkZXIgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ2xpbmUnKTtcbiAgICBoZHJCb3JkZXIuc2V0QXR0cmlidXRlKCd4MScsICcwJyk7XG4gICAgaGRyQm9yZGVyLnNldEF0dHJpYnV0ZSgneTEnLCBTdHJpbmcodGhpcy5IRUFERVJfSEVJR0hUKSk7XG4gICAgaGRyQm9yZGVyLnNldEF0dHJpYnV0ZSgneDInLCBTdHJpbmcodG90YWxXaWR0aCkpO1xuICAgIGhkckJvcmRlci5zZXRBdHRyaWJ1dGUoJ3kyJywgU3RyaW5nKHRoaXMuSEVBREVSX0hFSUdIVCkpO1xuICAgIGhkckJvcmRlci5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ3NkYy1nYW50dC1oZWFkZXItYm9yZGVyJyk7XG4gICAgdGhpcy5zdmcuYXBwZW5kQ2hpbGQoaGRyQm9yZGVyKTtcblxuICAgIC8vIEhvcml6b250YWwgcm93IHNlcGFyYXRvcnNcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8PSB0aGlzLnRhc2tzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB5ID0gdGhpcy5IRUFERVJfSEVJR0hUICsgaSAqIHRoaXMuUk9XX0hFSUdIVDtcbiAgICAgIGNvbnN0IGhMaW5lID0gdGhpcy5jcmVhdGVTdmdFbGVtZW50KCdsaW5lJyk7XG4gICAgICBoTGluZS5zZXRBdHRyaWJ1dGUoJ3gxJywgJzAnKTtcbiAgICAgIGhMaW5lLnNldEF0dHJpYnV0ZSgneTEnLCBTdHJpbmcoeSkpO1xuICAgICAgaExpbmUuc2V0QXR0cmlidXRlKCd4MicsIFN0cmluZyh0b3RhbFdpZHRoKSk7XG4gICAgICBoTGluZS5zZXRBdHRyaWJ1dGUoJ3kyJywgU3RyaW5nKHkpKTtcbiAgICAgIGhMaW5lLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnc2RjLWdhbnR0LWdyaWQtbGluZSBzZGMtZ2FudHQtZ3JpZC1saW5lLS1ob3Jpem9udGFsJyk7XG4gICAgICB0aGlzLnN2Zy5hcHBlbmRDaGlsZChoTGluZSk7XG4gICAgfVxuXG4gICAgLy8gUmlnaHQgYm9yZGVyIGxpbmVcbiAgICBjb25zdCByaWdodExpbmUgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ2xpbmUnKTtcbiAgICByaWdodExpbmUuc2V0QXR0cmlidXRlKCd4MScsIFN0cmluZyh0b3RhbFdpZHRoKSk7XG4gICAgcmlnaHRMaW5lLnNldEF0dHJpYnV0ZSgneTEnLCAnMCcpO1xuICAgIHJpZ2h0TGluZS5zZXRBdHRyaWJ1dGUoJ3gyJywgU3RyaW5nKHRvdGFsV2lkdGgpKTtcbiAgICByaWdodExpbmUuc2V0QXR0cmlidXRlKCd5MicsIFN0cmluZyh0b3RhbEhlaWdodCkpO1xuICAgIHJpZ2h0TGluZS5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ3NkYy1nYW50dC1ncmlkLWxpbmUnKTtcbiAgICB0aGlzLnN2Zy5hcHBlbmRDaGlsZChyaWdodExpbmUpO1xuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRDb2x1bW5MYWJlbChkYXRlOiBEYXRlLCBtb2RlOiBHYW50dFZpZXdNb2RlKTogc3RyaW5nIHtcbiAgICBzd2l0Y2ggKG1vZGUpIHtcbiAgICAgIGNhc2UgJ2hvdXInOlxuICAgICAgICByZXR1cm4gZm9ybWF0SG91ckxhYmVsKGRhdGUpO1xuICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgcmV0dXJuIGZvcm1hdERheU1vbnRoKGRhdGUpO1xuICAgICAgY2FzZSAnd2Vlayc6XG4gICAgICAgIHJldHVybiBmb3JtYXRXZWVrTGFiZWwoZGF0ZSk7XG4gICAgICBjYXNlICdtb250aCc6XG4gICAgICAgIHJldHVybiBmb3JtYXRNb250aExhYmVsKGRhdGUpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGZvcm1hdERheU1vbnRoKGRhdGUpO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBCYXIgZHJhd2luZ1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBwcml2YXRlIGRyYXdCYXJzKHJhbmdlU3RhcnQ6IERhdGUsIGNvbFc6IG51bWJlcik6IHZvaWQge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy50YXNrcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5kcmF3QmFyRWxlbWVudCh0aGlzLnRhc2tzW2ldLCBpLCByYW5nZVN0YXJ0LCBjb2xXKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRyYXdCYXJFbGVtZW50KHRhc2s6IEdhbnR0VGFzaywgcm93SW5kZXg6IG51bWJlciwgcmFuZ2VTdGFydDogRGF0ZSwgY29sVzogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgYmFyWCA9IHRoaXMuY29tcHV0ZUJhclgodGFzay5zdGFydCwgcmFuZ2VTdGFydCwgY29sVyk7XG4gICAgY29uc3QgYmFyVyA9IE1hdGgubWF4KHRoaXMuY29tcHV0ZUJhcldpZHRoKHRhc2ssIGNvbFcpLCA0KTtcbiAgICBjb25zdCBiYXJZID0gdGhpcy5IRUFERVJfSEVJR0hUICsgcm93SW5kZXggKiB0aGlzLlJPV19IRUlHSFQgKyAodGhpcy5ST1dfSEVJR0hUIC0gdGhpcy5CQVJfSEVJR0hUKSAvIDI7XG4gICAgY29uc3QgY29sb3IgPSB0YXNrLmNvbG9yID8/IEdBTlRUX0RFRkFVTFRfQkFSX0NPTE9SO1xuXG4gICAgY29uc3QgZ3JvdXAgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ2cnKTtcbiAgICBncm91cC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgYHNkYy1nYW50dC1iYXItZ3JvdXAke3Rhc2suY3VzdG9tQ2xhc3MgPyAnICcgKyB0YXNrLmN1c3RvbUNsYXNzIDogJyd9YCk7XG4gICAgZ3JvdXAuc2V0QXR0cmlidXRlKCdkYXRhLXRhc2staWQnLCB0YXNrLmlkKTtcbiAgICBncm91cC5zdHlsZS5jdXJzb3IgPSB0aGlzLm9wdGlvbnMuYWxsb3dNb3ZlbWVudCA/ICdncmFiJyA6ICdwb2ludGVyJztcblxuICAgIC8vIE1haW4gYmFyIHJlY3RhbmdsZVxuICAgIGNvbnN0IHJlY3QgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ3JlY3QnKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyhiYXJYKSk7XG4gICAgcmVjdC5zZXRBdHRyaWJ1dGUoJ3knLCBTdHJpbmcoYmFyWSkpO1xuICAgIHJlY3Quc2V0QXR0cmlidXRlKCd3aWR0aCcsIFN0cmluZyhiYXJXKSk7XG4gICAgcmVjdC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIFN0cmluZyh0aGlzLkJBUl9IRUlHSFQpKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZSgncngnLCBTdHJpbmcoUlhfVkFMVUUpKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZSgncnknLCBTdHJpbmcoUlhfVkFMVUUpKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZSgnZmlsbCcsIGNvbG9yKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnc2RjLWdhbnR0LWJhcicpO1xuICAgIGdyb3VwLmFwcGVuZENoaWxkKHJlY3QpO1xuXG4gICAgLy8gVGFzayBuYW1lIGluc2lkZSBiYXJcbiAgICBpZiAodGFzay5zaG93VGFza05hbWUpIHtcbiAgICAgIGNvbnN0IHRleHRFbCA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgndGV4dCcpO1xuICAgICAgdGV4dEVsLnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyhiYXJYICsgVEFTS19MQUJFTF9IT1JJWk9OVEFMX1BBRERJTkcpKTtcbiAgICAgIHRleHRFbC5zZXRBdHRyaWJ1dGUoJ3knLCBTdHJpbmcoYmFyWSArIHRoaXMuQkFSX0hFSUdIVCAvIDIgKyA0KSk7XG4gICAgICB0ZXh0RWwuc2V0QXR0cmlidXRlKCdjbGFzcycsICdzZGMtZ2FudHQtYmFyLWxhYmVsJyk7XG4gICAgICB0ZXh0RWwuc2V0QXR0cmlidXRlKCdjbGlwLXBhdGgnLCBgdXJsKCNjbGlwLSR7dGFzay5pZH0pYCk7XG4gICAgICB0ZXh0RWwudGV4dENvbnRlbnQgPSB0YXNrLm5hbWU7XG4gICAgICBncm91cC5hcHBlbmRDaGlsZCh0ZXh0RWwpO1xuXG4gICAgICAvLyBDbGlwIHBhdGggc28gdGV4dCBzdGF5cyBpbnNpZGUgdGhlIGJhclxuICAgICAgY29uc3QgZGVmcyA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgnZGVmcycpO1xuICAgICAgY29uc3QgY2xpcCA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgnY2xpcFBhdGgnKTtcbiAgICAgIGNsaXAuc2V0QXR0cmlidXRlKCdpZCcsIGBjbGlwLSR7dGFzay5pZH1gKTtcbiAgICAgIGNvbnN0IGNsaXBSZWN0ID0gdGhpcy5jcmVhdGVTdmdFbGVtZW50KCdyZWN0Jyk7XG4gICAgICBjbGlwUmVjdC5zZXRBdHRyaWJ1dGUoJ3gnLCBTdHJpbmcoYmFyWCArIDIpKTtcbiAgICAgIGNsaXBSZWN0LnNldEF0dHJpYnV0ZSgneScsIFN0cmluZyhiYXJZKSk7XG4gICAgICBjbGlwUmVjdC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgU3RyaW5nKE1hdGgubWF4KGJhclcgLSA0LCAwKSkpO1xuICAgICAgY2xpcFJlY3Quc2V0QXR0cmlidXRlKCdoZWlnaHQnLCBTdHJpbmcodGhpcy5CQVJfSEVJR0hUKSk7XG4gICAgICBjbGlwLmFwcGVuZENoaWxkKGNsaXBSZWN0KTtcbiAgICAgIGRlZnMuYXBwZW5kQ2hpbGQoY2xpcCk7XG4gICAgICB0aGlzLnN2Zy5pbnNlcnRCZWZvcmUoZGVmcywgdGhpcy5zdmcuZmlyc3RDaGlsZCk7XG4gICAgfVxuXG4gICAgLy8gUmVzaXplIGhhbmRsZXMgKG9ubHkgd2hlbiBtb3ZlbWVudCBpcyBhbGxvd2VkKVxuICAgIGlmICh0aGlzLm9wdGlvbnMuYWxsb3dNb3ZlbWVudCkge1xuICAgICAgY29uc3QgbGVmdEhhbmRsZSA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgncmVjdCcpO1xuICAgICAgbGVmdEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ3gnLCBTdHJpbmcoYmFyWCkpO1xuICAgICAgbGVmdEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ3knLCBTdHJpbmcoYmFyWSkpO1xuICAgICAgbGVmdEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgU3RyaW5nKEhBTkRMRV9XSURUSCkpO1xuICAgICAgbGVmdEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIFN0cmluZyh0aGlzLkJBUl9IRUlHSFQpKTtcbiAgICAgIGxlZnRIYW5kbGUuc2V0QXR0cmlidXRlKCdyeCcsIFN0cmluZyhSWF9WQUxVRSkpO1xuICAgICAgbGVmdEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAncmdiYSgwLDAsMCwwLjIpJyk7XG4gICAgICBsZWZ0SGFuZGxlLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnc2RjLWdhbnR0LWJhci1oYW5kbGUgc2RjLWdhbnR0LWJhci1oYW5kbGUtLWxlZnQnKTtcbiAgICAgIGxlZnRIYW5kbGUuc3R5bGUuY3Vyc29yID0gJ2V3LXJlc2l6ZSc7XG4gICAgICBsZWZ0SGFuZGxlLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHRoaXMuc3RhcnREcmFnKGUsIHRhc2ssIGdyb3VwLCBEcmFnTW9kZS5SZXNpemVMZWZ0LCB7XG4gICAgICAgICAgcmFuZ2VTdGFydCxcbiAgICAgICAgICBjb2xXLFxuICAgICAgICAgIHJvd0luZGV4LFxuICAgICAgICAgIGNsaWVudFg6IGUuY2xpZW50WCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGdyb3VwLmFwcGVuZENoaWxkKGxlZnRIYW5kbGUpO1xuXG4gICAgICBjb25zdCByaWdodEhhbmRsZSA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgncmVjdCcpO1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKGJhclggKyBiYXJXIC0gSEFORExFX1dJRFRIKSk7XG4gICAgICByaWdodEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ3knLCBTdHJpbmcoYmFyWSkpO1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCd3aWR0aCcsIFN0cmluZyhIQU5ETEVfV0lEVEgpKTtcbiAgICAgIHJpZ2h0SGFuZGxlLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgU3RyaW5nKHRoaXMuQkFSX0hFSUdIVCkpO1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCdyeCcsIFN0cmluZyhSWF9WQUxVRSkpO1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCdmaWxsJywgJ3JnYmEoMCwwLDAsMC4yKScpO1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCdjbGFzcycsICdzZGMtZ2FudHQtYmFyLWhhbmRsZSBzZGMtZ2FudHQtYmFyLWhhbmRsZS0tcmlnaHQnKTtcbiAgICAgIHJpZ2h0SGFuZGxlLnN0eWxlLmN1cnNvciA9ICdldy1yZXNpemUnO1xuICAgICAgcmlnaHRIYW5kbGUuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgKGU6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgdGhpcy5zdGFydERyYWcoZSwgdGFzaywgZ3JvdXAsIERyYWdNb2RlLlJlc2l6ZVJpZ2h0LCB7XG4gICAgICAgICAgcmFuZ2VTdGFydCxcbiAgICAgICAgICBjb2xXLFxuICAgICAgICAgIHJvd0luZGV4LFxuICAgICAgICAgIGNsaWVudFg6IGUuY2xpZW50WCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGdyb3VwLmFwcGVuZENoaWxkKHJpZ2h0SGFuZGxlKTtcbiAgICB9XG5cbiAgICAvLyBDbGljayAvIGRyYWcgb24gbWFpbiBiYXJcbiAgICByZWN0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmFsbG93TW92ZW1lbnQpIHtcbiAgICAgICAgdGhpcy5zdGFydERyYWcoZSwgdGFzaywgZ3JvdXAsIERyYWdNb2RlLk1vdmUsIHtcbiAgICAgICAgICByYW5nZVN0YXJ0LFxuICAgICAgICAgIGNvbFcsXG4gICAgICAgICAgcm93SW5kZXgsXG4gICAgICAgICAgY2xpZW50WDogZS5jbGllbnRYLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJlY3QuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZTogTW91c2VFdmVudCkgPT4ge1xuICAgICAgLy8gT25seSBmaXJlIGNsaWNrIGlmIG5vdCBkcmFnZ2luZ1xuICAgICAgaWYgKHRoaXMuZHJhZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmhhc1BvcHVwKSB7XG4gICAgICAgIHRoaXMuc2hvd1BvcHVwKHRhc2ssIGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgICAgIH1cbiAgICAgIHRoaXMub3B0aW9ucy5vblRhc2tDbGljaz8uKHRhc2spO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zdmcuYXBwZW5kQ2hpbGQoZ3JvdXApO1xuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIERyYWctYW5kLWRyb3BcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgcHJpdmF0ZSBzdGFydERyYWcoXG4gICAgZTogTW91c2VFdmVudCxcbiAgICB0YXNrOiBHYW50dFRhc2ssXG4gICAgYmFyR3JvdXA6IFNWR0dFbGVtZW50LFxuICAgIG1vZGU6IERyYWdNb2RlLFxuICAgIHNlZWQ6IERyYWdTdGF0ZVNlZWQsXG4gICk6IHZvaWQge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBiYXIgPSBiYXJHcm91cC5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PihCQVJfU0VMRUNUT1IpO1xuICAgIGlmICghYmFyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5kcmFnID0gdGhpcy5jcmVhdGVEcmFnU3RhdGUodGFzaywgYmFyR3JvdXAsIGJhciwgbW9kZSwgc2VlZCk7XG4gICAgdGhpcy51cGRhdGVCYXJWaXN1YWxGb3JEcmFnKGJhciwgYmFyR3JvdXApO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVEcmFnU3RhdGUoXG4gICAgdGFzazogR2FudHRUYXNrLFxuICAgIGJhckdyb3VwOiBTVkdHRWxlbWVudCxcbiAgICBiYXI6IFNWR1JlY3RFbGVtZW50LFxuICAgIG1vZGU6IERyYWdNb2RlLFxuICAgIHNlZWQ6IERyYWdTdGF0ZVNlZWRcbiAgKTogRHJhZ1N0YXRlIHtcbiAgICBjb25zdCBzdGFydFggPSBzZWVkLmNsaWVudFg7XG4gICAgY29uc3QgY29sdW1uV2lkdGggPSBzZWVkLmNvbFc7XG4gICAgY29uc3QgZHJhZ1JhbmdlU3RhcnQgPSBzZWVkLnJhbmdlU3RhcnQ7XG4gICAgY29uc3QgZHJhZ1Jvd0luZGV4ID0gc2VlZC5yb3dJbmRleDtcblxuICAgIHJldHVybiB7XG4gICAgICBzdGFydFgsXG4gICAgICB0YXNrLFxuICAgICAgYmFyR3JvdXAsXG4gICAgICBtb2RlLFxuICAgICAgb3JpZ2luYWxYOiBwYXJzZUZsb2F0KGJhci5nZXRBdHRyaWJ1dGUoJ3gnKSA/PyAnMCcpLFxuICAgICAgb3JpZ2luYWxXaWR0aDogcGFyc2VGbG9hdChiYXIuZ2V0QXR0cmlidXRlKCd3aWR0aCcpID8/ICcwJyksXG4gICAgICBjb2xXOiBjb2x1bW5XaWR0aCxcbiAgICAgIHJhbmdlU3RhcnQ6IGRyYWdSYW5nZVN0YXJ0LFxuICAgICAgcm93SW5kZXg6IGRyYWdSb3dJbmRleCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVCYXJWaXN1YWxGb3JEcmFnKGJhcjogU1ZHUmVjdEVsZW1lbnQsIGJhckdyb3VwOiBTVkdHRWxlbWVudCk6IHZvaWQge1xuICAgIGJhckdyb3VwLnN0eWxlLmN1cnNvciA9ICdncmFiYmluZyc7XG4gICAgYmFyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgJ3ZhcigtLXNkYy1nYW50dC1iYXItc2VsZWN0ZWQtc3Ryb2tlLCAjMjEyNTMzKScpO1xuICAgIGJhci5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsICcyJyk7XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VNb3ZlKGU6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBkcmFnID0gdGhpcy5kcmFnO1xuICAgIGlmICghZHJhZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGR4ID0gZS5jbGllbnRYIC0gZHJhZy5zdGFydFg7XG4gICAgY29uc3QgYmFyID0gZHJhZy5iYXJHcm91cC5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PihCQVJfU0VMRUNUT1IpO1xuICAgIGlmICghYmFyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgeyBtb2RlLCBvcmlnaW5hbFgsIG9yaWdpbmFsV2lkdGggfSA9IGRyYWc7XG5cbiAgICBpZiAobW9kZSA9PT0gRHJhZ01vZGUuTW92ZSkge1xuICAgICAgdGhpcy5oYW5kbGVEcmFnTW92ZShkcmFnLCBvcmlnaW5hbFgsIG9yaWdpbmFsV2lkdGgsIGJhciwgZHgpO1xuICAgIH0gZWxzZSBpZiAobW9kZSA9PT0gRHJhZ01vZGUuUmVzaXplUmlnaHQpIHtcbiAgICAgIHRoaXMuaGFuZGxlRHJhZ1Jlc2l6ZVJpZ2h0KGRyYWcsIG9yaWdpbmFsWCwgb3JpZ2luYWxXaWR0aCwgYmFyLCBkeCk7XG4gICAgfSBlbHNlIGlmIChtb2RlID09PSBEcmFnTW9kZS5SZXNpemVMZWZ0KSB7XG4gICAgICB0aGlzLmhhbmRsZURyYWdSZXNpemVMZWZ0KGRyYWcsIG9yaWdpbmFsWCwgb3JpZ2luYWxXaWR0aCwgYmFyLCBkeCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERyYWcgbW9kZSBpcyBleGhhdXN0aXZlIGJ5IHR5cGUsIHRoaXMgZ3VhcmRzIGZ1dHVyZSBjaGFuZ2VzLlxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlRHJhZ01vdmUoZHJhZzogRHJhZ1N0YXRlLCBvcmlnaW5hbFg6IG51bWJlciwgb3JpZ2luYWxXaWR0aDogbnVtYmVyLCBiYXI6IFNWR1JlY3RFbGVtZW50LCBkeDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgbmV3WCA9IE1hdGgubWF4KDAsIG9yaWdpbmFsWCArIGR4KTtcbiAgICBiYXIuc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKG5ld1gpKTtcblxuICAgIGNvbnN0IGxlZnRIYW5kbGUgPSBkcmFnLmJhckdyb3VwLnF1ZXJ5U2VsZWN0b3I8U1ZHUmVjdEVsZW1lbnQ+KCcuc2RjLWdhbnR0LWJhci1oYW5kbGUtLWxlZnQnKTtcbiAgICBjb25zdCByaWdodEhhbmRsZSA9IGRyYWcuYmFyR3JvdXAucXVlcnlTZWxlY3RvcjxTVkdSZWN0RWxlbWVudD4oJy5zZGMtZ2FudHQtYmFyLWhhbmRsZS0tcmlnaHQnKTtcbiAgICBpZiAobGVmdEhhbmRsZSkge1xuICAgICAgbGVmdEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ3gnLCBTdHJpbmcobmV3WCkpO1xuICAgIH1cblxuICAgIGlmIChyaWdodEhhbmRsZSkge1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKG5ld1ggKyBvcmlnaW5hbFdpZHRoIC0gSEFORExFX1dJRFRIKSk7XG4gICAgfVxuXG4gICAgY29uc3QgY2xpcFJlY3QgPSB0aGlzLnN2Zy5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PihgI2NsaXAtJHtkcmFnLnRhc2suaWR9IHJlY3RgKTtcbiAgICBpZiAoY2xpcFJlY3QpIHtcbiAgICAgIGNsaXBSZWN0LnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyhuZXdYICsgMikpO1xuICAgIH1cblxuICAgIGNvbnN0IGxhYmVsID0gZHJhZy5iYXJHcm91cC5xdWVyeVNlbGVjdG9yPFNWR1RleHRFbGVtZW50PignLnNkYy1nYW50dC1iYXItbGFiZWwnKTtcbiAgICBpZiAobGFiZWwpIHtcbiAgICAgIGxhYmVsLnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyhuZXdYICsgVEFTS19MQUJFTF9IT1JJWk9OVEFMX1BBRERJTkcpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZURyYWdSZXNpemVSaWdodChkcmFnOiBEcmFnU3RhdGUsIG9yaWdpbmFsWDogbnVtYmVyLCBvcmlnaW5hbFdpZHRoOiBudW1iZXIsIGJhcjogU1ZHUmVjdEVsZW1lbnQsIGR4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBuZXdXaWR0aCA9IE1hdGgubWF4KGRyYWcuY29sVyAvIERSQUdfTUlOX0hBTkRMRV9GQUNUT1IsIG9yaWdpbmFsV2lkdGggKyBkeCk7XG4gICAgYmFyLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBTdHJpbmcobmV3V2lkdGgpKTtcblxuICAgIGNvbnN0IHJpZ2h0SGFuZGxlID0gZHJhZy5iYXJHcm91cC5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PignLnNkYy1nYW50dC1iYXItaGFuZGxlLS1yaWdodCcpO1xuICAgIGlmIChyaWdodEhhbmRsZSkge1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKG9yaWdpbmFsWCArIG5ld1dpZHRoIC0gSEFORExFX1dJRFRIKSk7XG4gICAgfVxuXG4gICAgY29uc3QgY2xpcFJlY3QgPSB0aGlzLnN2Zy5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PihgI2NsaXAtJHtkcmFnLnRhc2suaWR9IHJlY3RgKTtcbiAgICBpZiAoY2xpcFJlY3QpIHtcbiAgICAgIGNsaXBSZWN0LnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBTdHJpbmcoTWF0aC5tYXgobmV3V2lkdGggLSA0LCAwKSkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlRHJhZ1Jlc2l6ZUxlZnQoZHJhZzogRHJhZ1N0YXRlLCBvcmlnaW5hbFg6IG51bWJlciwgb3JpZ2luYWxXaWR0aDogbnVtYmVyLCBiYXI6IFNWR1JlY3RFbGVtZW50LCBkeDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgbmV3V2lkdGggPSBNYXRoLm1heChkcmFnLmNvbFcgLyBEUkFHX01JTl9IQU5ETEVfRkFDVE9SLCBvcmlnaW5hbFdpZHRoIC0gZHgpO1xuICAgIGNvbnN0IG5ld1ggPSBvcmlnaW5hbFggKyAob3JpZ2luYWxXaWR0aCAtIG5ld1dpZHRoKTtcbiAgICBiYXIuc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKG5ld1gpKTtcbiAgICBiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsIFN0cmluZyhuZXdXaWR0aCkpO1xuXG4gICAgY29uc3QgbGVmdEhhbmRsZSA9IGRyYWcuYmFyR3JvdXAucXVlcnlTZWxlY3RvcjxTVkdSZWN0RWxlbWVudD4oJy5zZGMtZ2FudHQtYmFyLWhhbmRsZS0tbGVmdCcpO1xuICAgIGlmIChsZWZ0SGFuZGxlKSB7XG4gICAgICBsZWZ0SGFuZGxlLnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyhuZXdYKSk7XG4gICAgfVxuXG4gICAgY29uc3QgY2xpcFJlY3QgPSB0aGlzLnN2Zy5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PihgI2NsaXAtJHtkcmFnLnRhc2suaWR9IHJlY3RgKTtcbiAgICBpZiAoY2xpcFJlY3QpIHtcbiAgICAgIGNsaXBSZWN0LnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyhuZXdYICsgMikpO1xuICAgICAgY2xpcFJlY3Quc2V0QXR0cmlidXRlKCd3aWR0aCcsIFN0cmluZyhNYXRoLm1heChuZXdXaWR0aCAtIDQsIDApKSk7XG4gICAgfVxuXG4gICAgY29uc3QgbGFiZWwgPSBkcmFnLmJhckdyb3VwLnF1ZXJ5U2VsZWN0b3I8U1ZHVGV4dEVsZW1lbnQ+KCcuc2RjLWdhbnR0LWJhci1sYWJlbCcpO1xuICAgIGlmIChsYWJlbCkge1xuICAgICAgbGFiZWwuc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKG5ld1ggKyBUQVNLX0xBQkVMX0hPUklaT05UQUxfUEFERElORykpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25Nb3VzZVVwKGU6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZHJhZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgdGFzaywgYmFyR3JvdXAsIHJhbmdlU3RhcnQsIGNvbFcsIG1vZGUgfSA9IHRoaXMuZHJhZztcbiAgICBjb25zdCBiYXIgPSBiYXJHcm91cC5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PihCQVJfU0VMRUNUT1IpO1xuICAgIGlmICghYmFyKSB7XG4gICAgICB0aGlzLmRyYWcgPSBudWxsO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbmFsWCA9IHBhcnNlRmxvYXQoYmFyLmdldEF0dHJpYnV0ZSgneCcpID8/ICcwJyk7XG4gICAgY29uc3QgZmluYWxXID0gcGFyc2VGbG9hdChiYXIuZ2V0QXR0cmlidXRlKCd3aWR0aCcpID8/ICcwJyk7XG4gICAgY29uc3QgZHggPSBlLmNsaWVudFggLSB0aGlzLmRyYWcuc3RhcnRYO1xuXG4gICAgdGhpcy5lbWl0RGF0ZUNoYW5nZUlmU2lnbmlmaWNhbnRNb3ZlbWVudCh0YXNrLCBmaW5hbFgsIGZpbmFsVywgZHgsIHJhbmdlU3RhcnQsIGNvbFcsIG1vZGUpO1xuXG4gICAgLy8gUmVzZXQgdmlzdWFsIHN0YXRlc1xuICAgIGJhci5yZW1vdmVBdHRyaWJ1dGUoJ3N0cm9rZScpO1xuICAgIGJhci5yZW1vdmVBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcpO1xuICAgIGJhckdyb3VwLnN0eWxlLmN1cnNvciA9ICdncmFiJztcblxuICAgIHRoaXMuZHJhZyA9IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGVtaXREYXRlQ2hhbmdlSWZTaWduaWZpY2FudE1vdmVtZW50KFxuICAgIHRhc2s6IEdhbnR0VGFzayxcbiAgICBmaW5hbFg6IG51bWJlcixcbiAgICBmaW5hbFc6IG51bWJlcixcbiAgICBkeDogbnVtYmVyLFxuICAgIHJhbmdlU3RhcnQ6IERhdGUsXG4gICAgY29sVzogbnVtYmVyLFxuICAgIG1vZGU6IERyYWdNb2RlXG4gICk6IHZvaWQge1xuICAgIC8vIE9ubHkgZW1pdCBpZiB0aGVyZSB3YXMgbWVhbmluZ2Z1bCBtb3ZlbWVudFxuICAgIGlmIChNYXRoLmFicyhkeCkgPiAyICYmIHRoaXMub3B0aW9ucy5vbkRhdGVDaGFuZ2UpIHtcbiAgICAgIGNvbnN0IHsgbmV3U3RhcnQsIG5ld0VuZCB9ID0gdGhpcy5jYWxjdWxhdGVOZXdEYXRlcyh0YXNrLCBmaW5hbFgsIGZpbmFsVywgcmFuZ2VTdGFydCwgY29sVywgbW9kZSk7XG4gICAgICB0aGlzLm9wdGlvbnMub25EYXRlQ2hhbmdlKHRhc2ssIG5ld1N0YXJ0LCBuZXdFbmQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2FsY3VsYXRlTmV3RGF0ZXMoXG4gICAgdGFzazogR2FudHRUYXNrLFxuICAgIGZpbmFsWDogbnVtYmVyLFxuICAgIGZpbmFsVzogbnVtYmVyLFxuICAgIHJhbmdlU3RhcnQ6IERhdGUsXG4gICAgY29sVzogbnVtYmVyLFxuICAgIG1vZGU6IERyYWdNb2RlXG4gICk6IHsgbmV3U3RhcnQ6IERhdGU7IG5ld0VuZDogRGF0ZSB9IHtcbiAgICBjb25zdCBkdXJhdGlvbk1zID0gdGFzay5lbmQuZ2V0VGltZSgpIC0gdGFzay5zdGFydC5nZXRUaW1lKCk7XG4gICAgbGV0IG5ld1N0YXJ0OiBEYXRlO1xuICAgIGxldCBuZXdFbmQ6IERhdGU7XG5cbiAgICBpZiAobW9kZSA9PT0gRHJhZ01vZGUuTW92ZSkge1xuICAgICAgbmV3U3RhcnQgPSB0aGlzLnhUb0RhdGUoZmluYWxYLCByYW5nZVN0YXJ0LCBjb2xXKTtcbiAgICAgIG5ld0VuZCA9IG5ldyBEYXRlKG5ld1N0YXJ0LmdldFRpbWUoKSArIGR1cmF0aW9uTXMpO1xuICAgIH0gZWxzZSBpZiAobW9kZSA9PT0gRHJhZ01vZGUuUmVzaXplUmlnaHQpIHtcbiAgICAgIG5ld1N0YXJ0ID0gdGFzay5zdGFydDtcbiAgICAgIG5ld0VuZCA9IHRoaXMueFRvRGF0ZShmaW5hbFggKyBmaW5hbFcsIHJhbmdlU3RhcnQsIGNvbFcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyByZXNpemUtbGVmdFxuICAgICAgbmV3U3RhcnQgPSB0aGlzLnhUb0RhdGUoZmluYWxYLCByYW5nZVN0YXJ0LCBjb2xXKTtcbiAgICAgIG5ld0VuZCA9IHRhc2suZW5kO1xuICAgIH1cblxuICAgIHJldHVybiB7IG5ld1N0YXJ0LCBuZXdFbmQgfTtcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBQb3B1cFxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBwcml2YXRlIHNob3dQb3B1cCh0YXNrOiBHYW50dFRhc2ssIGNsaWVudFg6IG51bWJlciwgY2xpZW50WTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5yZW1vdmVQb3B1cCgpO1xuXG4gICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZGl2LmNsYXNzTmFtZSA9ICdzZGMtZ2FudHQtcG9wdXAnO1xuICAgIGRpdi5zdHlsZS5jc3NUZXh0ID0gYFxuICAgICAgcG9zaXRpb246IGZpeGVkO1xuICAgICAgei1pbmRleDogOTk5OTtcbiAgICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAjY2NjO1xuICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgICAgcGFkZGluZzogOHB4IDEycHg7XG4gICAgICBib3gtc2hhZG93OiAwIDJweCA4cHggcmdiYSgwLDAsMCwuMik7XG4gICAgICBmb250LXNpemU6IDEzcHg7XG4gICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgYDtcblxuICAgIGNvbnN0IGZvcm1hdE9wdHM6IEludGwuRGF0ZVRpbWVGb3JtYXRPcHRpb25zID0geyBkYXk6ICcyLWRpZ2l0JywgbW9udGg6ICdzaG9ydCcsIHllYXI6ICdudW1lcmljJyB9O1xuICAgIGNvbnN0IHN0YXJ0ID0gdGFzay5zdGFydC50b0xvY2FsZURhdGVTdHJpbmcoJ3B0LUJSJywgZm9ybWF0T3B0cyk7XG4gICAgY29uc3QgZW5kID0gdGFzay5lbmQudG9Mb2NhbGVEYXRlU3RyaW5nKCdwdC1CUicsIGZvcm1hdE9wdHMpO1xuXG4gICAgY29uc3QgdGl0bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHJvbmcnKTtcbiAgICB0aXRsZS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICB0aXRsZS5zdHlsZS5tYXJnaW5Cb3R0b20gPSAnNHB4JztcbiAgICB0aXRsZS50ZXh0Q29udGVudCA9IHRhc2submFtZTtcblxuICAgIGNvbnN0IHN0YXJ0TGFiZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgc3RhcnRMYWJlbC50ZXh0Q29udGVudCA9IGBJbmljaW86ICR7c3RhcnR9YDtcblxuICAgIGNvbnN0IGxpbmVCcmVhayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2JyJyk7XG5cbiAgICBjb25zdCBlbmRMYWJlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICBlbmRMYWJlbC50ZXh0Q29udGVudCA9IGBGaW06ICR7ZW5kfWA7XG5cbiAgICBkaXYucmVwbGFjZUNoaWxkcmVuKHRpdGxlLCBzdGFydExhYmVsLCBsaW5lQnJlYWssIGVuZExhYmVsKTsgLypcbiAgICAgIDxzdHJvbmcgc3R5bGU9XCJkaXNwbGF5OmJsb2NrO21hcmdpbi1ib3R0b206NHB4O1wiPiR7dGFzay5uYW1lfTwvc3Ryb25nPlxuICAgICAgPHNwYW4+SW7DrWNpbzogJHtzdGFydH08L3NwYW4+PGJyPlxuICAgICAgPHNwYW4+RmltOiAke2VuZH08L3NwYW4+XG4gICAgKi9cblxuICAgIGRpdi5zdHlsZS5sZWZ0ID0gYCR7Y2xpZW50WCArIHRoaXMuUEFERElOR31weGA7XG4gICAgZGl2LnN0eWxlLnRvcCA9IGAke2NsaWVudFkgLSAxMH1weGA7XG5cbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGRpdik7XG4gICAgdGhpcy5wb3B1cCA9IGRpdjtcblxuICAgIC8vIEF1dG8tcmVtb3ZlIGFmdGVyIDMgc1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5yZW1vdmVQb3B1cCgpLCBQT1BVUF9BVVRPX1JFTU9WRV9ERUxBWV9NUyk7XG5cbiAgICAvLyBSZW1vdmUgb24gbmV4dCBjbGljayBhbnl3aGVyZVxuICAgIGNvbnN0IHJlbW92ZU9uQ2xpY2sgPSAoKTogdm9pZCA9PiB7XG4gICAgICB0aGlzLnJlbW92ZVBvcHVwKCk7XG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHJlbW92ZU9uQ2xpY2ssIHRydWUpO1xuICAgIH07XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCByZW1vdmVPbkNsaWNrLCB0cnVlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlUG9wdXAoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucG9wdXA/LnBhcmVudE5vZGUpIHtcbiAgICAgIHRoaXMucG9wdXAucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnBvcHVwKTtcbiAgICB9XG5cbiAgICB0aGlzLnBvcHVwID0gbnVsbDtcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBQb3NpdGlvbiAvIGRpbWVuc2lvbiBoZWxwZXJzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHByaXZhdGUgY29tcHV0ZUJhclgodGFza1N0YXJ0OiBEYXRlLCByYW5nZVN0YXJ0OiBEYXRlLCBjb2xXOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IG1vZGUgPSB0aGlzLm9wdGlvbnMudmlld01vZGU7XG4gICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgcmV0dXJuIGRpZmZIb3VycyhyYW5nZVN0YXJ0LCB0YXNrU3RhcnQpICogY29sVztcbiAgICAgIGNhc2UgJ2RheSc6XG4gICAgICAgIHJldHVybiBkaWZmRGF5cyhyYW5nZVN0YXJ0LCB0YXNrU3RhcnQpICogY29sVztcbiAgICAgIGNhc2UgJ3dlZWsnOlxuICAgICAgICByZXR1cm4gKGRpZmZEYXlzKHJhbmdlU3RhcnQsIHRhc2tTdGFydCkgLyBEQVlTX0lOX1dFRUspICogY29sVztcbiAgICAgIGNhc2UgJ21vbnRoJzoge1xuICAgICAgICBjb25zdCBtb250aERpZmYgPVxuICAgICAgICAgICh0YXNrU3RhcnQuZ2V0RnVsbFllYXIoKSAtIHJhbmdlU3RhcnQuZ2V0RnVsbFllYXIoKSkgKiBNT05USFNfSU5fWUVBUiArXG4gICAgICAgICAgKHRhc2tTdGFydC5nZXRNb250aCgpIC0gcmFuZ2VTdGFydC5nZXRNb250aCgpKTtcbiAgICAgICAgY29uc3QgZGF5RnJhY3Rpb24gPSAodGFza1N0YXJ0LmdldERhdGUoKSAtIDEpIC8gbmV3IERhdGUodGFza1N0YXJ0LmdldEZ1bGxZZWFyKCksIHRhc2tTdGFydC5nZXRNb250aCgpICsgMSwgMCkuZ2V0RGF0ZSgpO1xuICAgICAgICByZXR1cm4gKG1vbnRoRGlmZiArIGRheUZyYWN0aW9uKSAqIGNvbFc7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZGlmZkRheXMocmFuZ2VTdGFydCwgdGFza1N0YXJ0KSAqIGNvbFc7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb21wdXRlQmFyV2lkdGgodGFzazogR2FudHRUYXNrLCBjb2xXOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IG1vZGUgPSB0aGlzLm9wdGlvbnMudmlld01vZGU7XG4gICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgcmV0dXJuIGRpZmZIb3Vycyh0YXNrLnN0YXJ0LCB0YXNrLmVuZCkgKiBjb2xXO1xuICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgcmV0dXJuIGRpZmZEYXlzKHRhc2suc3RhcnQsIHRhc2suZW5kKSAqIGNvbFc7XG4gICAgICBjYXNlICd3ZWVrJzpcbiAgICAgICAgcmV0dXJuIChkaWZmRGF5cyh0YXNrLnN0YXJ0LCB0YXNrLmVuZCkgLyBEQVlTX0lOX1dFRUspICogY29sVztcbiAgICAgIGNhc2UgJ21vbnRoJzoge1xuICAgICAgICBjb25zdCBkYXlzSW5SYW5nZSA9IGRpZmZEYXlzKHRhc2suc3RhcnQsIHRhc2suZW5kKTtcbiAgICAgICAgY29uc3QgZGF5c0luTW9udGggPSBuZXcgRGF0ZSh0YXNrLnN0YXJ0LmdldEZ1bGxZZWFyKCksIHRhc2suc3RhcnQuZ2V0TW9udGgoKSArIDEsIDApLmdldERhdGUoKTtcbiAgICAgICAgcmV0dXJuIChkYXlzSW5SYW5nZSAvIGRheXNJbk1vbnRoKSAqIGNvbFc7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZGlmZkRheXModGFzay5zdGFydCwgdGFzay5lbmQpICogY29sVztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHhUb0RhdGUoeDogbnVtYmVyLCByYW5nZVN0YXJ0OiBEYXRlLCBjb2xXOiBudW1iZXIpOiBEYXRlIHtcbiAgICBjb25zdCBtb2RlID0gdGhpcy5vcHRpb25zLnZpZXdNb2RlO1xuICAgIGNvbnN0IHNsb3RzID0geCAvIGNvbFc7XG4gICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgcmV0dXJuIGFkZEhvdXJzKHJhbmdlU3RhcnQsIE1hdGgucm91bmQoc2xvdHMpKTtcbiAgICAgIGNhc2UgJ2RheSc6XG4gICAgICAgIHJldHVybiBhZGREYXlzKHJhbmdlU3RhcnQsIE1hdGgucm91bmQoc2xvdHMpKTtcbiAgICAgIGNhc2UgJ3dlZWsnOlxuICAgICAgICByZXR1cm4gYWRkRGF5cyhyYW5nZVN0YXJ0LCBNYXRoLnJvdW5kKHNsb3RzICogREFZU19JTl9XRUVLKSk7XG4gICAgICBjYXNlICdtb250aCc6IHtcbiAgICAgICAgY29uc3QgZCA9IG5ldyBEYXRlKHJhbmdlU3RhcnQpO1xuICAgICAgICBkLnNldE1vbnRoKGQuZ2V0TW9udGgoKSArIE1hdGguZmxvb3Ioc2xvdHMpKTtcbiAgICAgICAgcmV0dXJuIGQ7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gYWRkRGF5cyhyYW5nZVN0YXJ0LCBNYXRoLnJvdW5kKHNsb3RzKSk7XG4gICAgfVxuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIFNWRyBoZWxwZXJzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHByaXZhdGUgY2xlYXJTdmcoKTogdm9pZCB7XG4gICAgd2hpbGUgKHRoaXMuc3ZnLmZpcnN0Q2hpbGQpIHtcbiAgICAgIHRoaXMuc3ZnLnJlbW92ZUNoaWxkKHRoaXMuc3ZnLmZpcnN0Q2hpbGQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlU3ZnRWxlbWVudDxLIGV4dGVuZHMga2V5b2YgU1ZHRWxlbWVudFRhZ05hbWVNYXA+KHRhZzogSyk6IFNWR0VsZW1lbnRUYWdOYW1lTWFwW0tdIHtcbiAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFNWR19OUywgdGFnKTtcbiAgfVxufVxuIl19