@angular/core 13.0.0-next.7 → 13.0.0-rc.1

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 (542) hide show
  1. package/core.d.ts +599 -963
  2. package/esm2020/core.mjs +5 -0
  3. package/{esm2015/index.js → esm2020/index.mjs} +0 -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 +135 -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 +46 -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/esm2020/src/i18n/locale_data_api.mjs +132 -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} +6 -6
  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} +0 -0
  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} +3 -3
  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} +2 -2
  103. package/{esm2015/src/render3/context_discovery.js → esm2020/src/render3/context_discovery.mjs} +0 -0
  104. package/{esm2015/src/render3/definition.js → esm2020/src/render3/definition.mjs} +0 -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} +0 -0
  107. package/{esm2015/src/render3/di_setup.js → esm2020/src/render3/di_setup.mjs} +0 -0
  108. package/{esm2015/src/render3/error_code.js → esm2020/src/render3/error_code.mjs} +0 -0
  109. package/{esm2015/src/render3/errors.js → esm2020/src/render3/errors.mjs} +0 -0
  110. package/{esm2015/src/render3/errors_di.js → esm2020/src/render3/errors_di.mjs} +0 -0
  111. package/{esm2015/src/render3/features/copy_definition_feature.js → esm2020/src/render3/features/copy_definition_feature.mjs} +0 -0
  112. package/{esm2015/src/render3/features/inherit_definition_feature.js → esm2020/src/render3/features/inherit_definition_feature.mjs} +0 -0
  113. package/esm2020/src/render3/features/ng_onchanges_feature.mjs +92 -0
  114. package/{esm2015/src/render3/features/providers_feature.js → esm2020/src/render3/features/providers_feature.mjs} +0 -0
  115. package/{esm2015/src/render3/fields.js → esm2020/src/render3/fields.mjs} +0 -0
  116. package/{esm2015/src/render3/global_utils_api.js → esm2020/src/render3/global_utils_api.mjs} +0 -0
  117. package/{esm2015/src/render3/hooks.js → esm2020/src/render3/hooks.mjs} +0 -0
  118. package/{esm2015/src/render3/i18n/i18n_apply.js → esm2020/src/render3/i18n/i18n_apply.mjs} +0 -0
  119. package/{esm2015/src/render3/i18n/i18n_debug.js → esm2020/src/render3/i18n/i18n_debug.mjs} +0 -0
  120. package/{esm2015/src/render3/i18n/i18n_insert_before_index.js → esm2020/src/render3/i18n/i18n_insert_before_index.mjs} +0 -0
  121. package/{esm2015/src/render3/i18n/i18n_locale_id.js → esm2020/src/render3/i18n/i18n_locale_id.mjs} +0 -0
  122. package/{esm2015/src/render3/i18n/i18n_parse.js → esm2020/src/render3/i18n/i18n_parse.mjs} +0 -0
  123. package/{esm2015/src/render3/i18n/i18n_postprocess.js → esm2020/src/render3/i18n/i18n_postprocess.mjs} +0 -0
  124. package/{esm2015/src/render3/i18n/i18n_tree_shaking.js → esm2020/src/render3/i18n/i18n_tree_shaking.mjs} +0 -0
  125. package/{esm2015/src/render3/i18n/i18n_util.js → esm2020/src/render3/i18n/i18n_util.mjs} +0 -0
  126. package/{esm2015/src/render3/index.js → esm2020/src/render3/index.mjs} +0 -0
  127. package/{esm2015/src/render3/instructions/advance.js → esm2020/src/render3/instructions/advance.mjs} +0 -0
  128. package/{esm2015/src/render3/instructions/all.js → esm2020/src/render3/instructions/all.mjs} +0 -0
  129. package/{esm2015/src/render3/instructions/attribute.js → esm2020/src/render3/instructions/attribute.mjs} +0 -0
  130. package/{esm2015/src/render3/instructions/attribute_interpolation.js → esm2020/src/render3/instructions/attribute_interpolation.mjs} +0 -0
  131. package/{esm2015/src/render3/instructions/change_detection.js → esm2020/src/render3/instructions/change_detection.mjs} +0 -0
  132. package/{esm2015/src/render3/instructions/class_map_interpolation.js → esm2020/src/render3/instructions/class_map_interpolation.mjs} +0 -0
  133. package/{esm2015/src/render3/instructions/di.js → esm2020/src/render3/instructions/di.mjs} +0 -0
  134. package/{esm2015/src/render3/instructions/di_attr.js → esm2020/src/render3/instructions/di_attr.mjs} +0 -0
  135. package/{esm2015/src/render3/instructions/element.js → esm2020/src/render3/instructions/element.mjs} +0 -0
  136. package/{esm2015/src/render3/instructions/element_container.js → esm2020/src/render3/instructions/element_container.mjs} +0 -0
  137. package/{esm2015/src/render3/instructions/get_current_view.js → esm2020/src/render3/instructions/get_current_view.mjs} +0 -0
  138. package/{esm2015/src/render3/instructions/host_property.js → esm2020/src/render3/instructions/host_property.mjs} +0 -0
  139. package/{esm2015/src/render3/instructions/i18n.js → esm2020/src/render3/instructions/i18n.mjs} +0 -0
  140. package/{esm2015/src/render3/instructions/i18n_icu_container_visitor.js → esm2020/src/render3/instructions/i18n_icu_container_visitor.mjs} +0 -0
  141. package/{esm2015/src/render3/instructions/interpolation.js → esm2020/src/render3/instructions/interpolation.mjs} +0 -0
  142. package/{esm2015/src/render3/instructions/listener.js → esm2020/src/render3/instructions/listener.mjs} +0 -0
  143. package/{esm2015/src/render3/instructions/lview_debug.js → esm2020/src/render3/instructions/lview_debug.mjs} +0 -0
  144. package/{esm2015/src/render3/instructions/namespace.js → esm2020/src/render3/instructions/namespace.mjs} +0 -0
  145. package/{esm2015/src/render3/instructions/next_context.js → esm2020/src/render3/instructions/next_context.mjs} +0 -0
  146. package/{esm2015/src/render3/instructions/projection.js → esm2020/src/render3/instructions/projection.mjs} +0 -0
  147. package/{esm2015/src/render3/instructions/property.js → esm2020/src/render3/instructions/property.mjs} +0 -0
  148. package/{esm2015/src/render3/instructions/property_interpolation.js → esm2020/src/render3/instructions/property_interpolation.mjs} +0 -0
  149. package/esm2020/src/render3/instructions/shared.mjs +1811 -0
  150. package/{esm2015/src/render3/instructions/storage.js → esm2020/src/render3/instructions/storage.mjs} +0 -0
  151. package/{esm2015/src/render3/instructions/style_map_interpolation.js → esm2020/src/render3/instructions/style_map_interpolation.mjs} +0 -0
  152. package/{esm2015/src/render3/instructions/style_prop_interpolation.js → esm2020/src/render3/instructions/style_prop_interpolation.mjs} +0 -0
  153. package/{esm2015/src/render3/instructions/styling.js → esm2020/src/render3/instructions/styling.mjs} +0 -0
  154. package/{esm2015/src/render3/instructions/template.js → esm2020/src/render3/instructions/template.mjs} +0 -0
  155. package/{esm2015/src/render3/instructions/text.js → esm2020/src/render3/instructions/text.mjs} +0 -0
  156. package/{esm2015/src/render3/instructions/text_interpolation.js → esm2020/src/render3/instructions/text_interpolation.mjs} +0 -0
  157. package/{esm2015/src/render3/interfaces/container.js → esm2020/src/render3/interfaces/container.mjs} +0 -0
  158. package/{esm2015/src/render3/interfaces/context.js → esm2020/src/render3/interfaces/context.mjs} +0 -0
  159. package/{esm2015/src/render3/interfaces/definition.js → esm2020/src/render3/interfaces/definition.mjs} +0 -0
  160. package/{esm2015/src/render3/interfaces/document.js → esm2020/src/render3/interfaces/document.mjs} +0 -0
  161. package/{esm2015/src/render3/interfaces/i18n.js → esm2020/src/render3/interfaces/i18n.mjs} +0 -0
  162. package/{esm2015/src/render3/interfaces/injector.js → esm2020/src/render3/interfaces/injector.mjs} +0 -0
  163. package/{esm2015/src/render3/interfaces/node.js → esm2020/src/render3/interfaces/node.mjs} +0 -0
  164. package/{esm2015/src/render3/interfaces/player.js → esm2020/src/render3/interfaces/player.mjs} +0 -0
  165. package/{esm2015/src/render3/interfaces/projection.js → esm2020/src/render3/interfaces/projection.mjs} +0 -0
  166. package/{esm2015/src/render3/interfaces/public_definitions.js → esm2020/src/render3/interfaces/public_definitions.mjs} +0 -0
  167. package/{esm2015/src/render3/interfaces/query.js → esm2020/src/render3/interfaces/query.mjs} +0 -0
  168. package/esm2020/src/render3/interfaces/renderer.mjs +27 -0
  169. package/{esm2015/src/render3/interfaces/renderer_dom.js → esm2020/src/render3/interfaces/renderer_dom.mjs} +0 -0
  170. package/{esm2015/src/render3/interfaces/sanitization.js → esm2020/src/render3/interfaces/sanitization.mjs} +0 -0
  171. package/{esm2015/src/render3/interfaces/styling.js → esm2020/src/render3/interfaces/styling.mjs} +0 -0
  172. package/{esm2015/src/render3/interfaces/type_checks.js → esm2020/src/render3/interfaces/type_checks.mjs} +0 -0
  173. package/{esm2015/src/render3/interfaces/view.js → esm2020/src/render3/interfaces/view.mjs} +0 -0
  174. package/esm2020/src/render3/jit/directive.mjs +325 -0
  175. package/esm2020/src/render3/jit/environment.mjs +165 -0
  176. package/{esm2015/src/render3/jit/jit_options.js → esm2020/src/render3/jit/jit_options.mjs} +0 -0
  177. package/{esm2015/src/render3/jit/module.js → esm2020/src/render3/jit/module.mjs} +0 -0
  178. package/esm2020/src/render3/jit/partial.mjs +104 -0
  179. package/{esm2015/src/render3/jit/pipe.js → esm2020/src/render3/jit/pipe.mjs} +0 -0
  180. package/esm2020/src/render3/metadata.mjs +49 -0
  181. package/{esm2015/src/render3/namespaces.js → esm2020/src/render3/namespaces.mjs} +0 -0
  182. package/esm2020/src/render3/ng_module_ref.mjs +122 -0
  183. package/{esm2015/src/render3/node_assert.js → esm2020/src/render3/node_assert.mjs} +0 -0
  184. package/{esm2015/src/render3/node_manipulation.js → esm2020/src/render3/node_manipulation.mjs} +0 -0
  185. package/{esm2015/src/render3/node_manipulation_i18n.js → esm2020/src/render3/node_manipulation_i18n.mjs} +0 -0
  186. package/{esm2015/src/render3/node_selector_matcher.js → esm2020/src/render3/node_selector_matcher.mjs} +0 -0
  187. package/esm2020/src/render3/pipe.mjs +184 -0
  188. package/{esm2015/src/render3/profiler.js → esm2020/src/render3/profiler.mjs} +0 -0
  189. package/{esm2015/src/render3/pure_function.js → esm2020/src/render3/pure_function.mjs} +0 -0
  190. package/{esm2015/src/render3/query.js → esm2020/src/render3/query.mjs} +0 -0
  191. package/{esm2015/src/render3/state.js → esm2020/src/render3/state.mjs} +0 -0
  192. package/{esm2015/src/render3/styling/class_differ.js → esm2020/src/render3/styling/class_differ.mjs} +0 -0
  193. package/{esm2015/src/render3/styling/static_styling.js → esm2020/src/render3/styling/static_styling.mjs} +0 -0
  194. package/{esm2015/src/render3/styling/style_binding_list.js → esm2020/src/render3/styling/style_binding_list.mjs} +0 -0
  195. package/{esm2015/src/render3/styling/styling_parser.js → esm2020/src/render3/styling/styling_parser.mjs} +0 -0
  196. package/{esm2015/src/render3/tokens.js → esm2020/src/render3/tokens.mjs} +0 -0
  197. package/{esm2015/src/render3/util/attrs_utils.js → esm2020/src/render3/util/attrs_utils.mjs} +0 -0
  198. package/{esm2015/src/render3/util/change_detection_utils.js → esm2020/src/render3/util/change_detection_utils.mjs} +0 -0
  199. package/{esm2015/src/render3/util/debug_utils.js → esm2020/src/render3/util/debug_utils.mjs} +0 -0
  200. package/esm2020/src/render3/util/discovery_utils.mjs +411 -0
  201. package/esm2020/src/render3/util/global_utils.mjs +77 -0
  202. package/{esm2015/src/render3/util/injector_utils.js → esm2020/src/render3/util/injector_utils.mjs} +0 -0
  203. package/esm2020/src/render3/util/misc_utils.mjs +61 -0
  204. package/{esm2015/src/render3/util/stringify_utils.js → esm2020/src/render3/util/stringify_utils.mjs} +0 -0
  205. package/{esm2015/src/render3/util/view_traversal_utils.js → esm2020/src/render3/util/view_traversal_utils.mjs} +0 -0
  206. package/{esm2015/src/render3/util/view_utils.js → esm2020/src/render3/util/view_utils.mjs} +0 -0
  207. package/{esm2015/src/render3/view_engine_compatibility_prebound.js → esm2020/src/render3/view_engine_compatibility_prebound.mjs} +1 -1
  208. package/{esm2015/src/render3/view_ref.js → esm2020/src/render3/view_ref.mjs} +0 -0
  209. package/{esm2015/src/sanitization/bypass.js → esm2020/src/sanitization/bypass.mjs} +0 -0
  210. package/{esm2015/src/sanitization/html_sanitizer.js → esm2020/src/sanitization/html_sanitizer.mjs} +0 -0
  211. package/{esm2015/src/sanitization/inert_body.js → esm2020/src/sanitization/inert_body.mjs} +3 -3
  212. package/{esm2015/src/sanitization/sanitization.js → esm2020/src/sanitization/sanitization.mjs} +0 -0
  213. package/{esm2015/src/sanitization/sanitizer.js → esm2020/src/sanitization/sanitizer.mjs} +0 -0
  214. package/{esm2015/src/sanitization/security.js → esm2020/src/sanitization/security.mjs} +0 -0
  215. package/{esm2015/src/sanitization/url_sanitizer.js → esm2020/src/sanitization/url_sanitizer.mjs} +0 -0
  216. package/esm2020/src/testability/testability.mjs +258 -0
  217. package/{esm2015/src/util/array_utils.js → esm2020/src/util/array_utils.mjs} +0 -0
  218. package/{esm2015/src/util/assert.js → esm2020/src/util/assert.mjs} +0 -0
  219. package/{esm2015/src/util/char_code.js → esm2020/src/util/char_code.mjs} +0 -0
  220. package/{esm2015/src/util/closure.js → esm2020/src/util/closure.mjs} +0 -0
  221. package/{esm2015/src/util/comparison.js → esm2020/src/util/comparison.mjs} +0 -0
  222. package/{esm2015/src/util/decorators.js → esm2020/src/util/decorators.mjs} +0 -0
  223. package/{esm2015/src/util/dom.js → esm2020/src/util/dom.mjs} +0 -0
  224. package/{esm2015/src/util/empty.js → esm2020/src/util/empty.mjs} +0 -0
  225. package/{esm2015/src/util/errors.js → esm2020/src/util/errors.mjs} +0 -0
  226. package/{esm2015/src/util/global.js → esm2020/src/util/global.mjs} +0 -0
  227. package/{esm2015/src/util/is_dev_mode.js → esm2020/src/util/is_dev_mode.mjs} +0 -0
  228. package/{esm2015/src/util/iterable.js → esm2020/src/util/iterable.mjs} +0 -0
  229. package/{esm2015/src/util/lang.js → esm2020/src/util/lang.mjs} +0 -0
  230. package/{esm2015/src/util/microtask.js → esm2020/src/util/microtask.mjs} +0 -0
  231. package/{esm2015/src/util/named_array_type.js → esm2020/src/util/named_array_type.mjs} +0 -0
  232. package/{esm2015/src/util/ng_dev_mode.js → esm2020/src/util/ng_dev_mode.mjs} +0 -0
  233. package/{esm2015/src/util/ng_i18n_closure_mode.js → esm2020/src/util/ng_i18n_closure_mode.mjs} +0 -0
  234. package/{esm2015/src/util/ng_jit_mode.js → esm2020/src/util/ng_jit_mode.mjs} +0 -0
  235. package/{esm2015/src/util/ng_reflect.js → esm2020/src/util/ng_reflect.mjs} +0 -0
  236. package/{esm2015/src/util/noop.js → esm2020/src/util/noop.mjs} +0 -0
  237. package/{esm2015/src/util/property.js → esm2020/src/util/property.mjs} +0 -0
  238. package/{esm2015/src/util/raf.js → esm2020/src/util/raf.mjs} +0 -0
  239. package/{esm2015/src/util/security/trusted_type_defs.js → esm2020/src/util/security/trusted_type_defs.mjs} +0 -0
  240. package/esm2020/src/util/security/trusted_types.mjs +130 -0
  241. package/esm2020/src/util/security/trusted_types_bypass.mjs +83 -0
  242. package/{esm2015/src/util/stringify.js → esm2020/src/util/stringify.mjs} +0 -0
  243. package/{esm2015/src/util/symbol.js → esm2020/src/util/symbol.mjs} +0 -0
  244. package/{esm2015/src/version.js → esm2020/src/version.mjs} +1 -1
  245. package/{esm2015/src/view/element.js → esm2020/src/view/element.mjs} +0 -0
  246. package/{esm2015/src/view/entrypoint.js → esm2020/src/view/entrypoint.mjs} +0 -0
  247. package/{esm2015/src/view/errors.js → esm2020/src/view/errors.mjs} +0 -0
  248. package/{esm2015/src/view/index.js → esm2020/src/view/index.mjs} +2 -2
  249. package/{esm2015/src/view/ng_content.js → esm2020/src/view/ng_content.mjs} +0 -0
  250. package/{esm2015/src/view/ng_module.js → esm2020/src/view/ng_module.mjs} +0 -0
  251. package/esm2020/src/view/provider.mjs +490 -0
  252. package/esm2020/src/view/provider_flags.mjs +26 -0
  253. package/{esm2015/src/view/pure_expression.js → esm2020/src/view/pure_expression.mjs} +0 -0
  254. package/{esm2015/src/view/query.js → esm2020/src/view/query.mjs} +0 -0
  255. package/esm2020/src/view/refs.mjs +369 -0
  256. package/{esm2015/src/view/services.js → esm2020/src/view/services.mjs} +0 -0
  257. package/{esm2015/src/view/text.js → esm2020/src/view/text.mjs} +0 -0
  258. package/{esm2015/src/view/types.js → esm2020/src/view/types.mjs} +0 -0
  259. package/esm2020/src/view/util.mjs +369 -0
  260. package/{esm2015/src/view/view.js → esm2020/src/view/view.mjs} +0 -0
  261. package/{esm2015/src/view/view_attach.js → esm2020/src/view/view_attach.mjs} +0 -0
  262. package/{esm2015/src/zone/ng_zone.js → esm2020/src/zone/ng_zone.mjs} +0 -0
  263. package/{esm2015/src/zone.js → esm2020/src/zone.mjs} +0 -0
  264. package/{esm2015/testing/index.js → esm2020/testing/index.mjs} +0 -0
  265. package/{esm2015/testing/public_api.js → esm2020/testing/public_api.mjs} +0 -0
  266. package/{esm2015/testing/src/async.js → esm2020/testing/src/async.mjs} +0 -0
  267. package/{esm2015/testing/src/component_fixture.js → esm2020/testing/src/component_fixture.mjs} +0 -0
  268. package/{esm2015/testing/src/fake_async.js → esm2020/testing/src/fake_async.mjs} +0 -0
  269. package/{esm2015/testing/src/lang_utils.js → esm2020/testing/src/lang_utils.mjs} +0 -0
  270. package/esm2020/testing/src/logger.mjs +34 -0
  271. package/{esm2015/testing/src/metadata_override.js → esm2020/testing/src/metadata_override.mjs} +0 -0
  272. package/{esm2015/testing/src/metadata_overrider.js → esm2020/testing/src/metadata_overrider.mjs} +0 -0
  273. package/esm2020/testing/src/ng_zone_mock.mjs +33 -0
  274. package/{esm2015/testing/src/private_export_testing.js → esm2020/testing/src/private_export_testing.mjs} +0 -0
  275. package/esm2020/testing/src/r3_test_bed.mjs +397 -0
  276. package/esm2020/testing/src/r3_test_bed_compiler.mjs +735 -0
  277. package/{esm2015/testing/src/resolvers.js → esm2020/testing/src/resolvers.mjs} +1 -1
  278. package/{esm2015/testing/src/styling.js → esm2020/testing/src/styling.mjs} +0 -0
  279. package/esm2020/testing/src/test_bed.mjs +614 -0
  280. package/esm2020/testing/src/test_bed_common.mjs +28 -0
  281. package/esm2020/testing/src/test_compiler.mjs +69 -0
  282. package/{esm2015/testing/src/test_hooks.js → esm2020/testing/src/test_hooks.mjs} +0 -0
  283. package/{esm2015/testing/src/testing.js → esm2020/testing/src/testing.mjs} +0 -0
  284. package/{esm2015/testing/src/testing_internal.js → esm2020/testing/src/testing_internal.mjs} +0 -0
  285. package/esm2020/testing/testing.mjs +5 -0
  286. package/fesm2015/{core.js → core.mjs} +8674 -8756
  287. package/fesm2015/core.mjs.map +1 -0
  288. package/fesm2015/{testing.js → testing.mjs} +50 -61
  289. package/fesm2015/testing.mjs.map +1 -0
  290. package/fesm2020/core.mjs +33107 -0
  291. package/fesm2020/core.mjs.map +1 -0
  292. package/fesm2020/testing.mjs +2635 -0
  293. package/fesm2020/testing.mjs.map +1 -0
  294. package/package.json +34 -9
  295. package/schematics/migrations/abstract-control-parent/index.js +6 -6
  296. package/schematics/migrations/abstract-control-parent/util.d.ts +1 -1
  297. package/schematics/migrations/abstract-control-parent/util.js +11 -8
  298. package/schematics/migrations/activated-route-snapshot-fragment/index.js +12 -9
  299. package/schematics/migrations/activated-route-snapshot-fragment/util.d.ts +1 -1
  300. package/schematics/migrations/activated-route-snapshot-fragment/util.js +10 -7
  301. package/schematics/migrations/can-activate-with-redirect-to/index.js +13 -10
  302. package/schematics/migrations/can-activate-with-redirect-to/util.d.ts +1 -1
  303. package/schematics/migrations/can-activate-with-redirect-to/util.js +13 -10
  304. package/schematics/migrations/deep-shadow-piercing-selector/index.js +3 -3
  305. package/schematics/migrations/dynamic-queries/index.js +13 -10
  306. package/schematics/migrations/dynamic-queries/util.d.ts +1 -1
  307. package/schematics/migrations/dynamic-queries/util.js +12 -9
  308. package/schematics/migrations/initial-navigation/collector.d.ts +1 -1
  309. package/schematics/migrations/initial-navigation/collector.js +23 -20
  310. package/schematics/migrations/initial-navigation/index.js +5 -5
  311. package/schematics/migrations/initial-navigation/transform.d.ts +1 -1
  312. package/schematics/migrations/initial-navigation/transform.js +11 -8
  313. package/schematics/migrations/initial-navigation/update_recorder.d.ts +1 -1
  314. package/schematics/migrations/initial-navigation/update_recorder.js +1 -1
  315. package/schematics/migrations/initial-navigation/util.d.ts +1 -1
  316. package/schematics/migrations/initial-navigation/util.js +10 -7
  317. package/schematics/migrations/missing-injectable/definition_collector.d.ts +1 -1
  318. package/schematics/migrations/missing-injectable/definition_collector.js +16 -13
  319. package/schematics/migrations/missing-injectable/index.js +26 -12
  320. package/schematics/migrations/missing-injectable/providers_evaluator.d.ts +9 -19
  321. package/schematics/migrations/missing-injectable/providers_evaluator.js +47 -40
  322. package/schematics/migrations/missing-injectable/transform.d.ts +3 -2
  323. package/schematics/migrations/missing-injectable/transform.js +18 -16
  324. package/schematics/migrations/missing-injectable/update_recorder.d.ts +1 -1
  325. package/schematics/migrations/missing-injectable/update_recorder.js +1 -1
  326. package/schematics/migrations/module-with-providers/collector.d.ts +1 -1
  327. package/schematics/migrations/module-with-providers/collector.js +12 -9
  328. package/schematics/migrations/module-with-providers/index.js +26 -12
  329. package/schematics/migrations/module-with-providers/transform.d.ts +4 -3
  330. package/schematics/migrations/module-with-providers/transform.js +23 -22
  331. package/schematics/migrations/module-with-providers/util.d.ts +1 -1
  332. package/schematics/migrations/module-with-providers/util.js +10 -7
  333. package/schematics/migrations/move-document/document_import_visitor.d.ts +1 -1
  334. package/schematics/migrations/move-document/document_import_visitor.js +7 -4
  335. package/schematics/migrations/move-document/index.js +8 -8
  336. package/schematics/migrations/move-document/move-import.d.ts +1 -1
  337. package/schematics/migrations/move-document/move-import.js +27 -24
  338. package/schematics/migrations/native-view-encapsulation/index.js +6 -6
  339. package/schematics/migrations/native-view-encapsulation/util.d.ts +1 -1
  340. package/schematics/migrations/native-view-encapsulation/util.js +8 -5
  341. package/schematics/migrations/navigation-extras-omissions/index.js +13 -10
  342. package/schematics/migrations/navigation-extras-omissions/util.d.ts +1 -1
  343. package/schematics/migrations/navigation-extras-omissions/util.js +17 -14
  344. package/schematics/migrations/relative-link-resolution/collector.d.ts +1 -1
  345. package/schematics/migrations/relative-link-resolution/collector.js +17 -14
  346. package/schematics/migrations/relative-link-resolution/index.js +5 -5
  347. package/schematics/migrations/relative-link-resolution/transform.d.ts +1 -1
  348. package/schematics/migrations/relative-link-resolution/transform.js +12 -9
  349. package/schematics/migrations/relative-link-resolution/update_recorder.d.ts +1 -1
  350. package/schematics/migrations/relative-link-resolution/update_recorder.js +1 -1
  351. package/schematics/migrations/relative-link-resolution/util.d.ts +1 -1
  352. package/schematics/migrations/relative-link-resolution/util.js +10 -7
  353. package/schematics/migrations/renderer-to-renderer2/helpers.d.ts +1 -1
  354. package/schematics/migrations/renderer-to-renderer2/helpers.js +92 -89
  355. package/schematics/migrations/renderer-to-renderer2/index.js +20 -17
  356. package/schematics/migrations/renderer-to-renderer2/migration.d.ts +1 -1
  357. package/schematics/migrations/renderer-to-renderer2/migration.js +33 -30
  358. package/schematics/migrations/renderer-to-renderer2/util.d.ts +1 -1
  359. package/schematics/migrations/renderer-to-renderer2/util.js +23 -20
  360. package/schematics/migrations/router-link-empty-expression/analyze_template.d.ts +2 -2
  361. package/schematics/migrations/router-link-empty-expression/analyze_template.js +6 -7
  362. package/schematics/migrations/router-link-empty-expression/angular/html_routerlink_empty_expr_visitor.d.ts +7 -6
  363. package/schematics/migrations/router-link-empty-expression/angular/html_routerlink_empty_expr_visitor.js +10 -11
  364. package/schematics/migrations/router-link-empty-expression/index.js +27 -16
  365. package/schematics/migrations/router-preserve-query-params/index.js +13 -10
  366. package/schematics/migrations/router-preserve-query-params/util.d.ts +1 -1
  367. package/schematics/migrations/router-preserve-query-params/util.js +19 -16
  368. package/schematics/migrations/static-queries/angular/directive_inputs.d.ts +1 -1
  369. package/schematics/migrations/static-queries/angular/directive_inputs.js +14 -11
  370. package/schematics/migrations/static-queries/angular/ng_query_visitor.d.ts +1 -1
  371. package/schematics/migrations/static-queries/angular/ng_query_visitor.js +17 -14
  372. package/schematics/migrations/static-queries/angular/query-definition.d.ts +1 -1
  373. package/schematics/migrations/static-queries/angular/query-definition.js +1 -1
  374. package/schematics/migrations/static-queries/angular/super_class.d.ts +1 -1
  375. package/schematics/migrations/static-queries/angular/super_class.js +1 -1
  376. package/schematics/migrations/static-queries/index.js +43 -18
  377. package/schematics/migrations/static-queries/strategies/template_strategy/template_strategy.d.ts +6 -3
  378. package/schematics/migrations/static-queries/strategies/template_strategy/template_strategy.js +44 -48
  379. package/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.d.ts +1 -1
  380. package/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.js +41 -38
  381. package/schematics/migrations/static-queries/strategies/usage_strategy/super_class_context.d.ts +1 -1
  382. package/schematics/migrations/static-queries/strategies/usage_strategy/super_class_context.js +10 -7
  383. package/schematics/migrations/static-queries/strategies/usage_strategy/template_usage_visitor.d.ts +10 -9
  384. package/schematics/migrations/static-queries/strategies/usage_strategy/template_usage_visitor.js +35 -36
  385. package/schematics/migrations/static-queries/strategies/usage_strategy/usage_strategy.d.ts +3 -2
  386. package/schematics/migrations/static-queries/strategies/usage_strategy/usage_strategy.js +14 -10
  387. package/schematics/migrations/static-queries/transform.d.ts +1 -1
  388. package/schematics/migrations/static-queries/transform.js +14 -11
  389. package/schematics/migrations/template-var-assignment/analyze_template.d.ts +2 -2
  390. package/schematics/migrations/template-var-assignment/analyze_template.js +6 -7
  391. package/schematics/migrations/template-var-assignment/angular/html_variable_assignment_visitor.d.ts +7 -6
  392. package/schematics/migrations/template-var-assignment/angular/html_variable_assignment_visitor.js +31 -30
  393. package/schematics/migrations/template-var-assignment/index.js +20 -9
  394. package/schematics/migrations/testbed-teardown/index.d.ts +11 -0
  395. package/schematics/migrations/testbed-teardown/index.js +92 -0
  396. package/schematics/migrations/testbed-teardown/util.d.ts +35 -0
  397. package/schematics/migrations/testbed-teardown/util.js +188 -0
  398. package/schematics/migrations/undecorated-classes-with-decorated-fields/index.js +26 -12
  399. package/schematics/migrations/undecorated-classes-with-decorated-fields/transform.d.ts +3 -2
  400. package/schematics/migrations/undecorated-classes-with-decorated-fields/transform.js +23 -21
  401. package/schematics/migrations/undecorated-classes-with-decorated-fields/update_recorder.d.ts +1 -1
  402. package/schematics/migrations/undecorated-classes-with-decorated-fields/update_recorder.js +1 -1
  403. package/schematics/migrations/undecorated-classes-with-di/create_ngc_program.d.ts +4 -4
  404. package/schematics/migrations/undecorated-classes-with-di/create_ngc_program.js +5 -6
  405. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/convert_directive_metadata.d.ts +3 -3
  406. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/convert_directive_metadata.js +18 -16
  407. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/decorator_rewriter.d.ts +3 -5
  408. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/decorator_rewriter.js +13 -11
  409. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/import_rewrite_visitor.d.ts +2 -2
  410. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/import_rewrite_visitor.js +18 -15
  411. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/path_format.js +2 -2
  412. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/source_file_exports.d.ts +1 -1
  413. package/schematics/migrations/undecorated-classes-with-di/decorator_rewrite/source_file_exports.js +16 -13
  414. package/schematics/migrations/undecorated-classes-with-di/index.js +64 -22
  415. package/schematics/migrations/undecorated-classes-with-di/ng_declaration_collector.d.ts +4 -4
  416. package/schematics/migrations/undecorated-classes-with-di/ng_declaration_collector.js +28 -35
  417. package/schematics/migrations/undecorated-classes-with-di/transform.d.ts +5 -5
  418. package/schematics/migrations/undecorated-classes-with-di/transform.js +29 -26
  419. package/schematics/migrations/undecorated-classes-with-di/update_recorder.d.ts +1 -1
  420. package/schematics/migrations/undecorated-classes-with-di/update_recorder.js +1 -1
  421. package/schematics/migrations/wait-for-async/index.js +16 -13
  422. package/schematics/migrations/wait-for-async/util.d.ts +1 -1
  423. package/schematics/migrations/wait-for-async/util.js +9 -6
  424. package/schematics/migrations/xhr-factory/index.js +13 -10
  425. package/schematics/migrations.json +6 -1
  426. package/schematics/package.json +3 -0
  427. package/schematics/utils/import_manager.d.ts +1 -1
  428. package/schematics/utils/import_manager.js +24 -21
  429. package/schematics/utils/load_esm.d.ts +32 -0
  430. package/schematics/utils/load_esm.js +79 -0
  431. package/schematics/utils/ng_component_template.d.ts +1 -1
  432. package/schematics/utils/ng_component_template.js +21 -18
  433. package/schematics/utils/ng_decorators.d.ts +1 -1
  434. package/schematics/utils/ng_decorators.js +2 -2
  435. package/schematics/utils/parse_html.d.ts +2 -2
  436. package/schematics/utils/parse_html.js +4 -5
  437. package/schematics/utils/project_tsconfig_paths.js +3 -3
  438. package/schematics/utils/template_ast_visitor.d.ts +55 -0
  439. package/schematics/utils/template_ast_visitor.js +73 -0
  440. package/schematics/utils/typescript/class_declaration.d.ts +1 -1
  441. package/schematics/utils/typescript/class_declaration.js +10 -7
  442. package/schematics/utils/typescript/compiler_host.d.ts +1 -1
  443. package/schematics/utils/typescript/compiler_host.js +11 -8
  444. package/schematics/utils/typescript/decorators.d.ts +1 -1
  445. package/schematics/utils/typescript/decorators.js +8 -5
  446. package/schematics/utils/typescript/find_base_classes.d.ts +1 -1
  447. package/schematics/utils/typescript/find_base_classes.js +7 -4
  448. package/schematics/utils/typescript/functions.d.ts +1 -1
  449. package/schematics/utils/typescript/functions.js +9 -6
  450. package/schematics/utils/typescript/imports.d.ts +1 -1
  451. package/schematics/utils/typescript/imports.js +12 -9
  452. package/schematics/utils/typescript/nodes.d.ts +1 -1
  453. package/schematics/utils/typescript/nodes.js +11 -8
  454. package/schematics/utils/typescript/parse_tsconfig.d.ts +1 -1
  455. package/schematics/utils/typescript/parse_tsconfig.js +31 -9
  456. package/schematics/utils/typescript/property_name.d.ts +1 -1
  457. package/schematics/utils/typescript/property_name.js +7 -4
  458. package/schematics/utils/typescript/symbol.d.ts +1 -1
  459. package/schematics/utils/typescript/symbol.js +15 -12
  460. package/testing/package.json +5 -5
  461. package/testing/testing.d.ts +57 -339
  462. package/bundles/core-testing.umd.js +0 -3179
  463. package/bundles/core-testing.umd.js.map +0 -1
  464. package/bundles/core.umd.js +0 -34488
  465. package/bundles/core.umd.js.map +0 -1
  466. package/core.metadata.json +0 -1
  467. package/esm2015/core.externs.js +0 -6
  468. package/esm2015/core.js +0 -38
  469. package/esm2015/src/application_init.js +0 -142
  470. package/esm2015/src/application_module.js +0 -134
  471. package/esm2015/src/application_ref.js +0 -735
  472. package/esm2015/src/change_detection/change_detection.js +0 -31
  473. package/esm2015/src/change_detection/change_detection_util.js +0 -105
  474. package/esm2015/src/change_detection/change_detector_ref.js +0 -96
  475. package/esm2015/src/change_detection/differs/default_iterable_differ.js +0 -668
  476. package/esm2015/src/change_detection.js +0 -14
  477. package/esm2015/src/codegen_private_exports.js +0 -11
  478. package/esm2015/src/compiler/compiler.externs.js +0 -0
  479. package/esm2015/src/console.js +0 -23
  480. package/esm2015/src/core.js +0 -50
  481. package/esm2015/src/core_private_export.js +0 -35
  482. package/esm2015/src/core_render3_private_export.js +0 -45
  483. package/esm2015/src/debug/debug_node.js +0 -632
  484. package/esm2015/src/di/injectable.js +0 -36
  485. package/esm2015/src/di/injection_token.js +0 -75
  486. package/esm2015/src/di/injector.js +0 -326
  487. package/esm2015/src/di/injector_compatibility.js +0 -187
  488. package/esm2015/src/di/interface/interface.externs.js +0 -0
  489. package/esm2015/src/di/jit/injectable.js +0 -96
  490. package/esm2015/src/di/metadata.js +0 -62
  491. package/esm2015/src/di/metadata_attr.js +0 -24
  492. package/esm2015/src/di/util.js +0 -53
  493. package/esm2015/src/event_emitter.js +0 -54
  494. package/esm2015/src/i18n/locale_data_api.js +0 -131
  495. package/esm2015/src/i18n/locale_en.js +0 -17
  496. package/esm2015/src/interface/interface.externs.js +0 -0
  497. package/esm2015/src/linker/compiler.js +0 -118
  498. package/esm2015/src/linker/element_ref.js +0 -66
  499. package/esm2015/src/linker/ng_module_factory.js +0 -21
  500. package/esm2015/src/linker/ng_module_factory_loader.js +0 -41
  501. package/esm2015/src/linker/system_js_ng_module_factory_loader.js +0 -77
  502. package/esm2015/src/linker/view_container_ref.js +0 -252
  503. package/esm2015/src/linker.js +0 -20
  504. package/esm2015/src/metadata/di.js +0 -99
  505. package/esm2015/src/metadata/directives.js +0 -120
  506. package/esm2015/src/metadata/ng_module.js +0 -44
  507. package/esm2015/src/reflection/reflection.externs.js +0 -0
  508. package/esm2015/src/render3/component.js +0 -206
  509. package/esm2015/src/render3/features/ng_onchanges_feature.js +0 -92
  510. package/esm2015/src/render3/instructions/shared.js +0 -1813
  511. package/esm2015/src/render3/interfaces/renderer.js +0 -29
  512. package/esm2015/src/render3/jit/directive.js +0 -312
  513. package/esm2015/src/render3/jit/environment.js +0 -167
  514. package/esm2015/src/render3/jit/partial.js +0 -105
  515. package/esm2015/src/render3/metadata.js +0 -49
  516. package/esm2015/src/render3/ng_module_ref.js +0 -108
  517. package/esm2015/src/render3/pipe.js +0 -202
  518. package/esm2015/src/render3/util/discovery_utils.js +0 -411
  519. package/esm2015/src/render3/util/global_utils.js +0 -78
  520. package/esm2015/src/render3/util/misc_utils.js +0 -63
  521. package/esm2015/src/testability/testability.js +0 -256
  522. package/esm2015/src/util/security/trusted_types.js +0 -133
  523. package/esm2015/src/util/security/trusted_types_bypass.js +0 -86
  524. package/esm2015/src/util/util.externs.js +0 -0
  525. package/esm2015/src/view/provider.js +0 -507
  526. package/esm2015/src/view/refs.js +0 -362
  527. package/esm2015/src/view/util.js +0 -378
  528. package/esm2015/testing/src/logger.js +0 -32
  529. package/esm2015/testing/src/ng_zone_mock.js +0 -31
  530. package/esm2015/testing/src/r3_test_bed.js +0 -397
  531. package/esm2015/testing/src/r3_test_bed_compiler.js +0 -744
  532. package/esm2015/testing/src/test_bed.js +0 -608
  533. package/esm2015/testing/src/test_bed_common.js +0 -31
  534. package/esm2015/testing/src/test_compiler.js +0 -66
  535. package/esm2015/testing/testing.externs.js +0 -6
  536. package/esm2015/testing/testing.js +0 -7
  537. package/fesm2015/core.js.map +0 -1
  538. package/fesm2015/testing.js.map +0 -1
  539. package/src/r3_symbols.d.ts +0 -1025
  540. package/testing/testing.metadata.json +0 -1
  541. package/testing.d.ts +0 -7
  542. package/testing.metadata.json +0 -1
