@angular/core 13.0.0-next.9 → 13.0.0-rc.3

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 (558) hide show
  1. package/core.d.ts +791 -1180
  2. package/esm2020/core.mjs +5 -0
  3. package/esm2020/index.mjs +14 -0
  4. package/{esm2015/public_api.js → esm2020/public_api.mjs} +0 -0
  5. package/esm2020/src/application_init.mjs +140 -0
  6. package/esm2020/src/application_module.mjs +130 -0
  7. package/esm2020/src/application_ref.mjs +738 -0
  8. package/{esm2015/src/application_tokens.js → esm2020/src/application_tokens.mjs} +0 -0
  9. package/esm2020/src/change_detection/change_detection.mjs +31 -0
  10. package/esm2020/src/change_detection/change_detection_util.mjs +64 -0
  11. package/esm2020/src/change_detection/change_detector_ref.mjs +89 -0
  12. package/{esm2015/src/change_detection/constants.js → esm2020/src/change_detection/constants.mjs} +0 -0
  13. package/esm2020/src/change_detection/differs/default_iterable_differ.mjs +666 -0
  14. package/{esm2015/src/change_detection/differs/default_keyvalue_differ.js → esm2020/src/change_detection/differs/default_keyvalue_differ.mjs} +0 -0
  15. package/{esm2015/src/change_detection/differs/iterable_differs.js → esm2020/src/change_detection/differs/iterable_differs.mjs} +0 -0
  16. package/{esm2015/src/change_detection/differs/keyvalue_differs.js → esm2020/src/change_detection/differs/keyvalue_differs.mjs} +0 -0
  17. package/{esm2015/src/change_detection/pipe_transform.js → esm2020/src/change_detection/pipe_transform.mjs} +0 -0
  18. package/esm2020/src/change_detection.mjs +14 -0
  19. package/esm2020/src/codegen_private_exports.mjs +11 -0
  20. package/{esm2015/src/compiler/compiler_facade.js → esm2020/src/compiler/compiler_facade.mjs} +0 -0
  21. package/{esm2015/src/compiler/compiler_facade_interface.js → esm2020/src/compiler/compiler_facade_interface.mjs} +1 -1
  22. package/esm2020/src/console.mjs +26 -0
  23. package/esm2020/src/core.mjs +52 -0
  24. package/esm2020/src/core_private_export.mjs +34 -0
  25. package/esm2020/src/core_render3_private_export.mjs +47 -0
  26. package/esm2020/src/debug/debug_node.mjs +625 -0
  27. package/{esm2015/src/debug/proxy.js → esm2020/src/debug/proxy.mjs} +0 -0
  28. package/{esm2015/src/di/forward_ref.js → esm2020/src/di/forward_ref.mjs} +0 -0
  29. package/{esm2015/src/di/index.js → esm2020/src/di/index.mjs} +0 -0
  30. package/{esm2015/src/di/inject_switch.js → esm2020/src/di/inject_switch.mjs} +0 -0
  31. package/esm2020/src/di/injectable.mjs +27 -0
  32. package/esm2020/src/di/injection_token.mjs +82 -0
  33. package/esm2020/src/di/injector.mjs +323 -0
  34. package/esm2020/src/di/injector_compatibility.mjs +185 -0
  35. package/{esm2015/src/di/injector_marker.js → esm2020/src/di/injector_marker.mjs} +0 -0
  36. package/{esm2015/src/di/injector_token.js → esm2020/src/di/injector_token.mjs} +0 -0
  37. package/{esm2015/src/di/interface/defs.js → esm2020/src/di/interface/defs.mjs} +0 -0
  38. package/{esm2015/src/di/interface/injector.js → esm2020/src/di/interface/injector.mjs} +0 -0
  39. package/{esm2015/src/di/interface/provider.js → esm2020/src/di/interface/provider.mjs} +0 -0
  40. package/{esm2015/src/di/jit/environment.js → esm2020/src/di/jit/environment.mjs} +0 -0
  41. package/esm2020/src/di/jit/injectable.mjs +94 -0
  42. package/{esm2015/src/di/jit/util.js → esm2020/src/di/jit/util.mjs} +0 -0
  43. package/esm2020/src/di/metadata.mjs +60 -0
  44. package/esm2020/src/di/metadata_attr.mjs +24 -0
  45. package/{esm2015/src/di/null_injector.js → esm2020/src/di/null_injector.mjs} +0 -0
  46. package/{esm2015/src/di/provider_token.js → esm2020/src/di/provider_token.mjs} +0 -0
  47. package/{esm2015/src/di/r3_injector.js → esm2020/src/di/r3_injector.mjs} +0 -0
  48. package/{esm2015/src/di/reflective_errors.js → esm2020/src/di/reflective_errors.mjs} +0 -0
  49. package/{esm2015/src/di/reflective_injector.js → esm2020/src/di/reflective_injector.mjs} +0 -0
  50. package/{esm2015/src/di/reflective_key.js → esm2020/src/di/reflective_key.mjs} +0 -0
  51. package/{esm2015/src/di/reflective_provider.js → esm2020/src/di/reflective_provider.mjs} +0 -0
  52. package/{esm2015/src/di/scope.js → esm2020/src/di/scope.mjs} +0 -0
  53. package/esm2020/src/di/util.mjs +51 -0
  54. package/{esm2015/src/di.js → esm2020/src/di.mjs} +0 -0
  55. package/{esm2015/src/error_handler.js → esm2020/src/error_handler.mjs} +0 -0
  56. package/{esm2015/src/errors.js → esm2020/src/errors.mjs} +0 -0
  57. package/esm2020/src/event_emitter.mjs +53 -0
  58. package/{esm2015/src/i18n/locale_data_api.js → esm2020/src/i18n/locale_data_api.mjs} +0 -0
  59. package/esm2020/src/i18n/locale_en.mjs +17 -0
  60. package/{esm2015/src/i18n/localization.js → esm2020/src/i18n/localization.mjs} +0 -0
  61. package/{esm2015/src/i18n/tokens.js → esm2020/src/i18n/tokens.mjs} +0 -0
  62. package/{esm2015/src/interface/lifecycle_hooks.js → esm2020/src/interface/lifecycle_hooks.mjs} +0 -0
  63. package/{esm2015/src/interface/simple_change.js → esm2020/src/interface/simple_change.mjs} +0 -0
  64. package/{esm2015/src/interface/type.js → esm2020/src/interface/type.mjs} +0 -0
  65. package/{esm2015/src/ivy_switch.js → esm2020/src/ivy_switch.mjs} +2 -2
  66. package/esm2020/src/linker/compiler.mjs +136 -0
  67. package/{esm2015/src/linker/component_factory.js → esm2020/src/linker/component_factory.mjs} +0 -0
  68. package/{esm2015/src/linker/component_factory_resolver.js → esm2020/src/linker/component_factory_resolver.mjs} +5 -5
  69. package/esm2020/src/linker/element_ref.mjs +59 -0
  70. package/esm2020/src/linker/ng_module_factory.mjs +29 -0
  71. package/esm2020/src/linker/ng_module_factory_loader.mjs +42 -0
  72. package/esm2020/src/linker/ng_module_factory_loader_impl.mjs +10 -0
  73. package/{esm2015/src/linker/ng_module_factory_registration.js → esm2020/src/linker/ng_module_factory_registration.mjs} +2 -2
  74. package/{esm2015/src/linker/query_list.js → esm2020/src/linker/query_list.mjs} +0 -0
  75. package/{esm2015/src/linker/template_ref.js → esm2020/src/linker/template_ref.mjs} +2 -2
  76. package/esm2020/src/linker/view_container_ref.mjs +283 -0
  77. package/{esm2015/src/linker/view_ref.js → esm2020/src/linker/view_ref.mjs} +0 -0
  78. package/esm2020/src/linker.mjs +19 -0
  79. package/esm2020/src/metadata/di.mjs +108 -0
  80. package/esm2020/src/metadata/directives.mjs +112 -0
  81. package/{esm2015/src/metadata/do_boostrap.js → esm2020/src/metadata/do_boostrap.mjs} +0 -0
  82. package/esm2020/src/metadata/ng_module.mjs +42 -0
  83. package/{esm2015/src/metadata/ng_module_def.js → esm2020/src/metadata/ng_module_def.mjs} +0 -0
  84. package/{esm2015/src/metadata/resource_loading.js → esm2020/src/metadata/resource_loading.mjs} +0 -0
  85. package/{esm2015/src/metadata/schema.js → esm2020/src/metadata/schema.mjs} +0 -0
  86. package/{esm2015/src/metadata/view.js → esm2020/src/metadata/view.mjs} +0 -0
  87. package/{esm2015/src/metadata.js → esm2020/src/metadata.mjs} +0 -0
  88. package/{esm2015/src/platform_core_providers.js → esm2020/src/platform_core_providers.mjs} +0 -0
  89. package/{esm2015/src/r3_symbols.js → esm2020/src/r3_symbols.mjs} +0 -0
  90. package/{esm2015/src/reflection/platform_reflection_capabilities.js → esm2020/src/reflection/platform_reflection_capabilities.mjs} +0 -0
  91. package/{esm2015/src/reflection/reflection.js → esm2020/src/reflection/reflection.mjs} +0 -0
  92. package/{esm2015/src/reflection/reflection_capabilities.js → esm2020/src/reflection/reflection_capabilities.mjs} +0 -0
  93. package/{esm2015/src/reflection/reflector.js → esm2020/src/reflection/reflector.mjs} +0 -0
  94. package/{esm2015/src/reflection/types.js → esm2020/src/reflection/types.mjs} +0 -0
  95. package/{esm2015/src/render/api.js → esm2020/src/render/api.mjs} +2 -2
  96. package/{esm2015/src/render/api_flags.js → esm2020/src/render/api_flags.mjs} +0 -0
  97. package/{esm2015/src/render.js → esm2020/src/render.mjs} +0 -0
  98. package/{esm2015/src/render3/assert.js → esm2020/src/render3/assert.mjs} +0 -0
  99. package/{esm2015/src/render3/bindings.js → esm2020/src/render3/bindings.mjs} +0 -0
  100. package/{esm2015/src/render3/collect_native_nodes.js → esm2020/src/render3/collect_native_nodes.mjs} +0 -0
  101. package/esm2020/src/render3/component.mjs +204 -0
  102. package/{esm2015/src/render3/component_ref.js → esm2020/src/render3/component_ref.mjs} +0 -0
  103. package/{esm2015/src/render3/context_discovery.js → esm2020/src/render3/context_discovery.mjs} +0 -0
  104. package/esm2020/src/render3/definition.mjs +296 -0
  105. package/{esm2015/src/render3/definition_factory.js → esm2020/src/render3/definition_factory.mjs} +0 -0
  106. package/{esm2015/src/render3/di.js → esm2020/src/render3/di.mjs} +3 -3
  107. package/{esm2015/src/render3/di_setup.js → esm2020/src/render3/di_setup.mjs} +0 -0
  108. package/esm2020/src/render3/error_code.mjs +42 -0
  109. package/esm2020/src/render3/error_details_base_url.mjs +16 -0
  110. package/{esm2015/src/render3/errors.js → esm2020/src/render3/errors.mjs} +0 -0
  111. package/{esm2015/src/render3/errors_di.js → esm2020/src/render3/errors_di.mjs} +0 -0
  112. package/{esm2015/src/render3/features/copy_definition_feature.js → esm2020/src/render3/features/copy_definition_feature.mjs} +0 -0
  113. package/{esm2015/src/render3/features/inherit_definition_feature.js → esm2020/src/render3/features/inherit_definition_feature.mjs} +0 -0
  114. package/esm2020/src/render3/features/ng_onchanges_feature.mjs +92 -0
  115. package/{esm2015/src/render3/features/providers_feature.js → esm2020/src/render3/features/providers_feature.mjs} +0 -0
  116. package/esm2020/src/render3/fields.mjs +21 -0
  117. package/{esm2015/src/render3/global_utils_api.js → esm2020/src/render3/global_utils_api.mjs} +0 -0
  118. package/{esm2015/src/render3/hooks.js → esm2020/src/render3/hooks.mjs} +0 -0
  119. package/{esm2015/src/render3/i18n/i18n_apply.js → esm2020/src/render3/i18n/i18n_apply.mjs} +0 -0
  120. package/{esm2015/src/render3/i18n/i18n_debug.js → esm2020/src/render3/i18n/i18n_debug.mjs} +0 -0
  121. package/{esm2015/src/render3/i18n/i18n_insert_before_index.js → esm2020/src/render3/i18n/i18n_insert_before_index.mjs} +0 -0
  122. package/{esm2015/src/render3/i18n/i18n_locale_id.js → esm2020/src/render3/i18n/i18n_locale_id.mjs} +0 -0
  123. package/{esm2015/src/render3/i18n/i18n_parse.js → esm2020/src/render3/i18n/i18n_parse.mjs} +0 -0
  124. package/{esm2015/src/render3/i18n/i18n_postprocess.js → esm2020/src/render3/i18n/i18n_postprocess.mjs} +0 -0
  125. package/{esm2015/src/render3/i18n/i18n_tree_shaking.js → esm2020/src/render3/i18n/i18n_tree_shaking.mjs} +0 -0
  126. package/{esm2015/src/render3/i18n/i18n_util.js → esm2020/src/render3/i18n/i18n_util.mjs} +0 -0
  127. package/{esm2015/src/render3/index.js → esm2020/src/render3/index.mjs} +0 -0
  128. package/{esm2015/src/render3/instructions/advance.js → esm2020/src/render3/instructions/advance.mjs} +0 -0
  129. package/{esm2015/src/render3/instructions/all.js → esm2020/src/render3/instructions/all.mjs} +0 -0
  130. package/{esm2015/src/render3/instructions/attribute.js → esm2020/src/render3/instructions/attribute.mjs} +0 -0
  131. package/{esm2015/src/render3/instructions/attribute_interpolation.js → esm2020/src/render3/instructions/attribute_interpolation.mjs} +0 -0
  132. package/{esm2015/src/render3/instructions/change_detection.js → esm2020/src/render3/instructions/change_detection.mjs} +0 -0
  133. package/{esm2015/src/render3/instructions/class_map_interpolation.js → esm2020/src/render3/instructions/class_map_interpolation.mjs} +0 -0
  134. package/{esm2015/src/render3/instructions/di.js → esm2020/src/render3/instructions/di.mjs} +0 -0
  135. package/{esm2015/src/render3/instructions/di_attr.js → esm2020/src/render3/instructions/di_attr.mjs} +0 -0
  136. package/{esm2015/src/render3/instructions/element.js → esm2020/src/render3/instructions/element.mjs} +0 -0
  137. package/{esm2015/src/render3/instructions/element_container.js → esm2020/src/render3/instructions/element_container.mjs} +0 -0
  138. package/{esm2015/src/render3/instructions/get_current_view.js → esm2020/src/render3/instructions/get_current_view.mjs} +0 -0
  139. package/{esm2015/src/render3/instructions/host_property.js → esm2020/src/render3/instructions/host_property.mjs} +0 -0
  140. package/{esm2015/src/render3/instructions/i18n.js → esm2020/src/render3/instructions/i18n.mjs} +0 -0
  141. package/{esm2015/src/render3/instructions/i18n_icu_container_visitor.js → esm2020/src/render3/instructions/i18n_icu_container_visitor.mjs} +0 -0
  142. package/{esm2015/src/render3/instructions/interpolation.js → esm2020/src/render3/instructions/interpolation.mjs} +0 -0
  143. package/{esm2015/src/render3/instructions/listener.js → esm2020/src/render3/instructions/listener.mjs} +0 -0
  144. package/{esm2015/src/render3/instructions/lview_debug.js → esm2020/src/render3/instructions/lview_debug.mjs} +0 -0
  145. package/{esm2015/src/render3/instructions/namespace.js → esm2020/src/render3/instructions/namespace.mjs} +0 -0
  146. package/{esm2015/src/render3/instructions/next_context.js → esm2020/src/render3/instructions/next_context.mjs} +0 -0
  147. package/{esm2015/src/render3/instructions/projection.js → esm2020/src/render3/instructions/projection.mjs} +0 -0
  148. package/{esm2015/src/render3/instructions/property.js → esm2020/src/render3/instructions/property.mjs} +0 -0
  149. package/{esm2015/src/render3/instructions/property_interpolation.js → esm2020/src/render3/instructions/property_interpolation.mjs} +0 -0
  150. package/esm2020/src/render3/instructions/shared.mjs +1811 -0
  151. package/{esm2015/src/render3/instructions/storage.js → esm2020/src/render3/instructions/storage.mjs} +0 -0
  152. package/{esm2015/src/render3/instructions/style_map_interpolation.js → esm2020/src/render3/instructions/style_map_interpolation.mjs} +0 -0
  153. package/{esm2015/src/render3/instructions/style_prop_interpolation.js → esm2020/src/render3/instructions/style_prop_interpolation.mjs} +0 -0
  154. package/{esm2015/src/render3/instructions/styling.js → esm2020/src/render3/instructions/styling.mjs} +0 -0
  155. package/{esm2015/src/render3/instructions/template.js → esm2020/src/render3/instructions/template.mjs} +0 -0
  156. package/{esm2015/src/render3/instructions/text.js → esm2020/src/render3/instructions/text.mjs} +0 -0
  157. package/{esm2015/src/render3/instructions/text_interpolation.js → esm2020/src/render3/instructions/text_interpolation.mjs} +0 -0
  158. package/{esm2015/src/render3/interfaces/container.js → esm2020/src/render3/interfaces/container.mjs} +0 -0
  159. package/{esm2015/src/render3/interfaces/context.js → esm2020/src/render3/interfaces/context.mjs} +0 -0
  160. package/{esm2015/src/render3/interfaces/definition.js → esm2020/src/render3/interfaces/definition.mjs} +0 -0
  161. package/{esm2015/src/render3/interfaces/document.js → esm2020/src/render3/interfaces/document.mjs} +0 -0
  162. package/{esm2015/src/render3/interfaces/i18n.js → esm2020/src/render3/interfaces/i18n.mjs} +0 -0
  163. package/{esm2015/src/render3/interfaces/injector.js → esm2020/src/render3/interfaces/injector.mjs} +0 -0
  164. package/{esm2015/src/render3/interfaces/node.js → esm2020/src/render3/interfaces/node.mjs} +0 -0
  165. package/{esm2015/src/render3/interfaces/player.js → esm2020/src/render3/interfaces/player.mjs} +0 -0
  166. package/{esm2015/src/render3/interfaces/projection.js → esm2020/src/render3/interfaces/projection.mjs} +0 -0
  167. package/{esm2015/src/render3/interfaces/public_definitions.js → esm2020/src/render3/interfaces/public_definitions.mjs} +0 -0
  168. package/{esm2015/src/render3/interfaces/query.js → esm2020/src/render3/interfaces/query.mjs} +0 -0
  169. package/esm2020/src/render3/interfaces/renderer.mjs +27 -0
  170. package/{esm2015/src/render3/interfaces/renderer_dom.js → esm2020/src/render3/interfaces/renderer_dom.mjs} +0 -0
  171. package/{esm2015/src/render3/interfaces/sanitization.js → esm2020/src/render3/interfaces/sanitization.mjs} +0 -0
  172. package/{esm2015/src/render3/interfaces/styling.js → esm2020/src/render3/interfaces/styling.mjs} +0 -0
  173. package/{esm2015/src/render3/interfaces/type_checks.js → esm2020/src/render3/interfaces/type_checks.mjs} +0 -0
  174. package/{esm2015/src/render3/interfaces/view.js → esm2020/src/render3/interfaces/view.mjs} +0 -0
  175. package/esm2020/src/render3/jit/directive.mjs +325 -0
  176. package/esm2020/src/render3/jit/environment.mjs +165 -0
  177. package/{esm2015/src/render3/jit/jit_options.js → esm2020/src/render3/jit/jit_options.mjs} +0 -0
  178. package/{esm2015/src/render3/jit/module.js → esm2020/src/render3/jit/module.mjs} +0 -0
  179. package/esm2020/src/render3/jit/partial.mjs +104 -0
  180. package/{esm2015/src/render3/jit/pipe.js → esm2020/src/render3/jit/pipe.mjs} +0 -0
  181. package/esm2020/src/render3/metadata.mjs +49 -0
  182. package/{esm2015/src/render3/namespaces.js → esm2020/src/render3/namespaces.mjs} +0 -0
  183. package/esm2020/src/render3/ng_module_ref.mjs +119 -0
  184. package/{esm2015/src/render3/node_assert.js → esm2020/src/render3/node_assert.mjs} +0 -0
  185. package/{esm2015/src/render3/node_manipulation.js → esm2020/src/render3/node_manipulation.mjs} +0 -0
  186. package/{esm2015/src/render3/node_manipulation_i18n.js → esm2020/src/render3/node_manipulation_i18n.mjs} +0 -0
  187. package/{esm2015/src/render3/node_selector_matcher.js → esm2020/src/render3/node_selector_matcher.mjs} +0 -0
  188. package/esm2020/src/render3/pipe.mjs +184 -0
  189. package/{esm2015/src/render3/profiler.js → esm2020/src/render3/profiler.mjs} +0 -0
  190. package/{esm2015/src/render3/pure_function.js → esm2020/src/render3/pure_function.mjs} +0 -0
  191. package/{esm2015/src/render3/query.js → esm2020/src/render3/query.mjs} +0 -0
  192. package/{esm2015/src/render3/state.js → esm2020/src/render3/state.mjs} +0 -0
  193. package/{esm2015/src/render3/styling/class_differ.js → esm2020/src/render3/styling/class_differ.mjs} +0 -0
  194. package/{esm2015/src/render3/styling/static_styling.js → esm2020/src/render3/styling/static_styling.mjs} +0 -0
  195. package/{esm2015/src/render3/styling/style_binding_list.js → esm2020/src/render3/styling/style_binding_list.mjs} +0 -0
  196. package/{esm2015/src/render3/styling/styling_parser.js → esm2020/src/render3/styling/styling_parser.mjs} +0 -0
  197. package/{esm2015/src/render3/tokens.js → esm2020/src/render3/tokens.mjs} +0 -0
  198. package/{esm2015/src/render3/util/attrs_utils.js → esm2020/src/render3/util/attrs_utils.mjs} +0 -0
  199. package/{esm2015/src/render3/util/change_detection_utils.js → esm2020/src/render3/util/change_detection_utils.mjs} +0 -0
  200. package/{esm2015/src/render3/util/debug_utils.js → esm2020/src/render3/util/debug_utils.mjs} +0 -0
  201. package/esm2020/src/render3/util/discovery_utils.mjs +411 -0
  202. package/esm2020/src/render3/util/global_utils.mjs +77 -0
  203. package/{esm2015/src/render3/util/injector_utils.js → esm2020/src/render3/util/injector_utils.mjs} +0 -0
  204. package/esm2020/src/render3/util/misc_utils.mjs +61 -0
  205. package/{esm2015/src/render3/util/stringify_utils.js → esm2020/src/render3/util/stringify_utils.mjs} +0 -0
  206. package/{esm2015/src/render3/util/view_traversal_utils.js → esm2020/src/render3/util/view_traversal_utils.mjs} +0 -0
  207. package/{esm2015/src/render3/util/view_utils.js → esm2020/src/render3/util/view_utils.mjs} +0 -0
  208. package/{esm2015/src/render3/view_engine_compatibility_prebound.js → esm2020/src/render3/view_engine_compatibility_prebound.mjs} +0 -0
  209. package/{esm2015/src/render3/view_ref.js → esm2020/src/render3/view_ref.mjs} +0 -0
  210. package/{esm2015/src/sanitization/bypass.js → esm2020/src/sanitization/bypass.mjs} +0 -0
  211. package/{esm2015/src/sanitization/html_sanitizer.js → esm2020/src/sanitization/html_sanitizer.mjs} +0 -0
  212. package/{esm2015/src/sanitization/inert_body.js → esm2020/src/sanitization/inert_body.mjs} +3 -3
  213. package/{esm2015/src/sanitization/sanitization.js → esm2020/src/sanitization/sanitization.mjs} +0 -0
  214. package/{esm2015/src/sanitization/sanitizer.js → esm2020/src/sanitization/sanitizer.mjs} +0 -0
  215. package/{esm2015/src/sanitization/security.js → esm2020/src/sanitization/security.mjs} +0 -0
  216. package/{esm2015/src/sanitization/url_sanitizer.js → esm2020/src/sanitization/url_sanitizer.mjs} +0 -0
  217. package/esm2020/src/testability/testability.mjs +258 -0
  218. package/{esm2015/src/util/array_utils.js → esm2020/src/util/array_utils.mjs} +0 -0
  219. package/{esm2015/src/util/assert.js → esm2020/src/util/assert.mjs} +0 -0
  220. package/{esm2015/src/util/char_code.js → esm2020/src/util/char_code.mjs} +0 -0
  221. package/{esm2015/src/util/closure.js → esm2020/src/util/closure.mjs} +0 -0
  222. package/{esm2015/src/util/comparison.js → esm2020/src/util/comparison.mjs} +0 -0
  223. package/{esm2015/src/util/decorators.js → esm2020/src/util/decorators.mjs} +0 -0
  224. package/{esm2015/src/util/dom.js → esm2020/src/util/dom.mjs} +0 -0
  225. package/{esm2015/src/util/empty.js → esm2020/src/util/empty.mjs} +0 -0
  226. package/{esm2015/src/util/errors.js → esm2020/src/util/errors.mjs} +0 -0
  227. package/{esm2015/src/util/global.js → esm2020/src/util/global.mjs} +0 -0
  228. package/{esm2015/src/util/is_dev_mode.js → esm2020/src/util/is_dev_mode.mjs} +0 -0
  229. package/{esm2015/src/util/iterable.js → esm2020/src/util/iterable.mjs} +0 -0
  230. package/{esm2015/src/util/lang.js → esm2020/src/util/lang.mjs} +0 -0
  231. package/{esm2015/src/util/microtask.js → esm2020/src/util/microtask.mjs} +0 -0
  232. package/{esm2015/src/util/named_array_type.js → esm2020/src/util/named_array_type.mjs} +0 -0
  233. package/{esm2015/src/util/ng_dev_mode.js → esm2020/src/util/ng_dev_mode.mjs} +0 -0
  234. package/{esm2015/src/util/ng_i18n_closure_mode.js → esm2020/src/util/ng_i18n_closure_mode.mjs} +0 -0
  235. package/{esm2015/src/util/ng_jit_mode.js → esm2020/src/util/ng_jit_mode.mjs} +0 -0
  236. package/{esm2015/src/util/ng_reflect.js → esm2020/src/util/ng_reflect.mjs} +0 -0
  237. package/{esm2015/src/util/noop.js → esm2020/src/util/noop.mjs} +0 -0
  238. package/{esm2015/src/util/property.js → esm2020/src/util/property.mjs} +0 -0
  239. package/{esm2015/src/util/raf.js → esm2020/src/util/raf.mjs} +0 -0
  240. package/{esm2015/src/util/security/trusted_type_defs.js → esm2020/src/util/security/trusted_type_defs.mjs} +0 -0
  241. package/esm2020/src/util/security/trusted_types.mjs +130 -0
  242. package/esm2020/src/util/security/trusted_types_bypass.mjs +83 -0
  243. package/{esm2015/src/util/stringify.js → esm2020/src/util/stringify.mjs} +0 -0
  244. package/{esm2015/src/util/symbol.js → esm2020/src/util/symbol.mjs} +0 -0
  245. package/{esm2015/src/version.js → esm2020/src/version.mjs} +1 -1
  246. package/{esm2015/src/view/element.js → esm2020/src/view/element.mjs} +0 -0
  247. package/{esm2015/src/view/entrypoint.js → esm2020/src/view/entrypoint.mjs} +0 -0
  248. package/{esm2015/src/view/errors.js → esm2020/src/view/errors.mjs} +0 -0
  249. package/{esm2015/src/view/index.js → esm2020/src/view/index.mjs} +2 -2
  250. package/{esm2015/src/view/ng_content.js → esm2020/src/view/ng_content.mjs} +0 -0
  251. package/{esm2015/src/view/ng_module.js → esm2020/src/view/ng_module.mjs} +0 -0
  252. package/esm2020/src/view/provider.mjs +490 -0
  253. package/{esm2015/src/view/provider_flags.js → esm2020/src/view/provider_flags.mjs} +0 -0
  254. package/{esm2015/src/view/pure_expression.js → esm2020/src/view/pure_expression.mjs} +0 -0
  255. package/{esm2015/src/view/query.js → esm2020/src/view/query.mjs} +0 -0
  256. package/{esm2015/src/view/refs.js → esm2020/src/view/refs.mjs} +0 -0
  257. package/{esm2015/src/view/services.js → esm2020/src/view/services.mjs} +0 -0
  258. package/{esm2015/src/view/text.js → esm2020/src/view/text.mjs} +0 -0
  259. package/{esm2015/src/view/types.js → esm2020/src/view/types.mjs} +0 -0
  260. package/esm2020/src/view/util.mjs +369 -0
  261. package/{esm2015/src/view/view.js → esm2020/src/view/view.mjs} +0 -0
  262. package/{esm2015/src/view/view_attach.js → esm2020/src/view/view_attach.mjs} +0 -0
  263. package/{esm2015/src/zone/ng_zone.js → esm2020/src/zone/ng_zone.mjs} +0 -0
  264. package/{esm2015/src/zone.js → esm2020/src/zone.mjs} +0 -0
  265. package/{esm2015/testing/index.js → esm2020/testing/index.mjs} +0 -0
  266. package/{esm2015/testing/public_api.js → esm2020/testing/public_api.mjs} +0 -0
  267. package/{esm2015/testing/src/async.js → esm2020/testing/src/async.mjs} +0 -0
  268. package/{esm2015/testing/src/component_fixture.js → esm2020/testing/src/component_fixture.mjs} +0 -0
  269. package/{esm2015/testing/src/fake_async.js → esm2020/testing/src/fake_async.mjs} +0 -0
  270. package/{esm2015/testing/src/lang_utils.js → esm2020/testing/src/lang_utils.mjs} +0 -0
  271. package/esm2020/testing/src/logger.mjs +34 -0
  272. package/{esm2015/testing/src/metadata_override.js → esm2020/testing/src/metadata_override.mjs} +0 -0
  273. package/{esm2015/testing/src/metadata_overrider.js → esm2020/testing/src/metadata_overrider.mjs} +0 -0
  274. package/esm2020/testing/src/ng_zone_mock.mjs +33 -0
  275. package/{esm2015/testing/src/private_export_testing.js → esm2020/testing/src/private_export_testing.mjs} +0 -0
  276. package/esm2020/testing/src/r3_test_bed.mjs +397 -0
  277. package/esm2020/testing/src/r3_test_bed_compiler.mjs +735 -0
  278. package/{esm2015/testing/src/resolvers.js → esm2020/testing/src/resolvers.mjs} +0 -0
  279. package/{esm2015/testing/src/styling.js → esm2020/testing/src/styling.mjs} +0 -0
  280. package/esm2020/testing/src/test_bed.mjs +614 -0
  281. package/esm2020/testing/src/test_bed_common.mjs +28 -0
  282. package/esm2020/testing/src/test_compiler.mjs +69 -0
  283. package/{esm2015/testing/src/test_hooks.js → esm2020/testing/src/test_hooks.mjs} +0 -0
  284. package/{esm2015/testing/src/testing.js → esm2020/testing/src/testing.mjs} +0 -0
  285. package/{esm2015/testing/src/testing_internal.js → esm2020/testing/src/testing_internal.mjs} +0 -0
  286. package/esm2020/testing/testing.mjs +5 -0
  287. package/fesm2015/{core.js → core.mjs} +496 -546
  288. package/fesm2015/core.mjs.map +1 -0
  289. package/fesm2015/{testing.js → testing.mjs} +50 -61
  290. package/fesm2015/testing.mjs.map +1 -0
  291. package/fesm2020/core.mjs +33109 -0
  292. package/fesm2020/core.mjs.map +1 -0
  293. package/fesm2020/testing.mjs +2635 -0
  294. package/fesm2020/testing.mjs.map +1 -0
  295. package/package.json +33 -8
  296. package/schematics/migrations/{move-document → testbed-teardown}/index.d.ts +2 -2
  297. package/schematics/migrations/testbed-teardown/index.js +92 -0
  298. package/schematics/migrations/testbed-teardown/util.d.ts +35 -0
  299. package/schematics/migrations/testbed-teardown/util.js +188 -0
  300. package/schematics/migrations.json +6 -101
  301. package/schematics/package.json +3 -0
  302. package/schematics/utils/import_manager.d.ts +1 -1
  303. package/schematics/utils/import_manager.js +22 -19
  304. package/schematics/utils/load_esm.d.ts +8 -0
  305. package/schematics/utils/load_esm.js +24 -2
  306. package/schematics/utils/ng_component_template.d.ts +1 -1
  307. package/schematics/utils/ng_component_template.js +12 -9
  308. package/schematics/utils/ng_decorators.d.ts +1 -1
  309. package/schematics/utils/ng_decorators.js +1 -1
  310. package/schematics/utils/typescript/class_declaration.d.ts +1 -1
  311. package/schematics/utils/typescript/class_declaration.js +10 -7
  312. package/schematics/utils/typescript/compiler_host.d.ts +1 -1
  313. package/schematics/utils/typescript/compiler_host.js +7 -4
  314. package/schematics/utils/typescript/decorators.d.ts +1 -1
  315. package/schematics/utils/typescript/decorators.js +7 -4
  316. package/schematics/utils/typescript/find_base_classes.d.ts +1 -1
  317. package/schematics/utils/typescript/find_base_classes.js +6 -3
  318. package/schematics/utils/typescript/functions.d.ts +1 -1
  319. package/schematics/utils/typescript/functions.js +9 -6
  320. package/schematics/utils/typescript/imports.d.ts +1 -1
  321. package/schematics/utils/typescript/imports.js +12 -9
  322. package/schematics/utils/typescript/nodes.d.ts +1 -1
  323. package/schematics/utils/typescript/nodes.js +11 -8
  324. package/schematics/utils/typescript/parse_tsconfig.d.ts +1 -1
  325. package/schematics/utils/typescript/parse_tsconfig.js +31 -9
  326. package/schematics/utils/typescript/property_name.d.ts +1 -1
  327. package/schematics/utils/typescript/property_name.js +7 -4
  328. package/schematics/utils/typescript/symbol.d.ts +1 -1
  329. package/schematics/utils/typescript/symbol.js +15 -12
  330. package/testing/package.json +5 -5
  331. package/testing/testing.d.ts +4 -333
  332. package/bundles/core-testing.umd.js +0 -3179
  333. package/bundles/core-testing.umd.js.map +0 -1
  334. package/bundles/core.umd.js +0 -34454
  335. package/bundles/core.umd.js.map +0 -1
  336. package/core.metadata.json +0 -1
  337. package/esm2015/core.externs.js +0 -6
  338. package/esm2015/core.js +0 -38
  339. package/esm2015/index.js +0 -13
  340. package/esm2015/src/application_init.js +0 -142
  341. package/esm2015/src/application_module.js +0 -134
  342. package/esm2015/src/application_ref.js +0 -738
  343. package/esm2015/src/change_detection/change_detection.js +0 -31
  344. package/esm2015/src/change_detection/change_detection_util.js +0 -105
  345. package/esm2015/src/change_detection/change_detector_ref.js +0 -96
  346. package/esm2015/src/change_detection/differs/default_iterable_differ.js +0 -668
  347. package/esm2015/src/change_detection.js +0 -14
  348. package/esm2015/src/codegen_private_exports.js +0 -11
  349. package/esm2015/src/compiler/compiler.externs.js +0 -0
  350. package/esm2015/src/console.js +0 -23
  351. package/esm2015/src/core.js +0 -50
  352. package/esm2015/src/core_private_export.js +0 -35
  353. package/esm2015/src/core_render3_private_export.js +0 -45
  354. package/esm2015/src/debug/debug_node.js +0 -632
  355. package/esm2015/src/di/injectable.js +0 -36
  356. package/esm2015/src/di/injection_token.js +0 -75
  357. package/esm2015/src/di/injector.js +0 -326
  358. package/esm2015/src/di/injector_compatibility.js +0 -187
  359. package/esm2015/src/di/interface/interface.externs.js +0 -0
  360. package/esm2015/src/di/jit/injectable.js +0 -96
  361. package/esm2015/src/di/metadata.js +0 -62
  362. package/esm2015/src/di/metadata_attr.js +0 -24
  363. package/esm2015/src/di/util.js +0 -53
  364. package/esm2015/src/event_emitter.js +0 -54
  365. package/esm2015/src/i18n/locale_en.js +0 -17
  366. package/esm2015/src/interface/interface.externs.js +0 -0
  367. package/esm2015/src/linker/compiler.js +0 -118
  368. package/esm2015/src/linker/element_ref.js +0 -66
  369. package/esm2015/src/linker/ng_module_factory.js +0 -21
  370. package/esm2015/src/linker/ng_module_factory_loader.js +0 -32
  371. package/esm2015/src/linker/view_container_ref.js +0 -290
  372. package/esm2015/src/linker.js +0 -19
  373. package/esm2015/src/metadata/di.js +0 -99
  374. package/esm2015/src/metadata/directives.js +0 -120
  375. package/esm2015/src/metadata/ng_module.js +0 -44
  376. package/esm2015/src/reflection/reflection.externs.js +0 -0
  377. package/esm2015/src/render3/component.js +0 -206
  378. package/esm2015/src/render3/definition.js +0 -299
  379. package/esm2015/src/render3/error_code.js +0 -45
  380. package/esm2015/src/render3/features/ng_onchanges_feature.js +0 -92
  381. package/esm2015/src/render3/fields.js +0 -22
  382. package/esm2015/src/render3/instructions/shared.js +0 -1813
  383. package/esm2015/src/render3/interfaces/renderer.js +0 -29
  384. package/esm2015/src/render3/jit/directive.js +0 -312
  385. package/esm2015/src/render3/jit/environment.js +0 -167
  386. package/esm2015/src/render3/jit/partial.js +0 -105
  387. package/esm2015/src/render3/metadata.js +0 -49
  388. package/esm2015/src/render3/ng_module_ref.js +0 -108
  389. package/esm2015/src/render3/pipe.js +0 -202
  390. package/esm2015/src/render3/util/discovery_utils.js +0 -411
  391. package/esm2015/src/render3/util/global_utils.js +0 -78
  392. package/esm2015/src/render3/util/misc_utils.js +0 -63
  393. package/esm2015/src/testability/testability.js +0 -256
  394. package/esm2015/src/util/security/trusted_types.js +0 -133
  395. package/esm2015/src/util/security/trusted_types_bypass.js +0 -86
  396. package/esm2015/src/util/util.externs.js +0 -0
  397. package/esm2015/src/view/provider.js +0 -490
  398. package/esm2015/src/view/util.js +0 -378
  399. package/esm2015/testing/src/logger.js +0 -32
  400. package/esm2015/testing/src/ng_zone_mock.js +0 -31
  401. package/esm2015/testing/src/r3_test_bed.js +0 -397
  402. package/esm2015/testing/src/r3_test_bed_compiler.js +0 -744
  403. package/esm2015/testing/src/test_bed.js +0 -608
  404. package/esm2015/testing/src/test_bed_common.js +0 -31
  405. package/esm2015/testing/src/test_compiler.js +0 -66
  406. package/esm2015/testing/testing.externs.js +0 -6
  407. package/esm2015/testing/testing.js +0 -7
  408. package/fesm2015/core.js.map +0 -1
  409. package/fesm2015/testing.js.map +0 -1
  410. package/schematics/migrations/abstract-control-parent/index.d.ts +0 -11
  411. package/schematics/migrations/abstract-control-parent/index.js +0 -69
  412. package/schematics/migrations/abstract-control-parent/util.d.ts +0 -14
  413. package/schematics/migrations/abstract-control-parent/util.js +0 -64
  414. package/schematics/migrations/activated-route-snapshot-fragment/index.d.ts +0 -13
  415. package/schematics/migrations/activated-route-snapshot-fragment/index.js +0 -70
  416. package/schematics/migrations/activated-route-snapshot-fragment/util.d.ts +0 -16
  417. package/schematics/migrations/activated-route-snapshot-fragment/util.js +0 -48
  418. package/schematics/migrations/can-activate-with-redirect-to/index.d.ts +0 -11
  419. package/schematics/migrations/can-activate-with-redirect-to/index.js +0 -66
  420. package/schematics/migrations/can-activate-with-redirect-to/util.d.ts +0 -11
  421. package/schematics/migrations/can-activate-with-redirect-to/util.js +0 -70
  422. package/schematics/migrations/deep-shadow-piercing-selector/index.d.ts +0 -10
  423. package/schematics/migrations/deep-shadow-piercing-selector/index.js +0 -49
  424. package/schematics/migrations/dynamic-queries/index.d.ts +0 -13
  425. package/schematics/migrations/dynamic-queries/index.js +0 -73
  426. package/schematics/migrations/dynamic-queries/util.d.ts +0 -25
  427. package/schematics/migrations/dynamic-queries/util.js +0 -81
  428. package/schematics/migrations/initial-navigation/collector.d.ts +0 -22
  429. package/schematics/migrations/initial-navigation/collector.js +0 -119
  430. package/schematics/migrations/initial-navigation/index.d.ts +0 -11
  431. package/schematics/migrations/initial-navigation/index.js +0 -83
  432. package/schematics/migrations/initial-navigation/transform.d.ts +0 -20
  433. package/schematics/migrations/initial-navigation/transform.js +0 -68
  434. package/schematics/migrations/initial-navigation/update_recorder.d.ts +0 -18
  435. package/schematics/migrations/initial-navigation/update_recorder.js +0 -20
  436. package/schematics/migrations/initial-navigation/util.d.ts +0 -12
  437. package/schematics/migrations/initial-navigation/util.js +0 -43
  438. package/schematics/migrations/missing-injectable/definition_collector.d.ts +0 -37
  439. package/schematics/migrations/missing-injectable/definition_collector.js +0 -89
  440. package/schematics/migrations/missing-injectable/index.d.ts +0 -11
  441. package/schematics/migrations/missing-injectable/index.js +0 -122
  442. package/schematics/migrations/missing-injectable/providers_evaluator.d.ts +0 -36
  443. package/schematics/migrations/missing-injectable/providers_evaluator.js +0 -64
  444. package/schematics/migrations/missing-injectable/transform.d.ts +0 -69
  445. package/schematics/migrations/missing-injectable/transform.js +0 -201
  446. package/schematics/migrations/missing-injectable/update_recorder.d.ts +0 -21
  447. package/schematics/migrations/missing-injectable/update_recorder.js +0 -20
  448. package/schematics/migrations/module-with-providers/collector.d.ts +0 -34
  449. package/schematics/migrations/module-with-providers/collector.js +0 -73
  450. package/schematics/migrations/module-with-providers/index.d.ts +0 -13
  451. package/schematics/migrations/module-with-providers/index.js +0 -93
  452. package/schematics/migrations/module-with-providers/transform.d.ts +0 -49
  453. package/schematics/migrations/module-with-providers/transform.js +0 -148
  454. package/schematics/migrations/module-with-providers/util.d.ts +0 -13
  455. package/schematics/migrations/module-with-providers/util.js +0 -40
  456. package/schematics/migrations/move-document/document_import_visitor.d.ts +0 -27
  457. package/schematics/migrations/move-document/document_import_visitor.js +0 -74
  458. package/schematics/migrations/move-document/index.js +0 -93
  459. package/schematics/migrations/move-document/move-import.d.ts +0 -12
  460. package/schematics/migrations/move-document/move-import.js +0 -61
  461. package/schematics/migrations/native-view-encapsulation/index.d.ts +0 -11
  462. package/schematics/migrations/native-view-encapsulation/index.js +0 -63
  463. package/schematics/migrations/native-view-encapsulation/util.d.ts +0 -11
  464. package/schematics/migrations/native-view-encapsulation/util.js +0 -48
  465. package/schematics/migrations/navigation-extras-omissions/index.d.ts +0 -11
  466. package/schematics/migrations/navigation-extras-omissions/index.js +0 -69
  467. package/schematics/migrations/navigation-extras-omissions/util.d.ts +0 -11
  468. package/schematics/migrations/navigation-extras-omissions/util.js +0 -126
  469. package/schematics/migrations/relative-link-resolution/collector.d.ts +0 -22
  470. package/schematics/migrations/relative-link-resolution/collector.js +0 -95
  471. package/schematics/migrations/relative-link-resolution/index.d.ts +0 -11
  472. package/schematics/migrations/relative-link-resolution/index.js +0 -84
  473. package/schematics/migrations/relative-link-resolution/transform.d.ts +0 -22
  474. package/schematics/migrations/relative-link-resolution/transform.js +0 -65
  475. package/schematics/migrations/relative-link-resolution/update_recorder.d.ts +0 -18
  476. package/schematics/migrations/relative-link-resolution/update_recorder.js +0 -20
  477. package/schematics/migrations/relative-link-resolution/util.d.ts +0 -12
  478. package/schematics/migrations/relative-link-resolution/util.js +0 -43
  479. package/schematics/migrations/renderer-to-renderer2/helpers.d.ts +0 -25
  480. package/schematics/migrations/renderer-to-renderer2/helpers.js +0 -238
  481. package/schematics/migrations/renderer-to-renderer2/index.d.ts +0 -14
  482. package/schematics/migrations/renderer-to-renderer2/index.js +0 -135
  483. package/schematics/migrations/renderer-to-renderer2/migration.d.ts +0 -18
  484. package/schematics/migrations/renderer-to-renderer2/migration.js +0 -225
  485. package/schematics/migrations/renderer-to-renderer2/util.d.ts +0 -18
  486. package/schematics/migrations/renderer-to-renderer2/util.js +0 -83
  487. package/schematics/migrations/router-preserve-query-params/index.d.ts +0 -14
  488. package/schematics/migrations/router-preserve-query-params/index.js +0 -72
  489. package/schematics/migrations/router-preserve-query-params/util.d.ts +0 -11
  490. package/schematics/migrations/router-preserve-query-params/util.js +0 -103
  491. package/schematics/migrations/static-queries/angular/directive_inputs.d.ts +0 -11
  492. package/schematics/migrations/static-queries/angular/directive_inputs.js +0 -84
  493. package/schematics/migrations/static-queries/angular/ng_query_visitor.d.ts +0 -45
  494. package/schematics/migrations/static-queries/angular/ng_query_visitor.js +0 -127
  495. package/schematics/migrations/static-queries/angular/query-definition.d.ts +0 -37
  496. package/schematics/migrations/static-queries/angular/query-definition.js +0 -33
  497. package/schematics/migrations/static-queries/angular/super_class.d.ts +0 -15
  498. package/schematics/migrations/static-queries/angular/super_class.js +0 -35
  499. package/schematics/migrations/static-queries/index.d.ts +0 -11
  500. package/schematics/migrations/static-queries/index.js +0 -230
  501. package/schematics/migrations/static-queries/strategies/template_strategy/template_strategy.d.ts +0 -41
  502. package/schematics/migrations/static-queries/strategies/template_strategy/template_strategy.js +0 -214
  503. package/schematics/migrations/static-queries/strategies/test_strategy/test_strategy.d.ts +0 -24
  504. package/schematics/migrations/static-queries/strategies/test_strategy/test_strategy.js +0 -38
  505. package/schematics/migrations/static-queries/strategies/timing-strategy.d.ts +0 -19
  506. package/schematics/migrations/static-queries/strategies/timing-strategy.js +0 -20
  507. package/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.d.ts +0 -82
  508. package/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.js +0 -369
  509. package/schematics/migrations/static-queries/strategies/usage_strategy/super_class_context.d.ts +0 -18
  510. package/schematics/migrations/static-queries/strategies/usage_strategy/super_class_context.js +0 -52
  511. package/schematics/migrations/static-queries/strategies/usage_strategy/template_usage_visitor.d.ts +0 -27
  512. package/schematics/migrations/static-queries/strategies/usage_strategy/template_usage_visitor.js +0 -93
  513. package/schematics/migrations/static-queries/strategies/usage_strategy/usage_strategy.d.ts +0 -34
  514. package/schematics/migrations/static-queries/strategies/usage_strategy/usage_strategy.js +0 -169
  515. package/schematics/migrations/static-queries/transform.d.ts +0 -21
  516. package/schematics/migrations/static-queries/transform.js +0 -102
  517. package/schematics/migrations/template-var-assignment/analyze_template.d.ts +0 -20
  518. package/schematics/migrations/template-var-assignment/analyze_template.js +0 -38
  519. package/schematics/migrations/template-var-assignment/angular/html_variable_assignment_visitor.d.ts +0 -28
  520. package/schematics/migrations/template-var-assignment/angular/html_variable_assignment_visitor.js +0 -80
  521. package/schematics/migrations/template-var-assignment/index.d.ts +0 -11
  522. package/schematics/migrations/template-var-assignment/index.js +0 -101
  523. package/schematics/migrations/undecorated-classes-with-decorated-fields/index.d.ts +0 -14
  524. package/schematics/migrations/undecorated-classes-with-decorated-fields/index.js +0 -114
  525. package/schematics/migrations/undecorated-classes-with-decorated-fields/transform.d.ts +0 -63
  526. package/schematics/migrations/undecorated-classes-with-decorated-fields/transform.js +0 -300
  527. package/schematics/migrations/undecorated-classes-with-decorated-fields/update_recorder.d.ts +0 -19
  528. package/schematics/migrations/undecorated-classes-with-decorated-fields/update_recorder.js +0 -20
  529. package/schematics/migrations/undecorated-classes-with-di/create_ngc_program.d.ts +0 -18
  530. package/schematics/migrations/undecorated-classes-with-di/create_ngc_program.js +0 -57
  531. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/convert_directive_metadata.d.ts +0 -18
  532. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/convert_directive_metadata.js +0 -96
  533. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/decorator_rewriter.d.ts +0 -39
  534. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/decorator_rewriter.js +0 -116
  535. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/import_rewrite_visitor.d.ts +0 -37
  536. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/import_rewrite_visitor.js +0 -126
  537. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/path_format.d.ts +0 -10
  538. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/path_format.js +0 -31
  539. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/source_file_exports.d.ts +0 -16
  540. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/source_file_exports.js +0 -65
  541. package/schematics/migrations/undecorated-classes-with-di/index.d.ts +0 -11
  542. package/schematics/migrations/undecorated-classes-with-di/index.js +0 -195
  543. package/schematics/migrations/undecorated-classes-with-di/ng_declaration_collector.d.ts +0 -38
  544. package/schematics/migrations/undecorated-classes-with-di/ng_declaration_collector.js +0 -142
  545. package/schematics/migrations/undecorated-classes-with-di/transform.d.ts +0 -98
  546. package/schematics/migrations/undecorated-classes-with-di/transform.js +0 -371
  547. package/schematics/migrations/undecorated-classes-with-di/update_recorder.d.ts +0 -20
  548. package/schematics/migrations/undecorated-classes-with-di/update_recorder.js +0 -20
  549. package/schematics/migrations/wait-for-async/index.d.ts +0 -11
  550. package/schematics/migrations/wait-for-async/index.js +0 -98
  551. package/schematics/migrations/wait-for-async/util.d.ts +0 -11
  552. package/schematics/migrations/wait-for-async/util.js +0 -37
  553. package/schematics/migrations/xhr-factory/index.d.ts +0 -10
  554. package/schematics/migrations/xhr-factory/index.js +0 -104
  555. package/src/r3_symbols.d.ts +0 -1025
  556. package/testing/testing.metadata.json +0 -1
  557. package/testing.d.ts +0 -7
  558. package/testing.metadata.json +0 -1
@@ -0,0 +1,1811 @@
1
+ import { ErrorHandler } from '../../error_handler';
2
+ import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '../../metadata/schema';
3
+ import { ViewEncapsulation } from '../../metadata/view';
4
+ import { validateAgainstEventAttributes, validateAgainstEventProperties } from '../../sanitization/sanitization';
5
+ import { assertDefined, assertDomNode, assertEqual, assertGreaterThanOrEqual, assertIndexInRange, assertNotEqual, assertNotSame, assertSame, assertString } from '../../util/assert';
6
+ import { escapeCommentText } from '../../util/dom';
7
+ import { createNamedArrayType } from '../../util/named_array_type';
8
+ import { initNgDevMode } from '../../util/ng_dev_mode';
9
+ import { normalizeDebugBindingName, normalizeDebugBindingValue } from '../../util/ng_reflect';
10
+ import { stringify } from '../../util/stringify';
11
+ import { assertFirstCreatePass, assertFirstUpdatePass, assertLContainer, assertLView, assertTNodeForLView, assertTNodeForTView } from '../assert';
12
+ import { attachPatchData, readPatchedLView } from '../context_discovery';
13
+ import { getFactoryDef } from '../definition_factory';
14
+ import { diPublicInInjector, getNodeInjectable, getOrCreateNodeInjectorForNode } from '../di';
15
+ import { formatRuntimeError, RuntimeError } from '../error_code';
16
+ import { throwMultipleComponentError } from '../errors';
17
+ import { executeCheckHooks, executeInitAndCheckHooks, incrementInitPhaseFlags } from '../hooks';
18
+ import { CONTAINER_HEADER_OFFSET, HAS_TRANSPLANTED_VIEWS, MOVED_VIEWS } from '../interfaces/container';
19
+ import { NodeInjectorFactory } from '../interfaces/injector';
20
+ import { isProceduralRenderer } from '../interfaces/renderer';
21
+ import { isComponentDef, isComponentHost, isContentQueryHost, isRootView } from '../interfaces/type_checks';
22
+ import { CHILD_HEAD, CHILD_TAIL, CLEANUP, CONTEXT, DECLARATION_COMPONENT_VIEW, DECLARATION_VIEW, FLAGS, HEADER_OFFSET, HOST, INJECTOR, NEXT, PARENT, RENDERER, RENDERER_FACTORY, SANITIZER, T_HOST, TRANSPLANTED_VIEWS_TO_REFRESH, TVIEW } from '../interfaces/view';
23
+ import { assertPureTNodeType, assertTNodeType } from '../node_assert';
24
+ import { updateTextNode } from '../node_manipulation';
25
+ import { isInlineTemplate, isNodeMatchingSelectorList } from '../node_selector_matcher';
26
+ import { profiler } from '../profiler';
27
+ import { enterView, getBindingsEnabled, getCurrentDirectiveIndex, getCurrentParentTNode, getCurrentTNode, getCurrentTNodePlaceholderOk, getSelectedIndex, isCurrentTNodeParent, isInCheckNoChangesMode, isInI18nBlock, leaveView, setBindingIndex, setBindingRootForHostBindings, setCurrentDirectiveIndex, setCurrentQueryIndex, setCurrentTNode, setIsInCheckNoChangesMode, setSelectedIndex } from '../state';
28
+ import { NO_CHANGE } from '../tokens';
29
+ import { isAnimationProp, mergeHostAttrs } from '../util/attrs_utils';
30
+ import { INTERPOLATION_DELIMITER } from '../util/misc_utils';
31
+ import { renderStringify, stringifyForError } from '../util/stringify_utils';
32
+ import { getFirstLContainer, getLViewParent, getNextLContainer } from '../util/view_traversal_utils';
33
+ import { getComponentLViewByIndex, getNativeByIndex, getNativeByTNode, isCreationMode, resetPreOrderHookFlags, unwrapLView, updateTransplantedViewCount, viewAttachedToChangeDetector } from '../util/view_utils';
34
+ import { selectIndexInternal } from './advance';
35
+ import { attachLContainerDebug, attachLViewDebug, cloneToLViewFromTViewBlueprint, cloneToTViewData, LCleanup, LViewBlueprint, MatchesArray, TCleanup, TNodeDebug, TNodeInitialInputs, TNodeLocalNames, TViewComponents, TViewConstructor } from './lview_debug';
36
+ /**
37
+ * A permanent marker promise which signifies that the current CD tree is
38
+ * clean.
39
+ */
40
+ const _CLEAN_PROMISE = (() => Promise.resolve(null))();
41
+ /**
42
+ * Invoke `HostBindingsFunction`s for view.
43
+ *
44
+ * This methods executes `TView.hostBindingOpCodes`. It is used to execute the
45
+ * `HostBindingsFunction`s associated with the current `LView`.
46
+ *
47
+ * @param tView Current `TView`.
48
+ * @param lView Current `LView`.
49
+ */
50
+ export function processHostBindingOpCodes(tView, lView) {
51
+ const hostBindingOpCodes = tView.hostBindingOpCodes;
52
+ if (hostBindingOpCodes === null)
53
+ return;
54
+ try {
55
+ for (let i = 0; i < hostBindingOpCodes.length; i++) {
56
+ const opCode = hostBindingOpCodes[i];
57
+ if (opCode < 0) {
58
+ // Negative numbers are element indexes.
59
+ setSelectedIndex(~opCode);
60
+ }
61
+ else {
62
+ // Positive numbers are NumberTuple which store bindingRootIndex and directiveIndex.
63
+ const directiveIdx = opCode;
64
+ const bindingRootIndx = hostBindingOpCodes[++i];
65
+ const hostBindingFn = hostBindingOpCodes[++i];
66
+ setBindingRootForHostBindings(bindingRootIndx, directiveIdx);
67
+ const context = lView[directiveIdx];
68
+ hostBindingFn(2 /* Update */, context);
69
+ }
70
+ }
71
+ }
72
+ finally {
73
+ setSelectedIndex(-1);
74
+ }
75
+ }
76
+ /** Refreshes all content queries declared by directives in a given view */
77
+ function refreshContentQueries(tView, lView) {
78
+ const contentQueries = tView.contentQueries;
79
+ if (contentQueries !== null) {
80
+ for (let i = 0; i < contentQueries.length; i += 2) {
81
+ const queryStartIdx = contentQueries[i];
82
+ const directiveDefIdx = contentQueries[i + 1];
83
+ if (directiveDefIdx !== -1) {
84
+ const directiveDef = tView.data[directiveDefIdx];
85
+ ngDevMode && assertDefined(directiveDef, 'DirectiveDef not found.');
86
+ ngDevMode &&
87
+ assertDefined(directiveDef.contentQueries, 'contentQueries function should be defined');
88
+ setCurrentQueryIndex(queryStartIdx);
89
+ directiveDef.contentQueries(2 /* Update */, lView[directiveDefIdx], directiveDefIdx);
90
+ }
91
+ }
92
+ }
93
+ }
94
+ /** Refreshes child components in the current view (update mode). */
95
+ function refreshChildComponents(hostLView, components) {
96
+ for (let i = 0; i < components.length; i++) {
97
+ refreshComponent(hostLView, components[i]);
98
+ }
99
+ }
100
+ /** Renders child components in the current view (creation mode). */
101
+ function renderChildComponents(hostLView, components) {
102
+ for (let i = 0; i < components.length; i++) {
103
+ renderComponent(hostLView, components[i]);
104
+ }
105
+ }
106
+ export function createLView(parentLView, tView, context, flags, host, tHostNode, rendererFactory, renderer, sanitizer, injector) {
107
+ const lView = ngDevMode ? cloneToLViewFromTViewBlueprint(tView) : tView.blueprint.slice();
108
+ lView[HOST] = host;
109
+ lView[FLAGS] = flags | 4 /* CreationMode */ | 128 /* Attached */ | 8 /* FirstLViewPass */;
110
+ resetPreOrderHookFlags(lView);
111
+ ngDevMode && tView.declTNode && parentLView && assertTNodeForLView(tView.declTNode, parentLView);
112
+ lView[PARENT] = lView[DECLARATION_VIEW] = parentLView;
113
+ lView[CONTEXT] = context;
114
+ lView[RENDERER_FACTORY] = (rendererFactory || parentLView && parentLView[RENDERER_FACTORY]);
115
+ ngDevMode && assertDefined(lView[RENDERER_FACTORY], 'RendererFactory is required');
116
+ lView[RENDERER] = (renderer || parentLView && parentLView[RENDERER]);
117
+ ngDevMode && assertDefined(lView[RENDERER], 'Renderer is required');
118
+ lView[SANITIZER] = sanitizer || parentLView && parentLView[SANITIZER] || null;
119
+ lView[INJECTOR] = injector || parentLView && parentLView[INJECTOR] || null;
120
+ lView[T_HOST] = tHostNode;
121
+ ngDevMode &&
122
+ assertEqual(tView.type == 2 /* Embedded */ ? parentLView !== null : true, true, 'Embedded views must have parentLView');
123
+ lView[DECLARATION_COMPONENT_VIEW] =
124
+ tView.type == 2 /* Embedded */ ? parentLView[DECLARATION_COMPONENT_VIEW] : lView;
125
+ ngDevMode && attachLViewDebug(lView);
126
+ return lView;
127
+ }
128
+ export function getOrCreateTNode(tView, index, type, name, attrs) {
129
+ ngDevMode && index !== 0 && // 0 are bogus nodes and they are OK. See `createContainerRef` in
130
+ // `view_engine_compatibility` for additional context.
131
+ assertGreaterThanOrEqual(index, HEADER_OFFSET, 'TNodes can\'t be in the LView header.');
132
+ // Keep this function short, so that the VM will inline it.
133
+ ngDevMode && assertPureTNodeType(type);
134
+ let tNode = tView.data[index];
135
+ if (tNode === null) {
136
+ tNode = createTNodeAtIndex(tView, index, type, name, attrs);
137
+ if (isInI18nBlock()) {
138
+ // If we are in i18n block then all elements should be pre declared through `Placeholder`
139
+ // See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
140
+ // If the `TNode` was not pre-declared than it means it was not mentioned which means it was
141
+ // removed, so we mark it as detached.
142
+ tNode.flags |= 64 /* isDetached */;
143
+ }
144
+ }
145
+ else if (tNode.type & 64 /* Placeholder */) {
146
+ tNode.type = type;
147
+ tNode.value = name;
148
+ tNode.attrs = attrs;
149
+ const parent = getCurrentParentTNode();
150
+ tNode.injectorIndex = parent === null ? -1 : parent.injectorIndex;
151
+ ngDevMode && assertTNodeForTView(tNode, tView);
152
+ ngDevMode && assertEqual(index, tNode.index, 'Expecting same index');
153
+ }
154
+ setCurrentTNode(tNode, true);
155
+ return tNode;
156
+ }
157
+ export function createTNodeAtIndex(tView, index, type, name, attrs) {
158
+ const currentTNode = getCurrentTNodePlaceholderOk();
159
+ const isParent = isCurrentTNodeParent();
160
+ const parent = isParent ? currentTNode : currentTNode && currentTNode.parent;
161
+ // Parents cannot cross component boundaries because components will be used in multiple places.
162
+ const tNode = tView.data[index] =
163
+ createTNode(tView, parent, type, index, name, attrs);
164
+ // Assign a pointer to the first child node of a given view. The first node is not always the one
165
+ // at index 0, in case of i18n, index 0 can be the instruction `i18nStart` and the first node has
166
+ // the index 1 or more, so we can't just check node index.
167
+ if (tView.firstChild === null) {
168
+ tView.firstChild = tNode;
169
+ }
170
+ if (currentTNode !== null) {
171
+ if (isParent) {
172
+ // FIXME(misko): This logic looks unnecessarily complicated. Could we simplify?
173
+ if (currentTNode.child == null && tNode.parent !== null) {
174
+ // We are in the same view, which means we are adding content node to the parent view.
175
+ currentTNode.child = tNode;
176
+ }
177
+ }
178
+ else {
179
+ if (currentTNode.next === null) {
180
+ // In the case of i18n the `currentTNode` may already be linked, in which case we don't want
181
+ // to break the links which i18n created.
182
+ currentTNode.next = tNode;
183
+ }
184
+ }
185
+ }
186
+ return tNode;
187
+ }
188
+ /**
189
+ * When elements are created dynamically after a view blueprint is created (e.g. through
190
+ * i18nApply()), we need to adjust the blueprint for future
191
+ * template passes.
192
+ *
193
+ * @param tView `TView` associated with `LView`
194
+ * @param lView The `LView` containing the blueprint to adjust
195
+ * @param numSlotsToAlloc The number of slots to alloc in the LView, should be >0
196
+ * @param initialValue Initial value to store in blueprint
197
+ */
198
+ export function allocExpando(tView, lView, numSlotsToAlloc, initialValue) {
199
+ if (numSlotsToAlloc === 0)
200
+ return -1;
201
+ if (ngDevMode) {
202
+ assertFirstCreatePass(tView);
203
+ assertSame(tView, lView[TVIEW], '`LView` must be associated with `TView`!');
204
+ assertEqual(tView.data.length, lView.length, 'Expecting LView to be same size as TView');
205
+ assertEqual(tView.data.length, tView.blueprint.length, 'Expecting Blueprint to be same size as TView');
206
+ assertFirstUpdatePass(tView);
207
+ }
208
+ const allocIdx = lView.length;
209
+ for (let i = 0; i < numSlotsToAlloc; i++) {
210
+ lView.push(initialValue);
211
+ tView.blueprint.push(initialValue);
212
+ tView.data.push(null);
213
+ }
214
+ return allocIdx;
215
+ }
216
+ //////////////////////////
217
+ //// Render
218
+ //////////////////////////
219
+ /**
220
+ * Processes a view in the creation mode. This includes a number of steps in a specific order:
221
+ * - creating view query functions (if any);
222
+ * - executing a template function in the creation mode;
223
+ * - updating static queries (if any);
224
+ * - creating child components defined in a given view.
225
+ */
226
+ export function renderView(tView, lView, context) {
227
+ ngDevMode && assertEqual(isCreationMode(lView), true, 'Should be run in creation mode');
228
+ enterView(lView);
229
+ try {
230
+ const viewQuery = tView.viewQuery;
231
+ if (viewQuery !== null) {
232
+ executeViewQueryFn(1 /* Create */, viewQuery, context);
233
+ }
234
+ // Execute a template associated with this view, if it exists. A template function might not be
235
+ // defined for the root component views.
236
+ const templateFn = tView.template;
237
+ if (templateFn !== null) {
238
+ executeTemplate(tView, lView, templateFn, 1 /* Create */, context);
239
+ }
240
+ // This needs to be set before children are processed to support recursive components.
241
+ // This must be set to false immediately after the first creation run because in an
242
+ // ngFor loop, all the views will be created together before update mode runs and turns
243
+ // off firstCreatePass. If we don't set it here, instances will perform directive
244
+ // matching, etc again and again.
245
+ if (tView.firstCreatePass) {
246
+ tView.firstCreatePass = false;
247
+ }
248
+ // We resolve content queries specifically marked as `static` in creation mode. Dynamic
249
+ // content queries are resolved during change detection (i.e. update mode), after embedded
250
+ // views are refreshed (see block above).
251
+ if (tView.staticContentQueries) {
252
+ refreshContentQueries(tView, lView);
253
+ }
254
+ // We must materialize query results before child components are processed
255
+ // in case a child component has projected a container. The LContainer needs
256
+ // to exist so the embedded views are properly attached by the container.
257
+ if (tView.staticViewQueries) {
258
+ executeViewQueryFn(2 /* Update */, tView.viewQuery, context);
259
+ }
260
+ // Render child component views.
261
+ const components = tView.components;
262
+ if (components !== null) {
263
+ renderChildComponents(lView, components);
264
+ }
265
+ }
266
+ catch (error) {
267
+ // If we didn't manage to get past the first template pass due to
268
+ // an error, mark the view as corrupted so we can try to recover.
269
+ if (tView.firstCreatePass) {
270
+ tView.incompleteFirstPass = true;
271
+ tView.firstCreatePass = false;
272
+ }
273
+ throw error;
274
+ }
275
+ finally {
276
+ lView[FLAGS] &= ~4 /* CreationMode */;
277
+ leaveView();
278
+ }
279
+ }
280
+ /**
281
+ * Processes a view in update mode. This includes a number of steps in a specific order:
282
+ * - executing a template function in update mode;
283
+ * - executing hooks;
284
+ * - refreshing queries;
285
+ * - setting host bindings;
286
+ * - refreshing child (embedded and component) views.
287
+ */
288
+ export function refreshView(tView, lView, templateFn, context) {
289
+ ngDevMode && assertEqual(isCreationMode(lView), false, 'Should be run in update mode');
290
+ const flags = lView[FLAGS];
291
+ if ((flags & 256 /* Destroyed */) === 256 /* Destroyed */)
292
+ return;
293
+ enterView(lView);
294
+ // Check no changes mode is a dev only mode used to verify that bindings have not changed
295
+ // since they were assigned. We do not want to execute lifecycle hooks in that mode.
296
+ const isInCheckNoChangesPass = isInCheckNoChangesMode();
297
+ try {
298
+ resetPreOrderHookFlags(lView);
299
+ setBindingIndex(tView.bindingStartIndex);
300
+ if (templateFn !== null) {
301
+ executeTemplate(tView, lView, templateFn, 2 /* Update */, context);
302
+ }
303
+ const hooksInitPhaseCompleted = (flags & 3 /* InitPhaseStateMask */) === 3 /* InitPhaseCompleted */;
304
+ // execute pre-order hooks (OnInit, OnChanges, DoCheck)
305
+ // PERF WARNING: do NOT extract this to a separate function without running benchmarks
306
+ if (!isInCheckNoChangesPass) {
307
+ if (hooksInitPhaseCompleted) {
308
+ const preOrderCheckHooks = tView.preOrderCheckHooks;
309
+ if (preOrderCheckHooks !== null) {
310
+ executeCheckHooks(lView, preOrderCheckHooks, null);
311
+ }
312
+ }
313
+ else {
314
+ const preOrderHooks = tView.preOrderHooks;
315
+ if (preOrderHooks !== null) {
316
+ executeInitAndCheckHooks(lView, preOrderHooks, 0 /* OnInitHooksToBeRun */, null);
317
+ }
318
+ incrementInitPhaseFlags(lView, 0 /* OnInitHooksToBeRun */);
319
+ }
320
+ }
321
+ // First mark transplanted views that are declared in this lView as needing a refresh at their
322
+ // insertion points. This is needed to avoid the situation where the template is defined in this
323
+ // `LView` but its declaration appears after the insertion component.
324
+ markTransplantedViewsForRefresh(lView);
325
+ refreshEmbeddedViews(lView);
326
+ // Content query results must be refreshed before content hooks are called.
327
+ if (tView.contentQueries !== null) {
328
+ refreshContentQueries(tView, lView);
329
+ }
330
+ // execute content hooks (AfterContentInit, AfterContentChecked)
331
+ // PERF WARNING: do NOT extract this to a separate function without running benchmarks
332
+ if (!isInCheckNoChangesPass) {
333
+ if (hooksInitPhaseCompleted) {
334
+ const contentCheckHooks = tView.contentCheckHooks;
335
+ if (contentCheckHooks !== null) {
336
+ executeCheckHooks(lView, contentCheckHooks);
337
+ }
338
+ }
339
+ else {
340
+ const contentHooks = tView.contentHooks;
341
+ if (contentHooks !== null) {
342
+ executeInitAndCheckHooks(lView, contentHooks, 1 /* AfterContentInitHooksToBeRun */);
343
+ }
344
+ incrementInitPhaseFlags(lView, 1 /* AfterContentInitHooksToBeRun */);
345
+ }
346
+ }
347
+ processHostBindingOpCodes(tView, lView);
348
+ // Refresh child component views.
349
+ const components = tView.components;
350
+ if (components !== null) {
351
+ refreshChildComponents(lView, components);
352
+ }
353
+ // View queries must execute after refreshing child components because a template in this view
354
+ // could be inserted in a child component. If the view query executes before child component
355
+ // refresh, the template might not yet be inserted.
356
+ const viewQuery = tView.viewQuery;
357
+ if (viewQuery !== null) {
358
+ executeViewQueryFn(2 /* Update */, viewQuery, context);
359
+ }
360
+ // execute view hooks (AfterViewInit, AfterViewChecked)
361
+ // PERF WARNING: do NOT extract this to a separate function without running benchmarks
362
+ if (!isInCheckNoChangesPass) {
363
+ if (hooksInitPhaseCompleted) {
364
+ const viewCheckHooks = tView.viewCheckHooks;
365
+ if (viewCheckHooks !== null) {
366
+ executeCheckHooks(lView, viewCheckHooks);
367
+ }
368
+ }
369
+ else {
370
+ const viewHooks = tView.viewHooks;
371
+ if (viewHooks !== null) {
372
+ executeInitAndCheckHooks(lView, viewHooks, 2 /* AfterViewInitHooksToBeRun */);
373
+ }
374
+ incrementInitPhaseFlags(lView, 2 /* AfterViewInitHooksToBeRun */);
375
+ }
376
+ }
377
+ if (tView.firstUpdatePass === true) {
378
+ // We need to make sure that we only flip the flag on successful `refreshView` only
379
+ // Don't do this in `finally` block.
380
+ // If we did this in `finally` block then an exception could block the execution of styling
381
+ // instructions which in turn would be unable to insert themselves into the styling linked
382
+ // list. The result of this would be that if the exception would not be throw on subsequent CD
383
+ // the styling would be unable to process it data and reflect to the DOM.
384
+ tView.firstUpdatePass = false;
385
+ }
386
+ // Do not reset the dirty state when running in check no changes mode. We don't want components
387
+ // to behave differently depending on whether check no changes is enabled or not. For example:
388
+ // Marking an OnPush component as dirty from within the `ngAfterViewInit` hook in order to
389
+ // refresh a `NgClass` binding should work. If we would reset the dirty state in the check
390
+ // no changes cycle, the component would be not be dirty for the next update pass. This would
391
+ // be different in production mode where the component dirty state is not reset.
392
+ if (!isInCheckNoChangesPass) {
393
+ lView[FLAGS] &= ~(64 /* Dirty */ | 8 /* FirstLViewPass */);
394
+ }
395
+ if (lView[FLAGS] & 1024 /* RefreshTransplantedView */) {
396
+ lView[FLAGS] &= ~1024 /* RefreshTransplantedView */;
397
+ updateTransplantedViewCount(lView[PARENT], -1);
398
+ }
399
+ }
400
+ finally {
401
+ leaveView();
402
+ }
403
+ }
404
+ export function renderComponentOrTemplate(tView, lView, templateFn, context) {
405
+ const rendererFactory = lView[RENDERER_FACTORY];
406
+ const normalExecutionPath = !isInCheckNoChangesMode();
407
+ const creationModeIsActive = isCreationMode(lView);
408
+ try {
409
+ if (normalExecutionPath && !creationModeIsActive && rendererFactory.begin) {
410
+ rendererFactory.begin();
411
+ }
412
+ if (creationModeIsActive) {
413
+ renderView(tView, lView, context);
414
+ }
415
+ refreshView(tView, lView, templateFn, context);
416
+ }
417
+ finally {
418
+ if (normalExecutionPath && !creationModeIsActive && rendererFactory.end) {
419
+ rendererFactory.end();
420
+ }
421
+ }
422
+ }
423
+ function executeTemplate(tView, lView, templateFn, rf, context) {
424
+ const prevSelectedIndex = getSelectedIndex();
425
+ const isUpdatePhase = rf & 2 /* Update */;
426
+ try {
427
+ setSelectedIndex(-1);
428
+ if (isUpdatePhase && lView.length > HEADER_OFFSET) {
429
+ // When we're updating, inherently select 0 so we don't
430
+ // have to generate that instruction for most update blocks.
431
+ selectIndexInternal(tView, lView, HEADER_OFFSET, isInCheckNoChangesMode());
432
+ }
433
+ const preHookType = isUpdatePhase ? 2 /* TemplateUpdateStart */ : 0 /* TemplateCreateStart */;
434
+ profiler(preHookType, context);
435
+ templateFn(rf, context);
436
+ }
437
+ finally {
438
+ setSelectedIndex(prevSelectedIndex);
439
+ const postHookType = isUpdatePhase ? 3 /* TemplateUpdateEnd */ : 1 /* TemplateCreateEnd */;
440
+ profiler(postHookType, context);
441
+ }
442
+ }
443
+ //////////////////////////
444
+ //// Element
445
+ //////////////////////////
446
+ export function executeContentQueries(tView, tNode, lView) {
447
+ if (isContentQueryHost(tNode)) {
448
+ const start = tNode.directiveStart;
449
+ const end = tNode.directiveEnd;
450
+ for (let directiveIndex = start; directiveIndex < end; directiveIndex++) {
451
+ const def = tView.data[directiveIndex];
452
+ if (def.contentQueries) {
453
+ def.contentQueries(1 /* Create */, lView[directiveIndex], directiveIndex);
454
+ }
455
+ }
456
+ }
457
+ }
458
+ /**
459
+ * Creates directive instances.
460
+ */
461
+ export function createDirectivesInstances(tView, lView, tNode) {
462
+ if (!getBindingsEnabled())
463
+ return;
464
+ instantiateAllDirectives(tView, lView, tNode, getNativeByTNode(tNode, lView));
465
+ if ((tNode.flags & 128 /* hasHostBindings */) === 128 /* hasHostBindings */) {
466
+ invokeDirectivesHostBindings(tView, lView, tNode);
467
+ }
468
+ }
469
+ /**
470
+ * Takes a list of local names and indices and pushes the resolved local variable values
471
+ * to LView in the same order as they are loaded in the template with load().
472
+ */
473
+ export function saveResolvedLocalsInData(viewData, tNode, localRefExtractor = getNativeByTNode) {
474
+ const localNames = tNode.localNames;
475
+ if (localNames !== null) {
476
+ let localIndex = tNode.index + 1;
477
+ for (let i = 0; i < localNames.length; i += 2) {
478
+ const index = localNames[i + 1];
479
+ const value = index === -1 ?
480
+ localRefExtractor(tNode, viewData) :
481
+ viewData[index];
482
+ viewData[localIndex++] = value;
483
+ }
484
+ }
485
+ }
486
+ /**
487
+ * Gets TView from a template function or creates a new TView
488
+ * if it doesn't already exist.
489
+ *
490
+ * @param def ComponentDef
491
+ * @returns TView
492
+ */
493
+ export function getOrCreateTComponentView(def) {
494
+ const tView = def.tView;
495
+ // Create a TView if there isn't one, or recreate it if the first create pass didn't
496
+ // complete successfully since we can't know for sure whether it's in a usable shape.
497
+ if (tView === null || tView.incompleteFirstPass) {
498
+ // Declaration node here is null since this function is called when we dynamically create a
499
+ // component and hence there is no declaration.
500
+ const declTNode = null;
501
+ return def.tView = createTView(1 /* Component */, declTNode, def.template, def.decls, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery, def.schemas, def.consts);
502
+ }
503
+ return tView;
504
+ }
505
+ /**
506
+ * Creates a TView instance
507
+ *
508
+ * @param type Type of `TView`.
509
+ * @param declTNode Declaration location of this `TView`.
510
+ * @param templateFn Template function
511
+ * @param decls The number of nodes, local refs, and pipes in this template
512
+ * @param directives Registry of directives for this view
513
+ * @param pipes Registry of pipes for this view
514
+ * @param viewQuery View queries for this view
515
+ * @param schemas Schemas for this view
516
+ * @param consts Constants for this view
517
+ */
518
+ export function createTView(type, declTNode, templateFn, decls, vars, directives, pipes, viewQuery, schemas, constsOrFactory) {
519
+ ngDevMode && ngDevMode.tView++;
520
+ const bindingStartIndex = HEADER_OFFSET + decls;
521
+ // This length does not yet contain host bindings from child directives because at this point,
522
+ // we don't know which directives are active on this template. As soon as a directive is matched
523
+ // that has a host binding, we will update the blueprint with that def's hostVars count.
524
+ const initialViewLength = bindingStartIndex + vars;
525
+ const blueprint = createViewBlueprint(bindingStartIndex, initialViewLength);
526
+ const consts = typeof constsOrFactory === 'function' ? constsOrFactory() : constsOrFactory;
527
+ const tView = blueprint[TVIEW] = ngDevMode ?
528
+ new TViewConstructor(type, // type: TViewType,
529
+ blueprint, // blueprint: LView,
530
+ templateFn, // template: ComponentTemplate<{}>|null,
531
+ null, // queries: TQueries|null
532
+ viewQuery, // viewQuery: ViewQueriesFunction<{}>|null,
533
+ declTNode, // declTNode: TNode|null,
534
+ cloneToTViewData(blueprint).fill(null, bindingStartIndex), // data: TData,
535
+ bindingStartIndex, // bindingStartIndex: number,
536
+ initialViewLength, // expandoStartIndex: number,
537
+ null, // hostBindingOpCodes: HostBindingOpCodes,
538
+ true, // firstCreatePass: boolean,
539
+ true, // firstUpdatePass: boolean,
540
+ false, // staticViewQueries: boolean,
541
+ false, // staticContentQueries: boolean,
542
+ null, // preOrderHooks: HookData|null,
543
+ null, // preOrderCheckHooks: HookData|null,
544
+ null, // contentHooks: HookData|null,
545
+ null, // contentCheckHooks: HookData|null,
546
+ null, // viewHooks: HookData|null,
547
+ null, // viewCheckHooks: HookData|null,
548
+ null, // destroyHooks: DestroyHookData|null,
549
+ null, // cleanup: any[]|null,
550
+ null, // contentQueries: number[]|null,
551
+ null, // components: number[]|null,
552
+ typeof directives === 'function' ? //
553
+ directives() : //
554
+ directives, // directiveRegistry: DirectiveDefList|null,
555
+ typeof pipes === 'function' ? pipes() : pipes, // pipeRegistry: PipeDefList|null,
556
+ null, // firstChild: TNode|null,
557
+ schemas, // schemas: SchemaMetadata[]|null,
558
+ consts, // consts: TConstants|null
559
+ false, // incompleteFirstPass: boolean
560
+ decls, // ngDevMode only: decls
561
+ vars) :
562
+ {
563
+ type: type,
564
+ blueprint: blueprint,
565
+ template: templateFn,
566
+ queries: null,
567
+ viewQuery: viewQuery,
568
+ declTNode: declTNode,
569
+ data: blueprint.slice().fill(null, bindingStartIndex),
570
+ bindingStartIndex: bindingStartIndex,
571
+ expandoStartIndex: initialViewLength,
572
+ hostBindingOpCodes: null,
573
+ firstCreatePass: true,
574
+ firstUpdatePass: true,
575
+ staticViewQueries: false,
576
+ staticContentQueries: false,
577
+ preOrderHooks: null,
578
+ preOrderCheckHooks: null,
579
+ contentHooks: null,
580
+ contentCheckHooks: null,
581
+ viewHooks: null,
582
+ viewCheckHooks: null,
583
+ destroyHooks: null,
584
+ cleanup: null,
585
+ contentQueries: null,
586
+ components: null,
587
+ directiveRegistry: typeof directives === 'function' ? directives() : directives,
588
+ pipeRegistry: typeof pipes === 'function' ? pipes() : pipes,
589
+ firstChild: null,
590
+ schemas: schemas,
591
+ consts: consts,
592
+ incompleteFirstPass: false
593
+ };
594
+ if (ngDevMode) {
595
+ // For performance reasons it is important that the tView retains the same shape during runtime.
596
+ // (To make sure that all of the code is monomorphic.) For this reason we seal the object to
597
+ // prevent class transitions.
598
+ Object.seal(tView);
599
+ }
600
+ return tView;
601
+ }
602
+ function createViewBlueprint(bindingStartIndex, initialViewLength) {
603
+ const blueprint = ngDevMode ? new LViewBlueprint() : [];
604
+ for (let i = 0; i < initialViewLength; i++) {
605
+ blueprint.push(i < bindingStartIndex ? null : NO_CHANGE);
606
+ }
607
+ return blueprint;
608
+ }
609
+ function createError(text, token) {
610
+ return new Error(`Renderer: ${text} [${stringifyForError(token)}]`);
611
+ }
612
+ function assertHostNodeExists(rElement, elementOrSelector) {
613
+ if (!rElement) {
614
+ if (typeof elementOrSelector === 'string') {
615
+ throw createError('Host node with selector not found:', elementOrSelector);
616
+ }
617
+ else {
618
+ throw createError('Host node is required:', elementOrSelector);
619
+ }
620
+ }
621
+ }
622
+ /**
623
+ * Locates the host native element, used for bootstrapping existing nodes into rendering pipeline.
624
+ *
625
+ * @param rendererFactory Factory function to create renderer instance.
626
+ * @param elementOrSelector Render element or CSS selector to locate the element.
627
+ * @param encapsulation View Encapsulation defined for component that requests host element.
628
+ */
629
+ export function locateHostElement(renderer, elementOrSelector, encapsulation) {
630
+ if (isProceduralRenderer(renderer)) {
631
+ // When using native Shadow DOM, do not clear host element to allow native slot projection
632
+ const preserveContent = encapsulation === ViewEncapsulation.ShadowDom;
633
+ return renderer.selectRootElement(elementOrSelector, preserveContent);
634
+ }
635
+ let rElement = typeof elementOrSelector === 'string' ?
636
+ renderer.querySelector(elementOrSelector) :
637
+ elementOrSelector;
638
+ ngDevMode && assertHostNodeExists(rElement, elementOrSelector);
639
+ // Always clear host element's content when Renderer3 is in use. For procedural renderer case we
640
+ // make it depend on whether ShadowDom encapsulation is used (in which case the content should be
641
+ // preserved to allow native slot projection). ShadowDom encapsulation requires procedural
642
+ // renderer, and procedural renderer case is handled above.
643
+ rElement.textContent = '';
644
+ return rElement;
645
+ }
646
+ /**
647
+ * Saves context for this cleanup function in LView.cleanupInstances.
648
+ *
649
+ * On the first template pass, saves in TView:
650
+ * - Cleanup function
651
+ * - Index of context we just saved in LView.cleanupInstances
652
+ *
653
+ * This function can also be used to store instance specific cleanup fns. In that case the `context`
654
+ * is `null` and the function is store in `LView` (rather than it `TView`).
655
+ */
656
+ export function storeCleanupWithContext(tView, lView, context, cleanupFn) {
657
+ const lCleanup = getOrCreateLViewCleanup(lView);
658
+ if (context === null) {
659
+ // If context is null that this is instance specific callback. These callbacks can only be
660
+ // inserted after template shared instances. For this reason in ngDevMode we freeze the TView.
661
+ if (ngDevMode) {
662
+ Object.freeze(getOrCreateTViewCleanup(tView));
663
+ }
664
+ lCleanup.push(cleanupFn);
665
+ }
666
+ else {
667
+ lCleanup.push(context);
668
+ if (tView.firstCreatePass) {
669
+ getOrCreateTViewCleanup(tView).push(cleanupFn, lCleanup.length - 1);
670
+ }
671
+ }
672
+ }
673
+ export function createTNode(tView, tParent, type, index, value, attrs) {
674
+ ngDevMode && index !== 0 && // 0 are bogus nodes and they are OK. See `createContainerRef` in
675
+ // `view_engine_compatibility` for additional context.
676
+ assertGreaterThanOrEqual(index, HEADER_OFFSET, 'TNodes can\'t be in the LView header.');
677
+ ngDevMode && assertNotSame(attrs, undefined, '\'undefined\' is not valid value for \'attrs\'');
678
+ ngDevMode && ngDevMode.tNode++;
679
+ ngDevMode && tParent && assertTNodeForTView(tParent, tView);
680
+ let injectorIndex = tParent ? tParent.injectorIndex : -1;
681
+ const tNode = ngDevMode ?
682
+ new TNodeDebug(tView, // tView_: TView
683
+ type, // type: TNodeType
684
+ index, // index: number
685
+ null, // insertBeforeIndex: null|-1|number|number[]
686
+ injectorIndex, // injectorIndex: number
687
+ -1, // directiveStart: number
688
+ -1, // directiveEnd: number
689
+ -1, // directiveStylingLast: number
690
+ null, // propertyBindings: number[]|null
691
+ 0, // flags: TNodeFlags
692
+ 0, // providerIndexes: TNodeProviderIndexes
693
+ value, // value: string|null
694
+ attrs, // attrs: (string|AttributeMarker|(string|SelectorFlags)[])[]|null
695
+ null, // mergedAttrs
696
+ null, // localNames: (string|number)[]|null
697
+ undefined, // initialInputs: (string[]|null)[]|null|undefined
698
+ null, // inputs: PropertyAliases|null
699
+ null, // outputs: PropertyAliases|null
700
+ null, // tViews: ITView|ITView[]|null
701
+ null, // next: ITNode|null
702
+ null, // projectionNext: ITNode|null
703
+ null, // child: ITNode|null
704
+ tParent, // parent: TElementNode|TContainerNode|null
705
+ null, // projection: number|(ITNode|RNode[])[]|null
706
+ null, // styles: string|null
707
+ null, // stylesWithoutHost: string|null
708
+ undefined, // residualStyles: string|null
709
+ null, // classes: string|null
710
+ null, // classesWithoutHost: string|null
711
+ undefined, // residualClasses: string|null
712
+ 0, // classBindings: TStylingRange;
713
+ 0) :
714
+ {
715
+ type,
716
+ index,
717
+ insertBeforeIndex: null,
718
+ injectorIndex,
719
+ directiveStart: -1,
720
+ directiveEnd: -1,
721
+ directiveStylingLast: -1,
722
+ propertyBindings: null,
723
+ flags: 0,
724
+ providerIndexes: 0,
725
+ value: value,
726
+ attrs: attrs,
727
+ mergedAttrs: null,
728
+ localNames: null,
729
+ initialInputs: undefined,
730
+ inputs: null,
731
+ outputs: null,
732
+ tViews: null,
733
+ next: null,
734
+ projectionNext: null,
735
+ child: null,
736
+ parent: tParent,
737
+ projection: null,
738
+ styles: null,
739
+ stylesWithoutHost: null,
740
+ residualStyles: undefined,
741
+ classes: null,
742
+ classesWithoutHost: null,
743
+ residualClasses: undefined,
744
+ classBindings: 0,
745
+ styleBindings: 0,
746
+ };
747
+ if (ngDevMode) {
748
+ // For performance reasons it is important that the tNode retains the same shape during runtime.
749
+ // (To make sure that all of the code is monomorphic.) For this reason we seal the object to
750
+ // prevent class transitions.
751
+ Object.seal(tNode);
752
+ }
753
+ return tNode;
754
+ }
755
+ function generatePropertyAliases(inputAliasMap, directiveDefIdx, propStore) {
756
+ for (let publicName in inputAliasMap) {
757
+ if (inputAliasMap.hasOwnProperty(publicName)) {
758
+ propStore = propStore === null ? {} : propStore;
759
+ const internalName = inputAliasMap[publicName];
760
+ if (propStore.hasOwnProperty(publicName)) {
761
+ propStore[publicName].push(directiveDefIdx, internalName);
762
+ }
763
+ else {
764
+ (propStore[publicName] = [directiveDefIdx, internalName]);
765
+ }
766
+ }
767
+ }
768
+ return propStore;
769
+ }
770
+ /**
771
+ * Initializes data structures required to work with directive inputs and outputs.
772
+ * Initialization is done for all directives matched on a given TNode.
773
+ */
774
+ function initializeInputAndOutputAliases(tView, tNode) {
775
+ ngDevMode && assertFirstCreatePass(tView);
776
+ const start = tNode.directiveStart;
777
+ const end = tNode.directiveEnd;
778
+ const tViewData = tView.data;
779
+ const tNodeAttrs = tNode.attrs;
780
+ const inputsFromAttrs = ngDevMode ? new TNodeInitialInputs() : [];
781
+ let inputsStore = null;
782
+ let outputsStore = null;
783
+ for (let i = start; i < end; i++) {
784
+ const directiveDef = tViewData[i];
785
+ const directiveInputs = directiveDef.inputs;
786
+ // Do not use unbound attributes as inputs to structural directives, since structural
787
+ // directive inputs can only be set using microsyntax (e.g. `<div *dir="exp">`).
788
+ // TODO(FW-1930): microsyntax expressions may also contain unbound/static attributes, which
789
+ // should be set for inline templates.
790
+ const initialInputs = (tNodeAttrs !== null && !isInlineTemplate(tNode)) ?
791
+ generateInitialInputs(directiveInputs, tNodeAttrs) :
792
+ null;
793
+ inputsFromAttrs.push(initialInputs);
794
+ inputsStore = generatePropertyAliases(directiveInputs, i, inputsStore);
795
+ outputsStore = generatePropertyAliases(directiveDef.outputs, i, outputsStore);
796
+ }
797
+ if (inputsStore !== null) {
798
+ if (inputsStore.hasOwnProperty('class')) {
799
+ tNode.flags |= 16 /* hasClassInput */;
800
+ }
801
+ if (inputsStore.hasOwnProperty('style')) {
802
+ tNode.flags |= 32 /* hasStyleInput */;
803
+ }
804
+ }
805
+ tNode.initialInputs = inputsFromAttrs;
806
+ tNode.inputs = inputsStore;
807
+ tNode.outputs = outputsStore;
808
+ }
809
+ /**
810
+ * Mapping between attributes names that don't correspond to their element property names.
811
+ *
812
+ * Performance note: this function is written as a series of if checks (instead of, say, a property
813
+ * object lookup) for performance reasons - the series of `if` checks seems to be the fastest way of
814
+ * mapping property names. Do NOT change without benchmarking.
815
+ *
816
+ * Note: this mapping has to be kept in sync with the equally named mapping in the template
817
+ * type-checking machinery of ngtsc.
818
+ */
819
+ function mapPropName(name) {
820
+ if (name === 'class')
821
+ return 'className';
822
+ if (name === 'for')
823
+ return 'htmlFor';
824
+ if (name === 'formaction')
825
+ return 'formAction';
826
+ if (name === 'innerHtml')
827
+ return 'innerHTML';
828
+ if (name === 'readonly')
829
+ return 'readOnly';
830
+ if (name === 'tabindex')
831
+ return 'tabIndex';
832
+ return name;
833
+ }
834
+ export function elementPropertyInternal(tView, tNode, lView, propName, value, renderer, sanitizer, nativeOnly) {
835
+ ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
836
+ const element = getNativeByTNode(tNode, lView);
837
+ let inputData = tNode.inputs;
838
+ let dataValue;
839
+ if (!nativeOnly && inputData != null && (dataValue = inputData[propName])) {
840
+ setInputsForProperty(tView, lView, dataValue, propName, value);
841
+ if (isComponentHost(tNode))
842
+ markDirtyIfOnPush(lView, tNode.index);
843
+ if (ngDevMode) {
844
+ setNgReflectProperties(lView, element, tNode.type, dataValue, value);
845
+ }
846
+ }
847
+ else if (tNode.type & 3 /* AnyRNode */) {
848
+ propName = mapPropName(propName);
849
+ if (ngDevMode) {
850
+ validateAgainstEventProperties(propName);
851
+ if (!validateProperty(tView, element, propName, tNode)) {
852
+ // Return here since we only log warnings for unknown properties.
853
+ logUnknownPropertyError(propName, tNode);
854
+ return;
855
+ }
856
+ ngDevMode.rendererSetProperty++;
857
+ }
858
+ // It is assumed that the sanitizer is only added when the compiler determines that the
859
+ // property is risky, so sanitization can be done without further checks.
860
+ value = sanitizer != null ? sanitizer(value, tNode.value || '', propName) : value;
861
+ if (isProceduralRenderer(renderer)) {
862
+ renderer.setProperty(element, propName, value);
863
+ }
864
+ else if (!isAnimationProp(propName)) {
865
+ element.setProperty ? element.setProperty(propName, value) :
866
+ element[propName] = value;
867
+ }
868
+ }
869
+ else if (tNode.type & 12 /* AnyContainer */) {
870
+ // If the node is a container and the property didn't
871
+ // match any of the inputs or schemas we should throw.
872
+ if (ngDevMode && !matchingSchemas(tView, tNode.value)) {
873
+ logUnknownPropertyError(propName, tNode);
874
+ }
875
+ }
876
+ }
877
+ /** If node is an OnPush component, marks its LView dirty. */
878
+ function markDirtyIfOnPush(lView, viewIndex) {
879
+ ngDevMode && assertLView(lView);
880
+ const childComponentLView = getComponentLViewByIndex(viewIndex, lView);
881
+ if (!(childComponentLView[FLAGS] & 16 /* CheckAlways */)) {
882
+ childComponentLView[FLAGS] |= 64 /* Dirty */;
883
+ }
884
+ }
885
+ function setNgReflectProperty(lView, element, type, attrName, value) {
886
+ const renderer = lView[RENDERER];
887
+ attrName = normalizeDebugBindingName(attrName);
888
+ const debugValue = normalizeDebugBindingValue(value);
889
+ if (type & 3 /* AnyRNode */) {
890
+ if (value == null) {
891
+ isProceduralRenderer(renderer) ? renderer.removeAttribute(element, attrName) :
892
+ element.removeAttribute(attrName);
893
+ }
894
+ else {
895
+ isProceduralRenderer(renderer) ?
896
+ renderer.setAttribute(element, attrName, debugValue) :
897
+ element.setAttribute(attrName, debugValue);
898
+ }
899
+ }
900
+ else {
901
+ const textContent = escapeCommentText(`bindings=${JSON.stringify({ [attrName]: debugValue }, null, 2)}`);
902
+ if (isProceduralRenderer(renderer)) {
903
+ renderer.setValue(element, textContent);
904
+ }
905
+ else {
906
+ element.textContent = textContent;
907
+ }
908
+ }
909
+ }
910
+ export function setNgReflectProperties(lView, element, type, dataValue, value) {
911
+ if (type & (3 /* AnyRNode */ | 4 /* Container */)) {
912
+ /**
913
+ * dataValue is an array containing runtime input or output names for the directives:
914
+ * i+0: directive instance index
915
+ * i+1: privateName
916
+ *
917
+ * e.g. [0, 'change', 'change-minified']
918
+ * we want to set the reflected property with the privateName: dataValue[i+1]
919
+ */
920
+ for (let i = 0; i < dataValue.length; i += 2) {
921
+ setNgReflectProperty(lView, element, type, dataValue[i + 1], value);
922
+ }
923
+ }
924
+ }
925
+ function validateProperty(tView, element, propName, tNode) {
926
+ // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
927
+ // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
928
+ // defined as an array (as an empty array in case `schemas` field is not defined) and we should
929
+ // execute the check below.
930
+ if (tView.schemas === null)
931
+ return true;
932
+ // The property is considered valid if the element matches the schema, it exists on the element
933
+ // or it is synthetic, and we are in a browser context (web worker nodes should be skipped).
934
+ if (matchingSchemas(tView, tNode.value) || propName in element || isAnimationProp(propName)) {
935
+ return true;
936
+ }
937
+ // Note: `typeof Node` returns 'function' in most browsers, but on IE it is 'object' so we
938
+ // need to account for both here, while being careful for `typeof null` also returning 'object'.
939
+ return typeof Node === 'undefined' || Node === null || !(element instanceof Node);
940
+ }
941
+ export function matchingSchemas(tView, tagName) {
942
+ const schemas = tView.schemas;
943
+ if (schemas !== null) {
944
+ for (let i = 0; i < schemas.length; i++) {
945
+ const schema = schemas[i];
946
+ if (schema === NO_ERRORS_SCHEMA ||
947
+ schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {
948
+ return true;
949
+ }
950
+ }
951
+ }
952
+ return false;
953
+ }
954
+ /**
955
+ * Logs an error that a property is not supported on an element.
956
+ * @param propName Name of the invalid property.
957
+ * @param tNode Node on which we encountered the property.
958
+ */
959
+ function logUnknownPropertyError(propName, tNode) {
960
+ let message = `Can't bind to '${propName}' since it isn't a known property of '${tNode.value}'.`;
961
+ console.error(formatRuntimeError("303" /* UNKNOWN_BINDING */, message));
962
+ }
963
+ /**
964
+ * Instantiate a root component.
965
+ */
966
+ export function instantiateRootComponent(tView, lView, def) {
967
+ const rootTNode = getCurrentTNode();
968
+ if (tView.firstCreatePass) {
969
+ if (def.providersResolver)
970
+ def.providersResolver(def);
971
+ const directiveIndex = allocExpando(tView, lView, 1, null);
972
+ ngDevMode &&
973
+ assertEqual(directiveIndex, rootTNode.directiveStart, 'Because this is a root component the allocated expando should match the TNode component.');
974
+ configureViewWithDirective(tView, rootTNode, lView, directiveIndex, def);
975
+ }
976
+ const directive = getNodeInjectable(lView, tView, rootTNode.directiveStart, rootTNode);
977
+ attachPatchData(directive, lView);
978
+ const native = getNativeByTNode(rootTNode, lView);
979
+ if (native) {
980
+ attachPatchData(native, lView);
981
+ }
982
+ return directive;
983
+ }
984
+ /**
985
+ * Resolve the matched directives on a node.
986
+ */
987
+ export function resolveDirectives(tView, lView, tNode, localRefs) {
988
+ // Please make sure to have explicit type for `exportsMap`. Inferred type triggers bug in
989
+ // tsickle.
990
+ ngDevMode && assertFirstCreatePass(tView);
991
+ let hasDirectives = false;
992
+ if (getBindingsEnabled()) {
993
+ const directiveDefs = findDirectiveDefMatches(tView, lView, tNode);
994
+ const exportsMap = localRefs === null ? null : { '': -1 };
995
+ if (directiveDefs !== null) {
996
+ hasDirectives = true;
997
+ initTNodeFlags(tNode, tView.data.length, directiveDefs.length);
998
+ // When the same token is provided by several directives on the same node, some rules apply in
999
+ // the viewEngine:
1000
+ // - viewProviders have priority over providers
1001
+ // - the last directive in NgModule.declarations has priority over the previous one
1002
+ // So to match these rules, the order in which providers are added in the arrays is very
1003
+ // important.
1004
+ for (let i = 0; i < directiveDefs.length; i++) {
1005
+ const def = directiveDefs[i];
1006
+ if (def.providersResolver)
1007
+ def.providersResolver(def);
1008
+ }
1009
+ let preOrderHooksFound = false;
1010
+ let preOrderCheckHooksFound = false;
1011
+ let directiveIdx = allocExpando(tView, lView, directiveDefs.length, null);
1012
+ ngDevMode &&
1013
+ assertSame(directiveIdx, tNode.directiveStart, 'TNode.directiveStart should point to just allocated space');
1014
+ for (let i = 0; i < directiveDefs.length; i++) {
1015
+ const def = directiveDefs[i];
1016
+ // Merge the attrs in the order of matches. This assumes that the first directive is the
1017
+ // component itself, so that the component has the least priority.
1018
+ tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, def.hostAttrs);
1019
+ configureViewWithDirective(tView, tNode, lView, directiveIdx, def);
1020
+ saveNameToExportMap(directiveIdx, def, exportsMap);
1021
+ if (def.contentQueries !== null)
1022
+ tNode.flags |= 8 /* hasContentQuery */;
1023
+ if (def.hostBindings !== null || def.hostAttrs !== null || def.hostVars !== 0)
1024
+ tNode.flags |= 128 /* hasHostBindings */;
1025
+ const lifeCycleHooks = def.type.prototype;
1026
+ // Only push a node index into the preOrderHooks array if this is the first
1027
+ // pre-order hook found on this node.
1028
+ if (!preOrderHooksFound &&
1029
+ (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngOnInit || lifeCycleHooks.ngDoCheck)) {
1030
+ // We will push the actual hook function into this array later during dir instantiation.
1031
+ // We cannot do it now because we must ensure hooks are registered in the same
1032
+ // order that directives are created (i.e. injection order).
1033
+ (tView.preOrderHooks || (tView.preOrderHooks = [])).push(tNode.index);
1034
+ preOrderHooksFound = true;
1035
+ }
1036
+ if (!preOrderCheckHooksFound && (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngDoCheck)) {
1037
+ (tView.preOrderCheckHooks || (tView.preOrderCheckHooks = [])).push(tNode.index);
1038
+ preOrderCheckHooksFound = true;
1039
+ }
1040
+ directiveIdx++;
1041
+ }
1042
+ initializeInputAndOutputAliases(tView, tNode);
1043
+ }
1044
+ if (exportsMap)
1045
+ cacheMatchingLocalNames(tNode, localRefs, exportsMap);
1046
+ }
1047
+ // Merge the template attrs last so that they have the highest priority.
1048
+ tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, tNode.attrs);
1049
+ return hasDirectives;
1050
+ }
1051
+ /**
1052
+ * Add `hostBindings` to the `TView.hostBindingOpCodes`.
1053
+ *
1054
+ * @param tView `TView` to which the `hostBindings` should be added.
1055
+ * @param tNode `TNode` the element which contains the directive
1056
+ * @param lView `LView` current `LView`
1057
+ * @param directiveIdx Directive index in view.
1058
+ * @param directiveVarsIdx Where will the directive's vars be stored
1059
+ * @param def `ComponentDef`/`DirectiveDef`, which contains the `hostVars`/`hostBindings` to add.
1060
+ */
1061
+ export function registerHostBindingOpCodes(tView, tNode, lView, directiveIdx, directiveVarsIdx, def) {
1062
+ ngDevMode && assertFirstCreatePass(tView);
1063
+ const hostBindings = def.hostBindings;
1064
+ if (hostBindings) {
1065
+ let hostBindingOpCodes = tView.hostBindingOpCodes;
1066
+ if (hostBindingOpCodes === null) {
1067
+ hostBindingOpCodes = tView.hostBindingOpCodes = [];
1068
+ }
1069
+ const elementIndx = ~tNode.index;
1070
+ if (lastSelectedElementIdx(hostBindingOpCodes) != elementIndx) {
1071
+ // Conditionally add select element so that we are more efficient in execution.
1072
+ // NOTE: this is strictly not necessary and it trades code size for runtime perf.
1073
+ // (We could just always add it.)
1074
+ hostBindingOpCodes.push(elementIndx);
1075
+ }
1076
+ hostBindingOpCodes.push(directiveIdx, directiveVarsIdx, hostBindings);
1077
+ }
1078
+ }
1079
+ /**
1080
+ * Returns the last selected element index in the `HostBindingOpCodes`
1081
+ *
1082
+ * For perf reasons we don't need to update the selected element index in `HostBindingOpCodes` only
1083
+ * if it changes. This method returns the last index (or '0' if not found.)
1084
+ *
1085
+ * Selected element index are only the ones which are negative.
1086
+ */
1087
+ function lastSelectedElementIdx(hostBindingOpCodes) {
1088
+ let i = hostBindingOpCodes.length;
1089
+ while (i > 0) {
1090
+ const value = hostBindingOpCodes[--i];
1091
+ if (typeof value === 'number' && value < 0) {
1092
+ return value;
1093
+ }
1094
+ }
1095
+ return 0;
1096
+ }
1097
+ /**
1098
+ * Instantiate all the directives that were previously resolved on the current node.
1099
+ */
1100
+ function instantiateAllDirectives(tView, lView, tNode, native) {
1101
+ const start = tNode.directiveStart;
1102
+ const end = tNode.directiveEnd;
1103
+ if (!tView.firstCreatePass) {
1104
+ getOrCreateNodeInjectorForNode(tNode, lView);
1105
+ }
1106
+ attachPatchData(native, lView);
1107
+ const initialInputs = tNode.initialInputs;
1108
+ for (let i = start; i < end; i++) {
1109
+ const def = tView.data[i];
1110
+ const isComponent = isComponentDef(def);
1111
+ if (isComponent) {
1112
+ ngDevMode && assertTNodeType(tNode, 3 /* AnyRNode */);
1113
+ addComponentLogic(lView, tNode, def);
1114
+ }
1115
+ const directive = getNodeInjectable(lView, tView, i, tNode);
1116
+ attachPatchData(directive, lView);
1117
+ if (initialInputs !== null) {
1118
+ setInputsFromAttrs(lView, i - start, directive, def, tNode, initialInputs);
1119
+ }
1120
+ if (isComponent) {
1121
+ const componentView = getComponentLViewByIndex(tNode.index, lView);
1122
+ componentView[CONTEXT] = directive;
1123
+ }
1124
+ }
1125
+ }
1126
+ function invokeDirectivesHostBindings(tView, lView, tNode) {
1127
+ const start = tNode.directiveStart;
1128
+ const end = tNode.directiveEnd;
1129
+ const firstCreatePass = tView.firstCreatePass;
1130
+ const elementIndex = tNode.index;
1131
+ const currentDirectiveIndex = getCurrentDirectiveIndex();
1132
+ try {
1133
+ setSelectedIndex(elementIndex);
1134
+ for (let dirIndex = start; dirIndex < end; dirIndex++) {
1135
+ const def = tView.data[dirIndex];
1136
+ const directive = lView[dirIndex];
1137
+ setCurrentDirectiveIndex(dirIndex);
1138
+ if (def.hostBindings !== null || def.hostVars !== 0 || def.hostAttrs !== null) {
1139
+ invokeHostBindingsInCreationMode(def, directive);
1140
+ }
1141
+ }
1142
+ }
1143
+ finally {
1144
+ setSelectedIndex(-1);
1145
+ setCurrentDirectiveIndex(currentDirectiveIndex);
1146
+ }
1147
+ }
1148
+ /**
1149
+ * Invoke the host bindings in creation mode.
1150
+ *
1151
+ * @param def `DirectiveDef` which may contain the `hostBindings` function.
1152
+ * @param directive Instance of directive.
1153
+ */
1154
+ export function invokeHostBindingsInCreationMode(def, directive) {
1155
+ if (def.hostBindings !== null) {
1156
+ def.hostBindings(1 /* Create */, directive);
1157
+ }
1158
+ }
1159
+ /**
1160
+ * Matches the current node against all available selectors.
1161
+ * If a component is matched (at most one), it is returned in first position in the array.
1162
+ */
1163
+ function findDirectiveDefMatches(tView, viewData, tNode) {
1164
+ ngDevMode && assertFirstCreatePass(tView);
1165
+ ngDevMode && assertTNodeType(tNode, 3 /* AnyRNode */ | 12 /* AnyContainer */);
1166
+ const registry = tView.directiveRegistry;
1167
+ let matches = null;
1168
+ if (registry) {
1169
+ for (let i = 0; i < registry.length; i++) {
1170
+ const def = registry[i];
1171
+ if (isNodeMatchingSelectorList(tNode, def.selectors, /* isProjectionMode */ false)) {
1172
+ matches || (matches = ngDevMode ? new MatchesArray() : []);
1173
+ diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, viewData), tView, def.type);
1174
+ if (isComponentDef(def)) {
1175
+ if (ngDevMode) {
1176
+ assertTNodeType(tNode, 2 /* Element */, `"${tNode.value}" tags cannot be used as component hosts. ` +
1177
+ `Please use a different tag to activate the ${stringify(def.type)} component.`);
1178
+ if (tNode.flags & 2 /* isComponentHost */)
1179
+ throwMultipleComponentError(tNode);
1180
+ }
1181
+ markAsComponentHost(tView, tNode);
1182
+ // The component is always stored first with directives after.
1183
+ matches.unshift(def);
1184
+ }
1185
+ else {
1186
+ matches.push(def);
1187
+ }
1188
+ }
1189
+ }
1190
+ }
1191
+ return matches;
1192
+ }
1193
+ /**
1194
+ * Marks a given TNode as a component's host. This consists of:
1195
+ * - setting appropriate TNode flags;
1196
+ * - storing index of component's host element so it will be queued for view refresh during CD.
1197
+ */
1198
+ export function markAsComponentHost(tView, hostTNode) {
1199
+ ngDevMode && assertFirstCreatePass(tView);
1200
+ hostTNode.flags |= 2 /* isComponentHost */;
1201
+ (tView.components || (tView.components = ngDevMode ? new TViewComponents() : []))
1202
+ .push(hostTNode.index);
1203
+ }
1204
+ /** Caches local names and their matching directive indices for query and template lookups. */
1205
+ function cacheMatchingLocalNames(tNode, localRefs, exportsMap) {
1206
+ if (localRefs) {
1207
+ const localNames = tNode.localNames = ngDevMode ? new TNodeLocalNames() : [];
1208
+ // Local names must be stored in tNode in the same order that localRefs are defined
1209
+ // in the template to ensure the data is loaded in the same slots as their refs
1210
+ // in the template (for template queries).
1211
+ for (let i = 0; i < localRefs.length; i += 2) {
1212
+ const index = exportsMap[localRefs[i + 1]];
1213
+ if (index == null)
1214
+ throw new RuntimeError("301" /* EXPORT_NOT_FOUND */, `Export of name '${localRefs[i + 1]}' not found!`);
1215
+ localNames.push(localRefs[i], index);
1216
+ }
1217
+ }
1218
+ }
1219
+ /**
1220
+ * Builds up an export map as directives are created, so local refs can be quickly mapped
1221
+ * to their directive instances.
1222
+ */
1223
+ function saveNameToExportMap(directiveIdx, def, exportsMap) {
1224
+ if (exportsMap) {
1225
+ if (def.exportAs) {
1226
+ for (let i = 0; i < def.exportAs.length; i++) {
1227
+ exportsMap[def.exportAs[i]] = directiveIdx;
1228
+ }
1229
+ }
1230
+ if (isComponentDef(def))
1231
+ exportsMap[''] = directiveIdx;
1232
+ }
1233
+ }
1234
+ /**
1235
+ * Initializes the flags on the current node, setting all indices to the initial index,
1236
+ * the directive count to 0, and adding the isComponent flag.
1237
+ * @param index the initial index
1238
+ */
1239
+ export function initTNodeFlags(tNode, index, numberOfDirectives) {
1240
+ ngDevMode &&
1241
+ assertNotEqual(numberOfDirectives, tNode.directiveEnd - tNode.directiveStart, 'Reached the max number of directives');
1242
+ tNode.flags |= 1 /* isDirectiveHost */;
1243
+ // When the first directive is created on a node, save the index
1244
+ tNode.directiveStart = index;
1245
+ tNode.directiveEnd = index + numberOfDirectives;
1246
+ tNode.providerIndexes = index;
1247
+ }
1248
+ /**
1249
+ * Setup directive for instantiation.
1250
+ *
1251
+ * We need to create a `NodeInjectorFactory` which is then inserted in both the `Blueprint` as well
1252
+ * as `LView`. `TView` gets the `DirectiveDef`.
1253
+ *
1254
+ * @param tView `TView`
1255
+ * @param tNode `TNode`
1256
+ * @param lView `LView`
1257
+ * @param directiveIndex Index where the directive will be stored in the Expando.
1258
+ * @param def `DirectiveDef`
1259
+ */
1260
+ function configureViewWithDirective(tView, tNode, lView, directiveIndex, def) {
1261
+ ngDevMode &&
1262
+ assertGreaterThanOrEqual(directiveIndex, HEADER_OFFSET, 'Must be in Expando section');
1263
+ tView.data[directiveIndex] = def;
1264
+ const directiveFactory = def.factory || (def.factory = getFactoryDef(def.type, true));
1265
+ const nodeInjectorFactory = new NodeInjectorFactory(directiveFactory, isComponentDef(def), null);
1266
+ tView.blueprint[directiveIndex] = nodeInjectorFactory;
1267
+ lView[directiveIndex] = nodeInjectorFactory;
1268
+ registerHostBindingOpCodes(tView, tNode, lView, directiveIndex, allocExpando(tView, lView, def.hostVars, NO_CHANGE), def);
1269
+ }
1270
+ function addComponentLogic(lView, hostTNode, def) {
1271
+ const native = getNativeByTNode(hostTNode, lView);
1272
+ const tView = getOrCreateTComponentView(def);
1273
+ // Only component views should be added to the view tree directly. Embedded views are
1274
+ // accessed through their containers because they may be removed / re-added later.
1275
+ const rendererFactory = lView[RENDERER_FACTORY];
1276
+ const componentView = addToViewTree(lView, createLView(lView, tView, null, def.onPush ? 64 /* Dirty */ : 16 /* CheckAlways */, native, hostTNode, rendererFactory, rendererFactory.createRenderer(native, def), null, null));
1277
+ // Component view will always be created before any injected LContainers,
1278
+ // so this is a regular element, wrap it with the component view
1279
+ lView[hostTNode.index] = componentView;
1280
+ }
1281
+ export function elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace) {
1282
+ if (ngDevMode) {
1283
+ assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
1284
+ validateAgainstEventAttributes(name);
1285
+ assertTNodeType(tNode, 2 /* Element */, `Attempted to set attribute \`${name}\` on a container node. ` +
1286
+ `Host bindings are not valid on ng-container or ng-template.`);
1287
+ }
1288
+ const element = getNativeByTNode(tNode, lView);
1289
+ setElementAttribute(lView[RENDERER], element, namespace, tNode.value, name, value, sanitizer);
1290
+ }
1291
+ export function setElementAttribute(renderer, element, namespace, tagName, name, value, sanitizer) {
1292
+ if (value == null) {
1293
+ ngDevMode && ngDevMode.rendererRemoveAttribute++;
1294
+ isProceduralRenderer(renderer) ? renderer.removeAttribute(element, name, namespace) :
1295
+ element.removeAttribute(name);
1296
+ }
1297
+ else {
1298
+ ngDevMode && ngDevMode.rendererSetAttribute++;
1299
+ const strValue = sanitizer == null ? renderStringify(value) : sanitizer(value, tagName || '', name);
1300
+ if (isProceduralRenderer(renderer)) {
1301
+ renderer.setAttribute(element, name, strValue, namespace);
1302
+ }
1303
+ else {
1304
+ namespace ? element.setAttributeNS(namespace, name, strValue) :
1305
+ element.setAttribute(name, strValue);
1306
+ }
1307
+ }
1308
+ }
1309
+ /**
1310
+ * Sets initial input properties on directive instances from attribute data
1311
+ *
1312
+ * @param lView Current LView that is being processed.
1313
+ * @param directiveIndex Index of the directive in directives array
1314
+ * @param instance Instance of the directive on which to set the initial inputs
1315
+ * @param def The directive def that contains the list of inputs
1316
+ * @param tNode The static data for this node
1317
+ */
1318
+ function setInputsFromAttrs(lView, directiveIndex, instance, def, tNode, initialInputData) {
1319
+ const initialInputs = initialInputData[directiveIndex];
1320
+ if (initialInputs !== null) {
1321
+ const setInput = def.setInput;
1322
+ for (let i = 0; i < initialInputs.length;) {
1323
+ const publicName = initialInputs[i++];
1324
+ const privateName = initialInputs[i++];
1325
+ const value = initialInputs[i++];
1326
+ if (setInput !== null) {
1327
+ def.setInput(instance, value, publicName, privateName);
1328
+ }
1329
+ else {
1330
+ instance[privateName] = value;
1331
+ }
1332
+ if (ngDevMode) {
1333
+ const nativeElement = getNativeByTNode(tNode, lView);
1334
+ setNgReflectProperty(lView, nativeElement, tNode.type, privateName, value);
1335
+ }
1336
+ }
1337
+ }
1338
+ }
1339
+ /**
1340
+ * Generates initialInputData for a node and stores it in the template's static storage
1341
+ * so subsequent template invocations don't have to recalculate it.
1342
+ *
1343
+ * initialInputData is an array containing values that need to be set as input properties
1344
+ * for directives on this node, but only once on creation. We need this array to support
1345
+ * the case where you set an @Input property of a directive using attribute-like syntax.
1346
+ * e.g. if you have a `name` @Input, you can set it once like this:
1347
+ *
1348
+ * <my-component name="Bess"></my-component>
1349
+ *
1350
+ * @param inputs The list of inputs from the directive def
1351
+ * @param attrs The static attrs on this node
1352
+ */
1353
+ function generateInitialInputs(inputs, attrs) {
1354
+ let inputsToStore = null;
1355
+ let i = 0;
1356
+ while (i < attrs.length) {
1357
+ const attrName = attrs[i];
1358
+ if (attrName === 0 /* NamespaceURI */) {
1359
+ // We do not allow inputs on namespaced attributes.
1360
+ i += 4;
1361
+ continue;
1362
+ }
1363
+ else if (attrName === 5 /* ProjectAs */) {
1364
+ // Skip over the `ngProjectAs` value.
1365
+ i += 2;
1366
+ continue;
1367
+ }
1368
+ // If we hit any other attribute markers, we're done anyway. None of those are valid inputs.
1369
+ if (typeof attrName === 'number')
1370
+ break;
1371
+ if (inputs.hasOwnProperty(attrName)) {
1372
+ if (inputsToStore === null)
1373
+ inputsToStore = [];
1374
+ inputsToStore.push(attrName, inputs[attrName], attrs[i + 1]);
1375
+ }
1376
+ i += 2;
1377
+ }
1378
+ return inputsToStore;
1379
+ }
1380
+ //////////////////////////
1381
+ //// ViewContainer & View
1382
+ //////////////////////////
1383
+ // Not sure why I need to do `any` here but TS complains later.
1384
+ const LContainerArray = ((typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode()) &&
1385
+ createNamedArrayType('LContainer');
1386
+ /**
1387
+ * Creates a LContainer, either from a container instruction, or for a ViewContainerRef.
1388
+ *
1389
+ * @param hostNative The host element for the LContainer
1390
+ * @param hostTNode The host TNode for the LContainer
1391
+ * @param currentView The parent view of the LContainer
1392
+ * @param native The native comment element
1393
+ * @param isForViewContainerRef Optional a flag indicating the ViewContainerRef case
1394
+ * @returns LContainer
1395
+ */
1396
+ export function createLContainer(hostNative, currentView, native, tNode) {
1397
+ ngDevMode && assertLView(currentView);
1398
+ ngDevMode && !isProceduralRenderer(currentView[RENDERER]) && assertDomNode(native);
1399
+ // https://jsperf.com/array-literal-vs-new-array-really
1400
+ const lContainer = new (ngDevMode ? LContainerArray : Array)(hostNative, // host native
1401
+ true, // Boolean `true` in this position signifies that this is an `LContainer`
1402
+ false, // has transplanted views
1403
+ currentView, // parent
1404
+ null, // next
1405
+ 0, // transplanted views to refresh count
1406
+ tNode, // t_host
1407
+ native, // native,
1408
+ null, // view refs
1409
+ null);
1410
+ ngDevMode &&
1411
+ assertEqual(lContainer.length, CONTAINER_HEADER_OFFSET, 'Should allocate correct number of slots for LContainer header.');
1412
+ ngDevMode && attachLContainerDebug(lContainer);
1413
+ return lContainer;
1414
+ }
1415
+ /**
1416
+ * Goes over embedded views (ones created through ViewContainerRef APIs) and refreshes
1417
+ * them by executing an associated template function.
1418
+ */
1419
+ function refreshEmbeddedViews(lView) {
1420
+ for (let lContainer = getFirstLContainer(lView); lContainer !== null; lContainer = getNextLContainer(lContainer)) {
1421
+ for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
1422
+ const embeddedLView = lContainer[i];
1423
+ const embeddedTView = embeddedLView[TVIEW];
1424
+ ngDevMode && assertDefined(embeddedTView, 'TView must be allocated');
1425
+ if (viewAttachedToChangeDetector(embeddedLView)) {
1426
+ refreshView(embeddedTView, embeddedLView, embeddedTView.template, embeddedLView[CONTEXT]);
1427
+ }
1428
+ }
1429
+ }
1430
+ }
1431
+ /**
1432
+ * Mark transplanted views as needing to be refreshed at their insertion points.
1433
+ *
1434
+ * @param lView The `LView` that may have transplanted views.
1435
+ */
1436
+ function markTransplantedViewsForRefresh(lView) {
1437
+ for (let lContainer = getFirstLContainer(lView); lContainer !== null; lContainer = getNextLContainer(lContainer)) {
1438
+ if (!lContainer[HAS_TRANSPLANTED_VIEWS])
1439
+ continue;
1440
+ const movedViews = lContainer[MOVED_VIEWS];
1441
+ ngDevMode && assertDefined(movedViews, 'Transplanted View flags set but missing MOVED_VIEWS');
1442
+ for (let i = 0; i < movedViews.length; i++) {
1443
+ const movedLView = movedViews[i];
1444
+ const insertionLContainer = movedLView[PARENT];
1445
+ ngDevMode && assertLContainer(insertionLContainer);
1446
+ // We don't want to increment the counter if the moved LView was already marked for
1447
+ // refresh.
1448
+ if ((movedLView[FLAGS] & 1024 /* RefreshTransplantedView */) === 0) {
1449
+ updateTransplantedViewCount(insertionLContainer, 1);
1450
+ }
1451
+ // Note, it is possible that the `movedViews` is tracking views that are transplanted *and*
1452
+ // those that aren't (declaration component === insertion component). In the latter case,
1453
+ // it's fine to add the flag, as we will clear it immediately in
1454
+ // `refreshEmbeddedViews` for the view currently being refreshed.
1455
+ movedLView[FLAGS] |= 1024 /* RefreshTransplantedView */;
1456
+ }
1457
+ }
1458
+ }
1459
+ /////////////
1460
+ /**
1461
+ * Refreshes components by entering the component view and processing its bindings, queries, etc.
1462
+ *
1463
+ * @param componentHostIdx Element index in LView[] (adjusted for HEADER_OFFSET)
1464
+ */
1465
+ function refreshComponent(hostLView, componentHostIdx) {
1466
+ ngDevMode && assertEqual(isCreationMode(hostLView), false, 'Should be run in update mode');
1467
+ const componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
1468
+ // Only attached components that are CheckAlways or OnPush and dirty should be refreshed
1469
+ if (viewAttachedToChangeDetector(componentView)) {
1470
+ const tView = componentView[TVIEW];
1471
+ if (componentView[FLAGS] & (16 /* CheckAlways */ | 64 /* Dirty */)) {
1472
+ refreshView(tView, componentView, tView.template, componentView[CONTEXT]);
1473
+ }
1474
+ else if (componentView[TRANSPLANTED_VIEWS_TO_REFRESH] > 0) {
1475
+ // Only attached components that are CheckAlways or OnPush and dirty should be refreshed
1476
+ refreshContainsDirtyView(componentView);
1477
+ }
1478
+ }
1479
+ }
1480
+ /**
1481
+ * Refreshes all transplanted views marked with `LViewFlags.RefreshTransplantedView` that are
1482
+ * children or descendants of the given lView.
1483
+ *
1484
+ * @param lView The lView which contains descendant transplanted views that need to be refreshed.
1485
+ */
1486
+ function refreshContainsDirtyView(lView) {
1487
+ for (let lContainer = getFirstLContainer(lView); lContainer !== null; lContainer = getNextLContainer(lContainer)) {
1488
+ for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
1489
+ const embeddedLView = lContainer[i];
1490
+ if (embeddedLView[FLAGS] & 1024 /* RefreshTransplantedView */) {
1491
+ const embeddedTView = embeddedLView[TVIEW];
1492
+ ngDevMode && assertDefined(embeddedTView, 'TView must be allocated');
1493
+ refreshView(embeddedTView, embeddedLView, embeddedTView.template, embeddedLView[CONTEXT]);
1494
+ }
1495
+ else if (embeddedLView[TRANSPLANTED_VIEWS_TO_REFRESH] > 0) {
1496
+ refreshContainsDirtyView(embeddedLView);
1497
+ }
1498
+ }
1499
+ }
1500
+ const tView = lView[TVIEW];
1501
+ // Refresh child component views.
1502
+ const components = tView.components;
1503
+ if (components !== null) {
1504
+ for (let i = 0; i < components.length; i++) {
1505
+ const componentView = getComponentLViewByIndex(components[i], lView);
1506
+ // Only attached components that are CheckAlways or OnPush and dirty should be refreshed
1507
+ if (viewAttachedToChangeDetector(componentView) &&
1508
+ componentView[TRANSPLANTED_VIEWS_TO_REFRESH] > 0) {
1509
+ refreshContainsDirtyView(componentView);
1510
+ }
1511
+ }
1512
+ }
1513
+ }
1514
+ function renderComponent(hostLView, componentHostIdx) {
1515
+ ngDevMode && assertEqual(isCreationMode(hostLView), true, 'Should be run in creation mode');
1516
+ const componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
1517
+ const componentTView = componentView[TVIEW];
1518
+ syncViewWithBlueprint(componentTView, componentView);
1519
+ renderView(componentTView, componentView, componentView[CONTEXT]);
1520
+ }
1521
+ /**
1522
+ * Syncs an LView instance with its blueprint if they have gotten out of sync.
1523
+ *
1524
+ * Typically, blueprints and their view instances should always be in sync, so the loop here
1525
+ * will be skipped. However, consider this case of two components side-by-side:
1526
+ *
1527
+ * App template:
1528
+ * ```
1529
+ * <comp></comp>
1530
+ * <comp></comp>
1531
+ * ```
1532
+ *
1533
+ * The following will happen:
1534
+ * 1. App template begins processing.
1535
+ * 2. First <comp> is matched as a component and its LView is created.
1536
+ * 3. Second <comp> is matched as a component and its LView is created.
1537
+ * 4. App template completes processing, so it's time to check child templates.
1538
+ * 5. First <comp> template is checked. It has a directive, so its def is pushed to blueprint.
1539
+ * 6. Second <comp> template is checked. Its blueprint has been updated by the first
1540
+ * <comp> template, but its LView was created before this update, so it is out of sync.
1541
+ *
1542
+ * Note that embedded views inside ngFor loops will never be out of sync because these views
1543
+ * are processed as soon as they are created.
1544
+ *
1545
+ * @param tView The `TView` that contains the blueprint for syncing
1546
+ * @param lView The view to sync
1547
+ */
1548
+ function syncViewWithBlueprint(tView, lView) {
1549
+ for (let i = lView.length; i < tView.blueprint.length; i++) {
1550
+ lView.push(tView.blueprint[i]);
1551
+ }
1552
+ }
1553
+ /**
1554
+ * Adds LView or LContainer to the end of the current view tree.
1555
+ *
1556
+ * This structure will be used to traverse through nested views to remove listeners
1557
+ * and call onDestroy callbacks.
1558
+ *
1559
+ * @param lView The view where LView or LContainer should be added
1560
+ * @param adjustedHostIndex Index of the view's host node in LView[], adjusted for header
1561
+ * @param lViewOrLContainer The LView or LContainer to add to the view tree
1562
+ * @returns The state passed in
1563
+ */
1564
+ export function addToViewTree(lView, lViewOrLContainer) {
1565
+ // TODO(benlesh/misko): This implementation is incorrect, because it always adds the LContainer
1566
+ // to the end of the queue, which means if the developer retrieves the LContainers from RNodes out
1567
+ // of order, the change detection will run out of order, as the act of retrieving the the
1568
+ // LContainer from the RNode is what adds it to the queue.
1569
+ if (lView[CHILD_HEAD]) {
1570
+ lView[CHILD_TAIL][NEXT] = lViewOrLContainer;
1571
+ }
1572
+ else {
1573
+ lView[CHILD_HEAD] = lViewOrLContainer;
1574
+ }
1575
+ lView[CHILD_TAIL] = lViewOrLContainer;
1576
+ return lViewOrLContainer;
1577
+ }
1578
+ ///////////////////////////////
1579
+ //// Change detection
1580
+ ///////////////////////////////
1581
+ /**
1582
+ * Marks current view and all ancestors dirty.
1583
+ *
1584
+ * Returns the root view because it is found as a byproduct of marking the view tree
1585
+ * dirty, and can be used by methods that consume markViewDirty() to easily schedule
1586
+ * change detection. Otherwise, such methods would need to traverse up the view tree
1587
+ * an additional time to get the root view and schedule a tick on it.
1588
+ *
1589
+ * @param lView The starting LView to mark dirty
1590
+ * @returns the root LView
1591
+ */
1592
+ export function markViewDirty(lView) {
1593
+ while (lView) {
1594
+ lView[FLAGS] |= 64 /* Dirty */;
1595
+ const parent = getLViewParent(lView);
1596
+ // Stop traversing up as soon as you find a root view that wasn't attached to any container
1597
+ if (isRootView(lView) && !parent) {
1598
+ return lView;
1599
+ }
1600
+ // continue otherwise
1601
+ lView = parent;
1602
+ }
1603
+ return null;
1604
+ }
1605
+ /**
1606
+ * Used to schedule change detection on the whole application.
1607
+ *
1608
+ * Unlike `tick`, `scheduleTick` coalesces multiple calls into one change detection run.
1609
+ * It is usually called indirectly by calling `markDirty` when the view needs to be
1610
+ * re-rendered.
1611
+ *
1612
+ * Typically `scheduleTick` uses `requestAnimationFrame` to coalesce multiple
1613
+ * `scheduleTick` requests. The scheduling function can be overridden in
1614
+ * `renderComponent`'s `scheduler` option.
1615
+ */
1616
+ export function scheduleTick(rootContext, flags) {
1617
+ const nothingScheduled = rootContext.flags === 0 /* Empty */;
1618
+ if (nothingScheduled && rootContext.clean == _CLEAN_PROMISE) {
1619
+ // https://github.com/angular/angular/issues/39296
1620
+ // should only attach the flags when really scheduling a tick
1621
+ rootContext.flags |= flags;
1622
+ let res;
1623
+ rootContext.clean = new Promise((r) => res = r);
1624
+ rootContext.scheduler(() => {
1625
+ if (rootContext.flags & 1 /* DetectChanges */) {
1626
+ rootContext.flags &= ~1 /* DetectChanges */;
1627
+ tickRootContext(rootContext);
1628
+ }
1629
+ if (rootContext.flags & 2 /* FlushPlayers */) {
1630
+ rootContext.flags &= ~2 /* FlushPlayers */;
1631
+ const playerHandler = rootContext.playerHandler;
1632
+ if (playerHandler) {
1633
+ playerHandler.flushPlayers();
1634
+ }
1635
+ }
1636
+ rootContext.clean = _CLEAN_PROMISE;
1637
+ res(null);
1638
+ });
1639
+ }
1640
+ }
1641
+ export function tickRootContext(rootContext) {
1642
+ for (let i = 0; i < rootContext.components.length; i++) {
1643
+ const rootComponent = rootContext.components[i];
1644
+ const lView = readPatchedLView(rootComponent);
1645
+ const tView = lView[TVIEW];
1646
+ renderComponentOrTemplate(tView, lView, tView.template, rootComponent);
1647
+ }
1648
+ }
1649
+ export function detectChangesInternal(tView, lView, context) {
1650
+ const rendererFactory = lView[RENDERER_FACTORY];
1651
+ if (rendererFactory.begin)
1652
+ rendererFactory.begin();
1653
+ try {
1654
+ refreshView(tView, lView, tView.template, context);
1655
+ }
1656
+ catch (error) {
1657
+ handleError(lView, error);
1658
+ throw error;
1659
+ }
1660
+ finally {
1661
+ if (rendererFactory.end)
1662
+ rendererFactory.end();
1663
+ }
1664
+ }
1665
+ /**
1666
+ * Synchronously perform change detection on a root view and its components.
1667
+ *
1668
+ * @param lView The view which the change detection should be performed on.
1669
+ */
1670
+ export function detectChangesInRootView(lView) {
1671
+ tickRootContext(lView[CONTEXT]);
1672
+ }
1673
+ export function checkNoChangesInternal(tView, view, context) {
1674
+ setIsInCheckNoChangesMode(true);
1675
+ try {
1676
+ detectChangesInternal(tView, view, context);
1677
+ }
1678
+ finally {
1679
+ setIsInCheckNoChangesMode(false);
1680
+ }
1681
+ }
1682
+ /**
1683
+ * Checks the change detector on a root view and its components, and throws if any changes are
1684
+ * detected.
1685
+ *
1686
+ * This is used in development mode to verify that running change detection doesn't
1687
+ * introduce other changes.
1688
+ *
1689
+ * @param lView The view which the change detection should be checked on.
1690
+ */
1691
+ export function checkNoChangesInRootView(lView) {
1692
+ setIsInCheckNoChangesMode(true);
1693
+ try {
1694
+ detectChangesInRootView(lView);
1695
+ }
1696
+ finally {
1697
+ setIsInCheckNoChangesMode(false);
1698
+ }
1699
+ }
1700
+ function executeViewQueryFn(flags, viewQueryFn, component) {
1701
+ ngDevMode && assertDefined(viewQueryFn, 'View queries function to execute must be defined.');
1702
+ setCurrentQueryIndex(0);
1703
+ viewQueryFn(flags, component);
1704
+ }
1705
+ ///////////////////////////////
1706
+ //// Bindings & interpolations
1707
+ ///////////////////////////////
1708
+ /**
1709
+ * Stores meta-data for a property binding to be used by TestBed's `DebugElement.properties`.
1710
+ *
1711
+ * In order to support TestBed's `DebugElement.properties` we need to save, for each binding:
1712
+ * - a bound property name;
1713
+ * - a static parts of interpolated strings;
1714
+ *
1715
+ * A given property metadata is saved at the binding's index in the `TView.data` (in other words, a
1716
+ * property binding metadata will be stored in `TView.data` at the same index as a bound value in
1717
+ * `LView`). Metadata are represented as `INTERPOLATION_DELIMITER`-delimited string with the
1718
+ * following format:
1719
+ * - `propertyName` for bound properties;
1720
+ * - `propertyName�prefix�interpolation_static_part1�..interpolation_static_partN�suffix` for
1721
+ * interpolated properties.
1722
+ *
1723
+ * @param tData `TData` where meta-data will be saved;
1724
+ * @param tNode `TNode` that is a target of the binding;
1725
+ * @param propertyName bound property name;
1726
+ * @param bindingIndex binding index in `LView`
1727
+ * @param interpolationParts static interpolation parts (for property interpolations)
1728
+ */
1729
+ export function storePropertyBindingMetadata(tData, tNode, propertyName, bindingIndex, ...interpolationParts) {
1730
+ // Binding meta-data are stored only the first time a given property instruction is processed.
1731
+ // Since we don't have a concept of the "first update pass" we need to check for presence of the
1732
+ // binding meta-data to decide if one should be stored (or if was stored already).
1733
+ if (tData[bindingIndex] === null) {
1734
+ if (tNode.inputs == null || !tNode.inputs[propertyName]) {
1735
+ const propBindingIdxs = tNode.propertyBindings || (tNode.propertyBindings = []);
1736
+ propBindingIdxs.push(bindingIndex);
1737
+ let bindingMetadata = propertyName;
1738
+ if (interpolationParts.length > 0) {
1739
+ bindingMetadata +=
1740
+ INTERPOLATION_DELIMITER + interpolationParts.join(INTERPOLATION_DELIMITER);
1741
+ }
1742
+ tData[bindingIndex] = bindingMetadata;
1743
+ }
1744
+ }
1745
+ }
1746
+ export const CLEAN_PROMISE = _CLEAN_PROMISE;
1747
+ export function getOrCreateLViewCleanup(view) {
1748
+ // top level variables should not be exported for performance reasons (PERF_NOTES.md)
1749
+ return view[CLEANUP] || (view[CLEANUP] = ngDevMode ? new LCleanup() : []);
1750
+ }
1751
+ export function getOrCreateTViewCleanup(tView) {
1752
+ return tView.cleanup || (tView.cleanup = ngDevMode ? new TCleanup() : []);
1753
+ }
1754
+ /**
1755
+ * There are cases where the sub component's renderer needs to be included
1756
+ * instead of the current renderer (see the componentSyntheticHost* instructions).
1757
+ */
1758
+ export function loadComponentRenderer(currentDef, tNode, lView) {
1759
+ // TODO(FW-2043): the `currentDef` is null when host bindings are invoked while creating root
1760
+ // component (see packages/core/src/render3/component.ts). This is not consistent with the process
1761
+ // of creating inner components, when current directive index is available in the state. In order
1762
+ // to avoid relying on current def being `null` (thus special-casing root component creation), the
1763
+ // process of creating root component should be unified with the process of creating inner
1764
+ // components.
1765
+ if (currentDef === null || isComponentDef(currentDef)) {
1766
+ lView = unwrapLView(lView[tNode.index]);
1767
+ }
1768
+ return lView[RENDERER];
1769
+ }
1770
+ /** Handles an error thrown in an LView. */
1771
+ export function handleError(lView, error) {
1772
+ const injector = lView[INJECTOR];
1773
+ const errorHandler = injector ? injector.get(ErrorHandler, null) : null;
1774
+ errorHandler && errorHandler.handleError(error);
1775
+ }
1776
+ /**
1777
+ * Set the inputs of directives at the current node to corresponding value.
1778
+ *
1779
+ * @param tView The current TView
1780
+ * @param lView the `LView` which contains the directives.
1781
+ * @param inputs mapping between the public "input" name and privately-known,
1782
+ * possibly minified, property names to write to.
1783
+ * @param value Value to set.
1784
+ */
1785
+ export function setInputsForProperty(tView, lView, inputs, publicName, value) {
1786
+ for (let i = 0; i < inputs.length;) {
1787
+ const index = inputs[i++];
1788
+ const privateName = inputs[i++];
1789
+ const instance = lView[index];
1790
+ ngDevMode && assertIndexInRange(lView, index);
1791
+ const def = tView.data[index];
1792
+ if (def.setInput !== null) {
1793
+ def.setInput(instance, value, publicName, privateName);
1794
+ }
1795
+ else {
1796
+ instance[privateName] = value;
1797
+ }
1798
+ }
1799
+ }
1800
+ /**
1801
+ * Updates a text binding at a given index in a given LView.
1802
+ */
1803
+ export function textBindingInternal(lView, index, value) {
1804
+ ngDevMode && assertString(value, 'Value should be a string');
1805
+ ngDevMode && assertNotSame(value, NO_CHANGE, 'value should not be NO_CHANGE');
1806
+ ngDevMode && assertIndexInRange(lView, index);
1807
+ const element = getNativeByIndex(index, lView);
1808
+ ngDevMode && assertDefined(element, 'native element should exist');
1809
+ updateTextNode(lView[RENDERER], element, value);
1810
+ }
1811
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29yZS9zcmMvcmVuZGVyMy9pbnN0cnVjdGlvbnMvc2hhcmVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVFBLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUVqRCxPQUFPLEVBQUMsc0JBQXNCLEVBQUUsZ0JBQWdCLEVBQWlCLE1BQU0sdUJBQXVCLENBQUM7QUFDL0YsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUFDLDhCQUE4QixFQUFFLDhCQUE4QixFQUFDLE1BQU0saUNBQWlDLENBQUM7QUFFL0csT0FBTyxFQUFDLGFBQWEsRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLHdCQUF3QixFQUFFLGtCQUFrQixFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ25MLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ2pELE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLDZCQUE2QixDQUFDO0FBQ2pFLE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUMseUJBQXlCLEVBQUUsMEJBQTBCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUM1RixPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDL0MsT0FBTyxFQUFDLHFCQUFxQixFQUFFLHFCQUFxQixFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxtQkFBbUIsRUFBQyxNQUFNLFdBQVcsQ0FBQztBQUNoSixPQUFPLEVBQUMsZUFBZSxFQUFFLGdCQUFnQixFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDdkUsT0FBTyxFQUFDLGFBQWEsRUFB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QyxHQUFHLEtBQUssQ0FBQztTQUMvQjtLQUNGO0FBQ0gsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLEtBQVksRUFBRSxLQUFhLEVBQUUsS0FBYTtJQUM1RSxTQUFTLElBQUksWUFBWSxDQUFDLEtBQUssRUFBRSwwQkFBMEIsQ0FBQyxDQUFDO0lBQzdELFNBQVMsSUFBSSxhQUFhLENBQUMsS0FBSyxFQUFFLFNBQWdCLEVBQUUsK0JBQStCLENBQUMsQ0FBQztJQUNyRixTQUFTLElBQUksa0JBQWtCLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzlDLE1BQU0sT0FBTyxHQUFHLGdCQUFnQixDQUFDLEtBQUssRUFBRSxLQUFLLENBQWlCLENBQUM7SUFDL0QsU0FBUyxJQUFJLGFBQWEsQ0FBQyxPQUFPLEVBQUUsNkJBQTZCLENBQUMsQ0FBQztJQUNuRSxjQUFjLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNsRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5pbXBvcnQge0luamVjdG9yfSBmcm9tICcuLi8uLi9kaSc7XG5pbXBvcnQge0Vycm9ySGFuZGxlcn0gZnJvbSAnLi4vLi4vZXJyb3JfaGFuZGxlcic7XG5pbXBvcnQge0RvQ2hlY2ssIE9uQ2hhbmdlcywgT25Jbml0fSBmcm9tICcuLi8uLi9pbnRlcmZhY2UvbGlmZWN5Y2xlX2hvb2tzJztcbmltcG9ydCB7Q1VTVE9NX0VMRU1FTlRTX1NDSEVNQSwgTk9fRVJST1JTX1NDSEVNQSwgU2NoZW1hTWV0YWRhdGF9IGZyb20gJy4uLy4uL21ldGFkYXRhL3NjaGVtYSc7XG5pbXBvcnQge1ZpZXdFbmNhcHN1bGF0aW9ufSBmcm9tICcuLi8uLi9tZXRhZGF0YS92aWV3JztcbmltcG9ydCB7dmFsaWRhdGVBZ2FpbnN0RXZlbnRBdHRyaWJ1dGVzLCB2YWxpZGF0ZUFnYWluc3RFdmVudFByb3BlcnRpZXN9IGZyb20gJy4uLy4uL3Nhbml0aXphdGlvbi9zYW5pdGl6YXRpb24nO1xuaW1wb3J0IHtTYW5pdGl6ZXJ9IGZyb20gJy4uLy4uL3Nhbml0aXphdGlvbi9zYW5pdGl6ZXInO1xuaW1wb3J0IHthc3NlcnREZWZpbmVkLCBhc3NlcnREb21Ob2RlLCBhc3NlcnRFcXVhbCwgYXNzZXJ0R3JlYXRlclRoYW5PckVxdWFsLCBhc3NlcnRJbmRleEluUmFuZ2UsIGFzc2VydE5vdEVxdWFsLCBhc3NlcnROb3RTYW1lLCBhc3NlcnRTYW1lLCBhc3NlcnRTdHJpbmd9IGZyb20gJy4uLy4uL3V0aWwvYXNzZXJ0JztcbmltcG9ydCB7ZXNjYXBlQ29tbWVudFRleHR9IGZyb20gJy4uLy4uL3V0aWwvZG9tJztcbmltcG9ydCB7Y3JlYXRlTmFtZWRBcnJheVR5cGV9IGZyb20gJy4uLy4uL3V0aWwvbmFtZWRfYXJyYXlfdHlwZSc7XG5pbXBvcnQge2luaXROZ0Rldk1vZGV9IGZyb20gJy4uLy4uL3V0aWwvbmdfZGV2X21vZGUnO1xuaW1wb3J0IHtub3JtYWxpemVEZWJ1Z0JpbmRpbmdOYW1lLCBub3JtYWxpemVEZWJ1Z0JpbmRpbmdWYWx1ZX0gZnJvbSAnLi4vLi4vdXRpbC9uZ19yZWZsZWN0JztcbmltcG9ydCB7c3RyaW5naWZ5fSBmcm9tICcuLi8uLi91dGlsL3N0cmluZ2lmeSc7XG5pbXBvcnQge2Fzc2VydEZpcnN0Q3JlYXRlUGFzcywgYXNzZXJ0Rmlyc3RVcGRhdGVQYXNzLCBhc3NlcnRMQ29udGFpbmVyLCBhc3NlcnRMVmlldywgYXNzZXJ0VE5vZGVGb3JMVmlldywgYXNzZXJ0VE5vZGVGb3JUVmlld30gZnJvbSAnLi4vYXNzZXJ0JztcbmltcG9ydCB7YXR0YWNoUGF0Y2hEYXRhLCByZWFkUGF0Y2hlZExWaWV3fSBmcm9tICcuLi9jb250ZXh0X2Rpc2NvdmVyeSc7XG5pbXBvcnQge2dldEZhY3RvcnlEZWZ9IGZyb20gJy4uL2RlZmluaXRpb25fZmFjdG9yeSc7XG5pbXBvcnQge2RpUHVibGljSW5JbmplY3RvciwgZ2V0Tm9kZUluamVjdGFibGUsIGdldE9yQ3JlYXRlTm9kZUluamVjdG9yRm9yTm9kZX0gZnJvbSAnLi4vZGknO1xuaW1wb3J0IHtmb3JtYXRSdW50aW1lRXJyb3IsIFJ1bnRpbWVFcnJvciwgUnVudGltZUVycm9yQ29kZX0gZnJvbSAnLi4vZXJyb3JfY29kZSc7XG5pbXBvcnQge3Rocm93TXVsdGlwbGVDb21wb25lbnRFcnJvcn0gZnJvbSAnLi4vZXJyb3JzJztcbmltcG9ydCB7ZXhlY3V0ZUNoZWNrSG9va3MsIGV4ZWN1dGVJbml0QW5kQ2hlY2tIb29rcywgaW5jcmVtZW50SW5pdFBoYXNlRmxhZ3N9IGZyb20gJy4uL2hvb2tzJztcbmltcG9ydCB7Q09OVEFJTkVSX0hFQURFUl9PRkZTRVQsIEhBU19UUkFOU1BMQU5URURfVklFV1MsIExDb250YWluZXIsIE1PVkVEX1ZJRVdTfSBmcm9tICcuLi9pbnRlcmZhY2VzL2NvbnRhaW5lcic7XG5pbXBvcnQge0NvbXBvbmVudERlZiwgQ29tcG9uZW50VGVtcGxhdGUsIERpcmVjdGl2ZURlZiwgRGlyZWN0aXZlRGVmTGlzdE9yRmFjdG9yeSwgSG9zdEJpbmRpbmdzRnVuY3Rpb24sIFBpcGVEZWZMaXN0T3JGYWN0b3J5LCBSZW5kZXJGbGFncywgVmlld1F1ZXJpZXNGdW5jdGlvbn0gZnJvbSAnLi4vaW50ZXJmYWNlcy9kZWZpbml0aW9uJztcbmltcG9ydCB7Tm9kZUluamVjdG9yRmFjdG9yeX0gZnJvbSAnLi4vaW50ZXJmYWNlcy9pbmplY3Rvcic7XG5pbXBvcnQge0F0dHJpYnV0ZU1hcmtlciwgSW5pdGlhbElucHV0RGF0YSwgSW5pdGlhbElucHV0cywgTG9jYWxSZWZFeHRyYWN0b3IsIFByb3BlcnR5QWxpYXNlcywgUHJvcGVydHlBbGlhc1ZhbHVlLCBUQXR0cmlidXRlcywgVENvbnN0YW50c09yRmFjdG9yeSwgVENvbnRhaW5lck5vZGUsIFREaXJlY3RpdmVIb3N0Tm9kZSwgVEVsZW1lbnRDb250YWluZXJOb2RlLCBURWxlbWVudE5vZGUsIFRJY3VDb250YWluZXJOb2RlLCBUTm9kZSwgVE5vZGVGbGFncywgVE5vZGVUeXBlLCBUUHJvamVjdGlvbk5vZGV9IGZyb20gJy4uL2ludGVyZmFjZXMvbm9kZSc7XG5pbXBvcnQge2lzUHJvY2VkdXJhbFJlbmRlcmVyLCBSZW5kZXJlcjMsIFJlbmRlcmVyRmFjdG9yeTN9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVuZGVyZXInO1xuaW1wb3J0IHtSQ29tbWVudCwgUkVsZW1lbnQsIFJOb2RlLCBSVGV4dH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZW5kZXJlcl9kb20nO1xuaW1wb3J0IHtTYW5pdGl6ZXJGbn0gZnJvbSAnLi4vaW50ZXJmYWNlcy9zYW5pdGl6YXRpb24nO1xuaW1wb3J0IHtpc0NvbXBvbmVudERlZiwgaXNDb21wb25lbnRIb3N0LCBpc0NvbnRlbnRRdWVyeUhvc3QsIGlzUm9vdFZpZXd9IGZyb20gJy4uL2ludGVyZmFjZXMvdHlwZV9jaGVja3MnO1xuaW1wb3J0IHtDSElMRF9IRUFELCBDSElMRF9UQUlMLCBDTEVBTlVQLCBDT05URVhULCBERUNMQVJBVElPTl9DT01QT05FTlRfVklFVywgREVDTEFSQVRJT05fVklFVywgRkxBR1MsIEhFQURFUl9PRkZTRVQsIEhPU1QsIEhvc3RCaW5kaW5nT3BDb2RlcywgSW5pdFBoYXNlU3RhdGUsIElOSkVDVE9SLCBMVmlldywgTFZpZXdGbGFncywgTkVYVCwgUEFSRU5ULCBSRU5ERVJFUiwgUkVOREVSRVJfRkFDVE9SWSwgUm9vdENvbnRleHQsIFJvb3RDb250ZXh0RmxhZ3MsIFNBTklUSVpFUiwgVF9IT1NULCBURGF0YSwgVFJBTlNQTEFOVEVEX1ZJRVdTX1RPX1JFRlJFU0gsIFRWSUVXLCBUVmlldywgVFZpZXdUeXBlfSBmcm9tICcuLi9pbnRlcmZhY2VzL3ZpZXcnO1xuaW1wb3J0IHthc3NlcnRQdXJlVE5vZGVUeXBlLCBhc3NlcnRUTm9kZVR5cGV9IGZyb20gJy4uL25vZGVfYXNzZXJ0JztcbmltcG9ydCB7dXBkYXRlVGV4dE5vZGV9IGZyb20gJy4uL25vZGVfbWFuaXB1bGF0aW9uJztcbmltcG9ydCB7aXNJbmxpbmVUZW1wbGF0ZSwgaXNOb2RlTWF0Y2hpbmdTZWxlY3Rvckxpc3R9IGZyb20gJy4uL25vZGVfc2VsZWN0b3JfbWF0Y2hlcic7XG5pbXBvcnQge3Byb2ZpbGVyLCBQcm9maWxlckV2ZW50fSBmcm9tICcuLi9wcm9maWxlcic7XG5pbXBvcnQge2VudGVyVmlldywgZ2V0QmluZGluZ3NFbmFibGVkLCBnZXRDdXJyZW50RGlyZWN0aXZlSW5kZXgsIGdldEN1cnJlbnRQYXJlbnRUTm9kZSwgZ2V0Q3VycmVudFROb2RlLCBnZXRDdXJyZW50VE5vZGVQbGFjZWhvbGRlck9rLCBnZXRTZWxlY3RlZEluZGV4LCBpc0N1cnJlbnRUTm9kZVBhcmVudCwgaXNJbkNoZWNrTm9DaGFuZ2VzTW9kZSwgaXNJbkkxOG5CbG9jaywgbGVhdmVWaWV3LCBzZXRCaW5kaW5nSW5kZXgsIHNldEJpbmRpbmdSb290Rm9ySG9zdEJpbmRpbmdzLCBzZXRDdXJyZW50RGlyZWN0aXZlSW5kZXgsIHNldEN1cnJlbnRRdWVyeUluZGV4LCBzZXRDdXJyZW50VE5vZGUsIHNldElzSW5DaGVja05vQ2hhbmdlc01vZGUsIHNldFNlbGVjdGVkSW5kZXh9IGZyb20gJy4uL3N0YXRlJztcbmltcG9ydCB7Tk9fQ0hBTkdFfSBmcm9tICcuLi90b2tlbnMnO1xuaW1wb3J0IHtpc0FuaW1hdGlvblByb3AsIG1lcmdlSG9zdEF0dHJzfSBmcm9tICcuLi91dGlsL2F0dHJzX3V0aWxzJztcbmltcG9ydCB7SU5URVJQT0xBVElPTl9ERUxJTUlURVJ9IGZyb20gJy4uL3V0aWwvbWlzY191dGlscyc7XG5pbXBvcnQge3JlbmRlclN0cmluZ2lmeSwgc3RyaW5naWZ5Rm9yRXJyb3J9IGZyb20gJy4uL3V0aWwvc3RyaW5naWZ5X3V0aWxzJztcbmltcG9ydCB7Z2V0Rmlyc3RMQ29udGFpbmVyLCBnZXRMVmlld1BhcmVudCwgZ2V0TmV4dExDb250YWluZXJ9IGZyb20gJy4uL3V0aWwvdmlld190cmF2ZXJzYWxfdXRpbHMnO1xuaW1wb3J0IHtnZXRDb21wb25lbnRMVmlld0J5SW5kZXgsIGdldE5hdGl2ZUJ5SW5kZXgsIGdldE5hdGl2ZUJ5VE5vZGUsIGlzQ3JlYXRpb25Nb2RlLCByZXNldFByZU9yZGVySG9va0ZsYWdzLCB1bndyYXBMVmlldywgdXBkYXRlVHJhbnNwbGFudGVkVmlld0NvdW50LCB2aWV3QXR0YWNoZWRUb0NoYW5nZURldGVjdG9yfSBmcm9tICcuLi91dGlsL3ZpZXdfdXRpbHMnO1xuXG5pbXBvcnQge3NlbGVjdEluZGV4SW50ZXJuYWx9IGZyb20gJy4vYWR2YW5jZSc7XG5pbXBvcnQge2F0dGFjaExDb250YWluZXJEZWJ1ZywgYXR0YWNoTFZpZXdEZWJ1ZywgY2xvbmVUb0xWaWV3RnJvbVRWaWV3Qmx1ZXByaW50LCBjbG9uZVRvVFZpZXdEYXRhLCBMQ2xlYW51cCwgTFZpZXdCbHVlcHJpbnQsIE1hdGNoZXNBcnJheSwgVENsZWFudXAsIFROb2RlRGVidWcsIFROb2RlSW5pdGlhbElucHV0cywgVE5vZGVMb2NhbE5hbWVzLCBUVmlld0NvbXBvbmVudHMsIFRWaWV3Q29uc3RydWN0b3J9IGZyb20gJy4vbHZpZXdfZGVidWcnO1xuXG5cblxuLyoqXG4gKiBBIHBlcm1hbmVudCBtYXJrZXIgcHJvbWlzZSB3aGljaCBzaWduaWZpZXMgdGhhdCB0aGUgY3VycmVudCBDRCB0cmVlIGlzXG4gKiBjbGVhbi5cbiAqL1xuY29uc3QgX0NMRUFOX1BST01JU0UgPSAoKCkgPT4gUHJvbWlzZS5yZXNvbHZlKG51bGwpKSgpO1xuXG4vKipcbiAqIEludm9rZSBgSG9zdEJpbmRpbmdzRnVuY3Rpb25gcyBmb3Igdmlldy5cbiAqXG4gKiBUaGlzIG1ldGhvZHMgZXhlY3V0ZXMgYFRWaWV3Lmhvc3RCaW5kaW5nT3BDb2Rlc2AuIEl0IGlzIHVzZWQgdG8gZXhlY3V0ZSB0aGVcbiAqIGBIb3N0QmluZGluZ3NGdW5jdGlvbmBzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY3VycmVudCBgTFZpZXdgLlxuICpcbiAqIEBwYXJhbSB0VmlldyBDdXJyZW50IGBUVmlld2AuXG4gKiBAcGFyYW0gbFZpZXcgQ3VycmVudCBgTFZpZXdgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvY2Vzc0hvc3RCaW5kaW5nT3BDb2Rlcyh0VmlldzogVFZpZXcsIGxWaWV3OiBMVmlldyk6IHZvaWQge1xuICBjb25zdCBob3N0QmluZGluZ09wQ29kZXMgPSB0Vmlldy5ob3N0QmluZGluZ09wQ29kZXM7XG4gIGlmIChob3N0QmluZGluZ09wQ29kZXMgPT09IG51bGwpIHJldHVybjtcbiAgdHJ5IHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhvc3RCaW5kaW5nT3BDb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgb3BDb2RlID0gaG9zdEJpbmRpbmdPcENvZGVzW2ldIGFzIG51bWJlcjtcbiAgICAgIGlmIChvcENvZGUgPCAwKSB7XG4gICAgICAgIC8vIE5lZ2F0aXZlIG51bWJlcnMgYXJlIGVsZW1lbnQgaW5kZXhlcy5cbiAgICAgICAgc2V0U2VsZWN0ZWRJbmRleCh+b3BDb2RlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFBvc2l0aXZlIG51bWJlcnMgYXJlIE51bWJlclR1cGxlIHdoaWNoIHN0b3JlIGJpbmRpbmdSb290SW5kZXggYW5kIGRpcmVjdGl2ZUluZGV4LlxuICAgICAgICBjb25zdCBkaXJlY3RpdmVJZHggPSBvcENvZGU7XG4gICAgICAgIGNvbnN0IGJpbmRpbmdSb290SW5keCA9IGhvc3RCaW5kaW5nT3BDb2Rlc1srK2ldIGFzIG51bWJlcjtcbiAgICAgICAgY29uc3QgaG9zdEJpbmRpbmdGbiA9IGhvc3RCaW5kaW5nT3BDb2Rlc1srK2ldIGFzIEhvc3RCaW5kaW5nc0Z1bmN0aW9uPGFueT47XG4gICAgICAgIHNldEJpbmRpbmdSb290Rm9ySG9zdEJpbmRpbmdzKGJpbmRpbmdSb290SW5keCwgZGlyZWN0aXZlSWR4KTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IGxWaWV3W2RpcmVjdGl2ZUlkeF07XG4gICAgICAgIGhvc3RCaW5kaW5nRm4oUmVuZGVyRmxhZ3MuVXBkYXRlLCBjb250ZXh0KTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZmluYWxseSB7XG4gICAgc2V0U2VsZWN0ZWRJbmRleCgtMSk7XG4gIH1cbn1cblxuXG4vKiogUmVmcmVzaGVzIGFsbCBjb250ZW50IHF1ZXJpZXMgZGVjbGFyZWQgYnkgZGlyZWN0aXZlcyBpbiBhIGdpdmVuIHZpZXcgKi9cbmZ1bmN0aW9uIHJlZnJlc2hDb250ZW50UXVlcmllcyh0VmlldzogVFZpZXcsIGxWaWV3OiBMVmlldyk6IHZvaWQge1xuICBjb25zdCBjb250ZW50UXVlcmllcyA9IHRWaWV3LmNvbnRlbnRRdWVyaWVzO1xuICBpZiAoY29udGVudFF1ZXJpZXMgIT09IG51bGwpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbnRlbnRRdWVyaWVzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgICBjb25zdCBxdWVyeVN0YXJ0SWR4ID0gY29udGVudFF1ZXJpZXNbaV07XG4gICAgICBjb25zdCBkaXJlY3RpdmVEZWZJZHggPSBjb250ZW50UXVlcmllc1tpICsgMV07XG4gICAgICBpZiAoZGlyZWN0aXZlRGVmSWR4ICE9PSAtMSkge1xuICAgICAgICBjb25zdCBkaXJlY3RpdmVEZWYgPSB0Vmlldy5kYXRhW2RpcmVjdGl2ZURlZklkeF0gYXMgRGlyZWN0aXZlRGVmPGFueT47XG4gICAgICAgIG5nRGV2TW9kZSAmJiBhc3NlcnREZWZpbmVkKGRpcmVjdGl2ZURlZiwgJ0RpcmVjdGl2ZURlZiBub3QgZm91bmQuJyk7XG4gICAgICAgIG5nRGV2TW9kZSAmJlxuICAgICAgICAgICAgYXNzZXJ0RGVmaW5lZChkaXJlY3RpdmVEZWYuY29udGVudFF1ZXJpZXMsICdjb250ZW50UXVlcmllcyBmdW5jdGlvbiBzaG91bGQgYmUgZGVmaW5lZCcpO1xuICAgICAgICBzZXRDdXJyZW50UXVlcnlJbmRleChxdWVyeVN0YXJ0SWR4KTtcbiAgICAgICAgZGlyZWN0aXZlRGVmLmNvbnRlbnRRdWVyaWVzIShSZW5kZXJGbGFncy5VcGRhdGUsIGxWaWV3W2RpcmVjdGl2ZURlZklkeF0sIGRpcmVjdGl2ZURlZklkeCk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKiBSZWZyZXNoZXMgY2hpbGQgY29tcG9uZW50cyBpbiB0aGUgY3VycmVudCB2aWV3ICh1cGRhdGUgbW9kZSkuICovXG5mdW5jdGlvbiByZWZyZXNoQ2hpbGRDb21wb25lbnRzKGhvc3RMVmlldzogTFZpZXcsIGNvbXBvbmVudHM6IG51bWJlcltdKTogdm9pZCB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY29tcG9uZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHJlZnJlc2hDb21wb25lbnQoaG9zdExWaWV3LCBjb21wb25lbnRzW2ldKTtcbiAgfVxufVxuXG4vKiogUmVuZGVycyBjaGlsZCBjb21wb25lbnRzIGluIHRoZSBjdXJyZW50IHZpZXcgKGNyZWF0aW9uIG1vZGUpLiAqL1xuZnVuY3Rpb24gcmVuZGVyQ2hpbGRDb21wb25lbnRzKGhvc3RMVmlldzogTFZpZXcsIGNvbXBvbmVudHM6IG51bWJlcltdKTogdm9pZCB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY29tcG9uZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHJlbmRlckNvbXBvbmVudChob3N0TFZpZXcsIGNvbXBvbmVudHNbaV0pO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVMVmlldzxUPihcbiAgICBwYXJlbnRMVmlldzogTFZpZXd8bnVsbCwgdFZpZXc6IFRWaWV3LCBjb250ZXh0OiBUfG51bGwsIGZsYWdzOiBMVmlld0ZsYWdzLCBob3N0OiBSRWxlbWVudHxudWxsLFxuICAgIHRIb3N0Tm9kZTogVE5vZGV8bnVsbCwgcmVuZGVyZXJGYWN0b3J5OiBSZW5kZXJlckZhY3RvcnkzfG51bGwsIHJlbmRlcmVyOiBSZW5kZXJlcjN8bnVsbCxcbiAgICBzYW5pdGl6ZXI6IFNhbml0aXplcnxudWxsLCBpbmplY3RvcjogSW5qZWN0b3J8bnVsbCk6IExWaWV3IHtcbiAgY29uc3QgbFZpZXcgPVxuICAgICAgbmdEZXZNb2RlID8gY2xvbmVUb0xWaWV3RnJvbVRWaWV3Qmx1ZXByaW50KHRWaWV3KSA6IHRWaWV3LmJsdWVwcmludC5zbGljZSgpIGFzIExWaWV3O1xuICBsVmlld1tIT1NUXSA9IGhvc3Q7XG4gIGxWaWV3W0ZMQUdTXSA9IGZsYWdzIHwgTFZpZXdGbGFncy5DcmVhdGlvbk1vZGUgfCBMVmlld0ZsYWdzLkF0dGFjaGVkIHwgTFZpZXdGbGFncy5GaXJzdExWaWV3UGFzcztcbiAgcmVzZXRQcmVPcmRlckhvb2tGbGFncyhsVmlldyk7XG4gIG5nRGV2TW9kZSAmJiB0Vmlldy5kZWNsVE5vZGUgJiYgcGFyZW50TFZpZXcgJiYgYXNzZXJ0VE5vZGVGb3JMVmlldyh0Vmlldy5kZWNsVE5vZGUsIHBhcmVudExWaWV3KTtcbiAgbFZpZXdbUEFSRU5UXSA9IGxWaWV3W0RFQ0xBUkFUSU9OX1ZJRVddID0gcGFyZW50TFZpZXc7XG4gIGxWaWV3W0NPTlRFWFRdID0gY29udGV4dDtcbiAgbFZpZXdbUkVOREVSRVJfRkFDVE9SWV0gPSAocmVuZGVyZXJGYWN0b3J5IHx8IHBhcmVudExWaWV3ICYmIHBhcmVudExWaWV3W1JFTkRFUkVSX0ZBQ1RPUlldKSE7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnREZWZpbmVkKGxWaWV3W1JFTkRFUkVSX0ZBQ1RPUlldLCAnUmVuZGVyZXJGYWN0b3J5IGlzIHJlcXVpcmVkJyk7XG4gIGxWaWV3W1JFTkRFUkVSXSA9IChyZW5kZXJlciB8fCBwYXJlbnRMVmlldyAmJiBwYXJlbnRMVmlld1tSRU5ERVJFUl0pITtcbiAgbmdEZXZNb2RlICYmIGFzc2VydERlZmluZWQobFZpZXdbUkVOREVSRVJdLCAnUmVuZGVyZXIgaXMgcmVxdWlyZWQnKTtcbiAgbFZpZXdbU0FOSVRJWkVSXSA9IHNhbml0aXplciB8fCBwYXJlbnRMVmlldyAmJiBwYXJlbnRMVmlld1tTQU5JVElaRVJdIHx8IG51bGwhO1xuICBsVmlld1tJTkpFQ1RPUiBhcyBhbnldID0gaW5qZWN0b3IgfHwgcGFyZW50TFZpZXcgJiYgcGFyZW50TFZpZXdbSU5KRUNUT1JdIHx8IG51bGw7XG4gIGxWaWV3W1RfSE9TVF0gPSB0SG9zdE5vZGU7XG4gIG5nRGV2TW9kZSAmJlxuICAgICAgYXNzZXJ0RXF1YWwoXG4gICAgICAgICAgdFZpZXcudHlwZSA9PSBUVmlld1R5cGUuRW1iZWRkZWQgPyBwYXJlbnRMVmlldyAhPT0gbnVsbCA6IHRydWUsIHRydWUsXG4gICAgICAgICAgJ0VtYmVkZGVkIHZpZXdzIG11c3QgaGF2ZSBwYXJlbnRMVmlldycpO1xuICBsVmlld1tERUNMQVJBVElPTl9DT01QT05FTlRfVklFV10gPVxuICAgICAgdFZpZXcudHlwZSA9PSBUVmlld1R5cGUuRW1iZWRkZWQgPyBwYXJlbnRMVmlldyFbREVDTEFSQVRJT05fQ09NUE9ORU5UX1ZJRVddIDogbFZpZXc7XG4gIG5nRGV2TW9kZSAmJiBhdHRhY2hMVmlld0RlYnVnKGxWaWV3KTtcbiAgcmV0dXJuIGxWaWV3O1xufVxuXG4vKipcbiAqIENyZWF0ZSBhbmQgc3RvcmVzIHRoZSBUTm9kZSwgYW5kIGhvb2tzIGl0IHVwIHRvIHRoZSB0cmVlLlxuICpcbiAqIEBwYXJhbSB0VmlldyBUaGUgY3VycmVudCBgVFZpZXdgLlxuICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBhdCB3aGljaCB0aGUgVE5vZGUgc2hvdWxkIGJlIHNhdmVkIChudWxsIGlmIHZpZXcsIHNpbmNlIHRoZXkgYXJlIG5vdFxuICogc2F2ZWQpLlxuICogQHBhcmFtIHR5cGUgVGhlIHR5cGUgb2YgVE5vZGUgdG8gY3JlYXRlXG4gKiBAcGFyYW0gbmF0aXZlIFRoZSBuYXRpdmUgZWxlbWVudCBmb3IgdGhpcyBub2RlLCBpZiBhcHBsaWNhYmxlXG4gKiBAcGFyYW0gbmFtZSBUaGUgdGFnIG5hbWUgb2YgdGhlIGFzc29jaWF0ZWQgbmF0aXZlIGVsZW1lbnQsIGlmIGFwcGxpY2FibGVcbiAqIEBwYXJhbSBhdHRycyBBbnkgYXR0cnMgZm9yIHRoZSBuYXRpdmUgZWxlbWVudCwgaWYgYXBwbGljYWJsZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0T3JDcmVhdGVUTm9kZShcbiAgICB0VmlldzogVFZpZXcsIGluZGV4OiBudW1iZXIsIHR5cGU6IFROb2RlVHlwZS5FbGVtZW50fFROb2RlVHlwZS5UZXh0LCBuYW1lOiBzdHJpbmd8bnVsbCxcbiAgICBhdHRyczogVEF0dHJpYnV0ZXN8bnVsbCk6IFRFbGVtZW50Tm9kZTtcbmV4cG9ydCBmdW5jdGlvbiBnZXRPckNyZWF0ZVROb2RlKFxuICAgIHRWaWV3OiBUVmlldywgaW5kZXg6IG51bWJlciwgdHlwZTogVE5vZGVUeXBlLkNvbnRhaW5lciwgbmFtZTogc3RyaW5nfG51bGwsXG4gICAgYXR0cnM6IFRBdHRyaWJ1dGVzfG51bGwpOiBUQ29udGFpbmVyTm9kZTtcbmV4cG9ydCBmdW5jdGlvbiBnZXRPckNyZWF0ZVROb2RlKFxuICAgIHRWaWV3OiBUVmlldywgaW5kZXg6IG51bWJlciwgdHlwZTogVE5vZGVUeXBlLlByb2plY3Rpb24sIG5hbWU6IG51bGwsXG4gICAgYXR0cnM6IFRBdHRyaWJ1dGVzfG51bGwpOiBUUHJvamVjdGlvbk5vZGU7XG5leHBvcnQgZnVuY3Rpb24gZ2V0T3JDcmVhdGVUTm9kZShcbiAgICB0VmlldzogVFZpZXcsIGluZGV4OiBudW1iZXIsIHR5cGU6IFROb2RlVHlwZS5FbGVtZW50Q29udGFpbmVyLCBuYW1lOiBzdHJpbmd8bnVsbCxcbiAgICBhdHRyczogVEF0dHJpYnV0ZXN8bnVsbCk6IFRFbGVtZW50Q29udGFpbmVyTm9kZTtcbmV4cG9ydCBmdW5jdGlvbiBnZXRPckNyZWF0ZVROb2RlKFxuICAgIHRWaWV3OiBUVmlldywgaW5kZXg6IG51bWJlciwgdHlwZTogVE5vZGVUeXBlLkljdSwgbmFtZTogbnVsbCxcbiAgICBhdHRyczogVEF0dHJpYnV0ZXN8bnVsbCk6IFRFbGVtZW50Q29udGFpbmVyTm9kZTtcbmV4cG9ydCBmdW5jdGlvbiBnZXRPckNyZWF0ZVROb2RlKFxuICAgIHRWaWV3OiBUVmlldywgaW5kZXg6IG51bWJlciwgdHlwZTogVE5vZGVUeXBlLCBuYW1lOiBzdHJpbmd8bnVsbCwgYXR0cnM6IFRBdHRyaWJ1dGVzfG51bGwpOlxuICAgIFRFbGVtZW50Tm9kZSZUQ29udGFpbmVyTm9kZSZURWxlbWVudENvbnRhaW5lck5vZGUmVFByb2plY3Rpb25Ob2RlJlRJY3VDb250YWluZXJOb2RlIHtcbiAgbmdEZXZNb2RlICYmIGluZGV4ICE9PSAwICYmICAvLyAwIGFyZSBib2d1cyBub2RlcyBhbmQgdGhleSBhcmUgT0suIFNlZSBgY3JlYXRlQ29udGFpbmVyUmVmYCBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGB2aWV3X2VuZ2luZV9jb21wYXRpYmlsaXR5YCBmb3IgYWRkaXRpb25hbCBjb250ZXh0LlxuICAgICAgYXNzZXJ0R3JlYXRlclRoYW5PckVxdWFsKGluZGV4LCBIRUFERVJfT0ZGU0VULCAnVE5vZGVzIGNhblxcJ3QgYmUgaW4gdGhlIExWaWV3IGhlYWRlci4nKTtcbiAgLy8gS2VlcCB0aGlzIGZ1bmN0aW9uIHNob3J0LCBzbyB0aGF0IHRoZSBWTSB3aWxsIGlubGluZSBpdC5cbiAgbmdEZXZNb2RlICYmIGFzc2VydFB1cmVUTm9kZVR5cGUodHlwZSk7XG4gIGxldCB0Tm9kZSA9IHRWaWV3LmRhdGFbaW5kZXhdIGFzIFROb2RlO1xuICBpZiAodE5vZGUgPT09IG51bGwpIHtcbiAgICB0Tm9kZSA9IGNyZWF0ZVROb2RlQXRJbmRleCh0VmlldywgaW5kZXgsIHR5cGUsIG5hbWUsIGF0dHJzKTtcbiAgICBpZiAoaXNJbkkxOG5CbG9jaygpKSB7XG4gICAgICAvLyBJZiB3ZSBhcmUgaW4gaTE4biBibG9jayB0aGVuIGFsbCBlbGVtZW50cyBzaG91bGQgYmUgcHJlIGRlY2xhcmVkIHRocm91Z2ggYFBsYWNlaG9sZGVyYFxuICAgICAgLy8gU2VlIGBUTm9kZVR5cGUuUGxhY2Vob2xkZXJgIGFuZCBgTEZyYW1lLmluSTE4bmAgZm9yIG1vcmUgY29udGV4dC5cbiAgICAgIC8vIElmIHRoZSBgVE5vZGVgIHdhcyBub3QgcHJlLWRlY2xhcmVkIHRoYW4gaXQgbWVhbnMgaXQgd2FzIG5vdCBtZW50aW9uZWQgd2hpY2ggbWVhbnMgaXQgd2FzXG4gICAgICAvLyByZW1vdmVkLCBzbyB3ZSBtYXJrIGl0IGFzIGRldGFjaGVkLlxuICAgICAgdE5vZGUuZmxhZ3MgfD0gVE5vZGVGbGFncy5pc0RldGFjaGVkO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0Tm9kZS50eXBlICYgVE5vZGVUeXBlLlBsYWNlaG9sZGVyKSB7XG4gICAgdE5vZGUudHlwZSA9IHR5cGU7XG4gICAgdE5vZGUudmFsdWUgPSBuYW1lO1xuICAgIHROb2RlLmF0dHJzID0gYXR0cnM7XG4gICAgY29uc3QgcGFyZW50ID0gZ2V0Q3VycmVudFBhcmVudFROb2RlKCk7XG4gICAgdE5vZGUuaW5qZWN0b3JJbmRleCA9IHBhcmVudCA9PT0gbnVsbCA/IC0xIDogcGFyZW50LmluamVjdG9ySW5kZXg7XG4gICAgbmdEZXZNb2RlICYmIGFzc2VydFROb2RlRm9yVFZpZXcodE5vZGUsIHRWaWV3KTtcbiAgICBuZ0Rldk1vZGUgJiYgYXNzZXJ0RXF1YWwoaW5kZXgsIHROb2RlLmluZGV4LCAnRXhwZWN0aW5nIHNhbWUgaW5kZXgnKTtcbiAgfVxuICBzZXRDdXJyZW50VE5vZGUodE5vZGUsIHRydWUpO1xuICByZXR1cm4gdE5vZGUgYXMgVEVsZW1lbnROb2RlICYgVENvbnRhaW5lck5vZGUgJiBURWxlbWVudENvbnRhaW5lck5vZGUgJiBUUHJvamVjdGlvbk5vZGUgJlxuICAgICAgVEljdUNvbnRhaW5lck5vZGU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUTm9kZUF0SW5kZXgoXG4gICAgdFZpZXc6IFRWaWV3LCBpbmRleDogbnVtYmVyLCB0eXBlOiBUTm9kZVR5cGUsIG5hbWU6IHN0cmluZ3xudWxsLCBhdHRyczogVEF0dHJpYnV0ZXN8bnVsbCkge1xuICBjb25zdCBjdXJyZW50VE5vZGUgPSBnZXRDdXJyZW50VE5vZGVQbGFjZWhvbGRlck9rKCk7XG4gIGNvbnN0IGlzUGFyZW50ID0gaXNDdXJyZW50VE5vZGVQYXJlbnQoKTtcbiAgY29uc3QgcGFyZW50ID0gaXNQYXJlbnQgPyBjdXJyZW50VE5vZGUgOiBjdXJyZW50VE5vZGUgJiYgY3VycmVudFROb2RlLnBhcmVudDtcbiAgLy8gUGFyZW50cyBjYW5ub3QgY3Jvc3MgY29tcG9uZW50IGJvdW5kYXJpZXMgYmVjYXVzZSBjb21wb25lbnRzIHdpbGwgYmUgdXNlZCBpbiBtdWx0aXBsZSBwbGFjZXMuXG4gIGNvbnN0IHROb2RlID0gdFZpZXcuZGF0YVtpbmRleF0gPVxuICAgICAgY3JlYXRlVE5vZGUodFZpZXcsIHBhcmVudCBhcyBURWxlbWVudE5vZGUgfCBUQ29udGFpbmVyTm9kZSwgdHlwZSwgaW5kZXgsIG5hbWUsIGF0dHJzKTtcbiAgLy8gQXNzaWduIGEgcG9pbnRlciB0byB0aGUgZmlyc3QgY2hpbGQgbm9kZSBvZiBhIGdpdmVuIHZpZXcuIFRoZSBmaXJzdCBub2RlIGlzIG5vdCBhbHdheXMgdGhlIG9uZVxuICAvLyBhdCBpbmRleCAwLCBpbiBjYXNlIG9mIGkxOG4sIGluZGV4IDAgY2FuIGJlIHRoZSBpbnN0cnVjdGlvbiBgaTE4blN0YXJ0YCBhbmQgdGhlIGZpcnN0IG5vZGUgaGFzXG4gIC8vIHRoZSBpbmRleCAxIG9yIG1vcmUsIHNvIHdlIGNhbid0IGp1c3QgY2hlY2sgbm9kZSBpbmRleC5cbiAgaWYgKHRWaWV3LmZpcnN0Q2hpbGQgPT09IG51bGwpIHtcbiAgICB0Vmlldy5maXJzdENoaWxkID0gdE5vZGU7XG4gIH1cbiAgaWYgKGN1cnJlbnRUTm9kZSAhPT0gbnVsbCkge1xuICAgIGlmIChpc1BhcmVudCkge1xuICAgICAgLy8gRklYTUUobWlza28pOiBUaGlzIGxvZ2ljIGxvb2tzIHVubmVjZXNzYXJpbHkgY29tcGxpY2F0ZWQuIENvdWxkIHdlIHNpbXBsaWZ5P1xuICAgICAgaWYgKGN1cnJlbnRUTm9kZS5jaGlsZCA9PSBudWxsICYmIHROb2RlLnBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAvLyBXZSBhcmUgaW4gdGhlIHNhbWUgdmlldywgd2hpY2ggbWVhbnMgd2UgYXJlIGFkZGluZyBjb250ZW50IG5vZGUgdG8gdGhlIHBhcmVudCB2aWV3LlxuICAgICAgICBjdXJyZW50VE5vZGUuY2hpbGQgPSB0Tm9kZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGN1cnJlbnRUTm9kZS5uZXh0ID09PSBudWxsKSB7XG4gICAgICAgIC8vIEluIHRoZSBjYXNlIG9mIGkxOG4gdGhlIGBjdXJyZW50VE5vZGVgIG1heSBhbHJlYWR5IGJlIGxpbmtlZCwgaW4gd2hpY2ggY2FzZSB3ZSBkb24ndCB3YW50XG4gICAgICAgIC8vIHRvIGJyZWFrIHRoZSBsaW5rcyB3aGljaCBpMThuIGNyZWF0ZWQuXG4gICAgICAgIGN1cnJlbnRUTm9kZS5uZXh0ID0gdE5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB0Tm9kZTtcbn1cblxuXG4vKipcbiAqIFdoZW4gZWxlbWVudHMgYXJlIGNyZWF0ZWQgZHluYW1pY2FsbHkgYWZ0ZXIgYSB2aWV3IGJsdWVwcmludCBpcyBjcmVhdGVkIChlLmcuIHRocm91Z2hcbiAqIGkxOG5BcHBseSgpKSwgd2UgbmVlZCB0byBhZGp1c3QgdGhlIGJsdWVwcmludCBmb3IgZnV0dXJlXG4gKiB0ZW1wbGF0ZSBwYXNzZXMuXG4gKlxuICogQHBhcmFtIHRWaWV3IGBUVmlld2AgYXNzb2NpYXRlZCB3aXRoIGBMVmlld2BcbiAqIEBwYXJhbSBsVmlldyBUaGUgYExWaWV3YCBjb250YWluaW5nIHRoZSBibHVlcHJpbnQgdG8gYWRqdXN0XG4gKiBAcGFyYW0gbnVtU2xvdHNUb0FsbG9jIFRoZSBudW1iZXIgb2Ygc2xvdHMgdG8gYWxsb2MgaW4gdGhlIExWaWV3LCBzaG91bGQgYmUgPjBcbiAqIEBwYXJhbSBpbml0aWFsVmFsdWUgSW5pdGlhbCB2YWx1ZSB0byBzdG9yZSBpbiBibHVlcHJpbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFsbG9jRXhwYW5kbyhcbiAgICB0VmlldzogVFZpZXcsIGxWaWV3OiBMVmlldywgbnVtU2xvdHNUb0FsbG9jOiBudW1iZXIsIGluaXRpYWxWYWx1ZTogYW55KTogbnVtYmVyIHtcbiAgaWYgKG51bVNsb3RzVG9BbGxvYyA9PT0gMCkgcmV0dXJuIC0xO1xuICBpZiAobmdEZXZNb2RlKSB7XG4gICAgYXNzZXJ0Rmlyc3RDcmVhdGVQYXNzKHRWaWV3KTtcbiAgICBhc3NlcnRTYW1lKHRWaWV3LCBsVmlld1tUVklFV10sICdgTFZpZXdgIG11c3QgYmUgYXNzb2NpYXRlZCB3aXRoIGBUVmlld2AhJyk7XG4gICAgYXNzZXJ0RXF1YWwodFZpZXcuZGF0YS5sZW5ndGgsIGxWaWV3Lmxlbmd0aCwgJ0V4cGVjdGluZyBMVmlldyB0byBiZSBzYW1lIHNpemUgYXMgVFZpZXcnKTtcbiAgICBhc3NlcnRFcXVhbChcbiAgICAgICAgdFZpZXcuZGF0YS5sZW5ndGgsIHRWaWV3LmJsdWVwcmludC5sZW5ndGgsICdFeHBlY3RpbmcgQmx1ZXByaW50IHRvIGJlIHNhbWUgc2l6ZSBhcyBUVmlldycpO1xuICAgIGFzc2VydEZpcnN0VXBkYXRlUGFzcyh0Vmlldyk7XG4gIH1cbiAgY29uc3QgYWxsb2NJZHggPSBsVmlldy5sZW5ndGg7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtU2xvdHNUb0FsbG9jOyBpKyspIHtcbiAgICBsVmlldy5wdXNoKGluaXRpYWxWYWx1ZSk7XG4gICAgdFZpZXcuYmx1ZXByaW50LnB1c2goaW5pdGlhbFZhbHVlKTtcbiAgICB0Vmlldy5kYXRhLnB1c2gobnVsbCk7XG4gIH1cbiAgcmV0dXJuIGFsbG9jSWR4O1xufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLy8vIFJlbmRlclxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBQcm9jZXNzZXMgYSB2aWV3IGluIHRoZSBjcmVhdGlvbiBtb2RlLiBUaGlzIGluY2x1ZGVzIGEgbnVtYmVyIG9mIHN0ZXBzIGluIGEgc3BlY2lmaWMgb3JkZXI6XG4gKiAtIGNyZWF0aW5nIHZpZXcgcXVlcnkgZnVuY3Rpb25zIChpZiBhbnkpO1xuICogLSBleGVjdXRpbmcgYSB0ZW1wbGF0ZSBmdW5jdGlvbiBpbiB0aGUgY3JlYXRpb24gbW9kZTtcbiAqIC0gdXBkYXRpbmcgc3RhdGljIHF1ZXJpZXMgKGlmIGFueSk7XG4gKiAtIGNyZWF0aW5nIGNoaWxkIGNvbXBvbmVudHMgZGVmaW5lZCBpbiBhIGdpdmVuIHZpZXcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJWaWV3PFQ+KHRWaWV3OiBUVmlldywgbFZpZXc6IExWaWV3LCBjb250ZXh0OiBUKTogdm9pZCB7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnRFcXVhbChpc0NyZWF0aW9uTW9kZShsVmlldyksIHRydWUsICdTaG91bGQgYmUgcnVuIGluIGNyZWF0aW9uIG1vZGUnKTtcbiAgZW50ZXJWaWV3KGxWaWV3KTtcbiAgdHJ5IHtcbiAgICBjb25zdCB2aWV3UXVlcnkgPSB0Vmlldy52aWV3UXVlcnk7XG4gICAgaWYgKHZpZXdRdWVyeSAhPT0gbnVsbCkge1xuICAgICAgZXhlY3V0ZVZpZXdRdWVyeUZuKFJlbmRlckZsYWdzLkNyZWF0ZSwgdmlld1F1ZXJ5LCBjb250ZXh0KTtcbiAgICB9XG5cbiAgICAvLyBFeGVjdXRlIGEgdGVtcGxhdGUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgdmlldywgaWYgaXQgZXhpc3RzLiBBIHRlbXBsYXRlIGZ1bmN0aW9uIG1pZ2h0IG5vdCBiZVxuICAgIC8vIGRlZmluZWQgZm9yIHRoZSByb290IGNvbXBvbmVudCB2aWV3cy5cbiAgICBjb25zdCB0ZW1wbGF0ZUZuID0gdFZpZXcudGVtcGxhdGU7XG4gICAgaWYgKHRlbXBsYXRlRm4gIT09IG51bGwpIHtcbiAgICAgIGV4ZWN1dGVUZW1wbGF0ZSh0VmlldywgbFZpZXcsIHRlbXBsYXRlRm4sIFJlbmRlckZsYWdzLkNyZWF0ZSwgY29udGV4dCk7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBuZWVkcyB0byBiZSBzZXQgYmVmb3JlIGNoaWxkcmVuIGFyZSBwcm9jZXNzZWQgdG8gc3VwcG9ydCByZWN1cnNpdmUgY29tcG9uZW50cy5cbiAgICAvLyBUaGlzIG11c3QgYmUgc2V0IHRvIGZhbHNlIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBmaXJzdCBjcmVhdGlvbiBydW4gYmVjYXVzZSBpbiBhblxuICAgIC8vIG5nRm9yIGxvb3AsIGFsbCB0aGUgdmlld3Mgd2lsbCBiZSBjcmVhdGVkIHRvZ2V0aGVyIGJlZm9yZSB1cGRhdGUgbW9kZSBydW5zIGFuZCB0dXJuc1xuICAgIC8vIG9mZiBmaXJzdENyZWF0ZVBhc3MuIElmIHdlIGRvbid0IHNldCBpdCBoZXJlLCBpbnN0YW5jZXMgd2lsbCBwZXJmb3JtIGRpcmVjdGl2ZVxuICAgIC8vIG1hdGNoaW5nLCBldGMgYWdhaW4gYW5kIGFnYWluLlxuICAgIGlmICh0Vmlldy5maXJzdENyZWF0ZVBhc3MpIHtcbiAgICAgIHRWaWV3LmZpcnN0Q3JlYXRlUGFzcyA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFdlIHJlc29sdmUgY29udGVudCBxdWVyaWVzIHNwZWNpZmljYWxseSBtYXJrZWQgYXMgYHN0YXRpY2AgaW4gY3JlYXRpb24gbW9kZS4gRHluYW1pY1xuICAgIC8vIGNvbnRlbnQgcXVlcmllcyBhcmUgcmVzb2x2ZWQgZHVyaW5nIGNoYW5nZSBkZXRlY3Rpb24gKGkuZS4gdXBkYXRlIG1vZGUpLCBhZnRlciBlbWJlZGRlZFxuICAgIC8vIHZpZXdzIGFyZSByZWZyZXNoZWQgKHNlZSBibG9jayBhYm92ZSkuXG4gICAgaWYgKHRWaWV3LnN0YXRpY0NvbnRlbnRRdWVyaWVzKSB7XG4gICAgICByZWZyZXNoQ29udGVudFF1ZXJpZXModFZpZXcsIGxWaWV3KTtcbiAgICB9XG5cbiAgICAvLyBXZSBtdXN0IG1hdGVyaWFsaXplIHF1ZXJ5IHJlc3VsdHMgYmVmb3JlIGNoaWxkIGNvbXBvbmVudHMgYXJlIHByb2Nlc3NlZFxuICAgIC8vIGluIGNhc2UgYSBjaGlsZCBjb21wb25lbnQgaGFzIHByb2plY3RlZCBhIGNvbnRhaW5lci4gVGhlIExDb250YWluZXIgbmVlZHNcbiAgICAvLyB0byBleGlzdCBzbyB0aGUgZW1iZWRkZWQgdmlld3MgYXJlIHByb3Blcmx5IGF0dGFjaGVkIGJ5IHRoZSBjb250YWluZXIuXG4gICAgaWYgKHRWaWV3LnN0YXRpY1ZpZXdRdWVyaWVzKSB7XG4gICAgICBleGVjdXRlVmlld1F1ZXJ5Rm4oUmVuZGVyRmxhZ3MuVXBkYXRlLCB0Vmlldy52aWV3UXVlcnkhLCBjb250ZXh0KTtcbiAgICB9XG5cbiAgICAvLyBSZW5kZXIgY2hpbGQgY29tcG9uZW50IHZpZXdzLlxuICAgIGNvbnN0IGNvbXBvbmVudHMgPSB0Vmlldy5jb21wb25lbnRzO1xuICAgIGlmIChjb21wb25lbnRzICE9PSBudWxsKSB7XG4gICAgICByZW5kZXJDaGlsZENvbXBvbmVudHMobFZpZXcsIGNvbXBvbmVudHMpO1xuICAgIH1cblxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIC8vIElmIHdlIGRpZG4ndCBtYW5hZ2UgdG8gZ2V0IHBhc3QgdGhlIGZpcnN0IHRlbXBsYXRlIHBhc3MgZHVlIHRvXG4gICAgLy8gYW4gZXJyb3IsIG1hcmsgdGhlIHZpZXcgYXMgY29ycnVwdGVkIHNvIHdlIGNhbiB0cnkgdG8gcmVjb3Zlci5cbiAgICBpZiAodFZpZXcuZmlyc3RDcmVhdGVQYXNzKSB7XG4gICAgICB0Vmlldy5pbmNvbXBsZXRlRmlyc3RQYXNzID0gdHJ1ZTtcbiAgICAgIHRWaWV3LmZpcnN0Q3JlYXRlUGFzcyA9IGZhbHNlO1xuICAgIH1cblxuICAgIHRocm93IGVycm9yO1xuICB9IGZpbmFsbHkge1xuICAgIGxWaWV3W0ZMQUdTXSAmPSB+TFZpZXdGbGFncy5DcmVhdGlvbk1vZGU7XG4gICAgbGVhdmVWaWV3KCk7XG4gIH1cbn1cblxuLyoqXG4gKiBQcm9jZXNzZXMgYSB2aWV3IGluIHVwZGF0ZSBtb2RlLiBUaGlzIGluY2x1ZGVzIGEgbnVtYmVyIG9mIHN0ZXBzIGluIGEgc3BlY2lmaWMgb3JkZXI6XG4gKiAtIGV4ZWN1dGluZyBhIHRlbXBsYXRlIGZ1bmN0aW9uIGluIHVwZGF0ZSBtb2RlO1xuICogLSBleGVjdXRpbmcgaG9va3M7XG4gKiAtIHJlZnJlc2hpbmcgcXVlcmllcztcbiAqIC0gc2V0dGluZyBob3N0IGJpbmRpbmdzO1xuICogLSByZWZyZXNoaW5nIGNoaWxkIChlbWJlZGRlZCBhbmQgY29tcG9uZW50KSB2aWV3cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZnJlc2hWaWV3PFQ+KFxuICAgIHRWaWV3OiBUVmlldywgbFZpZXc6IExWaWV3LCB0ZW1wbGF0ZUZuOiBDb21wb25lbnRUZW1wbGF0ZTx7fT58bnVsbCwgY29udGV4dDogVCkge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0RXF1YWwoaXNDcmVhdGlvbk1vZGUobFZpZXcpLCBmYWxzZSwgJ1Nob3VsZCBiZSBydW4gaW4gdXBkYXRlIG1vZGUnKTtcbiAgY29uc3QgZmxhZ3MgPSBsVmlld1tGTEFHU107XG4gIGlmICgoZmxhZ3MgJiBMVmlld0ZsYWdzLkRlc3Ryb3llZCkgPT09IExWaWV3RmxhZ3MuRGVzdHJveWVkKSByZXR1cm47XG4gIGVudGVyVmlldyhsVmlldyk7XG4gIC8vIENoZWNrIG5vIGNoYW5nZXMgbW9kZSBpcyBhIGRldiBvbmx5IG1vZGUgdXNlZCB0byB2ZXJpZnkgdGhhdCBiaW5kaW5ncyBoYXZlIG5vdCBjaGFuZ2VkXG4gIC8vIHNpbmNlIHRoZXkgd2VyZSBhc3NpZ25lZC4gV2UgZG8gbm90IHdhbnQgdG8gZXhlY3V0ZSBsaWZlY3ljbGUgaG9va3MgaW4gdGhhdCBtb2RlLlxuICBjb25zdCBpc0luQ2hlY2tOb0NoYW5nZXNQYXNzID0gaXNJbkNoZWNrTm9DaGFuZ2VzTW9kZSgpO1xuICB0cnkge1xuICAgIHJlc2V0UHJlT3JkZXJIb29rRmxhZ3MobFZpZXcpO1xuXG4gICAgc2V0QmluZGluZ0luZGV4KHRWaWV3LmJpbmRpbmdTdGFydEluZGV4KTtcbiAgICBpZiAodGVtcGxhdGVGbiAhPT0gbnVsbCkge1xuICAgICAgZXhlY3V0ZVRlbXBsYXRlKHRWaWV3LCBsVmlldywgdGVtcGxhdGVGbiwgUmVuZGVyRmxhZ3MuVXBkYXRlLCBjb250ZXh0KTtcbiAgICB9XG5cbiAgICBjb25zdCBob29rc0luaXRQaGFzZUNvbXBsZXRlZCA9XG4gICAgICAgIChmbGFncyAmIExWaWV3RmxhZ3MuSW5pdFBoYXNlU3RhdGVNYXNrKSA9PT0gSW5pdFBoYXNlU3RhdGUuSW5pdFBoYXNlQ29tcGxldGVkO1xuXG4gICAgLy8gZXhlY3V0ZSBwcmUtb3JkZXIgaG9va3MgKE9uSW5pdCwgT25DaGFuZ2VzLCBEb0NoZWNrKVxuICAgIC8vIFBFUkYgV0FSTklORzogZG8gTk9UIGV4dHJhY3QgdGhpcyB0byBhIHNlcGFyYXRlIGZ1bmN0aW9uIHdpdGhvdXQgcnVubmluZyBiZW5jaG1hcmtzXG4gICAgaWYgKCFpc0luQ2hlY2tOb0NoYW5nZXNQYXNzKSB7XG4gICAgICBpZiAoaG9va3NJbml0UGhhc2VDb21wbGV0ZWQpIHtcbiAgICAgICAgY29uc3QgcHJlT3JkZXJDaGVja0hvb2tzID0gdFZpZXcucHJlT3JkZXJDaGVja0hvb2tzO1xuICAgICAgICBpZiAocHJlT3JkZXJDaGVja0hvb2tzICE9PSBudWxsKSB7XG4gICAgICAgICAgZXhlY3V0ZUNoZWNrSG9va3MobFZpZXcsIHByZU9yZGVyQ2hlY2tIb29rcywgbnVsbCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHByZU9yZGVySG9va3MgPSB0Vmlldy5wcmVPcmRlckhvb2tzO1xuICAgICAgICBpZiAocHJlT3JkZXJIb29rcyAhPT0gbnVsbCkge1xuICAgICAgICAgIGV4ZWN1dGVJbml0QW5kQ2hlY2tIb29rcyhsVmlldywgcHJlT3JkZXJIb29rcywgSW5pdFBoYXNlU3RhdGUuT25Jbml0SG9va3NUb0JlUnVuLCBudWxsKTtcbiAgICAgICAgfVxuICAgICAgICBpbmNyZW1lbnRJbml0UGhhc2VGbGFncyhsVmlldywgSW5pdFBoYXNlU3RhdGUuT25Jbml0SG9va3NUb0JlUnVuKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBGaXJzdCBtYXJrIHRyYW5zcGxhbnRlZCB2aWV3cyB0aGF0IGFyZSBkZWNsYXJlZCBpbiB0aGlzIGxWaWV3IGFzIG5lZWRpbmcgYSByZWZyZXNoIGF0IHRoZWlyXG4gICAgLy8gaW5zZXJ0aW9uIHBvaW50cy4gVGhpcyBpcyBuZWVkZWQgdG8gYXZvaWQgdGhlIHNpdHVhdGlvbiB3aGVyZSB0aGUgdGVtcGxhdGUgaXMgZGVmaW5lZCBpbiB0aGlzXG4gICAgLy8gYExWaWV3YCBidXQgaXRzIGRlY2xhcmF0aW9uIGFwcGVhcnMgYWZ0ZXIgdGhlIGluc2VydGlvbiBjb21wb25lbnQuXG4gICAgbWFya1RyYW5zcGxhbnRlZFZpZXdzRm9yUmVmcmVzaChsVmlldyk7XG4gICAgcmVmcmVzaEVtYmVkZGVkVmlld3MobFZpZXcpO1xuXG4gICAgLy8gQ29udGVudCBxdWVyeSByZXN1bHRzIG11c3QgYmUgcmVmcmVzaGVkIGJlZm9yZSBjb250ZW50IGhvb2tzIGFyZSBjYWxsZWQuXG4gICAgaWYgKHRWaWV3LmNvbnRlbnRRdWVyaWVzICE9PSBudWxsKSB7XG4gICAgICByZWZyZXNoQ29udGVudFF1ZXJpZXModFZpZXcsIGxWaWV3KTtcbiAgICB9XG5cbiAgICAvLyBleGVjdXRlIGNvbnRlbnQgaG9va3MgKEFmdGVyQ29udGVudEluaXQsIEFmdGVyQ29udGVudENoZWNrZWQpXG4gICAgLy8gUEVSRiBXQVJOSU5HOiBkbyBOT1QgZXh0cmFjdCB0aGlzIHRvIGEgc2VwYXJhdGUgZnVuY3Rpb24gd2l0aG91dCBydW5uaW5nIGJlbmNobWFya3NcbiAgICBpZiAoIWlzSW5DaGVja05vQ2hhbmdlc1Bhc3MpIHtcbiAgICAgIGlmIChob29rc0luaXRQaGFzZUNvbXBsZXRlZCkge1xuICAgICAgICBjb25zdCBjb250ZW50Q2hlY2tIb29rcyA9IHRWaWV3LmNvbnRlbnRDaGVja0hvb2tzO1xuICAgICAgICBpZiAoY29udGVudENoZWNrSG9va3MgIT09IG51bGwpIHtcbiAgICAgICAgICBleGVjdXRlQ2hlY2tIb29rcyhsVmlldywgY29udGVudENoZWNrSG9va3MpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBjb250ZW50SG9va3MgPSB0Vmlldy5jb250ZW50SG9va3M7XG4gICAgICAgIGlmIChjb250ZW50SG9va3MgIT09IG51bGwpIHtcbiAgICAgICAgICBleGVjdXRlSW5pdEFuZENoZWNrSG9va3MoXG4gICAgICAgICAgICAgIGxWaWV3LCBjb250ZW50SG9va3MsIEluaXRQaGFzZVN0YXRlLkFmdGVyQ29udGVudEluaXRIb29rc1RvQmVSdW4pO1xuICAgICAgICB9XG4gICAgICAgIGluY3JlbWVudEluaXRQaGFzZUZsYWdzKGxWaWV3LCBJbml0UGhhc2VTdGF0ZS5BZnRlckNvbnRlbnRJbml0SG9va3NUb0JlUnVuKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcm9jZXNzSG9zdEJpbmRpbmdPcENvZGVzKHRWaWV3LCBsVmlldyk7XG5cbiAgICAvLyBSZWZyZXNoIGNoaWxkIGNvbXBvbmVudCB2aWV3cy5cbiAgICBjb25zdCBjb21wb25lbnRzID0gdFZpZXcuY29tcG9uZW50cztcbiAgICBpZiAoY29tcG9uZW50cyAhPT0gbnVsbCkge1xuICAgICAgcmVmcmVzaENoaWxkQ29tcG9uZW50cyhsVmlldywgY29tcG9uZW50cyk7XG4gICAgfVxuXG4gICAgLy8gVmlldyBxdWVyaWVzIG11c3QgZXhlY3V0ZSBhZnRlciByZWZyZXNoaW5nIGNoaWxkIGNvbXBvbmVudHMgYmVjYXVzZSBhIHRlbXBsYXRlIGluIHRoaXMgdmlld1xuICAgIC8vIGNvdWxkIGJlIGluc2VydGVkIGluIGEgY2hpbGQgY29tcG9uZW50LiBJZiB0aGUgdmlldyBxdWVyeSBleGVjdXRlcyBiZWZvcmUgY2hpbGQgY29tcG9uZW50XG4gICAgLy8gcmVmcmVzaCwgdGhlIHRlbXBsYXRlIG1pZ2h0IG5vdCB5ZXQgYmUgaW5zZXJ0ZWQuXG4gICAgY29uc3Qgdmlld1F1ZXJ5ID0gdFZpZXcudmlld1F1ZXJ5O1xuICAgIGlmICh2aWV3UXVlcnkgIT09IG51bGwpIHtcbiAgICAgIGV4ZWN1dGVWaWV3UXVlcnlGbihSZW5kZXJGbGFncy5VcGRhdGUsIHZpZXdRdWVyeSwgY29udGV4dCk7XG4gICAgfVxuXG4gICAgLy8gZXhlY3V0ZSB2aWV3IGhvb2tzIChBZnRlclZpZXdJbml0LCBBZnRlclZpZXdDaGVja2VkKVxuICAgIC8vIFBFUkYgV0FSTklORzogZG8gTk9UIGV4dHJhY3QgdGhpcyB0byBhIHNlcGFyYXRlIGZ1bmN0aW9uIHdpdGhvdXQgcnVubmluZyBiZW5jaG1hcmtzXG4gICAgaWYgKCFpc0luQ2hlY2tOb0NoYW5nZXNQYXNzKSB7XG4gICAgICBpZiAoaG9va3NJbml0UGhhc2VDb21wbGV0ZWQpIHtcbiAgICAgICAgY29uc3Qgdmlld0NoZWNrSG9va3MgPSB0Vmlldy52aWV3Q2hlY2tIb29rcztcbiAgICAgICAgaWYgKHZpZXdDaGVja0hvb2tzICE9PSBudWxsKSB7XG4gICAgICAgICAgZXhlY3V0ZUNoZWNrSG9va3MobFZpZXcsIHZpZXdDaGVja0hvb2tzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgdmlld0hvb2tzID0gdFZpZXcudmlld0hvb2tzO1xuICAgICAgICBpZiAodmlld0hvb2tzICE9PSBudWxsKSB7XG4gICAgICAgICAgZXhlY3V0ZUluaXRBbmRDaGVja0hvb2tzKGxWaWV3LCB2aWV3SG9va3MsIEluaXRQaGFzZVN0YXRlLkFmdGVyVmlld0luaXRIb29rc1RvQmVSdW4pO1xuICAgICAgICB9XG4gICAgICAgIGluY3JlbWVudEluaXRQaGFzZUZsYWdzKGxWaWV3LCBJbml0UGhhc2VTdGF0ZS5BZnRlclZpZXdJbml0SG9va3NUb0JlUnVuKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRWaWV3LmZpcnN0VXBkYXRlUGFzcyA9PT0gdHJ1ZSkge1xuICAgICAgLy8gV2UgbmVlZCB0byBtYWtlIHN1cmUgdGhhdCB3ZSBvbmx5IGZsaXAgdGhlIGZsYWcgb24gc3VjY2Vzc2Z1bCBgcmVmcmVzaFZpZXdgIG9ubHlcbiAgICAgIC8vIERvbid0IGRvIHRoaXMgaW4gYGZpbmFsbHlgIGJsb2NrLlxuICAgICAgLy8gSWYgd2UgZGlkIHRoaXMgaW4gYGZpbmFsbHlgIGJsb2NrIHRoZW4gYW4gZXhjZXB0aW9uIGNvdWxkIGJsb2NrIHRoZSBleGVjdXRpb24gb2Ygc3R5bGluZ1xuICAgICAgLy8gaW5zdHJ1Y3Rpb25zIHdoaWNoIGluIHR1cm4gd291bGQgYmUgdW5hYmxlIHRvIGluc2VydCB0aGVtc2VsdmVzIGludG8gdGhlIHN0eWxpbmcgbGlua2VkXG4gICAgICAvLyBsaXN0LiBUaGUgcmVzdWx0IG9mIHRoaXMgd291bGQgYmUgdGhhdCBpZiB0aGUgZXhjZXB0aW9uIHdvdWxkIG5vdCBiZSB0aHJvdyBvbiBzdWJzZXF1ZW50IENEXG4gICAgICAvLyB0aGUgc3R5bGluZyB3b3VsZCBiZSB1bmFibGUgdG8gcHJvY2VzcyBpdCBkYXRhIGFuZCByZWZsZWN0IHRvIHRoZSBET00uXG4gICAgICB0Vmlldy5maXJzdFVwZGF0ZVBhc3MgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBEbyBub3QgcmVzZXQgdGhlIGRpcnR5IHN0YXRlIHdoZW4gcnVubmluZyBpbiBjaGVjayBubyBjaGFuZ2VzIG1vZGUuIFdlIGRvbid0IHdhbnQgY29tcG9uZW50c1xuICAgIC8vIHRvIGJlaGF2ZSBkaWZmZXJlbnRseSBkZXBlbmRpbmcgb24gd2hldGhlciBjaGVjayBubyBjaGFuZ2VzIGlzIGVuYWJsZWQgb3Igbm90LiBGb3IgZXhhbXBsZTpcbiAgICAvLyBNYXJraW5nIGFuIE9uUHVzaCBjb21wb25lbnQgYXMgZGlydHkgZnJvbSB3aXRoaW4gdGhlIGBuZ0FmdGVyVmlld0luaXRgIGhvb2sgaW4gb3JkZXIgdG9cbiAgICAvLyByZWZyZXNoIGEgYE5nQ2xhc3NgIGJpbmRpbmcgc2hvdWxkIHdvcmsuIElmIHdlIHdvdWxkIHJlc2V0IHRoZSBkaXJ0eSBzdGF0ZSBpbiB0aGUgY2hlY2tcbiAgICAvLyBubyBjaGFuZ2VzIGN5Y2xlLCB0aGUgY29tcG9uZW50IHdvdWxkIGJlIG5vdCBiZSBkaXJ0eSBmb3IgdGhlIG5leHQgdXBkYXRlIHBhc3MuIFRoaXMgd291bGRcbiAgICAvLyBiZSBkaWZmZXJlbnQgaW4gcHJvZHVjdGlvbiBtb2RlIHdoZXJlIHRoZSBjb21wb25lbnQgZGlydHkgc3RhdGUgaXMgbm90IHJlc2V0LlxuICAgIGlmICghaXNJbkNoZWNrTm9DaGFuZ2VzUGFzcykge1xuICAgICAgbFZpZXdbRkxBR1NdICY9IH4oTFZpZXdGbGFncy5EaXJ0eSB8IExWaWV3RmxhZ3MuRmlyc3RMVmlld1Bhc3MpO1xuICAgIH1cbiAgICBpZiAobFZpZXdbRkxBR1NdICYgTFZpZXdGbGFncy5SZWZyZXNoVHJhbnNwbGFudGVkVmlldykge1xuICAgICAgbFZpZXdbRkxBR1NdICY9IH5MVmlld0ZsYWdzLlJlZnJlc2hUcmFuc3BsYW50ZWRWaWV3O1xuICAgICAgdXBkYXRlVHJhbnNwbGFudGVkVmlld0NvdW50KGxWaWV3W1BBUkVOVF0gYXMgTENvbnRhaW5lciwgLTEpO1xuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICBsZWF2ZVZpZXcoKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyQ29tcG9uZW50T3JUZW1wbGF0ZTxUPihcbiAgICB0VmlldzogVFZpZXcsIGxWaWV3OiBMVmlldywgdGVtcGxhdGVGbjogQ29tcG9uZW50VGVtcGxhdGU8e30+fG51bGwsIGNvbnRleHQ6IFQpIHtcbiAgY29uc3QgcmVuZGVyZXJGYWN0b3J5ID0gbFZpZXdbUkVOREVSRVJfRkFDVE9SWV07XG4gIGNvbnN0IG5vcm1hbEV4ZWN1dGlvblBhdGggPSAhaXNJbkNoZWNrTm9DaGFuZ2VzTW9kZSgpO1xuICBjb25zdCBjcmVhdGlvbk1vZGVJc0FjdGl2ZSA9IGlzQ3JlYXRpb25Nb2RlKGxWaWV3KTtcbiAgdHJ5IHtcbiAgICBpZiAobm9ybWFsRXhlY3V0aW9uUGF0aCAmJiAhY3JlYXRpb25Nb2RlSXNBY3RpdmUgJiYgcmVuZGVyZXJGYWN0b3J5LmJlZ2luKSB7XG4gICAgICByZW5kZXJlckZhY3RvcnkuYmVnaW4oKTtcbiAgICB9XG4gICAgaWYgKGNyZWF0aW9uTW9kZUlzQWN0aXZlKSB7XG4gICAgICByZW5kZXJWaWV3KHRWaWV3LCBsVmlldywgY29udGV4dCk7XG4gICAgfVxuICAgIHJlZnJlc2hWaWV3KHRWaWV3LCBsVmlldywgdGVtcGxhdGVGbiwgY29udGV4dCk7XG4gIH0gZmluYWxseSB7XG4gICAgaWYgKG5vcm1hbEV4ZWN1dGlvblBhdGggJiYgIWNyZWF0aW9uTW9kZUlzQWN0aXZlICYmIHJlbmRlcmVyRmFjdG9yeS5lbmQpIHtcbiAgICAgIHJlbmRlcmVyRmFjdG9yeS5lbmQoKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZXhlY3V0ZVRlbXBsYXRlPFQ+KFxuICAgIHRWaWV3OiBUVmlldywgbFZpZXc6IExWaWV3LCB0ZW1wbGF0ZUZuOiBDb21wb25lbnRUZW1wbGF0ZTxUPiwgcmY6IFJlbmRlckZsYWdzLCBjb250ZXh0OiBUKSB7XG4gIGNvbnN0IHByZXZTZWxlY3RlZEluZGV4ID0gZ2V0U2VsZWN0ZWRJbmRleCgpO1xuICBjb25zdCBpc1VwZGF0ZVBoYXNlID0gcmYgJiBSZW5kZXJGbGFncy5VcGRhdGU7XG4gIHRyeSB7XG4gICAgc2V0U2VsZWN0ZWRJbmRleCgtMSk7XG4gICAgaWYgKGlzVXBkYXRlUGhhc2UgJiYgbFZpZXcubGVuZ3RoID4gSEVBREVSX09GRlNFVCkge1xuICAgICAgLy8gV2hlbiB3ZSdyZSB1cGRhdGluZywgaW5oZXJlbnRseSBzZWxlY3QgMCBzbyB3ZSBkb24ndFxuICAgICAgLy8gaGF2ZSB0byBnZW5lcmF0ZSB0aGF0IGluc3RydWN0aW9uIGZvciBtb3N0IHVwZGF0ZSBibG9ja3MuXG4gICAgICBzZWxlY3RJbmRleEludGVybmFsKHRWaWV3LCBsVmlldywgSEVBREVSX09GRlNFVCwgaXNJbkNoZWNrTm9DaGFuZ2VzTW9kZSgpKTtcbiAgICB9XG5cbiAgICBjb25zdCBwcmVIb29rVHlwZSA9XG4gICAgICAgIGlzVXBkYXRlUGhhc2UgPyBQcm9maWxlckV2ZW50LlRlbXBsYXRlVXBkYXRlU3RhcnQgOiBQcm9maWxlckV2ZW50LlRlbXBsYXRlQ3JlYXRlU3RhcnQ7XG4gICAgcHJvZmlsZXIocHJlSG9va1R5cGUsIGNvbnRleHQpO1xuICAgIHRlbXBsYXRlRm4ocmYsIGNvbnRleHQpO1xuICB9IGZpbmFsbHkge1xuICAgIHNldFNlbGVjdGVkSW5kZXgocHJldlNlbGVjdGVkSW5kZXgpO1xuXG4gICAgY29uc3QgcG9zdEhvb2tUeXBlID1cbiAgICAgICAgaXNVcGRhdGVQaGFzZSA/IFByb2ZpbGVyRXZlbnQuVGVtcGxhdGVVcGRhdGVFbmQgOiBQcm9maWxlckV2ZW50LlRlbXBsYXRlQ3JlYXRlRW5kO1xuICAgIHByb2ZpbGVyKHBvc3RIb29rVHlwZSwgY29udGV4dCk7XG4gIH1cbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLy8gRWxlbWVudFxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZXhwb3J0IGZ1bmN0aW9uIGV4ZWN1dGVDb250ZW50UXVlcmllcyh0VmlldzogVFZpZXcsIHROb2RlOiBUTm9kZSwgbFZpZXc6IExWaWV3KSB7XG4gIGlmIChpc0NvbnRlbnRRdWVyeUhvc3QodE5vZGUpKSB7XG4gICAgY29uc3Qgc3RhcnQgPSB0Tm9kZS5kaXJlY3RpdmVTdGFydDtcbiAgICBjb25zdCBlbmQgPSB0Tm9kZS5kaXJlY3RpdmVFbmQ7XG4gICAgZm9yIChsZXQgZGlyZWN0aXZlSW5kZXggPSBzdGFydDsgZGlyZWN0aXZlSW5kZXggPCBlbmQ7IGRpcmVjdGl2ZUluZGV4KyspIHtcbiAgICAgIGNvbnN0IGRlZiA9IHRWaWV3LmRhdGFbZGlyZWN0aXZlSW5kZXhdIGFzIERpcmVjdGl2ZURlZjxhbnk+O1xuICAgICAgaWYgKGRlZi5jb250ZW50UXVlcmllcykge1xuICAgICAgICBkZWYuY29udGVudFF1ZXJpZXMoUmVuZGVyRmxhZ3MuQ3JlYXRlLCBsVmlld1tkaXJlY3RpdmVJbmRleF0sIGRpcmVjdGl2ZUluZGV4KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuXG4vKipcbiAqIENyZWF0ZXMgZGlyZWN0aXZlIGluc3RhbmNlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZURpcmVjdGl2ZXNJbnN0YW5jZXModFZpZXc6IFRWaWV3LCBsVmlldzogTFZpZXcsIHROb2RlOiBURGlyZWN0aXZlSG9zdE5vZGUpIHtcbiAgaWYgKCFnZXRCaW5kaW5nc0VuYWJsZWQoKSkgcmV0dXJuO1xuICBpbnN0YW50aWF0ZUFsbERpcmVjdGl2ZXModFZpZXcsIGxWaWV3LCB0Tm9kZSwgZ2V0TmF0aXZlQnlUTm9kZSh0Tm9kZSwgbFZpZXcpKTtcbiAgaWYgKCh0Tm9kZS5mbGFncyAmIFROb2RlRmxhZ3MuaGFzSG9zdEJpbmRpbmdzKSA9PT0gVE5vZGVGbGFncy5oYXNIb3N0QmluZGluZ3MpIHtcbiAgICBpbnZva2VEaXJlY3RpdmVzSG9zdEJpbmRpbmdzKHRWaWV3LCBsVmlldywgdE5vZGUpO1xuICB9XG59XG5cbi8qKlxuICogVGFrZXMgYSBsaXN0IG9mIGxvY2FsIG5hbWVzIGFuZCBpbmRpY2VzIGFuZCBwdXNoZXMgdGhlIHJlc29sdmVkIGxvY2FsIHZhcmlhYmxlIHZhbHVlc1xuICogdG8gTFZpZXcgaW4gdGhlIHNhbWUgb3JkZXIgYXMgdGhleSBhcmUgbG9hZGVkIGluIHRoZSB0ZW1wbGF0ZSB3aXRoIGxvYWQoKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNhdmVSZXNvbHZlZExvY2Fsc0luRGF0YShcbiAgICB2aWV3RGF0YTogTFZpZXcsIHROb2RlOiBURGlyZWN0aXZlSG9zdE5vZGUsXG4gICAgbG9jYWxSZWZFeHRyYWN0b3I6IExvY2FsUmVmRXh0cmFjdG9yID0gZ2V0TmF0aXZlQnlUTm9kZSk6IHZvaWQge1xuICBjb25zdCBsb2NhbE5hbWVzID0gdE5vZGUubG9jYWxOYW1lcztcbiAgaWYgKGxvY2FsTmFtZXMgIT09IG51bGwpIHtcbiAgICBsZXQgbG9jYWxJbmRleCA9IHROb2RlLmluZGV4ICsgMTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxvY2FsTmFtZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gbG9jYWxOYW1lc1tpICsgMV0gYXMgbnVtYmVyO1xuICAgICAgY29uc3QgdmFsdWUgPSBpbmRleCA9PT0gLTEgP1xuICAgICAgICAgIGxvY2FsUmVmRXh0cmFjdG9yKFxuICAgICAgICAgICAgICB0Tm9kZSBhcyBURWxlbWVudE5vZGUgfCBUQ29udGFpbmVyTm9kZSB8IFRFbGVtZW50Q29udGFpbmVyTm9kZSwgdmlld0RhdGEpIDpcbiAgICAgICAgICB2aWV3RGF0YVtpbmRleF07XG4gICAgICB2aWV3RGF0YVtsb2NhbEluZGV4KytdID0gdmFsdWU7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogR2V0cyBUVmlldyBmcm9tIGEgdGVtcGxhdGUgZnVuY3Rpb24gb3IgY3JlYXRlcyBhIG5ldyBUVmlld1xuICogaWYgaXQgZG9lc24ndCBhbHJlYWR5IGV4aXN0LlxuICpcbiAqIEBwYXJhbSBkZWYgQ29tcG9uZW50RGVmXG4gKiBAcmV0dXJucyBUVmlld1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0T3JDcmVhdGVUQ29tcG9uZW50VmlldyhkZWY6IENvbXBvbmVudERlZjxhbnk+KTogVFZpZXcge1xuICBjb25zdCB0VmlldyA9IGRlZi50VmlldztcblxuICAvLyBDcmVhdGUgYSBUVmlldyBpZiB0aGVyZSBpc24ndCBvbmUsIG9yIHJlY3JlYXRlIGl0IGlmIHRoZSBmaXJzdCBjcmVhdGUgcGFzcyBkaWRuJ3RcbiAgLy8gY29tcGxldGUgc3VjY2Vzc2Z1bGx5IHNpbmNlIHdlIGNhbid0IGtub3cgZm9yIHN1cmUgd2hldGhlciBpdCdzIGluIGEgdXNhYmxlIHNoYXBlLlxuICBpZiAodFZpZXcgPT09IG51bGwgfHwgdFZpZXcuaW5jb21wbGV0ZUZpcnN0UGFzcykge1xuICAgIC8vIERlY2xhcmF0aW9uIG5vZGUgaGVyZSBpcyBudWxsIHNpbmNlIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW4gd2UgZHluYW1pY2FsbHkgY3JlYXRlIGFcbiAgICAvLyBjb21wb25lbnQgYW5kIGhlbmNlIHRoZXJlIGlzIG5vIGRlY2xhcmF0aW9uLlxuICAgIGNvbnN0IGRlY2xUTm9kZSA9IG51bGw7XG4gICAgcmV0dXJuIGRlZi50VmlldyA9IGNyZWF0ZVRWaWV3KFxuICAgICAgICAgICAgICAgVFZpZXdUeXBlLkNvbXBvbmVudCwgZGVjbFROb2RlLCBkZWYudGVtcGxhdGUsIGRlZi5kZWNscywgZGVmLnZhcnMsIGRlZi5kaXJlY3RpdmVEZWZzLFxuICAgICAgICAgICAgICAgZGVmLnBpcGVEZWZzLCBkZWYudmlld1F1ZXJ5LCBkZWYuc2NoZW1hcywgZGVmLmNvbnN0cyk7XG4gIH1cblxuICByZXR1cm4gdFZpZXc7XG59XG5cblxuLyoqXG4gKiBDcmVhdGVzIGEgVFZpZXcgaW5zdGFuY2VcbiAqXG4gKiBAcGFyYW0gdHlwZSBUeXBlIG9mIGBUVmlld2AuXG4gKiBAcGFyYW0gZGVjbFROb2RlIERlY2xhcmF0aW9uIGxvY2F0aW9uIG9mIHRoaXMgYFRWaWV3YC5cbiAqIEBwYXJhbSB0ZW1wbGF0ZUZuIFRlbXBsYXRlIGZ1bmN0aW9uXG4gKiBAcGFyYW0gZGVjbHMgVGhlIG51bWJlciBvZiBub2RlcywgbG9jYWwgcmVmcywgYW5kIHBpcGVzIGluIHRoaXMgdGVtcGxhdGVcbiAqIEBwYXJhbSBkaXJlY3RpdmVzIFJlZ2lzdHJ5IG9mIGRpcmVjdGl2ZXMgZm9yIHRoaXMgdmlld1xuICogQHBhcmFtIHBpcGVzIFJlZ2lzdHJ5IG9mIHBpcGVzIGZvciB0aGlzIHZpZXdcbiAqIEBwYXJhbSB2aWV3UXVlcnkgVmlldyBxdWVyaWVzIGZvciB0aGlzIHZpZXdcbiAqIEBwYXJhbSBzY2hlbWFzIFNjaGVtYXMgZm9yIHRoaXMgdmlld1xuICogQHBhcmFtIGNvbnN0cyBDb25zdGFudHMgZm9yIHRoaXMgdmlld1xuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVFZpZXcoXG4gICAgdHlwZTogVFZpZXdUeXBlLCBkZWNsVE5vZGU6IFROb2RlfG51bGwsIHRlbXBsYXRlRm46IENvbXBvbmVudFRlbXBsYXRlPGFueT58bnVsbCwgZGVjbHM6IG51bWJlcixcbiAgICB2YXJzOiBudW1iZXIsIGRpcmVjdGl2ZXM6IERpcmVjdGl2ZURlZkxpc3RPckZhY3Rvcnl8bnVsbCwgcGlwZXM6IFBpcGVEZWZMaXN0T3JGYWN0b3J5fG51bGwsXG4gICAgdmlld1F1ZXJ5OiBWaWV3UXVlcmllc0Z1bmN0aW9uPGFueT58bnVsbCwgc2NoZW1hczogU2NoZW1hTWV0YWRhdGFbXXxudWxsLFxuICAgIGNvbnN0c09yRmFjdG9yeTogVENvbnN0YW50c09yRmFjdG9yeXxudWxsKTogVFZpZXcge1xuICBuZ0Rldk1vZGUgJiYgbmdEZXZNb2RlLnRWaWV3Kys7XG4gIGNvbnN0IGJpbmRpbmdTdGFydEluZGV4ID0gSEVBREVSX09GRlNFVCArIGRlY2xzO1xuICAvLyBUaGlzIGxlbmd0aCBkb2VzIG5vdCB5ZXQgY29udGFpbiBob3N0IGJpbmRpbmdzIGZyb20gY2hpbGQgZGlyZWN0aXZlcyBiZWNhdXNlIGF0IHRoaXMgcG9pbnQsXG4gIC8vIHdlIGRvbid0IGtub3cgd2hpY2ggZGlyZWN0aXZlcyBhcmUgYWN0aXZlIG9uIHRoaXMgdGVtcGxhdGUuIEFzIHNvb24gYXMgYSBkaXJlY3RpdmUgaXMgbWF0Y2hlZFxuICAvLyB0aGF0IGhhcyBhIGhvc3QgYmluZGluZywgd2Ugd2lsbCB1cGRhdGUgdGhlIGJsdWVwcmludCB3aXRoIHRoYXQgZGVmJ3MgaG9zdFZhcnMgY291bnQuXG4gIGNvbnN0IGluaXRpYWxWaWV3TGVuZ3RoID0gYmluZGluZ1N0YXJ0SW5kZXggKyB2YXJzO1xuICBjb25zdCBibHVlcHJpbnQgPSBjcmVhdGVWaWV3Qmx1ZXByaW50KGJpbmRpbmdTdGFydEluZGV4LCBpbml0aWFsVmlld0xlbmd0aCk7XG4gIGNvbnN0IGNvbnN0cyA9IHR5cGVvZiBjb25zdHNPckZhY3RvcnkgPT09ICdmdW5jdGlvbicgPyBjb25zdHNPckZhY3RvcnkoKSA6IGNvbnN0c09yRmFjdG9yeTtcbiAgY29uc3QgdFZpZXcgPSBibHVlcHJpbnRbVFZJRVcgYXMgYW55XSA9IG5nRGV2TW9kZSA/XG4gICAgICBuZXcgVFZpZXdDb25zdHJ1Y3RvcihcbiAgICAgICAgICB0eXBlLCAgICAgICAgLy8gdHlwZTogVFZpZXdUeXBlLFxuICAgICAgICAgIGJsdWVwcmludCwgICAvLyBibHVlcHJpbnQ6IExWaWV3LFxuICAgICAgICAgIHRlbXBsYXRlRm4sICAvLyB0ZW1wbGF0ZTogQ29tcG9uZW50VGVtcGxhdGU8e30+fG51bGwsXG4gICAgICAgICAgbnVsbCwgICAgICAgIC8vIHF1ZXJpZXM6IFRRdWVyaWVzfG51bGxcbiAgICAgICAgICB2aWV3UXVlcnksICAgLy8gdmlld1F1ZXJ5OiBWaWV3UXVlcmllc0Z1bmN0aW9uPHt9PnxudWxsLFxuICAgICAgICAgIGRlY2xUTm9kZSwgICAvLyBkZWNsVE5vZGU6IFROb2RlfG51bGwsXG4gICAgICAgICAgY2xvbmVUb1RWaWV3RGF0YShibHVlcHJpbnQpLmZpbGwobnVsbCwgYmluZGluZ1N0YXJ0SW5kZXgpLCAgLy8gZGF0YTogVERhdGEsXG4gICAgICAgICAgYmluZGluZ1N0YXJ0SW5kZXgsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYmluZGluZ1N0YXJ0SW5kZXg6IG51bWJlcixcbiAgICAgICAgICBpbml0aWFsVmlld0xlbmd0aCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBleHBhbmRvU3RhcnRJbmRleDogbnVtYmVyLFxuICAgICAgICAgIG51bGwsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhvc3RCaW5kaW5nT3BDb2RlczogSG9zdEJpbmRpbmdPcENvZGVzLFxuICAgICAgICAgIHRydWUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpcnN0Q3JlYXRlUGFzczogYm9vbGVhbixcbiAgICAgICAgICB0cnVlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaXJzdFVwZGF0ZVBhc3M6IGJvb2xlYW4sXG4gICAgICAgICAgZmFsc2UsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RhdGljVmlld1F1ZXJpZXM6IGJvb2xlYW4sXG4gICAgICAgICAgZmFsc2UsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RhdGljQ29udGVudFF1ZXJpZXM6IGJvb2xlYW4sXG4gICAgICAgICAgbnVsbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJlT3JkZXJIb29rczogSG9va0RhdGF8bnVsbCxcbiAgICAgICAgICBudWxsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwcmVPcmRlckNoZWNrSG9va3M6IEhvb2tEYXRhfG51bGwsXG4gICAgICAgICAgbnVsbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29udGVudEhvb2tzOiBIb29rRGF0YXxudWxsLFxuICAgICAgICAgIG51bGwsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnRlbnRDaGVja0hvb2tzOiBIb29rRGF0YXxudWxsLFxuICAgICAgICAgIG51bGwsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZpZXdIb29rczogSG9va0RhdGF8bnVsbCxcbiAgICAgICAgICBudWxsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB2aWV3Q2hlY2tIb29rczogSG9va0RhdGF8bnVsbCxcbiAgICAgICAgICBudWxsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZXN0cm95SG9va3M6IERlc3Ryb3lIb29rRGF0YXxudWxsLFxuICAgICAgICAgIG51bGwsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsZWFudXA6IGFueVtdfG51bGwsXG4gICAgICAgICAgbnVsbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29udGVudFF1ZXJpZXM6IG51bWJlcltdfG51bGwsXG4gICAgICAgICAgbnVsbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29tcG9uZW50czogbnVtYmVyW118bnVsbCxcbiAgICAgICAgICB0eXBlb2YgZGlyZWN0aXZlcyA9PT0gJ2Z1bmN0aW9uJyA/ICAvL1xuICAgICAgICAgICAgICBkaXJlY3RpdmVzKCkgOiAgICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgIGRpcmVjdGl2ZXMsICAgICAgICAgICAgICAgICAgICAgLy8gZGlyZWN0aXZlUmVnaXN0cnk6IERpcmVjdGl2ZURlZkxpc3R8bnVsbCxcbiAgICAgICAgICB0eXBlb2YgcGlwZXMgPT09ICdmdW5jdGlvbicgPyBwaXBlcygpIDogcGlwZXMsICAvLyBwaXBlUmVnaXN0cnk6IFBpcGVEZWZMaXN0fG51bGwsXG4gICAgICAgICAgbnVsbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlyc3RDaGlsZDogVE5vZGV8bnVsbCxcbiAgICAgICAgICBzY2hlbWFzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzY2hlbWFzOiBTY2hlbWFNZXRhZGF0YVtdfG51bGwsXG4gICAgICAgICAgY29uc3RzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc3RzOiBUQ29uc3RhbnRzfG51bGxcbiAgICAgICAgICBmYWxzZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmNvbXBsZXRlRmlyc3RQYXNzOiBib29sZWFuXG4gICAgICAgICAgZGVjbHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmdEZXZNb2RlIG9ubHk6IGRlY2xzXG4gICAgICAgICAgdmFycywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmdEZXZNb2RlIG9ubHk6IHZhcnNcbiAgICAgICAgICApIDpcbiAgICAgIHtcbiAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgYmx1ZXByaW50OiBibHVlcHJpbnQsXG4gICAgICAgIHRlbXBsYXRlOiB0ZW1wbGF0ZUZuLFxuICAgICAgICBxdWVyaWVzOiBudWxsLFxuICAgICAgICB2aWV3UXVlcnk6IHZpZXdRdWVyeSxcbiAgICAgICAgZGVjbFROb2RlOiBkZWNsVE5vZGUsXG4gICAgICAgIGRhdGE6IGJsdWVwcmludC5zbGljZSgpLmZpbGwobnVsbCwgYmluZGluZ1N0YXJ0SW5kZXgpLFxuICAgICAgICBiaW5kaW5nU3RhcnRJbmRleDogYmluZGluZ1N0YXJ0SW5kZXgsXG4gICAgICAgIGV4cGFuZG9TdGFydEluZGV4OiBpbml0aWFsVmlld0xlbmd0aCxcbiAgICAgICAgaG9zdEJpbmRpbmdPcENvZGVzOiBudWxsLFxuICAgICAgICBmaXJzdENyZWF0ZVBhc3M6IHRydWUsXG4gICAgICAgIGZpcnN0VXBkYXRlUGFzczogdHJ1ZSxcbiAgICAgICAgc3RhdGljVmlld1F1ZXJpZXM6IGZhbHNlLFxuICAgICAgICBzdGF0aWNDb250ZW50UXVlcmllczogZmFsc2UsXG4gICAgICAgIHByZU9yZGVySG9va3M6IG51bGwsXG4gICAgICAgIHByZU9yZGVyQ2hlY2tIb29rczogbnVsbCxcbiAgICAgICAgY29udGVudEhvb2tzOiBudWxsLFxuICAgICAgICBjb250ZW50Q2hlY2tIb29rczogbnVsbCxcbiAgICAgICAgdmlld0hvb2tzOiBudWxsLFxuICAgICAgICB2aWV3Q2hlY2tIb29rczogbnVsbCxcbiAgICAgICAgZGVzdHJveUhvb2tzOiBudWxsLFxuICAgICAgICBjbGVhbnVwOiBudWxsLFxuICAgICAgICBjb250ZW50UXVlcmllczogbnVsbCxcbiAgICAgICAgY29tcG9uZW50czogbnVsbCxcbiAgICAgICAgZGlyZWN0aXZlUmVnaXN0cnk6IHR5cGVvZiBkaXJlY3RpdmVzID09PSAnZnVuY3Rpb24nID8gZGlyZWN0aXZlcygpIDogZGlyZWN0aXZlcyxcbiAgICAgICAgcGlwZVJlZ2lzdHJ5OiB0eXBlb2YgcGlwZXMgPT09ICdmdW5jdGlvbicgPyBwaXBlcygpIDogcGlwZXMsXG4gICAgICAgIGZpcnN0Q2hpbGQ6IG51bGwsXG4gICAgICAgIHNjaGVtYXM6IHNjaGVtYXMsXG4gICAgICAgIGNvbnN0czogY29uc3RzLFxuICAgICAgICBpbmNvbXBsZXRlRmlyc3RQYXNzOiBmYWxzZVxuICAgICAgfTtcbiAgaWYgKG5nRGV2TW9kZSkge1xuICAgIC8vIEZvciBwZXJmb3JtYW5jZSByZWFzb25zIGl0IGlzIGltcG9ydGFudCB0aGF0IHRoZSB0VmlldyByZXRhaW5zIHRoZSBzYW1lIHNoYXBlIGR1cmluZyBydW50aW1lLlxuICAgIC8vIChUbyBtYWtlIHN1cmUgdGhhdCBhbGwgb2YgdGhlIGNvZGUgaXMgbW9ub21vcnBoaWMuKSBGb3IgdGhpcyByZWFzb24gd2Ugc2VhbCB0aGUgb2JqZWN0IHRvXG4gICAgLy8gcHJldmVudCBjbGFzcyB0cmFuc2l0aW9ucy5cbiAgICBPYmplY3Quc2VhbCh0Vmlldyk7XG4gIH1cbiAgcmV0dXJuIHRWaWV3O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVWaWV3Qmx1ZXByaW50KGJpbmRpbmdTdGFydEluZGV4OiBudW1iZXIsIGluaXRpYWxWaWV3TGVuZ3RoOiBudW1iZXIpOiBMVmlldyB7XG4gIGNvbnN0IGJsdWVwcmludCA9IG5nRGV2TW9kZSA/IG5ldyBMVmlld0JsdWVwcmludCgpIDogW107XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbml0aWFsVmlld0xlbmd0aDsgaSsrKSB7XG4gICAgYmx1ZXByaW50LnB1c2goaSA8IGJpbmRpbmdTdGFydEluZGV4ID8gbnVsbCA6IE5PX0NIQU5HRSk7XG4gIH1cblxuICByZXR1cm4gYmx1ZXByaW50IGFzIExWaWV3O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVFcnJvcih0ZXh0OiBzdHJpbmcsIHRva2VuOiBhbnkpIHtcbiAgcmV0dXJuIG5ldyBFcnJvcihgUmVuZGVyZXI6ICR7dGV4dH0gWyR7c3RyaW5naWZ5Rm9yRXJyb3IodG9rZW4pfV1gKTtcbn1cblxuZnVuY3Rpb24gYXNzZXJ0SG9zdE5vZGVFeGlzdHMockVsZW1lbnQ6IFJFbGVtZW50LCBlbGVtZW50T3JTZWxlY3RvcjogUkVsZW1lbnR8c3RyaW5nKSB7XG4gIGlmICghckVsZW1lbnQpIHtcbiAgICBpZiAodHlwZW9mIGVsZW1lbnRPclNlbGVjdG9yID09PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgY3JlYXRlRXJyb3IoJ0hvc3Qgbm9kZSB3aXRoIHNlbGVjdG9yIG5vdCBmb3VuZDonLCBlbGVtZW50T3JTZWxlY3Rvcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IGNyZWF0ZUVycm9yKCdIb3N0IG5vZGUgaXMgcmVxdWlyZWQ6JywgZWxlbWVudE9yU2VsZWN0b3IpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIExvY2F0ZXMgdGhlIGhvc3QgbmF0aXZlIGVsZW1lbnQsIHVzZWQgZm9yIGJvb3RzdHJhcHBpbmcgZXhpc3Rpbmcgbm9kZXMgaW50byByZW5kZXJpbmcgcGlwZWxpbmUuXG4gKlxuICogQHBhcmFtIHJlbmRlcmVyRmFjdG9yeSBGYWN0b3J5IGZ1bmN0aW9uIHRvIGNyZWF0ZSByZW5kZXJlciBpbnN0YW5jZS5cbiAqIEBwYXJhbSBlbGVtZW50T3JTZWxlY3RvciBSZW5kZXIgZWxlbWVudCBvciBDU1Mgc2VsZWN0b3IgdG8gbG9jYXRlIHRoZSBlbGVtZW50LlxuICogQHBhcmFtIGVuY2Fwc3VsYXRpb24gVmlldyBFbmNhcHN1bGF0aW9uIGRlZmluZWQgZm9yIGNvbXBvbmVudCB0aGF0IHJlcXVlc3RzIGhvc3QgZWxlbWVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvY2F0ZUhvc3RFbGVtZW50KFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjMsIGVsZW1lbnRPclNlbGVjdG9yOiBSRWxlbWVudHxzdHJpbmcsXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24pOiBSRWxlbWVudCB7XG4gIGlmIChpc1Byb2NlZHVyYWxSZW5kZXJlcihyZW5kZXJlcikpIHtcbiAgICAvLyBXaGVuIHVzaW5nIG5hdGl2ZSBTaGFkb3cgRE9NLCBkbyBub3QgY2xlYXIgaG9zdCBlbGVtZW50IHRvIGFsbG93IG5hdGl2ZSBzbG90IHByb2plY3Rpb25cbiAgICBjb25zdCBwcmVzZXJ2ZUNvbnRlbnQgPSBlbmNhcHN1bGF0aW9uID09PSBWaWV3RW5jYXBzdWxhdGlvbi5TaGFkb3dEb207XG4gICAgcmV0dXJuIHJlbmRlcmVyLnNlbGVjdFJvb3RFbGVtZW50KGVsZW1lbnRPclNlbGVjdG9yLCBwcmVzZXJ2ZUNvbnRlbnQpO1xuICB9XG5cbiAgbGV0IHJFbGVtZW50ID0gdHlwZW9mIGVsZW1lbnRPclNlbGVjdG9yID09PSAnc3RyaW5nJyA/XG4gICAgICByZW5kZXJlci5xdWVyeVNlbGVjdG9yKGVsZW1lbnRPclNlbGVjdG9yKSEgOlxuICAgICAgZWxlbWVudE9yU2VsZWN0b3I7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnRIb3N0Tm9kZUV4aXN0cyhyRWxlbWVudCwgZWxlbWVudE9yU2VsZWN0b3IpO1xuXG4gIC8vIEFsd2F5cyBjbGVhciBob3N0IGVsZW1lbnQncyBjb250ZW50IHdoZW4gUmVuZGVyZXIzIGlzIGluIHVzZS4gRm9yIHByb2NlZHVyYWwgcmVuZGVyZXIgY2FzZSB3ZVxuICAvLyBtYWtlIGl0IGRlcGVuZCBvbiB3aGV0aGVyIFNoYWRvd0RvbSBlbmNhcHN1bGF0aW9uIGlzIHVzZWQgKGluIHdoaWNoIGNhc2UgdGhlIGNvbnRlbnQgc2hvdWxkIGJlXG4gIC8vIHByZXNlcnZlZCB0byBhbGxvdyBuYXRpdmUgc2xvdCBwcm9qZWN0aW9uKS4gU2hhZG93RG9tIGVuY2Fwc3VsYXRpb24gcmVxdWlyZXMgcHJvY2VkdXJhbFxuICAvLyByZW5kZXJlciwgYW5kIHByb2NlZHVyYWwgcmVuZGVyZXIgY2FzZSBpcyBoYW5kbGVkIGFib3ZlLlxuICByRWxlbWVudC50ZXh0Q29udGVudCA9ICcnO1xuXG4gIHJldHVybiByRWxlbWVudDtcbn1cblxuLyoqXG4gKiBTYXZlcyBjb250ZXh0IGZvciB0aGlzIGNsZWFudXAgZnVuY3Rpb24gaW4gTFZpZXcuY2xlYW51cEluc3RhbmNlcy5cbiAqXG4gKiBPbiB0aGUgZmlyc3QgdGVtcGxhdGUgcGFzcywgc2F2ZXMgaW4gVFZpZXc6XG4gKiAtIENsZWFudXAgZnVuY3Rpb25cbiAqIC0gSW5kZXggb2YgY29udGV4dCB3ZSBqdXN0IHNhdmVkIGluIExWaWV3LmNsZWFudXBJbnN0YW5jZXNcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGNhbiBhbHNvIGJlIHVzZWQgdG8gc3RvcmUgaW5zdGFuY2Ugc3BlY2lmaWMgY2xlYW51cCBmbnMuIEluIHRoYXQgY2FzZSB0aGUgYGNvbnRleHRgXG4gKiBpcyBgbnVsbGAgYW5kIHRoZSBmdW5jdGlvbiBpcyBzdG9yZSBpbiBgTFZpZXdgIChyYXRoZXIgdGhhbiBpdCBgVFZpZXdgKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0b3JlQ2xlYW51cFdpdGhDb250ZXh0KFxuICAgIHRWaWV3OiBUVmlldywgbFZpZXc6IExWaWV3LCBjb250ZXh0OiBhbnksIGNsZWFudXBGbjogRnVuY3Rpb24pOiB2b2lkIHtcbiAgY29uc3QgbENsZWFudXAgPSBnZXRPckNyZWF0ZUxWaWV3Q2xlYW51cChsVmlldyk7XG4gIGlmIChjb250ZXh0ID09PSBudWxsKSB7XG4gICAgLy8gSWYgY29udGV4dCBpcyBudWxsIHRoYXQgdGhpcyBpcyBpbnN0YW5jZSBzcGVjaWZpYyBjYWxsYmFjay4gVGhlc2UgY2FsbGJhY2tzIGNhbiBvbmx5IGJlXG4gICAgLy8gaW5zZXJ0ZWQgYWZ0ZXIgdGVtcGxhdGUgc2hhcmVkIGluc3RhbmNlcy4gRm9yIHRoaXMgcmVhc29uIGluIG5nRGV2TW9kZSB3ZSBmcmVlemUgdGhlIFRWaWV3LlxuICAgIGlmIChuZ0Rldk1vZGUpIHtcbiAgICAgIE9iamVjdC5mcmVlemUoZ2V0T3JDcmVhdGVUVmlld0NsZWFudXAodFZpZXcpKTtcbiAgICB9XG4gICAgbENsZWFudXAucHVzaChjbGVhbnVwRm4pO1xuICB9IGVsc2Uge1xuICAgIGxDbGVhbnVwLnB1c2goY29udGV4dCk7XG5cbiAgICBpZiAodFZpZXcuZmlyc3RDcmVhdGVQYXNzKSB7XG4gICAgICBnZXRPckNyZWF0ZVRWaWV3Q2xlYW51cCh0VmlldykucHVzaChjbGVhbnVwRm4sIGxDbGVhbnVwLmxlbmd0aCAtIDEpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBUTm9kZSBvYmplY3QgZnJvbSB0aGUgYXJndW1lbnRzLlxuICpcbiAqIEBwYXJhbSB0VmlldyBgVFZpZXdgIHRvIHdoaWNoIHRoaXMgYFROb2RlYCBiZWxvbmdzICh1c2VkIG9ubHkgaW4gYG5nRGV2TW9kZWApXG4gKiBAcGFyYW0gdFBhcmVudCBQYXJlbnQgYFROb2RlYFxuICogQHBhcmFtIHR5cGUgVGhlIHR5cGUgb2YgdGhlIG5vZGVcbiAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIFROb2RlIGluIFRWaWV3LmRhdGEsIGFkanVzdGVkIGZvciBIRUFERVJfT0ZGU0VUXG4gKiBAcGFyYW0gdGFnTmFtZSBUaGUgdGFnIG5hbWUgb2YgdGhlIG5vZGVcbiAqIEBwYXJhbSBhdHRycyBUaGUgYXR0cmlidXRlcyBkZWZpbmVkIG9uIHRoaXMgbm9kZVxuICogQHBhcmFtIHRWaWV3cyBBbnkgVFZpZXdzIGF0dGFjaGVkIHRvIHRoaXMgbm9kZVxuICogQHJldHVybnMgdGhlIFROb2RlIG9iamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVE5vZGUoXG4gICAgdFZpZXc6IFRWaWV3LCB0UGFyZW50OiBURWxlbWVudE5vZGV8VENvbnRhaW5lck5vZGV8bnVsbCwgdHlwZTogVE5vZGVUeXBlLkNvbnRhaW5lcixcbiAgICBpbmRleDogbnVtYmVyLCB0YWdOYW1lOiBzdHJpbmd8bnVsbCwgYXR0cnM6IFRBdHRyaWJ1dGVzfG51bGwpOiBUQ29udGFpbmVyTm9kZTtcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUTm9kZShcbiAgICB0VmlldzogVFZpZXcsIHRQYXJlbnQ6IFRFbGVtZW50Tm9kZXxUQ29udGFpbmVyTm9kZXxudWxsLCB0eXBlOiBUTm9kZVR5cGUuRWxlbWVudHxUTm9kZVR5cGUuVGV4dCxcbiAgICBpbmRleDogbnVtYmVyLCB0YWdOYW1lOiBzdHJpbmd8bnVsbCwgYXR0cnM6IFRBdHRyaWJ1dGVzfG51bGwpOiBURWxlbWVudE5vZGU7XG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVE5vZGUoXG4gICAgdFZpZXc6IFRWaWV3LCB0UGFyZW50OiBURWxlbWVudE5vZGV8VENvbnRhaW5lck5vZGV8bnVsbCwgdHlwZTogVE5vZGVUeXBlLkVsZW1lbnRDb250YWluZXIsXG4gICAgaW5kZXg6IG51bWJlciwgdGFnTmFtZTogc3RyaW5nfG51bGwsIGF0dHJzOiBUQXR0cmlidXRlc3xudWxsKTogVEVsZW1lbnRDb250YWluZXJOb2RlO1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVROb2RlKFxuICAgIHRWaWV3OiBUVmlldywgdFBhcmVudDogVEVsZW1lbnROb2RlfFRDb250YWluZXJOb2RlfG51bGwsIHR5cGU6IFROb2RlVHlwZS5JY3UsIGluZGV4OiBudW1iZXIsXG4gICAgdGFnTmFtZTogc3RyaW5nfG51bGwsIGF0dHJzOiBUQXR0cmlidXRlc3xudWxsKTogVEljdUNvbnRhaW5lck5vZGU7XG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVE5vZGUoXG4gICAgdFZpZXc6IFRWaWV3LCB0UGFyZW50OiBURWxlbWVudE5vZGV8VENvbnRhaW5lck5vZGV8bnVsbCwgdHlwZTogVE5vZGVUeXBlLlByb2plY3Rpb24sXG4gICAgaW5kZXg6IG51bWJlciwgdGFnTmFtZTogc3RyaW5nfG51bGwsIGF0dHJzOiBUQXR0cmlidXRlc3xudWxsKTogVFByb2plY3Rpb25Ob2RlO1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVROb2RlKFxuICAgIHRWaWV3OiBUVmlldywgdFBhcmVudDogVEVsZW1lbnROb2RlfFRDb250YWluZXJOb2RlfG51bGwsIHR5cGU6IFROb2RlVHlwZSwgaW5kZXg6IG51bWJlcixcbiAgICB0YWdOYW1lOiBzdHJpbmd8bnVsbCwgYXR0cnM6IFRBdHRyaWJ1dGVzfG51bGwpOiBUTm9kZTtcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUTm9kZShcbiAgICB0VmlldzogVFZpZXcsIHRQYXJlbnQ6IFRFbGVtZW50Tm9kZXxUQ29udGFpbmVyTm9kZXxudWxsLCB0eXBlOiBUTm9kZVR5cGUsIGluZGV4OiBudW1iZXIsXG4gICAgdmFsdWU6IHN0cmluZ3xudWxsLCBhdHRyczogVEF0dHJpYnV0ZXN8bnVsbCk6IFROb2RlIHtcbiAgbmdEZXZNb2RlICYmIGluZGV4ICE9PSAwICYmICAvLyAwIGFyZSBib2d1cyBub2RlcyBhbmQgdGhleSBhcmUgT0suIFNlZSBgY3JlYXRlQ29udGFpbmVyUmVmYCBpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGB2aWV3X2VuZ2luZV9jb21wYXRpYmlsaXR5YCBmb3IgYWRkaXRpb25hbCBjb250ZXh0LlxuICAgICAgYXNzZXJ0R3JlYXRlclRoYW5PckVxdWFsKGluZGV4LCBIRUFERVJfT0ZGU0VULCAnVE5vZGVzIGNhblxcJ3QgYmUgaW4gdGhlIExWaWV3IGhlYWRlci4nKTtcbiAgbmdEZXZNb2RlICYmIGFzc2VydE5vdFNhbWUoYXR0cnMsIHVuZGVmaW5lZCwgJ1xcJ3VuZGVmaW5lZFxcJyBpcyBub3QgdmFsaWQgdmFsdWUgZm9yIFxcJ2F0dHJzXFwnJyk7XG4gIG5nRGV2TW9kZSAmJiBuZ0Rldk1vZGUudE5vZGUrKztcbiAgbmdEZXZNb2RlICYmIHRQYXJlbnQgJiYgYXNzZXJ0VE5vZGVGb3JUVmlldyh0UGFyZW50LCB0Vmlldyk7XG4gIGxldCBpbmplY3RvckluZGV4ID0gdFBhcmVudCA/IHRQYXJlbnQuaW5qZWN0b3JJbmRleCA6IC0xO1xuICBjb25zdCB0Tm9kZSA9IG5nRGV2TW9kZSA/XG4gICAgICBuZXcgVE5vZGVEZWJ1ZyhcbiAgICAgICAgICB0VmlldywgICAgICAgICAgLy8gdFZpZXdfOiBUVmlld1xuICAgICAgICAgIHR5cGUsICAgICAgICAgICAvLyB0eXBlOiBUTm9kZVR5cGVcbiAgICAgICAgICBpbmRleCwgICAgICAgICAgLy8gaW5kZXg6IG51bWJlclxuICAgICAgICAgIG51bGwsICAgICAgICAgICAvLyBpbnNlcnRCZWZvcmVJbmRleDogbnVsbHwtMXxudW1iZXJ8bnVtYmVyW11cbiAgICAgICAgICBpbmplY3RvckluZGV4LCAgLy8gaW5qZWN0b3JJbmRleDogbnVtYmVyXG4gICAgICAgICAgLTEsICAgICAgICAgICAgIC8vIGRpcmVjdGl2ZVN0YXJ0OiBudW1iZXJcbiAgICAgICAgICAtMSwgICAgICAgICAgICAgLy8gZGlyZWN0aXZlRW5kOiBudW1iZXJcbiAgICAgICAgICAtMSwgICAgICAgICAgICAgLy8gZGlyZWN0aXZlU3R5bGluZ0xhc3Q6IG51bWJlclxuICAgICAgICAgIG51bGwsICAgICAgICAgICAvLyBwcm9wZXJ0eUJpbmRpbmdzOiBudW1iZXJbXXxudWxsXG4gICAgICAgICAgMCwgICAgICAgICAgICAgIC8vIGZsYWdzOiBUTm9kZUZsYWdzXG4gICAgICAgICAgMCwgICAgICAgICAgICAgIC8vIHByb3ZpZGVySW5kZXhlczogVE5vZGVQcm92aWRlckluZGV4ZXNcbiAgICAgICAgICB2YWx1ZSwgICAgICAgICAgLy8gdmFsdWU6IHN0cmluZ3xudWxsXG4gICAgICAgICAgYXR0cnMsICAgICAgICAgIC8vIGF0dHJzOiAoc3RyaW5nfEF0dHJpYnV0ZU1hcmtlcnwoc3RyaW5nfFNlbGVjdG9yRmxhZ3MpW10pW118bnVsbFxuICAgICAgICAgIG51bGwsICAgICAgICAgICAvLyBtZXJnZWRBdHRyc1xuICAgICAgICAgIG51bGwsICAgICAgICAgICAvLyBsb2NhbE5hbWVzOiAoc3RyaW5nfG51bWJlcilbXXxudWxsXG4gICAgICAgICAgdW5kZWZpbmVkLCAgICAgIC8vIGluaXRpYWxJbnB1dHM6IChzdHJpbmdbXXxudWxsKVtdfG51bGx8dW5kZWZpbmVkXG4gICAgICAgICAgbnVsbCwgICAgICAgICAgIC8vIGlucHV0czogUHJvcGVydHlBbGlhc2VzfG51bGxcbiAgICAgICAgICBudWxsLCAgICAgICAgICAgLy8gb3V0cHV0czogUHJvcGVydHlBbGlhc2VzfG51bGxcbiAgICAgICAgICBudWxsLCAgICAgICAgICAgLy8gdFZpZXdzOiBJVFZpZXd8SVRWaWV3W118bnVsbFxuICAgICAgICAgIG51bGwsICAgICAgICAgICAvLyBuZXh0OiBJVE5vZGV8bnVsbFxuICAgICAgICAgIG51bGwsICAgICAgICAgICAvLyBwcm9qZWN0aW9uTmV4dDogSVROb2RlfG51bGxcbiAgICAgICAgICBudWxsLCAgICAgICAgICAgLy8gY2hpbGQ6IElUTm9kZXxudWxsXG4gICAgICAgICAgdFBhcmVudCwgICAgICAgIC8vIHBhcmVudDogVEVsZW1lbnROb2RlfFRDb250YWluZXJOb2RlfG51bGxcbiAgICAgICAgICBudWxsLCAgICAgICAgICAgLy8gcHJvamVjdGlvbjogbnVtYmVyfChJVE5vZGV8Uk5vZGVbXSlbXXxudWxsXG4gICAgICAgICAgbnVsbCwgICAgICAgICAgIC8vIHN0eWxlczogc3RyaW5nfG51bGxcbiAgICAgICAgICBudWxsLCAgICAgICAgICAgLy8gc3R5bGVzV2l0aG91dEhvc3Q6IHN0cmluZ3xudWxsXG4gICAgICAgICAgdW5kZWZpbmVkLCAgICAgIC8vIHJlc2lkdWFsU3R5bGVzOiBzdHJpbmd8bnVsbFxuICAgICAgICAgIG51bGwsICAgICAgICAgICAvLyBjbGFzc2VzOiBzdHJpbmd8bnVsbFxuICAgICAgICAgIG51bGwsICAgICAgICAgICAvLyBjbGFzc2VzV2l0aG91dEhvc3Q6IHN0cmluZ3xudWxsXG4gICAgICAgICAgdW5kZWZpbmVkLCAgICAgIC8vIHJlc2lkdWFsQ2xhc3Nlczogc3RyaW5nfG51bGxcbiAgICAgICAgICAwIGFzIGFueSwgICAgICAgLy8gY2xhc3NCaW5kaW5nczogVFN0eWxpbmdSYW5nZTtcbiAgICAgICAgICAwIGFzIGFueSwgICAgICAgLy8gc3R5bGVCaW5kaW5nczogVFN0eWxpbmdSYW5nZTtcbiAgICAgICAgICApIDpcbiAgICAgIHtcbiAgICAgICAgdHlwZSxcbiAgICAgICAgaW5kZXgsXG4gICAgICAgIGluc2VydEJlZm9yZUluZGV4OiBudWxsLFxuICAgICAgICBpbmplY3RvckluZGV4LFxuICAgICAgICBkaXJlY3RpdmVTdGFydDogLTEsXG4gICAgICAgIGRpcmVjdGl2ZUVuZDogLTEsXG4gICAgICAgIGRpcmVjdGl2ZVN0eWxpbmdMYXN0OiAtMSxcbiAgICAgICAgcHJvcGVydHlCaW5kaW5nczogbnVsbCxcbiAgICAgICAgZmxhZ3M6IDAsXG4gICAgICAgIHByb3ZpZGVySW5kZXhlczogMCxcbiAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICBhdHRyczogYXR0cnMsXG4gICAgICAgIG1lcmdlZEF0dHJzOiBudWxsLFxuICAgICAgICBsb2NhbE5hbWVzOiBudWxsLFxuICAgICAgICBpbml0aWFsSW5wdXRzOiB1bmRlZmluZWQsXG4gICAgICAgIGlucHV0czogbnVsbCxcbiAgICAgICAgb3V0cHV0czogbnVsbCxcbiAgICAgICAgdFZpZXdzOiBudWxsLFxuICAgICAgICBuZXh0OiBudWxsLFxuICAgICAgICBwcm9qZWN0aW9uTmV4dDogbnVsbCxcbiAgICAgICAgY2hpbGQ6IG51bGwsXG4gICAgICAgIHBhcmVudDogdFBhcmVudCxcbiAgICAgICAgcHJvamVjdGlvbjogbnVsbCxcbiAgICAgICAgc3R5bGVzOiBudWxsLFxuICAgICAgICBzdHlsZXNXaXRob3V0SG9zdDogbnVsbCxcbiAgICAgICAgcmVzaWR1YWxTdHlsZXM6IHVuZGVmaW5lZCxcbiAgICAgICAgY2xhc3NlczogbnVsbCxcbiAgICAgICAgY2xhc3Nlc1dpdGhvdXRIb3N0OiBudWxsLFxuICAgICAgICByZXNpZHVhbENsYXNzZXM6IHVuZGVmaW5lZCxcbiAgICAgICAgY2xhc3NCaW5kaW5nczogMCBhcyBhbnksXG4gICAgICAgIHN0eWxlQmluZGluZ3M6IDAgYXMgYW55LFxuICAgICAgfTtcbiAgaWYgKG5nRGV2TW9kZSkge1xuICAgIC8vIEZvciBwZXJmb3JtYW5jZSByZWFzb25zIGl0IGlzIGltcG9ydGFudCB0aGF0IHRoZSB0Tm9kZSByZXRhaW5zIHRoZSBzYW1lIHNoYXBlIGR1cmluZyBydW50aW1lLlxuICAgIC8vIChUbyBtYWtlIHN1cmUgdGhhdCBhbGwgb2YgdGhlIGNvZGUgaXMgbW9ub21vcnBoaWMuKSBGb3IgdGhpcyByZWFzb24gd2Ugc2VhbCB0aGUgb2JqZWN0IHRvXG4gICAgLy8gcHJldmVudCBjbGFzcyB0cmFuc2l0aW9ucy5cbiAgICBPYmplY3Quc2VhbCh0Tm9kZSk7XG4gIH1cbiAgcmV0dXJuIHROb2RlO1xufVxuXG5cbmZ1bmN0aW9uIGdlbmVyYXRlUHJvcGVydHlBbGlhc2VzKFxuICAgIGlucHV0QWxpYXNNYXA6IHtbcHVibGljTmFtZTogc3RyaW5nXTogc3RyaW5nfSwgZGlyZWN0aXZlRGVmSWR4OiBudW1iZXIsXG4gICAgcHJvcFN0b3JlOiBQcm9wZXJ0eUFsaWFzZXN8bnVsbCk6IFByb3BlcnR5QWxpYXNlc3xudWxsIHtcbiAgZm9yIChsZXQgcHVibGljTmFtZSBpbiBpbnB1dEFsaWFzTWFwKSB7XG4gICAgaWYgKGlucHV0QWxpYXNNYXAuaGFzT3duUHJvcGVydHkocHVibGljTmFtZSkpIHtcbiAgICAgIHByb3BTdG9yZSA9IHByb3BTdG9yZSA9PT0gbnVsbCA/IHt9IDogcHJvcFN0b3JlO1xuICAgICAgY29uc3QgaW50ZXJuYWxOYW1lID0gaW5wdXRBbGlhc01hcFtwdWJsaWNOYW1lXTtcblxuICAgICAgaWYgKHByb3BTdG9yZS5oYXNPd25Qcm9wZXJ0eShwdWJsaWNOYW1lKSkge1xuICAgICAgICBwcm9wU3RvcmVbcHVibGljTmFtZV0ucHVzaChkaXJlY3RpdmVEZWZJZHgsIGludGVybmFsTmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAocHJvcFN0b3JlW3B1YmxpY05hbWVdID0gW2RpcmVjdGl2ZURlZklkeCwgaW50ZXJuYWxOYW1lXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBwcm9wU3RvcmU7XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgZGF0YSBzdHJ1Y3R1cmVzIHJlcXVpcmVkIHRvIHdvcmsgd2l0aCBkaXJlY3RpdmUgaW5wdXRzIGFuZCBvdXRwdXRzLlxuICogSW5pdGlhbGl6YXRpb24gaXMgZG9uZSBmb3IgYWxsIGRpcmVjdGl2ZXMgbWF0Y2hlZCBvbiBhIGdpdmVuIFROb2RlLlxuICovXG5mdW5jdGlvbiBpbml0aWFsaXplSW5wdXRBbmRPdXRwdXRBbGlhc2VzKHRWaWV3OiBUVmlldywgdE5vZGU6IFROb2RlKTogdm9pZCB7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnRGaXJzdENyZWF0ZVBhc3ModFZpZXcpO1xuXG4gIGNvbnN0IHN0YXJ0ID0gdE5vZGUuZGlyZWN0aXZlU3RhcnQ7XG4gIGNvbnN0IGVuZCA9IHROb2RlLmRpcmVjdGl2ZUVuZDtcbiAgY29uc3QgdFZpZXdEYXRhID0gdFZpZXcuZGF0YTtcblxuICBjb25zdCB0Tm9kZUF0dHJzID0gdE5vZGUuYXR0cnM7XG4gIGNvbnN0IGlucHV0c0Zyb21BdHRyczogSW5pdGlhbElucHV0RGF0YSA9IG5nRGV2TW9kZSA/IG5ldyBUTm9kZUluaXRpYWxJbnB1dHMoKSA6IFtdO1xuICBsZXQgaW5wdXRzU3RvcmU6IFByb3BlcnR5QWxpYXNlc3xudWxsID0gbnVsbDtcbiAgbGV0IG91dHB1dHNTdG9yZTogUHJvcGVydHlBbGlhc2VzfG51bGwgPSBudWxsO1xuICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIGNvbnN0IGRpcmVjdGl2ZURlZiA9IHRWaWV3RGF0YVtpXSBhcyBEaXJlY3RpdmVEZWY8YW55PjtcbiAgICBjb25zdCBkaXJlY3RpdmVJbnB1dHMgPSBkaXJlY3RpdmVEZWYuaW5wdXRzO1xuICAgIC8vIERvIG5vdCB1c2UgdW5ib3VuZCBhdHRyaWJ1dGVzIGFzIGlucHV0cyB0byBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZXMsIHNpbmNlIHN0cnVjdHVyYWxcbiAgICAvLyBkaXJlY3RpdmUgaW5wdXRzIGNhbiBvbmx5IGJlIHNldCB1c2luZyBtaWNyb3N5bnRheCAoZS5nLiBgPGRpdiAqZGlyPVwiZXhwXCI+YCkuXG4gICAgLy8gVE9ETyhGVy0xOTMwKTogbWljcm9zeW50YXggZXhwcmVzc2lvbnMgbWF5IGFsc28gY29udGFpbiB1bmJvdW5kL3N0YXRpYyBhdHRyaWJ1dGVzLCB3aGljaFxuICAgIC8vIHNob3VsZCBiZSBzZXQgZm9yIGlubGluZSB0ZW1wbGF0ZXMuXG4gICAgY29uc3QgaW5pdGlhbElucHV0cyA9ICh0Tm9kZUF0dHJzICE9PSBudWxsICYmICFpc0lubGluZVRlbXBsYXRlKHROb2RlKSkgP1xuICAgICAgICBnZW5lcmF0ZUluaXRpYWxJbnB1dHMoZGlyZWN0aXZlSW5wdXRzLCB0Tm9kZUF0dHJzKSA6XG4gICAgICAgIG51bGw7XG4gICAgaW5wdXRzRnJvbUF0dHJzLnB1c2goaW5pdGlhbElucHV0cyk7XG4gICAgaW5wdXRzU3RvcmUgPSBnZW5lcmF0ZVByb3BlcnR5QWxpYXNlcyhkaXJlY3RpdmVJbnB1dHMsIGksIGlucHV0c1N0b3JlKTtcbiAgICBvdXRwdXRzU3RvcmUgPSBnZW5lcmF0ZVByb3BlcnR5QWxpYXNlcyhkaXJlY3RpdmVEZWYub3V0cHV0cywgaSwgb3V0cHV0c1N0b3JlKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNTdG9yZSAhPT0gbnVsbCkge1xuICAgIGlmIChpbnB1dHNTdG9yZS5oYXNPd25Qcm9wZXJ0eSgnY2xhc3MnKSkge1xuICAgICAgdE5vZGUuZmxhZ3MgfD0gVE5vZGVGbGFncy5oYXNDbGFzc0lucHV0O1xuICAgIH1cbiAgICBpZiAoaW5wdXRzU3RvcmUuaGFzT3duUHJvcGVydHkoJ3N0eWxlJykpIHtcbiAgICAgIHROb2RlLmZsYWdzIHw9IFROb2RlRmxhZ3MuaGFzU3R5bGVJbnB1dDtcbiAgICB9XG4gIH1cblxuICB0Tm9kZS5pbml0aWFsSW5wdXRzID0gaW5wdXRzRnJvbUF0dHJzO1xuICB0Tm9kZS5pbnB1dHMgPSBpbnB1dHNTdG9yZTtcbiAgdE5vZGUub3V0cHV0cyA9IG91dHB1dHNTdG9yZTtcbn1cblxuLyoqXG4gKiBNYXBwaW5nIGJldHdlZW4gYXR0cmlidXRlcyBuYW1lcyB0aGF0IGRvbid0IGNvcnJlc3BvbmQgdG8gdGhlaXIgZWxlbWVudCBwcm9wZXJ0eSBuYW1lcy5cbiAqXG4gKiBQZXJmb3JtYW5jZSBub3RlOiB0aGlzIGZ1bmN0aW9uIGlzIHdyaXR0ZW4gYXMgYSBzZXJpZXMgb2YgaWYgY2hlY2tzIChpbnN0ZWFkIG9mLCBzYXksIGEgcHJvcGVydHlcbiAqIG9iamVjdCBsb29rdXApIGZvciBwZXJmb3JtYW5jZSByZWFzb25zIC0gdGhlIHNlcmllcyBvZiBgaWZgIGNoZWNrcyBzZWVtcyB0byBiZSB0aGUgZmFzdGVzdCB3YXkgb2ZcbiAqIG1hcHBpbmcgcHJvcGVydHkgbmFtZXMuIERvIE5PVCBjaGFuZ2Ugd2l0aG91dCBiZW5jaG1hcmtpbmcuXG4gKlxuICogTm90ZTogdGhpcyBtYXBwaW5nIGhhcyB0byBiZSBrZXB0IGluIHN5bmMgd2l0aCB0aGUgZXF1YWxseSBuYW1lZCBtYXBwaW5nIGluIHRoZSB0ZW1wbGF0ZVxuICogdHlwZS1jaGVja2luZyBtYWNoaW5lcnkgb2Ygbmd0c2MuXG4gKi9cbmZ1bmN0aW9uIG1hcFByb3BOYW1lKG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChuYW1lID09PSAnY2xhc3MnKSByZXR1cm4gJ2NsYXNzTmFtZSc7XG4gIGlmIChuYW1lID09PSAnZm9yJykgcmV0dXJuICdodG1sRm9yJztcbiAgaWYgKG5hbWUgPT09ICdmb3JtYWN0aW9uJykgcmV0dXJuICdmb3JtQWN0aW9uJztcbiAgaWYgKG5hbWUgPT09ICdpbm5lckh0bWwnKSByZXR1cm4gJ2lubmVySFRNTCc7XG4gIGlmIChuYW1lID09PSAncmVhZG9ubHknKSByZXR1cm4gJ3JlYWRPbmx5JztcbiAgaWYgKG5hbWUgPT09ICd0YWJpbmRleCcpIHJldHVybiAndGFiSW5kZXgnO1xuICByZXR1cm4gbmFtZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVsZW1lbnRQcm9wZXJ0eUludGVybmFsPFQ+KFxuICAgIHRWaWV3OiBUVmlldywgdE5vZGU6IFROb2RlLCBsVmlldzogTFZpZXcsIHByb3BOYW1lOiBzdHJpbmcsIHZhbHVlOiBULCByZW5kZXJlcjogUmVuZGVyZXIzLFxuICAgIHNhbml0aXplcjogU2FuaXRpemVyRm58bnVsbHx1bmRlZmluZWQsIG5hdGl2ZU9ubHk6IGJvb2xlYW4pOiB2b2lkIHtcbiAgbmdEZXZNb2RlICYmIGFzc2VydE5vdFNhbWUodmFsdWUsIE5PX0NIQU5HRSBhcyBhbnksICdJbmNvbWluZyB2YWx1ZSBzaG91bGQgbmV2ZXIgYmUgTk9fQ0hBTkdFLicpO1xuICBjb25zdCBlbGVtZW50ID0gZ2V0TmF0aXZlQnlUTm9kZSh0Tm9kZSwgbFZpZXcpIGFzIFJFbGVtZW50IHwgUkNvbW1lbnQ7XG4gIGxldCBpbnB1dERhdGEgPSB0Tm9kZS5pbnB1dHM7XG4gIGxldCBkYXRhVmFsdWU6IFByb3BlcnR5QWxpYXNWYWx1ZXx1bmRlZmluZWQ7XG4gIGlmICghbmF0aXZlT25seSAmJiBpbnB1dERhdGEgIT0gbnVsbCAmJiAoZGF0YVZhbHVlID0gaW5wdXREYXRhW3Byb3BOYW1lXSkpIHtcbiAgICBzZXRJbnB1dHNGb3JQcm9wZXJ0eSh0VmlldywgbFZpZXcsIGRhdGFWYWx1ZSwgcHJvcE5hbWUsIHZhbHVlKTtcbiAgICBpZiAoaXNDb21wb25lbnRIb3N0KHROb2RlKSkgbWFya0RpcnR5SWZPblB1c2gobFZpZXcsIHROb2RlLmluZGV4KTtcbiAgICBpZiAobmdEZXZNb2RlKSB7XG4gICAgICBzZXROZ1JlZmxlY3RQcm9wZXJ0aWVzKGxWaWV3LCBlbGVtZW50LCB0Tm9kZS50eXBlLCBkYXRhVmFsdWUsIHZhbHVlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodE5vZGUudHlwZSAmIFROb2RlVHlwZS5BbnlSTm9kZSkge1xuICAgIHByb3BOYW1lID0gbWFwUHJvcE5hbWUocHJvcE5hbWUpO1xuXG4gICAgaWYgKG5nRGV2TW9kZSkge1xuICAgICAgdmFsaWRhdGVBZ2FpbnN0RXZlbnRQcm9wZXJ0aWVzKHByb3BOYW1lKTtcbiAgICAgIGlmICghdmFsaWRhdGVQcm9wZXJ0eSh0VmlldywgZWxlbWVudCwgcHJvcE5hbWUsIHROb2RlKSkge1xuICAgICAgICAvLyBSZXR1cm4gaGVyZSBzaW5jZSB3ZSBvbmx5IGxvZyB3YXJuaW5ncyBmb3IgdW5rbm93biBwcm9wZXJ0aWVzLlxuICAgICAgICBsb2dVbmtub3duUHJvcGVydHlFcnJvcihwcm9wTmFtZSwgdE5vZGUpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBuZ0Rldk1vZGUucmVuZGVyZXJTZXRQcm9wZXJ0eSsrO1xuICAgIH1cblxuICAgIC8vIEl0IGlzIGFzc3VtZWQgdGhhdCB0aGUgc2FuaXRpemVyIGlzIG9ubHkgYWRkZWQgd2hlbiB0aGUgY29tcGlsZXIgZGV0ZXJtaW5lcyB0aGF0IHRoZVxuICAgIC8vIHByb3BlcnR5IGlzIHJpc2t5LCBzbyBzYW5pdGl6YXRpb24gY2FuIGJlIGRvbmUgd2l0aG91dCBmdXJ0aGVyIGNoZWNrcy5cbiAgICB2YWx1ZSA9IHNhbml0aXplciAhPSBudWxsID8gKHNhbml0aXplcih2YWx1ZSwgdE5vZGUudmFsdWUgfHwgJycsIHByb3BOYW1lKSBhcyBhbnkpIDogdmFsdWU7XG4gICAgaWYgKGlzUHJvY2VkdXJhbFJlbmRlcmVyKHJlbmRlcmVyKSkge1xuICAgICAgcmVuZGVyZXIuc2V0UHJvcGVydHkoZWxlbWVudCBhcyBSRWxlbWVudCwgcHJvcE5hbWUsIHZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKCFpc0FuaW1hdGlvblByb3AocHJvcE5hbWUpKSB7XG4gICAgICAoZWxlbWVudCBhcyBSRWxlbWVudCkuc2V0UHJvcGVydHkgPyAoZWxlbWVudCBhcyBhbnkpLnNldFByb3BlcnR5KHByb3BOYW1lLCB2YWx1ZSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVsZW1lbnQgYXMgYW55KVtwcm9wTmFtZV0gPSB2YWx1ZTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodE5vZGUudHlwZSAmIFROb2RlVHlwZS5BbnlDb250YWluZXIpIHtcbiAgICAvLyBJZiB0aGUgbm9kZSBpcyBhIGNvbnRhaW5lciBhbmQgdGhlIHByb3BlcnR5IGRpZG4ndFxuICAgIC8vIG1hdGNoIGFueSBvZiB0aGUgaW5wdXRzIG9yIHNjaGVtYXMgd2Ugc2hvdWxkIHRocm93LlxuICAgIGlmIChuZ0Rldk1vZGUgJiYgIW1hdGNoaW5nU2NoZW1hcyh0VmlldywgdE5vZGUudmFsdWUpKSB7XG4gICAgICBsb2dVbmtub3duUHJvcGVydHlFcnJvcihwcm9wTmFtZSwgdE5vZGUpO1xuICAgIH1cbiAgfVxufVxuXG4vKiogSWYgbm9kZSBpcyBhbiBPblB1c2ggY29tcG9uZW50LCBtYXJrcyBpdHMgTFZpZXcgZGlydHkuICovXG5mdW5jdGlvbiBtYXJrRGlydHlJZk9uUHVzaChsVmlldzogTFZpZXcsIHZpZXdJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnRMVmlldyhsVmlldyk7XG4gIGNvbnN0IGNoaWxkQ29tcG9uZW50TFZpZXcgPSBnZXRDb21wb25lbnRMVmlld0J5SW5kZXgodmlld0luZGV4LCBsVmlldyk7XG4gIGlmICghKGNoaWxkQ29tcG9uZW50TFZpZXdbRkxBR1NdICYgTFZpZXdGbGFncy5DaGVja0Fsd2F5cykpIHtcbiAgICBjaGlsZENvbXBvbmVudExWaWV3W0ZMQUdTXSB8PSBMVmlld0ZsYWdzLkRpcnR5O1xuICB9XG59XG5cbmZ1bmN0aW9uIHNldE5nUmVmbGVjdFByb3BlcnR5KFxuICAgIGxWaWV3OiBMVmlldywgZWxlbWVudDogUkVsZW1lbnR8UkNvbW1lbnQsIHR5cGU6IFROb2RlVHlwZSwgYXR0ck5hbWU6IHN0cmluZywgdmFsdWU6IGFueSkge1xuICBjb25zdCByZW5kZXJlciA9IGxWaWV3W1JFTkRFUkVSXTtcbiAgYXR0ck5hbWUgPSBub3JtYWxpemVEZWJ1Z0JpbmRpbmdOYW1lKGF0dHJOYW1lKTtcbiAgY29uc3QgZGVidWdWYWx1ZSA9IG5vcm1hbGl6ZURlYnVnQmluZGluZ1ZhbHVlKHZhbHVlKTtcbiAgaWYgKHR5cGUgJiBUTm9kZVR5cGUuQW55Uk5vZGUpIHtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgaXNQcm9jZWR1cmFsUmVuZGVyZXIocmVuZGVyZXIpID8gcmVuZGVyZXIucmVtb3ZlQXR0cmlidXRlKChlbGVtZW50IGFzIFJFbGVtZW50KSwgYXR0ck5hbWUpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlbGVtZW50IGFzIFJFbGVtZW50KS5yZW1vdmVBdHRyaWJ1dGUoYXR0ck5hbWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpc1Byb2NlZHVyYWxSZW5kZXJlcihyZW5kZXJlcikgP1xuICAgICAgICAgIHJlbmRlcmVyLnNldEF0dHJpYnV0ZSgoZWxlbWVudCBhcyBSRWxlbWVudCksIGF0dHJOYW1lLCBkZWJ1Z1ZhbHVlKSA6XG4gICAgICAgICAgKGVsZW1lbnQgYXMgUkVsZW1lbnQpLnNldEF0dHJpYnV0ZShhdHRyTmFtZSwgZGVidWdWYWx1ZSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNvbnN0IHRleHRDb250ZW50ID1cbiAgICAgICAgZXNjYXBlQ29tbWVudFRleHQoYGJpbmRpbmdzPSR7SlNPTi5zdHJpbmdpZnkoe1thdHRyTmFtZV06IGRlYnVnVmFsdWV9LCBudWxsLCAyKX1gKTtcbiAgICBpZiAoaXNQcm9jZWR1cmFsUmVuZGVyZXIocmVuZGVyZXIpKSB7XG4gICAgICByZW5kZXJlci5zZXRWYWx1ZSgoZWxlbWVudCBhcyBSQ29tbWVudCksIHRleHRDb250ZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgKGVsZW1lbnQgYXMgUkNvbW1lbnQpLnRleHRDb250ZW50ID0gdGV4dENvbnRlbnQ7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXROZ1JlZmxlY3RQcm9wZXJ0aWVzKFxuICAgIGxWaWV3OiBMVmlldywgZWxlbWVudDogUkVsZW1lbnR8UkNvbW1lbnQsIHR5cGU6IFROb2RlVHlwZSwgZGF0YVZhbHVlOiBQcm9wZXJ0eUFsaWFzVmFsdWUsXG4gICAgdmFsdWU6IGFueSkge1xuICBpZiAodHlwZSAmIChUTm9kZVR5cGUuQW55Uk5vZGUgfCBUTm9kZVR5cGUuQ29udGFpbmVyKSkge1xuICAgIC8qKlxuICAgICAqIGRhdGFWYWx1ZSBpcyBhbiBhcnJheSBjb250YWluaW5nIHJ1bnRpbWUgaW5wdXQgb3Igb3V0cHV0IG5hbWVzIGZvciB0aGUgZGlyZWN0aXZlczpcbiAgICAgKiBpKzA6IGRpcmVjdGl2ZSBpbnN0YW5jZSBpbmRleFxuICAgICAqIGkrMTogcHJpdmF0ZU5hbWVcbiAgICAgKlxuICAgICAqIGUuZy4gWzAsICdjaGFuZ2UnLCAnY2hhbmdlLW1pbmlmaWVkJ11cbiAgICAgKiB3ZSB3YW50IHRvIHNldCB0aGUgcmVmbGVjdGVkIHByb3BlcnR5IHdpdGggdGhlIHByaXZhdGVOYW1lOiBkYXRhVmFsdWVbaSsxXVxuICAgICAqL1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YVZhbHVlLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgICBzZXROZ1JlZmxlY3RQcm9wZXJ0eShsVmlldywgZWxlbWVudCwgdHlwZSwgZGF0YVZhbHVlW2kgKyAxXSBhcyBzdHJpbmcsIHZhbHVlKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVQcm9wZXJ0eShcbiAgICB0VmlldzogVFZpZXcsIGVsZW1lbnQ6IFJFbGVtZW50fFJDb21tZW50LCBwcm9wTmFtZTogc3RyaW5nLCB0Tm9kZTogVE5vZGUpOiBib29sZWFuIHtcbiAgLy8gSWYgYHNjaGVtYXNgIGlzIHNldCB0byBgbnVsbGAsIHRoYXQncyBhbiBpbmRpY2F0aW9uIHRoYXQgdGhpcyBDb21wb25lbnQgd2FzIGNvbXBpbGVkIGluIEFPVFxuICAvLyBtb2RlIHdoZXJlIHRoaXMgY2hlY2sgaGFwcGVucyBhdCBjb21waWxlIHRpbWUuIEluIEpJVCBtb2RlLCBgc2NoZW1hc2AgaXMgYWx3YXlzIHByZXNlbnQgYW5kXG4gIC8vIGRlZmluZWQgYXMgYW4gYXJyYXkgKGFzIGFuIGVtcHR5IGFycmF5IGluIGNhc2UgYHNjaGVtYXNgIGZpZWxkIGlzIG5vdCBkZWZpbmVkKSBhbmQgd2Ugc2hvdWxkXG4gIC8vIGV4ZWN1dGUgdGhlIGNoZWNrIGJlbG93LlxuICBpZiAodFZpZXcuc2NoZW1hcyA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgLy8gVGhlIHByb3BlcnR5IGlzIGNvbnNpZGVyZWQgdmFsaWQgaWYgdGhlIGVsZW1lbnQgbWF0Y2hlcyB0aGUgc2NoZW1hLCBpdCBleGlzdHMgb24gdGhlIGVsZW1lbnRcbiAgLy8gb3IgaXQgaXMgc3ludGhldGljLCBhbmQgd2UgYXJlIGluIGEgYnJvd3NlciBjb250ZXh0ICh3ZWIgd29ya2VyIG5vZGVzIHNob3VsZCBiZSBza2lwcGVkKS5cbiAgaWYgKG1hdGNoaW5nU2NoZW1hcyh0VmlldywgdE5vZGUudmFsdWUpIHx8IHByb3BOYW1lIGluIGVsZW1lbnQgfHwgaXNBbmltYXRpb25Qcm9wKHByb3BOYW1lKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLy8gTm90ZTogYHR5cGVvZiBOb2RlYCByZXR1cm5zICdmdW5jdGlvbicgaW4gbW9zdCBicm93c2VycywgYnV0IG9uIElFIGl0IGlzICdvYmplY3QnIHNvIHdlXG4gIC8vIG5lZWQgdG8gYWNjb3VudCBmb3IgYm90aCBoZXJlLCB3aGlsZSBiZWluZyBjYXJlZnVsIGZvciBgdHlwZW9mIG51bGxgIGFsc28gcmV0dXJuaW5nICdvYmplY3QnLlxuICByZXR1cm4gdHlwZW9mIE5vZGUgPT09ICd1bmRlZmluZWQnIHx8IE5vZGUgPT09IG51bGwgfHwgIShlbGVtZW50IGluc3RhbmNlb2YgTm9kZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXRjaGluZ1NjaGVtYXModFZpZXc6IFRWaWV3LCB0YWdOYW1lOiBzdHJpbmd8bnVsbCk6IGJvb2xlYW4ge1xuICBjb25zdCBzY2hlbWFzID0gdFZpZXcuc2NoZW1hcztcblxuICBpZiAoc2NoZW1hcyAhPT0gbnVsbCkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2NoZW1hcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgc2NoZW1hID0gc2NoZW1hc1tpXTtcbiAgICAgIGlmIChzY2hlbWEgPT09IE5PX0VSUk9SU19TQ0hFTUEgfHxcbiAgICAgICAgICBzY2hlbWEgPT09IENVU1RPTV9FTEVNRU5UU19TQ0hFTUEgJiYgdGFnTmFtZSAmJiB0YWdOYW1lLmluZGV4T2YoJy0nKSA+IC0xKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBMb2dzIGFuIGVycm9yIHRoYXQgYSBwcm9wZXJ0eSBpcyBub3Qgc3VwcG9ydGVkIG9uIGFuIGVsZW1lbnQuXG4gKiBAcGFyYW0gcHJvcE5hbWUgTmFtZSBvZiB0aGUgaW52YWxpZCBwcm9wZXJ0eS5cbiAqIEBwYXJhbSB0Tm9kZSBOb2RlIG9uIHdoaWNoIHdlIGVuY291bnRlcmVkIHRoZSBwcm9wZXJ0eS5cbiAqL1xuZnVuY3Rpb24gbG9nVW5rbm93blByb3BlcnR5RXJyb3IocHJvcE5hbWU6IHN0cmluZywgdE5vZGU6IFROb2RlKTogdm9pZCB7XG4gIGxldCBtZXNzYWdlID0gYENhbid0IGJpbmQgdG8gJyR7cHJvcE5hbWV9JyBzaW5jZSBpdCBpc24ndCBhIGtub3duIHByb3BlcnR5IG9mICcke3ROb2RlLnZhbHVlfScuYDtcbiAgY29uc29sZS5lcnJvcihmb3JtYXRSdW50aW1lRXJyb3IoUnVudGltZUVycm9yQ29kZS5VTktOT1dOX0JJTkRJTkcsIG1lc3NhZ2UpKTtcbn1cblxuLyoqXG4gKiBJbnN0YW50aWF0ZSBhIHJvb3QgY29tcG9uZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5zdGFudGlhdGVSb290Q29tcG9uZW50PFQ+KHRWaWV3OiBUVmlldywgbFZpZXc6IExWaWV3LCBkZWY6IENvbXBvbmVudERlZjxUPik6IFQge1xuICBjb25zdCByb290VE5vZGUgPSBnZXRDdXJyZW50VE5vZGUoKSE7XG4gIGlmICh0Vmlldy5maXJzdENyZWF0ZVBhc3MpIHtcbiAgICBpZiAoZGVmLnByb3ZpZGVyc1Jlc29sdmVyKSBkZWYucHJvdmlkZXJzUmVzb2x2ZXIoZGVmKTtcbiAgICBjb25zdCBkaXJlY3RpdmVJbmRleCA9IGFsbG9jRXhwYW5kbyh0VmlldywgbFZpZXcsIDEsIG51bGwpO1xuICAgIG5nRGV2TW9kZSAmJlxuICAgICAgICBhc3NlcnRFcXVhbChcbiAgICAgICAgICAgIGRpcmVjdGl2ZUluZGV4LCByb290VE5vZGUuZGlyZWN0aXZlU3RhcnQsXG4gICAgICAgICAgICAnQmVjYXVzZSB0aGlzIGlzIGEgcm9vdCBjb21wb25lbnQgdGhlIGFsbG9jYXRlZCBleHBhbmRvIHNob3VsZCBtYXRjaCB0aGUgVE5vZGUgY29tcG9uZW50LicpO1xuICAgIGNvbmZpZ3VyZVZpZXdXaXRoRGlyZWN0aXZlKHRWaWV3LCByb290VE5vZGUsIGxWaWV3LCBkaXJlY3RpdmVJbmRleCwgZGVmKTtcbiAgfVxuICBjb25zdCBkaXJlY3RpdmUgPVxuICAgICAgZ2V0Tm9kZUluamVjdGFibGUobFZpZXcsIHRWaWV3LCByb290VE5vZGUuZGlyZWN0aXZlU3RhcnQsIHJvb3RUTm9kZSBhcyBURWxlbWVudE5vZGUpO1xuICBhdHRhY2hQYXRjaERhdGEoZGlyZWN0aXZlLCBsVmlldyk7XG4gIGNvbnN0IG5hdGl2ZSA9IGdldE5hdGl2ZUJ5VE5vZGUocm9vdFROb2RlLCBsVmlldyk7XG4gIGlmIChuYXRpdmUpIHtcbiAgICBhdHRhY2hQYXRjaERhdGEobmF0aXZlLCBsVmlldyk7XG4gIH1cbiAgcmV0dXJuIGRpcmVjdGl2ZTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIHRoZSBtYXRjaGVkIGRpcmVjdGl2ZXMgb24gYSBub2RlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZURpcmVjdGl2ZXMoXG4gICAgdFZpZXc6IFRWaWV3LCBsVmlldzogTFZpZXcsIHROb2RlOiBURWxlbWVudE5vZGV8VENvbnRhaW5lck5vZGV8VEVsZW1lbnRDb250YWluZXJOb2RlLFxuICAgIGxvY2FsUmVmczogc3RyaW5nW118bnVsbCk6IGJvb2xlYW4ge1xuICAvLyBQbGVhc2UgbWFrZSBzdXJlIHRvIGhhdmUgZXhwbGljaXQgdHlwZSBmb3IgYGV4cG9ydHNNYXBgLiBJbmZlcnJlZCB0eXBlIHRyaWdnZXJzIGJ1ZyBpblxuICAvLyB0c2lja2xlLlxuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0Rmlyc3RDcmVhdGVQYXNzKHRWaWV3KTtcblxuICBsZXQgaGFzRGlyZWN0aXZlcyA9IGZhbHNlO1xuICBpZiAoZ2V0QmluZGluZ3NFbmFibGVkKCkpIHtcbiAgICBjb25zdCBkaXJlY3RpdmVEZWZzOiBEaXJlY3RpdmVEZWY8YW55PltdfG51bGwgPSBmaW5kRGlyZWN0aXZlRGVmTWF0Y2hlcyh0VmlldywgbFZpZXcsIHROb2RlKTtcbiAgICBjb25zdCBleHBvcnRzTWFwOiAoe1trZXk6IHN0cmluZ106IG51bWJlcn18bnVsbCkgPSBsb2NhbFJlZnMgPT09IG51bGwgPyBudWxsIDogeycnOiAtMX07XG5cbiAgICBpZiAoZGlyZWN0aXZlRGVmcyAhPT0gbnVsbCkge1xuICAgICAgaGFzRGlyZWN0aXZlcyA9IHRydWU7XG4gICAgICBpbml0VE5vZGVGbGFncyh0Tm9kZSwgdFZpZXcuZGF0YS5sZW5ndGgsIGRpcmVjdGl2ZURlZnMubGVuZ3RoKTtcbiAgICAgIC8vIFdoZW4gdGhlIHNhbWUgdG9rZW4gaXMgcHJvdmlkZWQgYnkgc2V2ZXJhbCBkaXJlY3RpdmVzIG9uIHRoZSBzYW1lIG5vZGUsIHNvbWUgcnVsZXMgYXBwbHkgaW5cbiAgICAgIC8vIHRoZSB2aWV3RW5naW5lOlxuICAgICAgLy8gLSB2aWV3UHJvdmlkZXJzIGhhdmUgcHJpb3JpdHkgb3ZlciBwcm92aWRlcnNcbiAgICAgIC8vIC0gdGhlIGxhc3QgZGlyZWN0aXZlIGluIE5nTW9kdWxlLmRlY2xhcmF0aW9ucyBoYXMgcHJpb3JpdHkgb3ZlciB0aGUgcHJldmlvdXMgb25lXG4gICAgICAvLyBTbyB0byBtYXRjaCB0aGVzZSBydWxlcywgdGhlIG9yZGVyIGluIHdoaWNoIHByb3ZpZGVycyBhcmUgYWRkZWQgaW4gdGhlIGFycmF5cyBpcyB2ZXJ5XG4gICAgICAvLyBpbXBvcnRhbnQuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpcmVjdGl2ZURlZnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgZGVmID0gZGlyZWN0aXZlRGVmc1tpXTtcbiAgICAgICAgaWYgKGRlZi5wcm92aWRlcnNSZXNvbHZlcikgZGVmLnByb3ZpZGVyc1Jlc29sdmVyKGRlZik7XG4gICAgICB9XG4gICAgICBsZXQgcHJlT3JkZXJIb29rc0ZvdW5kID0gZmFsc2U7XG4gICAgICBsZXQgcHJlT3JkZXJDaGVja0hvb2tzRm91bmQgPSBmYWxzZTtcbiAgICAgIGxldCBkaXJlY3RpdmVJZHggPSBhbGxvY0V4cGFuZG8odFZpZXcsIGxWaWV3LCBkaXJlY3RpdmVEZWZzLmxlbmd0aCwgbnVsbCk7XG4gICAgICBuZ0Rldk1vZGUgJiZcbiAgICAgICAgICBhc3NlcnRTYW1lKFxuICAgICAgICAgICAgICBkaXJlY3RpdmVJZHgsIHROb2RlLmRpcmVjdGl2ZVN0YXJ0LFxuICAgICAgICAgICAgICAnVE5vZGUuZGlyZWN0aXZlU3RhcnQgc2hvdWxkIHBvaW50IHRvIGp1c3QgYWxsb2NhdGVkIHNwYWNlJyk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGlyZWN0aXZlRGVmcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBkZWYgPSBkaXJlY3RpdmVEZWZzW2ldO1xuICAgICAgICAvLyBNZXJnZSB0aGUgYXR0cnMgaW4gdGhlIG9yZGVyIG9mIG1hdGNoZXMuIFRoaXMgYXNzdW1lcyB0aGF0IHRoZSBmaXJzdCBkaXJlY3RpdmUgaXMgdGhlXG4gICAgICAgIC8vIGNvbXBvbmVudCBpdHNlbGYsIHNvIHRoYXQgdGhlIGNvbXBvbmVudCBoYXMgdGhlIGxlYXN0IHByaW9yaXR5LlxuICAgICAgICB0Tm9kZS5tZXJnZWRBdHRycyA9IG1lcmdlSG9zdEF0dHJzKHROb2RlLm1lcmdlZEF0dHJzLCBkZWYuaG9zdEF0dHJzKTtcblxuICAgICAgICBjb25maWd1cmVWaWV3V2l0aERpcmVjdGl2ZSh0VmlldywgdE5vZGUsIGxWaWV3LCBkaXJlY3RpdmVJZHgsIGRlZik7XG4gICAgICAgIHNhdmVOYW1lVG9FeHBvcnRNYXAoZGlyZWN0aXZlSWR4LCBkZWYsIGV4cG9ydHNNYXApO1xuXG4gICAgICAgIGlmIChkZWYuY29udGVudFF1ZXJpZXMgIT09IG51bGwpIHROb2RlLmZsYWdzIHw9IFROb2RlRmxhZ3MuaGFzQ29udGVudFF1ZXJ5O1xuICAgICAgICBpZiAoZGVmLmhvc3RCaW5kaW5ncyAhPT0gbnVsbCB8fCBkZWYuaG9zdEF0dHJzICE9PSBudWxsIHx8IGRlZi5ob3N0VmFycyAhPT0gMClcbiAgICAgICAgICB0Tm9kZS5mbGFncyB8PSBUTm9kZUZsYWdzLmhhc0hvc3RCaW5kaW5ncztcblxuICAgICAgICBjb25zdCBsaWZlQ3ljbGVIb29rczogT25DaGFuZ2VzJk9uSW5pdCZEb0NoZWNrID0gZGVmLnR5cGUucHJvdG90eXBlO1xuICAgICAgICAvLyBPbmx5IHB1c2ggYSBub2RlIGluZGV4IGludG8gdGhlIHByZU9yZGVySG9va3MgYXJyYXkgaWYgdGhpcyBpcyB0aGUgZmlyc3RcbiAgICAgICAgLy8gcHJlLW9yZGVyIGhvb2sgZm91bmQgb24gdGhpcyBub2RlLlxuICAgICAgICBpZiAoIXByZU9yZGVySG9va3NGb3VuZCAmJlxuICAgICAgICAgICAgKGxpZmVDeWNsZUhvb2tzLm5nT25DaGFuZ2VzIHx8IGxpZmVDeWNsZUhvb2tzLm5nT25Jbml0IHx8IGxpZmVDeWNsZUhvb2tzLm5nRG9DaGVjaykpIHtcbiAgICAgICAgICAvLyBXZSB3aWxsIHB1c2ggdGhlIGFjdHVhbCBob29rIGZ1bmN0aW9uIGludG8gdGhpcyBhcnJheSBsYXRlciBkdXJpbmcgZGlyIGluc3RhbnRpYXRpb24uXG4gICAgICAgICAgLy8gV2UgY2Fubm90IGRvIGl0IG5vdyBiZWNhdXNlIHdlIG11c3QgZW5zdXJlIGhvb2tzIGFyZSByZWdpc3RlcmVkIGluIHRoZSBzYW1lXG4gICAgICAgICAgLy8gb3JkZXIgdGhhdCBkaXJlY3RpdmVzIGFyZSBjcmVhdGVkIChpLmUuIGluamVjdGlvbiBvcmRlcikuXG4gICAgICAgICAgKHRWaWV3LnByZU9yZGVySG9va3MgfHwgKHRWaWV3LnByZU9yZGVySG9va3MgPSBbXSkpLnB1c2godE5vZGUuaW5kZXgpO1xuICAgICAgICAgIHByZU9yZGVySG9va3NGb3VuZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXByZU9yZGVyQ2hlY2tIb29rc0ZvdW5kICYmIChsaWZlQ3ljbGVIb29rcy5uZ09uQ2hhbmdlcyB8fCBsaWZlQ3ljbGVIb29rcy5uZ0RvQ2hlY2spKSB7XG4gICAgICAgICAgKHRWaWV3LnByZU9yZGVyQ2hlY2tIb29rcyB8fCAodFZpZXcucHJlT3JkZXJDaGVja0hvb2tzID0gW10pKS5wdXNoKHROb2RlLmluZGV4KTtcbiAgICAgICAgICBwcmVPcmRlckNoZWNrSG9va3NGb3VuZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBkaXJlY3RpdmVJZHgrKztcbiAgICAgIH1cblxuICAgICAgaW5pdGlhbGl6ZUlucHV0QW5kT3V0cHV0QWxpYXNlcyh0VmlldywgdE5vZGUpO1xuICAgIH1cbiAgICBpZiAoZXhwb3J0c01hcCkgY2FjaGVNYXRjaGluZ0xvY2FsTmFtZXModE5vZGUsIGxvY2FsUmVmcywgZXhwb3J0c01hcCk7XG4gIH1cbiAgLy8gTWVyZ2UgdGhlIHRlbXBsYXRlIGF0dHJzIGxhc3Qgc28gdGhhdCB0aGV5IGhhdmUgdGhlIGhpZ2hlc3QgcHJpb3JpdHkuXG4gIHROb2RlLm1lcmdlZEF0dHJzID0gbWVyZ2VIb3N0QXR0cnModE5vZGUubWVyZ2VkQXR0cnMsIHROb2RlLmF0dHJzKTtcbiAgcmV0dXJuIGhhc0RpcmVjdGl2ZXM7XG59XG5cbi8qKlxuICogQWRkIGBob3N0QmluZGluZ3NgIHRvIHRoZSBgVFZpZXcuaG9zdEJpbmRpbmdPcENvZGVzYC5cbiAqXG4gKiBAcGFyYW0gdFZpZXcgYFRWaWV3YCB0byB3aGljaCB0aGUgYGhvc3RCaW5kaW5nc2Agc2hvdWxkIGJlIGFkZGVkLlxuICogQHBhcmFtIHROb2RlIGBUTm9kZWAgdGhlIGVsZW1lbnQgd2hpY2ggY29udGFpbnMgdGhlIGRpcmVjdGl2ZVxuICogQHBhcmFtIGxWaWV3IGBMVmlld2AgY3VycmVudCBgTFZpZXdgXG4gKiBAcGFyYW0gZGlyZWN0aXZlSWR4IERpcmVjdGl2ZSBpbmRleCBpbiB2aWV3LlxuICogQHBhcmFtIGRpcmVjdGl2ZVZhcnNJZHggV2hlcmUgd2lsbCB0aGUgZGlyZWN0aXZlJ3MgdmFycyBiZSBzdG9yZWRcbiAqIEBwYXJhbSBkZWYgYENvbXBvbmVudERlZmAvYERpcmVjdGl2ZURlZmAsIHdoaWNoIGNvbnRhaW5zIHRoZSBgaG9zdFZhcnNgL2Bob3N0QmluZGluZ3NgIHRvIGFkZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVySG9zdEJpbmRpbmdPcENvZGVzKFxuICAgIHRWaWV3OiBUVmlldywgdE5vZGU6IFROb2RlLCBsVmlldzogTFZpZXcsIGRpcmVjdGl2ZUlkeDogbnVtYmVyLCBkaXJlY3RpdmVWYXJzSWR4OiBudW1iZXIsXG4gICAgZGVmOiBDb21wb25lbnREZWY8YW55PnxEaXJlY3RpdmVEZWY8YW55Pik6IHZvaWQge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0Rmlyc3RDcmVhdGVQYXNzKHRWaWV3KTtcblxuICBjb25zdCBob3N0QmluZGluZ3MgPSBkZWYuaG9zdEJpbmRpbmdzO1xuICBpZiAoaG9zdEJpbmRpbmdzKSB7XG4gICAgbGV0IGhvc3RCaW5kaW5nT3BDb2RlcyA9IHRWaWV3Lmhvc3RCaW5kaW5nT3BDb2RlcztcbiAgICBpZiAoaG9zdEJpbmRpbmdPcENvZGVzID09PSBudWxsKSB7XG4gICAgICBob3N0QmluZGluZ09wQ29kZXMgPSB0Vmlldy5ob3N0QmluZGluZ09wQ29kZXMgPSBbXSBhcyBhbnkgYXMgSG9zdEJpbmRpbmdPcENvZGVzO1xuICAgIH1cbiAgICBjb25zdCBlbGVtZW50SW5keCA9IH50Tm9kZS5pbmRleDtcbiAgICBpZiAobGFzdFNlbGVjdGVkRWxlbWVudElkeChob3N0QmluZGluZ09wQ29kZXMpICE9IGVsZW1lbnRJbmR4KSB7XG4gICAgICAvLyBDb25kaXRpb25hbGx5IGFkZCBzZWxlY3QgZWxlbWVudCBzbyB0aGF0IHdlIGFyZSBtb3JlIGVmZmljaWVudCBpbiBleGVjdXRpb24uXG4gICAgICAvLyBOT1RFOiB0aGlzIGlzIHN0cmljdGx5IG5vdCBuZWNlc3NhcnkgYW5kIGl0IHRyYWRlcyBjb2RlIHNpemUgZm9yIHJ1bnRpbWUgcGVyZi5cbiAgICAgIC8vIChXZSBjb3VsZCBqdXN0IGFsd2F5cyBhZGQgaXQuKVxuICAgICAgaG9zdEJpbmRpbmdPcENvZGVzLnB1c2goZWxlbWVudEluZHgpO1xuICAgIH1cbiAgICBob3N0QmluZGluZ09wQ29kZXMucHVzaChkaXJlY3RpdmVJZHgsIGRpcmVjdGl2ZVZhcnNJZHgsIGhvc3RCaW5kaW5ncyk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBsYXN0IHNlbGVjdGVkIGVsZW1lbnQgaW5kZXggaW4gdGhlIGBIb3N0QmluZGluZ09wQ29kZXNgXG4gKlxuICogRm9yIHBlcmYgcmVhc29ucyB3ZSBkb24ndCBuZWVkIHRvIHVwZGF0ZSB0aGUgc2VsZWN0ZWQgZWxlbWVudCBpbmRleCBpbiBgSG9zdEJpbmRpbmdPcENvZGVzYCBvbmx5XG4gKiBpZiBpdCBjaGFuZ2VzLiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBsYXN0IGluZGV4IChvciAnMCcgaWYgbm90IGZvdW5kLilcbiAqXG4gKiBTZWxlY3RlZCBlbGVtZW50IGluZGV4IGFyZSBvbmx5IHRoZSBvbmVzIHdoaWNoIGFyZSBuZWdhdGl2ZS5cbiAqL1xuZnVuY3Rpb24gbGFzdFNlbGVjdGVkRWxlbWVudElkeChob3N0QmluZGluZ09wQ29kZXM6IEhvc3RCaW5kaW5nT3BDb2Rlcyk6IG51bWJlciB7XG4gIGxldCBpID0gaG9zdEJpbmRpbmdPcENvZGVzLmxlbmd0aDtcbiAgd2hpbGUgKGkgPiAwKSB7XG4gICAgY29uc3QgdmFsdWUgPSBob3N0QmluZGluZ09wQ29kZXNbLS1pXTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiB2YWx1ZSA8IDApIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5cblxuLyoqXG4gKiBJbnN0YW50aWF0ZSBhbGwgdGhlIGRpcmVjdGl2ZXMgdGhhdCB3ZXJlIHByZXZpb3VzbHkgcmVzb2x2ZWQgb24gdGhlIGN1cnJlbnQgbm9kZS5cbiAqL1xuZnVuY3Rpb24gaW5zdGFudGlhdGVBbGxEaXJlY3RpdmVzKFxuICAgIHRWaWV3OiBUVmlldywgbFZpZXc6IExWaWV3LCB0Tm9kZTogVERpcmVjdGl2ZUhvc3ROb2RlLCBuYXRpdmU6IFJOb2RlKSB7XG4gIGNvbnN0IHN0YXJ0ID0gdE5vZGUuZGlyZWN0aXZlU3RhcnQ7XG4gIGNvbnN0IGVuZCA9IHROb2RlLmRpcmVjdGl2ZUVuZDtcbiAgaWYgKCF0Vmlldy5maXJzdENyZWF0ZVBhc3MpIHtcbiAgICBnZXRPckNyZWF0ZU5vZGVJbmplY3RvckZvck5vZGUodE5vZGUsIGxWaWV3KTtcbiAgfVxuXG4gIGF0dGFjaFBhdGNoRGF0YShuYXRpdmUsIGxWaWV3KTtcblxuICBjb25zdCBpbml0aWFsSW5wdXRzID0gdE5vZGUuaW5pdGlhbElucHV0cztcbiAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICBjb25zdCBkZWYgPSB0Vmlldy5kYXRhW2ldIGFzIERpcmVjdGl2ZURlZjxhbnk+O1xuICAgIGNvbnN0IGlzQ29tcG9uZW50ID0gaXNDb21wb25lbnREZWYoZGVmKTtcblxuICAgIGlmIChpc0NvbXBvbmVudCkge1xuICAgICAgbmdEZXZNb2RlICYmIGFzc2VydFROb2RlVHlwZSh0Tm9kZSwgVE5vZGVUeXBlLkFueVJOb2RlKTtcbiAgICAgIGFkZENvbXBvbmVudExvZ2ljKGxWaWV3LCB0Tm9kZSBhcyBURWxlbWVudE5vZGUsIGRlZiBhcyBDb21wb25lbnREZWY8YW55Pik7XG4gICAgfVxuXG4gICAgY29uc3QgZGlyZWN0aXZlID0gZ2V0Tm9kZUluamVjdGFibGUobFZpZXcsIHRWaWV3LCBpLCB0Tm9kZSk7XG4gICAgYXR0YWNoUGF0Y2hEYXRhKGRpcmVjdGl2ZSwgbFZpZXcpO1xuXG4gICAgaWYgKGluaXRpYWxJbnB1dHMgIT09IG51bGwpIHtcbiAgICAgIHNldElucHV0c0Zyb21BdHRycyhsVmlldywgaSAtIHN0YXJ0LCBkaXJlY3RpdmUsIGRlZiwgdE5vZGUsIGluaXRpYWxJbnB1dHMhKTtcbiAgICB9XG5cbiAgICBpZiAoaXNDb21wb25lbnQpIHtcbiAgICAgIGNvbnN0IGNvbXBvbmVudFZpZXcgPSBnZXRDb21wb25lbnRMVmlld0J5SW5kZXgodE5vZGUuaW5kZXgsIGxWaWV3KTtcbiAgICAgIGNvbXBvbmVudFZpZXdbQ09OVEVYVF0gPSBkaXJlY3RpdmU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGludm9rZURpcmVjdGl2ZXNIb3N0QmluZGluZ3ModFZpZXc6IFRWaWV3LCBsVmlldzogTFZpZXcsIHROb2RlOiBUTm9kZSkge1xuICBjb25zdCBzdGFydCA9IHROb2RlLmRpcmVjdGl2ZVN0YXJ0O1xuICBjb25zdCBlbmQgPSB0Tm9kZS5kaXJlY3RpdmVFbmQ7XG4gIGNvbnN0IGZpcnN0Q3JlYXRlUGFzcyA9IHRWaWV3LmZpcnN0Q3JlYXRlUGFzcztcbiAgY29uc3QgZWxlbWVudEluZGV4ID0gdE5vZGUuaW5kZXg7XG4gIGNvbnN0IGN1cnJlbnREaXJlY3RpdmVJbmRleCA9IGdldEN1cnJlbnREaXJlY3RpdmVJbmRleCgpO1xuICB0cnkge1xuICAgIHNldFNlbGVjdGVkSW5kZXgoZWxlbWVudEluZGV4KTtcbiAgICBmb3IgKGxldCBkaXJJbmRleCA9IHN0YXJ0OyBkaXJJbmRleCA8IGVuZDsgZGlySW5kZXgrKykge1xuICAgICAgY29uc3QgZGVmID0gdFZpZXcuZGF0YVtkaXJJbmRleF0gYXMgRGlyZWN0aXZlRGVmPHVua25vd24+O1xuICAgICAgY29uc3QgZGlyZWN0aXZlID0gbFZpZXdbZGlySW5kZXhdO1xuICAgICAgc2V0Q3VycmVudERpcmVjdGl2ZUluZGV4KGRpckluZGV4KTtcbiAgICAgIGlmIChkZWYuaG9zdEJpbmRpbmdzICE9PSBudWxsIHx8IGRlZi5ob3N0VmFycyAhPT0gMCB8fCBkZWYuaG9zdEF0dHJzICE9PSBudWxsKSB7XG4gICAgICAgIGludm9rZUhvc3RCaW5kaW5nc0luQ3JlYXRpb25Nb2RlKGRlZiwgZGlyZWN0aXZlKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZmluYWxseSB7XG4gICAgc2V0U2VsZWN0ZWRJbmRleCgtMSk7XG4gICAgc2V0Q3VycmVudERpcmVjdGl2ZUluZGV4KGN1cnJlbnREaXJlY3RpdmVJbmRleCk7XG4gIH1cbn1cblxuLyoqXG4gKiBJbnZva2UgdGhlIGhvc3QgYmluZGluZ3MgaW4gY3JlYXRpb24gbW9kZS5cbiAqXG4gKiBAcGFyYW0gZGVmIGBEaXJlY3RpdmVEZWZgIHdoaWNoIG1heSBjb250YWluIHRoZSBgaG9zdEJpbmRpbmdzYCBmdW5jdGlvbi5cbiAqIEBwYXJhbSBkaXJlY3RpdmUgSW5zdGFuY2Ugb2YgZGlyZWN0aXZlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW52b2tlSG9zdEJpbmRpbmdzSW5DcmVhdGlvbk1vZGUoZGVmOiBEaXJlY3RpdmVEZWY8YW55PiwgZGlyZWN0aXZlOiBhbnkpIHtcbiAgaWYgKGRlZi5ob3N0QmluZGluZ3MgIT09IG51bGwpIHtcbiAgICBkZWYuaG9zdEJpbmRpbmdzIShSZW5kZXJGbGFncy5DcmVhdGUsIGRpcmVjdGl2ZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBNYXRjaGVzIHRoZSBjdXJyZW50IG5vZGUgYWdhaW5zdCBhbGwgYXZhaWxhYmxlIHNlbGVjdG9ycy5cbiAqIElmIGEgY29tcG9uZW50IGlzIG1hdGNoZWQgKGF0IG1vc3Qgb25lKSwgaXQgaXMgcmV0dXJuZWQgaW4gZmlyc3QgcG9zaXRpb24gaW4gdGhlIGFycmF5LlxuICovXG5mdW5jdGlvbiBmaW5kRGlyZWN0aXZlRGVmTWF0Y2hlcyhcbiAgICB0VmlldzogVFZpZXcsIHZpZXdEYXRhOiBMVmlldyxcbiAgICB0Tm9kZTogVEVsZW1lbnROb2RlfFRDb250YWluZXJOb2RlfFRFbGVtZW50Q29udGFpbmVyTm9kZSk6IERpcmVjdGl2ZURlZjxhbnk+W118bnVsbCB7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnRGaXJzdENyZWF0ZVBhc3ModFZpZXcpO1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0VE5vZGVUeXBlKHROb2RlLCBUTm9kZVR5cGUuQW55Uk5vZGUgfCBUTm9kZVR5cGUuQW55Q29udGFpbmVyKTtcblxuICBjb25zdCByZWdpc3RyeSA9IHRWaWV3LmRpcmVjdGl2ZVJlZ2lzdHJ5O1xuICBsZXQgbWF0Y2hlczogYW55W118bnVsbCA9IG51bGw7XG4gIGlmIChyZWdpc3RyeSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVnaXN0cnkubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGRlZiA9IHJlZ2lzdHJ5W2ldIGFzIENvbXBvbmVudERlZjxhbnk+fCBEaXJlY3RpdmVEZWY8YW55PjtcbiAgICAgIGlmIChpc05vZGVNYXRjaGluZ1NlbGVjdG9yTGlzdCh0Tm9kZSwgZGVmLnNlbGVjdG9ycyEsIC8qIGlzUHJvamVjdGlvbk1vZGUgKi8gZmFsc2UpKSB7XG4gICAgICAgIG1hdGNoZXMgfHwgKG1hdGNoZXMgPSBuZ0Rldk1vZGUgPyBuZXcgTWF0Y2hlc0FycmF5KCkgOiBbXSk7XG4gICAgICAgIGRpUHVibGljSW5JbmplY3RvcihnZXRPckNyZWF0ZU5vZGVJbmplY3RvckZvck5vZGUodE5vZGUsIHZpZXdEYXRhKSwgdFZpZXcsIGRlZi50eXBlKTtcblxuICAgICAgICBpZiAoaXNDb21wb25lbnREZWYoZGVmKSkge1xuICAgICAgICAgIGlmIChuZ0Rldk1vZGUpIHtcbiAgICAgICAgICAgIGFzc2VydFROb2RlVHlwZShcbiAgICAgICAgICAgICAgICB0Tm9kZSwgVE5vZGVUeXBlLkVsZW1lbnQsXG4gICAgICAgICAgICAgICAgYFwiJHt0Tm9kZS52YWx1ZX1cIiB0YWdzIGNhbm5vdCBiZSB1c2VkIGFzIGNvbXBvbmVudCBob3N0cy4gYCArXG4gICAgICAgICAgICAgICAgICAgIGBQbGVhc2UgdXNlIGEgZGlmZmVyZW50IHRhZyB0byBhY3RpdmF0ZSB0aGUgJHtzdHJpbmdpZnkoZGVmLnR5cGUpfSBjb21wb25lbnQuYCk7XG5cbiAgICAgICAgICAgIGlmICh0Tm9kZS5mbGFncyAmIFROb2RlRmxhZ3MuaXNDb21wb25lbnRIb3N0KSB0aHJvd011bHRpcGxlQ29tcG9uZW50RXJyb3IodE5vZGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBtYXJrQXNDb21wb25lbnRIb3N0KHRWaWV3LCB0Tm9kZSk7XG4gICAgICAgICAgLy8gVGhlIGNvbXBvbmVudCBpcyBhbHdheXMgc3RvcmVkIGZpcnN0IHdpdGggZGlyZWN0aXZlcyBhZnRlci5cbiAgICAgICAgICBtYXRjaGVzLnVuc2hpZnQoZGVmKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtYXRjaGVzLnB1c2goZGVmKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gbWF0Y2hlcztcbn1cblxuLyoqXG4gKiBNYXJrcyBhIGdpdmVuIFROb2RlIGFzIGEgY29tcG9uZW50J3MgaG9zdC4gVGhpcyBjb25zaXN0cyBvZjpcbiAqIC0gc2V0dGluZyBhcHByb3ByaWF0ZSBUTm9kZSBmbGFncztcbiAqIC0gc3RvcmluZyBpbmRleCBvZiBjb21wb25lbnQncyBob3N0IGVsZW1lbnQgc28gaXQgd2lsbCBiZSBxdWV1ZWQgZm9yIHZpZXcgcmVmcmVzaCBkdXJpbmcgQ0QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrQXNDb21wb25lbnRIb3N0KHRWaWV3OiBUVmlldywgaG9zdFROb2RlOiBUTm9kZSk6IHZvaWQge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0Rmlyc3RDcmVhdGVQYXNzKHRWaWV3KTtcbiAgaG9zdFROb2RlLmZsYWdzIHw9IFROb2RlRmxhZ3MuaXNDb21wb25lbnRIb3N0O1xuICAodFZpZXcuY29tcG9uZW50cyB8fCAodFZpZXcuY29tcG9uZW50cyA9IG5nRGV2TW9kZSA/IG5ldyBUVmlld0NvbXBvbmVudHMoKSA6IFtdKSlcbiAgICAgIC5wdXNoKGhvc3RUTm9kZS5pbmRleCk7XG59XG5cblxuLyoqIENhY2hlcyBsb2NhbCBuYW1lcyBhbmQgdGhlaXIgbWF0Y2hpbmcgZGlyZWN0aXZlIGluZGljZXMgZm9yIHF1ZXJ5IGFuZCB0ZW1wbGF0ZSBsb29rdXBzLiAqL1xuZnVuY3Rpb24gY2FjaGVNYXRjaGluZ0xvY2FsTmFtZXMoXG4gICAgdE5vZGU6IFROb2RlLCBsb2NhbFJlZnM6IHN0cmluZ1tdfG51bGwsIGV4cG9ydHNNYXA6IHtba2V5OiBzdHJpbmddOiBudW1iZXJ9KTogdm9pZCB7XG4gIGlmIChsb2NhbFJlZnMpIHtcbiAgICBjb25zdCBsb2NhbE5hbWVzOiAoc3RyaW5nfG51bWJlcilbXSA9IHROb2RlLmxvY2FsTmFtZXMgPSBuZ0Rldk1vZGUgPyBuZXcgVE5vZGVMb2NhbE5hbWVzKCkgOiBbXTtcblxuICAgIC8vIExvY2FsIG5hbWVzIG11c3QgYmUgc3RvcmVkIGluIHROb2RlIGluIHRoZSBzYW1lIG9yZGVyIHRoYXQgbG9jYWxSZWZzIGFyZSBkZWZpbmVkXG4gICAgLy8gaW4gdGhlIHRlbXBsYXRlIHRvIGVuc3VyZSB0aGUgZGF0YSBpcyBsb2FkZWQgaW4gdGhlIHNhbWUgc2xvdHMgYXMgdGhlaXIgcmVmc1xuICAgIC8vIGluIHRoZSB0ZW1wbGF0ZSAoZm9yIHRlbXBsYXRlIHF1ZXJpZXMpLlxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbG9jYWxSZWZzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgICBjb25zdCBpbmRleCA9IGV4cG9ydHNNYXBbbG9jYWxSZWZzW2kgKyAxXV07XG4gICAgICBpZiAoaW5kZXggPT0gbnVsbClcbiAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcihcbiAgICAgICAgICAgIFJ1bnRpbWVFcnJvckNvZGUuRVhQT1JUX05PVF9GT1VORCwgYEV4cG9ydCBvZiBuYW1lICcke2xvY2FsUmVmc1tpICsgMV19JyBub3QgZm91bmQhYCk7XG4gICAgICBsb2NhbE5hbWVzLnB1c2gobG9jYWxSZWZzW2ldLCBpbmRleCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQnVpbGRzIHVwIGFuIGV4cG9ydCBtYXAgYXMgZGlyZWN0aXZlcyBhcmUgY3JlYXRlZCwgc28gbG9jYWwgcmVmcyBjYW4gYmUgcXVpY2tseSBtYXBwZWRcbiAqIHRvIHRoZWlyIGRpcmVjdGl2ZSBpbnN0YW5jZXMuXG4gKi9cbmZ1bmN0aW9uIHNhdmVOYW1lVG9FeHBvcnRNYXAoXG4gICAgZGlyZWN0aXZlSWR4OiBudW1iZXIsIGRlZjogRGlyZWN0aXZlRGVmPGFueT58Q29tcG9uZW50RGVmPGFueT4sXG4gICAgZXhwb3J0c01hcDoge1trZXk6IHN0cmluZ106IG51bWJlcn18bnVsbCkge1xuICBpZiAoZXhwb3J0c01hcCkge1xuICAgIGlmIChkZWYuZXhwb3J0QXMpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVmLmV4cG9ydEFzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGV4cG9ydHNNYXBbZGVmLmV4cG9ydEFzW2ldXSA9IGRpcmVjdGl2ZUlkeDtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzQ29tcG9uZW50RGVmKGRlZikpIGV4cG9ydHNNYXBbJyddID0gZGlyZWN0aXZlSWR4O1xuICB9XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgdGhlIGZsYWdzIG9uIHRoZSBjdXJyZW50IG5vZGUsIHNldHRpbmcgYWxsIGluZGljZXMgdG8gdGhlIGluaXRpYWwgaW5kZXgsXG4gKiB0aGUgZGlyZWN0aXZlIGNvdW50IHRvIDAsIGFuZCBhZGRpbmcgdGhlIGlzQ29tcG9uZW50IGZsYWcuXG4gKiBAcGFyYW0gaW5kZXggdGhlIGluaXRpYWwgaW5kZXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXRUTm9kZUZsYWdzKHROb2RlOiBUTm9kZSwgaW5kZXg6IG51bWJlciwgbnVtYmVyT2ZEaXJlY3RpdmVzOiBudW1iZXIpIHtcbiAgbmdEZXZNb2RlICYmXG4gICAgICBhc3NlcnROb3RFcXVhbChcbiAgICAgICAgICBudW1iZXJPZkRpcmVjdGl2ZXMsIHROb2RlLmRpcmVjdGl2ZUVuZCAtIHROb2RlLmRpcmVjdGl2ZVN0YXJ0LFxuICAgICAgICAgICdSZWFjaGVkIHRoZSBtYXggbnVtYmVyIG9mIGRpcmVjdGl2ZXMnKTtcbiAgdE5vZGUuZmxhZ3MgfD0gVE5vZGVGbGFncy5pc0RpcmVjdGl2ZUhvc3Q7XG4gIC8vIFdoZW4gdGhlIGZpcnN0IGRpcmVjdGl2ZSBpcyBjcmVhdGVkIG9uIGEgbm9kZSwgc2F2ZSB0aGUgaW5kZXhcbiAgdE5vZGUuZGlyZWN0aXZlU3RhcnQgPSBpbmRleDtcbiAgdE5vZGUuZGlyZWN0aXZlRW5kID0gaW5kZXggKyBudW1iZXJPZkRpcmVjdGl2ZXM7XG4gIHROb2RlLnByb3ZpZGVySW5kZXhlcyA9IGluZGV4O1xufVxuXG4vKipcbiAqIFNldHVwIGRpcmVjdGl2ZSBmb3IgaW5zdGFudGlhdGlvbi5cbiAqXG4gKiBXZSBuZWVkIHRvIGNyZWF0ZSBhIGBOb2RlSW5qZWN0b3JGYWN0b3J5YCB3aGljaCBpcyB0aGVuIGluc2VydGVkIGluIGJvdGggdGhlIGBCbHVlcHJpbnRgIGFzIHdlbGxcbiAqIGFzIGBMVmlld2AuIGBUVmlld2AgZ2V0cyB0aGUgYERpcmVjdGl2ZURlZmAuXG4gKlxuICogQHBhcmFtIHRWaWV3IGBUVmlld2BcbiAqIEBwYXJhbSB0Tm9kZSBgVE5vZGVgXG4gKiBAcGFyYW0gbFZpZXcgYExWaWV3YFxuICogQHBhcmFtIGRpcmVjdGl2ZUluZGV4IEluZGV4IHdoZXJlIHRoZSBkaXJlY3RpdmUgd2lsbCBiZSBzdG9yZWQgaW4gdGhlIEV4cGFuZG8uXG4gKiBAcGFyYW0gZGVmIGBEaXJlY3RpdmVEZWZgXG4gKi9cbmZ1bmN0aW9uIGNvbmZpZ3VyZVZpZXdXaXRoRGlyZWN0aXZlPFQ+KFxuICAgIHRWaWV3OiBUVmlldywgdE5vZGU6IFROb2RlLCBsVmlldzogTFZpZXcsIGRpcmVjdGl2ZUluZGV4OiBudW1iZXIsIGRlZjogRGlyZWN0aXZlRGVmPFQ+KTogdm9pZCB7XG4gIG5nRGV2TW9kZSAmJlxuICAgICAgYXNzZXJ0R3JlYXRlclRoYW5PckVxdWFsKGRpcmVjdGl2ZUluZGV4LCBIRUFERVJfT0ZGU0VULCAnTXVzdCBiZSBpbiBFeHBhbmRvIHNlY3Rpb24nKTtcbiAgdFZpZXcuZGF0YVtkaXJlY3RpdmVJbmRleF0gPSBkZWY7XG4gIGNvbnN0IGRpcmVjdGl2ZUZhY3RvcnkgPVxuICAgICAgZGVmLmZhY3RvcnkgfHwgKChkZWYgYXMge2ZhY3Rvcnk6IEZ1bmN0aW9ufSkuZmFjdG9yeSA9IGdldEZhY3RvcnlEZWYoZGVmLnR5cGUsIHRydWUpKTtcbiAgY29uc3Qgbm9kZUluamVjdG9yRmFjdG9yeSA9IG5ldyBOb2RlSW5qZWN0b3JGYWN0b3J5KGRpcmVjdGl2ZUZhY3RvcnksIGlzQ29tcG9uZW50RGVmKGRlZiksIG51bGwpO1xuICB0Vmlldy5ibHVlcHJpbnRbZGlyZWN0aXZlSW5kZXhdID0gbm9kZUluamVjdG9yRmFjdG9yeTtcbiAgbFZpZXdbZGlyZWN0aXZlSW5kZXhdID0gbm9kZUluamVjdG9yRmFjdG9yeTtcblxuICByZWdpc3Rlckhvc3RCaW5kaW5nT3BDb2RlcyhcbiAgICAgIHRWaWV3LCB0Tm9kZSwgbFZpZXcsIGRpcmVjdGl2ZUluZGV4LCBhbGxvY0V4cGFuZG8odFZpZXcsIGxWaWV3LCBkZWYuaG9zdFZhcnMsIE5PX0NIQU5HRSksXG4gICAgICBkZWYpO1xufVxuXG5mdW5jdGlvbiBhZGRDb21wb25lbnRMb2dpYzxUPihsVmlldzogTFZpZXcsIGhvc3RUTm9kZTogVEVsZW1lbnROb2RlLCBkZWY6IENvbXBvbmVudERlZjxUPik6IHZvaWQge1xuICBjb25zdCBuYXRpdmUgPSBnZXROYXRpdmVCeVROb2RlKGhvc3RUTm9kZSwgbFZpZXcpIGFzIFJFbGVtZW50O1xuICBjb25zdCB0VmlldyA9IGdldE9yQ3JlYXRlVENvbXBvbmVudFZpZXcoZGVmKTtcblxuICAvLyBPbmx5IGNvbXBvbmVudCB2aWV3cyBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIHZpZXcgdHJlZSBkaXJlY3RseS4gRW1iZWRkZWQgdmlld3MgYXJlXG4gIC8vIGFjY2Vzc2VkIHRocm91Z2ggdGhlaXIgY29udGFpbmVycyBiZWNhdXNlIHRoZXkgbWF5IGJlIHJlbW92ZWQgLyByZS1hZGRlZCBsYXRlci5cbiAgY29uc3QgcmVuZGVyZXJGYWN0b3J5ID0gbFZpZXdbUkVOREVSRVJfRkFDVE9SWV07XG4gIGNvbnN0IGNvbXBvbmVudFZpZXcgPSBhZGRUb1ZpZXdUcmVlKFxuICAgICAgbFZpZXcsXG4gICAgICBjcmVhdGVMVmlldyhcbiAgICAgICAgICBsVmlldywgdFZpZXcsIG51bGwsIGRlZi5vblB1c2ggPyBMVmlld0ZsYWdzLkRpcnR5IDogTFZpZXdGbGFncy5DaGVja0Fsd2F5cywgbmF0aXZlLFxuICAgICAgICAgIGhvc3RUTm9kZSBhcyBURWxlbWVudE5vZGUsIHJlbmRlcmVyRmFjdG9yeSwgcmVuZGVyZXJGYWN0b3J5LmNyZWF0ZVJlbmRlcmVyKG5hdGl2ZSwgZGVmKSxcbiAgICAgICAgICBudWxsLCBudWxsKSk7XG5cbiAgLy8gQ29tcG9uZW50IHZpZXcgd2lsbCBhbHdheXMgYmUgY3JlYXRlZCBiZWZvcmUgYW55IGluamVjdGVkIExDb250YWluZXJzLFxuICAvLyBzbyB0aGlzIGlzIGEgcmVndWxhciBlbGVtZW50LCB3cmFwIGl0IHdpdGggdGhlIGNvbXBvbmVudCB2aWV3XG4gIGxWaWV3W2hvc3RUTm9kZS5pbmRleF0gPSBjb21wb25lbnRWaWV3O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZWxlbWVudEF0dHJpYnV0ZUludGVybmFsKFxuICAgIHROb2RlOiBUTm9kZSwgbFZpZXc6IExWaWV3LCBuYW1lOiBzdHJpbmcsIHZhbHVlOiBhbnksIHNhbml0aXplcjogU2FuaXRpemVyRm58bnVsbHx1bmRlZmluZWQsXG4gICAgbmFtZXNwYWNlOiBzdHJpbmd8bnVsbHx1bmRlZmluZWQpIHtcbiAgaWYgKG5nRGV2TW9kZSkge1xuICAgIGFzc2VydE5vdFNhbWUodmFsdWUsIE5PX0NIQU5HRSBhcyBhbnksICdJbmNvbWluZyB2YWx1ZSBzaG91bGQgbmV2ZXIgYmUgTk9fQ0hBTkdFLicpO1xuICAgIHZhbGlkYXRlQWdhaW5zdEV2ZW50QXR0cmlidXRlcyhuYW1lKTtcbiAgICBhc3NlcnRUTm9kZVR5cGUoXG4gICAgICAgIHROb2RlLCBUTm9kZVR5cGUuRWxlbWVudCxcbiAgICAgICAgYEF0dGVtcHRlZCB0byBzZXQgYXR0cmlidXRlIFxcYCR7bmFtZX1cXGAgb24gYSBjb250YWluZXIgbm9kZS4gYCArXG4gICAgICAgICAgICBgSG9zdCBiaW5kaW5ncyBhcmUgbm90IHZhbGlkIG9uIG5nLWNvbnRhaW5lciBvciBuZy10ZW1wbGF0ZS5gKTtcbiAgfVxuICBjb25zdCBlbGVtZW50ID0gZ2V0TmF0aXZlQnlUTm9kZSh0Tm9kZSwgbFZpZXcpIGFzIFJFbGVtZW50O1xuICBzZXRFbGVtZW50QXR0cmlidXRlKGxWaWV3W1JFTkRFUkVSXSwgZWxlbWVudCwgbmFtZXNwYWNlLCB0Tm9kZS52YWx1ZSwgbmFtZSwgdmFsdWUsIHNhbml0aXplcik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRFbGVtZW50QXR0cmlidXRlKFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjMsIGVsZW1lbnQ6IFJFbGVtZW50LCBuYW1lc3BhY2U6IHN0cmluZ3xudWxsfHVuZGVmaW5lZCwgdGFnTmFtZTogc3RyaW5nfG51bGwsXG4gICAgbmFtZTogc3RyaW5nLCB2YWx1ZTogYW55LCBzYW5pdGl6ZXI6IFNhbml0aXplckZufG51bGx8dW5kZWZpbmVkKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgbmdEZXZNb2RlICYmIG5nRGV2TW9kZS5yZW5kZXJlclJlbW92ZUF0dHJpYnV0ZSsrO1xuICAgIGlzUHJvY2VkdXJhbFJlbmRlcmVyKHJlbmRlcmVyKSA/IHJlbmRlcmVyLnJlbW92ZUF0dHJpYnV0ZShlbGVtZW50LCBuYW1lLCBuYW1lc3BhY2UpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgfSBlbHNlIHtcbiAgICBuZ0Rldk1vZGUgJiYgbmdEZXZNb2RlLnJlbmRlcmVyU2V0QXR0cmlidXRlKys7XG4gICAgY29uc3Qgc3RyVmFsdWUgPVxuICAgICAgICBzYW5pdGl6ZXIgPT0gbnVsbCA/IHJlbmRlclN0cmluZ2lmeSh2YWx1ZSkgOiBzYW5pdGl6ZXIodmFsdWUsIHRhZ05hbWUgfHwgJycsIG5hbWUpO1xuXG5cbiAgICBpZiAoaXNQcm9jZWR1cmFsUmVuZGVyZXIocmVuZGVyZXIpKSB7XG4gICAgICByZW5kZXJlci5zZXRBdHRyaWJ1dGUoZWxlbWVudCwgbmFtZSwgc3RyVmFsdWUsIG5hbWVzcGFjZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWVzcGFjZSA/IGVsZW1lbnQuc2V0QXR0cmlidXRlTlMobmFtZXNwYWNlLCBuYW1lLCBzdHJWYWx1ZSkgOlxuICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUobmFtZSwgc3RyVmFsdWUpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFNldHMgaW5pdGlhbCBpbnB1dCBwcm9wZXJ0aWVzIG9uIGRpcmVjdGl2ZSBpbnN0YW5jZXMgZnJvbSBhdHRyaWJ1dGUgZGF0YVxuICpcbiAqIEBwYXJhbSBsVmlldyBDdXJyZW50IExWaWV3IHRoYXQgaXMgYmVpbmcgcHJvY2Vzc2VkLlxuICogQHBhcmFtIGRpcmVjdGl2ZUluZGV4IEluZGV4IG9mIHRoZSBkaXJlY3RpdmUgaW4gZGlyZWN0aXZlcyBhcnJheVxuICogQHBhcmFtIGluc3RhbmNlIEluc3RhbmNlIG9mIHRoZSBkaXJlY3RpdmUgb24gd2hpY2ggdG8gc2V0IHRoZSBpbml0aWFsIGlucHV0c1xuICogQHBhcmFtIGRlZiBUaGUgZGlyZWN0aXZlIGRlZiB0aGF0IGNvbnRhaW5zIHRoZSBsaXN0IG9mIGlucHV0c1xuICogQHBhcmFtIHROb2RlIFRoZSBzdGF0aWMgZGF0YSBmb3IgdGhpcyBub2RlXG4gKi9cbmZ1bmN0aW9uIHNldElucHV0c0Zyb21BdHRyczxUPihcbiAgICBsVmlldzogTFZpZXcsIGRpcmVjdGl2ZUluZGV4OiBudW1iZXIsIGluc3RhbmNlOiBULCBkZWY6IERpcmVjdGl2ZURlZjxUPiwgdE5vZGU6IFROb2RlLFxuICAgIGluaXRpYWxJbnB1dERhdGE6IEluaXRpYWxJbnB1dERhdGEpOiB2b2lkIHtcbiAgY29uc3QgaW5pdGlhbElucHV0czogSW5pdGlhbElucHV0c3xudWxsID0gaW5pdGlhbElucHV0RGF0YSFbZGlyZWN0aXZlSW5kZXhdO1xuICBpZiAoaW5pdGlhbElucHV0cyAhPT0gbnVsbCkge1xuICAgIGNvbnN0IHNldElucHV0ID0gZGVmLnNldElucHV0O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5pdGlhbElucHV0cy5sZW5ndGg7KSB7XG4gICAgICBjb25zdCBwdWJsaWNOYW1lID0gaW5pdGlhbElucHV0c1tpKytdO1xuICAgICAgY29uc3QgcHJpdmF0ZU5hbWUgPSBpbml0aWFsSW5wdXRzW2krK107XG4gICAgICBjb25zdCB2YWx1ZSA9IGluaXRpYWxJbnB1dHNbaSsrXTtcbiAgICAgIGlmIChzZXRJbnB1dCAhPT0gbnVsbCkge1xuICAgICAgICBkZWYuc2V0SW5wdXQhKGluc3RhbmNlLCB2YWx1ZSwgcHVibGljTmFtZSwgcHJpdmF0ZU5hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgKGluc3RhbmNlIGFzIGFueSlbcHJpdmF0ZU5hbWVdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAobmdEZXZNb2RlKSB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUVsZW1lbnQgPSBnZXROYXRpdmVCeVROb2RlKHROb2RlLCBsVmlldykgYXMgUkVsZW1lbnQ7XG4gICAgICAgIHNldE5nUmVmbGVjdFByb3BlcnR5KGxWaWV3LCBuYXRpdmVFbGVtZW50LCB0Tm9kZS50eXBlLCBwcml2YXRlTmFtZSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBpbml0aWFsSW5wdXREYXRhIGZvciBhIG5vZGUgYW5kIHN0b3JlcyBpdCBpbiB0aGUgdGVtcGxhdGUncyBzdGF0aWMgc3RvcmFnZVxuICogc28gc3Vic2VxdWVudCB0ZW1wbGF0ZSBpbnZvY2F0aW9ucyBkb24ndCBoYXZlIHRvIHJlY2FsY3VsYXRlIGl0LlxuICpcbiAqIGluaXRpYWxJbnB1dERhdGEgaXMgYW4gYXJyYXkgY29udGFpbmluZyB2YWx1ZXMgdGhhdCBuZWVkIHRvIGJlIHNldCBhcyBpbnB1dCBwcm9wZXJ0aWVzXG4gKiBmb3IgZGlyZWN0aXZlcyBvbiB0aGlzIG5vZGUsIGJ1dCBvbmx5IG9uY2Ugb24gY3JlYXRpb24uIFdlIG5lZWQgdGhpcyBhcnJheSB0byBzdXBwb3J0XG4gKiB0aGUgY2FzZSB3aGVyZSB5b3Ugc2V0IGFuIEBJbnB1dCBwcm9wZXJ0eSBvZiBhIGRpcmVjdGl2ZSB1c2luZyBhdHRyaWJ1dGUtbGlrZSBzeW50YXguXG4gKiBlLmcuIGlmIHlvdSBoYXZlIGEgYG5hbWVgIEBJbnB1dCwgeW91IGNhbiBzZXQgaXQgb25jZSBsaWtlIHRoaXM6XG4gKlxuICogPG15LWNvbXBvbmVudCBuYW1lPVwiQmVzc1wiPjwvbXktY29tcG9uZW50PlxuICpcbiAqIEBwYXJhbSBpbnB1dHMgVGhlIGxpc3Qgb2YgaW5wdXRzIGZyb20gdGhlIGRpcmVjdGl2ZSBkZWZcbiAqIEBwYXJhbSBhdHRycyBUaGUgc3RhdGljIGF0dHJzIG9uIHRoaXMgbm9kZVxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZUluaXRpYWxJbnB1dHMoaW5wdXRzOiB7W2tleTogc3RyaW5nXTogc3RyaW5nfSwgYXR0cnM6IFRBdHRyaWJ1dGVzKTogSW5pdGlhbElucHV0c3xcbiAgICBudWxsIHtcbiAgbGV0IGlucHV0c1RvU3RvcmU6IEluaXRpYWxJbnB1dHN8bnVsbCA9IG51bGw7XG4gIGxldCBpID0gMDtcbiAgd2hpbGUgKGkgPCBhdHRycy5sZW5ndGgpIHtcbiAgICBjb25zdCBhdHRyTmFtZSA9IGF0dHJzW2ldO1xuICAgIGlmIChhdHRyTmFtZSA9PT0gQXR0cmlidXRlTWFya2VyLk5hbWVzcGFjZVVSSSkge1xuICAgICAgLy8gV2UgZG8gbm90IGFsbG93IGlucHV0cyBvbiBuYW1lc3BhY2VkIGF0dHJpYnV0ZXMuXG4gICAgICBpICs9IDQ7XG4gICAgICBjb250aW51ZTtcbiAgICB9IGVsc2UgaWYgKGF0dHJOYW1lID09PSBBdHRyaWJ1dGVNYXJrZXIuUHJvamVjdEFzKSB7XG4gICAgICAvLyBTa2lwIG92ZXIgdGhlIGBuZ1Byb2plY3RBc2AgdmFsdWUuXG4gICAgICBpICs9IDI7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBJZiB3ZSBoaXQgYW55IG90aGVyIGF0dHJpYnV0ZSBtYXJrZXJzLCB3ZSdyZSBkb25lIGFueXdheS4gTm9uZSBvZiB0aG9zZSBhcmUgdmFsaWQgaW5wdXRzLlxuICAgIGlmICh0eXBlb2YgYXR0ck5hbWUgPT09ICdudW1iZXInKSBicmVhaztcblxuICAgIGlmIChpbnB1dHMuaGFzT3duUHJvcGVydHkoYXR0ck5hbWUgYXMgc3RyaW5nKSkge1xuICAgICAgaWYgKGlucHV0c1RvU3RvcmUgPT09IG51bGwpIGlucHV0c1RvU3RvcmUgPSBbXTtcbiAgICAgIGlucHV0c1RvU3RvcmUucHVzaChhdHRyTmFtZSBhcyBzdHJpbmcsIGlucHV0c1thdHRyTmFtZSBhcyBzdHJpbmddLCBhdHRyc1tpICsgMV0gYXMgc3RyaW5nKTtcbiAgICB9XG5cbiAgICBpICs9IDI7XG4gIH1cbiAgcmV0dXJuIGlucHV0c1RvU3RvcmU7XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLy8vIFZpZXdDb250YWluZXIgJiBWaWV3XG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vLyBOb3Qgc3VyZSB3aHkgSSBuZWVkIHRvIGRvIGBhbnlgIGhlcmUgYnV0IFRTIGNvbXBsYWlucyBsYXRlci5cbmNvbnN0IExDb250YWluZXJBcnJheTogYW55ID0gKCh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpICYmIGluaXROZ0Rldk1vZGUoKSkgJiZcbiAgICBjcmVhdGVOYW1lZEFycmF5VHlwZSgnTENvbnRhaW5lcicpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBMQ29udGFpbmVyLCBlaXRoZXIgZnJvbSBhIGNvbnRhaW5lciBpbnN0cnVjdGlvbiwgb3IgZm9yIGEgVmlld0NvbnRhaW5lclJlZi5cbiAqXG4gKiBAcGFyYW0gaG9zdE5hdGl2ZSBUaGUgaG9zdCBlbGVtZW50IGZvciB0aGUgTENvbnRhaW5lclxuICogQHBhcmFtIGhvc3RUTm9kZSBUaGUgaG9zdCBUTm9kZSBmb3IgdGhlIExDb250YWluZXJcbiAqIEBwYXJhbSBjdXJyZW50VmlldyBUaGUgcGFyZW50IHZpZXcgb2YgdGhlIExDb250YWluZXJcbiAqIEBwYXJhbSBuYXRpdmUgVGhlIG5hdGl2ZSBjb21tZW50IGVsZW1lbnRcbiAqIEBwYXJhbSBpc0ZvclZpZXdDb250YWluZXJSZWYgT3B0aW9uYWwgYSBmbGFnIGluZGljYXRpbmcgdGhlIFZpZXdDb250YWluZXJSZWYgY2FzZVxuICogQHJldHVybnMgTENvbnRhaW5lclxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTENvbnRhaW5lcihcbiAgICBob3N0TmF0aXZlOiBSRWxlbWVudHxSQ29tbWVudHxMVmlldywgY3VycmVudFZpZXc6IExWaWV3LCBuYXRpdmU6IFJDb21tZW50LFxuICAgIHROb2RlOiBUTm9kZSk6IExDb250YWluZXIge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TFZpZXcoY3VycmVudFZpZXcpO1xuICBuZ0Rldk1vZGUgJiYgIWlzUHJvY2VkdXJhbFJlbmRlcmVyKGN1cnJlbnRWaWV3W1JFTkRFUkVSXSkgJiYgYXNzZXJ0RG9tTm9kZShuYXRpdmUpO1xuICAvLyBodHRwczovL2pzcGVyZi5jb20vYXJyYXktbGl0ZXJhbC12cy1uZXctYXJyYXktcmVhbGx5XG4gIGNvbnN0IGxDb250YWluZXI6IExDb250YWluZXIgPSBuZXcgKG5nRGV2TW9kZSA/IExDb250YWluZXJBcnJheSA6IEFycmF5KShcbiAgICAgIGhvc3ROYXRpdmUsICAgLy8gaG9zdCBuYXRpdmVcbiAgICAgIHRydWUsICAgICAgICAgLy8gQm9vbGVhbiBgdHJ1ZWAgaW4gdGhpcyBwb3NpdGlvbiBzaWduaWZpZXMgdGhhdCB0aGlzIGlzIGFuIGBMQ29udGFpbmVyYFxuICAgICAgZmFsc2UsICAgICAgICAvLyBoYXMgdHJhbnNwbGFudGVkIHZpZXdzXG4gICAgICBjdXJyZW50VmlldywgIC8vIHBhcmVudFxuICAgICAgbnVsbCwgICAgICAgICAvLyBuZXh0XG4gICAgICAwLCAgICAgICAgICAgIC8vIHRyYW5zcGxhbnRlZCB2aWV3cyB0byByZWZyZXNoIGNvdW50XG4gICAgICB0Tm9kZSwgICAgICAgIC8vIHRfaG9zdFxuICAgICAgbmF0aXZlLCAgICAgICAvLyBuYXRpdmUsXG4gICAgICBudWxsLCAgICAgICAgIC8vIHZpZXcgcmVmc1xuICAgICAgbnVsbCwgICAgICAgICAvLyBtb3ZlZCB2aWV3c1xuICApO1xuICBuZ0Rldk1vZGUgJiZcbiAgICAgIGFzc2VydEVxdWFsKFxuICAgICAgICAgIGxDb250YWluZXIubGVuZ3RoLCBDT05UQUlORVJfSEVBREVSX09GRlNFVCxcbiAgICAgICAgICAnU2hvdWxkIGFsbG9jYXRlIGNvcnJlY3QgbnVtYmVyIG9mIHNsb3RzIGZvciBMQ29udGFpbmVyIGhlYWRlci4nKTtcbiAgbmdEZXZNb2RlICYmIGF0dGFjaExDb250YWluZXJEZWJ1ZyhsQ29udGFpbmVyKTtcbiAgcmV0dXJuIGxDb250YWluZXI7XG59XG5cbi8qKlxuICogR29lcyBvdmVyIGVtYmVkZGVkIHZpZXdzIChvbmVzIGNyZWF0ZWQgdGhyb3VnaCBWaWV3Q29udGFpbmVyUmVmIEFQSXMpIGFuZCByZWZyZXNoZXNcbiAqIHRoZW0gYnkgZXhlY3V0aW5nIGFuIGFzc29jaWF0ZWQgdGVtcGxhdGUgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIHJlZnJlc2hFbWJlZGRlZFZpZXdzKGxWaWV3OiBMVmlldykge1xuICBmb3IgKGxldCBsQ29udGFpbmVyID0gZ2V0Rmlyc3RMQ29udGFpbmVyKGxWaWV3KTsgbENvbnRhaW5lciAhPT0gbnVsbDtcbiAgICAgICBsQ29udGFpbmVyID0gZ2V0TmV4dExDb250YWluZXIobENvbnRhaW5lcikpIHtcbiAgICBmb3IgKGxldCBpID0gQ09OVEFJTkVSX0hFQURFUl9PRkZTRVQ7IGkgPCBsQ29udGFpbmVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBlbWJlZGRlZExWaWV3ID0gbENvbnRhaW5lcltpXTtcbiAgICAgIGNvbnN0IGVtYmVkZGVkVFZpZXcgPSBlbWJlZGRlZExWaWV3W1RWSUVXXTtcbiAgICAgIG5nRGV2TW9kZSAmJiBhc3NlcnREZWZpbmVkKGVtYmVkZGVkVFZpZXcsICdUVmlldyBtdXN0IGJlIGFsbG9jYXRlZCcpO1xuICAgICAgaWYgKHZpZXdBdHRhY2hlZFRvQ2hhbmdlRGV0ZWN0b3IoZW1iZWRkZWRMVmlldykpIHtcbiAgICAgICAgcmVmcmVzaFZpZXcoZW1iZWRkZWRUVmlldywgZW1iZWRkZWRMVmlldywgZW1iZWRkZWRUVmlldy50ZW1wbGF0ZSwgZW1iZWRkZWRMVmlld1tDT05URVhUXSEpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIE1hcmsgdHJhbnNwbGFudGVkIHZpZXdzIGFzIG5lZWRpbmcgdG8gYmUgcmVmcmVzaGVkIGF0IHRoZWlyIGluc2VydGlvbiBwb2ludHMuXG4gKlxuICogQHBhcmFtIGxWaWV3IFRoZSBgTFZpZXdgIHRoYXQgbWF5IGhhdmUgdHJhbnNwbGFudGVkIHZpZXdzLlxuICovXG5mdW5jdGlvbiBtYXJrVHJhbnNwbGFudGVkVmlld3NGb3JSZWZyZXNoKGxWaWV3OiBMVmlldykge1xuICBmb3IgKGxldCBsQ29udGFpbmVyID0gZ2V0Rmlyc3RMQ29udGFpbmVyKGxWaWV3KTsgbENvbnRhaW5lciAhPT0gbnVsbDtcbiAgICAgICBsQ29udGFpbmVyID0gZ2V0TmV4dExDb250YWluZXIobENvbnRhaW5lcikpIHtcbiAgICBpZiAoIWxDb250YWluZXJbSEFTX1RSQU5TUExBTlRFRF9WSUVXU10pIGNvbnRpbnVlO1xuXG4gICAgY29uc3QgbW92ZWRWaWV3cyA9IGxDb250YWluZXJbTU9WRURfVklFV1NdITtcbiAgICBuZ0Rldk1vZGUgJiYgYXNzZXJ0RGVmaW5lZChtb3ZlZFZpZXdzLCAnVHJhbnNwbGFudGVkIFZpZXcgZmxhZ3Mgc2V0IGJ1dCBtaXNzaW5nIE1PVkVEX1ZJRVdTJyk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtb3ZlZFZpZXdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBtb3ZlZExWaWV3ID0gbW92ZWRWaWV3c1tpXSE7XG4gICAgICBjb25zdCBpbnNlcnRpb25MQ29udGFpbmVyID0gbW92ZWRMVmlld1tQQVJFTlRdIGFzIExDb250YWluZXI7XG4gICAgICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TENvbnRhaW5lcihpbnNlcnRpb25MQ29udGFpbmVyKTtcbiAgICAgIC8vIFdlIGRvbid0IHdhbnQgdG8gaW5jcmVtZW50IHRoZSBjb3VudGVyIGlmIHRoZSBtb3ZlZCBMVmlldyB3YXMgYWxyZWFkeSBtYXJrZWQgZm9yXG4gICAgICAvLyByZWZyZXNoLlxuICAgICAgaWYgKChtb3ZlZExWaWV3W0ZMQUdTXSAmIExWaWV3RmxhZ3MuUmVmcmVzaFRyYW5zcGxhbnRlZFZpZXcpID09PSAwKSB7XG4gICAgICAgIHVwZGF0ZVRyYW5zcGxhbnRlZFZpZXdDb3VudChpbnNlcnRpb25MQ29udGFpbmVyLCAxKTtcbiAgICAgIH1cbiAgICAgIC8vIE5vdGUsIGl0IGlzIHBvc3NpYmxlIHRoYXQgdGhlIGBtb3ZlZFZpZXdzYCBpcyB0cmFja2luZyB2aWV3cyB0aGF0IGFyZSB0cmFuc3BsYW50ZWQgKmFuZCpcbiAgICAgIC8vIHRob3NlIHRoYXQgYXJlbid0IChkZWNsYXJhdGlvbiBjb21wb25lbnQgPT09IGluc2VydGlvbiBjb21wb25lbnQpLiBJbiB0aGUgbGF0dGVyIGNhc2UsXG4gICAgICAvLyBpdCdzIGZpbmUgdG8gYWRkIHRoZSBmbGFnLCBhcyB3ZSB3aWxsIGNsZWFyIGl0IGltbWVkaWF0ZWx5IGluXG4gICAgICAvLyBgcmVmcmVzaEVtYmVkZGVkVmlld3NgIGZvciB0aGUgdmlldyBjdXJyZW50bHkgYmVpbmcgcmVmcmVzaGVkLlxuICAgICAgbW92ZWRMVmlld1tGTEFHU10gfD0gTFZpZXdGbGFncy5SZWZyZXNoVHJhbnNwbGFudGVkVmlldztcbiAgICB9XG4gIH1cbn1cblxuLy8vLy8vLy8vLy8vL1xuXG4vKipcbiAqIFJlZnJlc2hlcyBjb21wb25lbnRzIGJ5IGVudGVyaW5nIHRoZSBjb21wb25lbnQgdmlldyBhbmQgcHJvY2Vzc2luZyBpdHMgYmluZGluZ3MsIHF1ZXJpZXMsIGV0Yy5cbiAqXG4gKiBAcGFyYW0gY29tcG9uZW50SG9zdElkeCAgRWxlbWVudCBpbmRleCBpbiBMVmlld1tdIChhZGp1c3RlZCBmb3IgSEVBREVSX09GRlNFVClcbiAqL1xuZnVuY3Rpb24gcmVmcmVzaENvbXBvbmVudChob3N0TFZpZXc6IExWaWV3LCBjb21wb25lbnRIb3N0SWR4OiBudW1iZXIpOiB2b2lkIHtcbiAgbmdEZXZNb2RlICYmIGFzc2VydEVxdWFsKGlzQ3JlYXRpb25Nb2RlKGhvc3RMVmlldyksIGZhbHNlLCAnU2hvdWxkIGJlIHJ1biBpbiB1cGRhdGUgbW9kZScpO1xuICBjb25zdCBjb21wb25lbnRWaWV3ID0gZ2V0Q29tcG9uZW50TFZpZXdCeUluZGV4KGNvbXBvbmVudEhvc3RJZHgsIGhvc3RMVmlldyk7XG4gIC8vIE9ubHkgYXR0YWNoZWQgY29tcG9uZW50cyB0aGF0IGFyZSBDaGVja0Fsd2F5cyBvciBPblB1c2ggYW5kIGRpcnR5IHNob3VsZCBiZSByZWZyZXNoZWRcbiAgaWYgKHZpZXdBdHRhY2hlZFRvQ2hhbmdlRGV0ZWN0b3IoY29tcG9uZW50VmlldykpIHtcbiAgICBjb25zdCB0VmlldyA9IGNvbXBvbmVudFZpZXdbVFZJRVddO1xuICAgIGlmIChjb21wb25lbnRWaWV3W0ZMQUdTXSAmIChMVmlld0ZsYWdzLkNoZWNrQWx3YXlzIHwgTFZpZXdGbGFncy5EaXJ0eSkpIHtcbiAgICAgIHJlZnJlc2hWaWV3KHRWaWV3LCBjb21wb25lbnRWaWV3LCB0Vmlldy50ZW1wbGF0ZSwgY29tcG9uZW50Vmlld1tDT05URVhUXSk7XG4gICAgfSBlbHNlIGlmIChjb21wb25lbnRWaWV3W1RSQU5TUExBTlRFRF9WSUVXU19UT19SRUZSRVNIXSA+IDApIHtcbiAgICAgIC8vIE9ubHkgYXR0YWNoZWQgY29tcG9uZW50cyB0aGF0IGFyZSBDaGVja0Fsd2F5cyBvciBPblB1c2ggYW5kIGRpcnR5IHNob3VsZCBiZSByZWZyZXNoZWRcbiAgICAgIHJlZnJlc2hDb250YWluc0RpcnR5Vmlldyhjb21wb25lbnRWaWV3KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZWZyZXNoZXMgYWxsIHRyYW5zcGxhbnRlZCB2aWV3cyBtYXJrZWQgd2l0aCBgTFZpZXdGbGFncy5SZWZyZXNoVHJhbnNwbGFudGVkVmlld2AgdGhhdCBhcmVcbiAqIGNoaWxkcmVuIG9yIGRlc2NlbmRhbnRzIG9mIHRoZSBnaXZlbiBsVmlldy5cbiAqXG4gKiBAcGFyYW0gbFZpZXcgVGhlIGxWaWV3IHdoaWNoIGNvbnRhaW5zIGRlc2NlbmRhbnQgdHJhbnNwbGFudGVkIHZpZXdzIHRoYXQgbmVlZCB0byBiZSByZWZyZXNoZWQuXG4gKi9cbmZ1bmN0aW9uIHJlZnJlc2hDb250YWluc0RpcnR5VmlldyhsVmlldzogTFZpZXcpIHtcbiAgZm9yIChsZXQgbENvbnRhaW5lciA9IGdldEZpcnN0TENvbnRhaW5lcihsVmlldyk7IGxDb250YWluZXIgIT09IG51bGw7XG4gICAgICAgbENvbnRhaW5lciA9IGdldE5leHRMQ29udGFpbmVyKGxDb250YWluZXIpKSB7XG4gICAgZm9yIChsZXQgaSA9IENPTlRBSU5FUl9IRUFERVJfT0ZGU0VUOyBpIDwgbENvbnRhaW5lci5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZW1iZWRkZWRMVmlldyA9IGxDb250YWluZXJbaV07XG4gICAgICBpZiAoZW1iZWRkZWRMVmlld1tGTEFHU10gJiBMVmlld0ZsYWdzLlJlZnJlc2hUcmFuc3BsYW50ZWRWaWV3KSB7XG4gICAgICAgIGNvbnN0IGVtYmVkZGVkVFZpZXcgPSBlbWJlZGRlZExWaWV3W1RWSUVXXTtcbiAgICAgICAgbmdEZXZNb2RlICYmIGFzc2VydERlZmluZWQoZW1iZWRkZWRUVmlldywgJ1RWaWV3IG11c3QgYmUgYWxsb2NhdGVkJyk7XG4gICAgICAgIHJlZnJlc2hWaWV3KGVtYmVkZGVkVFZpZXcsIGVtYmVkZGVkTFZpZXcsIGVtYmVkZGVkVFZpZXcudGVtcGxhdGUsIGVtYmVkZGVkTFZpZXdbQ09OVEVYVF0hKTtcbiAgICAgIH0gZWxzZSBpZiAoZW1iZWRkZWRMVmlld1tUUkFOU1BMQU5URURfVklFV1NfVE9fUkVGUkVTSF0gPiAwKSB7XG4gICAgICAgIHJlZnJlc2hDb250YWluc0RpcnR5VmlldyhlbWJlZGRlZExWaWV3KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCB0VmlldyA9IGxWaWV3W1RWSUVXXTtcbiAgLy8gUmVmcmVzaCBjaGlsZCBjb21wb25lbnQgdmlld3MuXG4gIGNvbnN0IGNvbXBvbmVudHMgPSB0Vmlldy5jb21wb25lbnRzO1xuICBpZiAoY29tcG9uZW50cyAhPT0gbnVsbCkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29tcG9uZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgY29tcG9uZW50VmlldyA9IGdldENvbXBvbmVudExWaWV3QnlJbmRleChjb21wb25lbnRzW2ldLCBsVmlldyk7XG4gICAgICAvLyBPbmx5IGF0dGFjaGVkIGNvbXBvbmVudHMgdGhhdCBhcmUgQ2hlY2tBbHdheXMgb3IgT25QdXNoIGFuZCBkaXJ0eSBzaG91bGQgYmUgcmVmcmVzaGVkXG4gICAgICBpZiAodmlld0F0dGFjaGVkVG9DaGFuZ2VEZXRlY3Rvcihjb21wb25lbnRWaWV3KSAmJlxuICAgICAgICAgIGNvbXBvbmVudFZpZXdbVFJBTlNQTEFOVEVEX1ZJRVdTX1RPX1JFRlJFU0hdID4gMCkge1xuICAgICAgICByZWZyZXNoQ29udGFpbnNEaXJ0eVZpZXcoY29tcG9uZW50Vmlldyk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHJlbmRlckNvbXBvbmVudChob3N0TFZpZXc6IExWaWV3LCBjb21wb25lbnRIb3N0SWR4OiBudW1iZXIpIHtcbiAgbmdEZXZNb2RlICYmIGFzc2VydEVxdWFsKGlzQ3JlYXRpb25Nb2RlKGhvc3RMVmlldyksIHRydWUsICdTaG91bGQgYmUgcnVuIGluIGNyZWF0aW9uIG1vZGUnKTtcbiAgY29uc3QgY29tcG9uZW50VmlldyA9IGdldENvbXBvbmVudExWaWV3QnlJbmRleChjb21wb25lbnRIb3N0SWR4LCBob3N0TFZpZXcpO1xuICBjb25zdCBjb21wb25lbnRUVmlldyA9IGNvbXBvbmVudFZpZXdbVFZJRVddO1xuICBzeW5jVmlld1dpdGhCbHVlcHJpbnQoY29tcG9uZW50VFZpZXcsIGNvbXBvbmVudFZpZXcpO1xuICByZW5kZXJWaWV3KGNvbXBvbmVudFRWaWV3LCBjb21wb25lbnRWaWV3LCBjb21wb25lbnRWaWV3W0NPTlRFWFRdKTtcbn1cblxuLyoqXG4gKiBTeW5jcyBhbiBMVmlldyBpbnN0YW5jZSB3aXRoIGl0cyBibHVlcHJpbnQgaWYgdGhleSBoYXZlIGdvdHRlbiBvdXQgb2Ygc3luYy5cbiAqXG4gKiBUeXBpY2FsbHksIGJsdWVwcmludHMgYW5kIHRoZWlyIHZpZXcgaW5zdGFuY2VzIHNob3VsZCBhbHdheXMgYmUgaW4gc3luYywgc28gdGhlIGxvb3AgaGVyZVxuICogd2lsbCBiZSBza2lwcGVkLiBIb3dldmVyLCBjb25zaWRlciB0aGlzIGNhc2Ugb2YgdHdvIGNvbXBvbmVudHMgc2lkZS1ieS1zaWRlOlxuICpcbiAqIEFwcCB0ZW1wbGF0ZTpcbiAqIGBgYFxuICogPGNvbXA+PC9jb21wPlxuICogPGNvbXA+PC9jb21wPlxuICogYGBgXG4gKlxuICogVGhlIGZvbGxvd2luZyB3aWxsIGhhcHBlbjpcbiAqIDEuIEFwcCB0ZW1wbGF0ZSBiZWdpbnMgcHJvY2Vzc2luZy5cbiAqIDIuIEZpcnN0IDxjb21wPiBpcyBtYXRjaGVkIGFzIGEgY29tcG9uZW50IGFuZCBpdHMgTFZpZXcgaXMgY3JlYXRlZC5cbiAqIDMuIFNlY29uZCA8Y29tcD4gaXMgbWF0Y2hlZCBhcyBhIGNvbXBvbmVudCBhbmQgaXRzIExWaWV3IGlzIGNyZWF0ZWQuXG4gKiA0LiBBcHAgdGVtcGxhdGUgY29tcGxldGVzIHByb2Nlc3NpbmcsIHNvIGl0J3MgdGltZSB0byBjaGVjayBjaGlsZCB0ZW1wbGF0ZXMuXG4gKiA1LiBGaXJzdCA8Y29tcD4gdGVtcGxhdGUgaXMgY2hlY2tlZC4gSXQgaGFzIGEgZGlyZWN0aXZlLCBzbyBpdHMgZGVmIGlzIHB1c2hlZCB0byBibHVlcHJpbnQuXG4gKiA2LiBTZWNvbmQgPGNvbXA+IHRlbXBsYXRlIGlzIGNoZWNrZWQuIEl0cyBibHVlcHJpbnQgaGFzIGJlZW4gdXBkYXRlZCBieSB0aGUgZmlyc3RcbiAqIDxjb21wPiB0ZW1wbGF0ZSwgYnV0IGl0cyBMVmlldyB3YXMgY3JlYXRlZCBiZWZvcmUgdGhpcyB1cGRhdGUsIHNvIGl0IGlzIG91dCBvZiBzeW5jLlxuICpcbiAqIE5vdGUgdGhhdCBlbWJlZGRlZCB2aWV3cyBpbnNpZGUgbmdGb3IgbG9vcHMgd2lsbCBuZXZlciBiZSBvdXQgb2Ygc3luYyBiZWNhdXNlIHRoZXNlIHZpZXdzXG4gKiBhcmUgcHJvY2Vzc2VkIGFzIHNvb24gYXMgdGhleSBhcmUgY3JlYXRlZC5cbiAqXG4gKiBAcGFyYW0gdFZpZXcgVGhlIGBUVmlld2AgdGhhdCBjb250YWlucyB0aGUgYmx1ZXByaW50IGZvciBzeW5jaW5nXG4gKiBAcGFyYW0gbFZpZXcgVGhlIHZpZXcgdG8gc3luY1xuICovXG5mdW5jdGlvbiBzeW5jVmlld1dpdGhCbHVlcHJpbnQodFZpZXc6IFRWaWV3LCBsVmlldzogTFZpZXcpIHtcbiAgZm9yIChsZXQgaSA9IGxWaWV3Lmxlbmd0aDsgaSA8IHRWaWV3LmJsdWVwcmludC5sZW5ndGg7IGkrKykge1xuICAgIGxWaWV3LnB1c2godFZpZXcuYmx1ZXByaW50W2ldKTtcbiAgfVxufVxuXG4vKipcbiAqIEFkZHMgTFZpZXcgb3IgTENvbnRhaW5lciB0byB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IHZpZXcgdHJlZS5cbiAqXG4gKiBUaGlzIHN0cnVjdHVyZSB3aWxsIGJlIHVzZWQgdG8gdHJhdmVyc2UgdGhyb3VnaCBuZXN0ZWQgdmlld3MgdG8gcmVtb3ZlIGxpc3RlbmVyc1xuICogYW5kIGNhbGwgb25EZXN0cm95IGNhbGxiYWNrcy5cbiAqXG4gKiBAcGFyYW0gbFZpZXcgVGhlIHZpZXcgd2hlcmUgTFZpZXcgb3IgTENvbnRhaW5lciBzaG91bGQgYmUgYWRkZWRcbiAqIEBwYXJhbSBhZGp1c3RlZEhvc3RJbmRleCBJbmRleCBvZiB0aGUgdmlldydzIGhvc3Qgbm9kZSBpbiBMVmlld1tdLCBhZGp1c3RlZCBmb3IgaGVhZGVyXG4gKiBAcGFyYW0gbFZpZXdPckxDb250YWluZXIgVGhlIExWaWV3IG9yIExDb250YWluZXIgdG8gYWRkIHRvIHRoZSB2aWV3IHRyZWVcbiAqIEByZXR1cm5zIFRoZSBzdGF0ZSBwYXNzZWQgaW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZFRvVmlld1RyZWU8VCBleHRlbmRzIExWaWV3fExDb250YWluZXI+KGxWaWV3OiBMVmlldywgbFZpZXdPckxDb250YWluZXI6IFQpOiBUIHtcbiAgLy8gVE9ETyhiZW5sZXNoL21pc2tvKTogVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBpbmNvcnJlY3QsIGJlY2F1c2UgaXQgYWx3YXlzIGFkZHMgdGhlIExDb250YWluZXJcbiAgLy8gdG8gdGhlIGVuZCBvZiB0aGUgcXVldWUsIHdoaWNoIG1lYW5zIGlmIHRoZSBkZXZlbG9wZXIgcmV0cmlldmVzIHRoZSBMQ29udGFpbmVycyBmcm9tIFJOb2RlcyBvdXRcbiAgLy8gb2Ygb3JkZXIsIHRoZSBjaGFuZ2UgZGV0ZWN0aW9uIHdpbGwgcnVuIG91dCBvZiBvcmRlciwgYXMgdGhlIGFjdCBvZiByZXRyaWV2aW5nIHRoZSB0aGVcbiAgLy8gTENvbnRhaW5lciBmcm9tIHRoZSBSTm9kZSBpcyB3aGF0IGFkZHMgaXQgdG8gdGhlIHF1ZXVlLlxuICBpZiAobFZpZXdbQ0hJTERfSEVBRF0pIHtcbiAgICBsVmlld1tDSElMRF9UQUlMXSFbTkVYVF0gPSBsVmlld09yTENvbnRhaW5lcjtcbiAgfSBlbHNlIHtcbiAgICBsVmlld1tDSElMRF9IRUFEXSA9IGxWaWV3T3JMQ29udGFpbmVyO1xuICB9XG4gIGxWaWV3W0NISUxEX1RBSUxdID0gbFZpZXdPckxDb250YWluZXI7XG4gIHJldHVybiBsVmlld09yTENvbnRhaW5lcjtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vLyBDaGFuZ2UgZGV0ZWN0aW9uXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cblxuLyoqXG4gKiBNYXJrcyBjdXJyZW50IHZpZXcgYW5kIGFsbCBhbmNlc3RvcnMgZGlydHkuXG4gKlxuICogUmV0dXJucyB0aGUgcm9vdCB2aWV3IGJlY2F1c2UgaXQgaXMgZm91bmQgYXMgYSBieXByb2R1Y3Qgb2YgbWFya2luZyB0aGUgdmlldyB0cmVlXG4gKiBkaXJ0eSwgYW5kIGNhbiBiZSB1c2VkIGJ5IG1ldGhvZHMgdGhhdCBjb25zdW1lIG1hcmtWaWV3RGlydHkoKSB0byBlYXNpbHkgc2NoZWR1bGVcbiAqIGNoYW5nZSBkZXRlY3Rpb24uIE90aGVyd2lzZSwgc3VjaCBtZXRob2RzIHdvdWxkIG5lZWQgdG8gdHJhdmVyc2UgdXAgdGhlIHZpZXcgdHJlZVxuICogYW4gYWRkaXRpb25hbCB0aW1lIHRvIGdldCB0aGUgcm9vdCB2aWV3IGFuZCBzY2hlZHVsZSBhIHRpY2sgb24gaXQuXG4gKlxuICogQHBhcmFtIGxWaWV3IFRoZSBzdGFydGluZyBMVmlldyB0byBtYXJrIGRpcnR5XG4gKiBAcmV0dXJucyB0aGUgcm9vdCBMVmlld1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWFya1ZpZXdEaXJ0eShsVmlldzogTFZpZXcpOiBMVmlld3xudWxsIHtcbiAgd2hpbGUgKGxWaWV3KSB7XG4gICAgbFZpZXdbRkxBR1NdIHw9IExWaWV3RmxhZ3MuRGlydHk7XG4gICAgY29uc3QgcGFyZW50ID0gZ2V0TFZpZXdQYXJlbnQobFZpZXcpO1xuICAgIC8vIFN0b3AgdHJhdmVyc2luZyB1cCBhcyBzb29uIGFzIHlvdSBmaW5kIGEgcm9vdCB2aWV3IHRoYXQgd2Fzbid0IGF0dGFjaGVkIHRvIGFueSBjb250YWluZXJcbiAgICBpZiAoaXNSb290VmlldyhsVmlldykgJiYgIXBhcmVudCkge1xuICAgICAgcmV0dXJuIGxWaWV3O1xuICAgIH1cbiAgICAvLyBjb250aW51ZSBvdGhlcndpc2VcbiAgICBsVmlldyA9IHBhcmVudCE7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cblxuLyoqXG4gKiBVc2VkIHRvIHNjaGVkdWxlIGNoYW5nZSBkZXRlY3Rpb24gb24gdGhlIHdob2xlIGFwcGxpY2F0aW9uLlxuICpcbiAqIFVubGlrZSBgdGlja2AsIGBzY2hlZHVsZVRpY2tgIGNvYWxlc2NlcyBtdWx0aXBsZSBjYWxscyBpbnRvIG9uZSBjaGFuZ2UgZGV0ZWN0aW9uIHJ1bi5cbiAqIEl0IGlzIHVzdWFsbHkgY2FsbGVkIGluZGlyZWN0bHkgYnkgY2FsbGluZyBgbWFya0RpcnR5YCB3aGVuIHRoZSB2aWV3IG5lZWRzIHRvIGJlXG4gKiByZS1yZW5kZXJlZC5cbiAqXG4gKiBUeXBpY2FsbHkgYHNjaGVkdWxlVGlja2AgdXNlcyBgcmVxdWVzdEFuaW1hdGlvbkZyYW1lYCB0byBjb2FsZXNjZSBtdWx0aXBsZVxuICogYHNjaGVkdWxlVGlja2AgcmVxdWVzdHMuIFRoZSBzY2hlZHVsaW5nIGZ1bmN0aW9uIGNhbiBiZSBvdmVycmlkZGVuIGluXG4gKiBgcmVuZGVyQ29tcG9uZW50YCdzIGBzY2hlZHVsZXJgIG9wdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjaGVkdWxlVGljayhyb290Q29udGV4dDogUm9vdENvbnRleHQsIGZsYWdzOiBSb290Q29udGV4dEZsYWdzKSB7XG4gIGNvbnN0IG5vdGhpbmdTY2hlZHVsZWQgPSByb290Q29udGV4dC5mbGFncyA9PT0gUm9vdENvbnRleHRGbGFncy5FbXB0eTtcbiAgaWYgKG5vdGhpbmdTY2hlZHVsZWQgJiYgcm9vdENvbnRleHQuY2xlYW4gPT0gX0NMRUFOX1BST01JU0UpIHtcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyL2lzc3Vlcy8zOTI5NlxuICAgIC8vIHNob3VsZCBvbmx5IGF0dGFjaCB0aGUgZmxhZ3Mgd2hlbiByZWFsbHkgc2NoZWR1bGluZyBhIHRpY2tcbiAgICByb290Q29udGV4dC5mbGFncyB8PSBmbGFncztcbiAgICBsZXQgcmVzOiBudWxsfCgodmFsOiBudWxsKSA9PiB2b2lkKTtcbiAgICByb290Q29udGV4dC5jbGVhbiA9IG5ldyBQcm9taXNlPG51bGw+KChyKSA9PiByZXMgPSByKTtcbiAgICByb290Q29udGV4dC5zY2hlZHVsZXIoKCkgPT4ge1xuICAgICAgaWYgKHJvb3RDb250ZXh0LmZsYWdzICYgUm9vdENvbnRleHRGbGFncy5EZXRlY3RDaGFuZ2VzKSB7XG4gICAgICAgIHJvb3RDb250ZXh0LmZsYWdzICY9IH5Sb290Q29udGV4dEZsYWdzLkRldGVjdENoYW5nZXM7XG4gICAgICAgIHRpY2tSb290Q29udGV4dChyb290Q29udGV4dCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyb290Q29udGV4dC5mbGFncyAmIFJvb3RDb250ZXh0RmxhZ3MuRmx1c2hQbGF5ZXJzKSB7XG4gICAgICAgIHJvb3RDb250ZXh0LmZsYWdzICY9IH5Sb290Q29udGV4dEZsYWdzLkZsdXNoUGxheWVycztcbiAgICAgICAgY29uc3QgcGxheWVySGFuZGxlciA9IHJvb3RDb250ZXh0LnBsYXllckhhbmRsZXI7XG4gICAgICAgIGlmIChwbGF5ZXJIYW5kbGVyKSB7XG4gICAgICAgICAgcGxheWVySGFuZGxlci5mbHVzaFBsYXllcnMoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByb290Q29udGV4dC5jbGVhbiA9IF9DTEVBTl9QUk9NSVNFO1xuICAgICAgcmVzIShudWxsKTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdGlja1Jvb3RDb250ZXh0KHJvb3RDb250ZXh0OiBSb290Q29udGV4dCkge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJvb3RDb250ZXh0LmNvbXBvbmVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCByb290Q29tcG9uZW50ID0gcm9vdENvbnRleHQuY29tcG9uZW50c1tpXTtcbiAgICBjb25zdCBsVmlldyA9IHJlYWRQYXRjaGVkTFZpZXcocm9vdENvbXBvbmVudCkhO1xuICAgIGNvbnN0IHRWaWV3ID0gbFZpZXdbVFZJRVddO1xuICAgIHJlbmRlckNvbXBvbmVudE9yVGVtcGxhdGUodFZpZXcsIGxWaWV3LCB0Vmlldy50ZW1wbGF0ZSwgcm9vdENvbXBvbmVudCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRldGVjdENoYW5nZXNJbnRlcm5hbDxUPih0VmlldzogVFZpZXcsIGxWaWV3OiBMVmlldywgY29udGV4dDogVCkge1xuICBjb25zdCByZW5kZXJlckZhY3RvcnkgPSBsVmlld1tSRU5ERVJFUl9GQUNUT1JZXTtcbiAgaWYgKHJlbmRlcmVyRmFjdG9yeS5iZWdpbikgcmVuZGVyZXJGYWN0b3J5LmJlZ2luKCk7XG4gIHRyeSB7XG4gICAgcmVmcmVzaFZpZXcodFZpZXcsIGxWaWV3LCB0Vmlldy50ZW1wbGF0ZSwgY29udGV4dCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaGFuZGxlRXJyb3IobFZpZXcsIGVycm9yKTtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfSBmaW5hbGx5IHtcbiAgICBpZiAocmVuZGVyZXJGYWN0b3J5LmVuZCkgcmVuZGVyZXJGYWN0b3J5LmVuZCgpO1xuICB9XG59XG5cbi8qKlxuICogU3luY2hyb25vdXNseSBwZXJmb3JtIGNoYW5nZSBkZXRlY3Rpb24gb24gYSByb290IHZpZXcgYW5kIGl0cyBjb21wb25lbnRzLlxuICpcbiAqIEBwYXJhbSBsVmlldyBUaGUgdmlldyB3aGljaCB0aGUgY2hhbmdlIGRldGVjdGlvbiBzaG91bGQgYmUgcGVyZm9ybWVkIG9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGV0ZWN0Q2hhbmdlc0luUm9vdFZpZXcobFZpZXc6IExWaWV3KTogdm9pZCB7XG4gIHRpY2tSb290Q29udGV4dChsVmlld1tDT05URVhUXSBhcyBSb290Q29udGV4dCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjaGVja05vQ2hhbmdlc0ludGVybmFsPFQ+KHRWaWV3OiBUVmlldywgdmlldzogTFZpZXcsIGNvbnRleHQ6IFQpIHtcbiAgc2V0SXNJbkNoZWNrTm9DaGFuZ2VzTW9kZSh0cnVlKTtcbiAgdHJ5IHtcbiAgICBkZXRlY3RDaGFuZ2VzSW50ZXJuYWwodFZpZXcsIHZpZXcsIGNvbnRleHQpO1xuICB9IGZpbmFsbHkge1xuICAgIHNldElzSW5DaGVja05vQ2hhbmdlc01vZGUoZmFsc2UpO1xuICB9XG59XG5cbi8qKlxuICogQ2hlY2tzIHRoZSBjaGFuZ2UgZGV0ZWN0b3Igb24gYSByb290IHZpZXcgYW5kIGl0cyBjb21wb25lbnRzLCBhbmQgdGhyb3dzIGlmIGFueSBjaGFuZ2VzIGFyZVxuICogZGV0ZWN0ZWQuXG4gKlxuICogVGhpcyBpcyB1c2VkIGluIGRldmVsb3BtZW50IG1vZGUgdG8gdmVyaWZ5IHRoYXQgcnVubmluZyBjaGFuZ2UgZGV0ZWN0aW9uIGRvZXNuJ3RcbiAqIGludHJvZHVjZSBvdGhlciBjaGFuZ2VzLlxuICpcbiAqIEBwYXJhbSBsVmlldyBUaGUgdmlldyB3aGljaCB0aGUgY2hhbmdlIGRldGVjdGlvbiBzaG91bGQgYmUgY2hlY2tlZCBvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrTm9DaGFuZ2VzSW5Sb290VmlldyhsVmlldzogTFZpZXcpOiB2b2lkIHtcbiAgc2V0SXNJbkNoZWNrTm9DaGFuZ2VzTW9kZSh0cnVlKTtcbiAgdHJ5IHtcbiAgICBkZXRlY3RDaGFuZ2VzSW5Sb290VmlldyhsVmlldyk7XG4gIH0gZmluYWxseSB7XG4gICAgc2V0SXNJbkNoZWNrTm9DaGFuZ2VzTW9kZShmYWxzZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZXhlY3V0ZVZpZXdRdWVyeUZuPFQ+KFxuICAgIGZsYWdzOiBSZW5kZXJGbGFncywgdmlld1F1ZXJ5Rm46IFZpZXdRdWVyaWVzRnVuY3Rpb248e30+LCBjb21wb25lbnQ6IFQpOiB2b2lkIHtcbiAgbmdEZXZNb2RlICYmIGFzc2VydERlZmluZWQodmlld1F1ZXJ5Rm4sICdWaWV3IHF1ZXJpZXMgZnVuY3Rpb24gdG8gZXhlY3V0ZSBtdXN0IGJlIGRlZmluZWQuJyk7XG4gIHNldEN1cnJlbnRRdWVyeUluZGV4KDApO1xuICB2aWV3UXVlcnlGbihmbGFncywgY29tcG9uZW50KTtcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLy8vIEJpbmRpbmdzICYgaW50ZXJwb2xhdGlvbnNcbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBTdG9yZXMgbWV0YS1kYXRhIGZvciBhIHByb3BlcnR5IGJpbmRpbmcgdG8gYmUgdXNlZCBieSBUZXN0QmVkJ3MgYERlYnVnRWxlbWVudC5wcm9wZXJ0aWVzYC5cbiAqXG4gKiBJbiBvcmRlciB0byBzdXBwb3J0IFRlc3RCZWQncyBgRGVidWdFbGVtZW50LnByb3BlcnRpZXNgIHdlIG5lZWQgdG8gc2F2ZSwgZm9yIGVhY2ggYmluZGluZzpcbiAqIC0gYSBib3VuZCBwcm9wZXJ0eSBuYW1lO1xuICogLSBhIHN0YXRpYyBwYXJ0cyBvZiBpbnRlcnBvbGF0ZWQgc3RyaW5ncztcbiAqXG4gKiBBIGdpdmVuIHByb3BlcnR5IG1ldGFkYXRhIGlzIHNhdmVkIGF0IHRoZSBiaW5kaW5nJ3MgaW5kZXggaW4gdGhlIGBUVmlldy5kYXRhYCAoaW4gb3RoZXIgd29yZHMsIGFcbiAqIHByb3BlcnR5IGJpbmRpbmcgbWV0YWRhdGEgd2lsbCBiZSBzdG9yZWQgaW4gYFRWaWV3LmRhdGFgIGF0IHRoZSBzYW1lIGluZGV4IGFzIGEgYm91bmQgdmFsdWUgaW5cbiAqIGBMVmlld2ApLiBNZXRhZGF0YSBhcmUgcmVwcmVzZW50ZWQgYXMgYElOVEVSUE9MQVRJT05fREVMSU1JVEVSYC1kZWxpbWl0ZWQgc3RyaW5nIHdpdGggdGhlXG4gKiBmb2xsb3dpbmcgZm9ybWF0OlxuICogLSBgcHJvcGVydHlOYW1lYCBmb3IgYm91bmQgcHJvcGVydGllcztcbiAqIC0gYHByb3BlcnR5TmFtZe+/vXByZWZpeO+/vWludGVycG9sYXRpb25fc3RhdGljX3BhcnQx77+9Li5pbnRlcnBvbGF0aW9uX3N0YXRpY19wYXJ0Tu+/vXN1ZmZpeGAgZm9yXG4gKiBpbnRlcnBvbGF0ZWQgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0gdERhdGEgYFREYXRhYCB3aGVyZSBtZXRhLWRhdGEgd2lsbCBiZSBzYXZlZDtcbiAqIEBwYXJhbSB0Tm9kZSBgVE5vZGVgIHRoYXQgaXMgYSB0YXJnZXQgb2YgdGhlIGJpbmRpbmc7XG4gKiBAcGFyYW0gcHJvcGVydHlOYW1lIGJvdW5kIHByb3BlcnR5IG5hbWU7XG4gKiBAcGFyYW0gYmluZGluZ0luZGV4IGJpbmRpbmcgaW5kZXggaW4gYExWaWV3YFxuICogQHBhcmFtIGludGVycG9sYXRpb25QYXJ0cyBzdGF0aWMgaW50ZXJwb2xhdGlvbiBwYXJ0cyAoZm9yIHByb3BlcnR5IGludGVycG9sYXRpb25zKVxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RvcmVQcm9wZXJ0eUJpbmRpbmdNZXRhZGF0YShcbiAgICB0RGF0YTogVERhdGEsIHROb2RlOiBUTm9kZSwgcHJvcGVydHlOYW1lOiBzdHJpbmcsIGJpbmRpbmdJbmRleDogbnVtYmVyLFxuICAgIC4uLmludGVycG9sYXRpb25QYXJ0czogc3RyaW5nW10pIHtcbiAgLy8gQmluZGluZyBtZXRhLWRhdGEgYXJlIHN0b3JlZCBvbmx5IHRoZSBmaXJzdCB0aW1lIGEgZ2l2ZW4gcHJvcGVydHkgaW5zdHJ1Y3Rpb24gaXMgcHJvY2Vzc2VkLlxuICAvLyBTaW5jZSB3ZSBkb24ndCBoYXZlIGEgY29uY2VwdCBvZiB0aGUgXCJmaXJzdCB1cGRhdGUgcGFzc1wiIHdlIG5lZWQgdG8gY2hlY2sgZm9yIHByZXNlbmNlIG9mIHRoZVxuICAvLyBiaW5kaW5nIG1ldGEtZGF0YSB0byBkZWNpZGUgaWYgb25lIHNob3VsZCBiZSBzdG9yZWQgKG9yIGlmIHdhcyBzdG9yZWQgYWxyZWFkeSkuXG4gIGlmICh0RGF0YVtiaW5kaW5nSW5kZXhdID09PSBudWxsKSB7XG4gICAgaWYgKHROb2RlLmlucHV0cyA9PSBudWxsIHx8ICF0Tm9kZS5pbnB1dHNbcHJvcGVydHlOYW1lXSkge1xuICAgICAgY29uc3QgcHJvcEJpbmRpbmdJZHhzID0gdE5vZGUucHJvcGVydHlCaW5kaW5ncyB8fCAodE5vZGUucHJvcGVydHlCaW5kaW5ncyA9IFtdKTtcbiAgICAgIHByb3BCaW5kaW5nSWR4cy5wdXNoKGJpbmRpbmdJbmRleCk7XG4gICAgICBsZXQgYmluZGluZ01ldGFkYXRhID0gcHJvcGVydHlOYW1lO1xuICAgICAgaWYgKGludGVycG9sYXRpb25QYXJ0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGJpbmRpbmdNZXRhZGF0YSArPVxuICAgICAgICAgICAgSU5URVJQT0xBVElPTl9ERUxJTUlURVIgKyBpbnRlcnBvbGF0aW9uUGFydHMuam9pbihJTlRFUlBPTEFUSU9OX0RFTElNSVRFUik7XG4gICAgICB9XG4gICAgICB0RGF0YVtiaW5kaW5nSW5kZXhdID0gYmluZGluZ01ldGFkYXRhO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgQ0xFQU5fUFJPTUlTRSA9IF9DTEVBTl9QUk9NSVNFO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0T3JDcmVhdGVMVmlld0NsZWFudXAodmlldzogTFZpZXcpOiBhbnlbXSB7XG4gIC8vIHRvcCBsZXZlbCB2YXJpYWJsZXMgc2hvdWxkIG5vdCBiZSBleHBvcnRlZCBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucyAoUEVSRl9OT1RFUy5tZClcbiAgcmV0dXJuIHZpZXdbQ0xFQU5VUF0gfHwgKHZpZXdbQ0xFQU5VUF0gPSBuZ0Rldk1vZGUgPyBuZXcgTENsZWFudXAoKSA6IFtdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE9yQ3JlYXRlVFZpZXdDbGVhbnVwKHRWaWV3OiBUVmlldyk6IGFueVtdIHtcbiAgcmV0dXJuIHRWaWV3LmNsZWFudXAgfHwgKHRWaWV3LmNsZWFudXAgPSBuZ0Rldk1vZGUgPyBuZXcgVENsZWFudXAoKSA6IFtdKTtcbn1cblxuLyoqXG4gKiBUaGVyZSBhcmUgY2FzZXMgd2hlcmUgdGhlIHN1YiBjb21wb25lbnQncyByZW5kZXJlciBuZWVkcyB0byBiZSBpbmNsdWRlZFxuICogaW5zdGVhZCBvZiB0aGUgY3VycmVudCByZW5kZXJlciAoc2VlIHRoZSBjb21wb25lbnRTeW50aGV0aWNIb3N0KiBpbnN0cnVjdGlvbnMpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZENvbXBvbmVudFJlbmRlcmVyKFxuICAgIGN1cnJlbnREZWY6IERpcmVjdGl2ZURlZjxhbnk+fG51bGwsIHROb2RlOiBUTm9kZSwgbFZpZXc6IExWaWV3KTogUmVuZGVyZXIzIHtcbiAgLy8gVE9ETyhGVy0yMDQzKTogdGhlIGBjdXJyZW50RGVmYCBpcyBudWxsIHdoZW4gaG9zdCBiaW5kaW5ncyBhcmUgaW52b2tlZCB3aGlsZSBjcmVhdGluZyByb290XG4gIC8vIGNvbXBvbmVudCAoc2VlIHBhY2thZ2VzL2NvcmUvc3JjL3JlbmRlcjMvY29tcG9uZW50LnRzKS4gVGhpcyBpcyBub3QgY29uc2lzdGVudCB3aXRoIHRoZSBwcm9jZXNzXG4gIC8vIG9mIGNyZWF0aW5nIGlubmVyIGNvbXBvbmVudHMsIHdoZW4gY3VycmVudCBkaXJlY3RpdmUgaW5kZXggaXMgYXZhaWxhYmxlIGluIHRoZSBzdGF0ZS4gSW4gb3JkZXJcbiAgLy8gdG8gYXZvaWQgcmVseWluZyBvbiBjdXJyZW50IGRlZiBiZWluZyBgbnVsbGAgKHRodXMgc3BlY2lhbC1jYXNpbmcgcm9vdCBjb21wb25lbnQgY3JlYXRpb24pLCB0aGVcbiAgLy8gcHJvY2VzcyBvZiBjcmVhdGluZyByb290IGNvbXBvbmVudCBzaG91bGQgYmUgdW5pZmllZCB3aXRoIHRoZSBwcm9jZXNzIG9mIGNyZWF0aW5nIGlubmVyXG4gIC8vIGNvbXBvbmVudHMuXG4gIGlmIChjdXJyZW50RGVmID09PSBudWxsIHx8IGlzQ29tcG9uZW50RGVmKGN1cnJlbnREZWYpKSB7XG4gICAgbFZpZXcgPSB1bndyYXBMVmlldyhsVmlld1t0Tm9kZS5pbmRleF0pITtcbiAgfVxuICByZXR1cm4gbFZpZXdbUkVOREVSRVJdO1xufVxuXG4vKiogSGFuZGxlcyBhbiBlcnJvciB0aHJvd24gaW4gYW4gTFZpZXcuICovXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlRXJyb3IobFZpZXc6IExWaWV3LCBlcnJvcjogYW55KTogdm9pZCB7XG4gIGNvbnN0IGluamVjdG9yID0gbFZpZXdbSU5KRUNUT1JdO1xuICBjb25zdCBlcnJvckhhbmRsZXIgPSBpbmplY3RvciA/IGluamVjdG9yLmdldChFcnJvckhhbmRsZXIsIG51bGwpIDogbnVsbDtcbiAgZXJyb3JIYW5kbGVyICYmIGVycm9ySGFuZGxlci5oYW5kbGVFcnJvcihlcnJvcik7XG59XG5cbi8qKlxuICogU2V0IHRoZSBpbnB1dHMgb2YgZGlyZWN0aXZlcyBhdCB0aGUgY3VycmVudCBub2RlIHRvIGNvcnJlc3BvbmRpbmcgdmFsdWUuXG4gKlxuICogQHBhcmFtIHRWaWV3IFRoZSBjdXJyZW50IFRWaWV3XG4gKiBAcGFyYW0gbFZpZXcgdGhlIGBMVmlld2Agd2hpY2ggY29udGFpbnMgdGhlIGRpcmVjdGl2ZXMuXG4gKiBAcGFyYW0gaW5wdXRzIG1hcHBpbmcgYmV0d2VlbiB0aGUgcHVibGljIFwiaW5wdXRcIiBuYW1lIGFuZCBwcml2YXRlbHkta25vd24sXG4gKiAgICAgICAgcG9zc2libHkgbWluaWZpZWQsIHByb3BlcnR5IG5hbWVzIHRvIHdyaXRlIHRvLlxuICogQHBhcmFtIHZhbHVlIFZhbHVlIHRvIHNldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldElucHV0c0ZvclByb3BlcnR5KFxuICAgIHRWaWV3OiBUVmlldywgbFZpZXc6IExWaWV3LCBpbnB1dHM6IFByb3BlcnR5QWxpYXNWYWx1ZSwgcHVibGljTmFtZTogc3RyaW5nLCB2YWx1ZTogYW55KTogdm9pZCB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDspIHtcbiAgICBjb25zdCBpbmRleCA9IGlucHV0c1tpKytdIGFzIG51bWJlcjtcbiAgICBjb25zdCBwcml2YXRlTmFtZSA9IGlucHV0c1tpKytdIGFzIHN0cmluZztcbiAgICBjb25zdCBpbnN0YW5jZSA9IGxWaWV3W2luZGV4XTtcbiAgICBuZ0Rldk1vZGUgJiYgYXNzZXJ0SW5kZXhJblJhbmdlKGxWaWV3LCBpbmRleCk7XG4gICAgY29uc3QgZGVmID0gdFZpZXcuZGF0YVtpbmRleF0gYXMgRGlyZWN0aXZlRGVmPGFueT47XG4gICAgaWYgKGRlZi5zZXRJbnB1dCAhPT0gbnVsbCkge1xuICAgICAgZGVmLnNldElucHV0IShpbnN0YW5jZSwgdmFsdWUsIHB1YmxpY05hbWUsIHByaXZhdGVOYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW5zdGFuY2VbcHJpdmF0ZU5hbWVdID0gdmFsdWU7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVXBkYXRlcyBhIHRleHQgYmluZGluZyBhdCBhIGdpdmVuIGluZGV4IGluIGEgZ2l2ZW4gTFZpZXcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0ZXh0QmluZGluZ0ludGVybmFsKGxWaWV3OiBMVmlldywgaW5kZXg6IG51bWJlciwgdmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0U3RyaW5nKHZhbHVlLCAnVmFsdWUgc2hvdWxkIGJlIGEgc3RyaW5nJyk7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnROb3RTYW1lKHZhbHVlLCBOT19DSEFOR0UgYXMgYW55LCAndmFsdWUgc2hvdWxkIG5vdCBiZSBOT19DSEFOR0UnKTtcbiAgbmdEZXZNb2RlICYmIGFzc2VydEluZGV4SW5SYW5nZShsVmlldywgaW5kZXgpO1xuICBjb25zdCBlbGVtZW50ID0gZ2V0TmF0aXZlQnlJbmRleChpbmRleCwgbFZpZXcpIGFzIGFueSBhcyBSVGV4dDtcbiAgbmdEZXZNb2RlICYmIGFzc2VydERlZmluZWQoZWxlbWVudCwgJ25hdGl2ZSBlbGVtZW50IHNob3VsZCBleGlzdCcpO1xuICB1cGRhdGVUZXh0Tm9kZShsVmlld1tSRU5ERVJFUl0sIGVsZW1lbnQsIHZhbHVlKTtcbn1cbiJdfQ==