@scion/workbench 17.0.0-beta.9 → 18.0.0-beta.10

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 (328) hide show
  1. package/_index.scss +7 -5
  2. package/design/_workbench-global-styles.scss +18 -0
  3. package/design/_workbench-icon-font.scss +1 -1
  4. package/design/_workbench-popup-global-styles.scss +1 -1
  5. package/design/{_workbench-view-drag-image-global-styles.scss → _workbench-view-global-styles.scss} +1 -2
  6. package/esm2022/lib/activation-instant.provider.mjs +3 -3
  7. package/esm2022/lib/common/asserts.util.mjs +1 -1
  8. package/esm2022/lib/common/class-list.mjs +67 -29
  9. package/esm2022/lib/common/coerce-observable.pipe.mjs +3 -3
  10. package/esm2022/lib/common/dom.util.mjs +1 -1
  11. package/esm2022/lib/common/grid-element-if-visible.pipe.mjs +4 -4
  12. package/esm2022/lib/common/instanceof.pipe.mjs +3 -3
  13. package/esm2022/lib/common/map-coerce.pipe.mjs +3 -3
  14. package/esm2022/lib/common/math.util.mjs +16 -0
  15. package/esm2022/lib/common/null-if-empty.pipe.mjs +4 -4
  16. package/esm2022/lib/common/objects.util.mjs +7 -1
  17. package/esm2022/lib/common/observables.mjs +1 -1
  18. package/esm2022/lib/common/operators.mjs +1 -12
  19. package/esm2022/lib/common/stringify-error.util.mjs +1 -1
  20. package/esm2022/lib/common/typeof.pipe.mjs +3 -3
  21. package/esm2022/lib/common/uid.util.mjs +22 -0
  22. package/esm2022/lib/common//311/265destroy-ref.mjs +1 -1
  23. package/esm2022/lib/content-projection/content-as-overlay.component.mjs +87 -30
  24. package/esm2022/lib/content-projection/workbench-element-references.mjs +32 -0
  25. package/esm2022/lib/dialog/dialog-footer/dialog-action-filter.pipe.mjs +3 -3
  26. package/esm2022/lib/dialog/dialog-footer/dialog-footer.component.mjs +3 -3
  27. package/esm2022/lib/dialog/dialog-footer/workbench-dialog-action.directive.mjs +3 -3
  28. package/esm2022/lib/dialog/dialog-footer/workbench-dialog-footer.directive.mjs +3 -3
  29. package/esm2022/lib/dialog/dialog-header/dialog-header.component.mjs +5 -10
  30. package/esm2022/lib/dialog/dialog-header/workbench-dialog-header.directive.mjs +3 -3
  31. package/esm2022/lib/dialog/movable.directive.mjs +6 -6
  32. package/esm2022/lib/dialog/resizable.directive.mjs +6 -6
  33. package/esm2022/lib/dialog/workbench-dialog.component.mjs +27 -25
  34. package/esm2022/lib/dialog/workbench-dialog.mjs +61 -1
  35. package/esm2022/lib/dialog/workbench-dialog.registry.mjs +4 -4
  36. package/esm2022/lib/dialog/workbench-dialog.service.mjs +3 -3
  37. package/esm2022/lib/dialog//311/265workbench-dialog.mjs +99 -61
  38. package/esm2022/lib/dialog//311/265workbench-dialog.service.mjs +28 -25
  39. package/esm2022/lib/executor/latest-task-executor.mjs +55 -0
  40. package/esm2022/lib/executor/single-task-executor.mjs +9 -19
  41. package/esm2022/lib/filter-field/filter-field.component.mjs +8 -8
  42. package/esm2022/lib/glass-pane/glass-pane.directive.mjs +4 -4
  43. package/esm2022/lib/layout/grid-element/grid-element.component.mjs +10 -20
  44. package/esm2022/lib/layout/main-area-layout/main-area-layout.component.mjs +19 -22
  45. package/esm2022/lib/layout/migration/model/workbench-layout-migration-v5.model.mjs +11 -0
  46. package/esm2022/lib/layout/migration/model/workbench-layout-migration-v6.model.mjs +11 -0
  47. package/esm2022/lib/layout/migration/workbench-layout-migration-v3.service.mjs +7 -7
  48. package/esm2022/lib/layout/migration/workbench-layout-migration-v4.service.mjs +4 -4
  49. package/esm2022/lib/layout/migration/workbench-layout-migration-v5.service.mjs +67 -0
  50. package/esm2022/lib/layout/migration/workbench-layout-migration-v6.service.mjs +59 -0
  51. package/esm2022/lib/layout/stringifier.mjs +70 -0
  52. package/esm2022/lib/layout/workbench-layout.component.mjs +19 -23
  53. package/esm2022/lib/layout/workbench-layout.factory.mjs +3 -3
  54. package/esm2022/lib/layout/workbench-layout.mjs +1 -1
  55. package/esm2022/lib/layout/workbench-layout.model.mjs +1 -1
  56. package/esm2022/lib/layout/workbench-layout.service.mjs +28 -26
  57. package/esm2022/lib/layout/workbench-layouts.util.mjs +1 -9
  58. package/esm2022/lib/layout/workench-layout-serializer.service.mjs +22 -32
  59. package/esm2022/lib/layout//311/265workbench-layout.factory.mjs +6 -5
  60. package/esm2022/lib/layout//311/265workbench-layout.mjs +77 -66
  61. package/esm2022/lib/logging/console-appender.service.mjs +4 -4
  62. package/esm2022/lib/logging/logger.mjs +3 -3
  63. package/esm2022/lib/logging/logging-support.mjs +7 -13
  64. package/esm2022/lib/logging/logging.model.mjs +3 -3
  65. package/esm2022/lib/logging//311/265logger.mjs +12 -12
  66. package/esm2022/lib/message-box/message-box-footer/message-box-footer.component.mjs +9 -8
  67. package/esm2022/lib/message-box/message-box-header/message-box-header.component.mjs +5 -5
  68. package/esm2022/lib/message-box/workbench-message-box.component.mjs +5 -5
  69. package/esm2022/lib/message-box/workbench-message-box.service.mjs +3 -3
  70. package/esm2022/lib/message-box//311/265workbench-message-box.service.mjs +6 -5
  71. package/esm2022/lib/microfrontend-platform/common/microfrontend.util.mjs +22 -6
  72. package/esm2022/lib/microfrontend-platform/initialization/microfrontend-platform-initializer.service.mjs +29 -22
  73. package/esm2022/lib/microfrontend-platform/initialization/ng-zone-observable-decorator.mjs +6 -6
  74. package/esm2022/lib/microfrontend-platform/initialization/workbench-host-manifest-interceptor.service.mjs +14 -4
  75. package/esm2022/lib/microfrontend-platform/manifest-object-cache.service.mjs +63 -0
  76. package/esm2022/lib/microfrontend-platform/microfrontend-dialog/microfrontend-dialog-capability-validator.interceptor.mjs +8 -7
  77. package/esm2022/lib/microfrontend-platform/microfrontend-dialog/microfrontend-dialog-intent-handler.interceptor.mjs +4 -4
  78. package/esm2022/lib/microfrontend-platform/microfrontend-dialog/microfrontend-dialog.component.mjs +8 -12
  79. package/esm2022/lib/microfrontend-platform/microfrontend-host-dialog/microfrontend-host-dialog.component.mjs +21 -12
  80. package/esm2022/lib/microfrontend-platform/microfrontend-host-message-box/microfrontend-host-message-box.component.mjs +10 -9
  81. package/esm2022/lib/microfrontend-platform/microfrontend-host-message-box/text-message/text-message.component.mjs +6 -6
  82. package/esm2022/lib/microfrontend-platform/microfrontend-host-popup/microfrontend-host-popup.component.mjs +17 -15
  83. package/esm2022/lib/microfrontend-platform/microfrontend-message-box/microfrontend-message-box-capability-validator.interceptor.mjs +6 -5
  84. package/esm2022/lib/microfrontend-platform/microfrontend-message-box/microfrontend-message-box-intent-handler.interceptor.mjs +4 -4
  85. package/esm2022/lib/microfrontend-platform/microfrontend-message-box/microfrontend-message-box-legacy-intent-translator.interceptor.mjs +4 -4
  86. package/esm2022/lib/microfrontend-platform/microfrontend-message-box/microfrontend-message-box.component.mjs +10 -15
  87. package/esm2022/lib/microfrontend-platform/microfrontend-notification/microfrontend-notification-intent-handler.service.mjs +3 -3
  88. package/esm2022/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-capability-validator.interceptor.mjs +39 -0
  89. package/esm2022/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-installer.service.mjs +120 -0
  90. package/esm2022/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-intent-handler.interceptor.mjs +55 -0
  91. package/esm2022/lib/microfrontend-platform/microfrontend-perspective/workbench-perspective-data.mjs +19 -0
  92. package/esm2022/lib/microfrontend-platform/microfrontend-platform-config-loader.mjs +3 -3
  93. package/esm2022/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup-capability-validator.interceptor.mjs +7 -6
  94. package/esm2022/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup-intent-handler.interceptor.mjs +13 -14
  95. package/esm2022/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup.component.mjs +14 -30
  96. package/esm2022/lib/microfrontend-platform/microfrontend-splash/microfrontend-splash.component.mjs +5 -5
  97. package/esm2022/lib/microfrontend-platform/microfrontend-view/microfrontend-view-command-handler.service.mjs +13 -29
  98. package/esm2022/lib/microfrontend-platform/microfrontend-view/microfrontend-view.component.mjs +92 -72
  99. package/esm2022/lib/microfrontend-platform/public_api.mjs +2 -1
  100. package/esm2022/lib/microfrontend-platform/routing/microfrontend-view-capability-validator.interceptor.mjs +8 -7
  101. package/esm2022/lib/microfrontend-platform/routing/microfrontend-view-intent-handler.interceptor.mjs +20 -18
  102. package/esm2022/lib/microfrontend-platform/routing/microfrontend-view-routes.mjs +30 -8
  103. package/esm2022/lib/microfrontend-platform/stable-capability-id-assigner.interceptor.mjs +32 -0
  104. package/esm2022/lib/microfrontend-platform/workbench-microfrontend-support.mjs +29 -11
  105. package/esm2022/lib/migration/workbench-migrator.mjs +1 -1
  106. package/esm2022/lib/notification/notification-css-classes.pipe.mjs +3 -3
  107. package/esm2022/lib/notification/notification-list.component.mjs +6 -10
  108. package/esm2022/lib/notification/notification.component.mjs +6 -7
  109. package/esm2022/lib/notification/notification.service.mjs +8 -7
  110. package/esm2022/lib/notification/text-notification.component.mjs +3 -3
  111. package/esm2022/lib/notification//311/265notification.mjs +1 -1
  112. package/esm2022/lib/page-not-found/page-not-found.component.mjs +7 -9
  113. package/esm2022/lib/part/part-action-bar/part-action-bar.component.mjs +12 -20
  114. package/esm2022/lib/part/part-action-bar/part-action.directive.mjs +7 -7
  115. package/esm2022/lib/part/part-bar/part-bar.component.mjs +334 -265
  116. package/esm2022/lib/part/part-portal.pipe.mjs +10 -10
  117. package/esm2022/lib/part/part.component.mjs +34 -43
  118. package/esm2022/lib/part/view-context-menu/accelerator-format.pipe.mjs +4 -4
  119. package/esm2022/lib/part/view-context-menu/text.component.mjs +17 -13
  120. package/esm2022/lib/part/view-context-menu/view-menu.component.mjs +6 -8
  121. package/esm2022/lib/part/view-context-menu/view-menu.directive.mjs +5 -5
  122. package/esm2022/lib/part/view-context-menu/view-menu.service.mjs +50 -51
  123. package/esm2022/lib/part/view-list/view-list.component.mjs +42 -49
  124. package/esm2022/lib/part/view-list-button/view-list-button.component.mjs +23 -27
  125. package/esm2022/lib/part/view-list-item/view-list-item.component.mjs +16 -18
  126. package/esm2022/lib/part/view-tab/view-tab.component.mjs +100 -111
  127. package/esm2022/lib/part/view-tab-content/view-tab-content.component.mjs +5 -6
  128. package/esm2022/lib/part/view-tab-drag-image/view-tab-drag-image.component.mjs +17 -18
  129. package/esm2022/lib/part/workbench-part-action.registry.mjs +18 -42
  130. package/esm2022/lib/part/workbench-part.model.mjs +10 -1
  131. package/esm2022/lib/part/workbench-part.registry.mjs +11 -45
  132. package/esm2022/lib/part//311/265workbench-part.model.mjs +71 -55
  133. package/esm2022/lib/perspective/migration/workbench-perspective-migration-v2.service.mjs +4 -4
  134. package/esm2022/lib/perspective/workbench-grid-merger.service.mjs +6 -6
  135. package/esm2022/lib/perspective/workbench-perspective-storage.service.mjs +4 -4
  136. package/esm2022/lib/perspective/workbench-perspective-view-conflict-resolver.service.mjs +4 -4
  137. package/esm2022/lib/perspective/workbench-perspective.model.mjs +1 -1
  138. package/esm2022/lib/perspective/workbench-perspective.registry.mjs +11 -43
  139. package/esm2022/lib/perspective/workbench-perspective.service.mjs +73 -64
  140. package/esm2022/lib/perspective/workench-perspective-serializer.service.mjs +5 -5
  141. package/esm2022/lib/perspective//311/265workbench-perspective.model.mjs +62 -47
  142. package/esm2022/lib/popup/popup.component.mjs +6 -6
  143. package/esm2022/lib/popup/popup.config.mjs +27 -25
  144. package/esm2022/lib/popup/popup.service.mjs +171 -176
  145. package/esm2022/lib/portal/wb-component-portal.mjs +18 -17
  146. package/esm2022/lib/portal/workbench-portal-outlet.directive.mjs +4 -4
  147. package/esm2022/lib/public_api.mjs +1 -1
  148. package/esm2022/lib/registry/workbench-object-registry.mjs +38 -17
  149. package/esm2022/lib/routing/empty-outlet/empty-outlet.component.mjs +3 -3
  150. package/esm2022/lib/routing/public_api.mjs +2 -2
  151. package/esm2022/lib/routing/routing.model.mjs +1 -1
  152. package/esm2022/lib/routing/routing.util.mjs +215 -0
  153. package/esm2022/lib/routing/url-segment-matcher.mjs +1 -1
  154. package/esm2022/lib/routing/workbench-auxiliary-route-installer.service.mjs +110 -0
  155. package/esm2022/lib/routing/workbench-dialog-differ.mjs +6 -6
  156. package/esm2022/lib/routing/workbench-layout-differ.mjs +6 -13
  157. package/esm2022/lib/routing/workbench-message-box-differ.mjs +6 -6
  158. package/esm2022/lib/routing/workbench-navigational-states.mjs +2 -2
  159. package/esm2022/lib/routing/workbench-popup-differ.mjs +6 -6
  160. package/esm2022/lib/routing/workbench-route-guards.mjs +57 -0
  161. package/esm2022/lib/routing/workbench-router-link.directive.mjs +5 -5
  162. package/esm2022/lib/routing/workbench-router.service.mjs +3 -3
  163. package/esm2022/lib/routing/workbench-url-observer.service.mjs +143 -151
  164. package/esm2022/lib/routing/workbench-view-outlet-differ.mjs +58 -0
  165. package/esm2022/lib/routing//311/265location.mjs +3 -3
  166. package/esm2022/lib/routing//311/265workbench-router.service.mjs +121 -76
  167. package/esm2022/lib/startup/splash/splash.component.mjs +5 -5
  168. package/esm2022/lib/startup/workbench-initializer.mjs +1 -1
  169. package/esm2022/lib/startup/workbench-launcher.service.mjs +28 -16
  170. package/esm2022/lib/storage/workbench-storage.mjs +3 -3
  171. package/esm2022/lib/testing/workbench-testing.module.mjs +4 -4
  172. package/esm2022/lib/testing/workbench.provider.mjs +5 -5
  173. package/esm2022/lib/theme/workbench-theme-switcher.service.mjs +18 -22
  174. package/esm2022/lib/view/public_api.mjs +1 -2
  175. package/esm2022/lib/view/view-move-handler.service.mjs +73 -58
  176. package/esm2022/lib/view/view-portal.pipe.mjs +9 -9
  177. package/esm2022/lib/view/view.component.mjs +55 -43
  178. package/esm2022/lib/view/workbench-view.model.mjs +1 -1
  179. package/esm2022/lib/view/workbench-view.registry.mjs +11 -45
  180. package/esm2022/lib/view//311/265workbench-view.model.mjs +183 -153
  181. package/esm2022/lib/view-dnd/grid-drop-targets.util.mjs +2 -2
  182. package/esm2022/lib/view-dnd/requires-drop-zone.pipe.mjs +4 -4
  183. package/esm2022/lib/view-dnd/view-drag.service.mjs +89 -73
  184. package/esm2022/lib/view-dnd/view-drop-placeholder-renderer.service.mjs +9 -9
  185. package/esm2022/lib/view-dnd/view-drop-zone.directive.mjs +9 -9
  186. package/esm2022/lib/view-dnd/view-tab-drag-image-renderer.service.mjs +45 -58
  187. package/esm2022/lib/workbench-config.mjs +2 -2
  188. package/esm2022/lib/workbench-id.mjs +3 -3
  189. package/esm2022/lib/workbench.component.mjs +67 -55
  190. package/esm2022/lib/workbench.constants.mjs +1 -5
  191. package/esm2022/lib/workbench.model.mjs +1 -1
  192. package/esm2022/lib/workbench.module.mjs +4 -4
  193. package/esm2022/lib/workbench.provider.mjs +3 -9
  194. package/esm2022/lib/workbench.service.mjs +4 -4
  195. package/esm2022/lib//311/265workbench.service.mjs +40 -44
  196. package/fesm2022/scion-workbench.mjs +4348 -3628
  197. package/fesm2022/scion-workbench.mjs.map +1 -1
  198. package/lib/common/class-list.d.ts +35 -22
  199. package/lib/common/math.util.d.ts +7 -0
  200. package/lib/common/objects.util.d.ts +6 -2
  201. package/lib/common/operators.d.ts +1 -6
  202. package/lib/common/uid.util.d.ts +9 -0
  203. package/lib/content-projection/content-as-overlay.component.d.ts +39 -22
  204. package/lib/content-projection/workbench-element-references.d.ts +13 -0
  205. package/lib/dialog/workbench-dialog.component.d.ts +3 -2
  206. package/lib/dialog/workbench-dialog.d.ts +57 -13
  207. package/lib/dialog//311/265workbench-dialog.d.ts +38 -24
  208. package/lib/dialog//311/265workbench-dialog.service.d.ts +10 -11
  209. package/lib/executor/latest-task-executor.d.ts +26 -0
  210. package/lib/executor/single-task-executor.d.ts +5 -8
  211. package/lib/filter-field/filter-field.component.d.ts +1 -1
  212. package/lib/layout/grid-element/grid-element.component.d.ts +1 -8
  213. package/lib/layout/main-area-layout/main-area-layout.component.d.ts +0 -4
  214. package/lib/layout/migration/model/workbench-layout-migration-v5.model.d.ts +36 -0
  215. package/lib/layout/migration/model/workbench-layout-migration-v6.model.d.ts +35 -0
  216. package/lib/layout/migration/{workbench-layout-migration-v2.service.d.ts → workbench-layout-migration-v5.service.d.ts} +4 -5
  217. package/lib/layout/migration/workbench-layout-migration-v6.service.d.ts +12 -0
  218. package/lib/layout/stringifier.d.ts +26 -0
  219. package/lib/layout/workbench-layout.component.d.ts +4 -5
  220. package/lib/layout/workbench-layout.d.ts +9 -6
  221. package/lib/layout/workbench-layout.model.d.ts +4 -3
  222. package/lib/layout/workbench-layout.service.d.ts +14 -16
  223. package/lib/layout/workbench-layouts.util.d.ts +0 -6
  224. package/lib/layout/workench-layout-serializer.service.d.ts +13 -16
  225. package/lib/layout//311/265workbench-layout.d.ts +18 -19
  226. package/lib/layout//311/265workbench-layout.factory.d.ts +3 -2
  227. package/lib/logging//311/265logger.d.ts +2 -3
  228. package/lib/microfrontend-platform/common/microfrontend.util.d.ts +5 -1
  229. package/lib/microfrontend-platform/initialization/microfrontend-platform-initializer.service.d.ts +7 -3
  230. package/lib/microfrontend-platform/manifest-object-cache.service.d.ts +33 -0
  231. package/lib/microfrontend-platform/microfrontend-host-dialog/microfrontend-host-dialog.component.d.ts +3 -6
  232. package/lib/microfrontend-platform/microfrontend-host-message-box/microfrontend-host-message-box.component.d.ts +2 -1
  233. package/lib/microfrontend-platform/microfrontend-host-message-box/text-message/text-message.component.d.ts +1 -1
  234. package/lib/microfrontend-platform/microfrontend-host-popup/microfrontend-host-popup.component.d.ts +2 -1
  235. package/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-capability-validator.interceptor.d.ts +10 -0
  236. package/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-installer.service.d.ts +24 -0
  237. package/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-intent-handler.interceptor.d.ts +20 -0
  238. package/lib/microfrontend-platform/microfrontend-perspective/workbench-perspective-data.d.ts +9 -0
  239. package/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup-intent-handler.interceptor.d.ts +4 -8
  240. package/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup.component.d.ts +0 -4
  241. package/lib/microfrontend-platform/microfrontend-view/microfrontend-view-command-handler.service.d.ts +5 -12
  242. package/lib/microfrontend-platform/microfrontend-view/microfrontend-view.component.d.ts +23 -33
  243. package/lib/microfrontend-platform/public_api.d.ts +1 -0
  244. package/lib/microfrontend-platform/routing/microfrontend-view-capability-validator.interceptor.d.ts +1 -1
  245. package/lib/microfrontend-platform/routing/microfrontend-view-intent-handler.interceptor.d.ts +3 -7
  246. package/lib/microfrontend-platform/routing/microfrontend-view-routes.d.ts +9 -2
  247. package/lib/microfrontend-platform/stable-capability-id-assigner.interceptor.d.ts +11 -0
  248. package/lib/notification/notification-list.component.d.ts +0 -2
  249. package/lib/page-not-found/page-not-found.component.d.ts +1 -0
  250. package/lib/part/part-action-bar/part-action-bar.component.d.ts +3 -4
  251. package/lib/part/part-action-bar/part-action.directive.d.ts +2 -2
  252. package/lib/part/part-bar/part-bar.component.d.ts +73 -63
  253. package/lib/part/part-portal.pipe.d.ts +3 -5
  254. package/lib/part/part.component.d.ts +9 -12
  255. package/lib/part/view-context-menu/text.component.d.ts +3 -4
  256. package/lib/part/view-context-menu/view-menu.directive.d.ts +1 -1
  257. package/lib/part/view-context-menu/view-menu.service.d.ts +13 -17
  258. package/lib/part/view-list/view-list.component.d.ts +8 -21
  259. package/lib/part/view-list-button/view-list-button.component.d.ts +8 -11
  260. package/lib/part/view-list-item/view-list-item.component.d.ts +3 -7
  261. package/lib/part/view-tab/view-tab.component.d.ts +19 -29
  262. package/lib/part/view-tab-drag-image/view-tab-drag-image.component.d.ts +4 -4
  263. package/lib/part/workbench-part-action.registry.d.ts +3 -23
  264. package/lib/part/workbench-part.model.d.ts +8 -27
  265. package/lib/part/workbench-part.registry.d.ts +3 -26
  266. package/lib/part//311/265workbench-part.model.d.ts +23 -17
  267. package/lib/perspective/workbench-perspective.model.d.ts +18 -25
  268. package/lib/perspective/workbench-perspective.registry.d.ts +3 -26
  269. package/lib/perspective/workbench-perspective.service.d.ts +16 -14
  270. package/lib/perspective/workench-perspective-serializer.service.d.ts +1 -1
  271. package/lib/perspective//311/265workbench-perspective.model.d.ts +30 -21
  272. package/lib/popup/popup.config.d.ts +11 -10
  273. package/lib/popup/popup.service.d.ts +15 -28
  274. package/lib/portal/wb-component-portal.d.ts +21 -5
  275. package/lib/public_api.d.ts +1 -1
  276. package/lib/registry/workbench-object-registry.d.ts +10 -6
  277. package/lib/routing/public_api.d.ts +2 -2
  278. package/lib/routing/routing.model.d.ts +25 -13
  279. package/lib/routing/{router.util.d.ts → routing.util.d.ts} +28 -1
  280. package/lib/routing/{workbench-auxiliary-routes-registrator.service.d.ts → workbench-auxiliary-route-installer.service.d.ts} +10 -3
  281. package/lib/routing/workbench-layout-differ.d.ts +1 -2
  282. package/lib/routing/workbench-navigational-states.d.ts +8 -4
  283. package/lib/{view/workbench-view-route-guards.d.ts → routing/workbench-route-guards.d.ts} +8 -2
  284. package/lib/routing/workbench-url-observer.service.d.ts +31 -55
  285. package/lib/routing/workbench-view-outlet-differ.d.ts +32 -0
  286. package/lib/routing//311/265workbench-router.service.d.ts +22 -18
  287. package/lib/startup/workbench-launcher.service.d.ts +4 -5
  288. package/lib/testing/workbench.provider.d.ts +3 -1
  289. package/lib/theme/workbench-theme-switcher.service.d.ts +4 -6
  290. package/lib/view/public_api.d.ts +0 -1
  291. package/lib/view/view-move-handler.service.d.ts +16 -14
  292. package/lib/view/view-portal.pipe.d.ts +1 -3
  293. package/lib/view/view.component.d.ts +21 -12
  294. package/lib/view/workbench-view.model.d.ts +88 -36
  295. package/lib/view/workbench-view.registry.d.ts +3 -27
  296. package/lib/view//311/265workbench-view.model.d.ts +62 -71
  297. package/lib/view-dnd/view-drag.service.d.ts +79 -49
  298. package/lib/view-dnd/view-drop-placeholder-renderer.service.d.ts +1 -1
  299. package/lib/view-dnd/view-tab-drag-image-renderer.service.d.ts +12 -36
  300. package/lib/workbench-config.d.ts +19 -7
  301. package/lib/workbench.component.d.ts +16 -30
  302. package/lib/workbench.constants.d.ts +0 -5
  303. package/lib/workbench.model.d.ts +31 -3
  304. package/lib/workbench.service.d.ts +58 -56
  305. package/lib//311/265workbench.service.d.ts +18 -31
  306. package/package.json +12 -12
  307. package/esm2022/lib/common/filter-by-predicate.pipe.mjs +0 -27
  308. package/esm2022/lib/common/filter-by-text.pipe.mjs +0 -39
  309. package/esm2022/lib/common/uuid.util.mjs +0 -17
  310. package/esm2022/lib/content-projection/content-projection.directive.mjs +0 -101
  311. package/esm2022/lib/content-projection/view-container.reference.mjs +0 -68
  312. package/esm2022/lib/layout/migration/model/workbench-layout-migration-v1.model.mjs +0 -11
  313. package/esm2022/lib/layout/migration/workbench-layout-migration-v2.service.mjs +0 -59
  314. package/esm2022/lib/microfrontend-platform/routing/microfrontend-view-capability-id-assigner.interceptor.mjs +0 -41
  315. package/esm2022/lib/page-not-found/format-url.pipe.mjs +0 -26
  316. package/esm2022/lib/part/part-action-bar/part-action-filter.pipe.mjs +0 -26
  317. package/esm2022/lib/routing/router.util.mjs +0 -126
  318. package/esm2022/lib/routing/workbench-auxiliary-routes-registrator.service.mjs +0 -94
  319. package/esm2022/lib/view/workbench-view-route-guards.mjs +0 -47
  320. package/lib/common/filter-by-predicate.pipe.d.ts +0 -10
  321. package/lib/common/filter-by-text.pipe.d.ts +0 -12
  322. package/lib/common/uuid.util.d.ts +0 -8
  323. package/lib/content-projection/content-projection.directive.d.ts +0 -30
  324. package/lib/content-projection/view-container.reference.d.ts +0 -42
  325. package/lib/layout/migration/model/workbench-layout-migration-v1.model.d.ts +0 -16
  326. package/lib/microfrontend-platform/routing/microfrontend-view-capability-id-assigner.interceptor.d.ts +0 -10
  327. package/lib/page-not-found/format-url.pipe.d.ts +0 -11
  328. package/lib/part/part-action-bar/part-action-filter.pipe.d.ts +0 -11
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2018-2023 Swiss Federal Railways
2
+ * Copyright (c) 2018-2024 Swiss Federal Railways
3
3
  *
4
4
  * This program and the accompanying materials are made
5
5
  * available under the terms of the Eclipse Public License 2.0
@@ -7,43 +7,43 @@
7
7
  *
8
8
  * SPDX-License-Identifier: EPL-2.0
9
9
  */
10
- import { Component, ElementRef, HostListener, Inject, ViewChild, ViewChildren } from '@angular/core';
10
+ import { Component, computed, effect, ElementRef, HostListener, inject, NgZone, signal, untracked, viewChild, viewChildren } from '@angular/core';
11
11
  import { ViewTabComponent } from '../view-tab/view-tab.component';
12
- import { filter, map, mergeMap, startWith, switchMap, take, takeUntil } from 'rxjs/operators';
13
- import { animationFrameScheduler, BehaviorSubject, combineLatest, firstValueFrom, from, interval, Subject } from 'rxjs';
14
- import { ViewDragImageRect } from '../../view-dnd/view-tab-drag-image-renderer.service';
12
+ import { map, mergeMap, takeUntil } from 'rxjs/operators';
13
+ import { from, fromEvent, merge, Observable, Subject, timer } from 'rxjs';
14
+ import { ViewTabDragImageRenderer } from '../../view-dnd/view-tab-drag-image-renderer.service';
15
+ import { ViewDragService } from '../../view-dnd/view-drag.service';
15
16
  import { getCssTranslation, setCssClass, setCssVariable, unsetCssClass, unsetCssVariable } from '../../common/dom.util';
16
- import { filterArray, mapArray, observeInside, subscribeInside } from '@scion/toolkit/operators';
17
+ import { ɵWorkbenchPart } from '../ɵworkbench-part.model';
18
+ import { filterArray, subscribeIn } from '@scion/toolkit/operators';
17
19
  import { SciViewportComponent } from '@scion/components/viewport';
18
- import { SciDimensionModule } from '@scion/components/dimension';
19
- import { AsyncPipe, NgFor, NgIf } from '@angular/common';
20
+ import { ɵWorkbenchRouter } from '../../routing/ɵworkbench-router.service';
21
+ import { boundingClientRect, dimension } from '@scion/components/dimension';
20
22
  import { PartActionBarComponent } from '../part-action-bar/part-action-bar.component';
21
23
  import { ViewListButtonComponent } from '../view-list-button/view-list-button.component';
22
24
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
23
- import { fromDimension$ } from '@scion/toolkit/observable';
24
25
  import { WORKBENCH_ID } from '../../workbench-id';
26
+ import { clamp } from '../../common/math.util';
25
27
  import * as i0 from "@angular/core";
26
- import * as i1 from "../../layout/workbench-layout.service";
27
- import * as i2 from "../../routing/\u0275workbench-router.service";
28
- import * as i3 from "../../view-dnd/view-tab-drag-image-renderer.service";
29
- import * as i4 from "../\u0275workbench-part.model";
30
- import * as i5 from "../../view-dnd/view-drag.service";
31
- import * as i6 from "@scion/components/dimension";
32
28
  /**
33
29
  * Renders view tabs and actions of a {@link WorkbenchPart}.
34
30
  *
35
31
  * Tabs are added to a viewport, which the user can scroll if not enough space. The viewport grows with its tabs,
36
32
  * allowing actions to be placed directly after the last tab or on the right side.
37
33
  *
38
- * ## Drag Events
34
+ * ## Drag and Drop
35
+ * This component subscribes to drag events to visualize tabs during a drag operation. The drag operation is initiated in {@link ViewTabComponent}.
36
+ *
39
37
  * We use native drag and drop to support dragging views to other windows.
40
38
  *
41
- * By listening to drag events, the tabbar visualizes tabs during a drag operation. The drag operation is initiated in {@link ViewTabComponent}.
42
- * - `dragstart` and `dragend` events are fired in the tabbar where the drag operation was initiated.
43
- * - `dragenter` event is fired when a tab enters the tabbar.
44
- * - `dragover` events are fired when dragging a tab over the tabbar.
45
- * - `dragleave` event is fired when a tab leaves the tabbar.
46
- * - `drop` event is fired when the user drops a tab in the tabbar.
39
+ * Following events are triggered:
40
+ * - dragstart: when start dragging a tab (only received in the tabbar where the drag operation has started)
41
+ * - dragend: when end dragging a tab, either via drop or cancel (only received in the tabbar where the drag operation has started)
42
+ * - dragenter: when a tab enters the tabbar
43
+ * - dragover: when dragging a tab over the tabbar, every few hundred milliseconds
44
+ * - dragleave: when a tab leaves the tabbar
45
+ * - drop: when the user drops a tab in the tabbar
46
+ *
47
47
  * - Note that `dragleave` event is not fired on drop action. Therefore, always handle both events, `dragleave` and `drop` events, respectively.
48
48
  *
49
49
  * ## Terminology
@@ -53,34 +53,34 @@ import * as i6 from "@scion/components/dimension";
53
53
  * e.g., to snap the drag image to the tabbar when dragging near it.
54
54
  */