@@ -0,0 +1,735 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.io/license
7
+ */
8
+ import { ResourceLoader } from '@angular/compiler';
9
+ import { ApplicationInitStatus, Compiler, COMPILER_OPTIONS, LOCALE_ID, ModuleWithComponentFactories, NgZone, resolveForwardRef, ɵcompileComponent as compileComponent, ɵcompileDirective as compileDirective, ɵcompileNgModuleDefs as compileNgModuleDefs, ɵcompilePipe as compilePipe, ɵDEFAULT_LOCALE_ID as DEFAULT_LOCALE_ID, ɵgetInjectableDef as getInjectableDef, ɵNG_COMP_DEF as NG_COMP_DEF, ɵNG_DIR_DEF as NG_DIR_DEF, ɵNG_INJ_DEF as NG_INJ_DEF, ɵNG_MOD_DEF as NG_MOD_DEF, ɵNG_PIPE_DEF as NG_PIPE_DEF, ɵNgModuleFactory as R3NgModuleFactory, ɵpatchComponentDefWithScope as patchComponentDefWithScope, ɵRender3ComponentFactory as ComponentFactory, ɵRender3NgModuleRef as NgModuleRef, ɵsetLocaleId as setLocaleId, ɵtransitiveScopesFor as transitiveScopesFor } from '@angular/core';
10
+ import { clearResolutionOfComponentResourcesQueue, isComponentDefPendingResolution, resolveComponentResources, restoreComponentResolutionQueue } from '../../src/metadata/resource_loading';
11
+ import { ComponentResolver, DirectiveResolver, NgModuleResolver, PipeResolver } from './resolvers';
12
+ var TestingModuleOverride;
13
+ (function (TestingModuleOverride) {
14
+ TestingModuleOverride[TestingModuleOverride["DECLARATION"] = 0] = "DECLARATION";
15
+ TestingModuleOverride[TestingModuleOverride["OVERRIDE_TEMPLATE"] = 1] = "OVERRIDE_TEMPLATE";
16
+ })(TestingModuleOverride || (TestingModuleOverride = {}));
17
+ function isTestingModuleOverride(value) {
18
+ return value === TestingModuleOverride.DECLARATION ||
19
+ value === TestingModuleOverride.OVERRIDE_TEMPLATE;
20
+ }
21
+ export class R3TestBedCompiler {
22
+ constructor(platform, additionalModuleTypes) {
23
+ this.platform = platform;
24
+ this.additionalModuleTypes = additionalModuleTypes;
25
+ this.originalComponentResolutionQueue = null;
26
+ // Testing module configuration
27
+ this.declarations = [];
28
+ this.imports = [];
29
+ this.providers = [];
30
+ this.schemas = [];
31
+ // Queues of components/directives/pipes that should be recompiled.
32
+ this.pendingComponents = new Set();
33
+ this.pendingDirectives = new Set();
34
+ this.pendingPipes = new Set();
35
+ // Keep track of all components and directives, so we can patch Providers onto defs later.
36
+ this.seenComponents = new Set();
37
+ this.seenDirectives = new Set();
38
+ // Keep track of overridden modules, so that we can collect all affected ones in the module tree.
39
+ this.overriddenModules = new Set();
40
+ // Store resolved styles for Components that have template overrides present and `styleUrls`
41
+ // defined at the same time.
42
+ this.existingComponentStyles = new Map();
43
+ this.resolvers = initResolvers();
44
+ this.componentToModuleScope = new Map();
45
+ // Map that keeps initial version of component/directive/pipe defs in case
46
+ // we compile a Type again, thus overriding respective static fields. This is
47
+ // required to make sure we restore defs to their initial states between test runs
48
+ // TODO: we should support the case with multiple defs on a type
49
+ this.initialNgDefs = new Map();
50
+ // Array that keeps cleanup operations for initial versions of component/directive/pipe/module
51
+ // defs in case TestBed makes changes to the originals.
52
+ this.defCleanupOps = [];
53
+ this._injector = null;
54
+ this.compilerProviders = null;
55
+ this.providerOverrides = [];
56
+ this.rootProviderOverrides = [];
57
+ // Overrides for injectables with `{providedIn: SomeModule}` need to be tracked and added to that
58
+ // module's provider list.
59
+ this.providerOverridesByModule = new Map();
60
+ this.providerOverridesByToken = new Map();
61
+ this.moduleProvidersOverridden = new Set();
62
+ this.testModuleRef = null;
63
+ class DynamicTestModule {
64
+ }
65
+ this.testModuleType = DynamicTestModule;
66
+ }
67
+ setCompilerProviders(providers) {
68
+ this.compilerProviders = providers;
69
+ this._injector = null;
70
+ }
71
+ configureTestingModule(moduleDef) {
72
+ // Enqueue any compilation tasks for the directly declared component.
73
+ if (moduleDef.declarations !== undefined) {
74
+ this.queueTypeArray(moduleDef.declarations, TestingModuleOverride.DECLARATION);
75
+ this.declarations.push(...moduleDef.declarations);
76
+ }
77
+ // Enqueue any compilation tasks for imported modules.
78
+ if (moduleDef.imports !== undefined) {
79
+ this.queueTypesFromModulesArray(moduleDef.imports);
80
+ this.imports.push(...moduleDef.imports);
81
+ }
82
+ if (moduleDef.providers !== undefined) {
83
+ this.providers.push(...moduleDef.providers);
84
+ }
85
+ if (moduleDef.schemas !== undefined) {
86
+ this.schemas.push(...moduleDef.schemas);
87
+ }
88
+ }
89
+ overrideModule(ngModule, override) {
90
+ this.overriddenModules.add(ngModule);
91
+ // Compile the module right away.
92
+ this.resolvers.module.addOverride(ngModule, override);
93
+ const metadata = this.resolvers.module.resolve(ngModule);
94
+ if (metadata === null) {
95
+ throw invalidTypeError(ngModule.name, 'NgModule');
96
+ }
97
+ this.recompileNgModule(ngModule, metadata);
98
+ // At this point, the module has a valid module def (ɵmod), but the override may have introduced
99
+ // new declarations or imported modules. Ingest any possible new types and add them to the
100
+ // current queue.
101
+ this.queueTypesFromModulesArray([ngModule]);
102
+ }
103
+ overrideComponent(component, override) {
104
+ this.resolvers.component.addOverride(component, override);
105
+ this.pendingComponents.add(component);
106
+ }
107
+ overrideDirective(directive, override) {
108
+ this.resolvers.directive.addOverride(directive, override);
109
+ this.pendingDirectives.add(directive);
110
+ }
111
+ overridePipe(pipe, override) {
112
+ this.resolvers.pipe.addOverride(pipe, override);
113
+ this.pendingPipes.add(pipe);
114
+ }
115
+ overrideProvider(token, provider) {
116
+ let providerDef;
117
+ if (provider.useFactory !== undefined) {
118
+ providerDef = {
119
+ provide: token,
120
+ useFactory: provider.useFactory,
121
+ deps: provider.deps || [],
122
+ multi: provider.multi
123
+ };
124
+ }
125
+ else if (provider.useValue !== undefined) {
126
+ providerDef = { provide: token, useValue: provider.useValue, multi: provider.multi };
127
+ }
128
+ else {
129
+ providerDef = { provide: token };
130
+ }
131
+ const injectableDef = typeof token !== 'string' ? getInjectableDef(token) : null;
132
+ const providedIn = injectableDef === null ? null : resolveForwardRef(injectableDef.providedIn);
133
+ const overridesBucket = providedIn === 'root' ? this.rootProviderOverrides : this.providerOverrides;
134
+ overridesBucket.push(providerDef);
135
+ // Keep overrides grouped by token as well for fast lookups using token
136
+ this.providerOverridesByToken.set(token, providerDef);
137
+ if (injectableDef !== null && providedIn !== null && typeof providedIn !== 'string') {
138
+ const existingOverrides = this.providerOverridesByModule.get(providedIn);
139
+ if (existingOverrides !== undefined) {
140
+ existingOverrides.push(providerDef);
141
+ }
142
+ else {
143
+ this.providerOverridesByModule.set(providedIn, [providerDef]);
144
+ }
145
+ }
146
+ }
147
+ overrideTemplateUsingTestingModule(type, template) {
148
+ const def = type[NG_COMP_DEF];
149
+ const hasStyleUrls = () => {
150
+ const metadata = this.resolvers.component.resolve(type);
151
+ return !!metadata.styleUrls && metadata.styleUrls.length > 0;
152
+ };
153
+ const overrideStyleUrls = !!def && !isComponentDefPendingResolution(type) && hasStyleUrls();
154
+ // In Ivy, compiling a component does not require knowing the module providing the
155
+ // component's scope, so overrideTemplateUsingTestingModule can be implemented purely via
156
+ // overrideComponent. Important: overriding template requires full Component re-compilation,
157
+ // which may fail in case styleUrls are also present (thus Component is considered as required
158
+ // resolution). In order to avoid this, we preemptively set styleUrls to an empty array,
159
+ // preserve current styles available on Component def and restore styles back once compilation
160
+ // is complete.
161
+ const override = overrideStyleUrls ? { template, styles: [], styleUrls: [] } : { template };
162
+ this.overrideComponent(type, { set: override });
163
+ if (overrideStyleUrls && def.styles && def.styles.length > 0) {
164
+ this.existingComponentStyles.set(type, def.styles);
165
+ }
166
+ // Set the component's scope to be the testing module.
167
+ this.componentToModuleScope.set(type, TestingModuleOverride.OVERRIDE_TEMPLATE);
168
+ }
169
+ async compileComponents() {
170
+ this.clearComponentResolutionQueue();
171
+ // Run compilers for all queued types.
172
+ let needsAsyncResources = this.compileTypesSync();
173
+ // compileComponents() should not be async unless it needs to be.
174
+ if (needsAsyncResources) {
175
+ let resourceLoader;
176
+ let resolver = (url) => {
177
+ if (!resourceLoader) {
178
+ resourceLoader = this.injector.get(ResourceLoader);
179
+ }
180
+ return Promise.resolve(resourceLoader.get(url));
181
+ };
182
+ await resolveComponentResources(resolver);
183
+ }
184
+ }
185
+ finalize() {
186
+ // One last compile
187
+ this.compileTypesSync();
188
+ // Create the testing module itself.
189
+ this.compileTestModule();
190
+ this.applyTransitiveScopes();
191
+ this.applyProviderOverrides();
192
+ // Patch previously stored `styles` Component values (taken from ɵcmp), in case these
193
+ // Components have `styleUrls` fields defined and template override was requested.
194
+ this.patchComponentsWithExistingStyles();
195
+ // Clear the componentToModuleScope map, so that future compilations don't reset the scope of
196
+ // every component.
197
+ this.componentToModuleScope.clear();
198
+ const parentInjector = this.platform.injector;
199
+ this.testModuleRef = new NgModuleRef(this.testModuleType, parentInjector);
200
+ // ApplicationInitStatus.runInitializers() is marked @internal to core.
201
+ // Cast it to any before accessing it.
202
+ this.testModuleRef.injector.get(ApplicationInitStatus).runInitializers();
203
+ // Set locale ID after running app initializers, since locale information might be updated while
204
+ // running initializers. This is also consistent with the execution order while bootstrapping an
205
+ // app (see `packages/core/src/application_ref.ts` file).
206
+ const localeId = this.testModuleRef.injector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
207
+ setLocaleId(localeId);
208
+ return this.testModuleRef;
209
+ }
210
+ /**
211
+ * @internal
212
+ */
213
+ _compileNgModuleSync(moduleType) {
214
+ this.queueTypesFromModulesArray([moduleType]);
215
+ this.compileTypesSync();
216
+ this.applyProviderOverrides();
217
+ this.applyProviderOverridesToModule(moduleType);
218
+ this.applyTransitiveScopes();
219
+ }
220
+ /**
221
+ * @internal
222
+ */
223
+ async _compileNgModuleAsync(moduleType) {
224
+ this.queueTypesFromModulesArray([moduleType]);
225
+ await this.compileComponents();
226
+ this.applyProviderOverrides();
227
+ this.applyProviderOverridesToModule(moduleType);
228
+ this.applyTransitiveScopes();
229
+ }
230
+ /**
231
+ * @internal
232
+ */
233
+ _getModuleResolver() {
234
+ return this.resolvers.module;
235
+ }
236
+ /**
237
+ * @internal
238
+ */
239
+ _getComponentFactories(moduleType) {
240
+ return maybeUnwrapFn(moduleType.ɵmod.declarations).reduce((factories, declaration) => {
241
+ const componentDef = declaration.ɵcmp;
242
+ componentDef && factories.push(new ComponentFactory(componentDef, this.testModuleRef));
243
+ return factories;
244
+ }, []);
245
+ }
246
+ compileTypesSync() {
247
+ // Compile all queued components, directives, pipes.
248
+ let needsAsyncResources = false;
249
+ this.pendingComponents.forEach(declaration => {
250
+ needsAsyncResources = needsAsyncResources || isComponentDefPendingResolution(declaration);
251
+ const metadata = this.resolvers.component.resolve(declaration);
252
+ if (metadata === null) {
253
+ throw invalidTypeError(declaration.name, 'Component');
254
+ }
255
+ this.maybeStoreNgDef(NG_COMP_DEF, declaration);
256
+ compileComponent(declaration, metadata);
257
+ });
258
+ this.pendingComponents.clear();
259
+ this.pendingDirectives.forEach(declaration => {
260
+ const metadata = this.resolvers.directive.resolve(declaration);
261
+ if (metadata === null) {
262
+ throw invalidTypeError(declaration.name, 'Directive');
263
+ }
264
+ this.maybeStoreNgDef(NG_DIR_DEF, declaration);
265
+ compileDirective(declaration, metadata);
266
+ });
267
+ this.pendingDirectives.clear();
268
+ this.pendingPipes.forEach(declaration => {
269
+ const metadata = this.resolvers.pipe.resolve(declaration);
270
+ if (metadata === null) {
271
+ throw invalidTypeError(declaration.name, 'Pipe');
272
+ }
273
+ this.maybeStoreNgDef(NG_PIPE_DEF, declaration);
274
+ compilePipe(declaration, metadata);
275
+ });
276
+ this.pendingPipes.clear();
277
+ return needsAsyncResources;
278
+ }
279
+ applyTransitiveScopes() {
280
+ if (this.overriddenModules.size > 0) {
281
+ // Module overrides (via `TestBed.overrideModule`) might affect scopes that were previously
282
+ // calculated and stored in `transitiveCompileScopes`. If module overrides are present,
283
+ // collect all affected modules and reset scopes to force their re-calculation.
284
+ const testingModuleDef = this.testModuleType[NG_MOD_DEF];
285
+ const affectedModules = this.collectModulesAffectedByOverrides(testingModuleDef.imports);
286
+ if (affectedModules.size > 0) {
287
+ affectedModules.forEach(moduleType => {
288
+ this.storeFieldOfDefOnType(moduleType, NG_MOD_DEF, 'transitiveCompileScopes');
289
+ moduleType[NG_MOD_DEF].transitiveCompileScopes = null;
290
+ });
291
+ }
292
+ }
293
+ const moduleToScope = new Map();
294
+ const getScopeOfModule = (moduleType) => {
295
+ if (!moduleToScope.has(moduleType)) {
296
+ const isTestingModule = isTestingModuleOverride(moduleType);
297
+ const realType = isTestingModule ? this.testModuleType : moduleType;
298
+ moduleToScope.set(moduleType, transitiveScopesFor(realType));
299
+ }
300
+ return moduleToScope.get(moduleType);
301
+ };
302
+ this.componentToModuleScope.forEach((moduleType, componentType) => {
303
+ const moduleScope = getScopeOfModule(moduleType);
304
+ this.storeFieldOfDefOnType(componentType, NG_COMP_DEF, 'directiveDefs');
305
+ this.storeFieldOfDefOnType(componentType, NG_COMP_DEF, 'pipeDefs');
306
+ // `tView` that is stored on component def contains information about directives and pipes
307
+ // that are in the scope of this component. Patching component scope will cause `tView` to be
308
+ // changed. Store original `tView` before patching scope, so the `tView` (including scope
309
+ // information) is restored back to its previous/original state before running next test.
310
+ this.storeFieldOfDefOnType(componentType, NG_COMP_DEF, 'tView');
311
+ patchComponentDefWithScope(componentType.ɵcmp, moduleScope);
312
+ });
313
+ this.componentToModuleScope.clear();
314
+ }
315
+ applyProviderOverrides() {
316
+ const maybeApplyOverrides = (field) => (type) => {
317
+ const resolver = field === NG_COMP_DEF ? this.resolvers.component : this.resolvers.directive;
318
+ const metadata = resolver.resolve(type);
319
+ if (this.hasProviderOverrides(metadata.providers)) {
320
+ this.patchDefWithProviderOverrides(type, field);
321
+ }
322
+ };
323
+ this.seenComponents.forEach(maybeApplyOverrides(NG_COMP_DEF));
324
+ this.seenDirectives.forEach(maybeApplyOverrides(NG_DIR_DEF));
325
+ this.seenComponents.clear();
326
+ this.seenDirectives.clear();
327
+ }
328
+ applyProviderOverridesToModule(moduleType) {
329
+ if (this.moduleProvidersOverridden.has(moduleType)) {
330
+ return;
331
+ }
332
+ this.moduleProvidersOverridden.add(moduleType);
333
+ const injectorDef = moduleType[NG_INJ_DEF];
334
+ if (this.providerOverridesByToken.size > 0) {
335
+ const providers = [
336
+ ...injectorDef.providers,
337
+ ...(this.providerOverridesByModule.get(moduleType) || [])
338
+ ];
339
+ if (this.hasProviderOverrides(providers)) {
340
+ this.maybeStoreNgDef(NG_INJ_DEF, moduleType);
341
+ this.storeFieldOfDefOnType(moduleType, NG_INJ_DEF, 'providers');
342
+ injectorDef.providers = this.getOverriddenProviders(providers);
343
+ }
344
+ // Apply provider overrides to imported modules recursively
345
+ const moduleDef = moduleType[NG_MOD_DEF];
346
+ const imports = maybeUnwrapFn(moduleDef.imports);
347
+ for (const importedModule of imports) {
348
+ this.applyProviderOverridesToModule(importedModule);
349
+ }
350
+ // Also override the providers on any ModuleWithProviders imports since those don't appear in
351
+ // the moduleDef.
352
+ for (const importedModule of flatten(injectorDef.imports)) {
353
+ if (isModuleWithProviders(importedModule)) {
354
+ this.defCleanupOps.push({
355
+ object: importedModule,
356
+ fieldName: 'providers',
357
+ originalValue: importedModule.providers
358
+ });
359
+ importedModule.providers = this.getOverriddenProviders(importedModule.providers);
360
+ }
361
+ }
362
+ }
363
+ }
364
+ patchComponentsWithExistingStyles() {
365
+ this.existingComponentStyles.forEach((styles, type) => type[NG_COMP_DEF].styles = styles);
366
+ this.existingComponentStyles.clear();
367
+ }
368
+ queueTypeArray(arr, moduleType) {
369
+ for (const value of arr) {
370
+ if (Array.isArray(value)) {
371
+ this.queueTypeArray(value, moduleType);
372
+ }
373
+ else {
374
+ this.queueType(value, moduleType);
375
+ }
376
+ }
377
+ }
378
+ recompileNgModule(ngModule, metadata) {
379
+ // Cache the initial ngModuleDef as it will be overwritten.
380
+ this.maybeStoreNgDef(NG_MOD_DEF, ngModule);
381
+ this.maybeStoreNgDef(NG_INJ_DEF, ngModule);
382
+ compileNgModuleDefs(ngModule, metadata);
383
+ }
384
+ queueType(type, moduleType) {
385
+ const component = this.resolvers.component.resolve(type);
386
+ if (component) {
387
+ // Check whether a give Type has respective NG def (ɵcmp) and compile if def is
388
+ // missing. That might happen in case a class without any Angular decorators extends another
389
+ // class where Component/Directive/Pipe decorator is defined.
390
+ if (isComponentDefPendingResolution(type) || !type.hasOwnProperty(NG_COMP_DEF)) {
391
+ this.pendingComponents.add(type);
392
+ }
393
+ this.seenComponents.add(type);
394
+ // Keep track of the module which declares this component, so later the component's scope
395
+ // can be set correctly. If the component has already been recorded here, then one of several
396
+ // cases is true:
397
+ // * the module containing the component was imported multiple times (common).
398
+ // * the component is declared in multiple modules (which is an error).
399
+ // * the component was in 'declarations' of the testing module, and also in an imported module
400
+ // in which case the module scope will be TestingModuleOverride.DECLARATION.
401
+ // * overrideTemplateUsingTestingModule was called for the component in which case the module
402
+ // scope will be TestingModuleOverride.OVERRIDE_TEMPLATE.
403
+ //
404
+ // If the component was previously in the testing module's 'declarations' (meaning the
405
+ // current value is TestingModuleOverride.DECLARATION), then `moduleType` is the component's
406
+ // real module, which was imported. This pattern is understood to mean that the component
407
+ // should use its original scope, but that the testing module should also contain the
408
+ // component in its scope.
409
+ if (!this.componentToModuleScope.has(type) ||
410
+ this.componentToModuleScope.get(type) === TestingModuleOverride.DECLARATION) {
411
+ this.componentToModuleScope.set(type, moduleType);
412
+ }
413
+ return;
414
+ }
415
+ const directive = this.resolvers.directive.resolve(type);
416
+ if (directive) {
417
+ if (!type.hasOwnProperty(NG_DIR_DEF)) {
418
+ this.pendingDirectives.add(type);
419
+ }
420
+ this.seenDirectives.add(type);
421
+ return;
422
+ }
423
+ const pipe = this.resolvers.pipe.resolve(type);
424
+ if (pipe && !type.hasOwnProperty(NG_PIPE_DEF)) {
425
+ this.pendingPipes.add(type);
426
+ return;
427
+ }
428
+ }
429
+ queueTypesFromModulesArray(arr) {
430
+ // Because we may encounter the same NgModule while processing the imports and exports of an
431
+ // NgModule tree, we cache them in this set so we can skip ones that have already been seen
432
+ // encountered. In some test setups, this caching resulted in 10X runtime improvement.
433
+ const processedNgModuleDefs = new Set();
434
+ const queueTypesFromModulesArrayRecur = (arr) => {
435
+ for (const value of arr) {
436
+ if (Array.isArray(value)) {
437
+ queueTypesFromModulesArrayRecur(value);
438
+ }
439
+ else if (hasNgModuleDef(value)) {
440
+ const def = value.ɵmod;
441
+ if (processedNgModuleDefs.has(def)) {
442
+ continue;
443
+ }
444
+ processedNgModuleDefs.add(def);
445
+ // Look through declarations, imports, and exports, and queue
446
+ // everything found there.
447
+ this.queueTypeArray(maybeUnwrapFn(def.declarations), value);
448
+ queueTypesFromModulesArrayRecur(maybeUnwrapFn(def.imports));
449
+ queueTypesFromModulesArrayRecur(maybeUnwrapFn(def.exports));
450
+ }
451
+ else if (isModuleWithProviders(value)) {
452
+ queueTypesFromModulesArrayRecur([value.ngModule]);
453
+ }
454
+ }
455
+ };
456
+ queueTypesFromModulesArrayRecur(arr);
457
+ }
458
+ // When module overrides (via `TestBed.overrideModule`) are present, it might affect all modules
459
+ // that import (even transitively) an overridden one. For all affected modules we need to
460
+ // recalculate their scopes for a given test run and restore original scopes at the end. The goal
461
+ // of this function is to collect all affected modules in a set for further processing. Example:
462
+ // if we have the following module hierarchy: A -> B -> C (where `->` means `imports`) and module
463
+ // `C` is overridden, we consider `A` and `B` as affected, since their scopes might become
464
+ // invalidated with the override.
465
+ collectModulesAffectedByOverrides(arr) {
466
+ const seenModules = new Set();
467
+ const affectedModules = new Set();
468
+ const calcAffectedModulesRecur = (arr, path) => {
469
+ for (const value of arr) {
470
+ if (Array.isArray(value)) {
471
+ // If the value is an array, just flatten it (by invoking this function recursively),
472
+ // keeping "path" the same.
473
+ calcAffectedModulesRecur(value, path);
474
+ }
475
+ else if (hasNgModuleDef(value)) {
476
+ if (seenModules.has(value)) {
477
+ // If we've seen this module before and it's included into "affected modules" list, mark
478
+ // the whole path that leads to that module as affected, but do not descend into its
479
+ // imports, since we already examined them before.
480
+ if (affectedModules.has(value)) {
481
+ path.forEach(item => affectedModules.add(item));
482
+ }
483
+ continue;
484
+ }
485
+ seenModules.add(value);
486
+ if (this.overriddenModules.has(value)) {
487
+ path.forEach(item => affectedModules.add(item));
488
+ }
489
+ // Examine module imports recursively to look for overridden modules.
490
+ const moduleDef = value[NG_MOD_DEF];
491
+ calcAffectedModulesRecur(maybeUnwrapFn(moduleDef.imports), path.concat(value));
492
+ }
493
+ }
494
+ };
495
+ calcAffectedModulesRecur(arr, []);
496
+ return affectedModules;
497
+ }
498
+ maybeStoreNgDef(prop, type) {
499
+ if (!this.initialNgDefs.has(type)) {
500
+ const currentDef = Object.getOwnPropertyDescriptor(type, prop);
501
+ this.initialNgDefs.set(type, [prop, currentDef]);
502
+ }
503
+ }
504
+ storeFieldOfDefOnType(type, defField, fieldName) {
505
+ const def = type[defField];
506
+ const originalValue = def[fieldName];
507
+ this.defCleanupOps.push({ object: def, fieldName, originalValue });
508
+ }
509
+ /**
510
+ * Clears current components resolution queue, but stores the state of the queue, so we can
511
+ * restore it later. Clearing the queue is required before we try to compile components (via
512
+ * `TestBed.compileComponents`), so that component defs are in sync with the resolution queue.
513
+ */
514
+ clearComponentResolutionQueue() {
515
+ if (this.originalComponentResolutionQueue === null) {
516
+ this.originalComponentResolutionQueue = new Map();
517
+ }
518
+ clearResolutionOfComponentResourcesQueue().forEach((value, key) => this.originalComponentResolutionQueue.set(key, value));
519
+ }
520
+ /*
521
+ * Restores component resolution queue to the previously saved state. This operation is performed
522
+ * as a part of restoring the state after completion of the current set of tests (that might
523
+ * potentially mutate the state).
524
+ */
525
+ restoreComponentResolutionQueue() {
526
+ if (this.originalComponentResolutionQueue !== null) {
527
+ restoreComponentResolutionQueue(this.originalComponentResolutionQueue);
528
+ this.originalComponentResolutionQueue = null;
529
+ }
530
+ }
531
+ restoreOriginalState() {
532
+ // Process cleanup ops in reverse order so the field's original value is restored correctly (in
533
+ // case there were multiple overrides for the same field).
534
+ forEachRight(this.defCleanupOps, (op) => {
535
+ op.object[op.fieldName] = op.originalValue;
536
+ });
537
+ // Restore initial component/directive/pipe defs
538
+ this.initialNgDefs.forEach((value, type) => {
539
+ const [prop, descriptor] = value;
540
+ if (!descriptor) {
541
+ // Delete operations are generally undesirable since they have performance implications
542
+ // on objects they were applied to. In this particular case, situations where this code
543
+ // is invoked should be quite rare to cause any noticeable impact, since it's applied
544
+ // only to some test cases (for example when class with no annotations extends some
545
+ // @Component) when we need to clear 'ɵcmp' field on a given class to restore
546
+ // its original state (before applying overrides and running tests).
547
+ delete type[prop];
548
+ }
549
+ else {
550
+ Object.defineProperty(type, prop, descriptor);
551
+ }
552
+ });
553
+ this.initialNgDefs.clear();
554
+ this.moduleProvidersOverridden.clear();
555
+ this.restoreComponentResolutionQueue();
556
+ // Restore the locale ID to the default value, this shouldn't be necessary but we never know
557
+ setLocaleId(DEFAULT_LOCALE_ID);
558
+ }
559
+ compileTestModule() {
560
+ class RootScopeModule {
561
+ }
562
+ compileNgModuleDefs(RootScopeModule, {
563
+ providers: [...this.rootProviderOverrides],
564
+ });
565
+ const ngZone = new NgZone({ enableLongStackTrace: true });
566
+ const providers = [
567
+ { provide: NgZone, useValue: ngZone },
568
+ { provide: Compiler, useFactory: () => new R3TestCompiler(this) },
569
+ ...this.providers,
570
+ ...this.providerOverrides,
571
+ ];
572
+ const imports = [RootScopeModule, this.additionalModuleTypes, this.imports || []];
573
+ // clang-format off
574
+ compileNgModuleDefs(this.testModuleType, {
575
+ declarations: this.declarations,
576
+ imports,
577
+ schemas: this.schemas,
578
+ providers,
579
+ }, /* allowDuplicateDeclarationsInRoot */ true);
580
+ // clang-format on
581
+ this.applyProviderOverridesToModule(this.testModuleType);
582
+ }
583
+ get injector() {
584
+ if (this._injector !== null) {
585
+ return this._injector;
586
+ }
587
+ const providers = [];
588
+ const compilerOptions = this.platform.injector.get(COMPILER_OPTIONS);
589
+ compilerOptions.forEach(opts => {
590
+ if (opts.providers) {
591
+ providers.push(opts.providers);
592
+ }
593
+ });
594
+ if (this.compilerProviders !== null) {
595
+ providers.push(...this.compilerProviders);
596
+ }
597
+ // TODO(ocombe): make this work with an Injector directly instead of creating a module for it
598
+ class CompilerModule {
599
+ }
600
+ compileNgModuleDefs(CompilerModule, { providers });
601
+ const CompilerModuleFactory = new R3NgModuleFactory(CompilerModule);
602
+ this._injector = CompilerModuleFactory.create(this.platform.injector).injector;
603
+ return this._injector;
604
+ }
605
+ // get overrides for a specific provider (if any)
606
+ getSingleProviderOverrides(provider) {
607
+ const token = getProviderToken(provider);
608
+ return this.providerOverridesByToken.get(token) || null;
609
+ }
610
+ getProviderOverrides(providers) {
611
+ if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
612
+ return [];
613
+ // There are two flattening operations here. The inner flatten() operates on the metadata's
614
+ // providers and applies a mapping function which retrieves overrides for each incoming
615
+ // provider. The outer flatten() then flattens the produced overrides array. If this is not
616
+ // done, the array can contain other empty arrays (e.g. `[[], []]`) which leak into the
617
+ // providers array and contaminate any error messages that might be generated.
618
+ return flatten(flatten(providers, (provider) => this.getSingleProviderOverrides(provider) || []));
619
+ }
620
+ getOverriddenProviders(providers) {
621
+ if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
622
+ return [];
623
+ const flattenedProviders = flatten(providers);
624
+ const overrides = this.getProviderOverrides(flattenedProviders);
625
+ const overriddenProviders = [...flattenedProviders, ...overrides];
626
+ const final = [];
627
+ const seenOverriddenProviders = new Set();
628
+ // We iterate through the list of providers in reverse order to make sure provider overrides
629
+ // take precedence over the values defined in provider list. We also filter out all providers
630
+ // that have overrides, keeping overridden values only. This is needed, since presence of a
631
+ // provider with `ngOnDestroy` hook will cause this hook to be registered and invoked later.
632
+ forEachRight(overriddenProviders, (provider) => {
633
+ const token = getProviderToken(provider);
634
+ if (this.providerOverridesByToken.has(token)) {
635
+ if (!seenOverriddenProviders.has(token)) {
636
+ seenOverriddenProviders.add(token);
637
+ // Treat all overridden providers as `{multi: false}` (even if it's a multi-provider) to
638
+ // make sure that provided override takes highest precedence and is not combined with
639
+ // other instances of the same multi provider.
640
+ final.unshift({ ...provider, multi: false });
641
+ }
642
+ }
643
+ else {
644
+ final.unshift(provider);
645
+ }
646
+ });
647
+ return final;
648
+ }
649
+ hasProviderOverrides(providers) {
650
+ return this.getProviderOverrides(providers).length > 0;
651
+ }
652
+ patchDefWithProviderOverrides(declaration, field) {
653
+ const def = declaration[field];
654
+ if (def && def.providersResolver) {
655
+ this.maybeStoreNgDef(field, declaration);
656
+ const resolver = def.providersResolver;
657
+ const processProvidersFn = (providers) => this.getOverriddenProviders(providers);
658
+ this.storeFieldOfDefOnType(declaration, field, 'providersResolver');
659
+ def.providersResolver = (ngDef) => resolver(ngDef, processProvidersFn);
660
+ }
661
+ }
662
+ }
663
+ function initResolvers() {
664
+ return {
665
+ module: new NgModuleResolver(),
666
+ component: new ComponentResolver(),
667
+ directive: new DirectiveResolver(),
668
+ pipe: new PipeResolver()
669
+ };
670
+ }
671
+ function hasNgModuleDef(value) {
672
+ return value.hasOwnProperty('ɵmod');
673
+ }
674
+ function maybeUnwrapFn(maybeFn) {
675
+ return maybeFn instanceof Function ? maybeFn() : maybeFn;
676
+ }
677
+ function flatten(values, mapFn) {
678
+ const out = [];
679
+ values.forEach(value => {
680
+ if (Array.isArray(value)) {
681
+ out.push(...flatten(value, mapFn));
682
+ }
683
+ else {
684
+ out.push(mapFn ? mapFn(value) : value);
685
+ }
686
+ });
687
+ return out;
688
+ }
689
+ function getProviderField(provider, field) {
690
+ return provider && typeof provider === 'object' && provider[field];
691
+ }
692
+ function getProviderToken(provider) {
693
+ return getProviderField(provider, 'provide') || provider;
694
+ }
695
+ function isModuleWithProviders(value) {
696
+ return value.hasOwnProperty('ngModule');
697
+ }
698
+ function forEachRight(values, fn) {
699
+ for (let idx = values.length - 1; idx >= 0; idx--) {
700
+ fn(values[idx], idx);
701
+ }
702
+ }
703
+ function invalidTypeError(name, expectedType) {
704
+ return new Error(`${name} class doesn't have @${expectedType} decorator or is missing metadata.`);
705
+ }
706
+ class R3TestCompiler {
707
+ constructor(testBed) {
708
+ this.testBed = testBed;
709
+ }
710
+ compileModuleSync(moduleType) {
711
+ this.testBed._compileNgModuleSync(moduleType);
712
+ return new R3NgModuleFactory(moduleType);
713
+ }
714
+ async compileModuleAsync(moduleType) {
715
+ await this.testBed._compileNgModuleAsync(moduleType);
716
+ return new R3NgModuleFactory(moduleType);
717
+ }
718
+ compileModuleAndAllComponentsSync(moduleType) {
719
+ const ngModuleFactory = this.compileModuleSync(moduleType);
720
+ const componentFactories = this.testBed._getComponentFactories(moduleType);
721
+ return new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
722
+ }
723
+ async compileModuleAndAllComponentsAsync(moduleType) {
724
+ const ngModuleFactory = await this.compileModuleAsync(moduleType);
725
+ const componentFactories = this.testBed._getComponentFactories(moduleType);
726
+ return new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
727
+ }
728
+ clearCache() { }
729
+ clearCacheFor(type) { }
730
+ getModuleId(moduleType) {
731
+ const meta = this.testBed._getModuleResolver().resolve(moduleType);
732
+ return meta && meta.id || undefined;
733
+ }
734
+ }
735
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicjNfdGVzdF9iZWRfY29tcGlsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3Rlc3Rpbmcvc3JjL3IzX3Rlc3RfYmVkX2NvbXBpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUNqRCxPQUFPLEVBQUMscUJBQXFCLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFnRCxTQUFTLEVBQUUsNEJBQTRCLEVBQWtELE1BQU0sRUFBK0IsaUJBQWlCLEVBQVEsaUJBQWlCLElBQUksZ0JBQWdCLEVBQUUsaUJBQWlCLElBQUksZ0JBQWdCLEVBQUUsb0JBQW9CLElBQUksbUJBQW1CLEVBQUUsWUFBWSxJQUFJLFdBQVcsRUFBRSxrQkFBa0IsSUFBSSxpQkFBaUIsRUFBaUMsaUJBQWlCLElBQUksZ0JBQWdCLEVBQUUsWUFBWSxJQUFJLFdBQVcsRUFBRSxXQUFXLElBQUksVUFBVSxFQUFFLFdBQVcsSUFBSSxVQUFVLEVBQUUsV0FBVyxJQUFJLFVBQVUsRUFBRSxZQUFZLElBQUksV0FBVyxFQUFFLGdCQUFnQixJQUFJLGlCQUFpQixFQUF3RiwyQkFBMkIsSUFBSSwwQkFBMEIsRUFBRSx3QkFBd0IsSUFBSSxnQkFBZ0IsRUFBRSxtQkFBbUIsSUFBSSxXQUFXLEVBQUUsWUFBWSxJQUFJLFdBQVcsRUFBRSxvQkFBb0IsSUFBSSxtQkFBbUIsRUFBbUQsTUFBTSxlQUFlLENBQUM7QUFFN2lDLE9BQU8sRUFBQyx3Q0FBd0MsRUFBRSwrQkFBK0IsRUFBRSx5QkFBeUIsRUFBRSwrQkFBK0IsRUFBQyxNQUFNLHFDQUFxQyxDQUFDO0FBRzFMLE9BQU8sRUFBQyxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQVcsTUFBTSxhQUFhLENBQUM7QUFHM0csSUFBSyxxQkFHSjtBQUhE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QUFVLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBRUQsaUNBQWlDLENBQUksVUFBbUI7UUFDdEQsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzNELE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxVQUE2QixDQUFDLENBQUM7UUFDOUYsT0FBTyxJQUFJLDRCQUE0QixDQUFDLGVBQWUsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO0lBQy9FLENBQUM7SUFFRCxLQUFLLENBQUMsa0NBQWtDLENBQUksVUFBbUI7UUFFN0QsTUFBTSxlQUFlLEdBQUcsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbEUsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLHNCQUFzQixDQUFDLFVBQTZCLENBQUMsQ0FBQztRQUM5RixPQUFPLElBQUksNEJBQTRCLENBQUMsZUFBZSxFQUFFLGtCQUFrQixDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUVELFVBQVUsS0FBVSxDQUFDO0lBRXJCLGFBQWEsQ0FBQyxJQUFlLElBQVMsQ0FBQztJQUV2QyxXQUFXLENBQUMsVUFBcUI7UUFDL0IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNuRSxPQUFPLElBQUksSUFBSSxJQUFJLENBQUMsRUFBRSxJQUFJLFNBQVMsQ0FBQztJQUN0QyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtSZXNvdXJjZUxvYWRlcn0gZnJvbSAnQGFuZ3VsYXIvY29tcGlsZXInO1xuaW1wb3J0IHtBcHBsaWNhdGlvbkluaXRTdGF0dXMsIENvbXBpbGVyLCBDT01QSUxFUl9PUFRJT05TLCBDb21wb25lbnQsIERpcmVjdGl2ZSwgSW5qZWN0b3IsIEluamVjdG9yVHlwZSwgTE9DQUxFX0lELCBNb2R1bGVXaXRoQ29tcG9uZW50RmFjdG9yaWVzLCBNb2R1bGVXaXRoUHJvdmlkZXJzLCBOZ01vZHVsZSwgTmdNb2R1bGVGYWN0b3J5LCBOZ1pvbmUsIFBpcGUsIFBsYXRmb3JtUmVmLCBQcm92aWRlciwgcmVzb2x2ZUZvcndhcmRSZWYsIFR5cGUsIMm1Y29tcGlsZUNvbXBvbmVudCBhcyBjb21waWxlQ29tcG9uZW50LCDJtWNvbXBpbGVEaXJlY3RpdmUgYXMgY29tcGlsZURpcmVjdGl2ZSwgybVjb21waWxlTmdNb2R1bGVEZWZzIGFzIGNvbXBpbGVOZ01vZHVsZURlZnMsIMm1Y29tcGlsZVBpcGUgYXMgY29tcGlsZVBpcGUsIMm1REVGQVVMVF9MT0NBTEVfSUQgYXMgREVGQVVMVF9MT0NBTEVfSUQsIMm1RGlyZWN0aXZlRGVmIGFzIERpcmVjdGl2ZURlZiwgybVnZXRJbmplY3RhYmxlRGVmIGFzIGdldEluamVjdGFibGVEZWYsIMm1TkdfQ09NUF9ERUYgYXMgTkdfQ09NUF9ERUYsIMm1TkdfRElSX0RFRiBhcyBOR19ESVJfREVGLCDJtU5HX0lOSl9ERUYgYXMgTkdfSU5KX0RFRiwgybVOR19NT0RfREVGIGFzIE5HX01PRF9ERUYsIMm1TkdfUElQRV9ERUYgYXMgTkdfUElQRV9ERUYsIMm1TmdNb2R1bGVGYWN0b3J5IGFzIFIzTmdNb2R1bGVGYWN0b3J5LCDJtU5nTW9kdWxlVHJhbnNpdGl2ZVNjb3BlcyBhcyBOZ01vZHVsZVRyYW5zaXRpdmVTY29wZXMsIMm1TmdNb2R1bGVUeXBlIGFzIE5nTW9kdWxlVHlwZSwgybVwYXRjaENvbXBvbmVudERlZldpdGhTY29wZSBhcyBwYXRjaENvbXBvbmVudERlZldpdGhTY29wZSwgybVSZW5kZXIzQ29tcG9uZW50RmFjdG9yeSBhcyBDb21wb25lbnRGYWN0b3J5LCDJtVJlbmRlcjNOZ01vZHVsZVJlZiBhcyBOZ01vZHVsZVJlZiwgybVzZXRMb2NhbGVJZCBhcyBzZXRMb2NhbGVJZCwgybV0cmFuc2l0aXZlU2NvcGVzRm9yIGFzIHRyYW5zaXRpdmVTY29wZXNGb3IsIMm1ybVJbmplY3RhYmxlRGVjbGFyYXRpb24gYXMgSW5qZWN0YWJsZURlY2xhcmF0aW9ufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtjbGVhclJlc29sdXRpb25PZkNvbXBvbmVudFJlc291cmNlc1F1ZXVlLCBpc0NvbXBvbmVudERlZlBlbmRpbmdSZXNvbHV0aW9uLCByZXNvbHZlQ29tcG9uZW50UmVzb3VyY2VzLCByZXN0b3JlQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlfSBmcm9tICcuLi8uLi9zcmMvbWV0YWRhdGEvcmVzb3VyY2VfbG9hZGluZyc7XG5cbmltcG9ydCB7TWV0YWRhdGFPdmVycmlkZX0gZnJvbSAnLi9tZXRhZGF0YV9vdmVycmlkZSc7XG5pbXBvcnQge0NvbXBvbmVudFJlc29sdmVyLCBEaXJlY3RpdmVSZXNvbHZlciwgTmdNb2R1bGVSZXNvbHZlciwgUGlwZVJlc29sdmVyLCBSZXNvbHZlcn0gZnJvbSAnLi9yZXNvbHZlcnMnO1xuaW1wb3J0IHtUZXN0TW9kdWxlTWV0YWRhdGF9IGZyb20gJy4vdGVzdF9iZWRfY29tbW9uJztcblxuZW51bSBUZXN0aW5nTW9kdWxlT3ZlcnJpZGUge1xuICBERUNMQVJBVElPTixcbiAgT1ZFUlJJREVfVEVNUExBVEUsXG59XG5cbmZ1bmN0aW9uIGlzVGVzdGluZ01vZHVsZU92ZXJyaWRlKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgVGVzdGluZ01vZHVsZU92ZXJyaWRlIHtcbiAgcmV0dXJuIHZhbHVlID09PSBUZXN0aW5nTW9kdWxlT3ZlcnJpZGUuREVDTEFSQVRJT04gfHxcbiAgICAgIHZhbHVlID09PSBUZXN0aW5nTW9kdWxlT3ZlcnJpZGUuT1ZFUlJJREVfVEVNUExBVEU7XG59XG5cbi8vIFJlc29sdmVycyBmb3IgQW5ndWxhciBkZWNvcmF0b3JzXG50eXBlIFJlc29sdmVycyA9IHtcbiAgbW9kdWxlOiBSZXNvbHZlcjxOZ01vZHVsZT4sXG4gIGNvbXBvbmVudDogUmVzb2x2ZXI8RGlyZWN0aXZlPixcbiAgZGlyZWN0aXZlOiBSZXNvbHZlcjxDb21wb25lbnQ+LFxuICBwaXBlOiBSZXNvbHZlcjxQaXBlPixcbn07XG5cbmludGVyZmFjZSBDbGVhbnVwT3BlcmF0aW9uIHtcbiAgZmllbGROYW1lOiBzdHJpbmc7XG4gIG9iamVjdDogYW55O1xuICBvcmlnaW5hbFZhbHVlOiB1bmtub3duO1xufVxuXG5leHBvcnQgY2xhc3MgUjNUZXN0QmVkQ29tcGlsZXIge1xuICBwcml2YXRlIG9yaWdpbmFsQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlOiBNYXA8VHlwZTxhbnk+LCBDb21wb25lbnQ+fG51bGwgPSBudWxsO1xuXG4gIC8vIFRlc3RpbmcgbW9kdWxlIGNvbmZpZ3VyYXRpb25cbiAgcHJpdmF0ZSBkZWNsYXJhdGlvbnM6IFR5cGU8YW55PltdID0gW107XG4gIHByaXZhdGUgaW1wb3J0czogVHlwZTxhbnk+W10gPSBbXTtcbiAgcHJpdmF0ZSBwcm92aWRlcnM6IFByb3ZpZGVyW10gPSBbXTtcbiAgcHJpdmF0ZSBzY2hlbWFzOiBhbnlbXSA9IFtdO1xuXG4gIC8vIFF1ZXVlcyBvZiBjb21wb25lbnRzL2RpcmVjdGl2ZXMvcGlwZXMgdGhhdCBzaG91bGQgYmUgcmVjb21waWxlZC5cbiAgcHJpdmF0ZSBwZW5kaW5nQ29tcG9uZW50cyA9IG5ldyBTZXQ8VHlwZTxhbnk+PigpO1xuICBwcml2YXRlIHBlbmRpbmdEaXJlY3RpdmVzID0gbmV3IFNldDxUeXBlPGFueT4+KCk7XG4gIHByaXZhdGUgcGVuZGluZ1BpcGVzID0gbmV3IFNldDxUeXBlPGFueT4+KCk7XG5cbiAgLy8gS2VlcCB0cmFjayBvZiBhbGwgY29tcG9uZW50cyBhbmQgZGlyZWN0aXZlcywgc28gd2UgY2FuIHBhdGNoIFByb3ZpZGVycyBvbnRvIGRlZnMgbGF0ZXIuXG4gIHByaXZhdGUgc2VlbkNvbXBvbmVudHMgPSBuZXcgU2V0PFR5cGU8YW55Pj4oKTtcbiAgcHJpdmF0ZSBzZWVuRGlyZWN0aXZlcyA9IG5ldyBTZXQ8VHlwZTxhbnk+PigpO1xuXG4gIC8vIEtlZXAgdHJhY2sgb2Ygb3ZlcnJpZGRlbiBtb2R1bGVzLCBzbyB0aGF0IHdlIGNhbiBjb2xsZWN0IGFsbCBhZmZlY3RlZCBvbmVzIGluIHRoZSBtb2R1bGUgdHJlZS5cbiAgcHJpdmF0ZSBvdmVycmlkZGVuTW9kdWxlcyA9IG5ldyBTZXQ8TmdNb2R1bGVUeXBlPGFueT4+KCk7XG5cbiAgLy8gU3RvcmUgcmVzb2x2ZWQgc3R5bGVzIGZvciBDb21wb25lbnRzIHRoYXQgaGF2ZSB0ZW1wbGF0ZSBvdmVycmlkZXMgcHJlc2VudCBhbmQgYHN0eWxlVXJsc2BcbiAgLy8gZGVmaW5lZCBhdCB0aGUgc2FtZSB0aW1lLlxuICBwcml2YXRlIGV4aXN0aW5nQ29tcG9uZW50U3R5bGVzID0gbmV3IE1hcDxUeXBlPGFueT4sIHN0cmluZ1tdPigpO1xuXG4gIHByaXZhdGUgcmVzb2x2ZXJzOiBSZXNvbHZlcnMgPSBpbml0UmVzb2x2ZXJzKCk7XG5cbiAgcHJpdmF0ZSBjb21wb25lbnRUb01vZHVsZVNjb3BlID0gbmV3IE1hcDxUeXBlPGFueT4sIFR5cGU8YW55PnxUZXN0aW5nTW9kdWxlT3ZlcnJpZGU+KCk7XG5cbiAgLy8gTWFwIHRoYXQga2VlcHMgaW5pdGlhbCB2ZXJzaW9uIG9mIGNvbXBvbmVudC9kaXJlY3RpdmUvcGlwZSBkZWZzIGluIGNhc2VcbiAgLy8gd2UgY29tcGlsZSBhIFR5cGUgYWdhaW4sIHRodXMgb3ZlcnJpZGluZyByZXNwZWN0aXZlIHN0YXRpYyBmaWVsZHMuIFRoaXMgaXNcbiAgLy8gcmVxdWlyZWQgdG8gbWFrZSBzdXJlIHdlIHJlc3RvcmUgZGVmcyB0byB0aGVpciBpbml0aWFsIHN0YXRlcyBiZXR3ZWVuIHRlc3QgcnVuc1xuICAvLyBUT0RPOiB3ZSBzaG91bGQgc3VwcG9ydCB0aGUgY2FzZSB3aXRoIG11bHRpcGxlIGRlZnMgb24gYSB0eXBlXG4gIHByaXZhdGUgaW5pdGlhbE5nRGVmcyA9IG5ldyBNYXA8VHlwZTxhbnk+LCBbc3RyaW5nLCBQcm9wZXJ0eURlc2NyaXB0b3J8dW5kZWZpbmVkXT4oKTtcblxuICAvLyBBcnJheSB0aGF0IGtlZXBzIGNsZWFudXAgb3BlcmF0aW9ucyBmb3IgaW5pdGlhbCB2ZXJzaW9ucyBvZiBjb21wb25lbnQvZGlyZWN0aXZlL3BpcGUvbW9kdWxlXG4gIC8vIGRlZnMgaW4gY2FzZSBUZXN0QmVkIG1ha2VzIGNoYW5nZXMgdG8gdGhlIG9yaWdpbmFscy5cbiAgcHJpdmF0ZSBkZWZDbGVhbnVwT3BzOiBDbGVhbnVwT3BlcmF0aW9uW10gPSBbXTtcblxuICBwcml2YXRlIF9pbmplY3RvcjogSW5qZWN0b3J8bnVsbCA9IG51bGw7XG4gIHByaXZhdGUgY29tcGlsZXJQcm92aWRlcnM6IFByb3ZpZGVyW118bnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBwcm92aWRlck92ZXJyaWRlczogUHJvdmlkZXJbXSA9IFtdO1xuICBwcml2YXRlIHJvb3RQcm92aWRlck92ZXJyaWRlczogUHJvdmlkZXJbXSA9IFtdO1xuICAvLyBPdmVycmlkZXMgZm9yIGluamVjdGFibGVzIHdpdGggYHtwcm92aWRlZEluOiBTb21lTW9kdWxlfWAgbmVlZCB0byBiZSB0cmFja2VkIGFuZCBhZGRlZCB0byB0aGF0XG4gIC8vIG1vZHVsZSdzIHByb3ZpZGVyIGxpc3QuXG4gIHByaXZhdGUgcHJvdmlkZXJPdmVycmlkZXNCeU1vZHVsZSA9IG5ldyBNYXA8SW5qZWN0b3JUeXBlPGFueT4sIFByb3ZpZGVyW10+KCk7XG4gIHByaXZhdGUgcHJvdmlkZXJPdmVycmlkZXNCeVRva2VuID0gbmV3IE1hcDxhbnksIFByb3ZpZGVyPigpO1xuICBwcml2YXRlIG1vZHVsZVByb3ZpZGVyc092ZXJyaWRkZW4gPSBuZXcgU2V0PFR5cGU8YW55Pj4oKTtcblxuICBwcml2YXRlIHRlc3RNb2R1bGVUeXBlOiBOZ01vZHVsZVR5cGU8YW55PjtcbiAgcHJpdmF0ZSB0ZXN0TW9kdWxlUmVmOiBOZ01vZHVsZVJlZjxhbnk+fG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcGxhdGZvcm06IFBsYXRmb3JtUmVmLCBwcml2YXRlIGFkZGl0aW9uYWxNb2R1bGVUeXBlczogVHlwZTxhbnk+fFR5cGU8YW55PltdKSB7XG4gICAgY2xhc3MgRHluYW1pY1Rlc3RNb2R1bGUge31cbiAgICB0aGlzLnRlc3RNb2R1bGVUeXBlID0gRHluYW1pY1Rlc3RNb2R1bGUgYXMgYW55O1xuICB9XG5cbiAgc2V0Q29tcGlsZXJQcm92aWRlcnMocHJvdmlkZXJzOiBQcm92aWRlcltdfG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLmNvbXBpbGVyUHJvdmlkZXJzID0gcHJvdmlkZXJzO1xuICAgIHRoaXMuX2luamVjdG9yID0gbnVsbDtcbiAgfVxuXG4gIGNvbmZpZ3VyZVRlc3RpbmdNb2R1bGUobW9kdWxlRGVmOiBUZXN0TW9kdWxlTWV0YWRhdGEpOiB2b2lkIHtcbiAgICAvLyBFbnF1ZXVlIGFueSBjb21waWxhdGlvbiB0YXNrcyBmb3IgdGhlIGRpcmVjdGx5IGRlY2xhcmVkIGNvbXBvbmVudC5cbiAgICBpZiAobW9kdWxlRGVmLmRlY2xhcmF0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnF1ZXVlVHlwZUFycmF5KG1vZHVsZURlZi5kZWNsYXJhdGlvbnMsIFRlc3RpbmdNb2R1bGVPdmVycmlkZS5ERUNMQVJBVElPTik7XG4gICAgICB0aGlzLmRlY2xhcmF0aW9ucy5wdXNoKC4uLm1vZHVsZURlZi5kZWNsYXJhdGlvbnMpO1xuICAgIH1cblxuICAgIC8vIEVucXVldWUgYW55IGNvbXBpbGF0aW9uIHRhc2tzIGZvciBpbXBvcnRlZCBtb2R1bGVzLlxuICAgIGlmIChtb2R1bGVEZWYuaW1wb3J0cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnF1ZXVlVHlwZXNGcm9tTW9kdWxlc0FycmF5KG1vZHVsZURlZi5pbXBvcnRzKTtcbiAgICAgIHRoaXMuaW1wb3J0cy5wdXNoKC4uLm1vZHVsZURlZi5pbXBvcnRzKTtcbiAgICB9XG5cbiAgICBpZiAobW9kdWxlRGVmLnByb3ZpZGVycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnByb3ZpZGVycy5wdXNoKC4uLm1vZHVsZURlZi5wcm92aWRlcnMpO1xuICAgIH1cblxuICAgIGlmIChtb2R1bGVEZWYuc2NoZW1hcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnNjaGVtYXMucHVzaCguLi5tb2R1bGVEZWYuc2NoZW1hcyk7XG4gICAgfVxuICB9XG5cbiAgb3ZlcnJpZGVNb2R1bGUobmdNb2R1bGU6IFR5cGU8YW55Piwgb3ZlcnJpZGU6IE1ldGFkYXRhT3ZlcnJpZGU8TmdNb2R1bGU+KTogdm9pZCB7XG4gICAgdGhpcy5vdmVycmlkZGVuTW9kdWxlcy5hZGQobmdNb2R1bGUgYXMgTmdNb2R1bGVUeXBlPGFueT4pO1xuXG4gICAgLy8gQ29tcGlsZSB0aGUgbW9kdWxlIHJpZ2h0IGF3YXkuXG4gICAgdGhpcy5yZXNvbHZlcnMubW9kdWxlLmFkZE92ZXJyaWRlKG5nTW9kdWxlLCBvdmVycmlkZSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnJlc29sdmVycy5tb2R1bGUucmVzb2x2ZShuZ01vZHVsZSk7XG4gICAgaWYgKG1ldGFkYXRhID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBpbnZhbGlkVHlwZUVycm9yKG5nTW9kdWxlLm5hbWUsICdOZ01vZHVsZScpO1xuICAgIH1cblxuICAgIHRoaXMucmVjb21waWxlTmdNb2R1bGUobmdNb2R1bGUsIG1ldGFkYXRhKTtcblxuICAgIC8vIEF0IHRoaXMgcG9pbnQsIHRoZSBtb2R1bGUgaGFzIGEgdmFsaWQgbW9kdWxlIGRlZiAoybVtb2QpLCBidXQgdGhlIG92ZXJyaWRlIG1heSBoYXZlIGludHJvZHVjZWRcbiAgICAvLyBuZXcgZGVjbGFyYXRpb25zIG9yIGltcG9ydGVkIG1vZHVsZXMuIEluZ2VzdCBhbnkgcG9zc2libGUgbmV3IHR5cGVzIGFuZCBhZGQgdGhlbSB0byB0aGVcbiAgICAvLyBjdXJyZW50IHF1ZXVlLlxuICAgIHRoaXMucXVldWVUeXBlc0Zyb21Nb2R1bGVzQXJyYXkoW25nTW9kdWxlXSk7XG4gIH1cblxuICBvdmVycmlkZUNvbXBvbmVudChjb21wb25lbnQ6IFR5cGU8YW55Piwgb3ZlcnJpZGU6IE1ldGFkYXRhT3ZlcnJpZGU8Q29tcG9uZW50Pik6IHZvaWQge1xuICAgIHRoaXMucmVzb2x2ZXJzLmNvbXBvbmVudC5hZGRPdmVycmlkZShjb21wb25lbnQsIG92ZXJyaWRlKTtcbiAgICB0aGlzLnBlbmRpbmdDb21wb25lbnRzLmFkZChjb21wb25lbnQpO1xuICB9XG5cbiAgb3ZlcnJpZGVEaXJlY3RpdmUoZGlyZWN0aXZlOiBUeXBlPGFueT4sIG92ZXJyaWRlOiBNZXRhZGF0YU92ZXJyaWRlPERpcmVjdGl2ZT4pOiB2b2lkIHtcbiAgICB0aGlzLnJlc29sdmVycy5kaXJlY3RpdmUuYWRkT3ZlcnJpZGUoZGlyZWN0aXZlLCBvdmVycmlkZSk7XG4gICAgdGhpcy5wZW5kaW5nRGlyZWN0aXZlcy5hZGQoZGlyZWN0aXZlKTtcbiAgfVxuXG4gIG92ZXJyaWRlUGlwZShwaXBlOiBUeXBlPGFueT4sIG92ZXJyaWRlOiBNZXRhZGF0YU92ZXJyaWRlPFBpcGU+KTogdm9pZCB7XG4gICAgdGhpcy5yZXNvbHZlcnMucGlwZS5hZGRPdmVycmlkZShwaXBlLCBvdmVycmlkZSk7XG4gICAgdGhpcy5wZW5kaW5nUGlwZXMuYWRkKHBpcGUpO1xuICB9XG5cbiAgb3ZlcnJpZGVQcm92aWRlcihcbiAgICAgIHRva2VuOiBhbnksXG4gICAgICBwcm92aWRlcjoge3VzZUZhY3Rvcnk/OiBGdW5jdGlvbiwgdXNlVmFsdWU/OiBhbnksIGRlcHM/OiBhbnlbXSwgbXVsdGk/OiBib29sZWFufSk6IHZvaWQge1xuICAgIGxldCBwcm92aWRlckRlZjogUHJvdmlkZXI7XG4gICAgaWYgKHByb3ZpZGVyLnVzZUZhY3RvcnkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcHJvdmlkZXJEZWYgPSB7XG4gICAgICAgIHByb3ZpZGU6IHRva2VuLFxuICAgICAgICB1c2VGYWN0b3J5OiBwcm92aWRlci51c2VGYWN0b3J5LFxuICAgICAgICBkZXBzOiBwcm92aWRlci5kZXBzIHx8IFtdLFxuICAgICAgICBtdWx0aTogcHJvdmlkZXIubXVsdGlcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChwcm92aWRlci51c2VWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBwcm92aWRlckRlZiA9IHtwcm92aWRlOiB0b2tlbiwgdXNlVmFsdWU6IHByb3ZpZGVyLnVzZVZhbHVlLCBtdWx0aTogcHJvdmlkZXIubXVsdGl9O1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm92aWRlckRlZiA9IHtwcm92aWRlOiB0b2tlbn07XG4gICAgfVxuXG4gICAgY29uc3QgaW5qZWN0YWJsZURlZjogSW5qZWN0YWJsZURlY2xhcmF0aW9uPGFueT58bnVsbCA9XG4gICAgICAgIHR5cGVvZiB0b2tlbiAhPT0gJ3N0cmluZycgPyBnZXRJbmplY3RhYmxlRGVmKHRva2VuKSA6IG51bGw7XG4gICAgY29uc3QgcHJvdmlkZWRJbiA9IGluamVjdGFibGVEZWYgPT09IG51bGwgPyBudWxsIDogcmVzb2x2ZUZvcndhcmRSZWYoaW5qZWN0YWJsZURlZi5wcm92aWRlZEluKTtcbiAgICBjb25zdCBvdmVycmlkZXNCdWNrZXQgPVxuICAgICAgICBwcm92aWRlZEluID09PSAncm9vdCcgPyB0aGlzLnJvb3RQcm92aWRlck92ZXJyaWRlcyA6IHRoaXMucHJvdmlkZXJPdmVycmlkZXM7XG4gICAgb3ZlcnJpZGVzQnVja2V0LnB1c2gocHJvdmlkZXJEZWYpO1xuXG4gICAgLy8gS2VlcCBvdmVycmlkZXMgZ3JvdXBlZCBieSB0b2tlbiBhcyB3ZWxsIGZvciBmYXN0IGxvb2t1cHMgdXNpbmcgdG9rZW5cbiAgICB0aGlzLnByb3ZpZGVyT3ZlcnJpZGVzQnlUb2tlbi5zZXQodG9rZW4sIHByb3ZpZGVyRGVmKTtcbiAgICBpZiAoaW5qZWN0YWJsZURlZiAhPT0gbnVsbCAmJiBwcm92aWRlZEluICE9PSBudWxsICYmIHR5cGVvZiBwcm92aWRlZEluICE9PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgZXhpc3RpbmdPdmVycmlkZXMgPSB0aGlzLnByb3ZpZGVyT3ZlcnJpZGVzQnlNb2R1bGUuZ2V0KHByb3ZpZGVkSW4pO1xuICAgICAgaWYgKGV4aXN0aW5nT3ZlcnJpZGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZXhpc3RpbmdPdmVycmlkZXMucHVzaChwcm92aWRlckRlZik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnByb3ZpZGVyT3ZlcnJpZGVzQnlNb2R1bGUuc2V0KHByb3ZpZGVkSW4sIFtwcm92aWRlckRlZl0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG92ZXJyaWRlVGVtcGxhdGVVc2luZ1Rlc3RpbmdNb2R1bGUodHlwZTogVHlwZTxhbnk+LCB0ZW1wbGF0ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZGVmID0gKHR5cGUgYXMgYW55KVtOR19DT01QX0RFRl07XG4gICAgY29uc3QgaGFzU3R5bGVVcmxzID0gKCk6IGJvb2xlYW4gPT4ge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnJlc29sdmVycy5jb21wb25lbnQucmVzb2x2ZSh0eXBlKSEgYXMgQ29tcG9uZW50O1xuICAgICAgcmV0dXJuICEhbWV0YWRhdGEuc3R5bGVVcmxzICYmIG1ldGFkYXRhLnN0eWxlVXJscy5sZW5ndGggPiAwO1xuICAgIH07XG4gICAgY29uc3Qgb3ZlcnJpZGVTdHlsZVVybHMgPSAhIWRlZiAmJiAhaXNDb21wb25lbnREZWZQZW5kaW5nUmVzb2x1dGlvbih0eXBlKSAmJiBoYXNTdHlsZVVybHMoKTtcblxuICAgIC8vIEluIEl2eSwgY29tcGlsaW5nIGEgY29tcG9uZW50IGRvZXMgbm90IHJlcXVpcmUga25vd2luZyB0aGUgbW9kdWxlIHByb3ZpZGluZyB0aGVcbiAgICAvLyBjb21wb25lbnQncyBzY29wZSwgc28gb3ZlcnJpZGVUZW1wbGF0ZVVzaW5nVGVzdGluZ01vZHVsZSBjYW4gYmUgaW1wbGVtZW50ZWQgcHVyZWx5IHZpYVxuICAgIC8vIG92ZXJyaWRlQ29tcG9uZW50LiBJbXBvcnRhbnQ6IG92ZXJyaWRpbmcgdGVtcGxhdGUgcmVxdWlyZXMgZnVsbCBDb21wb25lbnQgcmUtY29tcGlsYXRpb24sXG4gICAgLy8gd2hpY2ggbWF5IGZhaWwgaW4gY2FzZSBzdHlsZVVybHMgYXJlIGFsc28gcHJlc2VudCAodGh1cyBDb21wb25lbnQgaXMgY29uc2lkZXJlZCBhcyByZXF1aXJlZFxuICAgIC8vIHJlc29sdXRpb24pLiBJbiBvcmRlciB0byBhdm9pZCB0aGlzLCB3ZSBwcmVlbXB0aXZlbHkgc2V0IHN0eWxlVXJscyB0byBhbiBlbXB0eSBhcnJheSxcbiAgICAvLyBwcmVzZXJ2ZSBjdXJyZW50IHN0eWxlcyBhdmFpbGFibGUgb24gQ29tcG9uZW50IGRlZiBhbmQgcmVzdG9yZSBzdHlsZXMgYmFjayBvbmNlIGNvbXBpbGF0aW9uXG4gICAgLy8gaXMgY29tcGxldGUuXG4gICAgY29uc3Qgb3ZlcnJpZGUgPSBvdmVycmlkZVN0eWxlVXJscyA/IHt0ZW1wbGF0ZSwgc3R5bGVzOiBbXSwgc3R5bGVVcmxzOiBbXX0gOiB7dGVtcGxhdGV9O1xuICAgIHRoaXMub3ZlcnJpZGVDb21wb25lbnQodHlwZSwge3NldDogb3ZlcnJpZGV9KTtcblxuICAgIGlmIChvdmVycmlkZVN0eWxlVXJscyAmJiBkZWYuc3R5bGVzICYmIGRlZi5zdHlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5leGlzdGluZ0NvbXBvbmVudFN0eWxlcy5zZXQodHlwZSwgZGVmLnN0eWxlcyk7XG4gICAgfVxuXG4gICAgLy8gU2V0IHRoZSBjb21wb25lbnQncyBzY29wZSB0byBiZSB0aGUgdGVzdGluZyBtb2R1bGUuXG4gICAgdGhpcy5jb21wb25lbnRUb01vZHVsZVNjb3BlLnNldCh0eXBlLCBUZXN0aW5nTW9kdWxlT3ZlcnJpZGUuT1ZFUlJJREVfVEVNUExBVEUpO1xuICB9XG5cbiAgYXN5bmMgY29tcGlsZUNvbXBvbmVudHMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5jbGVhckNvbXBvbmVudFJlc29sdXRpb25RdWV1ZSgpO1xuICAgIC8vIFJ1biBjb21waWxlcnMgZm9yIGFsbCBxdWV1ZWQgdHlwZXMuXG4gICAgbGV0IG5lZWRzQXN5bmNSZXNvdXJjZXMgPSB0aGlzLmNvbXBpbGVUeXBlc1N5bmMoKTtcblxuICAgIC8vIGNvbXBpbGVDb21wb25lbnRzKCkgc2hvdWxkIG5vdCBiZSBhc3luYyB1bmxlc3MgaXQgbmVlZHMgdG8gYmUuXG4gICAgaWYgKG5lZWRzQXN5bmNSZXNvdXJjZXMpIHtcbiAgICAgIGxldCByZXNvdXJjZUxvYWRlcjogUmVzb3VyY2VMb2FkZXI7XG4gICAgICBsZXQgcmVzb2x2ZXIgPSAodXJsOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgICAgICBpZiAoIXJlc291cmNlTG9hZGVyKSB7XG4gICAgICAgICAgcmVzb3VyY2VMb2FkZXIgPSB0aGlzLmluamVjdG9yLmdldChSZXNvdXJjZUxvYWRlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNvdXJjZUxvYWRlci5nZXQodXJsKSk7XG4gICAgICB9O1xuICAgICAgYXdhaXQgcmVzb2x2ZUNvbXBvbmVudFJlc291cmNlcyhyZXNvbHZlcik7XG4gICAgfVxuICB9XG5cbiAgZmluYWxpemUoKTogTmdNb2R1bGVSZWY8YW55PiB7XG4gICAgLy8gT25lIGxhc3QgY29tcGlsZVxuICAgIHRoaXMuY29tcGlsZVR5cGVzU3luYygpO1xuXG4gICAgLy8gQ3JlYXRlIHRoZSB0ZXN0aW5nIG1vZHVsZSBpdHNlbGYuXG4gICAgdGhpcy5jb21waWxlVGVzdE1vZHVsZSgpO1xuXG4gICAgdGhpcy5hcHBseVRyYW5zaXRpdmVTY29wZXMoKTtcblxuICAgIHRoaXMuYXBwbHlQcm92aWRlck92ZXJyaWRlcygpO1xuXG4gICAgLy8gUGF0Y2ggcHJldmlvdXNseSBzdG9yZWQgYHN0eWxlc2AgQ29tcG9uZW50IHZhbHVlcyAodGFrZW4gZnJvbSDJtWNtcCksIGluIGNhc2UgdGhlc2VcbiAgICAvLyBDb21wb25lbnRzIGhhdmUgYHN0eWxlVXJsc2AgZmllbGRzIGRlZmluZWQgYW5kIHRlbXBsYXRlIG92ZXJyaWRlIHdhcyByZXF1ZXN0ZWQuXG4gICAgdGhpcy5wYXRjaENvbXBvbmVudHNXaXRoRXhpc3RpbmdTdHlsZXMoKTtcblxuICAgIC8vIENsZWFyIHRoZSBjb21wb25lbnRUb01vZHVsZVNjb3BlIG1hcCwgc28gdGhhdCBmdXR1cmUgY29tcGlsYXRpb25zIGRvbid0IHJlc2V0IHRoZSBzY29wZSBvZlxuICAgIC8vIGV2ZXJ5IGNvbXBvbmVudC5cbiAgICB0aGlzLmNvbXBvbmVudFRvTW9kdWxlU2NvcGUuY2xlYXIoKTtcblxuICAgIGNvbnN0IHBhcmVudEluamVjdG9yID0gdGhpcy5wbGF0Zm9ybS5pbmplY3RvcjtcbiAgICB0aGlzLnRlc3RNb2R1bGVSZWYgPSBuZXcgTmdNb2R1bGVSZWYodGhpcy50ZXN0TW9kdWxlVHlwZSwgcGFyZW50SW5qZWN0b3IpO1xuXG4gICAgLy8gQXBwbGljYXRpb25Jbml0U3RhdHVzLnJ1bkluaXRpYWxpemVycygpIGlzIG1hcmtlZCBAaW50ZXJuYWwgdG8gY29yZS5cbiAgICAvLyBDYXN0IGl0IHRvIGFueSBiZWZvcmUgYWNjZXNzaW5nIGl0LlxuICAgICh0aGlzLnRlc3RNb2R1bGVSZWYuaW5qZWN0b3IuZ2V0KEFwcGxpY2F0aW9uSW5pdFN0YXR1cykgYXMgYW55KS5ydW5Jbml0aWFsaXplcnMoKTtcblxuICAgIC8vIFNldCBsb2NhbGUgSUQgYWZ0ZXIgcnVubmluZyBhcHAgaW5pdGlhbGl6ZXJzLCBzaW5jZSBsb2NhbGUgaW5mb3JtYXRpb24gbWlnaHQgYmUgdXBkYXRlZCB3aGlsZVxuICAgIC8vIHJ1bm5pbmcgaW5pdGlhbGl6ZXJzLiBUaGlzIGlzIGFsc28gY29uc2lzdGVudCB3aXRoIHRoZSBleGVjdXRpb24gb3JkZXIgd2hpbGUgYm9vdHN0cmFwcGluZyBhblxuICAgIC8vIGFwcCAoc2VlIGBwYWNrYWdlcy9jb3JlL3NyYy9hcHBsaWNhdGlvbl9yZWYudHNgIGZpbGUpLlxuICAgIGNvbnN0IGxvY2FsZUlkID0gdGhpcy50ZXN0TW9kdWxlUmVmLmluamVjdG9yLmdldChMT0NBTEVfSUQsIERFRkFVTFRfTE9DQUxFX0lEKTtcbiAgICBzZXRMb2NhbGVJZChsb2NhbGVJZCk7XG5cbiAgICByZXR1cm4gdGhpcy50ZXN0TW9kdWxlUmVmO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgX2NvbXBpbGVOZ01vZHVsZVN5bmMobW9kdWxlVHlwZTogVHlwZTxhbnk+KTogdm9pZCB7XG4gICAgdGhpcy5xdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheShbbW9kdWxlVHlwZV0pO1xuICAgIHRoaXMuY29tcGlsZVR5cGVzU3luYygpO1xuICAgIHRoaXMuYXBwbHlQcm92aWRlck92ZXJyaWRlcygpO1xuICAgIHRoaXMuYXBwbHlQcm92aWRlck92ZXJyaWRlc1RvTW9kdWxlKG1vZHVsZVR5cGUpO1xuICAgIHRoaXMuYXBwbHlUcmFuc2l0aXZlU2NvcGVzKCk7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBhc3luYyBfY29tcGlsZU5nTW9kdWxlQXN5bmMobW9kdWxlVHlwZTogVHlwZTxhbnk+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5xdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheShbbW9kdWxlVHlwZV0pO1xuICAgIGF3YWl0IHRoaXMuY29tcGlsZUNvbXBvbmVudHMoKTtcbiAgICB0aGlzLmFwcGx5UHJvdmlkZXJPdmVycmlkZXMoKTtcbiAgICB0aGlzLmFwcGx5UHJvdmlkZXJPdmVycmlkZXNUb01vZHVsZShtb2R1bGVUeXBlKTtcbiAgICB0aGlzLmFwcGx5VHJhbnNpdGl2ZVNjb3BlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgX2dldE1vZHVsZVJlc29sdmVyKCk6IFJlc29sdmVyPE5nTW9kdWxlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZXJzLm1vZHVsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIF9nZXRDb21wb25lbnRGYWN0b3JpZXMobW9kdWxlVHlwZTogTmdNb2R1bGVUeXBlKTogQ29tcG9uZW50RmFjdG9yeTxhbnk+W10ge1xuICAgIHJldHVybiBtYXliZVVud3JhcEZuKG1vZHVsZVR5cGUuybVtb2QuZGVjbGFyYXRpb25zKS5yZWR1Y2UoKGZhY3RvcmllcywgZGVjbGFyYXRpb24pID0+IHtcbiAgICAgIGNvbnN0IGNvbXBvbmVudERlZiA9IChkZWNsYXJhdGlvbiBhcyBhbnkpLsm1Y21wO1xuICAgICAgY29tcG9uZW50RGVmICYmIGZhY3Rvcmllcy5wdXNoKG5ldyBDb21wb25lbnRGYWN0b3J5KGNvbXBvbmVudERlZiwgdGhpcy50ZXN0TW9kdWxlUmVmISkpO1xuICAgICAgcmV0dXJuIGZhY3RvcmllcztcbiAgICB9LCBbXSBhcyBDb21wb25lbnRGYWN0b3J5PGFueT5bXSk7XG4gIH1cblxuICBwcml2YXRlIGNvbXBpbGVUeXBlc1N5bmMoKTogYm9vbGVhbiB7XG4gICAgLy8gQ29tcGlsZSBhbGwgcXVldWVkIGNvbXBvbmVudHMsIGRpcmVjdGl2ZXMsIHBpcGVzLlxuICAgIGxldCBuZWVkc0FzeW5jUmVzb3VyY2VzID0gZmFsc2U7XG4gICAgdGhpcy5wZW5kaW5nQ29tcG9uZW50cy5mb3JFYWNoKGRlY2xhcmF0aW9uID0+IHtcbiAgICAgIG5lZWRzQXN5bmNSZXNvdXJjZXMgPSBuZWVkc0FzeW5jUmVzb3VyY2VzIHx8IGlzQ29tcG9uZW50RGVmUGVuZGluZ1Jlc29sdXRpb24oZGVjbGFyYXRpb24pO1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnJlc29sdmVycy5jb21wb25lbnQucmVzb2x2ZShkZWNsYXJhdGlvbik7XG4gICAgICBpZiAobWV0YWRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgaW52YWxpZFR5cGVFcnJvcihkZWNsYXJhdGlvbi5uYW1lLCAnQ29tcG9uZW50Jyk7XG4gICAgICB9XG4gICAgICB0aGlzLm1heWJlU3RvcmVOZ0RlZihOR19DT01QX0RFRiwgZGVjbGFyYXRpb24pO1xuICAgICAgY29tcGlsZUNvbXBvbmVudChkZWNsYXJhdGlvbiwgbWV0YWRhdGEpO1xuICAgIH0pO1xuICAgIHRoaXMucGVuZGluZ0NvbXBvbmVudHMuY2xlYXIoKTtcblxuICAgIHRoaXMucGVuZGluZ0RpcmVjdGl2ZXMuZm9yRWFjaChkZWNsYXJhdGlvbiA9PiB7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMucmVzb2x2ZXJzLmRpcmVjdGl2ZS5yZXNvbHZlKGRlY2xhcmF0aW9uKTtcbiAgICAgIGlmIChtZXRhZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBpbnZhbGlkVHlwZUVycm9yKGRlY2xhcmF0aW9uLm5hbWUsICdEaXJlY3RpdmUnKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubWF5YmVTdG9yZU5nRGVmKE5HX0RJUl9ERUYsIGRlY2xhcmF0aW9uKTtcbiAgICAgIGNvbXBpbGVEaXJlY3RpdmUoZGVjbGFyYXRpb24sIG1ldGFkYXRhKTtcbiAgICB9KTtcbiAgICB0aGlzLnBlbmRpbmdEaXJlY3RpdmVzLmNsZWFyKCk7XG5cbiAgICB0aGlzLnBlbmRpbmdQaXBlcy5mb3JFYWNoKGRlY2xhcmF0aW9uID0+IHtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5yZXNvbHZlcnMucGlwZS5yZXNvbHZlKGRlY2xhcmF0aW9uKTtcbiAgICAgIGlmIChtZXRhZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBpbnZhbGlkVHlwZUVycm9yKGRlY2xhcmF0aW9uLm5hbWUsICdQaXBlJyk7XG4gICAgICB9XG4gICAgICB0aGlzLm1heWJlU3RvcmVOZ0RlZihOR19QSVBFX0RFRiwgZGVjbGFyYXRpb24pO1xuICAgICAgY29tcGlsZVBpcGUoZGVjbGFyYXRpb24sIG1ldGFkYXRhKTtcbiAgICB9KTtcbiAgICB0aGlzLnBlbmRpbmdQaXBlcy5jbGVhcigpO1xuXG4gICAgcmV0dXJuIG5lZWRzQXN5bmNSZXNvdXJjZXM7XG4gIH1cblxuICBwcml2YXRlIGFwcGx5VHJhbnNpdGl2ZVNjb3BlcygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vdmVycmlkZGVuTW9kdWxlcy5zaXplID4gMCkge1xuICAgICAgLy8gTW9kdWxlIG92ZXJyaWRlcyAodmlhIGBUZXN0QmVkLm92ZXJyaWRlTW9kdWxlYCkgbWlnaHQgYWZmZWN0IHNjb3BlcyB0aGF0IHdlcmUgcHJldmlvdXNseVxuICAgICAgLy8gY2FsY3VsYXRlZCBhbmQgc3RvcmVkIGluIGB0cmFuc2l0aXZlQ29tcGlsZVNjb3Blc2AuIElmIG1vZHVsZSBvdmVycmlkZXMgYXJlIHByZXNlbnQsXG4gICAgICAvLyBjb2xsZWN0IGFsbCBhZmZlY3RlZCBtb2R1bGVzIGFuZCByZXNldCBzY29wZXMgdG8gZm9yY2UgdGhlaXIgcmUtY2FsY3VsYXRpb24uXG4gICAgICBjb25zdCB0ZXN0aW5nTW9kdWxlRGVmID0gKHRoaXMudGVzdE1vZHVsZVR5cGUgYXMgYW55KVtOR19NT0RfREVGXTtcbiAgICAgIGNvbnN0IGFmZmVjdGVkTW9kdWxlcyA9IHRoaXMuY29sbGVjdE1vZHVsZXNBZmZlY3RlZEJ5T3ZlcnJpZGVzKHRlc3RpbmdNb2R1bGVEZWYuaW1wb3J0cyk7XG4gICAgICBpZiAoYWZmZWN0ZWRNb2R1bGVzLnNpemUgPiAwKSB7XG4gICAgICAgIGFmZmVjdGVkTW9kdWxlcy5mb3JFYWNoKG1vZHVsZVR5cGUgPT4ge1xuICAgICAgICAgIHRoaXMuc3RvcmVGaWVsZE9mRGVmT25UeXBlKG1vZHVsZVR5cGUgYXMgYW55LCBOR19NT0RfREVGLCAndHJhbnNpdGl2ZUNvbXBpbGVTY29wZXMnKTtcbiAgICAgICAgICAobW9kdWxlVHlwZSBhcyBhbnkpW05HX01PRF9ERUZdLnRyYW5zaXRpdmVDb21waWxlU2NvcGVzID0gbnVsbDtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbW9kdWxlVG9TY29wZSA9IG5ldyBNYXA8VHlwZTxhbnk+fFRlc3RpbmdNb2R1bGVPdmVycmlkZSwgTmdNb2R1bGVUcmFuc2l0aXZlU2NvcGVzPigpO1xuICAgIGNvbnN0IGdldFNjb3BlT2ZNb2R1bGUgPVxuICAgICAgICAobW9kdWxlVHlwZTogVHlwZTxhbnk+fFRlc3RpbmdNb2R1bGVPdmVycmlkZSk6IE5nTW9kdWxlVHJhbnNpdGl2ZVNjb3BlcyA9PiB7XG4gICAgICAgICAgaWYgKCFtb2R1bGVUb1Njb3BlLmhhcyhtb2R1bGVUeXBlKSkge1xuICAgICAgICAgICAgY29uc3QgaXNUZXN0aW5nTW9kdWxlID0gaXNUZXN0aW5nTW9kdWxlT3ZlcnJpZGUobW9kdWxlVHlwZSk7XG4gICAgICAgICAgICBjb25zdCByZWFsVHlwZSA9IGlzVGVzdGluZ01vZHVsZSA/IHRoaXMudGVzdE1vZHVsZVR5cGUgOiBtb2R1bGVUeXBlIGFzIFR5cGU8YW55PjtcbiAgICAgICAgICAgIG1vZHVsZVRvU2NvcGUuc2V0KG1vZHVsZVR5cGUsIHRyYW5zaXRpdmVTY29wZXNGb3IocmVhbFR5cGUpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG1vZHVsZVRvU2NvcGUuZ2V0KG1vZHVsZVR5cGUpITtcbiAgICAgICAgfTtcblxuICAgIHRoaXMuY29tcG9uZW50VG9Nb2R1bGVTY29wZS5mb3JFYWNoKChtb2R1bGVUeXBlLCBjb21wb25lbnRUeXBlKSA9PiB7XG4gICAgICBjb25zdCBtb2R1bGVTY29wZSA9IGdldFNjb3BlT2ZNb2R1bGUobW9kdWxlVHlwZSk7XG4gICAgICB0aGlzLnN0b3JlRmllbGRPZkRlZk9uVHlwZShjb21wb25lbnRUeXBlLCBOR19DT01QX0RFRiwgJ2RpcmVjdGl2ZURlZnMnKTtcbiAgICAgIHRoaXMuc3RvcmVGaWVsZE9mRGVmT25UeXBlKGNvbXBvbmVudFR5cGUsIE5HX0NPTVBfREVGLCAncGlwZURlZnMnKTtcbiAgICAgIC8vIGB0Vmlld2AgdGhhdCBpcyBzdG9yZWQgb24gY29tcG9uZW50IGRlZiBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBkaXJlY3RpdmVzIGFuZCBwaXBlc1xuICAgICAgLy8gdGhhdCBhcmUgaW4gdGhlIHNjb3BlIG9mIHRoaXMgY29tcG9uZW50LiBQYXRjaGluZyBjb21wb25lbnQgc2NvcGUgd2lsbCBjYXVzZSBgdFZpZXdgIHRvIGJlXG4gICAgICAvLyBjaGFuZ2VkLiBTdG9yZSBvcmlnaW5hbCBgdFZpZXdgIGJlZm9yZSBwYXRjaGluZyBzY29wZSwgc28gdGhlIGB0Vmlld2AgKGluY2x1ZGluZyBzY29wZVxuICAgICAgLy8gaW5mb3JtYXRpb24pIGlzIHJlc3RvcmVkIGJhY2sgdG8gaXRzIHByZXZpb3VzL29yaWdpbmFsIHN0YXRlIGJlZm9yZSBydW5uaW5nIG5leHQgdGVzdC5cbiAgICAgIHRoaXMuc3RvcmVGaWVsZE9mRGVmT25UeXBlKGNvbXBvbmVudFR5cGUsIE5HX0NPTVBfREVGLCAndFZpZXcnKTtcbiAgICAgIHBhdGNoQ29tcG9uZW50RGVmV2l0aFNjb3BlKChjb21wb25lbnRUeXBlIGFzIGFueSkuybVjbXAsIG1vZHVsZVNjb3BlKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY29tcG9uZW50VG9Nb2R1bGVTY29wZS5jbGVhcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseVByb3ZpZGVyT3ZlcnJpZGVzKCk6IHZvaWQge1xuICAgIGNvbnN0IG1heWJlQXBwbHlPdmVycmlkZXMgPSAoZmllbGQ6IHN0cmluZykgPT4gKHR5cGU6IFR5cGU8YW55PikgPT4ge1xuICAgICAgY29uc3QgcmVzb2x2ZXIgPSBmaWVsZCA9PT0gTkdfQ09NUF9ERUYgPyB0aGlzLnJlc29sdmVycy5jb21wb25lbnQgOiB0aGlzLnJlc29sdmVycy5kaXJlY3RpdmU7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IHJlc29sdmVyLnJlc29sdmUodHlwZSkhO1xuICAgICAgaWYgKHRoaXMuaGFzUHJvdmlkZXJPdmVycmlkZXMobWV0YWRhdGEucHJvdmlkZXJzKSkge1xuICAgICAgICB0aGlzLnBhdGNoRGVmV2l0aFByb3ZpZGVyT3ZlcnJpZGVzKHR5cGUsIGZpZWxkKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHRoaXMuc2VlbkNvbXBvbmVudHMuZm9yRWFjaChtYXliZUFwcGx5T3ZlcnJpZGVzKE5HX0NPTVBfREVGKSk7XG4gICAgdGhpcy5zZWVuRGlyZWN0aXZlcy5mb3JFYWNoKG1heWJlQXBwbHlPdmVycmlkZXMoTkdfRElSX0RFRikpO1xuXG4gICAgdGhpcy5zZWVuQ29tcG9uZW50cy5jbGVhcigpO1xuICAgIHRoaXMuc2VlbkRpcmVjdGl2ZXMuY2xlYXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgYXBwbHlQcm92aWRlck92ZXJyaWRlc1RvTW9kdWxlKG1vZHVsZVR5cGU6IFR5cGU8YW55Pik6IHZvaWQge1xuICAgIGlmICh0aGlzLm1vZHVsZVByb3ZpZGVyc092ZXJyaWRkZW4uaGFzKG1vZHVsZVR5cGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubW9kdWxlUHJvdmlkZXJzT3ZlcnJpZGRlbi5hZGQobW9kdWxlVHlwZSk7XG5cbiAgICBjb25zdCBpbmplY3RvckRlZjogYW55ID0gKG1vZHVsZVR5cGUgYXMgYW55KVtOR19JTkpfREVGXTtcbiAgICBpZiAodGhpcy5wcm92aWRlck92ZXJyaWRlc0J5VG9rZW4uc2l6ZSA+IDApIHtcbiAgICAgIGNvbnN0IHByb3ZpZGVycyA9IFtcbiAgICAgICAgLi4uaW5qZWN0b3JEZWYucHJvdmlkZXJzLFxuICAgICAgICAuLi4odGhpcy5wcm92aWRlck92ZXJyaWRlc0J5TW9kdWxlLmdldChtb2R1bGVUeXBlIGFzIEluamVjdG9yVHlwZTxhbnk+KSB8fCBbXSlcbiAgICAgIF07XG4gICAgICBpZiAodGhpcy5oYXNQcm92aWRlck92ZXJyaWRlcyhwcm92aWRlcnMpKSB7XG4gICAgICAgIHRoaXMubWF5YmVTdG9yZU5nRGVmKE5HX0lOSl9ERUYsIG1vZHVsZVR5cGUpO1xuXG4gICAgICAgIHRoaXMuc3RvcmVGaWVsZE9mRGVmT25UeXBlKG1vZHVsZVR5cGUsIE5HX0lOSl9ERUYsICdwcm92aWRlcnMnKTtcbiAgICAgICAgaW5qZWN0b3JEZWYucHJvdmlkZXJzID0gdGhpcy5nZXRPdmVycmlkZGVuUHJvdmlkZXJzKHByb3ZpZGVycyk7XG4gICAgICB9XG5cbiAgICAgIC8vIEFwcGx5IHByb3ZpZGVyIG92ZXJyaWRlcyB0byBpbXBvcnRlZCBtb2R1bGVzIHJlY3Vyc2l2ZWx5XG4gICAgICBjb25zdCBtb2R1bGVEZWYgPSAobW9kdWxlVHlwZSBhcyBhbnkpW05HX01PRF9ERUZdO1xuICAgICAgY29uc3QgaW1wb3J0cyA9IG1heWJlVW53cmFwRm4obW9kdWxlRGVmLmltcG9ydHMpO1xuICAgICAgZm9yIChjb25zdCBpbXBvcnRlZE1vZHVsZSBvZiBpbXBvcnRzKSB7XG4gICAgICAgIHRoaXMuYXBwbHlQcm92aWRlck92ZXJyaWRlc1RvTW9kdWxlKGltcG9ydGVkTW9kdWxlKTtcbiAgICAgIH1cbiAgICAgIC8vIEFsc28gb3ZlcnJpZGUgdGhlIHByb3ZpZGVycyBvbiBhbnkgTW9kdWxlV2l0aFByb3ZpZGVycyBpbXBvcnRzIHNpbmNlIHRob3NlIGRvbid0IGFwcGVhciBpblxuICAgICAgLy8gdGhlIG1vZHVsZURlZi5cbiAgICAgIGZvciAoY29uc3QgaW1wb3J0ZWRNb2R1bGUgb2YgZmxhdHRlbihpbmplY3RvckRlZi5pbXBvcnRzKSkge1xuICAgICAgICBpZiAoaXNNb2R1bGVXaXRoUHJvdmlkZXJzKGltcG9ydGVkTW9kdWxlKSkge1xuICAgICAgICAgIHRoaXMuZGVmQ2xlYW51cE9wcy5wdXNoKHtcbiAgICAgICAgICAgIG9iamVjdDogaW1wb3J0ZWRNb2R1bGUsXG4gICAgICAgICAgICBmaWVsZE5hbWU6ICdwcm92aWRlcnMnLFxuICAgICAgICAgICAgb3JpZ2luYWxWYWx1ZTogaW1wb3J0ZWRNb2R1bGUucHJvdmlkZXJzXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaW1wb3J0ZWRNb2R1bGUucHJvdmlkZXJzID0gdGhpcy5nZXRPdmVycmlkZGVuUHJvdmlkZXJzKGltcG9ydGVkTW9kdWxlLnByb3ZpZGVycyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHBhdGNoQ29tcG9uZW50c1dpdGhFeGlzdGluZ1N0eWxlcygpOiB2b2lkIHtcbiAgICB0aGlzLmV4aXN0aW5nQ29tcG9uZW50U3R5bGVzLmZvckVhY2goXG4gICAgICAgIChzdHlsZXMsIHR5cGUpID0+ICh0eXBlIGFzIGFueSlbTkdfQ09NUF9ERUZdLnN0eWxlcyA9IHN0eWxlcyk7XG4gICAgdGhpcy5leGlzdGluZ0NvbXBvbmVudFN0eWxlcy5jbGVhcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBxdWV1ZVR5cGVBcnJheShhcnI6IGFueVtdLCBtb2R1bGVUeXBlOiBUeXBlPGFueT58VGVzdGluZ01vZHVsZU92ZXJyaWRlKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCB2YWx1ZSBvZiBhcnIpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICB0aGlzLnF1ZXVlVHlwZUFycmF5KHZhbHVlLCBtb2R1bGVUeXBlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucXVldWVUeXBlKHZhbHVlLCBtb2R1bGVUeXBlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlY29tcGlsZU5nTW9kdWxlKG5nTW9kdWxlOiBUeXBlPGFueT4sIG1ldGFkYXRhOiBOZ01vZHVsZSk6IHZvaWQge1xuICAgIC8vIENhY2hlIHRoZSBpbml0aWFsIG5nTW9kdWxlRGVmIGFzIGl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4uXG4gICAgdGhpcy5tYXliZVN0b3JlTmdEZWYoTkdfTU9EX0RFRiwgbmdNb2R1bGUpO1xuICAgIHRoaXMubWF5YmVTdG9yZU5nRGVmKE5HX0lOSl9ERUYsIG5nTW9kdWxlKTtcblxuICAgIGNvbXBpbGVOZ01vZHVsZURlZnMobmdNb2R1bGUgYXMgTmdNb2R1bGVUeXBlPGFueT4sIG1ldGFkYXRhKTtcbiAgfVxuXG4gIHByaXZhdGUgcXVldWVUeXBlKHR5cGU6IFR5cGU8YW55PiwgbW9kdWxlVHlwZTogVHlwZTxhbnk+fFRlc3RpbmdNb2R1bGVPdmVycmlkZSk6IHZvaWQge1xuICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMucmVzb2x2ZXJzLmNvbXBvbmVudC5yZXNvbHZlKHR5cGUpO1xuICAgIGlmIChjb21wb25lbnQpIHtcbiAgICAgIC8vIENoZWNrIHdoZXRoZXIgYSBnaXZlIFR5cGUgaGFzIHJlc3BlY3RpdmUgTkcgZGVmICjJtWNtcCkgYW5kIGNvbXBpbGUgaWYgZGVmIGlzXG4gICAgICAvLyBtaXNzaW5nLiBUaGF0IG1pZ2h0IGhhcHBlbiBpbiBjYXNlIGEgY2xhc3Mgd2l0aG91dCBhbnkgQW5ndWxhciBkZWNvcmF0b3JzIGV4dGVuZHMgYW5vdGhlclxuICAgICAgLy8gY2xhc3Mgd2hlcmUgQ29tcG9uZW50L0RpcmVjdGl2ZS9QaXBlIGRlY29yYXRvciBpcyBkZWZpbmVkLlxuICAgICAgaWYgKGlzQ29tcG9uZW50RGVmUGVuZGluZ1Jlc29sdXRpb24odHlwZSkgfHwgIXR5cGUuaGFzT3duUHJvcGVydHkoTkdfQ09NUF9ERUYpKSB7XG4gICAgICAgIHRoaXMucGVuZGluZ0NvbXBvbmVudHMuYWRkKHR5cGUpO1xuICAgICAgfVxuICAgICAgdGhpcy5zZWVuQ29tcG9uZW50cy5hZGQodHlwZSk7XG5cbiAgICAgIC8vIEtlZXAgdHJhY2sgb2YgdGhlIG1vZHVsZSB3aGljaCBkZWNsYXJlcyB0aGlzIGNvbXBvbmVudCwgc28gbGF0ZXIgdGhlIGNvbXBvbmVudCdzIHNjb3BlXG4gICAgICAvLyBjYW4gYmUgc2V0IGNvcnJlY3RseS4gSWYgdGhlIGNvbXBvbmVudCBoYXMgYWxyZWFkeSBiZWVuIHJlY29yZGVkIGhlcmUsIHRoZW4gb25lIG9mIHNldmVyYWxcbiAgICAgIC8vIGNhc2VzIGlzIHRydWU6XG4gICAgICAvLyAqIHRoZSBtb2R1bGUgY29udGFpbmluZyB0aGUgY29tcG9uZW50IHdhcyBpbXBvcnRlZCBtdWx0aXBsZSB0aW1lcyAoY29tbW9uKS5cbiAgICAgIC8vICogdGhlIGNvbXBvbmVudCBpcyBkZWNsYXJlZCBpbiBtdWx0aXBsZSBtb2R1bGVzICh3aGljaCBpcyBhbiBlcnJvcikuXG4gICAgICAvLyAqIHRoZSBjb21wb25lbnQgd2FzIGluICdkZWNsYXJhdGlvbnMnIG9mIHRoZSB0ZXN0aW5nIG1vZHVsZSwgYW5kIGFsc28gaW4gYW4gaW1wb3J0ZWQgbW9kdWxlXG4gICAgICAvLyAgIGluIHdoaWNoIGNhc2UgdGhlIG1vZHVsZSBzY29wZSB3aWxsIGJlIFRlc3RpbmdNb2R1bGVPdmVycmlkZS5ERUNMQVJBVElPTi5cbiAgICAgIC8vICogb3ZlcnJpZGVUZW1wbGF0ZVVzaW5nVGVzdGluZ01vZHVsZSB3YXMgY2FsbGVkIGZvciB0aGUgY29tcG9uZW50IGluIHdoaWNoIGNhc2UgdGhlIG1vZHVsZVxuICAgICAgLy8gICBzY29wZSB3aWxsIGJlIFRlc3RpbmdNb2R1bGVPdmVycmlkZS5PVkVSUklERV9URU1QTEFURS5cbiAgICAgIC8vXG4gICAgICAvLyBJZiB0aGUgY29tcG9uZW50IHdhcyBwcmV2aW91c2x5IGluIHRoZSB0ZXN0aW5nIG1vZHVsZSdzICdkZWNsYXJhdGlvbnMnIChtZWFuaW5nIHRoZVxuICAgICAgLy8gY3VycmVudCB2YWx1ZSBpcyBUZXN0aW5nTW9kdWxlT3ZlcnJpZGUuREVDTEFSQVRJT04pLCB0aGVuIGBtb2R1bGVUeXBlYCBpcyB0aGUgY29tcG9uZW50J3NcbiAgICAgIC8vIHJlYWwgbW9kdWxlLCB3aGljaCB3YXMgaW1wb3J0ZWQuIFRoaXMgcGF0dGVybiBpcyB1bmRlcnN0b29kIHRvIG1lYW4gdGhhdCB0aGUgY29tcG9uZW50XG4gICAgICAvLyBzaG91bGQgdXNlIGl0cyBvcmlnaW5hbCBzY29wZSwgYnV0IHRoYXQgdGhlIHRlc3RpbmcgbW9kdWxlIHNob3VsZCBhbHNvIGNvbnRhaW4gdGhlXG4gICAgICAvLyBjb21wb25lbnQgaW4gaXRzIHNjb3BlLlxuICAgICAgaWYgKCF0aGlzLmNvbXBvbmVudFRvTW9kdWxlU2NvcGUuaGFzKHR5cGUpIHx8XG4gICAgICAgICAgdGhpcy5jb21wb25lbnRUb01vZHVsZVNjb3BlLmdldCh0eXBlKSA9PT0gVGVzdGluZ01vZHVsZU92ZXJyaWRlLkRFQ0xBUkFUSU9OKSB7XG4gICAgICAgIHRoaXMuY29tcG9uZW50VG9Nb2R1bGVTY29wZS5zZXQodHlwZSwgbW9kdWxlVHlwZSk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZGlyZWN0aXZlID0gdGhpcy5yZXNvbHZlcnMuZGlyZWN0aXZlLnJlc29sdmUodHlwZSk7XG4gICAgaWYgKGRpcmVjdGl2ZSkge1xuICAgICAgaWYgKCF0eXBlLmhhc093blByb3BlcnR5KE5HX0RJUl9ERUYpKSB7XG4gICAgICAgIHRoaXMucGVuZGluZ0RpcmVjdGl2ZXMuYWRkKHR5cGUpO1xuICAgICAgfVxuICAgICAgdGhpcy5zZWVuRGlyZWN0aXZlcy5hZGQodHlwZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcGlwZSA9IHRoaXMucmVzb2x2ZXJzLnBpcGUucmVzb2x2ZSh0eXBlKTtcbiAgICBpZiAocGlwZSAmJiAhdHlwZS5oYXNPd25Qcm9wZXJ0eShOR19QSVBFX0RFRikpIHtcbiAgICAgIHRoaXMucGVuZGluZ1BpcGVzLmFkZCh0eXBlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHF1ZXVlVHlwZXNGcm9tTW9kdWxlc0FycmF5KGFycjogYW55W10pOiB2b2lkIHtcbiAgICAvLyBCZWNhdXNlIHdlIG1heSBlbmNvdW50ZXIgdGhlIHNhbWUgTmdNb2R1bGUgd2hpbGUgcHJvY2Vzc2luZyB0aGUgaW1wb3J0cyBhbmQgZXhwb3J0cyBvZiBhblxuICAgIC8vIE5nTW9kdWxlIHRyZWUsIHdlIGNhY2hlIHRoZW0gaW4gdGhpcyBzZXQgc28gd2UgY2FuIHNraXAgb25lcyB0aGF0IGhhdmUgYWxyZWFkeSBiZWVuIHNlZW5cbiAgICAvLyBlbmNvdW50ZXJlZC4gSW4gc29tZSB0ZXN0IHNldHVwcywgdGhpcyBjYWNoaW5nIHJlc3VsdGVkIGluIDEwWCBydW50aW1lIGltcHJvdmVtZW50LlxuICAgIGNvbnN0IHByb2Nlc3NlZE5nTW9kdWxlRGVmcyA9IG5ldyBTZXQoKTtcbiAgICBjb25zdCBxdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheVJlY3VyID0gKGFycjogYW55W10pOiB2b2lkID0+IHtcbiAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgYXJyKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHF1ZXVlVHlwZXNGcm9tTW9kdWxlc0FycmF5UmVjdXIodmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKGhhc05nTW9kdWxlRGVmKHZhbHVlKSkge1xuICAgICAgICAgIGNvbnN0IGRlZiA9IHZhbHVlLsm1bW9kO1xuICAgICAgICAgIGlmIChwcm9jZXNzZWROZ01vZHVsZURlZnMuaGFzKGRlZikpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwcm9jZXNzZWROZ01vZHVsZURlZnMuYWRkKGRlZik7XG4gICAgICAgICAgLy8gTG9vayB0aHJvdWdoIGRlY2xhcmF0aW9ucywgaW1wb3J0cywgYW5kIGV4cG9ydHMsIGFuZCBxdWV1ZVxuICAgICAgICAgIC8vIGV2ZXJ5dGhpbmcgZm91bmQgdGhlcmUuXG4gICAgICAgICAgdGhpcy5xdWV1ZVR5cGVBcnJheShtYXliZVVud3JhcEZuKGRlZi5kZWNsYXJhdGlvbnMpLCB2YWx1ZSk7XG4gICAgICAgICAgcXVldWVUeXBlc0Zyb21Nb2R1bGVzQXJyYXlSZWN1cihtYXliZVVud3JhcEZuKGRlZi5pbXBvcnRzKSk7XG4gICAgICAgICAgcXVldWVUeXBlc0Zyb21Nb2R1bGVzQXJyYXlSZWN1cihtYXliZVVud3JhcEZuKGRlZi5leHBvcnRzKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNNb2R1bGVXaXRoUHJvdmlkZXJzKHZhbHVlKSkge1xuICAgICAgICAgIHF1ZXVlVHlwZXNGcm9tTW9kdWxlc0FycmF5UmVjdXIoW3ZhbHVlLm5nTW9kdWxlXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICAgIHF1ZXVlVHlwZXNGcm9tTW9kdWxlc0FycmF5UmVjdXIoYXJyKTtcbiAgfVxuXG4gIC8vIFdoZW4gbW9kdWxlIG92ZXJyaWRlcyAodmlhIGBUZXN0QmVkLm92ZXJyaWRlTW9kdWxlYCkgYXJlIHByZXNlbnQsIGl0IG1pZ2h0IGFmZmVjdCBhbGwgbW9kdWxlc1xuICAvLyB0aGF0IGltcG9ydCAoZXZlbiB0cmFuc2l0aXZlbHkpIGFuIG92ZXJyaWRkZW4gb25lLiBGb3IgYWxsIGFmZmVjdGVkIG1vZHVsZXMgd2UgbmVlZCB0b1xuICAvLyByZWNhbGN1bGF0ZSB0aGVpciBzY29wZXMgZm9yIGEgZ2l2ZW4gdGVzdCBydW4gYW5kIHJlc3RvcmUgb3JpZ2luYWwgc2NvcGVzIGF0IHRoZSBlbmQuIFRoZSBnb2FsXG4gIC8vIG9mIHRoaXMgZnVuY3Rpb24gaXMgdG8gY29sbGVjdCBhbGwgYWZmZWN0ZWQgbW9kdWxlcyBpbiBhIHNldCBmb3IgZnVydGhlciBwcm9jZXNzaW5nLiBFeGFtcGxlOlxuICAvLyBpZiB3ZSBoYXZlIHRoZSBmb2xsb3dpbmcgbW9kdWxlIGhpZXJhcmNoeTogQSAtPiBCIC0+IEMgKHdoZXJlIGAtPmAgbWVhbnMgYGltcG9ydHNgKSBhbmQgbW9kdWxlXG4gIC8vIGBDYCBpcyBvdmVycmlkZGVuLCB3ZSBjb25zaWRlciBgQWAgYW5kIGBCYCBhcyBhZmZlY3RlZCwgc2luY2UgdGhlaXIgc2NvcGVzIG1pZ2h0IGJlY29tZVxuICAvLyBpbnZhbGlkYXRlZCB3aXRoIHRoZSBvdmVycmlkZS5cbiAgcHJpdmF0ZSBjb2xsZWN0TW9kdWxlc0FmZmVjdGVkQnlPdmVycmlkZXMoYXJyOiBhbnlbXSk6IFNldDxOZ01vZHVsZVR5cGU8YW55Pj4ge1xuICAgIGNvbnN0IHNlZW5Nb2R1bGVzID0gbmV3IFNldDxOZ01vZHVsZVR5cGU8YW55Pj4oKTtcbiAgICBjb25zdCBhZmZlY3RlZE1vZHVsZXMgPSBuZXcgU2V0PE5nTW9kdWxlVHlwZTxhbnk+PigpO1xuICAgIGNvbnN0IGNhbGNBZmZlY3RlZE1vZHVsZXNSZWN1ciA9IChhcnI6IGFueVtdLCBwYXRoOiBOZ01vZHVsZVR5cGU8YW55PltdKTogdm9pZCA9PiB7XG4gICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIGFycikge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAvLyBJZiB0aGUgdmFsdWUgaXMgYW4gYXJyYXksIGp1c3QgZmxhdHRlbiBpdCAoYnkgaW52b2tpbmcgdGhpcyBmdW5jdGlvbiByZWN1cnNpdmVseSksXG4gICAgICAgICAgLy8ga2VlcGluZyBcInBhdGhcIiB0aGUgc2FtZS5cbiAgICAgICAgICBjYWxjQWZmZWN0ZWRNb2R1bGVzUmVjdXIodmFsdWUsIHBhdGgpO1xuICAgICAgICB9IGVsc2UgaWYgKGhhc05nTW9kdWxlRGVmKHZhbHVlKSkge1xuICAgICAgICAgIGlmIChzZWVuTW9kdWxlcy5oYXModmFsdWUpKSB7XG4gICAgICAgICAgICAvLyBJZiB3ZSd2ZSBzZWVuIHRoaXMgbW9kdWxlIGJlZm9yZSBhbmQgaXQncyBpbmNsdWRlZCBpbnRvIFwiYWZmZWN0ZWQgbW9kdWxlc1wiIGxpc3QsIG1hcmtcbiAgICAgICAgICAgIC8vIHRoZSB3aG9sZSBwYXRoIHRoYXQgbGVhZHMgdG8gdGhhdCBtb2R1bGUgYXMgYWZmZWN0ZWQsIGJ1dCBkbyBub3QgZGVzY2VuZCBpbnRvIGl0c1xuICAgICAgICAgICAgLy8gaW1wb3J0cywgc2luY2Ugd2UgYWxyZWFkeSBleGFtaW5lZCB0aGVtIGJlZm9yZS5cbiAgICAgICAgICAgIGlmIChhZmZlY3RlZE1vZHVsZXMuaGFzKHZhbHVlKSkge1xuICAgICAgICAgICAgICBwYXRoLmZvckVhY2goaXRlbSA9PiBhZmZlY3RlZE1vZHVsZXMuYWRkKGl0ZW0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzZWVuTW9kdWxlcy5hZGQodmFsdWUpO1xuICAgICAgICAgIGlmICh0aGlzLm92ZXJyaWRkZW5Nb2R1bGVzLmhhcyh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHBhdGguZm9yRWFjaChpdGVtID0+IGFmZmVjdGVkTW9kdWxlcy5hZGQoaXRlbSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBFeGFtaW5lIG1vZHVsZSBpbXBvcnRzIHJlY3Vyc2l2ZWx5IHRvIGxvb2sgZm9yIG92ZXJyaWRkZW4gbW9kdWxlcy5cbiAgICAgICAgICBjb25zdCBtb2R1bGVEZWYgPSAodmFsdWUgYXMgYW55KVtOR19NT0RfREVGXTtcbiAgICAgICAgICBjYWxjQWZmZWN0ZWRNb2R1bGVzUmVjdXIobWF5YmVVbndyYXBGbihtb2R1bGVEZWYuaW1wb3J0cyksIHBhdGguY29uY2F0KHZhbHVlKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICAgIGNhbGNBZmZlY3RlZE1vZHVsZXNSZWN1cihhcnIsIFtdKTtcbiAgICByZXR1cm4gYWZmZWN0ZWRNb2R1bGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBtYXliZVN0b3JlTmdEZWYocHJvcDogc3RyaW5nLCB0eXBlOiBUeXBlPGFueT4pIHtcbiAgICBpZiAoIXRoaXMuaW5pdGlhbE5nRGVmcy5oYXModHlwZSkpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnREZWYgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHR5cGUsIHByb3ApO1xuICAgICAgdGhpcy5pbml0aWFsTmdEZWZzLnNldCh0eXBlLCBbcHJvcCwgY3VycmVudERlZl0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RvcmVGaWVsZE9mRGVmT25UeXBlKHR5cGU6IFR5cGU8YW55PiwgZGVmRmllbGQ6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBkZWY6IGFueSA9ICh0eXBlIGFzIGFueSlbZGVmRmllbGRdO1xuICAgIGNvbnN0IG9yaWdpbmFsVmFsdWU6IGFueSA9IGRlZltmaWVsZE5hbWVdO1xuICAgIHRoaXMuZGVmQ2xlYW51cE9wcy5wdXNoKHtvYmplY3Q6IGRlZiwgZmllbGROYW1lLCBvcmlnaW5hbFZhbHVlfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXJzIGN1cnJlbnQgY29tcG9uZW50cyByZXNvbHV0aW9uIHF1ZXVlLCBidXQgc3RvcmVzIHRoZSBzdGF0ZSBvZiB0aGUgcXVldWUsIHNvIHdlIGNhblxuICAgKiByZXN0b3JlIGl0IGxhdGVyLiBDbGVhcmluZyB0aGUgcXVldWUgaXMgcmVxdWlyZWQgYmVmb3JlIHdlIHRyeSB0byBjb21waWxlIGNvbXBvbmVudHMgKHZpYVxuICAgKiBgVGVzdEJlZC5jb21waWxlQ29tcG9uZW50c2ApLCBzbyB0aGF0IGNvbXBvbmVudCBkZWZzIGFyZSBpbiBzeW5jIHdpdGggdGhlIHJlc29sdXRpb24gcXVldWUuXG4gICAqL1xuICBwcml2YXRlIGNsZWFyQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlKCkge1xuICAgIGlmICh0aGlzLm9yaWdpbmFsQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlID09PSBudWxsKSB7XG4gICAgICB0aGlzLm9yaWdpbmFsQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICBjbGVhclJlc29sdXRpb25PZkNvbXBvbmVudFJlc291cmNlc1F1ZXVlKCkuZm9yRWFjaChcbiAgICAgICAgKHZhbHVlLCBrZXkpID0+IHRoaXMub3JpZ2luYWxDb21wb25lbnRSZXNvbHV0aW9uUXVldWUhLnNldChrZXksIHZhbHVlKSk7XG4gIH1cblxuICAvKlxuICAgKiBSZXN0b3JlcyBjb21wb25lbnQgcmVzb2x1dGlvbiBxdWV1ZSB0byB0aGUgcHJldmlvdXNseSBzYXZlZCBzdGF0ZS4gVGhpcyBvcGVyYXRpb24gaXMgcGVyZm9ybWVkXG4gICAqIGFzIGEgcGFydCBvZiByZXN0b3JpbmcgdGhlIHN0YXRlIGFmdGVyIGNvbXBsZXRpb24gb2YgdGhlIGN1cnJlbnQgc2V0IG9mIHRlc3RzICh0aGF0IG1pZ2h0XG4gICAqIHBvdGVudGlhbGx5IG11dGF0ZSB0aGUgc3RhdGUpLlxuICAgKi9cbiAgcHJpdmF0ZSByZXN0b3JlQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlKCkge1xuICAgIGlmICh0aGlzLm9yaWdpbmFsQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlICE9PSBudWxsKSB7XG4gICAgICByZXN0b3JlQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlKHRoaXMub3JpZ2luYWxDb21wb25lbnRSZXNvbHV0aW9uUXVldWUpO1xuICAgICAgdGhpcy5vcmlnaW5hbENvbXBvbmVudFJlc29sdXRpb25RdWV1ZSA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcmVzdG9yZU9yaWdpbmFsU3RhdGUoKTogdm9pZCB7XG4gICAgLy8gUHJvY2VzcyBjbGVhbnVwIG9wcyBpbiByZXZlcnNlIG9yZGVyIHNvIHRoZSBmaWVsZCdzIG9yaWdpbmFsIHZhbHVlIGlzIHJlc3RvcmVkIGNvcnJlY3RseSAoaW5cbiAgICAvLyBjYXNlIHRoZXJlIHdlcmUgbXVsdGlwbGUgb3ZlcnJpZGVzIGZvciB0aGUgc2FtZSBmaWVsZCkuXG4gICAgZm9yRWFjaFJpZ2h0KHRoaXMuZGVmQ2xlYW51cE9wcywgKG9wOiBDbGVhbnVwT3BlcmF0aW9uKSA9PiB7XG4gICAgICBvcC5vYmplY3Rbb3AuZmllbGROYW1lXSA9IG9wLm9yaWdpbmFsVmFsdWU7XG4gICAgfSk7XG4gICAgLy8gUmVzdG9yZSBpbml0aWFsIGNvbXBvbmVudC9kaXJlY3RpdmUvcGlwZSBkZWZzXG4gICAgdGhpcy5pbml0aWFsTmdEZWZzLmZvckVhY2goKHZhbHVlOiBbc3RyaW5nLCBQcm9wZXJ0eURlc2NyaXB0b3J8dW5kZWZpbmVkXSwgdHlwZTogVHlwZTxhbnk+KSA9PiB7XG4gICAgICBjb25zdCBbcHJvcCwgZGVzY3JpcHRvcl0gPSB2YWx1ZTtcbiAgICAgIGlmICghZGVzY3JpcHRvcikge1xuICAgICAgICAvLyBEZWxldGUgb3BlcmF0aW9ucyBhcmUgZ2VuZXJhbGx5IHVuZGVzaXJhYmxlIHNpbmNlIHRoZXkgaGF2ZSBwZXJmb3JtYW5jZSBpbXBsaWNhdGlvbnNcbiAgICAgICAgLy8gb24gb2JqZWN0cyB0aGV5IHdlcmUgYXBwbGllZCB0by4gSW4gdGhpcyBwYXJ0aWN1bGFyIGNhc2UsIHNpdHVhdGlvbnMgd2hlcmUgdGhpcyBjb2RlXG4gICAgICAgIC8vIGlzIGludm9rZWQgc2hvdWxkIGJlIHF1aXRlIHJhcmUgdG8gY2F1c2UgYW55IG5vdGljZWFibGUgaW1wYWN0LCBzaW5jZSBpdCdzIGFwcGxpZWRcbiAgICAgICAgLy8gb25seSB0byBzb21lIHRlc3QgY2FzZXMgKGZvciBleGFtcGxlIHdoZW4gY2xhc3Mgd2l0aCBubyBhbm5vdGF0aW9ucyBleHRlbmRzIHNvbWVcbiAgICAgICAgLy8gQENvbXBvbmVudCkgd2hlbiB3ZSBuZWVkIHRvIGNsZWFyICfJtWNtcCcgZmllbGQgb24gYSBnaXZlbiBjbGFzcyB0byByZXN0b3JlXG4gICAgICAgIC8vIGl0cyBvcmlnaW5hbCBzdGF0ZSAoYmVmb3JlIGFwcGx5aW5nIG92ZXJyaWRlcyBhbmQgcnVubmluZyB0ZXN0cykuXG4gICAgICAgIGRlbGV0ZSAodHlwZSBhcyBhbnkpW3Byb3BdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHR5cGUsIHByb3AsIGRlc2NyaXB0b3IpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMuaW5pdGlhbE5nRGVmcy5jbGVhcigpO1xuICAgIHRoaXMubW9kdWxlUHJvdmlkZXJzT3ZlcnJpZGRlbi5jbGVhcigpO1xuICAgIHRoaXMucmVzdG9yZUNvbXBvbmVudFJlc29sdXRpb25RdWV1ZSgpO1xuICAgIC8vIFJlc3RvcmUgdGhlIGxvY2FsZSBJRCB0byB0aGUgZGVmYXVsdCB2YWx1ZSwgdGhpcyBzaG91bGRuJ3QgYmUgbmVjZXNzYXJ5IGJ1dCB3ZSBuZXZlciBrbm93XG4gICAgc2V0TG9jYWxlSWQoREVGQVVMVF9MT0NBTEVfSUQpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb21waWxlVGVzdE1vZHVsZSgpOiB2b2lkIHtcbiAgICBjbGFzcyBSb290U2NvcGVNb2R1bGUge31cbiAgICBjb21waWxlTmdNb2R1bGVEZWZzKFJvb3RTY29wZU1vZHVsZSBhcyBOZ01vZHVsZVR5cGU8YW55Piwge1xuICAgICAgcHJvdmlkZXJzOiBbLi4udGhpcy5yb290UHJvdmlkZXJPdmVycmlkZXNdLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgbmdab25lID0gbmV3IE5nWm9uZSh7ZW5hYmxlTG9uZ1N0YWNrVHJhY2U6IHRydWV9KTtcbiAgICBjb25zdCBwcm92aWRlcnM6IFByb3ZpZGVyW10gPSBbXG4gICAgICB7cHJvdmlkZTogTmdab25lLCB1c2VWYWx1ZTogbmdab25lfSxcbiAgICAgIHtwcm92aWRlOiBDb21waWxlciwgdXNlRmFjdG9yeTogKCkgPT4gbmV3IFIzVGVzdENvbXBpbGVyKHRoaXMpfSxcbiAgICAgIC4uLnRoaXMucHJvdmlkZXJzLFxuICAgICAgLi4udGhpcy5wcm92aWRlck92ZXJyaWRlcyxcbiAgICBdO1xuICAgIGNvbnN0IGltcG9ydHMgPSBbUm9vdFNjb3BlTW9kdWxlLCB0aGlzLmFkZGl0aW9uYWxNb2R1bGVUeXBlcywgdGhpcy5pbXBvcnRzIHx8IFtdXTtcblxuICAgIC8vIGNsYW5nLWZvcm1hdCBvZmZcbiAgICBjb21waWxlTmdNb2R1bGVEZWZzKHRoaXMudGVzdE1vZHVsZVR5cGUsIHtcbiAgICAgIGRlY2xhcmF0aW9uczogdGhpcy5kZWNsYXJhdGlvbnMsXG4gICAgICBpbXBvcnRzLFxuICAgICAgc2NoZW1hczogdGhpcy5zY2hlbWFzLFxuICAgICAgcHJvdmlkZXJzLFxuICAgIH0sIC8qIGFsbG93RHVwbGljYXRlRGVjbGFyYXRpb25zSW5Sb290ICovIHRydWUpO1xuICAgIC8vIGNsYW5nLWZvcm1hdCBvblxuXG4gICAgdGhpcy5hcHBseVByb3ZpZGVyT3ZlcnJpZGVzVG9Nb2R1bGUodGhpcy50ZXN0TW9kdWxlVHlwZSk7XG4gIH1cblxuICBnZXQgaW5qZWN0b3IoKTogSW5qZWN0b3Ige1xuICAgIGlmICh0aGlzLl9pbmplY3RvciAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2luamVjdG9yO1xuICAgIH1cblxuICAgIGNvbnN0IHByb3ZpZGVyczogUHJvdmlkZXJbXSA9IFtdO1xuICAgIGNvbnN0IGNvbXBpbGVyT3B0aW9ucyA9IHRoaXMucGxhdGZvcm0uaW5qZWN0b3IuZ2V0KENPTVBJTEVSX09QVElPTlMpO1xuICAgIGNvbXBpbGVyT3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgaWYgKG9wdHMucHJvdmlkZXJzKSB7XG4gICAgICAgIHByb3ZpZGVycy5wdXNoKG9wdHMucHJvdmlkZXJzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAodGhpcy5jb21waWxlclByb3ZpZGVycyAhPT0gbnVsbCkge1xuICAgICAgcHJvdmlkZXJzLnB1c2goLi4udGhpcy5jb21waWxlclByb3ZpZGVycyk7XG4gICAgfVxuXG4gICAgLy8gVE9ETyhvY29tYmUpOiBtYWtlIHRoaXMgd29yayB3aXRoIGFuIEluamVjdG9yIGRpcmVjdGx5IGluc3RlYWQgb2YgY3JlYXRpbmcgYSBtb2R1bGUgZm9yIGl0XG4gICAgY2xhc3MgQ29tcGlsZXJNb2R1bGUge31cbiAgICBjb21waWxlTmdNb2R1bGVEZWZzKENvbXBpbGVyTW9kdWxlIGFzIE5nTW9kdWxlVHlwZTxhbnk+LCB7cHJvdmlkZXJzfSk7XG5cbiAgICBjb25zdCBDb21waWxlck1vZHVsZUZhY3RvcnkgPSBuZXcgUjNOZ01vZHVsZUZhY3RvcnkoQ29tcGlsZXJNb2R1bGUpO1xuICAgIHRoaXMuX2luamVjdG9yID0gQ29tcGlsZXJNb2R1bGVGYWN0b3J5LmNyZWF0ZSh0aGlzLnBsYXRmb3JtLmluamVjdG9yKS5pbmplY3RvcjtcbiAgICByZXR1cm4gdGhpcy5faW5qZWN0b3I7XG4gIH1cblxuICAvLyBnZXQgb3ZlcnJpZGVzIGZvciBhIHNwZWNpZmljIHByb3ZpZGVyIChpZiBhbnkpXG4gIHByaXZhdGUgZ2V0U2luZ2xlUHJvdmlkZXJPdmVycmlkZXMocHJvdmlkZXI6IFByb3ZpZGVyKTogUHJvdmlkZXJ8bnVsbCB7XG4gICAgY29uc3QgdG9rZW4gPSBnZXRQcm92aWRlclRva2VuKHByb3ZpZGVyKTtcbiAgICByZXR1cm4gdGhpcy5wcm92aWRlck92ZXJyaWRlc0J5VG9rZW4uZ2V0KHRva2VuKSB8fCBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQcm92aWRlck92ZXJyaWRlcyhwcm92aWRlcnM/OiBQcm92aWRlcltdKTogUHJvdmlkZXJbXSB7XG4gICAgaWYgKCFwcm92aWRlcnMgfHwgIXByb3ZpZGVycy5sZW5ndGggfHwgdGhpcy5wcm92aWRlck92ZXJyaWRlc0J5VG9rZW4uc2l6ZSA9PT0gMCkgcmV0dXJuIFtdO1xuICAgIC8vIFRoZXJlIGFyZSB0d28gZmxhdHRlbmluZyBvcGVyYXRpb25zIGhlcmUuIFRoZSBpbm5lciBmbGF0dGVuKCkgb3BlcmF0ZXMgb24gdGhlIG1ldGFkYXRhJ3NcbiAgICAvLyBwcm92aWRlcnMgYW5kIGFwcGxpZXMgYSBtYXBwaW5nIGZ1bmN0aW9uIHdoaWNoIHJldHJpZXZlcyBvdmVycmlkZXMgZm9yIGVhY2ggaW5jb21pbmdcbiAgICAvLyBwcm92aWRlci4gVGhlIG91dGVyIGZsYXR0ZW4oKSB0aGVuIGZsYXR0ZW5zIHRoZSBwcm9kdWNlZCBvdmVycmlkZXMgYXJyYXkuIElmIHRoaXMgaXMgbm90XG4gICAgLy8gZG9uZSwgdGhlIGFycmF5IGNhbiBjb250YWluIG90aGVyIGVtcHR5IGFycmF5cyAoZS5nLiBgW1tdLCBbXV1gKSB3aGljaCBsZWFrIGludG8gdGhlXG4gICAgLy8gcHJvdmlkZXJzIGFycmF5IGFuZCBjb250YW1pbmF0ZSBhbnkgZXJyb3IgbWVzc2FnZXMgdGhhdCBtaWdodCBiZSBnZW5lcmF0ZWQuXG4gICAgcmV0dXJuIGZsYXR0ZW4oZmxhdHRlbihcbiAgICAgICAgcHJvdmlkZXJzLCAocHJvdmlkZXI6IFByb3ZpZGVyKSA9PiB0aGlzLmdldFNpbmdsZVByb3ZpZGVyT3ZlcnJpZGVzKHByb3ZpZGVyKSB8fCBbXSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRPdmVycmlkZGVuUHJvdmlkZXJzKHByb3ZpZGVycz86IFByb3ZpZGVyW10pOiBQcm92aWRlcltdIHtcbiAgICBpZiAoIXByb3ZpZGVycyB8fCAhcHJvdmlkZXJzLmxlbmd0aCB8fCB0aGlzLnByb3ZpZGVyT3ZlcnJpZGVzQnlUb2tlbi5zaXplID09PSAwKSByZXR1cm4gW107XG5cbiAgICBjb25zdCBmbGF0dGVuZWRQcm92aWRlcnMgPSBmbGF0dGVuPFByb3ZpZGVyW10+KHByb3ZpZGVycyk7XG4gICAgY29uc3Qgb3ZlcnJpZGVzID0gdGhpcy5nZXRQcm92aWRlck92ZXJyaWRlcyhmbGF0dGVuZWRQcm92aWRlcnMpO1xuICAgIGNvbnN0IG92ZXJyaWRkZW5Qcm92aWRlcnMgPSBbLi4uZmxhdHRlbmVkUHJvdmlkZXJzLCAuLi5vdmVycmlkZXNdO1xuICAgIGNvbnN0IGZpbmFsOiBQcm92aWRlcltdID0gW107XG4gICAgY29uc3Qgc2Vlbk92ZXJyaWRkZW5Qcm92aWRlcnMgPSBuZXcgU2V0PFByb3ZpZGVyPigpO1xuXG4gICAgLy8gV2UgaXRlcmF0ZSB0aHJvdWdoIHRoZSBsaXN0IG9mIHByb3ZpZGVycyBpbiByZXZlcnNlIG9yZGVyIHRvIG1ha2Ugc3VyZSBwcm92aWRlciBvdmVycmlkZXNcbiAgICAvLyB0YWtlIHByZWNlZGVuY2Ugb3ZlciB0aGUgdmFsdWVzIGRlZmluZWQgaW4gcHJvdmlkZXIgbGlzdC4gV2UgYWxzbyBmaWx0ZXIgb3V0IGFsbCBwcm92aWRlcnNcbiAgICAvLyB0aGF0IGhhdmUgb3ZlcnJpZGVzLCBrZWVwaW5nIG92ZXJyaWRkZW4gdmFsdWVzIG9ubHkuIFRoaXMgaXMgbmVlZGVkLCBzaW5jZSBwcmVzZW5jZSBvZiBhXG4gICAgLy8gcHJvdmlkZXIgd2l0aCBgbmdPbkRlc3Ryb3lgIGhvb2sgd2lsbCBjYXVzZSB0aGlzIGhvb2sgdG8gYmUgcmVnaXN0ZXJlZCBhbmQgaW52b2tlZCBsYXRlci5cbiAgICBmb3JFYWNoUmlnaHQob3ZlcnJpZGRlblByb3ZpZGVycywgKHByb3ZpZGVyOiBhbnkpID0+IHtcbiAgICAgIGNvbnN0IHRva2VuOiBhbnkgPSBnZXRQcm92aWRlclRva2VuKHByb3ZpZGVyKTtcbiAgICAgIGlmICh0aGlzLnByb3ZpZGVyT3ZlcnJpZGVzQnlUb2tlbi5oYXModG9rZW4pKSB7XG4gICAgICAgIGlmICghc2Vlbk92ZXJyaWRkZW5Qcm92aWRlcnMuaGFzKHRva2VuKSkge1xuICAgICAgICAgIHNlZW5PdmVycmlkZGVuUHJvdmlkZXJzLmFkZCh0b2tlbik7XG4gICAgICAgICAgLy8gVHJlYXQgYWxsIG92ZXJyaWRkZW4gcHJvdmlkZXJzIGFzIGB7bXVsdGk6IGZhbHNlfWAgKGV2ZW4gaWYgaXQncyBhIG11bHRpLXByb3ZpZGVyKSB0b1xuICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGF0IHByb3ZpZGVkIG92ZXJyaWRlIHRha2VzIGhpZ2hlc3QgcHJlY2VkZW5jZSBhbmQgaXMgbm90IGNvbWJpbmVkIHdpdGhcbiAgICAgICAgICAvLyBvdGhlciBpbnN0YW5jZXMgb2YgdGhlIHNhbWUgbXVsdGkgcHJvdmlkZXIuXG4gICAgICAgICAgZmluYWwudW5zaGlmdCh7Li4ucHJvdmlkZXIsIG11bHRpOiBmYWxzZX0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmaW5hbC51bnNoaWZ0KHByb3ZpZGVyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gZmluYWw7XG4gIH1cblxuICBwcml2YXRlIGhhc1Byb3ZpZGVyT3ZlcnJpZGVzKHByb3ZpZGVycz86IFByb3ZpZGVyW10pOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZXRQcm92aWRlck92ZXJyaWRlcyhwcm92aWRlcnMpLmxlbmd0aCA+IDA7XG4gIH1cblxuICBwcml2YXRlIHBhdGNoRGVmV2l0aFByb3ZpZGVyT3ZlcnJpZGVzKGRlY2xhcmF0aW9uOiBUeXBlPGFueT4sIGZpZWxkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBkZWYgPSAoZGVjbGFyYXRpb24gYXMgYW55KVtmaWVsZF07XG4gICAgaWYgKGRlZiAmJiBkZWYucHJvdmlkZXJzUmVzb2x2ZXIpIHtcbiAgICAgIHRoaXMubWF5YmVTdG9yZU5nRGVmKGZpZWxkLCBkZWNsYXJhdGlvbik7XG5cbiAgICAgIGNvbnN0IHJlc29sdmVyID0gZGVmLnByb3ZpZGVyc1Jlc29sdmVyO1xuICAgICAgY29uc3QgcHJvY2Vzc1Byb3ZpZGVyc0ZuID0gKHByb3ZpZGVyczogUHJvdmlkZXJbXSkgPT4gdGhpcy5nZXRPdmVycmlkZGVuUHJvdmlkZXJzKHByb3ZpZGVycyk7XG4gICAgICB0aGlzLnN0b3JlRmllbGRPZkRlZk9uVHlwZShkZWNsYXJhdGlvbiwgZmllbGQsICdwcm92aWRlcnNSZXNvbHZlcicpO1xuICAgICAgZGVmLnByb3ZpZGVyc1Jlc29sdmVyID0gKG5nRGVmOiBEaXJlY3RpdmVEZWY8YW55PikgPT4gcmVzb2x2ZXIobmdEZWYsIHByb2Nlc3NQcm92aWRlcnNGbik7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGluaXRSZXNvbHZlcnMoKTogUmVzb2x2ZXJzIHtcbiAgcmV0dXJuIHtcbiAgICBtb2R1bGU6IG5ldyBOZ01vZHVsZVJlc29sdmVyKCksXG4gICAgY29tcG9uZW50OiBuZXcgQ29tcG9uZW50UmVzb2x2ZXIoKSxcbiAgICBkaXJlY3RpdmU6IG5ldyBEaXJlY3RpdmVSZXNvbHZlcigpLFxuICAgIHBpcGU6IG5ldyBQaXBlUmVzb2x2ZXIoKVxuICB9O1xufVxuXG5mdW5jdGlvbiBoYXNOZ01vZHVsZURlZjxUPih2YWx1ZTogVHlwZTxUPik6IHZhbHVlIGlzIE5nTW9kdWxlVHlwZTxUPiB7XG4gIHJldHVybiB2YWx1ZS5oYXNPd25Qcm9wZXJ0eSgnybVtb2QnKTtcbn1cblxuZnVuY3Rpb24gbWF5YmVVbndyYXBGbjxUPihtYXliZUZuOiAoKCkgPT4gVCl8VCk6IFQge1xuICByZXR1cm4gbWF5YmVGbiBpbnN0YW5jZW9mIEZ1bmN0aW9uID8gbWF5YmVGbigpIDogbWF5YmVGbjtcbn1cblxuZnVuY3Rpb24gZmxhdHRlbjxUPih2YWx1ZXM6IGFueVtdLCBtYXBGbj86ICh2YWx1ZTogVCkgPT4gYW55KTogVFtdIHtcbiAgY29uc3Qgb3V0OiBUW10gPSBbXTtcbiAgdmFsdWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgb3V0LnB1c2goLi4uZmxhdHRlbjxUPih2YWx1ZSwgbWFwRm4pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0LnB1c2gobWFwRm4gPyBtYXBGbih2YWx1ZSkgOiB2YWx1ZSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gZ2V0UHJvdmlkZXJGaWVsZChwcm92aWRlcjogUHJvdmlkZXIsIGZpZWxkOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHByb3ZpZGVyICYmIHR5cGVvZiBwcm92aWRlciA9PT0gJ29iamVjdCcgJiYgKHByb3ZpZGVyIGFzIGFueSlbZmllbGRdO1xufVxuXG5mdW5jdGlvbiBnZXRQcm92aWRlclRva2VuKHByb3ZpZGVyOiBQcm92aWRlcikge1xuICByZXR1cm4gZ2V0UHJvdmlkZXJGaWVsZChwcm92aWRlciwgJ3Byb3ZpZGUnKSB8fCBwcm92aWRlcjtcbn1cblxuZnVuY3Rpb24gaXNNb2R1bGVXaXRoUHJvdmlkZXJzKHZhbHVlOiBhbnkpOiB2YWx1ZSBpcyBNb2R1bGVXaXRoUHJvdmlkZXJzPGFueT4ge1xuICByZXR1cm4gdmFsdWUuaGFzT3duUHJvcGVydHkoJ25nTW9kdWxlJyk7XG59XG5cbmZ1bmN0aW9uIGZvckVhY2hSaWdodDxUPih2YWx1ZXM6IFRbXSwgZm46ICh2YWx1ZTogVCwgaWR4OiBudW1iZXIpID0+IHZvaWQpOiB2b2lkIHtcbiAgZm9yIChsZXQgaWR4ID0gdmFsdWVzLmxlbmd0aCAtIDE7IGlkeCA+PSAwOyBpZHgtLSkge1xuICAgIGZuKHZhbHVlc1tpZHhdLCBpZHgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGludmFsaWRUeXBlRXJyb3IobmFtZTogc3RyaW5nLCBleHBlY3RlZFR5cGU6IHN0cmluZyk6IEVycm9yIHtcbiAgcmV0dXJuIG5ldyBFcnJvcihgJHtuYW1lfSBjbGFzcyBkb2Vzbid0IGhhdmUgQCR7ZXhwZWN0ZWRUeXBlfSBkZWNvcmF0b3Igb3IgaXMgbWlzc2luZyBtZXRhZGF0YS5gKTtcbn1cblxuY2xhc3MgUjNUZXN0Q29tcGlsZXIgaW1wbGVtZW50cyBDb21waWxlciB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgdGVzdEJlZDogUjNUZXN0QmVkQ29tcGlsZXIpIHt9XG5cbiAgY29tcGlsZU1vZHVsZVN5bmM8VD4obW9kdWxlVHlwZTogVHlwZTxUPik6IE5nTW9kdWxlRmFjdG9yeTxUPiB7XG4gICAgdGhpcy50ZXN0QmVkLl9jb21waWxlTmdNb2R1bGVTeW5jKG1vZHVsZVR5cGUpO1xuICAgIHJldHVybiBuZXcgUjNOZ01vZHVsZUZhY3RvcnkobW9kdWxlVHlwZSk7XG4gIH1cblxuICBhc3luYyBjb21waWxlTW9kdWxlQXN5bmM8VD4obW9kdWxlVHlwZTogVHlwZTxUPik6IFByb21pc2U8TmdNb2R1bGVGYWN0b3J5PFQ+PiB7XG4gICAgYXdhaXQgdGhpcy50ZXN0QmVkLl9jb21waWxlTmdNb2R1bGVBc3luYyhtb2R1bGVUeXBlKTtcbiAgICByZXR1cm4gbmV3IFIzTmdNb2R1bGVGYWN0b3J5KG1vZHVsZVR5cGUpO1xuICB9XG5cbiAgY29tcGlsZU1vZHVsZUFuZEFsbENvbXBvbmVudHNTeW5jPFQ+KG1vZHVsZVR5cGU6IFR5cGU8VD4pOiBNb2R1bGVXaXRoQ29tcG9uZW50RmFjdG9yaWVzPFQ+IHtcbiAgICBjb25zdCBuZ01vZHVsZUZhY3RvcnkgPSB0aGlzLmNvbXBpbGVNb2R1bGVTeW5jKG1vZHVsZVR5cGUpO1xuICAgIGNvbnN0IGNvbXBvbmVudEZhY3RvcmllcyA9IHRoaXMudGVzdEJlZC5fZ2V0Q29tcG9uZW50RmFjdG9yaWVzKG1vZHVsZVR5cGUgYXMgTmdNb2R1bGVUeXBlPFQ+KTtcbiAgICByZXR1cm4gbmV3IE1vZHVsZVdpdGhDb21wb25lbnRGYWN0b3JpZXMobmdNb2R1bGVGYWN0b3J5LCBjb21wb25lbnRGYWN0b3JpZXMpO1xuICB9XG5cbiAgYXN5bmMgY29tcGlsZU1vZHVsZUFuZEFsbENvbXBvbmVudHNBc3luYzxUPihtb2R1bGVUeXBlOiBUeXBlPFQ+KTpcbiAgICAgIFByb21pc2U8TW9kdWxlV2l0aENvbXBvbmVudEZhY3RvcmllczxUPj4ge1xuICAgIGNvbnN0IG5nTW9kdWxlRmFjdG9yeSA9IGF3YWl0IHRoaXMuY29tcGlsZU1vZHVsZUFzeW5jKG1vZHVsZVR5cGUpO1xuICAgIGNvbnN0IGNvbXBvbmVudEZhY3RvcmllcyA9IHRoaXMudGVzdEJlZC5fZ2V0Q29tcG9uZW50RmFjdG9yaWVzKG1vZHVsZVR5cGUgYXMgTmdNb2R1bGVUeXBlPFQ+KTtcbiAgICByZXR1cm4gbmV3IE1vZHVsZVdpdGhDb21wb25lbnRGYWN0b3JpZXMobmdNb2R1bGVGYWN0b3J5LCBjb21wb25lbnRGYWN0b3JpZXMpO1xuICB9XG5cbiAgY2xlYXJDYWNoZSgpOiB2b2lkIHt9XG5cbiAgY2xlYXJDYWNoZUZvcih0eXBlOiBUeXBlPGFueT4pOiB2b2lkIHt9XG5cbiAgZ2V0TW9kdWxlSWQobW9kdWxlVHlwZTogVHlwZTxhbnk+KTogc3RyaW5nfHVuZGVmaW5lZCB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMudGVzdEJlZC5fZ2V0TW9kdWxlUmVzb2x2ZXIoKS5yZXNvbHZlKG1vZHVsZVR5cGUpO1xuICAgIHJldHVybiBtZXRhICYmIG1ldGEuaWQgfHwgdW5kZWZpbmVkO1xuICB9XG59XG4iXX0=