55
55
  export class PartBarComponent {
56
- set injectViewTabs(queryList) {
57
- queryList.changes
58
- .pipe(startWith(queryList), takeUntilDestroyed(this._destroyRef))
59
- .subscribe(queryList => this._viewTabs$.next(queryList.toArray()));
60
- }
61
- constructor(host, _workbenchId, _workbenchLayoutService, _router, _viewTabDragImageRenderer, _part, _viewDragService, _destroyRef, _zone) {
62
- this._workbenchId = _workbenchId;
63
- this._workbenchLayoutService = _workbenchLayoutService;
64
- this._router = _router;
65
- this._viewTabDragImageRenderer = _viewTabDragImageRenderer;
66
- this._part = _part;
67
- this._viewDragService = _viewDragService;
68
- this._destroyRef = _destroyRef;
69
- this._zone = _zone;
56
+ constructor() {
57
+ this._host = inject((ElementRef)).nativeElement;
70
58
  this._viewportChange$ = new Subject();
71
- this._viewTabs$ = new BehaviorSubject([]);
72
- this._dragenter$ = new Subject();
73
- this._dragleave$ = new Subject();
74
- this._dragend$ = new Subject();
59
+ this._workbenchId = inject(WORKBENCH_ID);
60
+ this._router = inject(ɵWorkbenchRouter);
61
+ this._viewTabDragImageRenderer = inject(ViewTabDragImageRenderer);
62
+ this._viewDragService = inject(ViewDragService);
63
+ this._zone = inject(NgZone);
64
+ this._viewTabs = viewChildren(ViewTabComponent);
65
+ this._hostBoundingClientRect = boundingClientRect(inject(ElementRef));
66
+ this._viewportComponent = viewChild.required(SciViewportComponent);
67
+ this._viewportComponentElement = viewChild.required(SciViewportComponent, { read: (ElementRef) });
68
+ this._tabCornerRadiusElement = viewChild.required('tab_corner_radius', { read: (ElementRef) });
69
+ this._paddingInlineElement = viewChild.required('padding_inline', { read: (ElementRef) });
70
+ this._fillerElement = viewChild.required('filler');
71
+ this._viewportBoundingBox = boundingClientRect(this._viewportComponentElement);
72
+ this.part = inject(ɵWorkbenchPart);
73
+ this.startActions = computed(() => this.part.actions().filter(action => action.align !== 'end'));
74
+ this.endActions = computed(() => this.part.actions().filter(action => action.align === 'end'));
75
75
  /**
76
76
  * Reference to the tab before which to insert the drag source on drop, or `end` if dropping it after the last tab.
77
77
  */
78
- this.dropTargetViewTab = null;
78
+ this.dropTargetViewTab = signal(null);
79
79
  /**
80
80
  * Reference to the tab where the drag operation was started.
81
81
  * This reference is only set if the drag operation started on a tab of this tabbar.
82
82
  */
83
- this.dragSourceViewTab = null;
83
+ this.dragSourceViewTab = signal(null);
84
84
  /**
85
85
  * Transfer data of the tab being dragged over this tabbar.
86
86
  */
@@ -89,6 +89,10 @@ export class PartBarComponent {
89
89
  * Function for snapping the drag image to the tabbar when dragging near it.
90
90
  */
91
91
  this._constrainFn = null;
92
+ /**
93
+ * Signals when unsetting drag state.
94
+ */
95
+ this._onUnsetDragState = signal(undefined, { equal: () => false });
92
96
  /**
93
97
  * Tabbar indents where to display the rounded bottom corners of the first and last view tab.
94
98
  */
@@ -96,171 +100,186 @@ export class PartBarComponent {
96
100
  left: 0,
97
101
  right: 0,
98
102
  };
99
- /**
100
- * Notifies when the drag animation has finished, i.e., tabs have transitioned to their final position.
101
- */
102
- this._dragAnimationStable$ = interval(0, animationFrameScheduler)
103
- .pipe(filter(() => this.isDragAnimationStable()), subscribeInside(continueFn => this._zone.runOutsideAngular(continueFn)), observeInside(continueFn => this._zone.run(continueFn)), map(() => undefined));
104
- this._host = host.nativeElement;
105
- this.dragover$ = this._viewDragService.tabbarDragOver$.pipe(map(partId => partId === this._part.id));
106
- }
107
- ngOnInit() {
103
+ this._maxViewportWidth = this.calculateMaxViewportWidth();
108
104
  this.installActiveViewScroller();
109
105
  this.installScrolledIntoViewUpdater();
110
106
  this.installViewDragListener();
111
- this.installTabbarIndentSizeDetector();
112
- this.installViewportClientSizeDetector();
107
+ this.installTabbarIndentSizeTracker();
108
+ this.installViewportChangeTracker();
113
109
  }
114
110
  onDoubleClick(event) {
115
- if (this._part.isInMainArea) {
111
+ if (this.part.isInMainArea) {
116
112
  this._router.navigate(layout => layout.toggleMaximized()).then();
117
113
  }
118
114
  event.stopPropagation();
119
115
  }
120
- get viewIds$() {
121
- return this._part.viewIds$;
122
- }
123
- onTabbarViewportDimensionChange() {
124
- this._viewportChange$.next();
125
- }
126
- onScroll() {
127
- this._viewportChange$.next();
128
- }
129
116
  /**
130
- * Method invoked when the user starts dragging a tab of this tabbar.
117
+ * Method invoked when the user starts dragging a tab of this tabbar, only in the tabbar where the drag started.
131
118
  */
132
- onViewDragStart(event) {
133
- if (!this._viewDragService.isViewDragEvent(event)) {
134
- return;
135
- }
136
- const dragData = this._viewDragService.viewDragData;
137
- const dragSourceIndex = this._viewTabs.findIndex(viewTab => viewTab.viewId === dragData.viewId);
138
- const dragSourceViewTab = this._viewTabs[dragSourceIndex];
139
- const dropTargetViewTab = this._viewTabs[dragSourceIndex + 1] ?? 'end';
140
- // Constrain function for snapping the drag image to the tabbar when dragging near it.
119
+ onTabDragStart() {
120
+ // Memoize drag data.
121
+ this._dragData = this._viewDragService.viewDragData();
122
+ // Indicate dragging over this tabbar.
123
+ this._viewDragService.signalTabbarDragEnter(this.part.id);
124
+ // Snap drag image to tabbar when dragging near it.
141
125
  this._constrainFn = this.createDragImageConstrainFn();
142
126
  this._viewTabDragImageRenderer.setConstrainDragImageRectFn(this._constrainFn);
143
- this._viewDragService.setTabbarDragover(this._part.id);
144
- // When start dragging a view tab, we remove it from the tabbar by setting its `display` to `none` and render its drag image in `ViewTabDragImageRenderer` instead.
145
- // However, do not unset the `display` of the drag source during `dragstart`. Otherwise, the native drag operation would be corrupted in Chrome and Edge (but not in Firefox).
146
- animationFrameScheduler.schedule(() => {
147
- this.dragSourceViewTab = dragSourceViewTab;
148
- this.dropTargetViewTab = dropTargetViewTab; // Set drop target to avoid tab animation.
149
- setCssVariable(this._host, {
150
- '--ɵpart-bar-drag-source-width': `${dragData.viewTabWidth}px`,
151
- '--ɵpart-bar-drag-image-placeholder-width': `${dragData.viewTabWidth}px`,
152
- });
153
- });
154
- // When dragging a tab very quickly out of this tabbar, only the `dragstart` event gets fired, but not the `dragenter` event.
155
- // Therefore, we subscribe to global `dragenter` events and manually invoke `onTabbarDragLeave` to correctly display the tabs and the active view.
156
- this._viewDragService.viewDrag$(window, { eventType: ['dragenter'] })
157
- .pipe(take(1), takeUntil(this._dragend$), takeUntilDestroyed(this._destroyRef))
127
+ // Disable pointer events to not break the drag operation (in Firefox, but not Chrome and Edge).
128
+ requestAnimationFrame(() => setCssClass(this._host, 'pointer-events-disabled'));
129
+ // Set CSS class to not animate start dragging.
130
+ setCssClass(this._host, 'on-drag-start');
131
+ this.onDragAnimationStable(() => unsetCssClass(this._host, 'on-drag-start'));
132
+ // Check if the user continues dragging over this tabbar.
133
+ // If not, the user has quickly dragged the tab out of the tabbar, so manually call `onTabbarDragEnter` and `onTabbarDragLeave`.
134
+ fromEvent(window, 'dragenter', { once: true })
135
+ .pipe(takeUntil(merge(fromEvent(this._host, 'dragenter'), fromEvent(this._host, 'dragend'))))
158
136
  .subscribe(event => {
159
- // Check if the user continues dragging over this tabbar.
160
- // If not, the user has quickly dragged the tab out of the tabbar and we manually call `onTabbarDragLeave`.
161
- if ((this._host.compareDocumentPosition(event.target) & Node.DOCUMENT_POSITION_CONTAINED_BY) === 0) {
162
- this.onTabbarDragLeave();
163
- }
137
+ this.onTabbarDragEnter(event);
138
+ this.onTabbarDragLeave(event);
164
139
  });
165
140
  }
166
141
  /**
167
- * Method invoked when the user ends dragging a tab of this tabbar.
168
- *
169
- * Invoked only in the tabbar where the drag operation started, regardless of whether the drag operation was completed or canceled.
142
+ * Method invoked when the user ends dragging a tab of this tabbar, either by drop or cancel, only in the tabbar where the drag started.
170
143
  */
171
- onViewDragEnd() {
172
- this._dragend$.next();
173
- this.unsetDragState();
144
+ onTabDragEnd(event) {
145
+ // Unset drag state only on cancel, not on drop, to prevent tabs from temporarily reverting to their pre-drag state. Drag state is reset in `onTabMoved` after a drop.
146
+ if (event.dataTransfer.dropEffect === 'none') {
147
+ // Reactivate the drag source view on cancel.
148
+ this.dragSourceViewTab()?.view().activate({ skipLocationChange: true }).then();
149
+ // Unset drag state.
150
+ this.unsetDragState();
151
+ }
152
+ }
153
+ /**
154
+ * Method invoked when the layout has changed after a drop. The drop may not be related to a tab of this tabbar.
155
+ */
156
+ onTabMoved(event) {
157
+ // Unset drag state only if no new drag has started since the drop.
158
+ if (this._dragData?.uid === event.dragData?.uid) {
159
+ this.unsetDragState();
160
+ }
174
161
  }
175
162
  /**
176
163
  * Method invoked when the user drags a tab into this tabbar.
177
164
  */
178
165
  onTabbarDragEnter(event) {
179
- this._dragenter$.next();
180
- this._viewDragService.setTabbarDragover(this._part.id);
181
- this._dragData = this._viewDragService.viewDragData;
182
- // Constrain function for snapping the drag image to the tabbar when dragging near it.
183
- if (!this._constrainFn) {
184
- this._constrainFn = this.createDragImageConstrainFn();
185
- this._viewTabDragImageRenderer.setConstrainDragImageRectFn(this._constrainFn);
166
+ // Memoize drag data.
167
+ const dragData = this._dragData = this._viewDragService.viewDragData();
168
+ // Indicate dragging over this tabbar.
169
+ this._viewDragService.signalTabbarDragEnter(this.part.id);
170
+ // Snap drag image to tabbar when dragging near it.
171
+ this._constrainFn = this.createDragImageConstrainFn();
172
+ this._viewTabDragImageRenderer.setConstrainDragImageRectFn(this._constrainFn);
173
+ // Set drag source, but only if started the drag operation in this part.
174
+ // We do not set the drag source in `dragstart` to not break the drag operation (in Chrome and Edge, but not Firefox).
175
+ if (this._host.classList.contains('on-drag-start')) {
176
+ this.dragSourceViewTab.set(this._viewTabs().find(viewTab => viewTab.viewId === dragData.viewId) ?? null);
177
+ setCssVariable(this._host, { '--ɵpart-bar-drag-placeholder-width': `${dragData.viewTabWidth}px` });
186
178
  }
187
- // Locate drop target to have a nice animation for the drag source placeholder.
188
- this.dropTargetViewTab = this.computeDropTarget(event);
189
- // Set the CSS class 'drag-enter' to indicate entering the tabbar.
190
- setCssClass(this._host, 'drag-enter', 'drag-over');
191
- this._dragAnimationStable$
192
- .pipe(take(1), takeUntil(this._dragenter$), takeUntilDestroyed(this._destroyRef))
193
- .subscribe({ complete: () => unsetCssClass(this._host, 'drag-enter') });
194
- setCssVariable(this._host, {
195
- '--ɵpart-bar-drag-source-width': `${this._dragData.viewTabWidth}px`,
196
- '--ɵpart-bar-drag-image-placeholder-width': `${this._dragData.viewTabWidth}px`,
197
- });
179
+ // Locate the tab the user is dragging over.
180
+ this.dropTargetViewTab.set(this.computeDropTarget(event));
181
+ // Disable pointer events on the tabbar for a smoother drag and drop experience when quickly swapping tabs.
182
+ setCssClass(this._host, 'pointer-events-disabled');
183
+ // Set CSS class to animate entering the tabbar.
184
+ setCssClass(this._host, 'on-drag-enter');
185
+ this.onDragAnimationStable(() => unsetCssClass(this._host, 'on-drag-enter'));
186
+ // Inject drag source width into CSS.
187
+ setCssVariable(this._host, { '--ɵpart-bar-drag-source-width': `${dragData.viewTabWidth}px` });
198
188
  }
199
189
  /**
200
190
  * Method invoked when the user drags a tab out of this tabbar.
201
191
  */
202
- onTabbarDragLeave() {
203
- this._dragleave$.next();
204
- // Set the CSS class 'drag-leave' to indicate leaving the tabbar.
205
- setCssClass(this._host, 'drag-leave');
206
- this._dragAnimationStable$
207
- .pipe(take(1), takeUntil(this._dragleave$), takeUntilDestroyed(this._destroyRef))
208
- .subscribe({ complete: () => unsetCssClass(this._host, 'drag-leave') });
209
- this.unsetDragState({ unsetDragSource: false });
210
- // Activate the view next to the view being dragged out of this tabbar. But, do not push the navigation into browsing history stack.
211
- if (this.dragSourceViewTab && this.dragSourceViewTab.active) {
212
- this._router.navigate(layout => layout.activateAdjacentView(this.dragSourceViewTab.viewId), { skipLocationChange: true }).then();
192
+ onTabbarDragLeave(event) {
193
+ // Set CSS class to animate leaving the tabbar, but not when canceling the drag operation for instant reset.
194
+ // Pointer coordinates are not set when the drag operation is canceled or when dragging the tab out of the window.
195
+ if (event.screenX || event.screenY) {
196
+ setCssClass(this._host, 'on-drag-leave');
197
+ this.onDragAnimationStable(() => unsetCssClass(this._host, 'on-drag-leave'));
213
198
  }
199
+ // Activate the adjacent tab, only if the drag operation is not canceled.
200
+ // The drag event does not provide information about cancelation. Therefore, we wait for a macrotask, canceling it when receiving `dragend`, i.e., the drag operation has been canceled.
201
+ if (this.dragSourceViewTab()?.active) {
202
+ timer(0)
203
+ .pipe(takeUntil(fromEvent(window, 'dragend')))
204
+ .subscribe(() => this._router.navigate(layout => layout.activateAdjacentView(this.dragSourceViewTab().viewId), { skipLocationChange: true }));
205
+ }
206
+ // Clean up drag state.
207
+ this.unsetDragState({ unsetDragSource: false, unsetDragData: false });
214
208
  }
215
209
  /**
216
- * Method invoked while the user is dragging a tab over this tabbar.
210
+ * Method invoked when the user is dragging a tab over this tabbar.
217
211
  */
218
- onTabbarDragOver(event) {
212
+ onTabbarDragOver(event, dragDistance, scrollDistance) {
213
+ NgZone.assertNotInAngularZone();
219
214
  event.preventDefault(); // allow view drop
220
- // Locate the tab over which the user is dragging the tab, but only after pending transitions have ended to prevent tabs from sliding back and forth.
221
- if (this.isDragAnimationStable()) {
222
- this.dropTargetViewTab = this.computeDropTarget(event);
223
- // Synchronize the width of the drag source placeholder with the drag pointer position to move actions along with the pointer.
224
- setCssVariable(this._host, { '--ɵpart-bar-drag-image-placeholder-width': `${this.calculateDragImagePlaceholderWidth(event)}px` });
225
- }
215
+ // Locate the tab the user is dragging over.
216
+ // - Run in animation frame for better performance, most noticeable on lower CPU power.
217
+ // - Do not wait for the drag animation to complete for a smoother drag and drop experience when quickly moving the tab in the tabbar.
218
+ requestAnimationFrame(() => {
219
+ // Skip if the drag operation has ended.
220
+ if (this._viewDragService.isDragOverTabbar !== this.part.id) {
221
+ return;
222
+ }
223
+ // Ignore the drag distance if `drag-enter` animation is in progress to avoid incorrect drop target computation when dragging a tab from the left.
224
+ if (this._host.classList.contains('on-drag-enter')) {
225
+ this.dropTargetViewTab.set(this.computeDropTarget(event, 0));
226
+ }
227
+ // Compute drop target only when moving the drag pointer to prevent tabs from sliding back and forth (while animation is in progress)
228
+ else if (dragDistance) {
229
+ this.dropTargetViewTab.set(this.computeDropTarget(event, dragDistance));
230
+ }
231
+ // Compute drop target when scrolling the viewport, i.e., not moving the drag pointer but scrolling the viewport because placed the drag pointer at the viewport edges.
232
+ else if (scrollDistance) {
233
+ this.dropTargetViewTab.set(this.computeDropTarget(event, scrollDistance));
234
+ }
235
+ // Set CSS class to animate dragging over the tabbar.
236
+ setCssClass(this._host, 'drag-over');
237
+ // Calculate the new size of the drag source placeholder.
238
+ // The placeholder expands the viewport when dragging a tab to the right, moving part actions along with the dragover event.
239
+ setCssVariable(this._host, { '--ɵpart-bar-drag-placeholder-width': `${this.calculateDragPlaceholderWidth(event)}px` });
240
+ });
226
241
  }
227
242
  /**
228
243
  * Method invoked when the user drops a tab in this tabbar.
229
244
  */
230
- onTabbarDrop() {
245
+ async onTabbarDrop() {
246
+ const dragData = this._dragData;
247
+ const dropTargetViewTab = this.dropTargetViewTab();
248
+ const dropPosition = dropTargetViewTab === 'end' ? 'end' : this._viewTabs().indexOf(dropTargetViewTab);
231
249
  this._viewDragService.dispatchViewMoveEvent({
232
250
  source: {
233
- workbenchId: this._dragData.workbenchId,
234
- partId: this._dragData.partId,
235
- viewId: this._dragData.viewId,
236
- alternativeViewId: this._dragData.alternativeViewId,
237
- viewUrlSegments: this._dragData.viewUrlSegments,
238
- navigationHint: this._dragData.navigationHint,
239
- classList: this._dragData.classList,
251
+ workbenchId: dragData.workbenchId,
252
+ partId: dragData.partId,
253
+ viewId: dragData.viewId,
254
+ alternativeViewId: dragData.alternativeViewId,
255
+ viewUrlSegments: dragData.viewUrlSegments,
256
+ navigationHint: dragData.navigationHint,
257
+ navigationData: dragData.navigationData,
258
+ classList: dragData.classList,
240
259
  },
241
260
  target: {
242
261
  workbenchId: this._workbenchId,
243
- position: this.dropTargetViewTab === 'end' ? 'end' : this._viewTabs.indexOf(this.dropTargetViewTab),
244
- elementId: this._part.id,
262
+ position: dropPosition,
263
+ elementId: this.part.id,
245
264
  },
246
- });
247
- // Wait undoing the drag state until flushed tab changes to the DOM, i.e., after the layout routing cycle completes.
248
- // If we were to undo the drag state immediately during the course of the drop event, the tab layout would temporarily
249
- // revert to the state before the drag operation, resulting in an ugly flicker.
250
- firstValueFrom(this._workbenchLayoutService.onLayoutChange$).then(() => {
251
- this.unsetDragState();
265
+ dragData: dragData,
252
266
  });
253
267
  }
254
268
  /**
255
269
  * Locates the tab before which the dragged tab is to be inserted when it is dropped. Dragging beyond the last tab returns `end`.
256
270
  */
257
- computeDropTarget(event) {
258
- const viewDragImageRect = this._viewTabDragImageRenderer.calculateDragImageRect(this._dragData, event);
259
- const viewTabs = this._viewTabs.filter(viewTab => viewTab !== this.dragSourceViewTab);
271
+ computeDropTarget(event, dragDistanceX = 0) {
272
+ const dragImage = this._viewTabDragImageRenderer.calculateDragImageRect(this._dragData, event);
273
+ const viewTabs = this._viewTabs().filter(viewTab => viewTab !== this.dragSourceViewTab());
260
274
  for (const viewTab of viewTabs) {
261
- const viewTabRect = viewTab.host.getBoundingClientRect();
262
- const viewTabMiddle = viewTabRect.left + (viewTabRect.width / 2);
263
- if (viewDragImageRect.left < viewTabMiddle && (viewTab !== this.dropTargetViewTab || viewDragImageRect.right < viewTabMiddle)) {
275
+ const { left, width } = viewTab.boundingClientRect();
276
+ const viewTabHCenter = left + (width / 2);
277
+ // Moving the pointer to the left.
278
+ if (dragDistanceX <= 0 && dragImage.left < viewTabHCenter) {
279
+ return viewTab;
280
+ }
281
+ // Moving the pinter to the right.
282
+ if (dragDistanceX > 0 && dragImage.right < viewTabHCenter) {
264
283
  return viewTab;
265
284
  }
266
285
  }
@@ -270,49 +289,32 @@ export class PartBarComponent {
270
289
  * Creates the function for snapping the drag image to the tabbar when dragging near it.
271
290
  */
272
291
  createDragImageConstrainFn() {
273
- const hostLeft = this._host.getBoundingClientRect().left;
274
- const maxViewportWidth = this.calculateMaxViewportWidth();
275
- return (rect) => {
276
- const viewportBoundingBox = this._viewportElement.nativeElement.getBoundingClientRect();
277
- return new ViewDragImageRect({
278
- x: Math.min(Math.max(hostLeft + this._tabbarIndent.left, rect.x), hostLeft + maxViewportWidth - rect.width - this._tabbarIndent.right),
279
- y: viewportBoundingBox.top,
280
- width: rect.width,
281
- height: viewportBoundingBox.height, // fit into tabbar, e.g., when dragging a tab into a tabbar of a different height
282
- });
283
- };
292
+ return (dragImage) => new DOMRect(clamp(dragImage.x, {
293
+ min: this._hostBoundingClientRect().left + this._tabbarIndent.left,
294
+ max: this._hostBoundingClientRect().left + this._maxViewportWidth() - dragImage.width - this._tabbarIndent.right,
295
+ }), this._viewportBoundingBox().top, dragImage.width, this._viewportBoundingBox().height);
284
296
  }
285
297
  /**
286
- * Calculates the maximum width of the tabbar viewport before an overflow would occur, which can then be used to constrain the drag image.
287
- *
288
- * To calculate the effective width, we need to simulate an overflow in the DOM. Therefore, call this method only from `dragstart` and not
289
- * from `dragover` and disable animations.
298
+ * Calculates the maximum width of the tabbar viewport before an overflow would occur.
299
+ * Use to constrain the drag image to the tabbar bounds.
290
300
  */
291
301
  calculateMaxViewportWidth() {
292
- const currentWidth = this._host.style.getPropertyValue('--ɵpart-bar-drag-image-placeholder-width');
293
- // Disable animations during calculation and force the viewport to overflow.
294
- setCssClass(this._host, 'calculating-max-viewport-width');
295
- setCssVariable(this._host, { '--ɵpart-bar-drag-image-placeholder-width': `${this._host.clientWidth}px` });
296
- try {
297
- return this._viewportElement.nativeElement.getBoundingClientRect().width;
298
- }
299
- finally {
300
- setCssVariable(this._host, { '--ɵpart-bar-drag-image-placeholder-width': currentWidth || null });
301
- unsetCssClass(this._host, 'calculating-max-viewport-width');
302
- }
302
+ const fillerDimension = dimension(this._fillerElement);
303
+ return computed(() => this._viewportBoundingBox().width + fillerDimension().offsetWidth);
303
304
  }
304
305
  /**
305
- * Calculates the width for the drag image placeholder.
306
+ * Calculates the width for the drag placeholder.
306
307
  *
308
+ * The placeholder expands the viewport when dragging a tab to the right, moving part actions along with the dragover event.
309
+ *
310
+ * Calculation:
307
311
  * - When dragging over tabs, the width is equal to the width of the drag source.
308
- * - When dragging to the right of the last tab, the width of the placeholder is calculated as the distance between the
309
- * last tab and the position of the dragover event. Applying this width will resize the viewport, moving part actions along
310
- * with the dragover event.
312
+ * - When dragging to the right of the last tab, the width of the placeholder is the distance between the last tab and the position of the drag pointer.
311
313
  */
312
- calculateDragImagePlaceholderWidth(event) {
314
+ calculateDragPlaceholderWidth(event) {
313
315
  const viewDragImageRect = this._viewTabDragImageRenderer.calculateDragImageRect(this._dragData, event);
314
- const lastViewTab = this._viewTabs.filter(viewTab => viewTab !== this.dragSourceViewTab).at(-1);
315
- const lastViewTabRight = lastViewTab?.host.getBoundingClientRect().right ?? this._host.getBoundingClientRect().left + this._tabbarIndent.left;
316
+ const lastViewTab = this._viewTabs().filter(viewTab => viewTab !== this.dragSourceViewTab()).at(-1);
317
+ const lastViewTabRight = lastViewTab?.boundingClientRect().right ?? this._hostBoundingClientRect().left + this._tabbarIndent.left;
316
318
  return Math.max(lastViewTabRight + viewDragImageRect.width, viewDragImageRect.right) - lastViewTabRight;
317
319
  }
318
320
  /**
@@ -320,11 +322,12 @@ export class PartBarComponent {
320
322
  * The animation is considered stable when all tabs have moved to their final position.
321
323
  */
322
324
  isDragAnimationStable() {
323
- if (!this.dropTargetViewTab) {
324
- return this._viewTabs.every(viewTab => getCssTranslation(viewTab.host).translateX === 'none');
325
+ const dropTargetViewTab = this.dropTargetViewTab();
326
+ if (this._viewDragService.isDragOverTabbar !== this.part.id) {
327
+ return this._viewTabs().every(viewTab => getCssTranslation(viewTab.host).translateX === 'none');
325
328
  }
326
- const viewTabs = this._viewTabs.filter(viewTab => viewTab !== this.dragSourceViewTab);
327
- const dropTargetIndex = this.dropTargetViewTab === 'end' ? viewTabs.length : viewTabs.indexOf(this.dropTargetViewTab);
329
+ const viewTabs = this._viewTabs().filter(viewTab => viewTab !== this.dragSourceViewTab());
330
+ const dropTargetIndex = dropTargetViewTab === 'end' ? viewTabs.length : viewTabs.indexOf(dropTargetViewTab);
328
331
  const dragSourceWidth = this._dragData.viewTabWidth;
329
332
  return viewTabs.every((viewTab, i) => {
330
333
  const viewTabTranslateX = getCssTranslation(viewTab.host).translateX;
@@ -339,33 +342,63 @@ export class PartBarComponent {
339
342
  return true;
340
343
  });
341
344
  }
345
+ /**
346
+ * Cleans up the drag state, unsetting drag data and drag source based on provided options.
347
+ */
342
348
  unsetDragState(options) {
343
- if (options?.unsetDragSource ?? true) {
344
- this.dragSourceViewTab = null;
345
- }
346
- this.dropTargetViewTab = null;
347
- this._dragData = null;
349
+ this.dropTargetViewTab.set(null);
350
+ this._onUnsetDragState.set();
348
351
  this._viewTabDragImageRenderer.unsetConstrainDragImageRectFn(this._constrainFn);
352
+ this._viewDragService.signalTabbarDragLeave(this.part.id);
349
353
  this._constrainFn = null;
350
- unsetCssClass(this._host, 'drag-over');
351
- unsetCssVariable(this._host, '--ɵpart-bar-drag-source-width', '--ɵpart-bar-drag-image-placeholder-width');
352
- this._viewDragService.unsetTabbarDragover(this._part.id);
354
+ unsetCssClass(this._host, 'drag-over', 'pointer-events-disabled');
355
+ unsetCssVariable(this._host, '--ɵpart-bar-drag-source-width', '--ɵpart-bar-drag-placeholder-width');
356
+ if (options?.unsetDragSource ?? true) {
357
+ this.dragSourceViewTab.set(null);
358
+ }
359
+ if (options?.unsetDragData ?? true) {
360
+ this._dragData = null;
361
+ }
353
362
  }
354
- get _viewTabs() {
355
- return this._viewTabs$.value;
363
+ /**
364
+ * Executes given function when the drag animation has finished, i.e., tabs have transitioned to their final position.
365
+ */
366
+ onDragAnimationStable(callback) {
367
+ if (NgZone.isInAngularZone()) {
368
+ this._zone.runOutsideAngular(() => this.onDragAnimationStable(callback));
369
+ return;
370
+ }
371
+ requestAnimationFrame(() => this.isDragAnimationStable() ? callback() : this.onDragAnimationStable(callback));
356
372
  }
357
373
  /**
358
374
  * Scrolls the tab of the active view into view.
359
375
  */
360
376
  installActiveViewScroller() {
361
- this._viewTabs$
362
- .pipe(switchMap(viewTabs => combineLatest(viewTabs.map(viewTab => viewTab.view.active$))), takeUntilDestroyed(this._destroyRef))
363
- .subscribe(() => {
364
- // There may be no active view in the tabbar, e.g., when dragging the last view out of the tabbar.
365
- const activeViewTab = this._viewTabs.find(viewTab => viewTab.active);
366
- if (activeViewTab && !this._viewportComponent.isElementInView(activeViewTab.host, 'full')) {
367
- this._viewportComponent.scrollIntoView(activeViewTab.host);
377
+ effect(() => {
378
+ // Track the active view.
379
+ const activeViewId = this.part.activeViewId();
380
+ // There may be no active view, e.g., if no view has been activated, or when dragging the last view out of the tabbar.
381
+ if (!activeViewId) {
382
+ return;
368
383
  }
384
+ // Do not track rendered tabs in general to prevent unwanted scrolling when opening or closing inactive tabs.
385
+ const viewTabs = untracked(() => this._viewTabs());
386
+ // Get a reference to the currently rendered active tab, waiting if necessary by tracking the rendered tabs.
387
+ const activeViewTab = viewTabs.find(viewTab => viewTab.viewId === activeViewId);
388
+ if (!activeViewTab) {
389
+ this._viewTabs(); // Track rendered tabs to re-execute once rendered.
390
+ return;
391
+ }
392
+ // Track navigation of the active view, scrolling its tab into view if necessary.
393
+ activeViewTab.view().navigationId();
394
+ // Track unsetting drag state to ensure the active view is scrolled into view after drop or cancel.
395
+ this._onUnsetDragState();
396
+ // Scroll the tab into view if scrolled out of view.
397
+ untracked(() => requestAnimationFrame(() => {
398
+ if (!this._viewportComponent().isElementInView(activeViewTab.host, 'full')) {
399
+ this._viewportComponent().scrollIntoView(activeViewTab.host);
400
+ }
401
+ }));
369
402
  });
370
403
  }
371
404
  /**
@@ -373,87 +406,123 @@ export class PartBarComponent {
373
406
  */
374
407
  installScrolledIntoViewUpdater() {
375
408
  this._viewportChange$
376
- .pipe(map(() => this._viewTabs), filterArray(viewTab => viewTab !== this.dragSourceViewTab), // skip drag source as always scrolled out of view
377
- mergeMap(viewTabs => from(viewTabs)), takeUntilDestroyed(this._destroyRef))
409
+ .pipe(map(() => this._viewTabs()), filterArray(viewTab => viewTab !== this.dragSourceViewTab()), // skip drag source as always scrolled out of view
410
+ mergeMap(viewTabs => from(viewTabs)), takeUntilDestroyed())
378
411
  .subscribe(viewTab => {
379
- viewTab.view.scrolledIntoView = this._viewportComponent.isElementInView(viewTab.host, 'full');
412
+ viewTab.view().scrolledIntoView = this._viewportComponent().isElementInView(viewTab.host, 'full');
380
413
  });
381
414
  }
415
+ /**
416
+ * Subscribes to drag events.
417
+ */
382
418
  installViewDragListener() {
419
+ const zone = inject(NgZone);
420
+ // Subscribe to drag events relevant for this tabbar.
383
421
  this._viewDragService.viewDrag$(this._host)
384
- .pipe(takeUntilDestroyed(this._destroyRef))
385
- .subscribe((event) => {
422
+ .pipe(subscribeIn(fn => zone.runOutsideAngular(fn)), calculateDistance(() => this._viewportComponent()), // provide viewport lazily because not injected yet
423
+ takeUntilDestroyed())
424
+ .subscribe(({ event, dragDistance, scrollDistance }) => {
386
425
  switch (event.type) {
426
+ case 'dragstart':
427
+ this.onTabDragStart();
428
+ break;
429
+ case 'dragend':
430
+ this.onTabDragEnd(event);
431
+ break;
387
432
  case 'dragenter':
388
433
  this.onTabbarDragEnter(event);
389
434
  break;
390
435
  case 'dragover':
391
- this.onTabbarDragOver(event);
436
+ this.onTabbarDragOver(event, dragDistance, scrollDistance);
392
437
  break;
393
438
  case 'dragleave':
394
- this.onTabbarDragLeave();
439
+ this.onTabbarDragLeave(event);
395
440
  break;
396
441
  case 'drop':
397
- this.onTabbarDrop();
442
+ this.onTabbarDrop().then();
398
443
  break;
399
444
  }
400
445
  });
446
+ // Get notified when a view has moved in the layout.
447
+ this._viewDragService.viewMoved$
448
+ .pipe(subscribeIn(fn => zone.runOutsideAngular(fn)), takeUntilDestroyed())
449
+ .subscribe(event => this.onTabMoved(event));
450
+ /**
451
+ * Calculates the distance the drag pointer and viewport have moved since the last drag event.
452
+ */
453
+ function calculateDistance(viewport) {
454
+ return source$ => new Observable(observer => {
455
+ let lastScreenX;
456
+ let lastScrollLeft;
457
+ const subscription = source$.subscribe(event => {
458
+ observer.next({
459
+ event,
460
+ dragDistance: event.screenX - (lastScreenX ?? event.screenX),
461
+ scrollDistance: viewport().scrollLeft - (lastScrollLeft ?? viewport().scrollLeft),
462
+ });
463
+ lastScreenX = event.screenX;
464
+ lastScrollLeft = viewport().scrollLeft;
465
+ });
466
+ return () => subscription.unsubscribe();
467
+ });
468
+ }
401
469
  }
402
- installViewportClientSizeDetector() {
403
- fromDimension$(this._viewportComponent.viewportClientElement)
404
- .pipe(subscribeInside(fn => this._zone.run(fn)), takeUntilDestroyed(this._destroyRef))
405
- .subscribe(() => this._viewportChange$.next());
470
+ /**
471
+ * Emits on {@link _viewportChange$} when the viewport size or scroll position changes.
472
+ */
473
+ installViewportChangeTracker() {
474
+ const viewportSize = dimension(computed(() => this._viewportComponentElement().nativeElement));
475
+ const viewportClientSize = dimension(computed(() => this._viewportComponent().viewportClientElement));
476
+ const zone = inject(NgZone);
477
+ // Detect resizing.
478
+ effect(() => {
479
+ // Track viewport and viewport client sizes.
480
+ viewportSize();
481
+ viewportClientSize();
482
+ untracked(() => this._viewportChange$.next());
483
+ });
484
+ // Detect scrolling.
485
+ effect(onCleanup => {
486
+ const viewport = this._viewportComponent().viewportElement;
487
+ untracked(() => {
488
+ const subscription = fromEvent(viewport, 'scroll')
489
+ .pipe(subscribeIn(fn => zone.runOutsideAngular(fn)))
490
+ .subscribe(() => this._viewportChange$.next());
491
+ onCleanup(() => subscription.unsubscribe());
492
+ });
493
+ });
406
494
  }
407
- installTabbarIndentSizeDetector() {
408
- combineLatest([fromDimension$(this._tabCornerRadiusElement.nativeElement), fromDimension$(this._paddingInlineElement.nativeElement)])
409
- .pipe(subscribeInside(fn => this._zone.runOutsideAngular(fn)), mapArray(dimension => dimension.clientWidth), takeUntilDestroyed(this._destroyRef))
410
- .subscribe(([tabCornerRadius, paddingInline]) => {
411
- this._tabbarIndent = { left: tabCornerRadius + paddingInline, right: tabCornerRadius + paddingInline };
412
- setCssVariable(this._host, { '--ɵpart-bar-indent-left': `${this._tabbarIndent.left}px` });
413
- setCssVariable(this._host, { '--ɵpart-bar-indent-right': `${this._tabbarIndent.right}px` });
495
+ /**
496
+ * Tracks the tabbar indents.
497
+ */
498
+ installTabbarIndentSizeTracker() {
499
+ const tabCornerRadiusDimension = dimension(this._tabCornerRadiusElement);
500
+ const paddingInlineDimension = dimension(this._paddingInlineElement);
501
+ effect(() => {
502
+ const indent = tabCornerRadiusDimension().clientWidth + paddingInlineDimension().clientWidth;
503
+ this._tabbarIndent = { left: indent, right: indent };
504
+ setCssVariable(this._host, {
505
+ '--ɵpart-bar-indent-left': `${this._tabbarIndent.left}px`,
506
+ '--ɵpart-bar-indent-right': `${this._tabbarIndent.right}px`,
507
+ });
414
508
  });
415
509
  }
416
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: PartBarComponent, deps: [{ token: i0.ElementRef }, { token: WORKBENCH_ID }, { token: i1.WorkbenchLayoutService }, { token: i2.ɵWorkbenchRouter }, { token: i3.ViewTabDragImageRenderer }, { token: i4.ɵWorkbenchPart }, { token: i5.ViewDragService }, { token: i0.DestroyRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
417
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: PartBarComponent, isStandalone: true, selector: "wb-part-bar", host: { listeners: { "dblclick": "onDoubleClick($event)", "dragstart": "onViewDragStart($event)", "dragend": "onViewDragEnd()" } }, viewQueries: [{ propertyName: "_viewportElement", first: true, predicate: SciViewportComponent, descendants: true, read: ElementRef, static: true }, { propertyName: "_viewportComponent", first: true, predicate: SciViewportComponent, descendants: true, static: true }, { propertyName: "_tabCornerRadiusElement", first: true, predicate: ["tab_corner_radius"], descendants: true, static: true }, { propertyName: "_paddingInlineElement", first: true, predicate: ["padding_inline"], descendants: true, static: true }, { propertyName: "injectViewTabs", predicate: ViewTabComponent, descendants: true }], ngImport: i0, template: "<sci-viewport class=\"tabbar\" scrollbarStyle=\"hidden\"\n [class.dragover]=\"dragover$ | async\"\n sciDimension (sciDimensionChange)=\"onTabbarViewportDimensionChange()\"\n (scroll)=\"onScroll()\">\n <ng-container *ngFor=\"let viewId of viewIds$ | async;\">\n <div class=\"divider\" *ngIf=\"viewtab === dropTargetViewTab\"></div>\n <wb-view-tab #viewtab\n [viewId]=\"viewId\"\n [class.drag-source]=\"viewtab === dragSourceViewTab\"\n [class.drop-target]=\"viewtab === dropTargetViewTab\">\n </wb-view-tab>\n <div class=\"divider\"></div>\n </ng-container>\n\n <!-- Placeholder element to grow the viewport to fit the drag image. -->\n <div class=\"drag-image-placeholder\"></div>\n</sci-viewport>\n<wb-part-action-bar/>\n<wb-view-list-button/>\n\n<!-- Element for injecting the corner radius into the component. -->\n<div class=\"tab-corner-radius\" #tab_corner_radius></div>\n<!-- Element for injecting the tabbar padding into the component. -->\n<div class=\"padding-inline\" #padding_inline></div>\n", styles: ["@charset \"UTF-8\";:host{--\\275part-bar-indent-left: 0;--\\275part-bar-indent-right: 0;--\\275part-bar-drag-source-width: 0;--\\275part-bar-drag-image-placeholder-width: 0;display:flex;color:var(--sci-workbench-tab-text-color);background-color:var(--sci-workbench-part-bar-background-color);border-top:var(--sci-workbench-part-bar-padding-top) solid transparent;background-clip:border-box;height:var(--sci-workbench-tab-height);box-sizing:content-box;position:relative;container-name:viewtab;container-type:size}wb-workbench:has(wb-main-area-layout) wb-part:not(.main-area) :host{background-color:var(--sci-workbench-part-peripheral-bar-background-color)}:host>sci-viewport.tabbar{flex:initial}:host>sci-viewport.tabbar::part(content){display:flex;padding-left:var(--\\275part-bar-indent-left);padding-right:var(--\\275part-bar-indent-right)}:host>sci-viewport.tabbar:not(.dragover):not(:has(wb-view-tab:not(.drag-source)))::part(content){padding-right:0}:host>sci-viewport.tabbar>wb-view-tab{flex:none}:host>sci-viewport.tabbar>wb-view-tab.drag-source{display:none}:host>sci-viewport.tabbar>div.divider{flex:none;display:flex;position:relative;width:0}:host>sci-viewport.tabbar>div.divider:after{flex:none;align-self:center;content:\"\";position:absolute;width:1px;left:-1px;height:65%;background-color:var(--sci-workbench-part-bar-divider-color)}:host>sci-viewport.tabbar>div.drag-image-placeholder{flex:none;width:var(--\\275part-bar-drag-image-placeholder-width)}:host>sci-viewport.tabbar>wb-view-tab.drop-target,:host>sci-viewport.tabbar wb-view-tab.drop-target~:is(wb-view-tab,div.divider),:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.drop-target){transform:translate(var(--\\275part-bar-drag-source-width))}:host>sci-viewport.tabbar>wb-view-tab:is(.active,.drag-source)+div.divider{display:none}:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.active:not(.drag-source)){display:none}:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.drag-source:not(.active)){display:none}:host>wb-part-action-bar{flex:auto}:host>wb-view-list-button{flex:none}:host:before{content:\"\";position:absolute;bottom:0;left:0;right:0;height:1px;background-color:var(--sci-workbench-tab-border-color)}:host>div.tab-corner-radius{position:absolute;visibility:hidden;width:var(--sci-workbench-tab-border-radius)}:host>div.padding-inline{position:absolute;visibility:hidden;width:var(--sci-workbench-part-bar-padding-inline)}:host:not(.calculating-max-viewport-width).drag-enter wb-view-tab,:host:not(.calculating-max-viewport-width).drag-enter div.divider,:host:not(.calculating-max-viewport-width).drag-over wb-view-tab,:host:not(.calculating-max-viewport-width).drag-over div.divider,:host:not(.calculating-max-viewport-width).drag-leave wb-view-tab,:host:not(.calculating-max-viewport-width).drag-leave div.divider{transition:transform 175ms cubic-bezier(0,0,.2,1)}:host:not(.calculating-max-viewport-width).drag-enter div.drag-image-placeholder,:host:not(.calculating-max-viewport-width).drag-leave div.drag-image-placeholder{transition:width 175ms cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: SciViewportComponent, selector: "sci-viewport", inputs: ["scrollbarStyle"], outputs: ["scroll"] }, { kind: "ngmodule", type: SciDimensionModule }, { kind: "directive", type: i6.SciDimensionDirective, selector: "[sciDimension]", inputs: ["emitOutsideAngular"], outputs: ["sciDimensionChange"], exportAs: ["sciDimension"] }, { kind: "component", type: ViewTabComponent, selector: "wb-view-tab", inputs: ["viewId"] }, { kind: "component", type: PartActionBarComponent, selector: "wb-part-action-bar" }, { kind: "component", type: ViewListButtonComponent, selector: "wb-view-list-button" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
510
+ ngOnDestroy() {
511
+ this.unsetDragState();
512
+ }
513
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: PartBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
514
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.2", type: PartBarComponent, isStandalone: true, selector: "wb-part-bar", host: { listeners: { "dblclick": "onDoubleClick($event)" } }, viewQueries: [{ propertyName: "_viewTabs", predicate: ViewTabComponent, descendants: true, isSignal: true }, { propertyName: "_viewportComponent", first: true, predicate: SciViewportComponent, descendants: true, isSignal: true }, { propertyName: "_viewportComponentElement", first: true, predicate: SciViewportComponent, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_tabCornerRadiusElement", first: true, predicate: ["tab_corner_radius"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_paddingInlineElement", first: true, predicate: ["padding_inline"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_fillerElement", first: true, predicate: ["filler"], descendants: true, isSignal: true }], ngImport: i0, template: "<sci-viewport class=\"tabbar e2e-tabbar\" scrollbarStyle=\"hidden\">\n @for (viewId of part.viewIds(); track viewId) {\n @if (viewtab === dropTargetViewTab()) {\n <div class=\"divider\"></div>\n }\n <wb-view-tab #viewtab\n [viewId]=\"viewId\"\n [class.drag-source]=\"viewtab === dragSourceViewTab()\"\n [class.drop-target]=\"viewtab === dropTargetViewTab()\"/>\n <div class=\"divider\"></div>\n }\n\n <!-- Placeholder for expanding the viewport when dragging a tab to the right, moving part actions along with the dragover event. -->\n <div class=\"drag-placeholder\"></div>\n</sci-viewport>\n\n<!-- Actions -->\n@if (startActions().length) {\n <wb-part-action-bar [actions]=\"startActions()\" class=\"start\"/>\n}\n<div class=\"filler\" #filler></div>\n@if (endActions().length) {\n <wb-part-action-bar [actions]=\"endActions()\" class=\"end\"/>\n}\n\n<!-- View List Dropdown -->\n<wb-view-list-button/>\n\n<!-- Element for injecting the corner radius into the component. -->\n<div class=\"tab-corner-radius\" #tab_corner_radius></div>\n<!-- Element for injecting the tabbar padding into the component. -->\n<div class=\"padding-inline\" #padding_inline></div>\n", styles: ["@charset \"UTF-8\";:host{--\\275part-bar-indent-left: 0;--\\275part-bar-indent-right: 0;--\\275part-bar-drag-source-width: 0;--\\275part-bar-drag-placeholder-width: 0;display:flex;color:var(--sci-workbench-tab-text-color);background-color:var(--sci-workbench-part-bar-background-color);border-top:var(--sci-workbench-part-bar-padding-top) solid transparent;background-clip:border-box;height:var(--sci-workbench-tab-height);box-sizing:content-box;position:relative;container-name:viewtab;container-type:size}wb-workbench:has(wb-main-area-layout) wb-part:not(.main-area) :host{background-color:var(--sci-workbench-part-peripheral-bar-background-color)}:host>sci-viewport.tabbar{flex:initial}:host>sci-viewport.tabbar::part(content){display:flex;padding-left:var(--\\275part-bar-indent-left);padding-right:var(--\\275part-bar-indent-right)}:host>sci-viewport.tabbar>wb-view-tab{flex:none}:host>sci-viewport.tabbar>wb-view-tab.drag-source{display:none}:host>sci-viewport.tabbar>div.divider{flex:none;display:flex;position:relative;width:0}:host>sci-viewport.tabbar>div.divider:after{flex:none;align-self:center;content:\"\";position:absolute;width:1px;left:-1px;height:65%;background-color:var(--sci-workbench-part-bar-divider-color)}:host>sci-viewport.tabbar>div.drag-placeholder{flex:none;width:var(--\\275part-bar-drag-placeholder-width)}:host>sci-viewport.tabbar>wb-view-tab.drop-target,:host>sci-viewport.tabbar wb-view-tab.drop-target~:is(wb-view-tab,div.divider),:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.drop-target){transform:translate(var(--\\275part-bar-drag-source-width))}:host>sci-viewport.tabbar>wb-view-tab:is(.active,.drag-source)+div.divider{display:none}:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.active:not(.drag-source)){display:none}:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.drag-source:not(.active)){display:none}:host:not(.drag-over)>sci-viewport.tabbar:not(:has(wb-view-tab:not(.drag-source)))::part(content){padding-right:0}:host>wb-part-action-bar.start{flex:none;padding-left:var(--sci-workbench-part-bar-actions-padding-inline)}:host>div.filler{flex:auto}:host>wb-part-action-bar.end{flex:none;padding-right:var(--sci-workbench-part-bar-actions-padding-inline)}:host>wb-view-list-button{flex:none}:host:before{content:\"\";position:absolute;bottom:0;left:0;right:0;height:1px;background-color:var(--sci-workbench-tab-border-color)}:host>div.tab-corner-radius{position:absolute;visibility:hidden;width:var(--sci-workbench-tab-border-radius)}:host>div.padding-inline{position:absolute;visibility:hidden;width:var(--sci-workbench-part-bar-padding-inline)}:host.on-drag-enter:not(.on-drag-start) wb-view-tab,:host.on-drag-enter:not(.on-drag-start) div.divider,:host.drag-over wb-view-tab,:host.drag-over div.divider,:host.on-drag-leave wb-view-tab,:host.on-drag-leave div.divider{transition:transform 175ms cubic-bezier(0,0,.2,1)}:host.on-drag-enter:not(.on-drag-start) div.drag-placeholder,:host.on-drag-leave div.drag-placeholder{transition:width 175ms cubic-bezier(0,0,.2,1)}:host:not(:has(wb-view-tab.drag-source)):not(:has(wb-view-tab.drop-target)):not(.drag-over) div.drag-placeholder{display:none}:host.pointer-events-disabled>sci-viewport.tabbar::part(content){pointer-events:none}\n"], dependencies: [{ kind: "component", type: SciViewportComponent, selector: "sci-viewport", inputs: ["scrollbarStyle"], outputs: ["scroll"] }, { kind: "component", type: ViewTabComponent, selector: "wb-view-tab", inputs: ["viewId"] }, { kind: "component", type: PartActionBarComponent, selector: "wb-part-action-bar", inputs: ["actions"] }, { kind: "component", type: ViewListButtonComponent, selector: "wb-view-list-button" }] }); }
418
515
  }
419
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: PartBarComponent, decorators: [{
516
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: PartBarComponent, decorators: [{
420
517
  type: Component,
421
518
  args: [{ selector: 'wb-part-bar', standalone: true, imports: [
422
- NgFor,
423
- AsyncPipe,
424
519
  SciViewportComponent,
425
- SciDimensionModule,
426
520
  ViewTabComponent,
427
521
  PartActionBarComponent,
428
522
  ViewListButtonComponent,
429
- NgIf,
430
- ], template: "<sci-viewport class=\"tabbar\" scrollbarStyle=\"hidden\"\n [class.dragover]=\"dragover$ | async\"\n sciDimension (sciDimensionChange)=\"onTabbarViewportDimensionChange()\"\n (scroll)=\"onScroll()\">\n <ng-container *ngFor=\"let viewId of viewIds$ | async;\">\n <div class=\"divider\" *ngIf=\"viewtab === dropTargetViewTab\"></div>\n <wb-view-tab #viewtab\n [viewId]=\"viewId\"\n [class.drag-source]=\"viewtab === dragSourceViewTab\"\n [class.drop-target]=\"viewtab === dropTargetViewTab\">\n </wb-view-tab>\n <div class=\"divider\"></div>\n </ng-container>\n\n <!-- Placeholder element to grow the viewport to fit the drag image. -->\n <div class=\"drag-image-placeholder\"></div>\n</sci-viewport>\n<wb-part-action-bar/>\n<wb-view-list-button/>\n\n<!-- Element for injecting the corner radius into the component. -->\n<div class=\"tab-corner-radius\" #tab_corner_radius></div>\n<!-- Element for injecting the tabbar padding into the component. -->\n<div class=\"padding-inline\" #padding_inline></div>\n", styles: ["@charset \"UTF-8\";:host{--\\275part-bar-indent-left: 0;--\\275part-bar-indent-right: 0;--\\275part-bar-drag-source-width: 0;--\\275part-bar-drag-image-placeholder-width: 0;display:flex;color:var(--sci-workbench-tab-text-color);background-color:var(--sci-workbench-part-bar-background-color);border-top:var(--sci-workbench-part-bar-padding-top) solid transparent;background-clip:border-box;height:var(--sci-workbench-tab-height);box-sizing:content-box;position:relative;container-name:viewtab;container-type:size}wb-workbench:has(wb-main-area-layout) wb-part:not(.main-area) :host{background-color:var(--sci-workbench-part-peripheral-bar-background-color)}:host>sci-viewport.tabbar{flex:initial}:host>sci-viewport.tabbar::part(content){display:flex;padding-left:var(--\\275part-bar-indent-left);padding-right:var(--\\275part-bar-indent-right)}:host>sci-viewport.tabbar:not(.dragover):not(:has(wb-view-tab:not(.drag-source)))::part(content){padding-right:0}:host>sci-viewport.tabbar>wb-view-tab{flex:none}:host>sci-viewport.tabbar>wb-view-tab.drag-source{display:none}:host>sci-viewport.tabbar>div.divider{flex:none;display:flex;position:relative;width:0}:host>sci-viewport.tabbar>div.divider:after{flex:none;align-self:center;content:\"\";position:absolute;width:1px;left:-1px;height:65%;background-color:var(--sci-workbench-part-bar-divider-color)}:host>sci-viewport.tabbar>div.drag-image-placeholder{flex:none;width:var(--\\275part-bar-drag-image-placeholder-width)}:host>sci-viewport.tabbar>wb-view-tab.drop-target,:host>sci-viewport.tabbar wb-view-tab.drop-target~:is(wb-view-tab,div.divider),:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.drop-target){transform:translate(var(--\\275part-bar-drag-source-width))}:host>sci-viewport.tabbar>wb-view-tab:is(.active,.drag-source)+div.divider{display:none}:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.active:not(.drag-source)){display:none}:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.drag-source:not(.active)){display:none}:host>wb-part-action-bar{flex:auto}:host>wb-view-list-button{flex:none}:host:before{content:\"\";position:absolute;bottom:0;left:0;right:0;height:1px;background-color:var(--sci-workbench-tab-border-color)}:host>div.tab-corner-radius{position:absolute;visibility:hidden;width:var(--sci-workbench-tab-border-radius)}:host>div.padding-inline{position:absolute;visibility:hidden;width:var(--sci-workbench-part-bar-padding-inline)}:host:not(.calculating-max-viewport-width).drag-enter wb-view-tab,:host:not(.calculating-max-viewport-width).drag-enter div.divider,:host:not(.calculating-max-viewport-width).drag-over wb-view-tab,:host:not(.calculating-max-viewport-width).drag-over div.divider,:host:not(.calculating-max-viewport-width).drag-leave wb-view-tab,:host:not(.calculating-max-viewport-width).drag-leave div.divider{transition:transform 175ms cubic-bezier(0,0,.2,1)}:host:not(.calculating-max-viewport-width).drag-enter div.drag-image-placeholder,:host:not(.calculating-max-viewport-width).drag-leave div.drag-image-placeholder{transition:width 175ms cubic-bezier(0,0,.2,1)}\n"] }]
431
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: undefined, decorators: [{
432
- type: Inject,
433
- args: [WORKBENCH_ID]
434
- }] }, { type: i1.WorkbenchLayoutService }, { type: i2.ɵWorkbenchRouter }, { type: i3.ViewTabDragImageRenderer }, { type: i4.ɵWorkbenchPart }, { type: i5.ViewDragService }, { type: i0.DestroyRef }, { type: i0.NgZone }], propDecorators: { _viewportElement: [{
435
- type: ViewChild,
436
- args: [SciViewportComponent, { static: true, read: ElementRef }]
437
- }], _viewportComponent: [{
438
- type: ViewChild,
439
- args: [SciViewportComponent, { static: true }]
440
- }], _tabCornerRadiusElement: [{
441
- type: ViewChild,
442
- args: ['tab_corner_radius', { static: true }]
443
- }], _paddingInlineElement: [{
444
- type: ViewChild,
445
- args: ['padding_inline', { static: true }]
446
- }], injectViewTabs: [{
447
- type: ViewChildren,
448
- args: [ViewTabComponent]
449
- }], onDoubleClick: [{
523
+ ], template: "<sci-viewport class=\"tabbar e2e-tabbar\" scrollbarStyle=\"hidden\">\n @for (viewId of part.viewIds(); track viewId) {\n @if (viewtab === dropTargetViewTab()) {\n <div class=\"divider\"></div>\n }\n <wb-view-tab #viewtab\n [viewId]=\"viewId\"\n [class.drag-source]=\"viewtab === dragSourceViewTab()\"\n [class.drop-target]=\"viewtab === dropTargetViewTab()\"/>\n <div class=\"divider\"></div>\n }\n\n <!-- Placeholder for expanding the viewport when dragging a tab to the right, moving part actions along with the dragover event. -->\n <div class=\"drag-placeholder\"></div>\n</sci-viewport>\n\n<!-- Actions -->\n@if (startActions().length) {\n <wb-part-action-bar [actions]=\"startActions()\" class=\"start\"/>\n}\n<div class=\"filler\" #filler></div>\n@if (endActions().length) {\n <wb-part-action-bar [actions]=\"endActions()\" class=\"end\"/>\n}\n\n<!-- View List Dropdown -->\n<wb-view-list-button/>\n\n<!-- Element for injecting the corner radius into the component. -->\n<div class=\"tab-corner-radius\" #tab_corner_radius></div>\n<!-- Element for injecting the tabbar padding into the component. -->\n<div class=\"padding-inline\" #padding_inline></div>\n", styles: ["@charset \"UTF-8\";:host{--\\275part-bar-indent-left: 0;--\\275part-bar-indent-right: 0;--\\275part-bar-drag-source-width: 0;--\\275part-bar-drag-placeholder-width: 0;display:flex;color:var(--sci-workbench-tab-text-color);background-color:var(--sci-workbench-part-bar-background-color);border-top:var(--sci-workbench-part-bar-padding-top) solid transparent;background-clip:border-box;height:var(--sci-workbench-tab-height);box-sizing:content-box;position:relative;container-name:viewtab;container-type:size}wb-workbench:has(wb-main-area-layout) wb-part:not(.main-area) :host{background-color:var(--sci-workbench-part-peripheral-bar-background-color)}:host>sci-viewport.tabbar{flex:initial}:host>sci-viewport.tabbar::part(content){display:flex;padding-left:var(--\\275part-bar-indent-left);padding-right:var(--\\275part-bar-indent-right)}:host>sci-viewport.tabbar>wb-view-tab{flex:none}:host>sci-viewport.tabbar>wb-view-tab.drag-source{display:none}:host>sci-viewport.tabbar>div.divider{flex:none;display:flex;position:relative;width:0}:host>sci-viewport.tabbar>div.divider:after{flex:none;align-self:center;content:\"\";position:absolute;width:1px;left:-1px;height:65%;background-color:var(--sci-workbench-part-bar-divider-color)}:host>sci-viewport.tabbar>div.drag-placeholder{flex:none;width:var(--\\275part-bar-drag-placeholder-width)}:host>sci-viewport.tabbar>wb-view-tab.drop-target,:host>sci-viewport.tabbar wb-view-tab.drop-target~:is(wb-view-tab,div.divider),:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.drop-target){transform:translate(var(--\\275part-bar-drag-source-width))}:host>sci-viewport.tabbar>wb-view-tab:is(.active,.drag-source)+div.divider{display:none}:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.active:not(.drag-source)){display:none}:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.drag-source:not(.active)){display:none}:host:not(.drag-over)>sci-viewport.tabbar:not(:has(wb-view-tab:not(.drag-source)))::part(content){padding-right:0}:host>wb-part-action-bar.start{flex:none;padding-left:var(--sci-workbench-part-bar-actions-padding-inline)}:host>div.filler{flex:auto}:host>wb-part-action-bar.end{flex:none;padding-right:var(--sci-workbench-part-bar-actions-padding-inline)}:host>wb-view-list-button{flex:none}:host:before{content:\"\";position:absolute;bottom:0;left:0;right:0;height:1px;background-color:var(--sci-workbench-tab-border-color)}:host>div.tab-corner-radius{position:absolute;visibility:hidden;width:var(--sci-workbench-tab-border-radius)}:host>div.padding-inline{position:absolute;visibility:hidden;width:var(--sci-workbench-part-bar-padding-inline)}:host.on-drag-enter:not(.on-drag-start) wb-view-tab,:host.on-drag-enter:not(.on-drag-start) div.divider,:host.drag-over wb-view-tab,:host.drag-over div.divider,:host.on-drag-leave wb-view-tab,:host.on-drag-leave div.divider{transition:transform 175ms cubic-bezier(0,0,.2,1)}:host.on-drag-enter:not(.on-drag-start) div.drag-placeholder,:host.on-drag-leave div.drag-placeholder{transition:width 175ms cubic-bezier(0,0,.2,1)}:host:not(:has(wb-view-tab.drag-source)):not(:has(wb-view-tab.drop-target)):not(.drag-over) div.drag-placeholder{display:none}:host.pointer-events-disabled>sci-viewport.tabbar::part(content){pointer-events:none}\n"] }]
524
+ }], ctorParameters: () => [], propDecorators: { onDoubleClick: [{
450
525
  type: HostListener,
451
526
  args: ['dblclick', ['$event']]
452
- }], onViewDragStart: [{
453
- type: HostListener,
454
- args: ['dragstart', ['$event']]
455
- }], onViewDragEnd: [{
456
- type: HostListener,
457
- args: ['dragend']
458
527
  }] } });
459
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFydC1iYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2Npb24vd29ya2JlbmNoL3NyYy9saWIvcGFydC9wYXJ0LWJhci9wYXJ0LWJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zY2lvbi93b3JrYmVuY2gvc3JjL2xpYi9wYXJ0L3BhcnQtYmFyL3BhcnQtYmFyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBRUgsT0FBTyxFQUFDLFNBQVMsRUFBYyxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBNkIsU0FBUyxFQUFFLFlBQVksRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUMxSSxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxnQ0FBZ0MsQ0FBQztBQUVoRSxPQUFPLEVBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUYsT0FBTyxFQUFDLHVCQUF1QixFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQWMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ2xJLE9BQU8sRUFBYyxpQkFBaUIsRUFBMkIsTUFBTSxxREFBcUQsQ0FBQztBQUU3SCxPQUFPLEVBQUMsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUV0SCxPQUFPLEVBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsZUFBZSxFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDL0YsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFFaEUsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sNkJBQTZCLENBQUM7QUFDL0QsT0FBTyxFQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDdkQsT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sOENBQThDLENBQUM7QUFDcEYsT0FBTyxFQUFDLHVCQUF1QixFQUFDLE1BQU0sZ0RBQWdELENBQUM7QUFDdkYsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDOUQsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBQ3pELE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQzs7Ozs7Ozs7QUFHaEQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FzQkc7QUFpQkgsTUFBTSxPQUFPLGdCQUFnQjtJQXNCM0IsSUFDVyxjQUFjLENBQUMsU0FBc0M7UUFDOUQsU0FBUyxDQUFDLE9BQU87YUFDZCxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFLGtCQUFrQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQzthQUNoRSxTQUFTLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUEwQ0QsWUFBWSxJQUE2QixFQUNDLFlBQW9CLEVBQzFDLHVCQUErQyxFQUMvQyxPQUF5QixFQUN6Qix5QkFBbUQsRUFDbkQsS0FBcUIsRUFDckIsZ0JBQWlDLEVBQ2pDLFdBQXVCLEVBQ3ZCLEtBQWE7UUFQUyxpQkFBWSxHQUFaLFlBQVksQ0FBUTtRQUMxQyw0QkFBdUIsR0FBdkIsdUJBQXVCLENBQXdCO1FBQy9DLFlBQU8sR0FBUCxPQUFPLENBQWtCO1FBQ3pCLDhCQUF5QixHQUF6Qix5QkFBeUIsQ0FBMEI7UUFDbkQsVUFBSyxHQUFMLEtBQUssQ0FBZ0I7UUFDckIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFpQjtRQUNqQyxnQkFBVyxHQUFYLFdBQVcsQ0FBWTtRQUN2QixVQUFLLEdBQUwsS0FBSyxDQUFRO1FBMUVoQixxQkFBZ0IsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ3ZDLGVBQVUsR0FBRyxJQUFJLGVBQWUsQ0FBcUIsRUFBRSxDQUFDLENBQUM7UUFDekQsZ0JBQVcsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ2xDLGdCQUFXLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUNsQyxjQUFTLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQXNCakQ7O1dBRUc7UUFDSSxzQkFBaUIsR0FBb0MsSUFBSSxDQUFDO1FBRWpFOzs7V0FHRztRQUNJLHNCQUFpQixHQUE0QixJQUFJLENBQUM7UUFFekQ7O1dBRUc7UUFDSyxjQUFTLEdBQXdCLElBQUksQ0FBQztRQUU5Qzs7V0FFRztRQUNLLGlCQUFZLEdBQXVCLElBQUksQ0FBQztRQUVoRDs7V0FFRztRQUNLLGtCQUFhLEdBQUc7WUFDdEIsSUFBSSxFQUFFLENBQUM7WUFDUCxLQUFLLEVBQUUsQ0FBQztTQUNULENBQUM7UUFFRjs7V0FFRztRQUNLLDBCQUFxQixHQUFHLFFBQVEsQ0FBQyxDQUFDLEVBQUUsdUJBQXVCLENBQUM7YUFDakUsSUFBSSxDQUNILE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxFQUMxQyxlQUFlLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQ3ZFLGFBQWEsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQ3ZELEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFpQixDQUFDLENBQzdCLENBQUM7UUFXRixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDaEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3ZHLENBQUM7SUFFTSxRQUFRO1FBQ2IsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7UUFDakMsSUFBSSxDQUFDLDhCQUE4QixFQUFFLENBQUM7UUFDdEMsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLCtCQUErQixFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLGlDQUFpQyxFQUFFLENBQUM7SUFDM0MsQ0FBQztJQUdNLGFBQWEsQ0FBQyxLQUFpQjtRQUNwQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFO1lBQzNCLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDbEU7UUFDRCxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVELElBQVcsUUFBUTtRQUNqQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDO0lBQzdCLENBQUM7SUFFTSwrQkFBK0I7UUFDcEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFTSxRQUFRO1FBQ2IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFRDs7T0FFRztJQUVJLGVBQWUsQ0FBQyxLQUFnQjtRQUNyQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUNqRCxPQUFPO1NBQ1I7UUFFRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBYSxDQUFDO1FBQ3JELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEcsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzFELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDO1FBRXZFLHNGQUFzRjtRQUN0RixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQ3RELElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDOUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFdkQsbUtBQW1LO1FBQ25LLDhLQUE4SztRQUM5Syx1QkFBdUIsQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQ3BDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQztZQUMzQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsaUJBQWlCLENBQUMsQ0FBQywwQ0FBMEM7WUFDdEYsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUU7Z0JBQ3pCLCtCQUErQixFQUFFLEdBQUcsUUFBUSxDQUFDLFlBQVksSUFBSTtnQkFDN0QsMENBQTBDLEVBQUUsR0FBRyxRQUFRLENBQUMsWUFBWSxJQUFJO2FBQ3pFLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsNkhBQTZIO1FBQzdILGtKQUFrSjtRQUNsSixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxFQUFDLFNBQVMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxFQUFDLENBQUM7YUFDaEUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLGtCQUFrQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQzthQUM5RSxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDakIseURBQXlEO1lBQ3pELDRHQUE0RztZQUM1RyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsTUFBaUIsQ0FBQyxHQUFHLElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDN0csSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7YUFDMUI7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRDs7OztPQUlHO0lBRUksYUFBYTtRQUNsQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQ7O09BRUc7SUFDSyxpQkFBaUIsQ0FBQyxLQUFnQjtRQUN4QyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQWEsQ0FBQztRQUVyRCxzRkFBc0Y7UUFDdEYsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDdEIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQztZQUN0RCxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQTJCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1NBQy9FO1FBRUQsK0VBQStFO1FBQy9FLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdkQsa0VBQWtFO1FBQ2xFLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFlBQVksRUFBRSxXQUFXLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMscUJBQXFCO2FBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7YUFDaEYsU0FBUyxDQUFDLEVBQUMsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxFQUFDLENBQUMsQ0FBQztRQUV4RSxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRTtZQUN6QiwrQkFBK0IsRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxJQUFJO1lBQ25FLDBDQUEwQyxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLElBQUk7U0FDL0UsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ssaUJBQWlCO1FBQ3ZCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFeEIsaUVBQWlFO1FBQ2pFLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxxQkFBcUI7YUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLGtCQUFrQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQzthQUNoRixTQUFTLENBQUMsRUFBQyxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsWUFBWSxDQUFDLEVBQUMsQ0FBQyxDQUFDO1FBRXhFLElBQUksQ0FBQyxjQUFjLENBQUMsRUFBQyxlQUFlLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQztRQUU5QyxvSUFBb0k7UUFDcEksSUFBSSxJQUFJLENBQUMsaUJBQWlCLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRTtZQUMzRCxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsaUJBQWtCLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBQyxrQkFBa0IsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1NBQ2pJO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ssZ0JBQWdCLENBQUMsS0FBZ0I7UUFDdkMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsa0JBQWtCO1FBRTFDLHFKQUFxSjtRQUNySixJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxFQUFFO1lBQ2hDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkQsOEhBQThIO1lBQzlILGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUMsMENBQTBDLEVBQUUsR0FBRyxJQUFJLENBQUMsa0NBQWtDLENBQUMsS0FBSyxDQUFDLElBQUksRUFBQyxDQUFDLENBQUM7U0FDakk7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxZQUFZO1FBQ2xCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxxQkFBcUIsQ0FBQztZQUMxQyxNQUFNLEVBQUU7Z0JBQ04sV0FBVyxFQUFFLElBQUksQ0FBQyxTQUFVLENBQUMsV0FBVztnQkFDeEMsTUFBTSxFQUFFLElBQUksQ0FBQyxTQUFVLENBQUMsTUFBTTtnQkFDOUIsTUFBTSxFQUFFLElBQUksQ0FBQyxTQUFVLENBQUMsTUFBTTtnQkFDOUIsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLFNBQVUsQ0FBQyxpQkFBaUI7Z0JBQ3BELGVBQWUsRUFBRSxJQUFJLENBQUMsU0FBVSxDQUFDLGVBQWU7Z0JBQ2hELGNBQWMsRUFBRSxJQUFJLENBQUMsU0FBVSxDQUFDLGNBQWM7Z0JBQzlDLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBVSxDQUFDLFNBQVM7YUFDckM7WUFDRCxNQUFNLEVBQUU7Z0JBQ04sV0FBVyxFQUFFLElBQUksQ0FBQyxZQUFZO2dCQUM5QixRQUFRLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUJBQWtCLENBQUM7Z0JBQ3BHLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7YUFDekI7U0FDRixDQUFDLENBQUM7UUFFSCxvSEFBb0g7UUFDcEgsc0hBQXNIO1FBQ3RILCtFQUErRTtRQUMvRSxjQUFjLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLGVBQWUsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7WUFDckUsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3hCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ksaUJBQWlCLENBQUMsS0FBZ0I7UUFDdkMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLFNBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN4RyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUV0RixLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRTtZQUM5QixNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDekQsTUFBTSxhQUFhLEdBQUcsV0FBVyxDQUFDLElBQUksR0FBRyxDQUFDLFdBQVcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDakUsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLEdBQUcsYUFBYSxJQUFJLENBQUMsT0FBTyxLQUFLLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxpQkFBaUIsQ0FBQyxLQUFLLEdBQUcsYUFBYSxDQUFDLEVBQUU7Z0JBQzdILE9BQU8sT0FBTyxDQUFDO2FBQ2hCO1NBQ0Y7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRDs7T0FFRztJQUNLLDBCQUEwQjtRQUNoQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLENBQUMsSUFBSSxDQUFDO1FBQ3pELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7UUFDMUQsT0FBTyxDQUFDLElBQXVCLEVBQXFCLEVBQUU7WUFDcEQsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDeEYsT0FBTyxJQUFJLGlCQUFpQixDQUFDO2dCQUMzQixDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxHQUFHLGdCQUFnQixHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUM7Z0JBQ3RJLENBQUMsRUFBRSxtQkFBbUIsQ0FBQyxHQUFHO2dCQUMxQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7Z0JBQ2pCLE1BQU0sRUFBRSxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsaUZBQWlGO2FBQ3RILENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNLLHlCQUF5QjtRQUMvQixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO1FBRW5HLDRFQUE0RTtRQUM1RSxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxnQ0FBZ0MsQ0FBQyxDQUFDO1FBQzFELGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUMsMENBQTBDLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsSUFBSSxFQUFDLENBQUMsQ0FBQztRQUN4RyxJQUFJO1lBQ0YsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLHFCQUFxQixFQUFFLENBQUMsS0FBSyxDQUFDO1NBQzFFO2dCQUNPO1lBQ04sY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBQywwQ0FBMEMsRUFBRSxZQUFZLElBQUksSUFBSSxFQUFDLENBQUMsQ0FBQztZQUMvRixhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxnQ0FBZ0MsQ0FBQyxDQUFDO1NBQzdEO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSyxrQ0FBa0MsQ0FBQyxLQUFnQjtRQUN6RCxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsU0FBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3hHLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxLQUFLLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hHLE1BQU0sZ0JBQWdCLEdBQUcsV0FBVyxFQUFFLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixFQUFFLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDO1FBQzlJLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsR0FBRyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLENBQUMsS0FBSyxDQUFDLEdBQUcsZ0JBQWdCLENBQUM7SUFDMUcsQ0FBQztJQUVEOzs7T0FHRztJQUNLLHFCQUFxQjtRQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQzNCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxLQUFLLE1BQU0sQ0FBQyxDQUFDO1NBQy9GO1FBRUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDdEYsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUJBQWtCLENBQUMsQ0FBQztRQUN2SCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsU0FBVSxDQUFDLFlBQVksQ0FBQztRQUVyRCxPQUFPLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDbkMsTUFBTSxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDO1lBQ3JFLHdFQUF3RTtZQUN4RSxJQUFJLENBQUMsR0FBRyxlQUFlLElBQUksaUJBQWlCLEtBQUssTUFBTSxFQUFFO2dCQUN2RCxPQUFPLEtBQUssQ0FBQzthQUNkO1lBQ0Qsb0ZBQW9GO1lBQ3BGLElBQUksQ0FBQyxJQUFJLGVBQWUsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsRUFBRSxFQUFFLDhEQUE4RDtnQkFDakssT0FBTyxLQUFLLENBQUM7YUFDZDtZQUNELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sY0FBYyxDQUFDLE9BQXFDO1FBQzFELElBQUksT0FBTyxFQUFFLGVBQWUsSUFBSSxJQUFJLEVBQUU7WUFDcEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztTQUMvQjtRQUVELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7UUFDOUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdEIsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxZQUFhLENBQUMsQ0FBQztRQUNqRixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUV6QixhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztRQUN2QyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLCtCQUErQixFQUFFLDBDQUEwQyxDQUFDLENBQUM7UUFDMUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVELElBQVksU0FBUztRQUNuQixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO0lBQy9CLENBQUM7SUFFRDs7T0FFRztJQUNLLHlCQUF5QjtRQUMvQixJQUFJLENBQUMsVUFBVTthQUNaLElBQUksQ0FDSCxTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUNuRixrQkFBa0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQ3JDO2FBQ0EsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNkLGtHQUFrRztZQUNsRyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyRSxJQUFJLGFBQWEsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsRUFBRTtnQkFDekYsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDNUQ7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRDs7T0FFRztJQUNLLDhCQUE4QjtRQUNwQyxJQUFJLENBQUMsZ0JBQWdCO2FBQ2xCLElBQUksQ0FDSCxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUN6QixXQUFXLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsa0RBQWtEO1FBQzlHLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUNwQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQ3JDO2FBQ0EsU0FBUyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ25CLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2hHLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVPLHVCQUF1QjtRQUM3QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7YUFDeEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQzthQUMxQyxTQUFTLENBQUMsQ0FBQyxLQUFnQixFQUFFLEVBQUU7WUFDOUIsUUFBUSxLQUFLLENBQUMsSUFBSSxFQUFFO2dCQUNsQixLQUFLLFdBQVc7b0JBQ2QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUM5QixNQUFNO2dCQUNSLEtBQUssVUFBVTtvQkFDYixJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQzdCLE1BQU07Z0JBQ1IsS0FBSyxXQUFXO29CQUNkLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO29CQUN6QixNQUFNO2dCQUNSLEtBQUssTUFBTTtvQkFDVCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7b0JBQ3BCLE1BQU07YUFDVDtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVPLGlDQUFpQztRQUN2QyxjQUFjLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLHFCQUFxQixDQUFDO2FBQzFELElBQUksQ0FDSCxlQUFlLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUN6QyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQ3JDO2FBQ0EsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFTywrQkFBK0I7UUFDckMsYUFBYSxDQUFDLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxhQUFhLENBQUMsRUFBRSxjQUFjLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7YUFDbEksSUFBSSxDQUNILGVBQWUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDdkQsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxFQUM1QyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQ3JDO2FBQ0EsU0FBUyxDQUFDLENBQUMsQ0FBQyxlQUFlLEVBQUUsYUFBYSxDQUFDLEVBQUUsRUFBRTtZQUM5QyxJQUFJLENBQUMsYUFBYSxHQUFHLEVBQUMsSUFBSSxFQUFFLGVBQWUsR0FBRyxhQUFhLEVBQUUsS0FBSyxFQUFFLGVBQWUsR0FBRyxhQUFhLEVBQUMsQ0FBQztZQUNyRyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFDLHlCQUF5QixFQUFFLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLElBQUksRUFBQyxDQUFDLENBQUM7WUFDeEYsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBQywwQkFBMEIsRUFBRSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxJQUFJLEVBQUMsQ0FBQyxDQUFDO1FBQzVGLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQzs4R0FoY1UsZ0JBQWdCLDRDQXNFUCxZQUFZO2tHQXRFckIsZ0JBQWdCLDZQQVVoQixvQkFBb0IsMkJBQXVCLFVBQVUsZ0ZBR3JELG9CQUFvQix1VUFTakIsZ0JBQWdCLGdEQzVGaEMsb2xDQXdCQSxta0dEb0NJLEtBQUssOEdBQ0wsU0FBUyw4Q0FDVCxvQkFBb0IseUdBQ3BCLGtCQUFrQiwrTUFDbEIsZ0JBQWdCLDRFQUNoQixzQkFBc0IsK0RBQ3RCLHVCQUF1QixnRUFDdkIsSUFBSTs7MkZBR0ssZ0JBQWdCO2tCQWhCNUIsU0FBUzsrQkFDRSxhQUFhLGNBR1gsSUFBSSxXQUNQO3dCQUNQLEtBQUs7d0JBQ0wsU0FBUzt3QkFDVCxvQkFBb0I7d0JBQ3BCLGtCQUFrQjt3QkFDbEIsZ0JBQWdCO3dCQUNoQixzQkFBc0I7d0JBQ3RCLHVCQUF1Qjt3QkFDdkIsSUFBSTtxQkFDTDs7MEJBd0VZLE1BQU07MkJBQUMsWUFBWTs2UEEzRHhCLGdCQUFnQjtzQkFEdkIsU0FBUzt1QkFBQyxvQkFBb0IsRUFBRSxFQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBQztnQkFJekQsa0JBQWtCO3NCQUR6QixTQUFTO3VCQUFDLG9CQUFvQixFQUFFLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBQztnQkFJdkMsdUJBQXVCO3NCQUQ5QixTQUFTO3VCQUFDLG1CQUFtQixFQUFFLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBQztnQkFJdEMscUJBQXFCO3NCQUQ1QixTQUFTO3VCQUFDLGdCQUFnQixFQUFFLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBQztnQkFJaEMsY0FBYztzQkFEeEIsWUFBWTt1QkFBQyxnQkFBZ0I7Z0JBcUV2QixhQUFhO3NCQURuQixZQUFZO3VCQUFDLFVBQVUsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkF3QjdCLGVBQWU7c0JBRHJCLFlBQVk7dUJBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQThDOUIsYUFBYTtzQkFEbkIsWUFBWTt1QkFBQyxTQUFTIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoYykgMjAxOC0yMDIzIFN3aXNzIEZlZGVyYWwgUmFpbHdheXNcbiAqXG4gKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlXG4gKiBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIDIuMFxuICogd2hpY2ggaXMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAvXG4gKlxuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjBcbiAqL1xuXG5pbXBvcnQge0NvbXBvbmVudCwgRGVzdHJveVJlZiwgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBJbmplY3QsIE5nWm9uZSwgT25Jbml0LCBRdWVyeUxpc3QsIFZpZXdDaGlsZCwgVmlld0NoaWxkcmVufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Vmlld1RhYkNvbXBvbmVudH0gZnJvbSAnLi4vdmlldy10YWIvdmlldy10YWIuY29tcG9uZW50JztcbmltcG9ydCB7V29ya2JlbmNoTGF5b3V0U2VydmljZX0gZnJvbSAnLi4vLi4vbGF5b3V0L3dvcmtiZW5jaC1sYXlvdXQuc2VydmljZSc7XG5pbXBvcnQge2ZpbHRlciwgbWFwLCBtZXJnZU1hcCwgc3RhcnRXaXRoLCBzd2l0Y2hNYXAsIHRha2UsIHRha2VVbnRpbH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHthbmltYXRpb25GcmFtZVNjaGVkdWxlciwgQmVoYXZpb3JTdWJqZWN0LCBjb21iaW5lTGF0ZXN0LCBmaXJzdFZhbHVlRnJvbSwgZnJvbSwgaW50ZXJ2YWwsIE9ic2VydmFibGUsIFN1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtDb25zdHJhaW5GbiwgVmlld0RyYWdJbWFnZVJlY3QsIFZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlcn0gZnJvbSAnLi4vLi4vdmlldy1kbmQvdmlldy10YWItZHJhZy1pbWFnZS1yZW5kZXJlci5zZXJ2aWNlJztcbmltcG9ydCB7Vmlld0RyYWdEYXRhLCBWaWV3RHJhZ1NlcnZpY2V9IGZyb20gJy4uLy4uL3ZpZXctZG5kL3ZpZXctZHJhZy5zZXJ2aWNlJztcbmltcG9ydCB7Z2V0Q3NzVHJhbnNsYXRpb24sIHNldENzc0NsYXNzLCBzZXRDc3NWYXJpYWJsZSwgdW5zZXRDc3NDbGFzcywgdW5zZXRDc3NWYXJpYWJsZX0gZnJvbSAnLi4vLi4vY29tbW9uL2RvbS51dGlsJztcbmltcG9ydCB7ybVXb3JrYmVuY2hQYXJ0fSBmcm9tICcuLi/JtXdvcmtiZW5jaC1wYXJ0Lm1vZGVsJztcbmltcG9ydCB7ZmlsdGVyQXJyYXksIG1hcEFycmF5LCBvYnNlcnZlSW5zaWRlLCBzdWJzY3JpYmVJbnNpZGV9IGZyb20gJ0BzY2lvbi90b29sa2l0L29wZXJhdG9ycyc7XG5pbXBvcnQge1NjaVZpZXdwb3J0Q29tcG9uZW50fSBmcm9tICdAc2Npb24vY29tcG9uZW50cy92aWV3cG9ydCc7XG5pbXBvcnQge8m1V29ya2JlbmNoUm91dGVyfSBmcm9tICcuLi8uLi9yb3V0aW5nL8m1d29ya2JlbmNoLXJvdXRlci5zZXJ2aWNlJztcbmltcG9ydCB7U2NpRGltZW5zaW9uTW9kdWxlfSBmcm9tICdAc2Npb24vY29tcG9uZW50cy9kaW1lbnNpb24nO1xuaW1wb3J0IHtBc3luY1BpcGUsIE5nRm9yLCBOZ0lmfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtQYXJ0QWN0aW9uQmFyQ29tcG9uZW50fSBmcm9tICcuLi9wYXJ0LWFjdGlvbi1iYXIvcGFydC1hY3Rpb24tYmFyLmNvbXBvbmVudCc7XG5pbXBvcnQge1ZpZXdMaXN0QnV0dG9uQ29tcG9uZW50fSBmcm9tICcuLi92aWV3LWxpc3QtYnV0dG9uL3ZpZXctbGlzdC1idXR0b24uY29tcG9uZW50JztcbmltcG9ydCB7dGFrZVVudGlsRGVzdHJveWVkfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQge2Zyb21EaW1lbnNpb24kfSBmcm9tICdAc2Npb24vdG9vbGtpdC9vYnNlcnZhYmxlJztcbmltcG9ydCB7V09SS0JFTkNIX0lEfSBmcm9tICcuLi8uLi93b3JrYmVuY2gtaWQnO1xuaW1wb3J0IHtWaWV3SWR9IGZyb20gJy4uLy4uL3ZpZXcvd29ya2JlbmNoLXZpZXcubW9kZWwnO1xuXG4vKipcbiAqIFJlbmRlcnMgdmlldyB0YWJzIGFuZCBhY3Rpb25zIG9mIGEge0BsaW5rIFdvcmtiZW5jaFBhcnR9LlxuICpcbiAqIFRhYnMgYXJlIGFkZGVkIHRvIGEgdmlld3BvcnQsIHdoaWNoIHRoZSB1c2VyIGNhbiBzY3JvbGwgaWYgbm90IGVub3VnaCBzcGFjZS4gVGhlIHZpZXdwb3J0IGdyb3dzIHdpdGggaXRzIHRhYnMsXG4gKiBhbGxvd2luZyBhY3Rpb25zIHRvIGJlIHBsYWNlZCBkaXJlY3RseSBhZnRlciB0aGUgbGFzdCB0YWIgb3Igb24gdGhlIHJpZ2h0IHNpZGUuXG4gKlxuICogIyMgRHJhZyBFdmVudHNcbiAqIFdlIHVzZSBuYXRpdmUgZHJhZyBhbmQgZHJvcCB0byBzdXBwb3J0IGRyYWdnaW5nIHZpZXdzIHRvIG90aGVyIHdpbmRvd3MuXG4gKlxuICogQnkgbGlzdGVuaW5nIHRvIGRyYWcgZXZlbnRzLCB0aGUgdGFiYmFyIHZpc3VhbGl6ZXMgdGFicyBkdXJpbmcgYSBkcmFnIG9wZXJhdGlvbi4gVGhlIGRyYWcgb3BlcmF0aW9uIGlzIGluaXRpYXRlZCBpbiB7QGxpbmsgVmlld1RhYkNvbXBvbmVudH0uXG4gKiAtIGBkcmFnc3RhcnRgIGFuZCBgZHJhZ2VuZGAgZXZlbnRzIGFyZSBmaXJlZCBpbiB0aGUgdGFiYmFyIHdoZXJlIHRoZSBkcmFnIG9wZXJhdGlvbiB3YXMgaW5pdGlhdGVkLlxuICogLSBgZHJhZ2VudGVyYCBldmVudCBpcyBmaXJlZCB3aGVuIGEgdGFiIGVudGVycyB0aGUgdGFiYmFyLlxuICogLSBgZHJhZ292ZXJgIGV2ZW50cyBhcmUgZmlyZWQgd2hlbiBkcmFnZ2luZyBhIHRhYiBvdmVyIHRoZSB0YWJiYXIuXG4gKiAtIGBkcmFnbGVhdmVgIGV2ZW50IGlzIGZpcmVkIHdoZW4gYSB0YWIgbGVhdmVzIHRoZSB0YWJiYXIuXG4gKiAtIGBkcm9wYCBldmVudCBpcyBmaXJlZCB3aGVuIHRoZSB1c2VyIGRyb3BzIGEgdGFiIGluIHRoZSB0YWJiYXIuXG4gKiAtIE5vdGUgdGhhdCBgZHJhZ2xlYXZlYCBldmVudCBpcyBub3QgZmlyZWQgb24gZHJvcCBhY3Rpb24uIFRoZXJlZm9yZSwgYWx3YXlzIGhhbmRsZSBib3RoIGV2ZW50cywgYGRyYWdsZWF2ZWAgYW5kIGBkcm9wYCBldmVudHMsIHJlc3BlY3RpdmVseS5cbiAqXG4gKiAjIyBUZXJtaW5vbG9neVxuICogLSBEcmFnIHNvdXJjZTogVGFiIHRoYXQgaXMgYmVpbmcgZHJhZ2dlZC5cbiAqIC0gRHJvcCB0YXJnZXQ6IFRhYiBiZWZvcmUgd2hpY2ggdG8gaW5zZXJ0IHRoZSBkcmFnIHNvdXJjZSBvbiBkcm9wLCBvciBgZW5kYCBpZiBkcm9wcGluZyBpdCBhZnRlciB0aGUgbGFzdCB0YWIuXG4gKiAtIERyYWcgaW1hZ2U6ICBJbWFnZSBmb3IgdGhlIHRhYiB0byBiZSBkcmFnZ2VkLiBXZSBkbyBub3QgdXNlIHRoZSBuYXRpdmUgZHJhZyBpbWFnZSBzdXBwb3J0IHRvIGNvbnRyb2wgZHJhZyBpbWFnZSBwb3NpdGlvbiBhbmQgc2l6ZSxcbiAqICAgICAgICAgICAgICAgIGUuZy4sIHRvIHNuYXAgdGhlIGRyYWcgaW1hZ2UgdG8gdGhlIHRhYmJhciB3aGVuIGRyYWdnaW5nIG5lYXIgaXQuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3diLXBhcnQtYmFyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3BhcnQtYmFyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcGFydC1iYXIuY29tcG9uZW50LnNjc3MnXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIE5nRm9yLFxuICAgIEFzeW5jUGlwZSxcbiAgICBTY2lWaWV3cG9ydENvbXBvbmVudCxcbiAgICBTY2lEaW1lbnNpb25Nb2R1bGUsXG4gICAgVmlld1RhYkNvbXBvbmVudCxcbiAgICBQYXJ0QWN0aW9uQmFyQ29tcG9uZW50LFxuICAgIFZpZXdMaXN0QnV0dG9uQ29tcG9uZW50LFxuICAgIE5nSWYsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIFBhcnRCYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2hvc3Q6IEhUTUxFbGVtZW50O1xuICBwcml2YXRlIHJlYWRvbmx5IF92aWV3cG9ydENoYW5nZSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IF92aWV3VGFicyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFZpZXdUYWJDb21wb25lbnRbXT4oW10pO1xuICBwcml2YXRlIHJlYWRvbmx5IF9kcmFnZW50ZXIkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZHJhZ2xlYXZlJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RyYWdlbmQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHVibGljIHJlYWRvbmx5IGRyYWdvdmVyJDogT2JzZXJ2YWJsZTxib29sZWFuPjtcblxuICBAVmlld0NoaWxkKFNjaVZpZXdwb3J0Q29tcG9uZW50LCB7c3RhdGljOiB0cnVlLCByZWFkOiBFbGVtZW50UmVmfSlcbiAgcHJpdmF0ZSBfdmlld3BvcnRFbGVtZW50ITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cbiAgQFZpZXdDaGlsZChTY2lWaWV3cG9ydENvbXBvbmVudCwge3N0YXRpYzogdHJ1ZX0pXG4gIHByaXZhdGUgX3ZpZXdwb3J0Q29tcG9uZW50ITogU2NpVmlld3BvcnRDb21wb25lbnQ7XG5cbiAgQFZpZXdDaGlsZCgndGFiX2Nvcm5lcl9yYWRpdXMnLCB7c3RhdGljOiB0cnVlfSlcbiAgcHJpdmF0ZSBfdGFiQ29ybmVyUmFkaXVzRWxlbWVudCE6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuXG4gIEBWaWV3Q2hpbGQoJ3BhZGRpbmdfaW5saW5lJywge3N0YXRpYzogdHJ1ZX0pXG4gIHByaXZhdGUgX3BhZGRpbmdJbmxpbmVFbGVtZW50ITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cbiAgQFZpZXdDaGlsZHJlbihWaWV3VGFiQ29tcG9uZW50KVxuICBwdWJsaWMgc2V0IGluamVjdFZpZXdUYWJzKHF1ZXJ5TGlzdDogUXVlcnlMaXN0PFZpZXdUYWJDb21wb25lbnQ+KSB7XG4gICAgcXVlcnlMaXN0LmNoYW5nZXNcbiAgICAgIC5waXBlKHN0YXJ0V2l0aChxdWVyeUxpc3QpLCB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKHF1ZXJ5TGlzdCA9PiB0aGlzLl92aWV3VGFicyQubmV4dChxdWVyeUxpc3QudG9BcnJheSgpKSk7XG4gIH1cblxuICAvKipcbiAgICogUmVmZXJlbmNlIHRvIHRoZSB0YWIgYmVmb3JlIHdoaWNoIHRvIGluc2VydCB0aGUgZHJhZyBzb3VyY2Ugb24gZHJvcCwgb3IgYGVuZGAgaWYgZHJvcHBpbmcgaXQgYWZ0ZXIgdGhlIGxhc3QgdGFiLlxuICAgKi9cbiAgcHVibGljIGRyb3BUYXJnZXRWaWV3VGFiOiBWaWV3VGFiQ29tcG9uZW50IHwgJ2VuZCcgfCBudWxsID0gbnVsbDtcblxuICAvKipcbiAgICogUmVmZXJlbmNlIHRvIHRoZSB0YWIgd2hlcmUgdGhlIGRyYWcgb3BlcmF0aW9uIHdhcyBzdGFydGVkLlxuICAgKiBUaGlzIHJlZmVyZW5jZSBpcyBvbmx5IHNldCBpZiB0aGUgZHJhZyBvcGVyYXRpb24gc3RhcnRlZCBvbiBhIHRhYiBvZiB0aGlzIHRhYmJhci5cbiAgICovXG4gIHB1YmxpYyBkcmFnU291cmNlVmlld1RhYjogVmlld1RhYkNvbXBvbmVudCB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBUcmFuc2ZlciBkYXRhIG9mIHRoZSB0YWIgYmVpbmcgZHJhZ2dlZCBvdmVyIHRoaXMgdGFiYmFyLlxuICAgKi9cbiAgcHJpdmF0ZSBfZHJhZ0RhdGE6IFZpZXdEcmFnRGF0YSB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBGdW5jdGlvbiBmb3Igc25hcHBpbmcgdGhlIGRyYWcgaW1hZ2UgdG8gdGhlIHRhYmJhciB3aGVuIGRyYWdnaW5nIG5lYXIgaXQuXG4gICAqL1xuICBwcml2YXRlIF9jb25zdHJhaW5GbjogQ29uc3RyYWluRm4gfCBudWxsID0gbnVsbDtcblxuICAvKipcbiAgICogVGFiYmFyIGluZGVudHMgd2hlcmUgdG8gZGlzcGxheSB0aGUgcm91bmRlZCBib3R0b20gY29ybmVycyBvZiB0aGUgZmlyc3QgYW5kIGxhc3QgdmlldyB0YWIuXG4gICAqL1xuICBwcml2YXRlIF90YWJiYXJJbmRlbnQgPSB7XG4gICAgbGVmdDogMCxcbiAgICByaWdodDogMCxcbiAgfTtcblxuICAvKipcbiAgICogTm90aWZpZXMgd2hlbiB0aGUgZHJhZyBhbmltYXRpb24gaGFzIGZpbmlzaGVkLCBpLmUuLCB0YWJzIGhhdmUgdHJhbnNpdGlvbmVkIHRvIHRoZWlyIGZpbmFsIHBvc2l0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBfZHJhZ0FuaW1hdGlvblN0YWJsZSQgPSBpbnRlcnZhbCgwLCBhbmltYXRpb25GcmFtZVNjaGVkdWxlcilcbiAgICAucGlwZShcbiAgICAgIGZpbHRlcigoKSA9PiB0aGlzLmlzRHJhZ0FuaW1hdGlvblN0YWJsZSgpKSxcbiAgICAgIHN1YnNjcmliZUluc2lkZShjb250aW51ZUZuID0+IHRoaXMuX3pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoY29udGludWVGbikpLFxuICAgICAgb2JzZXJ2ZUluc2lkZShjb250aW51ZUZuID0+IHRoaXMuX3pvbmUucnVuKGNvbnRpbnVlRm4pKSxcbiAgICAgIG1hcCgoKSA9PiB1bmRlZmluZWQgYXMgdm9pZCksXG4gICAgKTtcblxuICBjb25zdHJ1Y3Rvcihob3N0OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PixcbiAgICAgICAgICAgICAgQEluamVjdChXT1JLQkVOQ0hfSUQpIHByaXZhdGUgX3dvcmtiZW5jaElkOiBzdHJpbmcsXG4gICAgICAgICAgICAgIHByaXZhdGUgX3dvcmtiZW5jaExheW91dFNlcnZpY2U6IFdvcmtiZW5jaExheW91dFNlcnZpY2UsXG4gICAgICAgICAgICAgIHByaXZhdGUgX3JvdXRlcjogybVXb3JrYmVuY2hSb3V0ZXIsXG4gICAgICAgICAgICAgIHByaXZhdGUgX3ZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlcjogVmlld1RhYkRyYWdJbWFnZVJlbmRlcmVyLFxuICAgICAgICAgICAgICBwcml2YXRlIF9wYXJ0OiDJtVdvcmtiZW5jaFBhcnQsXG4gICAgICAgICAgICAgIHByaXZhdGUgX3ZpZXdEcmFnU2VydmljZTogVmlld0RyYWdTZXJ2aWNlLFxuICAgICAgICAgICAgICBwcml2YXRlIF9kZXN0cm95UmVmOiBEZXN0cm95UmVmLFxuICAgICAgICAgICAgICBwcml2YXRlIF96b25lOiBOZ1pvbmUpIHtcbiAgICB0aGlzLl9ob3N0ID0gaG9zdC5uYXRpdmVFbGVtZW50O1xuICAgIHRoaXMuZHJhZ292ZXIkID0gdGhpcy5fdmlld0RyYWdTZXJ2aWNlLnRhYmJhckRyYWdPdmVyJC5waXBlKG1hcChwYXJ0SWQgPT4gcGFydElkID09PSB0aGlzLl9wYXJ0LmlkKSk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5pbnN0YWxsQWN0aXZlVmlld1Njcm9sbGVyKCk7XG4gICAgdGhpcy5pbnN0YWxsU2Nyb2xsZWRJbnRvVmlld1VwZGF0ZXIoKTtcbiAgICB0aGlzLmluc3RhbGxWaWV3RHJhZ0xpc3RlbmVyKCk7XG4gICAgdGhpcy5pbnN0YWxsVGFiYmFySW5kZW50U2l6ZURldGVjdG9yKCk7XG4gICAgdGhpcy5pbnN0YWxsVmlld3BvcnRDbGllbnRTaXplRGV0ZWN0b3IoKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RibGNsaWNrJywgWyckZXZlbnQnXSlcbiAgcHVibGljIG9uRG91YmxlQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fcGFydC5pc0luTWFpbkFyZWEpIHtcbiAgICAgIHRoaXMuX3JvdXRlci5uYXZpZ2F0ZShsYXlvdXQgPT4gbGF5b3V0LnRvZ2dsZU1heGltaXplZCgpKS50aGVuKCk7XG4gICAgfVxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgcHVibGljIGdldCB2aWV3SWRzJCgpOiBPYnNlcnZhYmxlPFZpZXdJZFtdPiB7XG4gICAgcmV0dXJuIHRoaXMuX3BhcnQudmlld0lkcyQ7XG4gIH1cblxuICBwdWJsaWMgb25UYWJiYXJWaWV3cG9ydERpbWVuc2lvbkNoYW5nZSgpOiB2b2lkIHtcbiAgICB0aGlzLl92aWV3cG9ydENoYW5nZSQubmV4dCgpO1xuICB9XG5cbiAgcHVibGljIG9uU2Nyb2xsKCk6IHZvaWQge1xuICAgIHRoaXMuX3ZpZXdwb3J0Q2hhbmdlJC5uZXh0KCk7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIGludm9rZWQgd2hlbiB0aGUgdXNlciBzdGFydHMgZHJhZ2dpbmcgYSB0YWIgb2YgdGhpcyB0YWJiYXIuXG4gICAqL1xuICBASG9zdExpc3RlbmVyKCdkcmFnc3RhcnQnLCBbJyRldmVudCddKVxuICBwdWJsaWMgb25WaWV3RHJhZ1N0YXJ0KGV2ZW50OiBEcmFnRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuX3ZpZXdEcmFnU2VydmljZS5pc1ZpZXdEcmFnRXZlbnQoZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZHJhZ0RhdGEgPSB0aGlzLl92aWV3RHJhZ1NlcnZpY2Uudmlld0RyYWdEYXRhITtcbiAgICBjb25zdCBkcmFnU291cmNlSW5kZXggPSB0aGlzLl92aWV3VGFicy5maW5kSW5kZXgodmlld1RhYiA9PiB2aWV3VGFiLnZpZXdJZCA9PT0gZHJhZ0RhdGEudmlld0lkKTtcbiAgICBjb25zdCBkcmFnU291cmNlVmlld1RhYiA9IHRoaXMuX3ZpZXdUYWJzW2RyYWdTb3VyY2VJbmRleF07XG4gICAgY29uc3QgZHJvcFRhcmdldFZpZXdUYWIgPSB0aGlzLl92aWV3VGFic1tkcmFnU291cmNlSW5kZXggKyAxXSA/PyAnZW5kJztcblxuICAgIC8vIENvbnN0cmFpbiBmdW5jdGlvbiBmb3Igc25hcHBpbmcgdGhlIGRyYWcgaW1hZ2UgdG8gdGhlIHRhYmJhciB3aGVuIGRyYWdnaW5nIG5lYXIgaXQuXG4gICAgdGhpcy5fY29uc3RyYWluRm4gPSB0aGlzLmNyZWF0ZURyYWdJbWFnZUNvbnN0cmFpbkZuKCk7XG4gICAgdGhpcy5fdmlld1RhYkRyYWdJbWFnZVJlbmRlcmVyLnNldENvbnN0cmFpbkRyYWdJbWFnZVJlY3RGbih0aGlzLl9jb25zdHJhaW5Gbik7XG4gICAgdGhpcy5fdmlld0RyYWdTZXJ2aWNlLnNldFRhYmJhckRyYWdvdmVyKHRoaXMuX3BhcnQuaWQpO1xuXG4gICAgLy8gV2hlbiBzdGFydCBkcmFnZ2luZyBhIHZpZXcgdGFiLCB3ZSByZW1vdmUgaXQgZnJvbSB0aGUgdGFiYmFyIGJ5IHNldHRpbmcgaXRzIGBkaXNwbGF5YCB0byBgbm9uZWAgYW5kIHJlbmRlciBpdHMgZHJhZyBpbWFnZSBpbiBgVmlld1RhYkRyYWdJbWFnZVJlbmRlcmVyYCBpbnN0ZWFkLlxuICAgIC8vIEhvd2V2ZXIsIGRvIG5vdCB1bnNldCB0aGUgYGRpc3BsYXlgIG9mIHRoZSBkcmFnIHNvdXJjZSBkdXJpbmcgYGRyYWdzdGFydGAuIE90aGVyd2lzZSwgdGhlIG5hdGl2ZSBkcmFnIG9wZXJhdGlvbiB3b3VsZCBiZSBjb3JydXB0ZWQgaW4gQ2hyb21lIGFuZCBFZGdlIChidXQgbm90IGluIEZpcmVmb3gpLlxuICAgIGFuaW1hdGlvbkZyYW1lU2NoZWR1bGVyLnNjaGVkdWxlKCgpID0+IHtcbiAgICAgIHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIgPSBkcmFnU291cmNlVmlld1RhYjtcbiAgICAgIHRoaXMuZHJvcFRhcmdldFZpZXdUYWIgPSBkcm9wVGFyZ2V0Vmlld1RhYjsgLy8gU2V0IGRyb3AgdGFyZ2V0IHRvIGF2b2lkIHRhYiBhbmltYXRpb24uXG4gICAgICBzZXRDc3NWYXJpYWJsZSh0aGlzLl9ob3N0LCB7XG4gICAgICAgICctLcm1cGFydC1iYXItZHJhZy1zb3VyY2Utd2lkdGgnOiBgJHtkcmFnRGF0YS52aWV3VGFiV2lkdGh9cHhgLFxuICAgICAgICAnLS3JtXBhcnQtYmFyLWRyYWctaW1hZ2UtcGxhY2Vob2xkZXItd2lkdGgnOiBgJHtkcmFnRGF0YS52aWV3VGFiV2lkdGh9cHhgLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBXaGVuIGRyYWdnaW5nIGEgdGFiIHZlcnkgcXVpY2tseSBvdXQgb2YgdGhpcyB0YWJiYXIsIG9ubHkgdGhlIGBkcmFnc3RhcnRgIGV2ZW50IGdldHMgZmlyZWQsIGJ1dCBub3QgdGhlIGBkcmFnZW50ZXJgIGV2ZW50LlxuICAgIC8vIFRoZXJlZm9yZSwgd2Ugc3Vic2NyaWJlIHRvIGdsb2JhbCBgZHJhZ2VudGVyYCBldmVudHMgYW5kIG1hbnVhbGx5IGludm9rZSBgb25UYWJiYXJEcmFnTGVhdmVgIHRvIGNvcnJlY3RseSBkaXNwbGF5IHRoZSB0YWJzIGFuZCB0aGUgYWN0aXZlIHZpZXcuXG4gICAgdGhpcy5fdmlld0RyYWdTZXJ2aWNlLnZpZXdEcmFnJCh3aW5kb3csIHtldmVudFR5cGU6IFsnZHJhZ2VudGVyJ119KVxuICAgICAgLnBpcGUodGFrZSgxKSwgdGFrZVVudGlsKHRoaXMuX2RyYWdlbmQkKSwgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZShldmVudCA9PiB7XG4gICAgICAgIC8vIENoZWNrIGlmIHRoZSB1c2VyIGNvbnRpbnVlcyBkcmFnZ2luZyBvdmVyIHRoaXMgdGFiYmFyLlxuICAgICAgICAvLyBJZiBub3QsIHRoZSB1c2VyIGhhcyBxdWlja2x5IGRyYWdnZWQgdGhlIHRhYiBvdXQgb2YgdGhlIHRhYmJhciBhbmQgd2UgIG1hbnVhbGx5IGNhbGwgYG9uVGFiYmFyRHJhZ0xlYXZlYC5cbiAgICAgICAgaWYgKCh0aGlzLl9ob3N0LmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGV2ZW50LnRhcmdldCBhcyBFbGVtZW50KSAmIE5vZGUuRE9DVU1FTlRfUE9TSVRJT05fQ09OVEFJTkVEX0JZKSA9PT0gMCkge1xuICAgICAgICAgIHRoaXMub25UYWJiYXJEcmFnTGVhdmUoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIGludm9rZWQgd2hlbiB0aGUgdXNlciBlbmRzIGRyYWdnaW5nIGEgdGFiIG9mIHRoaXMgdGFiYmFyLlxuICAgKlxuICAgKiBJbnZva2VkIG9ubHkgaW4gdGhlIHRhYmJhciB3aGVyZSB0aGUgZHJhZyBvcGVyYXRpb24gc3RhcnRlZCwgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZSBkcmFnIG9wZXJhdGlvbiB3YXMgY29tcGxldGVkIG9yIGNhbmNlbGVkLlxuICAgKi9cbiAgQEhvc3RMaXN0ZW5lcignZHJhZ2VuZCcpXG4gIHB1YmxpYyBvblZpZXdEcmFnRW5kKCk6IHZvaWQge1xuICAgIHRoaXMuX2RyYWdlbmQkLm5leHQoKTtcbiAgICB0aGlzLnVuc2V0RHJhZ1N0YXRlKCk7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIGludm9rZWQgd2hlbiB0aGUgdXNlciBkcmFncyBhIHRhYiBpbnRvIHRoaXMgdGFiYmFyLlxuICAgKi9cbiAgcHJpdmF0ZSBvblRhYmJhckRyYWdFbnRlcihldmVudDogRHJhZ0V2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5fZHJhZ2VudGVyJC5uZXh0KCk7XG4gICAgdGhpcy5fdmlld0RyYWdTZXJ2aWNlLnNldFRhYmJhckRyYWdvdmVyKHRoaXMuX3BhcnQuaWQpO1xuICAgIHRoaXMuX2RyYWdEYXRhID0gdGhpcy5fdmlld0RyYWdTZXJ2aWNlLnZpZXdEcmFnRGF0YSE7XG5cbiAgICAvLyBDb25zdHJhaW4gZnVuY3Rpb24gZm9yIHNuYXBwaW5nIHRoZSBkcmFnIGltYWdlIHRvIHRoZSB0YWJiYXIgd2hlbiBkcmFnZ2luZyBuZWFyIGl0LlxuICAgIGlmICghdGhpcy5fY29uc3RyYWluRm4pIHtcbiAgICAgIHRoaXMuX2NvbnN0cmFpbkZuID0gdGhpcy5jcmVhdGVEcmFnSW1hZ2VDb25zdHJhaW5GbigpO1xuICAgICAgdGhpcy5fdmlld1RhYkRyYWdJbWFnZVJlbmRlcmVyLnNldENvbnN0cmFpbkRyYWdJbWFnZVJlY3RGbih0aGlzLl9jb25zdHJhaW5Gbik7XG4gICAgfVxuXG4gICAgLy8gTG9jYXRlIGRyb3AgdGFyZ2V0IHRvIGhhdmUgYSBuaWNlIGFuaW1hdGlvbiBmb3IgdGhlIGRyYWcgc291cmNlIHBsYWNlaG9sZGVyLlxuICAgIHRoaXMuZHJvcFRhcmdldFZpZXdUYWIgPSB0aGlzLmNvbXB1dGVEcm9wVGFyZ2V0KGV2ZW50KTtcblxuICAgIC8vIFNldCB0aGUgQ1NTIGNsYXNzICdkcmFnLWVudGVyJyB0byBpbmRpY2F0ZSBlbnRlcmluZyB0aGUgdGFiYmFyLlxuICAgIHNldENzc0NsYXNzKHRoaXMuX2hvc3QsICdkcmFnLWVudGVyJywgJ2RyYWctb3ZlcicpO1xuICAgIHRoaXMuX2RyYWdBbmltYXRpb25TdGFibGUkXG4gICAgICAucGlwZSh0YWtlKDEpLCB0YWtlVW50aWwodGhpcy5fZHJhZ2VudGVyJCksIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoe2NvbXBsZXRlOiAoKSA9PiB1bnNldENzc0NsYXNzKHRoaXMuX2hvc3QsICdkcmFnLWVudGVyJyl9KTtcblxuICAgIHNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsIHtcbiAgICAgICctLcm1cGFydC1iYXItZHJhZy1zb3VyY2Utd2lkdGgnOiBgJHt0aGlzLl9kcmFnRGF0YS52aWV3VGFiV2lkdGh9cHhgLFxuICAgICAgJy0tybVwYXJ0LWJhci1kcmFnLWltYWdlLXBsYWNlaG9sZGVyLXdpZHRoJzogYCR7dGhpcy5fZHJhZ0RhdGEudmlld1RhYldpZHRofXB4YCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgaW52b2tlZCB3aGVuIHRoZSB1c2VyIGRyYWdzIGEgdGFiIG91dCBvZiB0aGlzIHRhYmJhci5cbiAgICovXG4gIHByaXZhdGUgb25UYWJiYXJEcmFnTGVhdmUoKTogdm9pZCB7XG4gICAgdGhpcy5fZHJhZ2xlYXZlJC5uZXh0KCk7XG5cbiAgICAvLyBTZXQgdGhlIENTUyBjbGFzcyAnZHJhZy1sZWF2ZScgdG8gaW5kaWNhdGUgbGVhdmluZyB0aGUgdGFiYmFyLlxuICAgIHNldENzc0NsYXNzKHRoaXMuX2hvc3QsICdkcmFnLWxlYXZlJyk7XG4gICAgdGhpcy5fZHJhZ0FuaW1hdGlvblN0YWJsZSRcbiAgICAgIC5waXBlKHRha2UoMSksIHRha2VVbnRpbCh0aGlzLl9kcmFnbGVhdmUkKSwgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSh7Y29tcGxldGU6ICgpID0+IHVuc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ2RyYWctbGVhdmUnKX0pO1xuXG4gICAgdGhpcy51bnNldERyYWdTdGF0ZSh7dW5zZXREcmFnU291cmNlOiBmYWxzZX0pO1xuXG4gICAgLy8gQWN0aXZhdGUgdGhlIHZpZXcgbmV4dCB0byB0aGUgdmlldyBiZWluZyBkcmFnZ2VkIG91dCBvZiB0aGlzIHRhYmJhci4gQnV0LCBkbyBub3QgcHVzaCB0aGUgbmF2aWdhdGlvbiBpbnRvIGJyb3dzaW5nIGhpc3Rvcnkgc3RhY2suXG4gICAgaWYgKHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIgJiYgdGhpcy5kcmFnU291cmNlVmlld1RhYi5hY3RpdmUpIHtcbiAgICAgIHRoaXMuX3JvdXRlci5uYXZpZ2F0ZShsYXlvdXQgPT4gbGF5b3V0LmFjdGl2YXRlQWRqYWNlbnRWaWV3KHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIhLnZpZXdJZCksIHtza2lwTG9jYXRpb25DaGFuZ2U6IHRydWV9KS50aGVuKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBpbnZva2VkIHdoaWxlIHRoZSB1c2VyIGlzIGRyYWdnaW5nIGEgdGFiIG92ZXIgdGhpcyB0YWJiYXIuXG4gICAqL1xuICBwcml2YXRlIG9uVGFiYmFyRHJhZ092ZXIoZXZlbnQ6IERyYWdFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7IC8vIGFsbG93IHZpZXcgZHJvcFxuXG4gICAgLy8gTG9jYXRlIHRoZSB0YWIgb3ZlciB3aGljaCB0aGUgdXNlciBpcyBkcmFnZ2luZyB0aGUgdGFiLCBidXQgb25seSBhZnRlciBwZW5kaW5nIHRyYW5zaXRpb25zIGhhdmUgZW5kZWQgdG8gcHJldmVudCB0YWJzIGZyb20gc2xpZGluZyBiYWNrIGFuZCBmb3J0aC5cbiAgICBpZiAodGhpcy5pc0RyYWdBbmltYXRpb25TdGFibGUoKSkge1xuICAgICAgdGhpcy5kcm9wVGFyZ2V0Vmlld1RhYiA9IHRoaXMuY29tcHV0ZURyb3BUYXJnZXQoZXZlbnQpO1xuICAgICAgLy8gU3luY2hyb25pemUgdGhlIHdpZHRoIG9mIHRoZSBkcmFnIHNvdXJjZSBwbGFjZWhvbGRlciB3aXRoIHRoZSBkcmFnIHBvaW50ZXIgcG9zaXRpb24gdG8gbW92ZSBhY3Rpb25zIGFsb25nIHdpdGggdGhlIHBvaW50ZXIuXG4gICAgICBzZXRDc3NWYXJpYWJsZSh0aGlzLl9ob3N0LCB7Jy0tybVwYXJ0LWJhci1kcmFnLWltYWdlLXBsYWNlaG9sZGVyLXdpZHRoJzogYCR7dGhpcy5jYWxjdWxhdGVEcmFnSW1hZ2VQbGFjZWhvbGRlcldpZHRoKGV2ZW50KX1weGB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIGludm9rZWQgd2hlbiB0aGUgdXNlciBkcm9wcyBhIHRhYiBpbiB0aGlzIHRhYmJhci5cbiAgICovXG4gIHByaXZhdGUgb25UYWJiYXJEcm9wKCk6IHZvaWQge1xuICAgIHRoaXMuX3ZpZXdEcmFnU2VydmljZS5kaXNwYXRjaFZpZXdNb3ZlRXZlbnQoe1xuICAgICAgc291cmNlOiB7XG4gICAgICAgIHdvcmtiZW5jaElkOiB0aGlzLl9kcmFnRGF0YSEud29ya2JlbmNoSWQsXG4gICAgICAgIHBhcnRJZDogdGhpcy5fZHJhZ0RhdGEhLnBhcnRJZCxcbiAgICAgICAgdmlld0lkOiB0aGlzLl9kcmFnRGF0YSEudmlld0lkLFxuICAgICAgICBhbHRlcm5hdGl2ZVZpZXdJZDogdGhpcy5fZHJhZ0RhdGEhLmFsdGVybmF0aXZlVmlld0lkLFxuICAgICAgICB2aWV3VXJsU2VnbWVudHM6IHRoaXMuX2RyYWdEYXRhIS52aWV3VXJsU2VnbWVudHMsXG4gICAgICAgIG5hdmlnYXRpb25IaW50OiB0aGlzLl9kcmFnRGF0YSEubmF2aWdhdGlvbkhpbnQsXG4gICAgICAgIGNsYXNzTGlzdDogdGhpcy5fZHJhZ0RhdGEhLmNsYXNzTGlzdCxcbiAgICAgIH0sXG4gICAgICB0YXJnZXQ6IHtcbiAgICAgICAgd29ya2JlbmNoSWQ6IHRoaXMuX3dvcmtiZW5jaElkLFxuICAgICAgICBwb3NpdGlvbjogdGhpcy5kcm9wVGFyZ2V0Vmlld1RhYiA9PT0gJ2VuZCcgPyAnZW5kJyA6IHRoaXMuX3ZpZXdUYWJzLmluZGV4T2YodGhpcy5kcm9wVGFyZ2V0Vmlld1RhYiEpLFxuICAgICAgICBlbGVtZW50SWQ6IHRoaXMuX3BhcnQuaWQsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gV2FpdCB1bmRvaW5nIHRoZSBkcmFnIHN0YXRlIHVudGlsIGZsdXNoZWQgdGFiIGNoYW5nZXMgdG8gdGhlIERPTSwgaS5lLiwgYWZ0ZXIgdGhlIGxheW91dCByb3V0aW5nIGN5Y2xlIGNvbXBsZXRlcy5cbiAgICAvLyBJZiB3ZSB3ZXJlIHRvIHVuZG8gdGhlIGRyYWcgc3RhdGUgaW1tZWRpYXRlbHkgZHVyaW5nIHRoZSBjb3Vyc2Ugb2YgdGhlIGRyb3AgZXZlbnQsIHRoZSB0YWIgbGF5b3V0IHdvdWxkIHRlbXBvcmFyaWx5XG4gICAgLy8gcmV2ZXJ0IHRvIHRoZSBzdGF0ZSBiZWZvcmUgdGhlIGRyYWcgb3BlcmF0aW9uLCByZXN1bHRpbmcgaW4gYW4gdWdseSBmbGlja2VyLlxuICAgIGZpcnN0VmFsdWVGcm9tKHRoaXMuX3dvcmtiZW5jaExheW91dFNlcnZpY2Uub25MYXlvdXRDaGFuZ2UkKS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMudW5zZXREcmFnU3RhdGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2NhdGVzIHRoZSB0YWIgYmVmb3JlIHdoaWNoIHRoZSBkcmFnZ2VkIHRhYiBpcyB0byBiZSBpbnNlcnRlZCB3aGVuIGl0IGlzIGRyb3BwZWQuIERyYWdnaW5nIGJleW9uZCB0aGUgbGFzdCB0YWIgcmV0dXJucyBgZW5kYC5cbiAgICovXG4gIHB1YmxpYyBjb21wdXRlRHJvcFRhcmdldChldmVudDogRHJhZ0V2ZW50KTogVmlld1RhYkNvbXBvbmVudCB8ICdlbmQnIHtcbiAgICBjb25zdCB2aWV3RHJhZ0ltYWdlUmVjdCA9IHRoaXMuX3ZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlci5jYWxjdWxhdGVEcmFnSW1hZ2VSZWN0KHRoaXMuX2RyYWdEYXRhISwgZXZlbnQpO1xuICAgIGNvbnN0IHZpZXdUYWJzID0gdGhpcy5fdmlld1RhYnMuZmlsdGVyKHZpZXdUYWIgPT4gdmlld1RhYiAhPT0gdGhpcy5kcmFnU291cmNlVmlld1RhYik7XG5cbiAgICBmb3IgKGNvbnN0IHZpZXdUYWIgb2Ygdmlld1RhYnMpIHtcbiAgICAgIGNvbnN0IHZpZXdUYWJSZWN0ID0gdmlld1RhYi5ob3N0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3Qgdmlld1RhYk1pZGRsZSA9IHZpZXdUYWJSZWN0LmxlZnQgKyAodmlld1RhYlJlY3Qud2lkdGggLyAyKTtcbiAgICAgIGlmICh2aWV3RHJhZ0ltYWdlUmVjdC5sZWZ0IDwgdmlld1RhYk1pZGRsZSAmJiAodmlld1RhYiAhPT0gdGhpcy5kcm9wVGFyZ2V0Vmlld1RhYiB8fCB2aWV3RHJhZ0ltYWdlUmVjdC5yaWdodCA8IHZpZXdUYWJNaWRkbGUpKSB7XG4gICAgICAgIHJldHVybiB2aWV3VGFiO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gJ2VuZCc7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgZnVuY3Rpb24gZm9yIHNuYXBwaW5nIHRoZSBkcmFnIGltYWdlIHRvIHRoZSB0YWJiYXIgd2hlbiBkcmFnZ2luZyBuZWFyIGl0LlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVEcmFnSW1hZ2VDb25zdHJhaW5GbigpOiBDb25zdHJhaW5GbiB7XG4gICAgY29uc3QgaG9zdExlZnQgPSB0aGlzLl9ob3N0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQ7XG4gICAgY29uc3QgbWF4Vmlld3BvcnRXaWR0aCA9IHRoaXMuY2FsY3VsYXRlTWF4Vmlld3BvcnRXaWR0aCgpO1xuICAgIHJldHVybiAocmVjdDogVmlld0RyYWdJbWFnZVJlY3QpOiBWaWV3RHJhZ0ltYWdlUmVjdCA9PiB7XG4gICAgICBjb25zdCB2aWV3cG9ydEJvdW5kaW5nQm94ID0gdGhpcy5fdmlld3BvcnRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICByZXR1cm4gbmV3IFZpZXdEcmFnSW1hZ2VSZWN0KHtcbiAgICAgICAgeDogTWF0aC5taW4oTWF0aC5tYXgoaG9zdExlZnQgKyB0aGlzLl90YWJiYXJJbmRlbnQubGVmdCwgcmVjdC54KSwgaG9zdExlZnQgKyBtYXhWaWV3cG9ydFdpZHRoIC0gcmVjdC53aWR0aCAtIHRoaXMuX3RhYmJhckluZGVudC5yaWdodCksXG4gICAgICAgIHk6IHZpZXdwb3J0Qm91bmRpbmdCb3gudG9wLFxuICAgICAgICB3aWR0aDogcmVjdC53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiB2aWV3cG9ydEJvdW5kaW5nQm94LmhlaWdodCwgLy8gZml0IGludG8gdGFiYmFyLCBlLmcuLCB3aGVuIGRyYWdnaW5nIGEgdGFiIGludG8gYSB0YWJiYXIgb2YgYSBkaWZmZXJlbnQgaGVpZ2h0XG4gICAgICB9KTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgdGhlIG1heGltdW0gd2lkdGggb2YgdGhlIHRhYmJhciB2aWV3cG9ydCBiZWZvcmUgYW4gb3ZlcmZsb3cgd291bGQgb2NjdXIsIHdoaWNoIGNhbiB0aGVuIGJlIHVzZWQgdG8gY29uc3RyYWluIHRoZSBkcmFnIGltYWdlLlxuICAgKlxuICAgKiBUbyBjYWxjdWxhdGUgdGhlIGVmZmVjdGl2ZSB3aWR0aCwgd2UgbmVlZCB0byBzaW11bGF0ZSBhbiBvdmVyZmxvdyBpbiB0aGUgRE9NLiBUaGVyZWZvcmUsIGNhbGwgdGhpcyBtZXRob2Qgb25seSBmcm9tIGBkcmFnc3RhcnRgIGFuZCBub3RcbiAgICogZnJvbSBgZHJhZ292ZXJgIGFuZCBkaXNhYmxlIGFuaW1hdGlvbnMuXG4gICAqL1xuICBwcml2YXRlIGNhbGN1bGF0ZU1heFZpZXdwb3J0V2lkdGgoKTogbnVtYmVyIHtcbiAgICBjb25zdCBjdXJyZW50V2lkdGggPSB0aGlzLl9ob3N0LnN0eWxlLmdldFByb3BlcnR5VmFsdWUoJy0tybVwYXJ0LWJhci1kcmFnLWltYWdlLXBsYWNlaG9sZGVyLXdpZHRoJyk7XG5cbiAgICAvLyBEaXNhYmxlIGFuaW1hdGlvbnMgZHVyaW5nIGNhbGN1bGF0aW9uIGFuZCBmb3JjZSB0aGUgdmlld3BvcnQgdG8gb3ZlcmZsb3cuXG4gICAgc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ2NhbGN1bGF0aW5nLW1heC12aWV3cG9ydC13aWR0aCcpO1xuICAgIHNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsIHsnLS3JtXBhcnQtYmFyLWRyYWctaW1hZ2UtcGxhY2Vob2xkZXItd2lkdGgnOiBgJHt0aGlzLl9ob3N0LmNsaWVudFdpZHRofXB4YH0pO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gdGhpcy5fdmlld3BvcnRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGg7XG4gICAgfVxuICAgIGZpbmFsbHkge1xuICAgICAgc2V0Q3NzVmFyaWFibGUodGhpcy5faG9zdCwgeyctLcm1cGFydC1iYXItZHJhZy1pbWFnZS1wbGFjZWhvbGRlci13aWR0aCc6IGN1cnJlbnRXaWR0aCB8fCBudWxsfSk7XG4gICAgICB1bnNldENzc0NsYXNzKHRoaXMuX2hvc3QsICdjYWxjdWxhdGluZy1tYXgtdmlld3BvcnQtd2lkdGgnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyB0aGUgd2lkdGggZm9yIHRoZSBkcmFnIGltYWdlIHBsYWNlaG9sZGVyLlxuICAgKlxuICAgKiAtIFdoZW4gZHJhZ2dpbmcgb3ZlciB0YWJzLCB0aGUgd2lkdGggaXMgZXF1YWwgdG8gdGhlIHdpZHRoIG9mIHRoZSBkcmFnIHNvdXJjZS5cbiAgICogLSBXaGVuIGRyYWdnaW5nIHRvIHRoZSByaWdodCBvZiB0aGUgbGFzdCB0YWIsIHRoZSB3aWR0aCBvZiB0aGUgcGxhY2Vob2xkZXIgaXMgY2FsY3VsYXRlZCBhcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGVcbiAgICogICBsYXN0IHRhYiBhbmQgdGhlIHBvc2l0aW9uIG9mIHRoZSBkcmFnb3ZlciBldmVudC4gQXBwbHlpbmcgdGhpcyB3aWR0aCB3aWxsIHJlc2l6ZSB0aGUgdmlld3BvcnQsIG1vdmluZyBwYXJ0IGFjdGlvbnMgYWxvbmdcbiAgICogICB3aXRoIHRoZSBkcmFnb3ZlciBldmVudC5cbiAgICovXG4gIHByaXZhdGUgY2FsY3VsYXRlRHJhZ0ltYWdlUGxhY2Vob2xkZXJXaWR0aChldmVudDogRHJhZ0V2ZW50KTogbnVtYmVyIHtcbiAgICBjb25zdCB2aWV3RHJhZ0ltYWdlUmVjdCA9IHRoaXMuX3ZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlci5jYWxjdWxhdGVEcmFnSW1hZ2VSZWN0KHRoaXMuX2RyYWdEYXRhISwgZXZlbnQpO1xuICAgIGNvbnN0IGxhc3RWaWV3VGFiID0gdGhpcy5fdmlld1RhYnMuZmlsdGVyKHZpZXdUYWIgPT4gdmlld1RhYiAhPT0gdGhpcy5kcmFnU291cmNlVmlld1RhYikuYXQoLTEpO1xuICAgIGNvbnN0IGxhc3RWaWV3VGFiUmlnaHQgPSBsYXN0Vmlld1RhYj8uaG9zdC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5yaWdodCA/PyB0aGlzLl9ob3N0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQgKyB0aGlzLl90YWJiYXJJbmRlbnQubGVmdDtcbiAgICByZXR1cm4gTWF0aC5tYXgobGFzdFZpZXdUYWJSaWdodCArIHZpZXdEcmFnSW1hZ2VSZWN0LndpZHRoLCB2aWV3RHJhZ0ltYWdlUmVjdC5yaWdodCkgLSBsYXN0Vmlld1RhYlJpZ2h0O1xuICB9XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIENTUyBhbmltYXRpb25zIGhhdmUgZmluaXNoZWQgd2hlbiBkcmFnZ2luZyBhIHRhYiBvdmVyIHRoZSB0YWJiYXIuXG4gICAqIFRoZSBhbmltYXRpb24gaXMgY29uc2lkZXJlZCBzdGFibGUgd2hlbiBhbGwgdGFicyBoYXZlIG1vdmVkIHRvIHRoZWlyIGZpbmFsIHBvc2l0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBpc0RyYWdBbmltYXRpb25TdGFibGUoKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmRyb3BUYXJnZXRWaWV3VGFiKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdmlld1RhYnMuZXZlcnkodmlld1RhYiA9PiBnZXRDc3NUcmFuc2xhdGlvbih2aWV3VGFiLmhvc3QpLnRyYW5zbGF0ZVggPT09ICdub25lJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgdmlld1RhYnMgPSB0aGlzLl92aWV3VGFicy5maWx0ZXIodmlld1RhYiA9PiB2aWV3VGFiICE9PSB0aGlzLmRyYWdTb3VyY2VWaWV3VGFiKTtcbiAgICBjb25zdCBkcm9wVGFyZ2V0SW5kZXggPSB0aGlzLmRyb3BUYXJnZXRWaWV3VGFiID09PSAnZW5kJyA/IHZpZXdUYWJzLmxlbmd0aCA6IHZpZXdUYWJzLmluZGV4T2YodGhpcy5kcm9wVGFyZ2V0Vmlld1RhYiEpO1xuICAgIGNvbnN0IGRyYWdTb3VyY2VXaWR0aCA9IHRoaXMuX2RyYWdEYXRhIS52aWV3VGFiV2lkdGg7XG5cbiAgICByZXR1cm4gdmlld1RhYnMuZXZlcnkoKHZpZXdUYWIsIGkpID0+IHtcbiAgICAgIGNvbnN0IHZpZXdUYWJUcmFuc2xhdGVYID0gZ2V0Q3NzVHJhbnNsYXRpb24odmlld1RhYi5ob3N0KS50cmFuc2xhdGVYO1xuICAgICAgLy8gRXhwZWN0IHRhYnMgcHJlY2VkaW5nIHRoZSBkcm9wIHRhcmdldCBub3QgdG8gYmUgc2hpZnRlZCB0byB0aGUgcmlnaHQuXG4gICAgICBpZiAoaSA8IGRyb3BUYXJnZXRJbmRleCAmJiB2aWV3VGFiVHJhbnNsYXRlWCAhPT0gJ25vbmUnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIC8vIEV4cGVjdCBkcm9wIHRhcmdldCBhbmQgdGFicyBmb2xsb3dpbmcgdGhlIGRyb3AgdGFyZ2V0IHRvIGJlIHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0LlxuICAgICAgaWYgKGkgPj0gZHJvcFRhcmdldEluZGV4ICYmIE1hdGguZmxvb3IoTnVtYmVyKHZpZXdUYWJUcmFuc2xhdGVYKSkgIT09IE1hdGguZmxvb3IoZHJhZ1NvdXJjZVdpZHRoKSkgeyAvLyBjb21wYXJlIGZsb29yZWQgbnVtYmVycyBiZWNhdXNlIGB0cmFuc2xhdGVYYCBpcyBub3QgcHJlY2lzZVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdW5zZXREcmFnU3RhdGUob3B0aW9ucz86IHt1bnNldERyYWdTb3VyY2U/OiBib29sZWFufSk6IHZvaWQge1xuICAgIGlmIChvcHRpb25zPy51bnNldERyYWdTb3VyY2UgPz8gdHJ1ZSkge1xuICAgICAgdGhpcy5kcmFnU291cmNlVmlld1RhYiA9IG51bGw7XG4gICAgfVxuXG4gICAgdGhpcy5kcm9wVGFyZ2V0Vmlld1RhYiA9IG51bGw7XG4gICAgdGhpcy5fZHJhZ0RhdGEgPSBudWxsO1xuICAgIHRoaXMuX3ZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlci51bnNldENvbnN0cmFpbkRyYWdJbWFnZVJlY3RGbih0aGlzLl9jb25zdHJhaW5GbiEpO1xuICAgIHRoaXMuX2NvbnN0cmFpbkZuID0gbnVsbDtcblxuICAgIHVuc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ2RyYWctb3ZlcicpO1xuICAgIHVuc2V0Q3NzVmFyaWFibGUodGhpcy5faG9zdCwgJy0tybVwYXJ0LWJhci1kcmFnLXNvdXJjZS13aWR0aCcsICctLcm1cGFydC1iYXItZHJhZy1pbWFnZS1wbGFjZWhvbGRlci13aWR0aCcpO1xuICAgIHRoaXMuX3ZpZXdEcmFnU2VydmljZS51bnNldFRhYmJhckRyYWdvdmVyKHRoaXMuX3BhcnQuaWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgX3ZpZXdUYWJzKCk6IFZpZXdUYWJDb21wb25lbnRbXSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZpZXdUYWJzJC52YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTY3JvbGxzIHRoZSB0YWIgb2YgdGhlIGFjdGl2ZSB2aWV3IGludG8gdmlldy5cbiAgICovXG4gIHByaXZhdGUgaW5zdGFsbEFjdGl2ZVZpZXdTY3JvbGxlcigpOiB2b2lkIHtcbiAgICB0aGlzLl92aWV3VGFicyRcbiAgICAgIC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAodmlld1RhYnMgPT4gY29tYmluZUxhdGVzdCh2aWV3VGFicy5tYXAodmlld1RhYiA9PiB2aWV3VGFiLnZpZXcuYWN0aXZlJCkpKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIC8vIFRoZXJlIG1heSBiZSBubyBhY3RpdmUgdmlldyBpbiB0aGUgdGFiYmFyLCBlLmcuLCB3aGVuIGRyYWdnaW5nIHRoZSBsYXN0IHZpZXcgb3V0IG9mIHRoZSB0YWJiYXIuXG4gICAgICAgIGNvbnN0IGFjdGl2ZVZpZXdUYWIgPSB0aGlzLl92aWV3VGFicy5maW5kKHZpZXdUYWIgPT4gdmlld1RhYi5hY3RpdmUpO1xuICAgICAgICBpZiAoYWN0aXZlVmlld1RhYiAmJiAhdGhpcy5fdmlld3BvcnRDb21wb25lbnQuaXNFbGVtZW50SW5WaWV3KGFjdGl2ZVZpZXdUYWIuaG9zdCwgJ2Z1bGwnKSkge1xuICAgICAgICAgIHRoaXMuX3ZpZXdwb3J0Q29tcG9uZW50LnNjcm9sbEludG9WaWV3KGFjdGl2ZVZpZXdUYWIuaG9zdCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMge0BsaW5rIMm1V29ya2JlbmNoVmlld30gd2hlbiBpdHMgdGFiIGlzIHNjcm9sbGVkIGludG8gdmlldy5cbiAgICovXG4gIHByaXZhdGUgaW5zdGFsbFNjcm9sbGVkSW50b1ZpZXdVcGRhdGVyKCk6IHZvaWQge1xuICAgIHRoaXMuX3ZpZXdwb3J0Q2hhbmdlJFxuICAgICAgLnBpcGUoXG4gICAgICAgIG1hcCgoKSA9PiB0aGlzLl92aWV3VGFicyksXG4gICAgICAgIGZpbHRlckFycmF5KHZpZXdUYWIgPT4gdmlld1RhYiAhPT0gdGhpcy5kcmFnU291cmNlVmlld1RhYiksIC8vIHNraXAgZHJhZyBzb3VyY2UgYXMgYWx3YXlzIHNjcm9sbGVkIG91dCBvZiB2aWV3XG4gICAgICAgIG1lcmdlTWFwKHZpZXdUYWJzID0+IGZyb20odmlld1RhYnMpKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSh2aWV3VGFiID0+IHtcbiAgICAgICAgdmlld1RhYi52aWV3LnNjcm9sbGVkSW50b1ZpZXcgPSB0aGlzLl92aWV3cG9ydENvbXBvbmVudC5pc0VsZW1lbnRJblZpZXcodmlld1RhYi5ob3N0LCAnZnVsbCcpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGluc3RhbGxWaWV3RHJhZ0xpc3RlbmVyKCk6IHZvaWQge1xuICAgIHRoaXMuX3ZpZXdEcmFnU2VydmljZS52aWV3RHJhZyQodGhpcy5faG9zdClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKGV2ZW50OiBEcmFnRXZlbnQpID0+IHtcbiAgICAgICAgc3dpdGNoIChldmVudC50eXBlKSB7XG4gICAgICAgICAgY2FzZSAnZHJhZ2VudGVyJzpcbiAgICAgICAgICAgIHRoaXMub25UYWJiYXJEcmFnRW50ZXIoZXZlbnQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZHJhZ292ZXInOlxuICAgICAgICAgICAgdGhpcy5vblRhYmJhckRyYWdPdmVyKGV2ZW50KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2RyYWdsZWF2ZSc6XG4gICAgICAgICAgICB0aGlzLm9uVGFiYmFyRHJhZ0xlYXZlKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdkcm9wJzpcbiAgICAgICAgICAgIHRoaXMub25UYWJiYXJEcm9wKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGluc3RhbGxWaWV3cG9ydENsaWVudFNpemVEZXRlY3RvcigpOiB2b2lkIHtcbiAgICBmcm9tRGltZW5zaW9uJCh0aGlzLl92aWV3cG9ydENvbXBvbmVudC52aWV3cG9ydENsaWVudEVsZW1lbnQpXG4gICAgICAucGlwZShcbiAgICAgICAgc3Vic2NyaWJlSW5zaWRlKGZuID0+IHRoaXMuX3pvbmUucnVuKGZuKSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fdmlld3BvcnRDaGFuZ2UkLm5leHQoKSk7XG4gIH1cblxuICBwcml2YXRlIGluc3RhbGxUYWJiYXJJbmRlbnRTaXplRGV0ZWN0b3IoKTogdm9pZCB7XG4gICAgY29tYmluZUxhdGVzdChbZnJvbURpbWVuc2lvbiQodGhpcy5fdGFiQ29ybmVyUmFkaXVzRWxlbWVudC5uYXRpdmVFbGVtZW50KSwgZnJvbURpbWVuc2lvbiQodGhpcy5fcGFkZGluZ0lubGluZUVsZW1lbnQubmF0aXZlRWxlbWVudCldKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN1YnNjcmliZUluc2lkZShmbiA9PiB0aGlzLl96b25lLnJ1bk91dHNpZGVBbmd1bGFyKGZuKSksXG4gICAgICAgIG1hcEFycmF5KGRpbWVuc2lvbiA9PiBkaW1lbnNpb24uY2xpZW50V2lkdGgpLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZiksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKChbdGFiQ29ybmVyUmFkaXVzLCBwYWRkaW5nSW5saW5lXSkgPT4ge1xuICAgICAgICB0aGlzLl90YWJiYXJJbmRlbnQgPSB7bGVmdDogdGFiQ29ybmVyUmFkaXVzICsgcGFkZGluZ0lubGluZSwgcmlnaHQ6IHRhYkNvcm5lclJhZGl1cyArIHBhZGRpbmdJbmxpbmV9O1xuICAgICAgICBzZXRDc3NWYXJpYWJsZSh0aGlzLl9ob3N0LCB7Jy0tybVwYXJ0LWJhci1pbmRlbnQtbGVmdCc6IGAke3RoaXMuX3RhYmJhckluZGVudC5sZWZ0fXB4YH0pO1xuICAgICAgICBzZXRDc3NWYXJpYWJsZSh0aGlzLl9ob3N0LCB7Jy0tybVwYXJ0LWJhci1pbmRlbnQtcmlnaHQnOiBgJHt0aGlzLl90YWJiYXJJbmRlbnQucmlnaHR9cHhgfSk7XG4gICAgICB9KTtcbiAgfVxufVxuIiwiPHNjaS12aWV3cG9ydCBjbGFzcz1cInRhYmJhclwiIHNjcm9sbGJhclN0eWxlPVwiaGlkZGVuXCJcbiAgICAgICAgICAgICAgW2NsYXNzLmRyYWdvdmVyXT1cImRyYWdvdmVyJCB8IGFzeW5jXCJcbiAgICAgICAgICAgICAgc2NpRGltZW5zaW9uIChzY2lEaW1lbnNpb25DaGFuZ2UpPVwib25UYWJiYXJWaWV3cG9ydERpbWVuc2lvbkNoYW5nZSgpXCJcbiAgICAgICAgICAgICAgKHNjcm9sbCk9XCJvblNjcm9sbCgpXCI+XG4gIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHZpZXdJZCBvZiB2aWV3SWRzJCB8IGFzeW5jO1wiPlxuICAgIDxkaXYgY2xhc3M9XCJkaXZpZGVyXCIgKm5nSWY9XCJ2aWV3dGFiID09PSBkcm9wVGFyZ2V0Vmlld1RhYlwiPjwvZGl2PlxuICAgIDx3Yi12aWV3LXRhYiAjdmlld3RhYlxuICAgICAgICAgICAgICAgICBbdmlld0lkXT1cInZpZXdJZFwiXG4gICAgICAgICAgICAgICAgIFtjbGFzcy5kcmFnLXNvdXJjZV09XCJ2aWV3dGFiID09PSBkcmFnU291cmNlVmlld1RhYlwiXG4gICAgICAgICAgICAgICAgIFtjbGFzcy5kcm9wLXRhcmdldF09XCJ2aWV3dGFiID09PSBkcm9wVGFyZ2V0Vmlld1RhYlwiPlxuICAgIDwvd2Itdmlldy10YWI+XG4gICAgPGRpdiBjbGFzcz1cImRpdmlkZXJcIj48L2Rpdj5cbiAgPC9uZy1jb250YWluZXI+XG5cbiAgPCEtLSBQbGFjZWhvbGRlciBlbGVtZW50IHRvIGdyb3cgdGhlIHZpZXdwb3J0IHRvIGZpdCB0aGUgZHJhZyBpbWFnZS4gLS0+XG4gIDxkaXYgY2xhc3M9XCJkcmFnLWltYWdlLXBsYWNlaG9sZGVyXCI+PC9kaXY+XG48L3NjaS12aWV3cG9ydD5cbjx3Yi1wYXJ0LWFjdGlvbi1iYXIvPlxuPHdiLXZpZXctbGlzdC1idXR0b24vPlxuXG48IS0tIEVsZW1lbnQgZm9yIGluamVjdGluZyB0aGUgY29ybmVyIHJhZGl1cyBpbnRvIHRoZSBjb21wb25lbnQuIC0tPlxuPGRpdiBjbGFzcz1cInRhYi1jb3JuZXItcmFkaXVzXCIgI3RhYl9jb3JuZXJfcmFkaXVzPjwvZGl2PlxuPCEtLSBFbGVtZW50IGZvciBpbmplY3RpbmcgdGhlIHRhYmJhciBwYWRkaW5nIGludG8gdGhlIGNvbXBvbmVudC4gLS0+XG48ZGl2IGNsYXNzPVwicGFkZGluZy1pbmxpbmVcIiAjcGFkZGluZ19pbmxpbmU+PC9kaXY+XG4iXX0=
528
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFydC1iYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2Npb24vd29ya2JlbmNoL3NyYy9saWIvcGFydC9wYXJ0LWJhci9wYXJ0LWJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zY2lvbi93b3JrYmVuY2gvc3JjL2xpYi9wYXJ0L3BhcnQtYmFyL3BhcnQtYmFyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBRUgsT0FBTyxFQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBcUIsTUFBTSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ25LLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLGdDQUFnQyxDQUFDO0FBQ2hFLE9BQU8sRUFBQyxHQUFHLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hELE9BQU8sRUFBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQW9CLE9BQU8sRUFBRSxLQUFLLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDMUYsT0FBTyxFQUFjLHdCQUF3QixFQUFDLE1BQU0scURBQXFELENBQUM7QUFDMUcsT0FBTyxFQUFlLGVBQWUsRUFBZ0IsTUFBTSxrQ0FBa0MsQ0FBQztBQUM5RixPQUFPLEVBQUMsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUN0SCxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDeEQsT0FBTyxFQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUNsRSxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSx5Q0FBeUMsQ0FBQztBQUN6RSxPQUFPLEVBQUMsa0JBQWtCLEVBQUUsU0FBUyxFQUFDLE1BQU0sNkJBQTZCLENBQUM7QUFDMUUsT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sOENBQThDLENBQUM7QUFDcEYsT0FBTyxFQUFDLHVCQUF1QixFQUFDLE1BQU0sZ0RBQWdELENBQUM7QUFDdkYsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDOUQsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sRUFBQyxLQUFLLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQzs7QUFFN0M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEJHO0FBYUgsTUFBTSxPQUFPLGdCQUFnQjtJQTBEM0I7UUF4RGlCLFVBQUssR0FBRyxNQUFNLENBQUMsQ0FBQSxVQUF1QixDQUFBLENBQUMsQ0FBQyxhQUFhLENBQUM7UUFDdEQscUJBQWdCLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUN2QyxpQkFBWSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNwQyxZQUFPLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDbkMsOEJBQXlCLEdBQUcsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUM7UUFDN0QscUJBQWdCLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzNDLFVBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFdkIsY0FBUyxHQUFHLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzNDLDRCQUF1QixHQUFHLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ2pFLHVCQUFrQixHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUM5RCw4QkFBeUIsR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDLG9CQUFvQixFQUFFLEVBQUMsSUFBSSxFQUFFLENBQUEsVUFBdUIsQ0FBQSxFQUFDLENBQUMsQ0FBQztRQUN0Ryw0QkFBdUIsR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDLG1CQUFtQixFQUFFLEVBQUMsSUFBSSxFQUFFLENBQUEsVUFBdUIsQ0FBQSxFQUFDLENBQUMsQ0FBQztRQUNuRywwQkFBcUIsR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEVBQUMsSUFBSSxFQUFFLENBQUEsVUFBdUIsQ0FBQSxFQUFDLENBQUMsQ0FBQztRQUM5RixtQkFBYyxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQTBCLFFBQVEsQ0FBQyxDQUFDO1FBQ3ZFLHlCQUFvQixHQUFHLGtCQUFrQixDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBR3hFLFNBQUksR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDOUIsaUJBQVksR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDNUYsZUFBVSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQztRQUU3Rzs7V0FFRztRQUNPLHNCQUFpQixHQUFHLE1BQU0sQ0FBa0MsSUFBSSxDQUFDLENBQUM7UUFFNUU7OztXQUdHO1FBQ08sc0JBQWlCLEdBQUcsTUFBTSxDQUEwQixJQUFJLENBQUMsQ0FBQztRQUVwRTs7V0FFRztRQUNLLGNBQVMsR0FBd0IsSUFBSSxDQUFDO1FBRTlDOztXQUVHO1FBQ0ssaUJBQVksR0FBdUIsSUFBSSxDQUFDO1FBRWhEOztXQUVHO1FBQ0ssc0JBQWlCLEdBQUcsTUFBTSxDQUFPLFNBQVMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxLQUFLLEVBQUMsQ0FBQyxDQUFDO1FBRTFFOztXQUVHO1FBQ0ssa0JBQWEsR0FBRztZQUN0QixJQUFJLEVBQUUsQ0FBQztZQUNQLEtBQUssRUFBRSxDQUFDO1NBQ1QsQ0FBQztRQUdBLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztRQUMxRCxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztRQUNqQyxJQUFJLENBQUMsOEJBQThCLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsOEJBQThCLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQztJQUN0QyxDQUFDO0lBR1MsYUFBYSxDQUFDLEtBQWlCO1FBQ3ZDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ25FLENBQUM7UUFDRCxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVEOztPQUVHO0lBQ0ssY0FBYztRQUNwQixxQkFBcUI7UUFDckIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFHLENBQUM7UUFFdkQsc0NBQXNDO1FBQ3RDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRTFELG1EQUFtRDtRQUNuRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQ3RELElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFOUUsZ0dBQWdHO1FBQ2hHLHFCQUFxQixDQUFDLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLHlCQUF5QixDQUFDLENBQUMsQ0FBQztRQUVoRiwrQ0FBK0M7UUFDL0MsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUM7UUFFN0UseURBQXlEO1FBQ3pELGdJQUFnSTtRQUNoSSxTQUFTLENBQVksTUFBTSxFQUFFLFdBQVcsRUFBRSxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUMsQ0FBQzthQUNwRCxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDNUYsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ2pCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5QixJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxZQUFZLENBQUMsS0FBZ0I7UUFDbkMsc0tBQXNLO1FBQ3RLLElBQUksS0FBSyxDQUFDLFlBQWEsQ0FBQyxVQUFVLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDOUMsNkNBQTZDO1lBQzdDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFDLGtCQUFrQixFQUFFLElBQUksRUFBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDN0Usb0JBQW9CO1lBQ3BCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN4QixDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ssVUFBVSxDQUFDLEtBQW9CO1FBQ3JDLG1FQUFtRTtRQUNuRSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsR0FBRyxLQUFLLEtBQUssQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQUM7WUFDaEQsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3hCLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxpQkFBaUIsQ0FBQyxLQUFnQjtRQUN4QyxxQkFBcUI7UUFDckIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFHLENBQUM7UUFFeEUsc0NBQXNDO1FBQ3RDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRTFELG1EQUFtRDtRQUNuRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQ3RELElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFOUUsd0VBQXdFO1FBQ3hFLHNIQUFzSDtRQUN0SCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDO1lBQ25ELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEtBQUssUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDO1lBQ3pHLGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUMsb0NBQW9DLEVBQUUsR0FBRyxRQUFRLENBQUMsWUFBWSxJQUFJLEVBQUMsQ0FBQyxDQUFDO1FBQ25HLENBQUM7UUFFRCw0Q0FBNEM7UUFDNUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUUxRCwyR0FBMkc7UUFDM0csV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUseUJBQXlCLENBQUMsQ0FBQztRQUVuRCxnREFBZ0Q7UUFDaEQsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUM7UUFFN0UscUNBQXFDO1FBQ3JDLGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUMsK0JBQStCLEVBQUUsR0FBRyxRQUFRLENBQUMsWUFBWSxJQUFJLEVBQUMsQ0FBQyxDQUFDO0lBQzlGLENBQUM7SUFFRDs7T0FFRztJQUNLLGlCQUFpQixDQUFDLEtBQWdCO1FBQ3hDLDRHQUE0RztRQUM1RyxrSEFBa0g7UUFDbEgsSUFBSSxLQUFLLENBQUMsT0FBTyxJQUFJLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNuQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsQ0FBQztZQUN6QyxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQztRQUMvRSxDQUFDO1FBRUQseUVBQXlFO1FBQ3pFLHdMQUF3TDtRQUN4TCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxDQUFDO1lBQ3JDLEtBQUssQ0FBQyxDQUFDLENBQUM7aUJBQ0wsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7aUJBQzdDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFDLGtCQUFrQixFQUFFLElBQUksRUFBQyxDQUFDLENBQUMsQ0FBQztRQUNqSixDQUFDO1FBRUQsdUJBQXVCO1FBQ3ZCLElBQUksQ0FBQyxjQUFjLENBQUMsRUFBQyxlQUFlLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFFRDs7T0FFRztJQUNLLGdCQUFnQixDQUFDLEtBQWdCLEVBQUUsWUFBb0IsRUFBRSxjQUFzQjtRQUNyRixNQUFNLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUNoQyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxrQkFBa0I7UUFFMUMsNENBQTRDO1FBQzVDLHVGQUF1RjtRQUN2RixzSUFBc0k7UUFDdEkscUJBQXFCLENBQUMsR0FBRyxFQUFFO1lBQ3pCLHdDQUF3QztZQUN4QyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0IsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUM1RCxPQUFPO1lBQ1QsQ0FBQztZQUVELGtKQUFrSjtZQUNsSixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDO2dCQUNuRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMvRCxDQUFDO1lBQ0QscUlBQXFJO2lCQUNoSSxJQUFJLFlBQVksRUFBRSxDQUFDO2dCQUN0QixJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztZQUMxRSxDQUFDO1lBQ0QsdUtBQXVLO2lCQUNsSyxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUN4QixJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQztZQUM1RSxDQUFDO1lBRUQscURBQXFEO1lBQ3JELFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBRXJDLHlEQUF5RDtZQUN6RCw0SEFBNEg7WUFDNUgsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBQyxvQ0FBb0MsRUFBRSxHQUFHLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFDLENBQUMsQ0FBQztRQUN2SCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNLLEtBQUssQ0FBQyxZQUFZO1FBQ3hCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFVLENBQUM7UUFDakMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUcsQ0FBQztRQUNwRCxNQUFNLFlBQVksR0FBRyxpQkFBaUIsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBRXZHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxxQkFBcUIsQ0FBQztZQUMxQyxNQUFNLEVBQUU7Z0JBQ04sV0FBVyxFQUFFLFFBQVEsQ0FBQyxXQUFXO2dCQUNqQyxNQUFNLEVBQUUsUUFBUSxDQUFDLE1BQU07Z0JBQ3ZCLE1BQU0sRUFBRSxRQUFRLENBQUMsTUFBTTtnQkFDdkIsaUJBQWlCLEVBQUUsUUFBUSxDQUFDLGlCQUFpQjtnQkFDN0MsZUFBZSxFQUFFLFFBQVEsQ0FBQyxlQUFlO2dCQUN6QyxjQUFjLEVBQUUsUUFBUSxDQUFDLGNBQWM7Z0JBQ3ZDLGNBQWMsRUFBRSxRQUFRLENBQUMsY0FBYztnQkFDdkMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxTQUFTO2FBQzlCO1lBQ0QsTUFBTSxFQUFFO2dCQUNOLFdBQVcsRUFBRSxJQUFJLENBQUMsWUFBWTtnQkFDOUIsUUFBUSxFQUFFLFlBQVk7Z0JBQ3RCLFNBQVMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7YUFDeEI7WUFDRCxRQUFRLEVBQUUsUUFBUTtTQUNuQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxpQkFBaUIsQ0FBQyxLQUFnQixFQUFFLGFBQWEsR0FBRyxDQUFDO1FBQzNELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsU0FBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2hHLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztRQUUxRixLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQy9CLE1BQU0sRUFBQyxJQUFJLEVBQUUsS0FBSyxFQUFDLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDbkQsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBRTFDLGtDQUFrQztZQUNsQyxJQUFJLGFBQWEsSUFBSSxDQUFDLElBQUksU0FBUyxDQUFDLElBQUksR0FBRyxjQUFjLEVBQUUsQ0FBQztnQkFDMUQsT0FBTyxPQUFPLENBQUM7WUFDakIsQ0FBQztZQUNELGtDQUFrQztZQUNsQyxJQUFJLGFBQWEsR0FBRyxDQUFDLElBQUksU0FBUyxDQUFDLEtBQUssR0FBRyxjQUFjLEVBQUUsQ0FBQztnQkFDMUQsT0FBTyxPQUFPLENBQUM7WUFDakIsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRDs7T0FFRztJQUNLLDBCQUEwQjtRQUNoQyxPQUFPLENBQUMsU0FBa0IsRUFBVyxFQUFFLENBQUMsSUFBSSxPQUFPLENBQ2pELEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFO1lBQ2pCLEdBQUcsRUFBRSxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJO1lBQ2xFLEdBQUcsRUFBRSxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLEdBQUcsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUs7U0FDakgsQ0FBQyxFQUNGLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLEdBQUcsRUFDL0IsU0FBUyxDQUFDLEtBQUssRUFDZixJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxNQUFNLENBQ25DLENBQUM7SUFDSixDQUFDO0lBRUQ7OztPQUdHO0lBQ0sseUJBQXlCO1FBQy9CLE1BQU0sZUFBZSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDdkQsT0FBTyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUMsS0FBSyxHQUFHLGVBQWUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzNGLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNLLDZCQUE2QixDQUFDLEtBQWdCO1FBQ3BELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxTQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDeEcsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BHLE1BQU0sZ0JBQWdCLEdBQUcsV0FBVyxFQUFFLGtCQUFrQixFQUFFLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQztRQUNsSSxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEdBQUcsaUJBQWlCLENBQUMsS0FBSyxFQUFFLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxHQUFHLGdCQUFnQixDQUFDO0lBQzFHLENBQUM7SUFFRDs7O09BR0c7SUFDSyxxQkFBcUI7UUFDM0IsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUNuRCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0IsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQzVELE9BQU8sSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLEtBQUssTUFBTSxDQUFDLENBQUM7UUFDbEcsQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztRQUMxRixNQUFNLGVBQWUsR0FBRyxpQkFBaUIsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsaUJBQWtCLENBQUMsQ0FBQztRQUM3RyxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsU0FBVSxDQUFDLFlBQVksQ0FBQztRQUVyRCxPQUFPLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDbkMsTUFBTSxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDO1lBQ3JFLHdFQUF3RTtZQUN4RSxJQUFJLENBQUMsR0FBRyxlQUFlLElBQUksaUJBQWlCLEtBQUssTUFBTSxFQUFFLENBQUM7Z0JBQ3hELE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztZQUNELG9GQUFvRjtZQUNwRixJQUFJLENBQUMsSUFBSSxlQUFlLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxDQUFDLDhEQUE4RDtnQkFDakssT0FBTyxLQUFLLENBQUM7WUFDZixDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNLLGNBQWMsQ0FBQyxPQUEwRDtRQUMvRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMseUJBQXlCLENBQUMsNkJBQTZCLENBQUMsSUFBSSxDQUFDLFlBQWEsQ0FBQyxDQUFDO1FBQ2pGLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBRXpCLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO1FBQ2xFLGdCQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsK0JBQStCLEVBQUUsb0NBQW9DLENBQUMsQ0FBQztRQUVwRyxJQUFJLE9BQU8sRUFBRSxlQUFlLElBQUksSUFBSSxFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsSUFBSSxPQUFPLEVBQUUsYUFBYSxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ25DLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1FBQ3hCLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxxQkFBcUIsQ0FBQyxRQUFvQjtRQUNoRCxJQUFJLE1BQU0sQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDekUsT0FBTztRQUNULENBQUM7UUFDRCxxQkFBcUIsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ2hILENBQUM7SUFFRDs7T0FFRztJQUNLLHlCQUF5QjtRQUMvQixNQUFNLENBQUMsR0FBRyxFQUFFO1lBQ1YseUJBQXlCO1lBQ3pCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDOUMsc0hBQXNIO1lBQ3RILElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDbEIsT0FBTztZQUNULENBQUM7WUFFRCw2R0FBNkc7WUFDN0csTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBRW5ELDRHQUE0RztZQUM1RyxNQUFNLGFBQWEsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxZQUFZLENBQUMsQ0FBQztZQUNoRixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ25CLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLG1EQUFtRDtnQkFDckUsT0FBTztZQUNULENBQUM7WUFFRCxpRkFBaUY7WUFDakYsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBRXBDLG1HQUFtRztZQUNuRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUV6QixvREFBb0Q7WUFDcEQsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLHFCQUFxQixDQUFDLEdBQUcsRUFBRTtnQkFDekMsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUM7b0JBQzNFLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQy9ELENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSyw4QkFBOEI7UUFDcEMsSUFBSSxDQUFDLGdCQUFnQjthQUNsQixJQUFJLENBQ0gsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUMzQixXQUFXLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsRUFBRSxrREFBa0Q7UUFDaEgsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQ3BDLGtCQUFrQixFQUFFLENBQ3JCO2FBQ0EsU0FBUyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ25CLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNwRyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRDs7T0FFRztJQUNLLHVCQUF1QjtRQUM3QixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFNUIscURBQXFEO1FBQ3JELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQzthQUN4QyxJQUFJLENBQ0gsV0FBVyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQzdDLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLEVBQUUsbURBQW1EO1FBQ3ZHLGtCQUFrQixFQUFFLENBQ3JCO2FBQ0EsU0FBUyxDQUFDLENBQUMsRUFBQyxLQUFLLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBQyxFQUFFLEVBQUU7WUFDbkQsUUFBUSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ25CLEtBQUssV0FBVztvQkFDZCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7b0JBQ3RCLE1BQU07Z0JBQ1IsS0FBSyxTQUFTO29CQUNaLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3pCLE1BQU07Z0JBQ1IsS0FBSyxXQUFXO29CQUNkLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDOUIsTUFBTTtnQkFDUixLQUFLLFVBQVU7b0JBQ2IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxZQUFZLEVBQUUsY0FBYyxDQUFDLENBQUM7b0JBQzNELE1BQU07Z0JBQ1IsS0FBSyxXQUFXO29CQUNkLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDOUIsTUFBTTtnQkFDUixLQUFLLE1BQU07b0JBQ1QsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO29CQUMzQixNQUFNO1lBQ1YsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUwsb0RBQW9EO1FBQ3BELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVO2FBQzdCLElBQUksQ0FDSCxXQUFXLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDN0Msa0JBQWtCLEVBQUUsQ0FDckI7YUFDQSxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFOUM7O1dBRUc7UUFDSCxTQUFTLGlCQUFpQixDQUFDLFFBQW9DO1lBQzdELE9BQU8sT0FBTyxDQUFDLEVBQUUsQ0FBQyxJQUFJLFVBQVUsQ0FBd0IsUUFBUSxDQUFDLEVBQUU7Z0JBQ2pFLElBQUksV0FBK0IsQ0FBQztnQkFDcEMsSUFBSSxjQUFrQyxDQUFDO2dCQUV2QyxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFO29CQUM3QyxRQUFRLENBQUMsSUFBSSxDQUFDO3dCQUNaLEtBQUs7d0JBQ0wsWUFBWSxFQUFFLEtBQUssQ0FBQyxPQUFPLEdBQUcsQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQzt3QkFDNUQsY0FBYyxFQUFFLFFBQVEsRUFBRSxDQUFDLFVBQVUsR0FBRyxDQUFDLGNBQWMsSUFBSSxRQUFRLEVBQUUsQ0FBQyxVQUFVLENBQUM7cUJBQ2xGLENBQUMsQ0FBQztvQkFDSCxXQUFXLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztvQkFDNUIsY0FBYyxHQUFHLFFBQVEsRUFBRSxDQUFDLFVBQVUsQ0FBQztnQkFDekMsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsT0FBTyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDMUMsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ssNEJBQTRCO1FBQ2xDLE1BQU0sWUFBWSxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztRQUMvRixNQUFNLGtCQUFrQixHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDO1FBQ3RHLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUU1QixtQkFBbUI7UUFDbkIsTUFBTSxDQUFDLEdBQUcsRUFBRTtZQUNWLDRDQUE0QztZQUM1QyxZQUFZLEVBQUUsQ0FBQztZQUNmLGtCQUFrQixFQUFFLENBQUM7WUFDckIsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ2hELENBQUMsQ0FBQyxDQUFDO1FBRUgsb0JBQW9CO1FBQ3BCLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUNqQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxlQUFlLENBQUM7WUFDM0QsU0FBUyxDQUFDLEdBQUcsRUFBRTtnQkFDYixNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQztxQkFDL0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO3FCQUNuRCxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQ2pELFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztZQUM5QyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ssOEJBQThCO1FBQ3BDLE1BQU0sd0JBQXdCLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQ3pFLE1BQU0sc0JBQXNCLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBRXJFLE1BQU0sQ0FBQyxHQUFHLEVBQUU7WUFDVixNQUFNLE1BQU0sR0FBRyx3QkFBd0IsRUFBRSxDQUFDLFdBQVcsR0FBRyxzQkFBc0IsRUFBRSxDQUFDLFdBQVcsQ0FBQztZQUM3RixJQUFJLENBQUMsYUFBYSxHQUFHLEVBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFDLENBQUM7WUFDbkQsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUU7Z0JBQ3pCLHlCQUF5QixFQUFFLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLElBQUk7Z0JBQ3pELDBCQUEwQixFQUFFLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLElBQUk7YUFDNUQsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sV0FBVztRQUNoQixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDeEIsQ0FBQzs4R0E5aEJVLGdCQUFnQjtrR0FBaEIsZ0JBQWdCLG1LQVVlLGdCQUFnQixxR0FFRCxvQkFBb0IsNEdBQ2Isb0JBQW9CLDJCQUFTLFVBQVUsdUlBQ2IsVUFBVSxrSUFDZixVQUFVLHdKQ2xGakcsb3RDQWdDQSw0dUdENkJJLG9CQUFvQiwwR0FDcEIsZ0JBQWdCLDRFQUNoQixzQkFBc0Isb0ZBQ3RCLHVCQUF1Qjs7MkZBR2QsZ0JBQWdCO2tCQVo1QixTQUFTOytCQUNFLGFBQWEsY0FHWCxJQUFJLFdBQ1A7d0JBQ1Asb0JBQW9CO3dCQUNwQixnQkFBZ0I7d0JBQ2hCLHNCQUFzQjt3QkFDdEIsdUJBQXVCO3FCQUN4Qjt3REFzRVMsYUFBYTtzQkFEdEIsWUFBWTt1QkFBQyxVQUFVLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE4LTIwMjQgU3dpc3MgRmVkZXJhbCBSYWlsd2F5c1xuICpcbiAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGVcbiAqIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgMi4wXG4gKiB3aGljaCBpcyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC9cbiAqXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMFxuICovXG5cbmltcG9ydCB7Q29tcG9uZW50LCBjb21wdXRlZCwgZWZmZWN0LCBFbGVtZW50UmVmLCBIb3N0TGlzdGVuZXIsIGluamVjdCwgTmdab25lLCBPbkRlc3Ryb3ksIFNpZ25hbCwgc2lnbmFsLCB1bnRyYWNrZWQsIHZpZXdDaGlsZCwgdmlld0NoaWxkcmVufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Vmlld1RhYkNvbXBvbmVudH0gZnJvbSAnLi4vdmlldy10YWIvdmlldy10YWIuY29tcG9uZW50JztcbmltcG9ydCB7bWFwLCBtZXJnZU1hcCwgdGFrZVVudGlsfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge2Zyb20sIGZyb21FdmVudCwgbWVyZ2UsIE9ic2VydmFibGUsIE9wZXJhdG9yRnVuY3Rpb24sIFN1YmplY3QsIHRpbWVyfSBmcm9tICdyeGpzJztcbmltcG9ydCB7Q29uc3RyYWluRm4sIFZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlcn0gZnJvbSAnLi4vLi4vdmlldy1kbmQvdmlldy10YWItZHJhZy1pbWFnZS1yZW5kZXJlci5zZXJ2aWNlJztcbmltcG9ydCB7Vmlld0RyYWdEYXRhLCBWaWV3RHJhZ1NlcnZpY2UsIFZpZXdNb3ZlRXZlbnR9IGZyb20gJy4uLy4uL3ZpZXctZG5kL3ZpZXctZHJhZy5zZXJ2aWNlJztcbmltcG9ydCB7Z2V0Q3NzVHJhbnNsYXRpb24sIHNldENzc0NsYXNzLCBzZXRDc3NWYXJpYWJsZSwgdW5zZXRDc3NDbGFzcywgdW5zZXRDc3NWYXJpYWJsZX0gZnJvbSAnLi4vLi4vY29tbW9uL2RvbS51dGlsJztcbmltcG9ydCB7ybVXb3JrYmVuY2hQYXJ0fSBmcm9tICcuLi/JtXdvcmtiZW5jaC1wYXJ0Lm1vZGVsJztcbmltcG9ydCB7ZmlsdGVyQXJyYXksIHN1YnNjcmliZUlufSBmcm9tICdAc2Npb24vdG9vbGtpdC9vcGVyYXRvcnMnO1xuaW1wb3J0IHtTY2lWaWV3cG9ydENvbXBvbmVudH0gZnJvbSAnQHNjaW9uL2NvbXBvbmVudHMvdmlld3BvcnQnO1xuaW1wb3J0IHvJtVdvcmtiZW5jaFJvdXRlcn0gZnJvbSAnLi4vLi4vcm91dGluZy/JtXdvcmtiZW5jaC1yb3V0ZXIuc2VydmljZSc7XG5pbXBvcnQge2JvdW5kaW5nQ2xpZW50UmVjdCwgZGltZW5zaW9ufSBmcm9tICdAc2Npb24vY29tcG9uZW50cy9kaW1lbnNpb24nO1xuaW1wb3J0IHtQYXJ0QWN0aW9uQmFyQ29tcG9uZW50fSBmcm9tICcuLi9wYXJ0LWFjdGlvbi1iYXIvcGFydC1hY3Rpb24tYmFyLmNvbXBvbmVudCc7XG5pbXBvcnQge1ZpZXdMaXN0QnV0dG9uQ29tcG9uZW50fSBmcm9tICcuLi92aWV3LWxpc3QtYnV0dG9uL3ZpZXctbGlzdC1idXR0b24uY29tcG9uZW50JztcbmltcG9ydCB7dGFrZVVudGlsRGVzdHJveWVkfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQge1dPUktCRU5DSF9JRH0gZnJvbSAnLi4vLi4vd29ya2JlbmNoLWlkJztcbmltcG9ydCB7Y2xhbXB9IGZyb20gJy4uLy4uL2NvbW1vbi9tYXRoLnV0aWwnO1xuXG4vKipcbiAqIFJlbmRlcnMgdmlldyB0YWJzIGFuZCBhY3Rpb25zIG9mIGEge0BsaW5rIFdvcmtiZW5jaFBhcnR9LlxuICpcbiAqIFRhYnMgYXJlIGFkZGVkIHRvIGEgdmlld3BvcnQsIHdoaWNoIHRoZSB1c2VyIGNhbiBzY3JvbGwgaWYgbm90IGVub3VnaCBzcGFjZS4gVGhlIHZpZXdwb3J0IGdyb3dzIHdpdGggaXRzIHRhYnMsXG4gKiBhbGxvd2luZyBhY3Rpb25zIHRvIGJlIHBsYWNlZCBkaXJlY3RseSBhZnRlciB0aGUgbGFzdCB0YWIgb3Igb24gdGhlIHJpZ2h0IHNpZGUuXG4gKlxuICogIyMgRHJhZyBhbmQgRHJvcFxuICogVGhpcyBjb21wb25lbnQgc3Vic2NyaWJlcyB0byBkcmFnIGV2ZW50cyB0byB2aXN1YWxpemUgdGFicyBkdXJpbmcgYSBkcmFnIG9wZXJhdGlvbi4gVGhlIGRyYWcgb3BlcmF0aW9uIGlzIGluaXRpYXRlZCBpbiB7QGxpbmsgVmlld1RhYkNvbXBvbmVudH0uXG4gKlxuICogV2UgdXNlIG5hdGl2ZSBkcmFnIGFuZCBkcm9wIHRvIHN1cHBvcnQgZHJhZ2dpbmcgdmlld3MgdG8gb3RoZXIgd2luZG93cy5cbiAqXG4gKiBGb2xsb3dpbmcgZXZlbnRzIGFyZSB0cmlnZ2VyZWQ6XG4gKiAtIGRyYWdzdGFydDogd2hlbiBzdGFydCBkcmFnZ2luZyBhIHRhYiAob25seSByZWNlaXZlZCBpbiB0aGUgdGFiYmFyIHdoZXJlIHRoZSBkcmFnIG9wZXJhdGlvbiBoYXMgc3RhcnRlZClcbiAqIC0gZHJhZ2VuZDogICB3aGVuIGVuZCBkcmFnZ2luZyBhIHRhYiwgZWl0aGVyIHZpYSBkcm9wIG9yIGNhbmNlbCAob25seSByZWNlaXZlZCBpbiB0aGUgdGFiYmFyIHdoZXJlIHRoZSBkcmFnIG9wZXJhdGlvbiBoYXMgc3RhcnRlZClcbiAqIC0gZHJhZ2VudGVyOiB3aGVuIGEgdGFiIGVudGVycyB0aGUgdGFiYmFyXG4gKiAtIGRyYWdvdmVyOiAgd2hlbiBkcmFnZ2luZyBhIHRhYiBvdmVyIHRoZSB0YWJiYXIsIGV2ZXJ5IGZldyBodW5kcmVkIG1pbGxpc2Vjb25kc1xuICogLSBkcmFnbGVhdmU6IHdoZW4gYSB0YWIgbGVhdmVzIHRoZSB0YWJiYXJcbiAqIC0gZHJvcDogICAgICB3aGVuIHRoZSB1c2VyIGRyb3BzIGEgdGFiIGluIHRoZSB0YWJiYXJcbiAqXG4gKiAtIE5vdGUgdGhhdCBgZHJhZ2xlYXZlYCBldmVudCBpcyBub3QgZmlyZWQgb24gZHJvcCBhY3Rpb24uIFRoZXJlZm9yZSwgYWx3YXlzIGhhbmRsZSBib3RoIGV2ZW50cywgYGRyYWdsZWF2ZWAgYW5kIGBkcm9wYCBldmVudHMsIHJlc3BlY3RpdmVseS5cbiAqXG4gKiAjIyBUZXJtaW5vbG9neVxuICogLSBEcmFnIHNvdXJjZTogVGFiIHRoYXQgaXMgYmVpbmcgZHJhZ2dlZC5cbiAqIC0gRHJvcCB0YXJnZXQ6IFRhYiBiZWZvcmUgd2hpY2ggdG8gaW5zZXJ0IHRoZSBkcmFnIHNvdXJjZSBvbiBkcm9wLCBvciBgZW5kYCBpZiBkcm9wcGluZyBpdCBhZnRlciB0aGUgbGFzdCB0YWIuXG4gKiAtIERyYWcgaW1hZ2U6ICBJbWFnZSBmb3IgdGhlIHRhYiB0byBiZSBkcmFnZ2VkLiBXZSBkbyBub3QgdXNlIHRoZSBuYXRpdmUgZHJhZyBpbWFnZSBzdXBwb3J0IHRvIGNvbnRyb2wgZHJhZyBpbWFnZSBwb3NpdGlvbiBhbmQgc2l6ZSxcbiAqICAgICAgICAgICAgICAgIGUuZy4sIHRvIHNuYXAgdGhlIGRyYWcgaW1hZ2UgdG8gdGhlIHRhYmJhciB3aGVuIGRyYWdnaW5nIG5lYXIgaXQuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3diLXBhcnQtYmFyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3BhcnQtYmFyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcGFydC1iYXIuY29tcG9uZW50LnNjc3MnXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIFNjaVZpZXdwb3J0Q29tcG9uZW50LFxuICAgIFZpZXdUYWJDb21wb25lbnQsXG4gICAgUGFydEFjdGlvbkJhckNvbXBvbmVudCxcbiAgICBWaWV3TGlzdEJ1dHRvbkNvbXBvbmVudCxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgUGFydEJhckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfaG9zdCA9IGluamVjdChFbGVtZW50UmVmPEhUTUxFbGVtZW50PikubmF0aXZlRWxlbWVudDtcbiAgcHJpdmF0ZSByZWFkb25seSBfdmlld3BvcnRDaGFuZ2UkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfd29ya2JlbmNoSWQgPSBpbmplY3QoV09SS0JFTkNIX0lEKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfcm91dGVyID0gaW5qZWN0KMm1V29ya2JlbmNoUm91dGVyKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfdmlld1RhYkRyYWdJbWFnZVJlbmRlcmVyID0gaW5qZWN0KFZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlcik7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3ZpZXdEcmFnU2VydmljZSA9IGluamVjdChWaWV3RHJhZ1NlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IF96b25lID0gaW5qZWN0KE5nWm9uZSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfdmlld1RhYnMgPSB2aWV3Q2hpbGRyZW4oVmlld1RhYkNvbXBvbmVudCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2hvc3RCb3VuZGluZ0NsaWVudFJlY3QgPSBib3VuZGluZ0NsaWVudFJlY3QoaW5qZWN0KEVsZW1lbnRSZWYpKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfdmlld3BvcnRDb21wb25lbnQgPSB2aWV3Q2hpbGQucmVxdWlyZWQoU2NpVmlld3BvcnRDb21wb25lbnQpO1xuICBwcml2YXRlIHJlYWRvbmx5IF92aWV3cG9ydENvbXBvbmVudEVsZW1lbnQgPSB2aWV3Q2hpbGQucmVxdWlyZWQoU2NpVmlld3BvcnRDb21wb25lbnQsIHtyZWFkOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50Pn0pO1xuICBwcml2YXRlIHJlYWRvbmx5IF90YWJDb3JuZXJSYWRpdXNFbGVtZW50ID0gdmlld0NoaWxkLnJlcXVpcmVkKCd0YWJfY29ybmVyX3JhZGl1cycsIHtyZWFkOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50Pn0pO1xuICBwcml2YXRlIHJlYWRvbmx5IF9wYWRkaW5nSW5saW5lRWxlbWVudCA9IHZpZXdDaGlsZC5yZXF1aXJlZCgncGFkZGluZ19pbmxpbmUnLCB7cmVhZDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD59KTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZmlsbGVyRWxlbWVudCA9IHZpZXdDaGlsZC5yZXF1aXJlZDxFbGVtZW50UmVmPEhUTUxFbGVtZW50Pj4oJ2ZpbGxlcicpO1xuICBwcml2YXRlIHJlYWRvbmx5IF92aWV3cG9ydEJvdW5kaW5nQm94ID0gYm91bmRpbmdDbGllbnRSZWN0KHRoaXMuX3ZpZXdwb3J0Q29tcG9uZW50RWxlbWVudCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX21heFZpZXdwb3J0V2lkdGg6IFNpZ25hbDxudW1iZXI+O1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBwYXJ0ID0gaW5qZWN0KMm1V29ya2JlbmNoUGFydCk7XG4gIHByb3RlY3RlZCByZWFkb25seSBzdGFydEFjdGlvbnMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLnBhcnQuYWN0aW9ucygpLmZpbHRlcihhY3Rpb24gPT4gYWN0aW9uLmFsaWduICE9PSAnZW5kJykpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZW5kQWN0aW9ucyA9IGNvbXB1dGVkKCgpID0+IHRoaXMucGFydC5hY3Rpb25zKCkuZmlsdGVyKGFjdGlvbiA9PiBhY3Rpb24uYWxpZ24gPT09ICdlbmQnKSk7XG5cbiAgLyoqXG4gICAqIFJlZmVyZW5jZSB0byB0aGUgdGFiIGJlZm9yZSB3aGljaCB0byBpbnNlcnQgdGhlIGRyYWcgc291cmNlIG9uIGRyb3AsIG9yIGBlbmRgIGlmIGRyb3BwaW5nIGl0IGFmdGVyIHRoZSBsYXN0IHRhYi5cbiAgICovXG4gIHByb3RlY3RlZCBkcm9wVGFyZ2V0Vmlld1RhYiA9IHNpZ25hbDxWaWV3VGFiQ29tcG9uZW50IHwgJ2VuZCcgfCBudWxsPihudWxsKTtcblxuICAvKipcbiAgICogUmVmZXJlbmNlIHRvIHRoZSB0YWIgd2hlcmUgdGhlIGRyYWcgb3BlcmF0aW9uIHdhcyBzdGFydGVkLlxuICAgKiBUaGlzIHJlZmVyZW5jZSBpcyBvbmx5IHNldCBpZiB0aGUgZHJhZyBvcGVyYXRpb24gc3RhcnRlZCBvbiBhIHRhYiBvZiB0aGlzIHRhYmJhci5cbiAgICovXG4gIHByb3RlY3RlZCBkcmFnU291cmNlVmlld1RhYiA9IHNpZ25hbDxWaWV3VGFiQ29tcG9uZW50IHwgbnVsbD4obnVsbCk7XG5cbiAgLyoqXG4gICAqIFRyYW5zZmVyIGRhdGEgb2YgdGhlIHRhYiBiZWluZyBkcmFnZ2VkIG92ZXIgdGhpcyB0YWJiYXIuXG4gICAqL1xuICBwcml2YXRlIF9kcmFnRGF0YTogVmlld0RyYWdEYXRhIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIEZ1bmN0aW9uIGZvciBzbmFwcGluZyB0aGUgZHJhZyBpbWFnZSB0byB0aGUgdGFiYmFyIHdoZW4gZHJhZ2dpbmcgbmVhciBpdC5cbiAgICovXG4gIHByaXZhdGUgX2NvbnN0cmFpbkZuOiBDb25zdHJhaW5GbiB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBTaWduYWxzIHdoZW4gdW5zZXR0aW5nIGRyYWcgc3RhdGUuXG4gICAqL1xuICBwcml2YXRlIF9vblVuc2V0RHJhZ1N0YXRlID0gc2lnbmFsPHZvaWQ+KHVuZGVmaW5lZCwge2VxdWFsOiAoKSA9PiBmYWxzZX0pO1xuXG4gIC8qKlxuICAgKiBUYWJiYXIgaW5kZW50cyB3aGVyZSB0byBkaXNwbGF5IHRoZSByb3VuZGVkIGJvdHRvbSBjb3JuZXJzIG9mIHRoZSBmaXJzdCBhbmQgbGFzdCB2aWV3IHRhYi5cbiAgICovXG4gIHByaXZhdGUgX3RhYmJhckluZGVudCA9IHtcbiAgICBsZWZ0OiAwLFxuICAgIHJpZ2h0OiAwLFxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuX21heFZpZXdwb3J0V2lkdGggPSB0aGlzLmNhbGN1bGF0ZU1heFZpZXdwb3J0V2lkdGgoKTtcbiAgICB0aGlzLmluc3RhbGxBY3RpdmVWaWV3U2Nyb2xsZXIoKTtcbiAgICB0aGlzLmluc3RhbGxTY3JvbGxlZEludG9WaWV3VXBkYXRlcigpO1xuICAgIHRoaXMuaW5zdGFsbFZpZXdEcmFnTGlzdGVuZXIoKTtcbiAgICB0aGlzLmluc3RhbGxUYWJiYXJJbmRlbnRTaXplVHJhY2tlcigpO1xuICAgIHRoaXMuaW5zdGFsbFZpZXdwb3J0Q2hhbmdlVHJhY2tlcigpO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZGJsY2xpY2snLCBbJyRldmVudCddKVxuICBwcm90ZWN0ZWQgb25Eb3VibGVDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnBhcnQuaXNJbk1haW5BcmVhKSB7XG4gICAgICB0aGlzLl9yb3V0ZXIubmF2aWdhdGUobGF5b3V0ID0+IGxheW91dC50b2dnbGVNYXhpbWl6ZWQoKSkudGhlbigpO1xuICAgIH1cbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgaW52b2tlZCB3aGVuIHRoZSB1c2VyIHN0YXJ0cyBkcmFnZ2luZyBhIHRhYiBvZiB0aGlzIHRhYmJhciwgb25seSBpbiB0aGUgdGFiYmFyIHdoZXJlIHRoZSBkcmFnIHN0YXJ0ZWQuXG4gICAqL1xuICBwcml2YXRlIG9uVGFiRHJhZ1N0YXJ0KCk6IHZvaWQge1xuICAgIC8vIE1lbW9pemUgZHJhZyBkYXRhLlxuICAgIHRoaXMuX2RyYWdEYXRhID0gdGhpcy5fdmlld0RyYWdTZXJ2aWNlLnZpZXdEcmFnRGF0YSgpITtcblxuICAgIC8vIEluZGljYXRlIGRyYWdnaW5nIG92ZXIgdGhpcyB0YWJiYXIuXG4gICAgdGhpcy5fdmlld0RyYWdTZXJ2aWNlLnNpZ25hbFRhYmJhckRyYWdFbnRlcih0aGlzLnBhcnQuaWQpO1xuXG4gICAgLy8gU25hcCBkcmFnIGltYWdlIHRvIHRhYmJhciB3aGVuIGRyYWdnaW5nIG5lYXIgaXQuXG4gICAgdGhpcy5fY29uc3RyYWluRm4gPSB0aGlzLmNyZWF0ZURyYWdJbWFnZUNvbnN0cmFpbkZuKCk7XG4gICAgdGhpcy5fdmlld1RhYkRyYWdJbWFnZVJlbmRlcmVyLnNldENvbnN0cmFpbkRyYWdJbWFnZVJlY3RGbih0aGlzLl9jb25zdHJhaW5Gbik7XG5cbiAgICAvLyBEaXNhYmxlIHBvaW50ZXIgZXZlbnRzIHRvIG5vdCBicmVhayB0aGUgZHJhZyBvcGVyYXRpb24gKGluIEZpcmVmb3gsIGJ1dCBub3QgQ2hyb21lIGFuZCBFZGdlKS5cbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ3BvaW50ZXItZXZlbnRzLWRpc2FibGVkJykpO1xuXG4gICAgLy8gU2V0IENTUyBjbGFzcyB0byBub3QgYW5pbWF0ZSBzdGFydCBkcmFnZ2luZy5cbiAgICBzZXRDc3NDbGFzcyh0aGlzLl9ob3N0LCAnb24tZHJhZy1zdGFydCcpO1xuICAgIHRoaXMub25EcmFnQW5pbWF0aW9uU3RhYmxlKCgpID0+IHVuc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ29uLWRyYWctc3RhcnQnKSk7XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgdXNlciBjb250aW51ZXMgZHJhZ2dpbmcgb3ZlciB0aGlzIHRhYmJhci5cbiAgICAvLyBJZiBub3QsIHRoZSB1c2VyIGhhcyBxdWlja2x5IGRyYWdnZWQgdGhlIHRhYiBvdXQgb2YgdGhlIHRhYmJhciwgc28gbWFudWFsbHkgY2FsbCBgb25UYWJiYXJEcmFnRW50ZXJgIGFuZCBgb25UYWJiYXJEcmFnTGVhdmVgLlxuICAgIGZyb21FdmVudDxEcmFnRXZlbnQ+KHdpbmRvdywgJ2RyYWdlbnRlcicsIHtvbmNlOiB0cnVlfSlcbiAgICAgIC5waXBlKHRha2VVbnRpbChtZXJnZShmcm9tRXZlbnQodGhpcy5faG9zdCwgJ2RyYWdlbnRlcicpLCBmcm9tRXZlbnQodGhpcy5faG9zdCwgJ2RyYWdlbmQnKSkpKVxuICAgICAgLnN1YnNjcmliZShldmVudCA9PiB7XG4gICAgICAgIHRoaXMub25UYWJiYXJEcmFnRW50ZXIoZXZlbnQpO1xuICAgICAgICB0aGlzLm9uVGFiYmFyRHJhZ0xlYXZlKGV2ZW50KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBpbnZva2VkIHdoZW4gdGhlIHVzZXIgZW5kcyBkcmFnZ2luZyBhIHRhYiBvZiB0aGlzIHRhYmJhciwgZWl0aGVyIGJ5IGRyb3Agb3IgY2FuY2VsLCBvbmx5IGluIHRoZSB0YWJiYXIgd2hlcmUgdGhlIGRyYWcgc3RhcnRlZC5cbiAgICovXG4gIHByaXZhdGUgb25UYWJEcmFnRW5kKGV2ZW50OiBEcmFnRXZlbnQpOiB2b2lkIHtcbiAgICAvLyBVbnNldCBkcmFnIHN0YXRlIG9ubHkgb24gY2FuY2VsLCBub3Qgb24gZHJvcCwgdG8gcHJldmVudCB0YWJzIGZyb20gdGVtcG9yYXJpbHkgcmV2ZXJ0aW5nIHRvIHRoZWlyIHByZS1kcmFnIHN0YXRlLiBEcmFnIHN0YXRlIGlzIHJlc2V0IGluIGBvblRhYk1vdmVkYCBhZnRlciBhIGRyb3AuXG4gICAgaWYgKGV2ZW50LmRhdGFUcmFuc2ZlciEuZHJvcEVmZmVjdCA9PT0gJ25vbmUnKSB7XG4gICAgICAvLyBSZWFjdGl2YXRlIHRoZSBkcmFnIHNvdXJjZSB2aWV3IG9uIGNhbmNlbC5cbiAgICAgIHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIoKT8udmlldygpLmFjdGl2YXRlKHtza2lwTG9jYXRpb25DaGFuZ2U6IHRydWV9KS50aGVuKCk7XG4gICAgICAvLyBVbnNldCBkcmFnIHN0YXRlLlxuICAgICAgdGhpcy51bnNldERyYWdTdGF0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgaW52b2tlZCB3aGVuIHRoZSBsYXlvdXQgaGFzIGNoYW5nZWQgYWZ0ZXIgYSBkcm9wLiBUaGUgZHJvcCBtYXkgbm90IGJlIHJlbGF0ZWQgdG8gYSB0YWIgb2YgdGhpcyB0YWJiYXIuXG4gICAqL1xuICBwcml2YXRlIG9uVGFiTW92ZWQoZXZlbnQ6IFZpZXdNb3ZlRXZlbnQpOiB2b2lkIHtcbiAgICAvLyBVbnNldCBkcmFnIHN0YXRlIG9ubHkgaWYgbm8gbmV3IGRyYWcgaGFzIHN0YXJ0ZWQgc2luY2UgdGhlIGRyb3AuXG4gICAgaWYgKHRoaXMuX2RyYWdEYXRhPy51aWQgPT09IGV2ZW50LmRyYWdEYXRhPy51aWQpIHtcbiAgICAgIHRoaXMudW5zZXREcmFnU3RhdGUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIGludm9rZWQgd2hlbiB0aGUgdXNlciBkcmFncyBhIHRhYiBpbnRvIHRoaXMgdGFiYmFyLlxuICAgKi9cbiAgcHJpdmF0ZSBvblRhYmJhckRyYWdFbnRlcihldmVudDogRHJhZ0V2ZW50KTogdm9pZCB7XG4gICAgLy8gTWVtb2l6ZSBkcmFnIGRhdGEuXG4gICAgY29uc3QgZHJhZ0RhdGEgPSB0aGlzLl9kcmFnRGF0YSA9IHRoaXMuX3ZpZXdEcmFnU2VydmljZS52aWV3RHJhZ0RhdGEoKSE7XG5cbiAgICAvLyBJbmRpY2F0ZSBkcmFnZ2luZyBvdmVyIHRoaXMgdGFiYmFyLlxuICAgIHRoaXMuX3ZpZXdEcmFnU2VydmljZS5zaWduYWxUYWJiYXJEcmFnRW50ZXIodGhpcy5wYXJ0LmlkKTtcblxuICAgIC8vIFNuYXAgZHJhZyBpbWFnZSB0byB0YWJiYXIgd2hlbiBkcmFnZ2luZyBuZWFyIGl0LlxuICAgIHRoaXMuX2NvbnN0cmFpbkZuID0gdGhpcy5jcmVhdGVEcmFnSW1hZ2VDb25zdHJhaW5GbigpO1xuICAgIHRoaXMuX3ZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlci5zZXRDb25zdHJhaW5EcmFnSW1hZ2VSZWN0Rm4odGhpcy5fY29uc3RyYWluRm4pO1xuXG4gICAgLy8gU2V0IGRyYWcgc291cmNlLCBidXQgb25seSBpZiBzdGFydGVkIHRoZSBkcmFnIG9wZXJhdGlvbiBpbiB0aGlzIHBhcnQuXG4gICAgLy8gV2UgZG8gbm90IHNldCB0aGUgZHJhZyBzb3VyY2UgaW4gYGRyYWdzdGFydGAgdG8gbm90IGJyZWFrIHRoZSBkcmFnIG9wZXJhdGlvbiAoaW4gQ2hyb21lIGFuZCBFZGdlLCBidXQgbm90IEZpcmVmb3gpLlxuICAgIGlmICh0aGlzLl9ob3N0LmNsYXNzTGlzdC5jb250YWlucygnb24tZHJhZy1zdGFydCcpKSB7XG4gICAgICB0aGlzLmRyYWdTb3VyY2VWaWV3VGFiLnNldCh0aGlzLl92aWV3VGFicygpLmZpbmQodmlld1RhYiA9PiB2aWV3VGFiLnZpZXdJZCA9PT0gZHJhZ0RhdGEudmlld0lkKSA/PyBudWxsKTtcbiAgICAgIHNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsIHsnLS3JtXBhcnQtYmFyLWRyYWctcGxhY2Vob2xkZXItd2lkdGgnOiBgJHtkcmFnRGF0YS52aWV3VGFiV2lkdGh9cHhgfSk7XG4gICAgfVxuXG4gICAgLy8gTG9jYXRlIHRoZSB0YWIgdGhlIHVzZXIgaXMgZHJhZ2dpbmcgb3Zlci5cbiAgICB0aGlzLmRyb3BUYXJnZXRWaWV3VGFiLnNldCh0aGlzLmNvbXB1dGVEcm9wVGFyZ2V0KGV2ZW50KSk7XG5cbiAgICAvLyBEaXNhYmxlIHBvaW50ZXIgZXZlbnRzIG9uIHRoZSB0YWJiYXIgZm9yIGEgc21vb3RoZXIgZHJhZyBhbmQgZHJvcCBleHBlcmllbmNlIHdoZW4gcXVpY2tseSBzd2FwcGluZyB0YWJzLlxuICAgIHNldENzc0NsYXNzKHRoaXMuX2hvc3QsICdwb2ludGVyLWV2ZW50cy1kaXNhYmxlZCcpO1xuXG4gICAgLy8gU2V0IENTUyBjbGFzcyB0byBhbmltYXRlIGVudGVyaW5nIHRoZSB0YWJiYXIuXG4gICAgc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ29uLWRyYWctZW50ZXInKTtcbiAgICB0aGlzLm9uRHJhZ0FuaW1hdGlvblN0YWJsZSgoKSA9PiB1bnNldENzc0NsYXNzKHRoaXMuX2hvc3QsICdvbi1kcmFnLWVudGVyJykpO1xuXG4gICAgLy8gSW5qZWN0IGRyYWcgc291cmNlIHdpZHRoIGludG8gQ1NTLlxuICAgIHNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsIHsnLS3JtXBhcnQtYmFyLWRyYWctc291cmNlLXdpZHRoJzogYCR7ZHJhZ0RhdGEudmlld1RhYldpZHRofXB4YH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBpbnZva2VkIHdoZW4gdGhlIHVzZXIgZHJhZ3MgYSB0YWIgb3V0IG9mIHRoaXMgdGFiYmFyLlxuICAgKi9cbiAgcHJpdmF0ZSBvblRhYmJhckRyYWdMZWF2ZShldmVudDogRHJhZ0V2ZW50KTogdm9pZCB7XG4gICAgLy8gU2V0IENTUyBjbGFzcyB0byBhbmltYXRlIGxlYXZpbmcgdGhlIHRhYmJhciwgYnV0IG5vdCB3aGVuIGNhbmNlbGluZyB0aGUgZHJhZyBvcGVyYXRpb24gZm9yIGluc3RhbnQgcmVzZXQuXG4gICAgLy8gUG9pbnRlciBjb29yZGluYXRlcyBhcmUgbm90IHNldCB3aGVuIHRoZSBkcmFnIG9wZXJhdGlvbiBpcyBjYW5jZWxlZCBvciB3aGVuIGRyYWdnaW5nIHRoZSB0YWIgb3V0IG9mIHRoZSB3aW5kb3cuXG4gICAgaWYgKGV2ZW50LnNjcmVlblggfHwgZXZlbnQuc2NyZWVuWSkge1xuICAgICAgc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ29uLWRyYWctbGVhdmUnKTtcbiAgICAgIHRoaXMub25EcmFnQW5pbWF0aW9uU3RhYmxlKCgpID0+IHVuc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ29uLWRyYWctbGVhdmUnKSk7XG4gICAgfVxuXG4gICAgLy8gQWN0aXZhdGUgdGhlIGFkamFjZW50IHRhYiwgb25seSBpZiB0aGUgZHJhZyBvcGVyYXRpb24gaXMgbm90IGNhbmNlbGVkLlxuICAgIC8vIFRoZSBkcmFnIGV2ZW50IGRvZXMgbm90IHByb3ZpZGUgaW5mb3JtYXRpb24gYWJvdXQgY2FuY2VsYXRpb24uIFRoZXJlZm9yZSwgd2Ugd2FpdCBmb3IgYSBtYWNyb3Rhc2ssIGNhbmNlbGluZyBpdCB3aGVuIHJlY2VpdmluZyBgZHJhZ2VuZGAsIGkuZS4sIHRoZSBkcmFnIG9wZXJhdGlvbiBoYXMgYmVlbiBjYW5jZWxlZC5cbiAgICBpZiAodGhpcy5kcmFnU291cmNlVmlld1RhYigpPy5hY3RpdmUpIHtcbiAgICAgIHRpbWVyKDApXG4gICAgICAgIC5waXBlKHRha2VVbnRpbChmcm9tRXZlbnQod2luZG93LCAnZHJhZ2VuZCcpKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLl9yb3V0ZXIubmF2aWdhdGUobGF5b3V0ID0+IGxheW91dC5hY3RpdmF0ZUFkamFjZW50Vmlldyh0aGlzLmRyYWdTb3VyY2VWaWV3VGFiKCkhLnZpZXdJZCksIHtza2lwTG9jYXRpb25DaGFuZ2U6IHRydWV9KSk7XG4gICAgfVxuXG4gICAgLy8gQ2xlYW4gdXAgZHJhZyBzdGF0ZS5cbiAgICB0aGlzLnVuc2V0RHJhZ1N0YXRlKHt1bnNldERyYWdTb3VyY2U6IGZhbHNlLCB1bnNldERyYWdEYXRhOiBmYWxzZX0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBpbnZva2VkIHdoZW4gdGhlIHVzZXIgaXMgZHJhZ2dpbmcgYSB0YWIgb3ZlciB0aGlzIHRhYmJhci5cbiAgICovXG4gIHByaXZhdGUgb25UYWJiYXJEcmFnT3ZlcihldmVudDogRHJhZ0V2ZW50LCBkcmFnRGlzdGFuY2U6IG51bWJlciwgc2Nyb2xsRGlzdGFuY2U6IG51bWJlcik6IHZvaWQge1xuICAgIE5nWm9uZS5hc3NlcnROb3RJbkFuZ3VsYXJab25lKCk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsgLy8gYWxsb3cgdmlldyBkcm9wXG5cbiAgICAvLyBMb2NhdGUgdGhlIHRhYiB0aGUgdXNlciBpcyBkcmFnZ2luZyBvdmVyLlxuICAgIC8vIC0gUnVuIGluIGFuaW1hdGlvbiBmcmFtZSBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlLCBtb3N0IG5vdGljZWFibGUgb24gbG93ZXIgQ1BVIHBvd2VyLlxuICAgIC8vIC0gRG8gbm90IHdhaXQgZm9yIHRoZSBkcmFnIGFuaW1hdGlvbiB0byBjb21wbGV0ZSBmb3IgYSBzbW9vdGhlciBkcmFnIGFuZCBkcm9wIGV4cGVyaWVuY2Ugd2hlbiBxdWlja2x5IG1vdmluZyB0aGUgdGFiIGluIHRoZSB0YWJiYXIuXG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgIC8vIFNraXAgaWYgdGhlIGRyYWcgb3BlcmF0aW9uIGhhcyBlbmRlZC5cbiAgICAgIGlmICh0aGlzLl92aWV3RHJhZ1NlcnZpY2UuaXNEcmFnT3ZlclRhYmJhciAhPT0gdGhpcy5wYXJ0LmlkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gSWdub3JlIHRoZSBkcmFnIGRpc3RhbmNlIGlmIGBkcmFnLWVudGVyYCBhbmltYXRpb24gaXMgaW4gcHJvZ3Jlc3MgdG8gYXZvaWQgaW5jb3JyZWN0IGRyb3AgdGFyZ2V0IGNvbXB1dGF0aW9uIHdoZW4gZHJhZ2dpbmcgYSB0YWIgZnJvbSB0aGUgbGVmdC5cbiAgICAgIGlmICh0aGlzLl9ob3N0LmNsYXNzTGlzdC5jb250YWlucygnb24tZHJhZy1lbnRlcicpKSB7XG4gICAgICAgIHRoaXMuZHJvcFRhcmdldFZpZXdUYWIuc2V0KHRoaXMuY29tcHV0ZURyb3BUYXJnZXQoZXZlbnQsIDApKTtcbiAgICAgIH1cbiAgICAgIC8vIENvbXB1dGUgZHJvcCB0YXJnZXQgb25seSB3aGVuIG1vdmluZyB0aGUgZHJhZyBwb2ludGVyIHRvIHByZXZlbnQgdGFicyBmcm9tIHNsaWRpbmcgYmFjayBhbmQgZm9ydGggKHdoaWxlIGFuaW1hdGlvbiBpcyBpbiBwcm9ncmVzcylcbiAgICAgIGVsc2UgaWYgKGRyYWdEaXN0YW5jZSkge1xuICAgICAgICB0aGlzLmRyb3BUYXJnZXRWaWV3VGFiLnNldCh0aGlzLmNvbXB1dGVEcm9wVGFyZ2V0KGV2ZW50LCBkcmFnRGlzdGFuY2UpKTtcbiAgICAgIH1cbiAgICAgIC8vIENvbXB1dGUgZHJvcCB0YXJnZXQgd2hlbiBzY3JvbGxpbmcgdGhlIHZpZXdwb3J0LCBpLmUuLCBub3QgbW92aW5nIHRoZSBkcmFnIHBvaW50ZXIgYnV0IHNjcm9sbGluZyB0aGUgdmlld3BvcnQgYmVjYXVzZSBwbGFjZWQgdGhlIGRyYWcgcG9pbnRlciBhdCB0aGUgdmlld3BvcnQgZWRnZXMuXG4gICAgICBlbHNlIGlmIChzY3JvbGxEaXN0YW5jZSkge1xuICAgICAgICB0aGlzLmRyb3BUYXJnZXRWaWV3VGFiLnNldCh0aGlzLmNvbXB1dGVEcm9wVGFyZ2V0KGV2ZW50LCBzY3JvbGxEaXN0YW5jZSkpO1xuICAgICAgfVxuXG4gICAgICAvLyBTZXQgQ1NTIGNsYXNzIHRvIGFuaW1hdGUgZHJhZ2dpbmcgb3ZlciB0aGUgdGFiYmFyLlxuICAgICAgc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ2RyYWctb3ZlcicpO1xuXG4gICAgICAvLyBDYWxjdWxhdGUgdGhlIG5ldyBzaXplIG9mIHRoZSBkcmFnIHNvdXJjZSBwbGFjZWhvbGRlci5cbiAgICAgIC8vIFRoZSBwbGFjZWhvbGRlciBleHBhbmRzIHRoZSB2aWV3cG9ydCB3aGVuIGRyYWdnaW5nIGEgdGFiIHRvIHRoZSByaWdodCwgbW92aW5nIHBhcnQgYWN0aW9ucyBhbG9uZyB3aXRoIHRoZSBkcmFnb3ZlciBldmVudC5cbiAgICAgIHNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsIHsnLS3JtXBhcnQtYmFyLWRyYWctcGxhY2Vob2xkZXItd2lkdGgnOiBgJHt0aGlzLmNhbGN1bGF0ZURyYWdQbGFjZWhvbGRlcldpZHRoKGV2ZW50KX1weGB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgaW52b2tlZCB3aGVuIHRoZSB1c2VyIGRyb3BzIGEgdGFiIGluIHRoaXMgdGFiYmFyLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBvblRhYmJhckRyb3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZHJhZ0RhdGEgPSB0aGlzLl9kcmFnRGF0YSE7XG4gICAgY29uc3QgZHJvcFRhcmdldFZpZXdUYWIgPSB0aGlzLmRyb3BUYXJnZXRWaWV3VGFiKCkhO1xuICAgIGNvbnN0IGRyb3BQb3NpdGlvbiA9IGRyb3BUYXJnZXRWaWV3VGFiID09PSAnZW5kJyA/ICdlbmQnIDogdGhpcy5fdmlld1RhYnMoKS5pbmRleE9mKGRyb3BUYXJnZXRWaWV3VGFiKTtcblxuICAgIHRoaXMuX3ZpZXdEcmFnU2VydmljZS5kaXNwYXRjaFZpZXdNb3ZlRXZlbnQoe1xuICAgICAgc291cmNlOiB7XG4gICAgICAgIHdvcmtiZW5jaElkOiBkcmFnRGF0YS53b3JrYmVuY2hJZCxcbiAgICAgICAgcGFydElkOiBkcmFnRGF0YS5wYXJ0SWQsXG4gICAgICAgIHZpZXdJZDogZHJhZ0RhdGEudmlld0lkLFxuICAgICAgICBhbHRlcm5hdGl2ZVZpZXdJZDogZHJhZ0RhdGEuYWx0ZXJuYXRpdmVWaWV3SWQsXG4gICAgICAgIHZpZXdVcmxTZWdtZW50czogZHJhZ0RhdGEudmlld1VybFNlZ21lbnRzLFxuICAgICAgICBuYXZpZ2F0aW9uSGludDogZHJhZ0RhdGEubmF2aWdhdGlvbkhpbnQsXG4gICAgICAgIG5hdmlnYXRpb25EYXRhOiBkcmFnRGF0YS5uYXZpZ2F0aW9uRGF0YSxcbiAgICAgICAgY2xhc3NMaXN0OiBkcmFnRGF0YS5jbGFzc0xpc3QsXG4gICAgICB9LFxuICAgICAgdGFyZ2V0OiB7XG4gICAgICAgIHdvcmtiZW5jaElkOiB0aGlzLl93b3JrYmVuY2hJZCxcbiAgICAgICAgcG9zaXRpb246IGRyb3BQb3NpdGlvbixcbiAgICAgICAgZWxlbWVudElkOiB0aGlzLnBhcnQuaWQsXG4gICAgICB9LFxuICAgICAgZHJhZ0RhdGE6IGRyYWdEYXRhLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIExvY2F0ZXMgdGhlIHRhYiBiZWZvcmUgd2hpY2ggdGhlIGRyYWdnZWQgdGFiIGlzIHRvIGJlIGluc2VydGVkIHdoZW4gaXQgaXMgZHJvcHBlZC4gRHJhZ2dpbmcgYmV5b25kIHRoZSBsYXN0IHRhYiByZXR1cm5zIGBlbmRgLlxuICAgKi9cbiAgcHJpdmF0ZSBjb21wdXRlRHJvcFRhcmdldChldmVudDogRHJhZ0V2ZW50LCBkcmFnRGlzdGFuY2VYID0gMCk6IFZpZXdUYWJDb21wb25lbnQgfCAnZW5kJyB7XG4gICAgY29uc3QgZHJhZ0ltYWdlID0gdGhpcy5fdmlld1RhYkRyYWdJbWFnZVJlbmRlcmVyLmNhbGN1bGF0ZURyYWdJbWFnZVJlY3QodGhpcy5fZHJhZ0RhdGEhLCBldmVudCk7XG4gICAgY29uc3Qgdmlld1RhYnMgPSB0aGlzLl92aWV3VGFicygpLmZpbHRlcih2aWV3VGFiID0+IHZpZXdUYWIgIT09IHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIoKSk7XG5cbiAgICBmb3IgKGNvbnN0IHZpZXdUYWIgb2Ygdmlld1RhYnMpIHtcbiAgICAgIGNvbnN0IHtsZWZ0LCB3aWR0aH0gPSB2aWV3VGFiLmJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3Qgdmlld1RhYkhDZW50ZXIgPSBsZWZ0ICsgKHdpZHRoIC8gMik7XG5cbiAgICAgIC8vIE1vdmluZyB0aGUgcG9pbnRlciB0byB0aGUgbGVmdC5cbiAgICAgIGlmIChkcmFnRGlzdGFuY2VYIDw9IDAgJiYgZHJhZ0ltYWdlLmxlZnQgPCB2aWV3VGFiSENlbnRlcikge1xuICAgICAgICByZXR1cm4gdmlld1RhYjtcbiAgICAgIH1cbiAgICAgIC8vIE1vdmluZyB0aGUgcGludGVyIHRvIHRoZSByaWdodC5cbiAgICAgIGlmIChkcmFnRGlzdGFuY2VYID4gMCAmJiBkcmFnSW1hZ2UucmlnaHQgPCB2aWV3VGFiSENlbnRlcikge1xuICAgICAgICByZXR1cm4gdmlld1RhYjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuICdlbmQnO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgdGhlIGZ1bmN0aW9uIGZvciBzbmFwcGluZyB0aGUgZHJhZyBpbWFnZSB0byB0aGUgdGFiYmFyIHdoZW4gZHJhZ2dpbmcgbmVhciBpdC5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlRHJhZ0ltYWdlQ29uc3RyYWluRm4oKTogQ29uc3RyYWluRm4ge1xuICAgIHJldHVybiAoZHJhZ0ltYWdlOiBET01SZWN0KTogRE9NUmVjdCA9PiBuZXcgRE9NUmVjdChcbiAgICAgIGNsYW1wKGRyYWdJbWFnZS54LCB7XG4gICAgICAgIG1pbjogdGhpcy5faG9zdEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQgKyB0aGlzLl90YWJiYXJJbmRlbnQubGVmdCxcbiAgICAgICAgbWF4OiB0aGlzLl9ob3N0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdCArIHRoaXMuX21heFZpZXdwb3J0V2lkdGgoKSAtIGRyYWdJbWFnZS53aWR0aCAtIHRoaXMuX3RhYmJhckluZGVudC5yaWdodCxcbiAgICAgIH0pLFxuICAgICAgdGhpcy5fdmlld3BvcnRCb3VuZGluZ0JveCgpLnRvcCxcbiAgICAgIGRyYWdJbWFnZS53aWR0aCxcbiAgICAgIHRoaXMuX3ZpZXdwb3J0Qm91bmRpbmdCb3goKS5oZWlnaHQsIC8vIGZpdCBpbnRvIHRhYmJhciwgZS5nLiwgd2hlbiBkcmFnZ2luZyBhIHRhYiBpbnRvIGEgdGFiYmFyIG9mIGEgZGlmZmVyZW50IGhlaWdodFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyB0aGUgbWF4aW11bSB3aWR0aCBvZiB0aGUgdGFiYmFyIHZpZXdwb3J0IGJlZm9yZSBhbiBvdmVyZmxvdyB3b3VsZCBvY2N1ci5cbiAgICogVXNlIHRvIGNvbnN0cmFpbiB0aGUgZHJhZyBpbWFnZSB0byB0aGUgdGFiYmFyIGJvdW5kcy5cbiAgICovXG4gIHByaXZhdGUgY2FsY3VsYXRlTWF4Vmlld3BvcnRXaWR0aCgpOiBTaWduYWw8bnVtYmVyPiB7XG4gICAgY29uc3QgZmlsbGVyRGltZW5zaW9uID0gZGltZW5zaW9uKHRoaXMuX2ZpbGxlckVsZW1lbnQpO1xuICAgIHJldHVybiBjb21wdXRlZCgoKSA9PiB0aGlzLl92aWV3cG9ydEJvdW5kaW5nQm94KCkud2lkdGggKyBmaWxsZXJEaW1lbnNpb24oKS5vZmZzZXRXaWR0aCk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyB0aGUgd2lkdGggZm9yIHRoZSBkcmFnIHBsYWNlaG9sZGVyLlxuICAgKlxuICAgKiBUaGUgcGxhY2Vob2xkZXIgZXhwYW5kcyB0aGUgdmlld3BvcnQgd2hlbiBkcmFnZ2luZyBhIHRhYiB0byB0aGUgcmlnaHQsIG1vdmluZyBwYXJ0IGFjdGlvbnMgYWxvbmcgd2l0aCB0aGUgZHJhZ292ZXIgZXZlbnQuXG4gICAqXG4gICAqIENhbGN1bGF0aW9uOlxuICAgKiAtIFdoZW4gZHJhZ2dpbmcgb3ZlciB0YWJzLCB0aGUgd2lkdGggaXMgZXF1YWwgdG8gdGhlIHdpZHRoIG9mIHRoZSBkcmFnIHNvdXJjZS5cbiAgICogLSBXaGVuIGRyYWdnaW5nIHRvIHRoZSByaWdodCBvZiB0aGUgbGFzdCB0YWIsIHRoZSB3aWR0aCBvZiB0aGUgcGxhY2Vob2xkZXIgaXMgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIGxhc3QgdGFiIGFuZCB0aGUgcG9zaXRpb24gb2YgdGhlIGRyYWcgcG9pbnRlci5cbiAgICovXG4gIHByaXZhdGUgY2FsY3VsYXRlRHJhZ1BsYWNlaG9sZGVyV2lkdGgoZXZlbnQ6IERyYWdFdmVudCk6IG51bWJlciB7XG4gICAgY29uc3Qgdmlld0RyYWdJbWFnZVJlY3QgPSB0aGlzLl92aWV3VGFiRHJhZ0ltYWdlUmVuZGVyZXIuY2FsY3VsYXRlRHJhZ0ltYWdlUmVjdCh0aGlzLl9kcmFnRGF0YSEsIGV2ZW50KTtcbiAgICBjb25zdCBsYXN0Vmlld1RhYiA9IHRoaXMuX3ZpZXdUYWJzKCkuZmlsdGVyKHZpZXdUYWIgPT4gdmlld1RhYiAhPT0gdGhpcy5kcmFnU291cmNlVmlld1RhYigpKS5hdCgtMSk7XG4gICAgY29uc3QgbGFzdFZpZXdUYWJSaWdodCA9IGxhc3RWaWV3VGFiPy5ib3VuZGluZ0NsaWVudFJlY3QoKS5yaWdodCA/PyB0aGlzLl9ob3N0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdCArIHRoaXMuX3RhYmJhckluZGVudC5sZWZ0O1xuICAgIHJldHVybiBNYXRoLm1heChsYXN0Vmlld1RhYlJpZ2h0ICsgdmlld0RyYWdJbWFnZVJlY3Qud2lkdGgsIHZpZXdEcmFnSW1hZ2VSZWN0LnJpZ2h0KSAtIGxhc3RWaWV3VGFiUmlnaHQ7XG4gIH1cblxuICAvKipcbiAgICogSW5kaWNhdGVzIHdoZXRoZXIgQ1NTIGFuaW1hdGlvbnMgaGF2ZSBmaW5pc2hlZCB3aGVuIGRyYWdnaW5nIGEgdGFiIG92ZXIgdGhlIHRhYmJhci5cbiAgICogVGhlIGFuaW1hdGlvbiBpcyBjb25zaWRlcmVkIHN0YWJsZSB3aGVuIGFsbCB0YWJzIGhhdmUgbW92ZWQgdG8gdGhlaXIgZmluYWwgcG9zaXRpb24uXG4gICAqL1xuICBwcml2YXRlIGlzRHJhZ0FuaW1hdGlvblN0YWJsZSgpOiBib29sZWFuIHtcbiAgICBjb25zdCBkcm9wVGFyZ2V0Vmlld1RhYiA9IHRoaXMuZHJvcFRhcmdldFZpZXdUYWIoKTtcbiAgICBpZiAodGhpcy5fdmlld0RyYWdTZXJ2aWNlLmlzRHJhZ092ZXJUYWJiYXIgIT09IHRoaXMucGFydC5pZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZpZXdUYWJzKCkuZXZlcnkodmlld1RhYiA9PiBnZXRDc3NUcmFuc2xhdGlvbih2aWV3VGFiLmhvc3QpLnRyYW5zbGF0ZVggPT09ICdub25lJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgdmlld1RhYnMgPSB0aGlzLl92aWV3VGFicygpLmZpbHRlcih2aWV3VGFiID0+IHZpZXdUYWIgIT09IHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIoKSk7XG4gICAgY29uc3QgZHJvcFRhcmdldEluZGV4ID0gZHJvcFRhcmdldFZpZXdUYWIgPT09ICdlbmQnID8gdmlld1RhYnMubGVuZ3RoIDogdmlld1RhYnMuaW5kZXhPZihkcm9wVGFyZ2V0Vmlld1RhYiEpO1xuICAgIGNvbnN0IGRyYWdTb3VyY2VXaWR0aCA9IHRoaXMuX2RyYWdEYXRhIS52aWV3VGFiV2lkdGg7XG5cbiAgICByZXR1cm4gdmlld1RhYnMuZXZlcnkoKHZpZXdUYWIsIGkpID0+IHtcbiAgICAgIGNvbnN0IHZpZXdUYWJUcmFuc2xhdGVYID0gZ2V0Q3NzVHJhbnNsYXRpb24odmlld1RhYi5ob3N0KS50cmFuc2xhdGVYO1xuICAgICAgLy8gRXhwZWN0IHRhYnMgcHJlY2VkaW5nIHRoZSBkcm9wIHRhcmdldCBub3QgdG8gYmUgc2hpZnRlZCB0byB0aGUgcmlnaHQuXG4gICAgICBpZiAoaSA8IGRyb3BUYXJnZXRJbmRleCAmJiB2aWV3VGFiVHJhbnNsYXRlWCAhPT0gJ25vbmUnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIC8vIEV4cGVjdCBkcm9wIHRhcmdldCBhbmQgdGFicyBmb2xsb3dpbmcgdGhlIGRyb3AgdGFyZ2V0IHRvIGJlIHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0LlxuICAgICAgaWYgKGkgPj0gZHJvcFRhcmdldEluZGV4ICYmIE1hdGguZmxvb3IoTnVtYmVyKHZpZXdUYWJUcmFuc2xhdGVYKSkgIT09IE1hdGguZmxvb3IoZHJhZ1NvdXJjZVdpZHRoKSkgeyAvLyBjb21wYXJlIGZsb29yZWQgbnVtYmVycyBiZWNhdXNlIGB0cmFuc2xhdGVYYCBpcyBub3QgcHJlY2lzZVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhbnMgdXAgdGhlIGRyYWcgc3RhdGUsIHVuc2V0dGluZyBkcmFnIGRhdGEgYW5kIGRyYWcgc291cmNlIGJhc2VkIG9uIHByb3ZpZGVkIG9wdGlvbnMuXG4gICAqL1xuICBwcml2YXRlIHVuc2V0RHJhZ1N0YXRlKG9wdGlvbnM/OiB7dW5zZXREcmFnU291cmNlPzogZmFsc2U7IHVuc2V0RHJhZ0RhdGE/OiBmYWxzZX0pOiB2b2lkIHtcbiAgICB0aGlzLmRyb3BUYXJnZXRWaWV3VGFiLnNldChudWxsKTtcbiAgICB0aGlzLl9vblVuc2V0RHJhZ1N0YXRlLnNldCgpO1xuICAgIHRoaXMuX3ZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlci51bnNldENvbnN0cmFpbkRyYWdJbWFnZVJlY3RGbih0aGlzLl9jb25zdHJhaW5GbiEpO1xuICAgIHRoaXMuX3ZpZXdEcmFnU2VydmljZS5zaWduYWxUYWJiYXJEcmFnTGVhdmUodGhpcy5wYXJ0LmlkKTtcbiAgICB0aGlzLl9jb25zdHJhaW5GbiA9IG51bGw7XG5cbiAgICB1bnNldENzc0NsYXNzKHRoaXMuX2hvc3QsICdkcmFnLW92ZXInLCAncG9pbnRlci1ldmVudHMtZGlzYWJsZWQnKTtcbiAgICB1bnNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsICctLcm1cGFydC1iYXItZHJhZy1zb3VyY2Utd2lkdGgnLCAnLS3JtXBhcnQtYmFyLWRyYWctcGxhY2Vob2xkZXItd2lkdGgnKTtcblxuICAgIGlmIChvcHRpb25zPy51bnNldERyYWdTb3VyY2UgPz8gdHJ1ZSkge1xuICAgICAgdGhpcy5kcmFnU291cmNlVmlld1RhYi5zZXQobnVsbCk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zPy51bnNldERyYWdEYXRhID8/IHRydWUpIHtcbiAgICAgIHRoaXMuX2RyYWdEYXRhID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZXMgZ2l2ZW4gZnVuY3Rpb24gd2hlbiB0aGUgZHJhZyBhbmltYXRpb24gaGFzIGZpbmlzaGVkLCBpLmUuLCB0YWJzIGhhdmUgdHJhbnNpdGlvbmVkIHRvIHRoZWlyIGZpbmFsIHBvc2l0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBvbkRyYWdBbmltYXRpb25TdGFibGUoY2FsbGJhY2s6ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICBpZiAoTmdab25lLmlzSW5Bbmd1bGFyWm9uZSgpKSB7XG4gICAgICB0aGlzLl96b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHRoaXMub25EcmFnQW5pbWF0aW9uU3RhYmxlKGNhbGxiYWNrKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB0aGlzLmlzRHJhZ0FuaW1hdGlvblN0YWJsZSgpID8gY2FsbGJhY2soKSA6IHRoaXMub25EcmFnQW5pbWF0aW9uU3RhYmxlKGNhbGxiYWNrKSk7XG4gIH1cblxuICAvKipcbiAgICogU2Nyb2xscyB0aGUgdGFiIG9mIHRoZSBhY3RpdmUgdmlldyBpbnRvIHZpZXcuXG4gICAqL1xuICBwcml2YXRlIGluc3RhbGxBY3RpdmVWaWV3U2Nyb2xsZXIoKTogdm9pZCB7XG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIC8vIFRyYWNrIHRoZSBhY3RpdmUgdmlldy5cbiAgICAgIGNvbnN0IGFjdGl2ZVZpZXdJZCA9IHRoaXMucGFydC5hY3RpdmVWaWV3SWQoKTtcbiAgICAgIC8vIFRoZXJlIG1heSBiZSBubyBhY3RpdmUgdmlldywgZS5nLiwgaWYgbm8gdmlldyBoYXMgYmVlbiBhY3RpdmF0ZWQsIG9yIHdoZW4gZHJhZ2dpbmcgdGhlIGxhc3QgdmlldyBvdXQgb2YgdGhlIHRhYmJhci5cbiAgICAgIGlmICghYWN0aXZlVmlld0lkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gRG8gbm90IHRyYWNrIHJlbmRlcmVkIHRhYnMgaW4gZ2VuZXJhbCB0byBwcmV2ZW50IHVud2FudGVkIHNjcm9sbGluZyB3aGVuIG9wZW5pbmcgb3IgY2xvc2luZyBpbmFjdGl2ZSB0YWJzLlxuICAgICAgY29uc3Qgdmlld1RhYnMgPSB1bnRyYWNrZWQoKCkgPT4gdGhpcy5fdmlld1RhYnMoKSk7XG5cbiAgICAgIC8vIEdldCBhIHJlZmVyZW5jZSB0byB0aGUgY3VycmVudGx5IHJlbmRlcmVkIGFjdGl2ZSB0YWIsIHdhaXRpbmcgaWYgbmVjZXNzYXJ5IGJ5IHRyYWNraW5nIHRoZSByZW5kZXJlZCB0YWJzLlxuICAgICAgY29uc3QgYWN0aXZlVmlld1RhYiA9IHZpZXdUYWJzLmZpbmQodmlld1RhYiA9PiB2aWV3VGFiLnZpZXdJZCA9PT0gYWN0aXZlVmlld0lkKTtcbiAgICAgIGlmICghYWN0aXZlVmlld1RhYikge1xuICAgICAgICB0aGlzLl92aWV3VGFicygpOyAvLyBUcmFjayByZW5kZXJlZCB0YWJzIHRvIHJlLWV4ZWN1dGUgb25jZSByZW5kZXJlZC5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBUcmFjayBuYXZpZ2F0aW9uIG9mIHRoZSBhY3RpdmUgdmlldywgc2Nyb2xsaW5nIGl0cyB0YWIgaW50byB2aWV3IGlmIG5lY2Vzc2FyeS5cbiAgICAgIGFjdGl2ZVZpZXdUYWIudmlldygpLm5hdmlnYXRpb25JZCgpO1xuXG4gICAgICAvLyBUcmFjayB1bnNldHRpbmcgZHJhZyBzdGF0ZSB0byBlbnN1cmUgdGhlIGFjdGl2ZSB2aWV3IGlzIHNjcm9sbGVkIGludG8gdmlldyBhZnRlciBkcm9wIG9yIGNhbmNlbC5cbiAgICAgIHRoaXMuX29uVW5zZXREcmFnU3RhdGUoKTtcblxuICAgICAgLy8gU2Nyb2xsIHRoZSB0YWIgaW50byB2aWV3IGlmIHNjcm9sbGVkIG91dCBvZiB2aWV3LlxuICAgICAgdW50cmFja2VkKCgpID0+IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5fdmlld3BvcnRDb21wb25lbnQoKS5pc0VsZW1lbnRJblZpZXcoYWN0aXZlVmlld1RhYi5ob3N0LCAnZnVsbCcpKSB7XG4gICAgICAgICAgdGhpcy5fdmlld3BvcnRDb21wb25lbnQoKS5zY3JvbGxJbnRvVmlldyhhY3RpdmVWaWV3VGFiLmhvc3QpO1xuICAgICAgICB9XG4gICAgICB9KSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB7QGxpbmsgybVXb3JrYmVuY2hWaWV3fSB3aGVuIGl0cyB0YWIgaXMgc2Nyb2xsZWQgaW50byB2aWV3LlxuICAgKi9cbiAgcHJpdmF0ZSBpbnN0YWxsU2Nyb2xsZWRJbnRvVmlld1VwZGF0ZXIoKTogdm9pZCB7XG4gICAgdGhpcy5fdmlld3BvcnRDaGFuZ2UkXG4gICAgICAucGlwZShcbiAgICAgICAgbWFwKCgpID0+IHRoaXMuX3ZpZXdUYWJzKCkpLFxuICAgICAgICBmaWx0ZXJBcnJheSh2aWV3VGFiID0+IHZpZXdUYWIgIT09IHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIoKSksIC8vIHNraXAgZHJhZyBzb3VyY2UgYXMgYWx3YXlzIHNjcm9sbGVkIG91dCBvZiB2aWV3XG4gICAgICAgIG1lcmdlTWFwKHZpZXdUYWJzID0+IGZyb20odmlld1RhYnMpKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKHZpZXdUYWIgPT4ge1xuICAgICAgICB2aWV3VGFiLnZpZXcoKS5zY3JvbGxlZEludG9WaWV3ID0gdGhpcy5fdmlld3BvcnRDb21wb25lbnQoKS5pc0VsZW1lbnRJblZpZXcodmlld1RhYi5ob3N0LCAnZnVsbCcpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU3Vic2NyaWJlcyB0byBkcmFnIGV2ZW50cy5cbiAgICovXG4gIHByaXZhdGUgaW5zdGFsbFZpZXdEcmFnTGlzdGVuZXIoKTogdm9pZCB7XG4gICAgY29uc3Qgem9uZSA9IGluamVjdChOZ1pvbmUpO1xuXG4gICAgLy8gU3Vic2NyaWJlIHRvIGRyYWcgZXZlbnRzIHJlbGV2YW50IGZvciB0aGlzIHRhYmJhci5cbiAgICB0aGlzLl92aWV3RHJhZ1NlcnZpY2Uudmlld0RyYWckKHRoaXMuX2hvc3QpXG4gICAgICAucGlwZShcbiAgICAgICAgc3Vic2NyaWJlSW4oZm4gPT4gem9uZS5ydW5PdXRzaWRlQW5ndWxhcihmbikpLFxuICAgICAgICBjYWxjdWxhdGVEaXN0YW5jZSgoKSA9PiB0aGlzLl92aWV3cG9ydENvbXBvbmVudCgpKSwgLy8gcHJvdmlkZSB2aWV3cG9ydCBsYXppbHkgYmVjYXVzZSBub3QgaW5qZWN0ZWQgeWV0XG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCgpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoe2V2ZW50LCBkcmFnRGlzdGFuY2UsIHNjcm9sbERpc3RhbmNlfSkgPT4ge1xuICAgICAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcbiAgICAgICAgICBjYXNlICdkcmFnc3RhcnQnOlxuICAgICAgICAgICAgdGhpcy5vblRhYkRyYWdTdGFydCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZHJhZ2VuZCc6XG4gICAgICAgICAgICB0aGlzLm9uVGFiRHJhZ0VuZChldmVudCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdkcmFnZW50ZXInOlxuICAgICAgICAgICAgdGhpcy5vblRhYmJhckRyYWdFbnRlcihldmVudCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdkcmFnb3Zlcic6XG4gICAgICAgICAgICB0aGlzLm9uVGFiYmFyRHJhZ092ZXIoZXZlbnQsIGRyYWdEaXN0YW5jZSwgc2Nyb2xsRGlzdGFuY2UpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZHJhZ2xlYXZlJzpcbiAgICAgICAgICAgIHRoaXMub25UYWJiYXJEcmFnTGVhdmUoZXZlbnQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZHJvcCc6XG4gICAgICAgICAgICB0aGlzLm9uVGFiYmFyRHJvcCgpLnRoZW4oKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIC8vIEdldCBub3RpZmllZCB3aGVuIGEgdmlldyBoYXMgbW92ZWQgaW4gdGhlIGxheW91dC5cbiAgICB0aGlzLl92aWV3RHJhZ1NlcnZpY2Uudmlld01vdmVkJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHN1YnNjcmliZUluKGZuID0+IHpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoZm4pKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKGV2ZW50ID0+IHRoaXMub25UYWJNb3ZlZChldmVudCkpO1xuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgZGlzdGFuY2UgdGhlIGRyYWcgcG9pbnRlciBhbmQgdmlld3BvcnQgaGF2ZSBtb3ZlZCBzaW5jZSB0aGUgbGFzdCBkcmFnIGV2ZW50LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNhbGN1bGF0ZURpc3RhbmNlKHZpZXdwb3J0OiAoKSA9PiBTY2lWaWV3cG9ydENvbXBvbmVudCk6IE9wZXJhdG9yRnVuY3Rpb248RHJhZ0V2ZW50LCBEcmFnRXZlbnRQbHVzRGlzdGFuY2U+IHtcbiAgICAgIHJldHVybiBzb3VyY2UkID0+IG5ldyBPYnNlcnZhYmxlPERyYWdFdmVudFBsdXNEaXN0YW5jZT4ob2JzZXJ2ZXIgPT4ge1xuICAgICAgICBsZXQgbGFzdFNjcmVlblg6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGxhc3RTY3JvbGxMZWZ0OiBudW1iZXIgfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gc291cmNlJC5zdWJzY3JpYmUoZXZlbnQgPT4ge1xuICAgICAgICAgIG9ic2VydmVyLm5leHQoe1xuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICBkcmFnRGlzdGFuY2U6IGV2ZW50LnNjcmVlblggLSAobGFzdFNjcmVlblggPz8gZXZlbnQuc2NyZWVuWCksXG4gICAgICAgICAgICBzY3JvbGxEaXN0YW5jZTogdmlld3BvcnQoKS5zY3JvbGxMZWZ0IC0gKGxhc3RTY3JvbGxMZWZ0ID8/IHZpZXdwb3J0KCkuc2Nyb2xsTGVmdCksXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgbGFzdFNjcmVlblggPSBldmVudC5zY3JlZW5YO1xuICAgICAgICAgIGxhc3RTY3JvbGxMZWZ0ID0gdmlld3BvcnQoKS5zY3JvbGxMZWZ0O1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuICgpID0+IHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVtaXRzIG9uIHtAbGluayBfdmlld3BvcnRDaGFuZ2UkfSB3aGVuIHRoZSB2aWV3cG9ydCBzaXplIG9yIHNjcm9sbCBwb3NpdGlvbiBjaGFuZ2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBpbnN0YWxsVmlld3BvcnRDaGFuZ2VUcmFja2VyKCk6IHZvaWQge1xuICAgIGNvbnN0IHZpZXdwb3J0U2l6ZSA9IGRpbWVuc2lvbihjb21wdXRlZCgoKSA9PiB0aGlzLl92aWV3cG9ydENvbXBvbmVudEVsZW1lbnQoKS5uYXRpdmVFbGVtZW50KSk7XG4gICAgY29uc3Qgdmlld3BvcnRDbGllbnRTaXplID0gZGltZW5zaW9uKGNvbXB1dGVkKCgpID0+IHRoaXMuX3ZpZXdwb3J0Q29tcG9uZW50KCkudmlld3BvcnRDbGllbnRFbGVtZW50KSk7XG4gICAgY29uc3Qgem9uZSA9IGluamVjdChOZ1pvbmUpO1xuXG4gICAgLy8gRGV0ZWN0IHJlc2l6aW5nLlxuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICAvLyBUcmFjayB2aWV3cG9ydCBhbmQgdmlld3BvcnQgY2xpZW50IHNpemVzLlxuICAgICAgdmlld3BvcnRTaXplKCk7XG4gICAgICB2aWV3cG9ydENsaWVudFNpemUoKTtcbiAgICAgIHVudHJhY2tlZCgoKSA9PiB0aGlzLl92aWV3cG9ydENoYW5nZSQubmV4dCgpKTtcbiAgICB9KTtcblxuICAgIC8vIERldGVjdCBzY3JvbGxpbmcuXG4gICAgZWZmZWN0KG9uQ2xlYW51cCA9PiB7XG4gICAgICBjb25zdCB2aWV3cG9ydCA9IHRoaXMuX3ZpZXdwb3J0Q29tcG9uZW50KCkudmlld3BvcnRFbGVtZW50O1xuICAgICAgdW50cmFja2VkKCgpID0+IHtcbiAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gZnJvbUV2ZW50KHZpZXdwb3J0LCAnc2Nyb2xsJylcbiAgICAgICAgICAucGlwZShzdWJzY3JpYmVJbihmbiA9PiB6b25lLnJ1bk91dHNpZGVBbmd1bGFyKGZuKSkpXG4gICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLl92aWV3cG9ydENoYW5nZSQubmV4dCgpKTtcbiAgICAgICAgb25DbGVhbnVwKCgpID0+IHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrcyB0aGUgdGFiYmFyIGluZGVudHMuXG4gICAqL1xuICBwcml2YXRlIGluc3RhbGxUYWJiYXJJbmRlbnRTaXplVHJhY2tlcigpOiB2b2lkIHtcbiAgICBjb25zdCB0YWJDb3JuZXJSYWRpdXNEaW1lbnNpb24gPSBkaW1lbnNpb24odGhpcy5fdGFiQ29ybmVyUmFkaXVzRWxlbWVudCk7XG4gICAgY29uc3QgcGFkZGluZ0lubGluZURpbWVuc2lvbiA9IGRpbWVuc2lvbih0aGlzLl9wYWRkaW5nSW5saW5lRWxlbWVudCk7XG5cbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgY29uc3QgaW5kZW50ID0gdGFiQ29ybmVyUmFkaXVzRGltZW5zaW9uKCkuY2xpZW50V2lkdGggKyBwYWRkaW5nSW5saW5lRGltZW5zaW9uKCkuY2xpZW50V2lkdGg7XG4gICAgICB0aGlzLl90YWJiYXJJbmRlbnQgPSB7bGVmdDogaW5kZW50LCByaWdodDogaW5kZW50fTtcbiAgICAgIHNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsIHtcbiAgICAgICAgJy0tybVwYXJ0LWJhci1pbmRlbnQtbGVmdCc6IGAke3RoaXMuX3RhYmJhckluZGVudC5sZWZ0fXB4YCxcbiAgICAgICAgJy0tybVwYXJ0LWJhci1pbmRlbnQtcmlnaHQnOiBgJHt0aGlzLl90YWJiYXJJbmRlbnQucmlnaHR9cHhgLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy51bnNldERyYWdTdGF0ZSgpO1xuICB9XG59XG5cbi8qKlxuICogQ29udGFpbnMgdGhlIGV2ZW50IHBsdXMgZHJhZyBhbmQgc2Nyb2xsIGRpc3RhbmNlLlxuICovXG5pbnRlcmZhY2UgRHJhZ0V2ZW50UGx1c0Rpc3RhbmNlIHtcbiAgLyoqXG4gICAqIFJlZmVyZW5jZSB0byB0aGUgZHJhZyBldmVudC5cbiAgICovXG4gIGV2ZW50OiBEcmFnRXZlbnQ7XG4gIC8qKlxuICAgKiBEaXN0YW5jZSB0aGUgZHJhZyBwb2ludGVyIGhhcyBtb3ZlZCBzaW5jZSB0aGUgbGFzdCBkcmFnIGV2ZW50LlxuICAgKi9cbiAgZHJhZ0Rpc3RhbmNlOiBudW1iZXI7XG4gIC8qKlxuICAgKiBEaXN0YW5jZSB0aGUgdmlld3BvcnQgaGFzIHNjcm9sbGVkIHNpbmNlIHRoZSBsYXN0IGRyYWcgZXZlbnQuXG4gICAqL1xuICBzY3JvbGxEaXN0YW5jZTogbnVtYmVyO1xufVxuIiwiPHNjaS12aWV3cG9ydCBjbGFzcz1cInRhYmJhciBlMmUtdGFiYmFyXCIgc2Nyb2xsYmFyU3R5bGU9XCJoaWRkZW5cIj5cbiAgQGZvciAodmlld0lkIG9mIHBhcnQudmlld0lkcygpOyB0cmFjayB2aWV3SWQpIHtcbiAgICBAaWYgKHZpZXd0YWIgPT09IGRyb3BUYXJnZXRWaWV3VGFiKCkpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJkaXZpZGVyXCI+PC9kaXY+XG4gICAgfVxuICAgIDx3Yi12aWV3LXRhYiAjdmlld3RhYlxuICAgICAgICAgICAgICAgICBbdmlld0lkXT1cInZpZXdJZFwiXG4gICAgICAgICAgICAgICAgIFtjbGFzcy5kcmFnLXNvdXJjZV09XCJ2aWV3dGFiID09PSBkcmFnU291cmNlVmlld1RhYigpXCJcbiAgICAgICAgICAgICAgICAgW2NsYXNzLmRyb3AtdGFyZ2V0XT1cInZpZXd0YWIgPT09IGRyb3BUYXJnZXRWaWV3VGFiKClcIi8+XG4gICAgPGRpdiBjbGFzcz1cImRpdmlkZXJcIj48L2Rpdj5cbiAgfVxuXG4gIDwhLS0gUGxhY2Vob2xkZXIgZm9yIGV4cGFuZGluZyB0aGUgdmlld3BvcnQgd2hlbiBkcmFnZ2luZyBhIHRhYiB0byB0aGUgcmlnaHQsIG1vdmluZyBwYXJ0IGFjdGlvbnMgYWxvbmcgd2l0aCB0aGUgZHJhZ292ZXIgZXZlbnQuIC0tPlxuICA8ZGl2IGNsYXNzPVwiZHJhZy1wbGFjZWhvbGRlclwiPjwvZGl2PlxuPC9zY2ktdmlld3BvcnQ+XG5cbjwhLS0gQWN0aW9ucyAtLT5cbkBpZiAoc3RhcnRBY3Rpb25zKCkubGVuZ3RoKSB7XG4gIDx3Yi1wYXJ0LWFjdGlvbi1iYXIgW2FjdGlvbnNdPVwic3RhcnRBY3Rpb25zKClcIiBjbGFzcz1cInN0YXJ0XCIvPlxufVxuPGRpdiBjbGFzcz1cImZpbGxlclwiICNmaWxsZXI+PC9kaXY+XG5AaWYgKGVuZEFjdGlvbnMoKS5sZW5ndGgpIHtcbiAgPHdiLXBhcnQtYWN0aW9uLWJhciBbYWN0aW9uc109XCJlbmRBY3Rpb25zKClcIiBjbGFzcz1cImVuZFwiLz5cbn1cblxuPCEtLSBWaWV3IExpc3QgRHJvcGRvd24gLS0+XG48d2Itdmlldy1saXN0LWJ1dHRvbi8+XG5cbjwhLS0gRWxlbWVudCBmb3IgaW5qZWN0aW5nIHRoZSBjb3JuZXIgcmFkaXVzIGludG8gdGhlIGNvbXBvbmVudC4gLS0+XG48ZGl2IGNsYXNzPVwidGFiLWNvcm5lci1yYWRpdXNcIiAjdGFiX2Nvcm5lcl9yYWRpdXM+PC9kaXY+XG48IS0tIEVsZW1lbnQgZm9yIGluamVjdGluZyB0aGUgdGFiYmFyIHBhZGRpbmcgaW50byB0aGUgY29tcG9uZW50LiAtLT5cbjxkaXYgY2xhc3M9XCJwYWRkaW5nLWlubGluZVwiICNwYWRkaW5nX2lubGluZT48L2Rpdj5cbiJdfQ==