@angular/core 16.0.0-next.3 → 16.0.0-next.5
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.
- package/{esm2020 → esm2022}/src/application_init.mjs +3 -3
- package/{esm2020 → esm2022}/src/application_module.mjs +4 -4
- package/esm2022/src/application_ref.mjs +908 -0
- package/esm2022/src/application_tokens.mjs +105 -0
- package/esm2022/src/change_detection/change_detector_ref.mjs +93 -0
- package/esm2022/src/change_detection/differs/iterable_differs.mjs +81 -0
- package/esm2022/src/change_detection/differs/keyvalue_differs.mjs +74 -0
- package/esm2022/src/compiler/compiler_facade_interface.mjs +29 -0
- package/{esm2020 → esm2022}/src/console.mjs +3 -3
- package/esm2022/src/core.mjs +56 -0
- package/esm2022/src/core_private_export.mjs +39 -0
- package/esm2022/src/core_reactivity_export_internal.mjs +12 -0
- package/esm2022/src/core_render3_private_export.mjs +37 -0
- package/esm2022/src/di/contextual.mjs +54 -0
- package/esm2022/src/di/index.mjs +29 -0
- package/esm2022/src/di/injector.mjs +62 -0
- package/esm2022/src/di/injector_compatibility.mjs +239 -0
- package/esm2022/src/di/provider_collection.mjs +279 -0
- package/esm2022/src/di/r3_injector.mjs +428 -0
- package/esm2022/src/di/reflective_injector.mjs +311 -0
- package/{esm2020 → esm2022}/src/errors.mjs +1 -1
- package/esm2022/src/hydration/annotate.mjs +426 -0
- package/esm2022/src/hydration/api.mjs +143 -0
- package/esm2022/src/hydration/cleanup.mjs +103 -0
- package/esm2022/src/hydration/compression.mjs +69 -0
- package/esm2022/src/hydration/error_handling.mjs +379 -0
- package/esm2022/src/hydration/interfaces.mjs +33 -0
- package/esm2022/src/hydration/node_lookup_utils.mjs +273 -0
- package/esm2022/src/hydration/utils.mjs +219 -0
- package/esm2022/src/hydration/views.mjs +84 -0
- package/esm2022/src/initial_render_pending_tasks.mjs +75 -0
- package/{esm2020 → esm2022}/src/linker/compiler.mjs +5 -5
- package/esm2022/src/linker/component_factory_resolver.mjs +42 -0
- package/esm2022/src/linker/destroy_ref.mjs +44 -0
- package/{esm2020 → esm2022}/src/linker/element_ref.mjs +6 -6
- package/esm2022/src/linker/query_list.mjs +169 -0
- package/{esm2020 → esm2022}/src/linker/template_ref.mjs +6 -6
- package/esm2022/src/linker/view_container_ref.mjs +395 -0
- package/esm2022/src/metadata/di.mjs +69 -0
- package/esm2022/src/metadata/directives.mjs +116 -0
- package/{esm2020 → esm2022}/src/metadata/do_boostrap.mjs +1 -1
- package/{esm2020 → esm2022}/src/metadata/ng_module.mjs +2 -2
- package/esm2022/src/metadata.mjs +18 -0
- package/{esm2020 → esm2022}/src/render/api.mjs +6 -6
- package/esm2022/src/render3/component_ref.mjs +386 -0
- package/{esm2020 → esm2022}/src/render3/context_discovery.mjs +1 -1
- package/esm2022/src/render3/features/standalone_feature.mjs +70 -0
- package/esm2022/src/render3/instructions/element.mjs +205 -0
- package/{esm2020 → esm2022}/src/render3/instructions/element_container.mjs +2 -5
- package/esm2022/src/render3/instructions/element_validation.mjs +271 -0
- package/esm2022/src/render3/instructions/listener.mjs +244 -0
- package/esm2022/src/render3/instructions/mark_view_dirty.mjs +35 -0
- package/esm2022/src/render3/instructions/projection.mjs +121 -0
- package/esm2022/src/render3/instructions/shared.mjs +1681 -0
- package/{esm2020 → esm2022}/src/render3/instructions/styling.mjs +5 -2
- package/esm2022/src/render3/instructions/template.mjs +117 -0
- package/esm2022/src/render3/instructions/text.mjs +67 -0
- package/esm2022/src/render3/interfaces/public_definitions.mjs +9 -0
- package/esm2022/src/render3/interfaces/type_checks.mjs +42 -0
- package/esm2022/src/render3/interfaces/view.mjs +49 -0
- package/esm2022/src/render3/jit/module.mjs +531 -0
- package/esm2022/src/render3/node_manipulation.mjs +960 -0
- package/esm2022/src/render3/node_selector_matcher.mjs +426 -0
- package/esm2022/src/render3/reactive_lview_consumer.mjs +80 -0
- package/esm2022/src/render3/reactivity/effect.mjs +67 -0
- package/{esm2020 → esm2022}/src/render3/util/change_detection_utils.mjs +2 -2
- package/{esm2020 → esm2022}/src/render3/util/view_utils.mjs +12 -1
- package/esm2022/src/render3/view_ref.mjs +307 -0
- package/{esm2020 → esm2022}/src/sanitization/sanitizer.mjs +7 -7
- package/esm2022/src/signals/index.mjs +15 -0
- package/esm2022/src/signals/src/api.mjs +47 -0
- package/esm2022/src/signals/src/computed.mjs +139 -0
- package/esm2022/src/signals/src/graph.mjs +165 -0
- package/esm2022/src/signals/src/signal.mjs +75 -0
- package/esm2022/src/signals/src/watch.mjs +62 -0
- package/esm2022/src/signals/src/weak_ref.mjs +35 -0
- package/{esm2020 → esm2022}/src/testability/testability.mjs +5 -5
- package/esm2022/src/transfer_state.mjs +153 -0
- package/esm2022/src/util/ng_dev_mode.mjs +79 -0
- package/{esm2020 → esm2022}/src/version.mjs +1 -1
- package/{esm2020 → esm2022}/testing/src/logger.mjs +4 -4
- package/{esm2020 → esm2022}/testing/src/ng_zone_mock.mjs +4 -4
- package/{esm2020 → esm2022}/testing/src/test_bed.mjs +2 -2
- package/esm2022/testing/src/test_bed_compiler.mjs +846 -0
- package/{fesm2020 → fesm2022}/core.mjs +1890 -779
- package/fesm2022/core.mjs.map +1 -0
- package/{fesm2020 → fesm2022}/testing.mjs +1203 -178
- package/fesm2022/testing.mjs.map +1 -0
- package/index.d.ts +453 -394
- package/package.json +8 -16
- package/schematics/migrations/guard-and-resolve-interfaces/bundle.js +694 -0
- package/schematics/migrations/guard-and-resolve-interfaces/bundle.js.map +7 -0
- package/schematics/migrations/{router-link-with-href → remove-module-id}/bundle.js +153 -155
- package/schematics/migrations/remove-module-id/bundle.js.map +7 -0
- package/schematics/migrations.json +8 -8
- package/schematics/ng-generate/standalone-migration/bundle.js +1082 -619
- package/schematics/ng-generate/standalone-migration/bundle.js.map +2 -2
- package/testing/index.d.ts +1 -1
- package/esm2020/src/application_ref.mjs +0 -907
- package/esm2020/src/application_tokens.mjs +0 -73
- package/esm2020/src/change_detection/change_detector_ref.mjs +0 -93
- package/esm2020/src/change_detection/differs/iterable_differs.mjs +0 -81
- package/esm2020/src/change_detection/differs/keyvalue_differs.mjs +0 -74
- package/esm2020/src/compiler/compiler_facade_interface.mjs +0 -29
- package/esm2020/src/core.mjs +0 -55
- package/esm2020/src/core_private_export.mjs +0 -37
- package/esm2020/src/core_reactivity_export_internal.mjs +0 -9
- package/esm2020/src/core_render3_private_export.mjs +0 -38
- package/esm2020/src/di/contextual.mjs +0 -37
- package/esm2020/src/di/index.mjs +0 -29
- package/esm2020/src/di/injector.mjs +0 -62
- package/esm2020/src/di/injector_compatibility.mjs +0 -236
- package/esm2020/src/di/provider_collection.mjs +0 -279
- package/esm2020/src/di/r3_injector.mjs +0 -421
- package/esm2020/src/di/reflective_injector.mjs +0 -311
- package/esm2020/src/hydration/annotate.mjs +0 -271
- package/esm2020/src/hydration/api.mjs +0 -128
- package/esm2020/src/hydration/cleanup.mjs +0 -50
- package/esm2020/src/hydration/error_handling.mjs +0 -37
- package/esm2020/src/hydration/interfaces.mjs +0 -17
- package/esm2020/src/hydration/node_lookup_utils.mjs +0 -83
- package/esm2020/src/hydration/utils.mjs +0 -206
- package/esm2020/src/hydration/views.mjs +0 -80
- package/esm2020/src/linker/component_factory_resolver.mjs +0 -42
- package/esm2020/src/linker/destroy_ref.mjs +0 -41
- package/esm2020/src/linker/query_list.mjs +0 -169
- package/esm2020/src/linker/view_container_ref.mjs +0 -394
- package/esm2020/src/metadata/di.mjs +0 -108
- package/esm2020/src/metadata/directives.mjs +0 -111
- package/esm2020/src/metadata.mjs +0 -18
- package/esm2020/src/render3/component_ref.mjs +0 -377
- package/esm2020/src/render3/features/standalone_feature.mjs +0 -70
- package/esm2020/src/render3/instructions/element.mjs +0 -198
- package/esm2020/src/render3/instructions/element_validation.mjs +0 -271
- package/esm2020/src/render3/instructions/listener.mjs +0 -243
- package/esm2020/src/render3/instructions/projection.mjs +0 -118
- package/esm2020/src/render3/instructions/shared.mjs +0 -1696
- package/esm2020/src/render3/instructions/template.mjs +0 -120
- package/esm2020/src/render3/instructions/text.mjs +0 -67
- package/esm2020/src/render3/interfaces/public_definitions.mjs +0 -9
- package/esm2020/src/render3/interfaces/type_checks.mjs +0 -39
- package/esm2020/src/render3/interfaces/view.mjs +0 -47
- package/esm2020/src/render3/jit/module.mjs +0 -544
- package/esm2020/src/render3/node_manipulation.mjs +0 -961
- package/esm2020/src/render3/node_selector_matcher.mjs +0 -414
- package/esm2020/src/render3/view_ref.mjs +0 -306
- package/esm2020/src/signals/index.mjs +0 -15
- package/esm2020/src/signals/src/api.mjs +0 -46
- package/esm2020/src/signals/src/computed.mjs +0 -142
- package/esm2020/src/signals/src/effect.mjs +0 -69
- package/esm2020/src/signals/src/graph.mjs +0 -114
- package/esm2020/src/signals/src/signal.mjs +0 -78
- package/esm2020/src/signals/src/watch.mjs +0 -54
- package/esm2020/src/signals/src/weak_ref.mjs +0 -11
- package/esm2020/src/transfer_state.mjs +0 -153
- package/esm2020/src/util/ng_dev_mode.mjs +0 -78
- package/esm2020/testing/src/test_bed_compiler.mjs +0 -841
- package/fesm2015/core.mjs +0 -29585
- package/fesm2015/core.mjs.map +0 -1
- package/fesm2015/testing.mjs +0 -25669
- package/fesm2015/testing.mjs.map +0 -1
- package/fesm2020/core.mjs.map +0 -1
- package/fesm2020/testing.mjs.map +0 -1
- package/schematics/migrations/relative-link-resolution/bundle.js +0 -283
- package/schematics/migrations/relative-link-resolution/bundle.js.map +0 -7
- package/schematics/migrations/router-link-with-href/bundle.js.map +0 -7
- /package/{esm2020 → esm2022}/core.mjs +0 -0
- /package/{esm2020 → esm2022}/index.mjs +0 -0
- /package/{esm2020 → esm2022}/public_api.mjs +0 -0
- /package/{esm2020 → esm2022}/src/application_config.mjs +0 -0
- /package/{esm2020 → esm2022}/src/change_detection/change_detection.mjs +0 -0
- /package/{esm2020 → esm2022}/src/change_detection/constants.mjs +0 -0
- /package/{esm2020 → esm2022}/src/change_detection/differs/default_iterable_differ.mjs +0 -0
- /package/{esm2020 → esm2022}/src/change_detection/differs/default_keyvalue_differ.mjs +0 -0
- /package/{esm2020 → esm2022}/src/change_detection/pipe_transform.mjs +0 -0
- /package/{esm2020 → esm2022}/src/change_detection.mjs +0 -0
- /package/{esm2020 → esm2022}/src/compiler/compiler_facade.mjs +0 -0
- /package/{esm2020 → esm2022}/src/core_reactivity_export.mjs +0 -0
- /package/{esm2020 → esm2022}/src/debug/debug_node.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/create_injector.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/forward_ref.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/initializer_token.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/inject_switch.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/injectable.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/injection_token.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/injector_marker.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/injector_token.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/interface/defs.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/interface/injector.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/interface/provider.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/internal_tokens.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/jit/environment.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/jit/injectable.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/jit/util.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/metadata.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/metadata_attr.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/null_injector.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/provider_token.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/reflective_errors.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/reflective_key.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/reflective_provider.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di/scope.mjs +0 -0
- /package/{esm2020 → esm2022}/src/di.mjs +0 -0
- /package/{esm2020 → esm2022}/src/error_details_base_url.mjs +0 -0
- /package/{esm2020 → esm2022}/src/error_handler.mjs +0 -0
- /package/{esm2020 → esm2022}/src/event_emitter.mjs +0 -0
- /package/{esm2020 → esm2022}/src/hydration/skip_hydration.mjs +0 -0
- /package/{esm2020 → esm2022}/src/hydration/tokens.mjs +0 -0
- /package/{esm2020 → esm2022}/src/i18n/locale_data_api.mjs +0 -0
- /package/{esm2020 → esm2022}/src/i18n/locale_en.mjs +0 -0
- /package/{esm2020 → esm2022}/src/i18n/localization.mjs +0 -0
- /package/{esm2020 → esm2022}/src/i18n/tokens.mjs +0 -0
- /package/{esm2020 → esm2022}/src/interface/lifecycle_hooks.mjs +0 -0
- /package/{esm2020 → esm2022}/src/interface/simple_change.mjs +0 -0
- /package/{esm2020 → esm2022}/src/interface/type.mjs +0 -0
- /package/{esm2020 → esm2022}/src/linker/component_factory.mjs +0 -0
- /package/{esm2020 → esm2022}/src/linker/ng_module_factory.mjs +0 -0
- /package/{esm2020 → esm2022}/src/linker/ng_module_factory_loader.mjs +0 -0
- /package/{esm2020 → esm2022}/src/linker/ng_module_factory_loader_impl.mjs +0 -0
- /package/{esm2020 → esm2022}/src/linker/ng_module_registration.mjs +0 -0
- /package/{esm2020 → esm2022}/src/linker/view_ref.mjs +0 -0
- /package/{esm2020 → esm2022}/src/linker.mjs +0 -0
- /package/{esm2020 → esm2022}/src/metadata/ng_module_def.mjs +0 -0
- /package/{esm2020 → esm2022}/src/metadata/resource_loading.mjs +0 -0
- /package/{esm2020 → esm2022}/src/metadata/schema.mjs +0 -0
- /package/{esm2020 → esm2022}/src/metadata/view.mjs +0 -0
- /package/{esm2020 → esm2022}/src/platform_core_providers.mjs +0 -0
- /package/{esm2020 → esm2022}/src/r3_symbols.mjs +0 -0
- /package/{esm2020 → esm2022}/src/reflection/platform_reflection_capabilities.mjs +0 -0
- /package/{esm2020 → esm2022}/src/reflection/reflection_capabilities.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render/api_flags.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/assert.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/bindings.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/collect_native_nodes.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/component.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/definition.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/definition_factory.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/di.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/di_setup.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/errors.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/errors_di.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/features/copy_definition_feature.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/features/host_directives_feature.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/features/inherit_definition_feature.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/features/ng_onchanges_feature.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/features/providers_feature.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/fields.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/global_utils_api.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/hooks.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_apply.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_debug.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_insert_before_index.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_locale_id.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_parse.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_postprocess.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_tree_shaking.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/i18n/i18n_util.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/index.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/advance.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/all.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/attribute.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/attribute_interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/change_detection.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/class_map_interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/di.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/di_attr.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/get_current_view.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/host_property.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/i18n.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/i18n_icu_container_visitor.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/namespace.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/next_context.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/property.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/property_interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/storage.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/style_map_interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/style_prop_interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/instructions/text_interpolation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/container.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/context.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/definition.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/document.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/i18n.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/injector.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/lview_tracking.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/node.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/projection.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/query.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/renderer.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/renderer_dom.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/sanitization.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/interfaces/styling.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/directive.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/environment.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/jit_options.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/module_patch.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/partial.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/pipe.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/jit/util.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/metadata.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/namespaces.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/ng_module_ref.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/node_assert.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/node_manipulation_i18n.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/pipe.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/profiler.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/pure_function.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/query.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/state.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/styling/class_differ.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/styling/static_styling.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/styling/style_binding_list.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/styling/styling_parser.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/tokens.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/attrs_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/discovery_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/global_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/injector_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/misc_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/stringify_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/util/view_traversal_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/render3/view_engine_compatibility_prebound.mjs +0 -0
- /package/{esm2020 → esm2022}/src/sanitization/bypass.mjs +0 -0
- /package/{esm2020 → esm2022}/src/sanitization/html_sanitizer.mjs +0 -0
- /package/{esm2020 → esm2022}/src/sanitization/iframe_attrs_validation.mjs +0 -0
- /package/{esm2020 → esm2022}/src/sanitization/inert_body.mjs +0 -0
- /package/{esm2020 → esm2022}/src/sanitization/sanitization.mjs +0 -0
- /package/{esm2020 → esm2022}/src/sanitization/security.mjs +0 -0
- /package/{esm2020 → esm2022}/src/sanitization/url_sanitizer.mjs +0 -0
- /package/{esm2020 → esm2022}/src/signals/src/untracked.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/array_utils.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/assert.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/char_code.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/closure.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/coercion.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/comparison.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/decorators.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/dom.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/empty.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/errors.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/global.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/is_dev_mode.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/iterable.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/lang.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/microtask.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/ng_i18n_closure_mode.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/ng_jit_mode.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/ng_reflect.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/noop.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/property.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/raf.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/security/trusted_type_defs.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/security/trusted_types.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/security/trusted_types_bypass.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util/stringify.mjs +0 -0
- /package/{esm2020 → esm2022}/src/view/provider_flags.mjs +0 -0
- /package/{esm2020 → esm2022}/src/zone/async-stack-tagging.mjs +0 -0
- /package/{esm2020 → esm2022}/src/zone/ng_zone.mjs +0 -0
- /package/{esm2020 → esm2022}/src/zone.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/index.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/public_api.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/async.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/component_fixture.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/fake_async.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/metadata_override.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/metadata_overrider.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/resolvers.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/styling.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/test_bed_common.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/test_hooks.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/testing.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/src/testing_internal.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/testing.mjs +0 -0
|
@@ -1,841 +0,0 @@
|
|
|
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, ɵisEnvironmentProviders as isEnvironmentProviders, ɵ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, ɵprovideNgZoneChangeDetection as provideNgZoneChangeDetection, ɵ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 { generateStandaloneInDeclarationsError } from '../../src/render3/jit/module';
|
|
12
|
-
import { ComponentResolver, DirectiveResolver, NgModuleResolver, PipeResolver } from './resolvers';
|
|
13
|
-
var TestingModuleOverride;
|
|
14
|
-
(function (TestingModuleOverride) {
|
|
15
|
-
TestingModuleOverride[TestingModuleOverride["DECLARATION"] = 0] = "DECLARATION";
|
|
16
|
-
TestingModuleOverride[TestingModuleOverride["OVERRIDE_TEMPLATE"] = 1] = "OVERRIDE_TEMPLATE";
|
|
17
|
-
})(TestingModuleOverride || (TestingModuleOverride = {}));
|
|
18
|
-
function isTestingModuleOverride(value) {
|
|
19
|
-
return value === TestingModuleOverride.DECLARATION ||
|
|
20
|
-
value === TestingModuleOverride.OVERRIDE_TEMPLATE;
|
|
21
|
-
}
|
|
22
|
-
function assertNoStandaloneComponents(types, resolver, location) {
|
|
23
|
-
types.forEach(type => {
|
|
24
|
-
const component = resolver.resolve(type);
|
|
25
|
-
if (component && component.standalone) {
|
|
26
|
-
throw new Error(generateStandaloneInDeclarationsError(type, location));
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
export class TestBedCompiler {
|
|
31
|
-
constructor(platform, additionalModuleTypes) {
|
|
32
|
-
this.platform = platform;
|
|
33
|
-
this.additionalModuleTypes = additionalModuleTypes;
|
|
34
|
-
this.originalComponentResolutionQueue = null;
|
|
35
|
-
// Testing module configuration
|
|
36
|
-
this.declarations = [];
|
|
37
|
-
this.imports = [];
|
|
38
|
-
this.providers = [];
|
|
39
|
-
this.schemas = [];
|
|
40
|
-
// Queues of components/directives/pipes that should be recompiled.
|
|
41
|
-
this.pendingComponents = new Set();
|
|
42
|
-
this.pendingDirectives = new Set();
|
|
43
|
-
this.pendingPipes = new Set();
|
|
44
|
-
// Keep track of all components and directives, so we can patch Providers onto defs later.
|
|
45
|
-
this.seenComponents = new Set();
|
|
46
|
-
this.seenDirectives = new Set();
|
|
47
|
-
// Keep track of overridden modules, so that we can collect all affected ones in the module tree.
|
|
48
|
-
this.overriddenModules = new Set();
|
|
49
|
-
// Store resolved styles for Components that have template overrides present and `styleUrls`
|
|
50
|
-
// defined at the same time.
|
|
51
|
-
this.existingComponentStyles = new Map();
|
|
52
|
-
this.resolvers = initResolvers();
|
|
53
|
-
this.componentToModuleScope = new Map();
|
|
54
|
-
// Map that keeps initial version of component/directive/pipe defs in case
|
|
55
|
-
// we compile a Type again, thus overriding respective static fields. This is
|
|
56
|
-
// required to make sure we restore defs to their initial states between test runs.
|
|
57
|
-
// Note: one class may have multiple defs (for example: ɵmod and ɵinj in case of an
|
|
58
|
-
// NgModule), store all of them in a map.
|
|
59
|
-
this.initialNgDefs = new Map();
|
|
60
|
-
// Array that keeps cleanup operations for initial versions of component/directive/pipe/module
|
|
61
|
-
// defs in case TestBed makes changes to the originals.
|
|
62
|
-
this.defCleanupOps = [];
|
|
63
|
-
this._injector = null;
|
|
64
|
-
this.compilerProviders = null;
|
|
65
|
-
this.providerOverrides = [];
|
|
66
|
-
this.rootProviderOverrides = [];
|
|
67
|
-
// Overrides for injectables with `{providedIn: SomeModule}` need to be tracked and added to that
|
|
68
|
-
// module's provider list.
|
|
69
|
-
this.providerOverridesByModule = new Map();
|
|
70
|
-
this.providerOverridesByToken = new Map();
|
|
71
|
-
this.scopesWithOverriddenProviders = new Set();
|
|
72
|
-
this.testModuleRef = null;
|
|
73
|
-
class DynamicTestModule {
|
|
74
|
-
}
|
|
75
|
-
this.testModuleType = DynamicTestModule;
|
|
76
|
-
}
|
|
77
|
-
setCompilerProviders(providers) {
|
|
78
|
-
this.compilerProviders = providers;
|
|
79
|
-
this._injector = null;
|
|
80
|
-
}
|
|
81
|
-
configureTestingModule(moduleDef) {
|
|
82
|
-
// Enqueue any compilation tasks for the directly declared component.
|
|
83
|
-
if (moduleDef.declarations !== undefined) {
|
|
84
|
-
// Verify that there are no standalone components
|
|
85
|
-
assertNoStandaloneComponents(moduleDef.declarations, this.resolvers.component, '"TestBed.configureTestingModule" call');
|
|
86
|
-
this.queueTypeArray(moduleDef.declarations, TestingModuleOverride.DECLARATION);
|
|
87
|
-
this.declarations.push(...moduleDef.declarations);
|
|
88
|
-
}
|
|
89
|
-
// Enqueue any compilation tasks for imported modules.
|
|
90
|
-
if (moduleDef.imports !== undefined) {
|
|
91
|
-
this.queueTypesFromModulesArray(moduleDef.imports);
|
|
92
|
-
this.imports.push(...moduleDef.imports);
|
|
93
|
-
}
|
|
94
|
-
if (moduleDef.providers !== undefined) {
|
|
95
|
-
this.providers.push(...moduleDef.providers);
|
|
96
|
-
}
|
|
97
|
-
if (moduleDef.schemas !== undefined) {
|
|
98
|
-
this.schemas.push(...moduleDef.schemas);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
overrideModule(ngModule, override) {
|
|
102
|
-
this.overriddenModules.add(ngModule);
|
|
103
|
-
// Compile the module right away.
|
|
104
|
-
this.resolvers.module.addOverride(ngModule, override);
|
|
105
|
-
const metadata = this.resolvers.module.resolve(ngModule);
|
|
106
|
-
if (metadata === null) {
|
|
107
|
-
throw invalidTypeError(ngModule.name, 'NgModule');
|
|
108
|
-
}
|
|
109
|
-
this.recompileNgModule(ngModule, metadata);
|
|
110
|
-
// At this point, the module has a valid module def (ɵmod), but the override may have introduced
|
|
111
|
-
// new declarations or imported modules. Ingest any possible new types and add them to the
|
|
112
|
-
// current queue.
|
|
113
|
-
this.queueTypesFromModulesArray([ngModule]);
|
|
114
|
-
}
|
|
115
|
-
overrideComponent(component, override) {
|
|
116
|
-
this.verifyNoStandaloneFlagOverrides(component, override);
|
|
117
|
-
this.resolvers.component.addOverride(component, override);
|
|
118
|
-
this.pendingComponents.add(component);
|
|
119
|
-
}
|
|
120
|
-
overrideDirective(directive, override) {
|
|
121
|
-
this.verifyNoStandaloneFlagOverrides(directive, override);
|
|
122
|
-
this.resolvers.directive.addOverride(directive, override);
|
|
123
|
-
this.pendingDirectives.add(directive);
|
|
124
|
-
}
|
|
125
|
-
overridePipe(pipe, override) {
|
|
126
|
-
this.verifyNoStandaloneFlagOverrides(pipe, override);
|
|
127
|
-
this.resolvers.pipe.addOverride(pipe, override);
|
|
128
|
-
this.pendingPipes.add(pipe);
|
|
129
|
-
}
|
|
130
|
-
verifyNoStandaloneFlagOverrides(type, override) {
|
|
131
|
-
if (override.add?.hasOwnProperty('standalone') || override.set?.hasOwnProperty('standalone') ||
|
|
132
|
-
override.remove?.hasOwnProperty('standalone')) {
|
|
133
|
-
throw new Error(`An override for the ${type.name} class has the \`standalone\` flag. ` +
|
|
134
|
-
`Changing the \`standalone\` flag via TestBed overrides is not supported.`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
overrideProvider(token, provider) {
|
|
138
|
-
let providerDef;
|
|
139
|
-
if (provider.useFactory !== undefined) {
|
|
140
|
-
providerDef = {
|
|
141
|
-
provide: token,
|
|
142
|
-
useFactory: provider.useFactory,
|
|
143
|
-
deps: provider.deps || [],
|
|
144
|
-
multi: provider.multi
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
else if (provider.useValue !== undefined) {
|
|
148
|
-
providerDef = { provide: token, useValue: provider.useValue, multi: provider.multi };
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
providerDef = { provide: token };
|
|
152
|
-
}
|
|
153
|
-
const injectableDef = typeof token !== 'string' ? getInjectableDef(token) : null;
|
|
154
|
-
const providedIn = injectableDef === null ? null : resolveForwardRef(injectableDef.providedIn);
|
|
155
|
-
const overridesBucket = providedIn === 'root' ? this.rootProviderOverrides : this.providerOverrides;
|
|
156
|
-
overridesBucket.push(providerDef);
|
|
157
|
-
// Keep overrides grouped by token as well for fast lookups using token
|
|
158
|
-
this.providerOverridesByToken.set(token, providerDef);
|
|
159
|
-
if (injectableDef !== null && providedIn !== null && typeof providedIn !== 'string') {
|
|
160
|
-
const existingOverrides = this.providerOverridesByModule.get(providedIn);
|
|
161
|
-
if (existingOverrides !== undefined) {
|
|
162
|
-
existingOverrides.push(providerDef);
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
this.providerOverridesByModule.set(providedIn, [providerDef]);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
overrideTemplateUsingTestingModule(type, template) {
|
|
170
|
-
const def = type[NG_COMP_DEF];
|
|
171
|
-
const hasStyleUrls = () => {
|
|
172
|
-
const metadata = this.resolvers.component.resolve(type);
|
|
173
|
-
return !!metadata.styleUrls && metadata.styleUrls.length > 0;
|
|
174
|
-
};
|
|
175
|
-
const overrideStyleUrls = !!def && !isComponentDefPendingResolution(type) && hasStyleUrls();
|
|
176
|
-
// In Ivy, compiling a component does not require knowing the module providing the
|
|
177
|
-
// component's scope, so overrideTemplateUsingTestingModule can be implemented purely via
|
|
178
|
-
// overrideComponent. Important: overriding template requires full Component re-compilation,
|
|
179
|
-
// which may fail in case styleUrls are also present (thus Component is considered as required
|
|
180
|
-
// resolution). In order to avoid this, we preemptively set styleUrls to an empty array,
|
|
181
|
-
// preserve current styles available on Component def and restore styles back once compilation
|
|
182
|
-
// is complete.
|
|
183
|
-
const override = overrideStyleUrls ? { template, styles: [], styleUrls: [] } : { template };
|
|
184
|
-
this.overrideComponent(type, { set: override });
|
|
185
|
-
if (overrideStyleUrls && def.styles && def.styles.length > 0) {
|
|
186
|
-
this.existingComponentStyles.set(type, def.styles);
|
|
187
|
-
}
|
|
188
|
-
// Set the component's scope to be the testing module.
|
|
189
|
-
this.componentToModuleScope.set(type, TestingModuleOverride.OVERRIDE_TEMPLATE);
|
|
190
|
-
}
|
|
191
|
-
async compileComponents() {
|
|
192
|
-
this.clearComponentResolutionQueue();
|
|
193
|
-
// Run compilers for all queued types.
|
|
194
|
-
let needsAsyncResources = this.compileTypesSync();
|
|
195
|
-
// compileComponents() should not be async unless it needs to be.
|
|
196
|
-
if (needsAsyncResources) {
|
|
197
|
-
let resourceLoader;
|
|
198
|
-
let resolver = (url) => {
|
|
199
|
-
if (!resourceLoader) {
|
|
200
|
-
resourceLoader = this.injector.get(ResourceLoader);
|
|
201
|
-
}
|
|
202
|
-
return Promise.resolve(resourceLoader.get(url));
|
|
203
|
-
};
|
|
204
|
-
await resolveComponentResources(resolver);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
finalize() {
|
|
208
|
-
// One last compile
|
|
209
|
-
this.compileTypesSync();
|
|
210
|
-
// Create the testing module itself.
|
|
211
|
-
this.compileTestModule();
|
|
212
|
-
this.applyTransitiveScopes();
|
|
213
|
-
this.applyProviderOverrides();
|
|
214
|
-
// Patch previously stored `styles` Component values (taken from ɵcmp), in case these
|
|
215
|
-
// Components have `styleUrls` fields defined and template override was requested.
|
|
216
|
-
this.patchComponentsWithExistingStyles();
|
|
217
|
-
// Clear the componentToModuleScope map, so that future compilations don't reset the scope of
|
|
218
|
-
// every component.
|
|
219
|
-
this.componentToModuleScope.clear();
|
|
220
|
-
const parentInjector = this.platform.injector;
|
|
221
|
-
this.testModuleRef = new NgModuleRef(this.testModuleType, parentInjector, []);
|
|
222
|
-
// ApplicationInitStatus.runInitializers() is marked @internal to core.
|
|
223
|
-
// Cast it to any before accessing it.
|
|
224
|
-
this.testModuleRef.injector.get(ApplicationInitStatus).runInitializers();
|
|
225
|
-
// Set locale ID after running app initializers, since locale information might be updated while
|
|
226
|
-
// running initializers. This is also consistent with the execution order while bootstrapping an
|
|
227
|
-
// app (see `packages/core/src/application_ref.ts` file).
|
|
228
|
-
const localeId = this.testModuleRef.injector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
|
|
229
|
-
setLocaleId(localeId);
|
|
230
|
-
return this.testModuleRef;
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* @internal
|
|
234
|
-
*/
|
|
235
|
-
_compileNgModuleSync(moduleType) {
|
|
236
|
-
this.queueTypesFromModulesArray([moduleType]);
|
|
237
|
-
this.compileTypesSync();
|
|
238
|
-
this.applyProviderOverrides();
|
|
239
|
-
this.applyProviderOverridesInScope(moduleType);
|
|
240
|
-
this.applyTransitiveScopes();
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* @internal
|
|
244
|
-
*/
|
|
245
|
-
async _compileNgModuleAsync(moduleType) {
|
|
246
|
-
this.queueTypesFromModulesArray([moduleType]);
|
|
247
|
-
await this.compileComponents();
|
|
248
|
-
this.applyProviderOverrides();
|
|
249
|
-
this.applyProviderOverridesInScope(moduleType);
|
|
250
|
-
this.applyTransitiveScopes();
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* @internal
|
|
254
|
-
*/
|
|
255
|
-
_getModuleResolver() {
|
|
256
|
-
return this.resolvers.module;
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* @internal
|
|
260
|
-
*/
|
|
261
|
-
_getComponentFactories(moduleType) {
|
|
262
|
-
return maybeUnwrapFn(moduleType.ɵmod.declarations).reduce((factories, declaration) => {
|
|
263
|
-
const componentDef = declaration.ɵcmp;
|
|
264
|
-
componentDef && factories.push(new ComponentFactory(componentDef, this.testModuleRef));
|
|
265
|
-
return factories;
|
|
266
|
-
}, []);
|
|
267
|
-
}
|
|
268
|
-
compileTypesSync() {
|
|
269
|
-
// Compile all queued components, directives, pipes.
|
|
270
|
-
let needsAsyncResources = false;
|
|
271
|
-
this.pendingComponents.forEach(declaration => {
|
|
272
|
-
needsAsyncResources = needsAsyncResources || isComponentDefPendingResolution(declaration);
|
|
273
|
-
const metadata = this.resolvers.component.resolve(declaration);
|
|
274
|
-
if (metadata === null) {
|
|
275
|
-
throw invalidTypeError(declaration.name, 'Component');
|
|
276
|
-
}
|
|
277
|
-
this.maybeStoreNgDef(NG_COMP_DEF, declaration);
|
|
278
|
-
compileComponent(declaration, metadata);
|
|
279
|
-
});
|
|
280
|
-
this.pendingComponents.clear();
|
|
281
|
-
this.pendingDirectives.forEach(declaration => {
|
|
282
|
-
const metadata = this.resolvers.directive.resolve(declaration);
|
|
283
|
-
if (metadata === null) {
|
|
284
|
-
throw invalidTypeError(declaration.name, 'Directive');
|
|
285
|
-
}
|
|
286
|
-
this.maybeStoreNgDef(NG_DIR_DEF, declaration);
|
|
287
|
-
compileDirective(declaration, metadata);
|
|
288
|
-
});
|
|
289
|
-
this.pendingDirectives.clear();
|
|
290
|
-
this.pendingPipes.forEach(declaration => {
|
|
291
|
-
const metadata = this.resolvers.pipe.resolve(declaration);
|
|
292
|
-
if (metadata === null) {
|
|
293
|
-
throw invalidTypeError(declaration.name, 'Pipe');
|
|
294
|
-
}
|
|
295
|
-
this.maybeStoreNgDef(NG_PIPE_DEF, declaration);
|
|
296
|
-
compilePipe(declaration, metadata);
|
|
297
|
-
});
|
|
298
|
-
this.pendingPipes.clear();
|
|
299
|
-
return needsAsyncResources;
|
|
300
|
-
}
|
|
301
|
-
applyTransitiveScopes() {
|
|
302
|
-
if (this.overriddenModules.size > 0) {
|
|
303
|
-
// Module overrides (via `TestBed.overrideModule`) might affect scopes that were previously
|
|
304
|
-
// calculated and stored in `transitiveCompileScopes`. If module overrides are present,
|
|
305
|
-
// collect all affected modules and reset scopes to force their re-calculation.
|
|
306
|
-
const testingModuleDef = this.testModuleType[NG_MOD_DEF];
|
|
307
|
-
const affectedModules = this.collectModulesAffectedByOverrides(testingModuleDef.imports);
|
|
308
|
-
if (affectedModules.size > 0) {
|
|
309
|
-
affectedModules.forEach(moduleType => {
|
|
310
|
-
this.storeFieldOfDefOnType(moduleType, NG_MOD_DEF, 'transitiveCompileScopes');
|
|
311
|
-
moduleType[NG_MOD_DEF].transitiveCompileScopes = null;
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
const moduleToScope = new Map();
|
|
316
|
-
const getScopeOfModule = (moduleType) => {
|
|
317
|
-
if (!moduleToScope.has(moduleType)) {
|
|
318
|
-
const isTestingModule = isTestingModuleOverride(moduleType);
|
|
319
|
-
const realType = isTestingModule ? this.testModuleType : moduleType;
|
|
320
|
-
moduleToScope.set(moduleType, transitiveScopesFor(realType));
|
|
321
|
-
}
|
|
322
|
-
return moduleToScope.get(moduleType);
|
|
323
|
-
};
|
|
324
|
-
this.componentToModuleScope.forEach((moduleType, componentType) => {
|
|
325
|
-
const moduleScope = getScopeOfModule(moduleType);
|
|
326
|
-
this.storeFieldOfDefOnType(componentType, NG_COMP_DEF, 'directiveDefs');
|
|
327
|
-
this.storeFieldOfDefOnType(componentType, NG_COMP_DEF, 'pipeDefs');
|
|
328
|
-
// `tView` that is stored on component def contains information about directives and pipes
|
|
329
|
-
// that are in the scope of this component. Patching component scope will cause `tView` to be
|
|
330
|
-
// changed. Store original `tView` before patching scope, so the `tView` (including scope
|
|
331
|
-
// information) is restored back to its previous/original state before running next test.
|
|
332
|
-
this.storeFieldOfDefOnType(componentType, NG_COMP_DEF, 'tView');
|
|
333
|
-
patchComponentDefWithScope(componentType.ɵcmp, moduleScope);
|
|
334
|
-
});
|
|
335
|
-
this.componentToModuleScope.clear();
|
|
336
|
-
}
|
|
337
|
-
applyProviderOverrides() {
|
|
338
|
-
const maybeApplyOverrides = (field) => (type) => {
|
|
339
|
-
const resolver = field === NG_COMP_DEF ? this.resolvers.component : this.resolvers.directive;
|
|
340
|
-
const metadata = resolver.resolve(type);
|
|
341
|
-
if (this.hasProviderOverrides(metadata.providers)) {
|
|
342
|
-
this.patchDefWithProviderOverrides(type, field);
|
|
343
|
-
}
|
|
344
|
-
};
|
|
345
|
-
this.seenComponents.forEach(maybeApplyOverrides(NG_COMP_DEF));
|
|
346
|
-
this.seenDirectives.forEach(maybeApplyOverrides(NG_DIR_DEF));
|
|
347
|
-
this.seenComponents.clear();
|
|
348
|
-
this.seenDirectives.clear();
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Applies provider overrides to a given type (either an NgModule or a standalone component)
|
|
352
|
-
* and all imported NgModules and standalone components recursively.
|
|
353
|
-
*/
|
|
354
|
-
applyProviderOverridesInScope(type) {
|
|
355
|
-
const hasScope = isStandaloneComponent(type) || isNgModule(type);
|
|
356
|
-
// The function can be re-entered recursively while inspecting dependencies
|
|
357
|
-
// of an NgModule or a standalone component. Exit early if we come across a
|
|
358
|
-
// type that can not have a scope (directive or pipe) or the type is already
|
|
359
|
-
// processed earlier.
|
|
360
|
-
if (!hasScope || this.scopesWithOverriddenProviders.has(type)) {
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
this.scopesWithOverriddenProviders.add(type);
|
|
364
|
-
// NOTE: the line below triggers JIT compilation of the module injector,
|
|
365
|
-
// which also invokes verification of the NgModule semantics, which produces
|
|
366
|
-
// detailed error messages. The fact that the code relies on this line being
|
|
367
|
-
// present here is suspicious and should be refactored in a way that the line
|
|
368
|
-
// below can be moved (for ex. after an early exit check below).
|
|
369
|
-
const injectorDef = type[NG_INJ_DEF];
|
|
370
|
-
// No provider overrides, exit early.
|
|
371
|
-
if (this.providerOverridesByToken.size === 0)
|
|
372
|
-
return;
|
|
373
|
-
if (isStandaloneComponent(type)) {
|
|
374
|
-
// Visit all component dependencies and override providers there.
|
|
375
|
-
const def = getComponentDef(type);
|
|
376
|
-
const dependencies = maybeUnwrapFn(def.dependencies ?? []);
|
|
377
|
-
for (const dependency of dependencies) {
|
|
378
|
-
this.applyProviderOverridesInScope(dependency);
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
else {
|
|
382
|
-
const providers = [
|
|
383
|
-
...injectorDef.providers,
|
|
384
|
-
...(this.providerOverridesByModule.get(type) || [])
|
|
385
|
-
];
|
|
386
|
-
if (this.hasProviderOverrides(providers)) {
|
|
387
|
-
this.maybeStoreNgDef(NG_INJ_DEF, type);
|
|
388
|
-
this.storeFieldOfDefOnType(type, NG_INJ_DEF, 'providers');
|
|
389
|
-
injectorDef.providers = this.getOverriddenProviders(providers);
|
|
390
|
-
}
|
|
391
|
-
// Apply provider overrides to imported modules recursively
|
|
392
|
-
const moduleDef = type[NG_MOD_DEF];
|
|
393
|
-
const imports = maybeUnwrapFn(moduleDef.imports);
|
|
394
|
-
for (const importedModule of imports) {
|
|
395
|
-
this.applyProviderOverridesInScope(importedModule);
|
|
396
|
-
}
|
|
397
|
-
// Also override the providers on any ModuleWithProviders imports since those don't appear in
|
|
398
|
-
// the moduleDef.
|
|
399
|
-
for (const importedModule of flatten(injectorDef.imports)) {
|
|
400
|
-
if (isModuleWithProviders(importedModule)) {
|
|
401
|
-
this.defCleanupOps.push({
|
|
402
|
-
object: importedModule,
|
|
403
|
-
fieldName: 'providers',
|
|
404
|
-
originalValue: importedModule.providers
|
|
405
|
-
});
|
|
406
|
-
importedModule.providers = this.getOverriddenProviders(importedModule.providers);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
patchComponentsWithExistingStyles() {
|
|
412
|
-
this.existingComponentStyles.forEach((styles, type) => type[NG_COMP_DEF].styles = styles);
|
|
413
|
-
this.existingComponentStyles.clear();
|
|
414
|
-
}
|
|
415
|
-
queueTypeArray(arr, moduleType) {
|
|
416
|
-
for (const value of arr) {
|
|
417
|
-
if (Array.isArray(value)) {
|
|
418
|
-
this.queueTypeArray(value, moduleType);
|
|
419
|
-
}
|
|
420
|
-
else {
|
|
421
|
-
this.queueType(value, moduleType);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
recompileNgModule(ngModule, metadata) {
|
|
426
|
-
// Cache the initial ngModuleDef as it will be overwritten.
|
|
427
|
-
this.maybeStoreNgDef(NG_MOD_DEF, ngModule);
|
|
428
|
-
this.maybeStoreNgDef(NG_INJ_DEF, ngModule);
|
|
429
|
-
compileNgModuleDefs(ngModule, metadata);
|
|
430
|
-
}
|
|
431
|
-
queueType(type, moduleType) {
|
|
432
|
-
const component = this.resolvers.component.resolve(type);
|
|
433
|
-
if (component) {
|
|
434
|
-
// Check whether a give Type has respective NG def (ɵcmp) and compile if def is
|
|
435
|
-
// missing. That might happen in case a class without any Angular decorators extends another
|
|
436
|
-
// class where Component/Directive/Pipe decorator is defined.
|
|
437
|
-
if (isComponentDefPendingResolution(type) || !type.hasOwnProperty(NG_COMP_DEF)) {
|
|
438
|
-
this.pendingComponents.add(type);
|
|
439
|
-
}
|
|
440
|
-
this.seenComponents.add(type);
|
|
441
|
-
// Keep track of the module which declares this component, so later the component's scope
|
|
442
|
-
// can be set correctly. If the component has already been recorded here, then one of several
|
|
443
|
-
// cases is true:
|
|
444
|
-
// * the module containing the component was imported multiple times (common).
|
|
445
|
-
// * the component is declared in multiple modules (which is an error).
|
|
446
|
-
// * the component was in 'declarations' of the testing module, and also in an imported module
|
|
447
|
-
// in which case the module scope will be TestingModuleOverride.DECLARATION.
|
|
448
|
-
// * overrideTemplateUsingTestingModule was called for the component in which case the module
|
|
449
|
-
// scope will be TestingModuleOverride.OVERRIDE_TEMPLATE.
|
|
450
|
-
//
|
|
451
|
-
// If the component was previously in the testing module's 'declarations' (meaning the
|
|
452
|
-
// current value is TestingModuleOverride.DECLARATION), then `moduleType` is the component's
|
|
453
|
-
// real module, which was imported. This pattern is understood to mean that the component
|
|
454
|
-
// should use its original scope, but that the testing module should also contain the
|
|
455
|
-
// component in its scope.
|
|
456
|
-
//
|
|
457
|
-
// Note: standalone components have no associated NgModule, so the `moduleType` can be `null`.
|
|
458
|
-
if (moduleType !== null &&
|
|
459
|
-
(!this.componentToModuleScope.has(type) ||
|
|
460
|
-
this.componentToModuleScope.get(type) === TestingModuleOverride.DECLARATION)) {
|
|
461
|
-
this.componentToModuleScope.set(type, moduleType);
|
|
462
|
-
}
|
|
463
|
-
return;
|
|
464
|
-
}
|
|
465
|
-
const directive = this.resolvers.directive.resolve(type);
|
|
466
|
-
if (directive) {
|
|
467
|
-
if (!type.hasOwnProperty(NG_DIR_DEF)) {
|
|
468
|
-
this.pendingDirectives.add(type);
|
|
469
|
-
}
|
|
470
|
-
this.seenDirectives.add(type);
|
|
471
|
-
return;
|
|
472
|
-
}
|
|
473
|
-
const pipe = this.resolvers.pipe.resolve(type);
|
|
474
|
-
if (pipe && !type.hasOwnProperty(NG_PIPE_DEF)) {
|
|
475
|
-
this.pendingPipes.add(type);
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
queueTypesFromModulesArray(arr) {
|
|
480
|
-
// Because we may encounter the same NgModule while processing the imports and exports of an
|
|
481
|
-
// NgModule tree, we cache them in this set so we can skip ones that have already been seen
|
|
482
|
-
// encountered. In some test setups, this caching resulted in 10X runtime improvement.
|
|
483
|
-
const processedNgModuleDefs = new Set();
|
|
484
|
-
const queueTypesFromModulesArrayRecur = (arr) => {
|
|
485
|
-
for (const value of arr) {
|
|
486
|
-
if (Array.isArray(value)) {
|
|
487
|
-
queueTypesFromModulesArrayRecur(value);
|
|
488
|
-
}
|
|
489
|
-
else if (hasNgModuleDef(value)) {
|
|
490
|
-
const def = value.ɵmod;
|
|
491
|
-
if (processedNgModuleDefs.has(def)) {
|
|
492
|
-
continue;
|
|
493
|
-
}
|
|
494
|
-
processedNgModuleDefs.add(def);
|
|
495
|
-
// Look through declarations, imports, and exports, and queue
|
|
496
|
-
// everything found there.
|
|
497
|
-
this.queueTypeArray(maybeUnwrapFn(def.declarations), value);
|
|
498
|
-
queueTypesFromModulesArrayRecur(maybeUnwrapFn(def.imports));
|
|
499
|
-
queueTypesFromModulesArrayRecur(maybeUnwrapFn(def.exports));
|
|
500
|
-
}
|
|
501
|
-
else if (isModuleWithProviders(value)) {
|
|
502
|
-
queueTypesFromModulesArrayRecur([value.ngModule]);
|
|
503
|
-
}
|
|
504
|
-
else if (isStandaloneComponent(value)) {
|
|
505
|
-
this.queueType(value, null);
|
|
506
|
-
const def = getComponentDef(value);
|
|
507
|
-
const dependencies = maybeUnwrapFn(def.dependencies ?? []);
|
|
508
|
-
dependencies.forEach((dependency) => {
|
|
509
|
-
// Note: in AOT, the `dependencies` might also contain regular
|
|
510
|
-
// (NgModule-based) Component, Directive and Pipes, so we handle
|
|
511
|
-
// them separately and proceed with recursive process for standalone
|
|
512
|
-
// Components and NgModules only.
|
|
513
|
-
if (isStandaloneComponent(dependency) || hasNgModuleDef(dependency)) {
|
|
514
|
-
queueTypesFromModulesArrayRecur([dependency]);
|
|
515
|
-
}
|
|
516
|
-
else {
|
|
517
|
-
this.queueType(dependency, null);
|
|
518
|
-
}
|
|
519
|
-
});
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
};
|
|
523
|
-
queueTypesFromModulesArrayRecur(arr);
|
|
524
|
-
}
|
|
525
|
-
// When module overrides (via `TestBed.overrideModule`) are present, it might affect all modules
|
|
526
|
-
// that import (even transitively) an overridden one. For all affected modules we need to
|
|
527
|
-
// recalculate their scopes for a given test run and restore original scopes at the end. The goal
|
|
528
|
-
// of this function is to collect all affected modules in a set for further processing. Example:
|
|
529
|
-
// if we have the following module hierarchy: A -> B -> C (where `->` means `imports`) and module
|
|
530
|
-
// `C` is overridden, we consider `A` and `B` as affected, since their scopes might become
|
|
531
|
-
// invalidated with the override.
|
|
532
|
-
collectModulesAffectedByOverrides(arr) {
|
|
533
|
-
const seenModules = new Set();
|
|
534
|
-
const affectedModules = new Set();
|
|
535
|
-
const calcAffectedModulesRecur = (arr, path) => {
|
|
536
|
-
for (const value of arr) {
|
|
537
|
-
if (Array.isArray(value)) {
|
|
538
|
-
// If the value is an array, just flatten it (by invoking this function recursively),
|
|
539
|
-
// keeping "path" the same.
|
|
540
|
-
calcAffectedModulesRecur(value, path);
|
|
541
|
-
}
|
|
542
|
-
else if (hasNgModuleDef(value)) {
|
|
543
|
-
if (seenModules.has(value)) {
|
|
544
|
-
// If we've seen this module before and it's included into "affected modules" list, mark
|
|
545
|
-
// the whole path that leads to that module as affected, but do not descend into its
|
|
546
|
-
// imports, since we already examined them before.
|
|
547
|
-
if (affectedModules.has(value)) {
|
|
548
|
-
path.forEach(item => affectedModules.add(item));
|
|
549
|
-
}
|
|
550
|
-
continue;
|
|
551
|
-
}
|
|
552
|
-
seenModules.add(value);
|
|
553
|
-
if (this.overriddenModules.has(value)) {
|
|
554
|
-
path.forEach(item => affectedModules.add(item));
|
|
555
|
-
}
|
|
556
|
-
// Examine module imports recursively to look for overridden modules.
|
|
557
|
-
const moduleDef = value[NG_MOD_DEF];
|
|
558
|
-
calcAffectedModulesRecur(maybeUnwrapFn(moduleDef.imports), path.concat(value));
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
};
|
|
562
|
-
calcAffectedModulesRecur(arr, []);
|
|
563
|
-
return affectedModules;
|
|
564
|
-
}
|
|
565
|
-
/**
|
|
566
|
-
* Preserve an original def (such as ɵmod, ɵinj, etc) before applying an override.
|
|
567
|
-
* Note: one class may have multiple defs (for example: ɵmod and ɵinj in case of
|
|
568
|
-
* an NgModule). If there is a def in a set already, don't override it, since
|
|
569
|
-
* an original one should be restored at the end of a test.
|
|
570
|
-
*/
|
|
571
|
-
maybeStoreNgDef(prop, type) {
|
|
572
|
-
if (!this.initialNgDefs.has(type)) {
|
|
573
|
-
this.initialNgDefs.set(type, new Map());
|
|
574
|
-
}
|
|
575
|
-
const currentDefs = this.initialNgDefs.get(type);
|
|
576
|
-
if (!currentDefs.has(prop)) {
|
|
577
|
-
const currentDef = Object.getOwnPropertyDescriptor(type, prop);
|
|
578
|
-
currentDefs.set(prop, currentDef);
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
storeFieldOfDefOnType(type, defField, fieldName) {
|
|
582
|
-
const def = type[defField];
|
|
583
|
-
const originalValue = def[fieldName];
|
|
584
|
-
this.defCleanupOps.push({ object: def, fieldName, originalValue });
|
|
585
|
-
}
|
|
586
|
-
/**
|
|
587
|
-
* Clears current components resolution queue, but stores the state of the queue, so we can
|
|
588
|
-
* restore it later. Clearing the queue is required before we try to compile components (via
|
|
589
|
-
* `TestBed.compileComponents`), so that component defs are in sync with the resolution queue.
|
|
590
|
-
*/
|
|
591
|
-
clearComponentResolutionQueue() {
|
|
592
|
-
if (this.originalComponentResolutionQueue === null) {
|
|
593
|
-
this.originalComponentResolutionQueue = new Map();
|
|
594
|
-
}
|
|
595
|
-
clearResolutionOfComponentResourcesQueue().forEach((value, key) => this.originalComponentResolutionQueue.set(key, value));
|
|
596
|
-
}
|
|
597
|
-
/*
|
|
598
|
-
* Restores component resolution queue to the previously saved state. This operation is performed
|
|
599
|
-
* as a part of restoring the state after completion of the current set of tests (that might
|
|
600
|
-
* potentially mutate the state).
|
|
601
|
-
*/
|
|
602
|
-
restoreComponentResolutionQueue() {
|
|
603
|
-
if (this.originalComponentResolutionQueue !== null) {
|
|
604
|
-
restoreComponentResolutionQueue(this.originalComponentResolutionQueue);
|
|
605
|
-
this.originalComponentResolutionQueue = null;
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
restoreOriginalState() {
|
|
609
|
-
// Process cleanup ops in reverse order so the field's original value is restored correctly (in
|
|
610
|
-
// case there were multiple overrides for the same field).
|
|
611
|
-
forEachRight(this.defCleanupOps, (op) => {
|
|
612
|
-
op.object[op.fieldName] = op.originalValue;
|
|
613
|
-
});
|
|
614
|
-
// Restore initial component/directive/pipe defs
|
|
615
|
-
this.initialNgDefs.forEach((defs, type) => {
|
|
616
|
-
defs.forEach((descriptor, prop) => {
|
|
617
|
-
if (!descriptor) {
|
|
618
|
-
// Delete operations are generally undesirable since they have performance
|
|
619
|
-
// implications on objects they were applied to. In this particular case, situations
|
|
620
|
-
// where this code is invoked should be quite rare to cause any noticeable impact,
|
|
621
|
-
// since it's applied only to some test cases (for example when class with no
|
|
622
|
-
// annotations extends some @Component) when we need to clear 'ɵcmp' field on a given
|
|
623
|
-
// class to restore its original state (before applying overrides and running tests).
|
|
624
|
-
delete type[prop];
|
|
625
|
-
}
|
|
626
|
-
else {
|
|
627
|
-
Object.defineProperty(type, prop, descriptor);
|
|
628
|
-
}
|
|
629
|
-
});
|
|
630
|
-
});
|
|
631
|
-
this.initialNgDefs.clear();
|
|
632
|
-
this.scopesWithOverriddenProviders.clear();
|
|
633
|
-
this.restoreComponentResolutionQueue();
|
|
634
|
-
// Restore the locale ID to the default value, this shouldn't be necessary but we never know
|
|
635
|
-
setLocaleId(DEFAULT_LOCALE_ID);
|
|
636
|
-
}
|
|
637
|
-
compileTestModule() {
|
|
638
|
-
class RootScopeModule {
|
|
639
|
-
}
|
|
640
|
-
compileNgModuleDefs(RootScopeModule, {
|
|
641
|
-
providers: [...this.rootProviderOverrides],
|
|
642
|
-
});
|
|
643
|
-
const ngZone = new NgZone({ enableLongStackTrace: true });
|
|
644
|
-
const providers = [
|
|
645
|
-
provideNgZoneChangeDetection(ngZone),
|
|
646
|
-
{ provide: Compiler, useFactory: () => new R3TestCompiler(this) },
|
|
647
|
-
...this.providers,
|
|
648
|
-
...this.providerOverrides,
|
|
649
|
-
];
|
|
650
|
-
const imports = [RootScopeModule, this.additionalModuleTypes, this.imports || []];
|
|
651
|
-
// clang-format off
|
|
652
|
-
compileNgModuleDefs(this.testModuleType, {
|
|
653
|
-
declarations: this.declarations,
|
|
654
|
-
imports,
|
|
655
|
-
schemas: this.schemas,
|
|
656
|
-
providers,
|
|
657
|
-
}, /* allowDuplicateDeclarationsInRoot */ true);
|
|
658
|
-
// clang-format on
|
|
659
|
-
this.applyProviderOverridesInScope(this.testModuleType);
|
|
660
|
-
}
|
|
661
|
-
get injector() {
|
|
662
|
-
if (this._injector !== null) {
|
|
663
|
-
return this._injector;
|
|
664
|
-
}
|
|
665
|
-
const providers = [];
|
|
666
|
-
const compilerOptions = this.platform.injector.get(COMPILER_OPTIONS);
|
|
667
|
-
compilerOptions.forEach(opts => {
|
|
668
|
-
if (opts.providers) {
|
|
669
|
-
providers.push(opts.providers);
|
|
670
|
-
}
|
|
671
|
-
});
|
|
672
|
-
if (this.compilerProviders !== null) {
|
|
673
|
-
providers.push(...this.compilerProviders);
|
|
674
|
-
}
|
|
675
|
-
// TODO(ocombe): make this work with an Injector directly instead of creating a module for it
|
|
676
|
-
class CompilerModule {
|
|
677
|
-
}
|
|
678
|
-
compileNgModuleDefs(CompilerModule, { providers });
|
|
679
|
-
const CompilerModuleFactory = new R3NgModuleFactory(CompilerModule);
|
|
680
|
-
this._injector = CompilerModuleFactory.create(this.platform.injector).injector;
|
|
681
|
-
return this._injector;
|
|
682
|
-
}
|
|
683
|
-
// get overrides for a specific provider (if any)
|
|
684
|
-
getSingleProviderOverrides(provider) {
|
|
685
|
-
const token = getProviderToken(provider);
|
|
686
|
-
return this.providerOverridesByToken.get(token) || null;
|
|
687
|
-
}
|
|
688
|
-
getProviderOverrides(providers) {
|
|
689
|
-
if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
|
|
690
|
-
return [];
|
|
691
|
-
// There are two flattening operations here. The inner flattenProviders() operates on the
|
|
692
|
-
// metadata's providers and applies a mapping function which retrieves overrides for each
|
|
693
|
-
// incoming provider. The outer flatten() then flattens the produced overrides array. If this is
|
|
694
|
-
// not done, the array can contain other empty arrays (e.g. `[[], []]`) which leak into the
|
|
695
|
-
// providers array and contaminate any error messages that might be generated.
|
|
696
|
-
return flatten(flattenProviders(providers, (provider) => this.getSingleProviderOverrides(provider) || []));
|
|
697
|
-
}
|
|
698
|
-
getOverriddenProviders(providers) {
|
|
699
|
-
if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
|
|
700
|
-
return [];
|
|
701
|
-
const flattenedProviders = flattenProviders(providers);
|
|
702
|
-
const overrides = this.getProviderOverrides(flattenedProviders);
|
|
703
|
-
const overriddenProviders = [...flattenedProviders, ...overrides];
|
|
704
|
-
const final = [];
|
|
705
|
-
const seenOverriddenProviders = new Set();
|
|
706
|
-
// We iterate through the list of providers in reverse order to make sure provider overrides
|
|
707
|
-
// take precedence over the values defined in provider list. We also filter out all providers
|
|
708
|
-
// that have overrides, keeping overridden values only. This is needed, since presence of a
|
|
709
|
-
// provider with `ngOnDestroy` hook will cause this hook to be registered and invoked later.
|
|
710
|
-
forEachRight(overriddenProviders, (provider) => {
|
|
711
|
-
const token = getProviderToken(provider);
|
|
712
|
-
if (this.providerOverridesByToken.has(token)) {
|
|
713
|
-
if (!seenOverriddenProviders.has(token)) {
|
|
714
|
-
seenOverriddenProviders.add(token);
|
|
715
|
-
// Treat all overridden providers as `{multi: false}` (even if it's a multi-provider) to
|
|
716
|
-
// make sure that provided override takes highest precedence and is not combined with
|
|
717
|
-
// other instances of the same multi provider.
|
|
718
|
-
final.unshift({ ...provider, multi: false });
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
else {
|
|
722
|
-
final.unshift(provider);
|
|
723
|
-
}
|
|
724
|
-
});
|
|
725
|
-
return final;
|
|
726
|
-
}
|
|
727
|
-
hasProviderOverrides(providers) {
|
|
728
|
-
return this.getProviderOverrides(providers).length > 0;
|
|
729
|
-
}
|
|
730
|
-
patchDefWithProviderOverrides(declaration, field) {
|
|
731
|
-
const def = declaration[field];
|
|
732
|
-
if (def && def.providersResolver) {
|
|
733
|
-
this.maybeStoreNgDef(field, declaration);
|
|
734
|
-
const resolver = def.providersResolver;
|
|
735
|
-
const processProvidersFn = (providers) => this.getOverriddenProviders(providers);
|
|
736
|
-
this.storeFieldOfDefOnType(declaration, field, 'providersResolver');
|
|
737
|
-
def.providersResolver = (ngDef) => resolver(ngDef, processProvidersFn);
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
function initResolvers() {
|
|
742
|
-
return {
|
|
743
|
-
module: new NgModuleResolver(),
|
|
744
|
-
component: new ComponentResolver(),
|
|
745
|
-
directive: new DirectiveResolver(),
|
|
746
|
-
pipe: new PipeResolver()
|
|
747
|
-
};
|
|
748
|
-
}
|
|
749
|
-
function isStandaloneComponent(value) {
|
|
750
|
-
const def = getComponentDef(value);
|
|
751
|
-
return !!def?.standalone;
|
|
752
|
-
}
|
|
753
|
-
function getComponentDef(value) {
|
|
754
|
-
return value.ɵcmp ?? null;
|
|
755
|
-
}
|
|
756
|
-
function hasNgModuleDef(value) {
|
|
757
|
-
return value.hasOwnProperty('ɵmod');
|
|
758
|
-
}
|
|
759
|
-
function isNgModule(value) {
|
|
760
|
-
return hasNgModuleDef(value);
|
|
761
|
-
}
|
|
762
|
-
function maybeUnwrapFn(maybeFn) {
|
|
763
|
-
return maybeFn instanceof Function ? maybeFn() : maybeFn;
|
|
764
|
-
}
|
|
765
|
-
function flatten(values) {
|
|
766
|
-
const out = [];
|
|
767
|
-
values.forEach(value => {
|
|
768
|
-
if (Array.isArray(value)) {
|
|
769
|
-
out.push(...flatten(value));
|
|
770
|
-
}
|
|
771
|
-
else {
|
|
772
|
-
out.push(value);
|
|
773
|
-
}
|
|
774
|
-
});
|
|
775
|
-
return out;
|
|
776
|
-
}
|
|
777
|
-
function identityFn(value) {
|
|
778
|
-
return value;
|
|
779
|
-
}
|
|
780
|
-
function flattenProviders(providers, mapFn = identityFn) {
|
|
781
|
-
const out = [];
|
|
782
|
-
for (let provider of providers) {
|
|
783
|
-
if (isEnvironmentProviders(provider)) {
|
|
784
|
-
provider = provider.ɵproviders;
|
|
785
|
-
}
|
|
786
|
-
if (Array.isArray(provider)) {
|
|
787
|
-
out.push(...flattenProviders(provider, mapFn));
|
|
788
|
-
}
|
|
789
|
-
else {
|
|
790
|
-
out.push(mapFn(provider));
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
return out;
|
|
794
|
-
}
|
|
795
|
-
function getProviderField(provider, field) {
|
|
796
|
-
return provider && typeof provider === 'object' && provider[field];
|
|
797
|
-
}
|
|
798
|
-
function getProviderToken(provider) {
|
|
799
|
-
return getProviderField(provider, 'provide') || provider;
|
|
800
|
-
}
|
|
801
|
-
function isModuleWithProviders(value) {
|
|
802
|
-
return value.hasOwnProperty('ngModule');
|
|
803
|
-
}
|
|
804
|
-
function forEachRight(values, fn) {
|
|
805
|
-
for (let idx = values.length - 1; idx >= 0; idx--) {
|
|
806
|
-
fn(values[idx], idx);
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
function invalidTypeError(name, expectedType) {
|
|
810
|
-
return new Error(`${name} class doesn't have @${expectedType} decorator or is missing metadata.`);
|
|
811
|
-
}
|
|
812
|
-
class R3TestCompiler {
|
|
813
|
-
constructor(testBed) {
|
|
814
|
-
this.testBed = testBed;
|
|
815
|
-
}
|
|
816
|
-
compileModuleSync(moduleType) {
|
|
817
|
-
this.testBed._compileNgModuleSync(moduleType);
|
|
818
|
-
return new R3NgModuleFactory(moduleType);
|
|
819
|
-
}
|
|
820
|
-
async compileModuleAsync(moduleType) {
|
|
821
|
-
await this.testBed._compileNgModuleAsync(moduleType);
|
|
822
|
-
return new R3NgModuleFactory(moduleType);
|
|
823
|
-
}
|
|
824
|
-
compileModuleAndAllComponentsSync(moduleType) {
|
|
825
|
-
const ngModuleFactory = this.compileModuleSync(moduleType);
|
|
826
|
-
const componentFactories = this.testBed._getComponentFactories(moduleType);
|
|
827
|
-
return new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
|
|
828
|
-
}
|
|
829
|
-
async compileModuleAndAllComponentsAsync(moduleType) {
|
|
830
|
-
const ngModuleFactory = await this.compileModuleAsync(moduleType);
|
|
831
|
-
const componentFactories = this.testBed._getComponentFactories(moduleType);
|
|
832
|
-
return new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
|
|
833
|
-
}
|
|
834
|
-
clearCache() { }
|
|
835
|
-
clearCacheFor(type) { }
|
|
836
|
-
getModuleId(moduleType) {
|
|
837
|
-
const meta = this.testBed._getModuleResolver().resolve(moduleType);
|
|
838
|
-
return meta && meta.id || undefined;
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdF9iZWRfY29tcGlsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3Rlc3Rpbmcvc3JjL3Rlc3RfYmVkX2NvbXBpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUNqRCxPQUFPLEVBQUMscUJBQXFCLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFnRCxTQUFTLEVBQUUsNEJBQTRCLEVBQWtELE1BQU0sRUFBK0IsaUJBQWlCLEVBQVEsaUJBQWlCLElBQUksZ0JBQWdCLEVBQUUsaUJBQWlCLElBQUksZ0JBQWdCLEVBQUUsb0JBQW9CLElBQUksbUJBQW1CLEVBQUUsWUFBWSxJQUFJLFdBQVcsRUFBRSxrQkFBa0IsSUFBSSxpQkFBaUIsRUFBaUMsaUJBQWlCLElBQUksZ0JBQWdCLEVBQWlFLHVCQUF1QixJQUFJLHNCQUFzQixFQUFFLFlBQVksSUFBSSxXQUFXLEVBQUUsV0FBVyxJQUFJLFVBQVUsRUFBRSxXQUFXLElBQUksVUFBVSxFQUFFLFdBQVcsSUFBSSxVQUFVLEVBQUUsWUFBWSxJQUFJLFdBQVcsRUFBRSxnQkFBZ0IsSUFBSSxpQkFBaUIsRUFBd0YsMkJBQTJCLElBQUksMEJBQTBCLEVBQUUsNkJBQTZCLElBQUksNEJBQTRCLEVBQUUsd0JBQXdCLElBQUksZ0JBQWdCLEVBQUUsbUJBQW1CLElBQUksV0FBVyxFQUFFLFlBQVksSUFBSSxXQUFXLEVBQUUsb0JBQW9CLElBQUksbUJBQW1CLEVBQW1ELE1BQU0sZUFBZSxDQUFDO0FBRTl0QyxPQUFPLEVBQUMsd0NBQXdDLEVBQUUsK0JBQStCLEVBQUUseUJBQXlCLEVBQUUsK0JBQStCLEVBQUMsTUFBTSxxQ0FBcUMsQ0FBQztBQUUxTCxPQUFPLEVBQUMscUNBQXFDLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUduRixPQUFP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cHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge1Jlc291cmNlTG9hZGVyfSBmcm9tICdAYW5ndWxhci9jb21waWxlcic7XG5pbXBvcnQge0FwcGxpY2F0aW9uSW5pdFN0YXR1cywgQ29tcGlsZXIsIENPTVBJTEVSX09QVElPTlMsIENvbXBvbmVudCwgRGlyZWN0aXZlLCBJbmplY3RvciwgSW5qZWN0b3JUeXBlLCBMT0NBTEVfSUQsIE1vZHVsZVdpdGhDb21wb25lbnRGYWN0b3JpZXMsIE1vZHVsZVdpdGhQcm92aWRlcnMsIE5nTW9kdWxlLCBOZ01vZHVsZUZhY3RvcnksIE5nWm9uZSwgUGlwZSwgUGxhdGZvcm1SZWYsIFByb3ZpZGVyLCByZXNvbHZlRm9yd2FyZFJlZiwgVHlwZSwgybVjb21waWxlQ29tcG9uZW50IGFzIGNvbXBpbGVDb21wb25lbnQsIMm1Y29tcGlsZURpcmVjdGl2ZSBhcyBjb21waWxlRGlyZWN0aXZlLCDJtWNvbXBpbGVOZ01vZHVsZURlZnMgYXMgY29tcGlsZU5nTW9kdWxlRGVmcywgybVjb21waWxlUGlwZSBhcyBjb21waWxlUGlwZSwgybVERUZBVUxUX0xPQ0FMRV9JRCBhcyBERUZBVUxUX0xPQ0FMRV9JRCwgybVEaXJlY3RpdmVEZWYgYXMgRGlyZWN0aXZlRGVmLCDJtWdldEluamVjdGFibGVEZWYgYXMgZ2V0SW5qZWN0YWJsZURlZiwgybVJbnRlcm5hbEVudmlyb25tZW50UHJvdmlkZXJzIGFzIEludGVybmFsRW52aXJvbm1lbnRQcm92aWRlcnMsIMm1aXNFbnZpcm9ubWVudFByb3ZpZGVycyBhcyBpc0Vudmlyb25tZW50UHJvdmlkZXJzLCDJtU5HX0NPTVBfREVGIGFzIE5HX0NPTVBfREVGLCDJtU5HX0RJUl9ERUYgYXMgTkdfRElSX0RFRiwgybVOR19JTkpfREVGIGFzIE5HX0lOSl9ERUYsIMm1TkdfTU9EX0RFRiBhcyBOR19NT0RfREVGLCDJtU5HX1BJUEVfREVGIGFzIE5HX1BJUEVfREVGLCDJtU5nTW9kdWxlRmFjdG9yeSBhcyBSM05nTW9kdWxlRmFjdG9yeSwgybVOZ01vZHVsZVRyYW5zaXRpdmVTY29wZXMgYXMgTmdNb2R1bGVUcmFuc2l0aXZlU2NvcGVzLCDJtU5nTW9kdWxlVHlwZSBhcyBOZ01vZHVsZVR5cGUsIMm1cGF0Y2hDb21wb25lbnREZWZXaXRoU2NvcGUgYXMgcGF0Y2hDb21wb25lbnREZWZXaXRoU2NvcGUsIMm1cHJvdmlkZU5nWm9uZUNoYW5nZURldGVjdGlvbiBhcyBwcm92aWRlTmdab25lQ2hhbmdlRGV0ZWN0aW9uLCDJtVJlbmRlcjNDb21wb25lbnRGYWN0b3J5IGFzIENvbXBvbmVudEZhY3RvcnksIMm1UmVuZGVyM05nTW9kdWxlUmVmIGFzIE5nTW9kdWxlUmVmLCDJtXNldExvY2FsZUlkIGFzIHNldExvY2FsZUlkLCDJtXRyYW5zaXRpdmVTY29wZXNGb3IgYXMgdHJhbnNpdGl2ZVNjb3Blc0ZvciwgybXJtUluamVjdGFibGVEZWNsYXJhdGlvbiBhcyBJbmplY3RhYmxlRGVjbGFyYXRpb259IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQge2NsZWFyUmVzb2x1dGlvbk9mQ29tcG9uZW50UmVzb3VyY2VzUXVldWUsIGlzQ29tcG9uZW50RGVmUGVuZGluZ1Jlc29sdXRpb24sIHJlc29sdmVDb21wb25lbnRSZXNvdXJjZXMsIHJlc3RvcmVDb21wb25lbnRSZXNvbHV0aW9uUXVldWV9IGZyb20gJy4uLy4uL3NyYy9tZXRhZGF0YS9yZXNvdXJjZV9sb2FkaW5nJztcbmltcG9ydCB7Q29tcG9uZW50RGVmLCBDb21wb25lbnRUeXBlfSBmcm9tICcuLi8uLi9zcmMvcmVuZGVyMyc7XG5pbXBvcnQge2dlbmVyYXRlU3RhbmRhbG9uZUluRGVjbGFyYXRpb25zRXJyb3J9IGZyb20gJy4uLy4uL3NyYy9yZW5kZXIzL2ppdC9tb2R1bGUnO1xuXG5pbXBvcnQge01ldGFkYXRhT3ZlcnJpZGV9IGZyb20gJy4vbWV0YWRhdGFfb3ZlcnJpZGUnO1xuaW1wb3J0IHtDb21wb25lbnRSZXNvbHZlciwgRGlyZWN0aXZlUmVzb2x2ZXIsIE5nTW9kdWxlUmVzb2x2ZXIsIFBpcGVSZXNvbHZlciwgUmVzb2x2ZXJ9IGZyb20gJy4vcmVzb2x2ZXJzJztcbmltcG9ydCB7VGVzdE1vZHVsZU1ldGFkYXRhfSBmcm9tICcuL3Rlc3RfYmVkX2NvbW1vbic7XG5cbmVudW0gVGVzdGluZ01vZHVsZU92ZXJyaWRlIHtcbiAgREVDTEFSQVRJT04sXG4gIE9WRVJSSURFX1RFTVBMQVRFLFxufVxuXG5mdW5jdGlvbiBpc1Rlc3RpbmdNb2R1bGVPdmVycmlkZSh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFRlc3RpbmdNb2R1bGVPdmVycmlkZSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gVGVzdGluZ01vZHVsZU92ZXJyaWRlLkRFQ0xBUkFUSU9OIHx8XG4gICAgICB2YWx1ZSA9PT0gVGVzdGluZ01vZHVsZU92ZXJyaWRlLk9WRVJSSURFX1RFTVBMQVRFO1xufVxuXG5mdW5jdGlvbiBhc3NlcnROb1N0YW5kYWxvbmVDb21wb25lbnRzKFxuICAgIHR5cGVzOiBUeXBlPGFueT5bXSwgcmVzb2x2ZXI6IFJlc29sdmVyPGFueT4sIGxvY2F0aW9uOiBzdHJpbmcpIHtcbiAgdHlwZXMuZm9yRWFjaCh0eXBlID0+IHtcbiAgICBjb25zdCBjb21wb25lbnQgPSByZXNvbHZlci5yZXNvbHZlKHR5cGUpO1xuICAgIGlmIChjb21wb25lbnQgJiYgY29tcG9uZW50LnN0YW5kYWxvbmUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihnZW5lcmF0ZVN0YW5kYWxvbmVJbkRlY2xhcmF0aW9uc0Vycm9yKHR5cGUsIGxvY2F0aW9uKSk7XG4gICAgfVxuICB9KTtcbn1cblxuLy8gUmVzb2x2ZXJzIGZvciBBbmd1bGFyIGRlY29yYXRvcnNcbnR5cGUgUmVzb2x2ZXJzID0ge1xuICBtb2R1bGU6IFJlc29sdmVyPE5nTW9kdWxlPixcbiAgY29tcG9uZW50OiBSZXNvbHZlcjxEaXJlY3RpdmU+LFxuICBkaXJlY3RpdmU6IFJlc29sdmVyPENvbXBvbmVudD4sXG4gIHBpcGU6IFJlc29sdmVyPFBpcGU+LFxufTtcblxuaW50ZXJmYWNlIENsZWFudXBPcGVyYXRpb24ge1xuICBmaWVsZE5hbWU6IHN0cmluZztcbiAgb2JqZWN0OiBhbnk7XG4gIG9yaWdpbmFsVmFsdWU6IHVua25vd247XG59XG5cbmV4cG9ydCBjbGFzcyBUZXN0QmVkQ29tcGlsZXIge1xuICBwcml2YXRlIG9yaWdpbmFsQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlOiBNYXA8VHlwZTxhbnk+LCBDb21wb25lbnQ+fG51bGwgPSBudWxsO1xuXG4gIC8vIFRlc3RpbmcgbW9kdWxlIGNvbmZpZ3VyYXRpb25cbiAgcHJpdmF0ZSBkZWNsYXJhdGlvbnM6IFR5cGU8YW55PltdID0gW107XG4gIHByaXZhdGUgaW1wb3J0czogVHlwZTxhbnk+W10gPSBbXTtcbiAgcHJpdmF0ZSBwcm92aWRlcnM6IFByb3ZpZGVyW10gPSBbXTtcbiAgcHJpdmF0ZSBzY2hlbWFzOiBhbnlbXSA9IFtdO1xuXG4gIC8vIFF1ZXVlcyBvZiBjb21wb25lbnRzL2RpcmVjdGl2ZXMvcGlwZXMgdGhhdCBzaG91bGQgYmUgcmVjb21waWxlZC5cbiAgcHJpdmF0ZSBwZW5kaW5nQ29tcG9uZW50cyA9IG5ldyBTZXQ8VHlwZTxhbnk+PigpO1xuICBwcml2YXRlIHBlbmRpbmdEaXJlY3RpdmVzID0gbmV3IFNldDxUeXBlPGFueT4+KCk7XG4gIHByaXZhdGUgcGVuZGluZ1BpcGVzID0gbmV3IFNldDxUeXBlPGFueT4+KCk7XG5cbiAgLy8gS2VlcCB0cmFjayBvZiBhbGwgY29tcG9uZW50cyBhbmQgZGlyZWN0aXZlcywgc28gd2UgY2FuIHBhdGNoIFByb3ZpZGVycyBvbnRvIGRlZnMgbGF0ZXIuXG4gIHByaXZhdGUgc2VlbkNvbXBvbmVudHMgPSBuZXcgU2V0PFR5cGU8YW55Pj4oKTtcbiAgcHJpdmF0ZSBzZWVuRGlyZWN0aXZlcyA9IG5ldyBTZXQ8VHlwZTxhbnk+PigpO1xuXG4gIC8vIEtlZXAgdHJhY2sgb2Ygb3ZlcnJpZGRlbiBtb2R1bGVzLCBzbyB0aGF0IHdlIGNhbiBjb2xsZWN0IGFsbCBhZmZlY3RlZCBvbmVzIGluIHRoZSBtb2R1bGUgdHJlZS5cbiAgcHJpdmF0ZSBvdmVycmlkZGVuTW9kdWxlcyA9IG5ldyBTZXQ8TmdNb2R1bGVUeXBlPGFueT4+KCk7XG5cbiAgLy8gU3RvcmUgcmVzb2x2ZWQgc3R5bGVzIGZvciBDb21wb25lbnRzIHRoYXQgaGF2ZSB0ZW1wbGF0ZSBvdmVycmlkZXMgcHJlc2VudCBhbmQgYHN0eWxlVXJsc2BcbiAgLy8gZGVmaW5lZCBhdCB0aGUgc2FtZSB0aW1lLlxuICBwcml2YXRlIGV4aXN0aW5nQ29tcG9uZW50U3R5bGVzID0gbmV3IE1hcDxUeXBlPGFueT4sIHN0cmluZ1tdPigpO1xuXG4gIHByaXZhdGUgcmVzb2x2ZXJzOiBSZXNvbHZlcnMgPSBpbml0UmVzb2x2ZXJzKCk7XG5cbiAgcHJpdmF0ZSBjb21wb25lbnRUb01vZHVsZVNjb3BlID0gbmV3IE1hcDxUeXBlPGFueT4sIFR5cGU8YW55PnxUZXN0aW5nTW9kdWxlT3ZlcnJpZGU+KCk7XG5cbiAgLy8gTWFwIHRoYXQga2VlcHMgaW5pdGlhbCB2ZXJzaW9uIG9mIGNvbXBvbmVudC9kaXJlY3RpdmUvcGlwZSBkZWZzIGluIGNhc2VcbiAgLy8gd2UgY29tcGlsZSBhIFR5cGUgYWdhaW4sIHRodXMgb3ZlcnJpZGluZyByZXNwZWN0aXZlIHN0YXRpYyBmaWVsZHMuIFRoaXMgaXNcbiAgLy8gcmVxdWlyZWQgdG8gbWFrZSBzdXJlIHdlIHJlc3RvcmUgZGVmcyB0byB0aGVpciBpbml0aWFsIHN0YXRlcyBiZXR3ZWVuIHRlc3QgcnVucy5cbiAgLy8gTm90ZTogb25lIGNsYXNzIG1heSBoYXZlIG11bHRpcGxlIGRlZnMgKGZvciBleGFtcGxlOiDJtW1vZCBhbmQgybVpbmogaW4gY2FzZSBvZiBhblxuICAvLyBOZ01vZHVsZSksIHN0b3JlIGFsbCBvZiB0aGVtIGluIGEgbWFwLlxuICBwcml2YXRlIGluaXRpYWxOZ0RlZnMgPSBuZXcgTWFwPFR5cGU8YW55PiwgTWFwPHN0cmluZywgUHJvcGVydHlEZXNjcmlwdG9yfHVuZGVmaW5lZD4+KCk7XG5cbiAgLy8gQXJyYXkgdGhhdCBrZWVwcyBjbGVhbnVwIG9wZXJhdGlvbnMgZm9yIGluaXRpYWwgdmVyc2lvbnMgb2YgY29tcG9uZW50L2RpcmVjdGl2ZS9waXBlL21vZHVsZVxuICAvLyBkZWZzIGluIGNhc2UgVGVzdEJlZCBtYWtlcyBjaGFuZ2VzIHRvIHRoZSBvcmlnaW5hbHMuXG4gIHByaXZhdGUgZGVmQ2xlYW51cE9wczogQ2xlYW51cE9wZXJhdGlvbltdID0gW107XG5cbiAgcHJpdmF0ZSBfaW5qZWN0b3I6IEluamVjdG9yfG51bGwgPSBudWxsO1xuICBwcml2YXRlIGNvbXBpbGVyUHJvdmlkZXJzOiBQcm92aWRlcltdfG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgcHJvdmlkZXJPdmVycmlkZXM6IFByb3ZpZGVyW10gPSBbXTtcbiAgcHJpdmF0ZSByb290UHJvdmlkZXJPdmVycmlkZXM6IFByb3ZpZGVyW10gPSBbXTtcbiAgLy8gT3ZlcnJpZGVzIGZvciBpbmplY3RhYmxlcyB3aXRoIGB7cHJvdmlkZWRJbjogU29tZU1vZHVsZX1gIG5lZWQgdG8gYmUgdHJhY2tlZCBhbmQgYWRkZWQgdG8gdGhhdFxuICAvLyBtb2R1bGUncyBwcm92aWRlciBsaXN0LlxuICBwcml2YXRlIHByb3ZpZGVyT3ZlcnJpZGVzQnlNb2R1bGUgPSBuZXcgTWFwPEluamVjdG9yVHlwZTxhbnk+LCBQcm92aWRlcltdPigpO1xuICBwcml2YXRlIHByb3ZpZGVyT3ZlcnJpZGVzQnlUb2tlbiA9IG5ldyBNYXA8YW55LCBQcm92aWRlcj4oKTtcbiAgcHJpdmF0ZSBzY29wZXNXaXRoT3ZlcnJpZGRlblByb3ZpZGVycyA9IG5ldyBTZXQ8VHlwZTxhbnk+PigpO1xuXG4gIHByaXZhdGUgdGVzdE1vZHVsZVR5cGU6IE5nTW9kdWxlVHlwZTxhbnk+O1xuICBwcml2YXRlIHRlc3RNb2R1bGVSZWY6IE5nTW9kdWxlUmVmPGFueT58bnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBwbGF0Zm9ybTogUGxhdGZvcm1SZWYsIHByaXZhdGUgYWRkaXRpb25hbE1vZHVsZVR5cGVzOiBUeXBlPGFueT58VHlwZTxhbnk+W10pIHtcbiAgICBjbGFzcyBEeW5hbWljVGVzdE1vZHVsZSB7fVxuICAgIHRoaXMudGVzdE1vZHVsZVR5cGUgPSBEeW5hbWljVGVzdE1vZHVsZSBhcyBhbnk7XG4gIH1cblxuICBzZXRDb21waWxlclByb3ZpZGVycyhwcm92aWRlcnM6IFByb3ZpZGVyW118bnVsbCk6IHZvaWQge1xuICAgIHRoaXMuY29tcGlsZXJQcm92aWRlcnMgPSBwcm92aWRlcnM7XG4gICAgdGhpcy5faW5qZWN0b3IgPSBudWxsO1xuICB9XG5cbiAgY29uZmlndXJlVGVzdGluZ01vZHVsZShtb2R1bGVEZWY6IFRlc3RNb2R1bGVNZXRhZGF0YSk6IHZvaWQge1xuICAgIC8vIEVucXVldWUgYW55IGNvbXBpbGF0aW9uIHRhc2tzIGZvciB0aGUgZGlyZWN0bHkgZGVjbGFyZWQgY29tcG9uZW50LlxuICAgIGlmIChtb2R1bGVEZWYuZGVjbGFyYXRpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIFZlcmlmeSB0aGF0IHRoZXJlIGFyZSBubyBzdGFuZGFsb25lIGNvbXBvbmVudHNcbiAgICAgIGFzc2VydE5vU3RhbmRhbG9uZUNvbXBvbmVudHMoXG4gICAgICAgICAgbW9kdWxlRGVmLmRlY2xhcmF0aW9ucywgdGhpcy5yZXNvbHZlcnMuY29tcG9uZW50LFxuICAgICAgICAgICdcIlRlc3RCZWQuY29uZmlndXJlVGVzdGluZ01vZHVsZVwiIGNhbGwnKTtcbiAgICAgIHRoaXMucXVldWVUeXBlQXJyYXkobW9kdWxlRGVmLmRlY2xhcmF0aW9ucywgVGVzdGluZ01vZHVsZU92ZXJyaWRlLkRFQ0xBUkFUSU9OKTtcbiAgICAgIHRoaXMuZGVjbGFyYXRpb25zLnB1c2goLi4ubW9kdWxlRGVmLmRlY2xhcmF0aW9ucyk7XG4gICAgfVxuXG4gICAgLy8gRW5xdWV1ZSBhbnkgY29tcGlsYXRpb24gdGFza3MgZm9yIGltcG9ydGVkIG1vZHVsZXMuXG4gICAgaWYgKG1vZHVsZURlZi5pbXBvcnRzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMucXVldWVUeXBlc0Zyb21Nb2R1bGVzQXJyYXkobW9kdWxlRGVmLmltcG9ydHMpO1xuICAgICAgdGhpcy5pbXBvcnRzLnB1c2goLi4ubW9kdWxlRGVmLmltcG9ydHMpO1xuICAgIH1cblxuICAgIGlmIChtb2R1bGVEZWYucHJvdmlkZXJzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMucHJvdmlkZXJzLnB1c2goLi4ubW9kdWxlRGVmLnByb3ZpZGVycyk7XG4gICAgfVxuXG4gICAgaWYgKG1vZHVsZURlZi5zY2hlbWFzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuc2NoZW1hcy5wdXNoKC4uLm1vZHVsZURlZi5zY2hlbWFzKTtcbiAgICB9XG4gIH1cblxuICBvdmVycmlkZU1vZHVsZShuZ01vZHVsZTogVHlwZTxhbnk+LCBvdmVycmlkZTogTWV0YWRhdGFPdmVycmlkZTxOZ01vZHVsZT4pOiB2b2lkIHtcbiAgICB0aGlzLm92ZXJyaWRkZW5Nb2R1bGVzLmFkZChuZ01vZHVsZSBhcyBOZ01vZHVsZVR5cGU8YW55Pik7XG5cbiAgICAvLyBDb21waWxlIHRoZSBtb2R1bGUgcmlnaHQgYXdheS5cbiAgICB0aGlzLnJlc29sdmVycy5tb2R1bGUuYWRkT3ZlcnJpZGUobmdNb2R1bGUsIG92ZXJyaWRlKTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMucmVzb2x2ZXJzLm1vZHVsZS5yZXNvbHZlKG5nTW9kdWxlKTtcbiAgICBpZiAobWV0YWRhdGEgPT09IG51bGwpIHtcbiAgICAgIHRocm93IGludmFsaWRUeXBlRXJyb3IobmdNb2R1bGUubmFtZSwgJ05nTW9kdWxlJyk7XG4gICAgfVxuXG4gICAgdGhpcy5yZWNvbXBpbGVOZ01vZHVsZShuZ01vZHVsZSwgbWV0YWRhdGEpO1xuXG4gICAgLy8gQXQgdGhpcyBwb2ludCwgdGhlIG1vZHVsZSBoYXMgYSB2YWxpZCBtb2R1bGUgZGVmICjJtW1vZCksIGJ1dCB0aGUgb3ZlcnJpZGUgbWF5IGhhdmUgaW50cm9kdWNlZFxuICAgIC8vIG5ldyBkZWNsYXJhdGlvbnMgb3IgaW1wb3J0ZWQgbW9kdWxlcy4gSW5nZXN0IGFueSBwb3NzaWJsZSBuZXcgdHlwZXMgYW5kIGFkZCB0aGVtIHRvIHRoZVxuICAgIC8vIGN1cnJlbnQgcXVldWUuXG4gICAgdGhpcy5xdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheShbbmdNb2R1bGVdKTtcbiAgfVxuXG4gIG92ZXJyaWRlQ29tcG9uZW50KGNvbXBvbmVudDogVHlwZTxhbnk+LCBvdmVycmlkZTogTWV0YWRhdGFPdmVycmlkZTxDb21wb25lbnQ+KTogdm9pZCB7XG4gICAgdGhpcy52ZXJpZnlOb1N0YW5kYWxvbmVGbGFnT3ZlcnJpZGVzKGNvbXBvbmVudCwgb3ZlcnJpZGUpO1xuICAgIHRoaXMucmVzb2x2ZXJzLmNvbXBvbmVudC5hZGRPdmVycmlkZShjb21wb25lbnQsIG92ZXJyaWRlKTtcbiAgICB0aGlzLnBlbmRpbmdDb21wb25lbnRzLmFkZChjb21wb25lbnQpO1xuICB9XG5cbiAgb3ZlcnJpZGVEaXJlY3RpdmUoZGlyZWN0aXZlOiBUeXBlPGFueT4sIG92ZXJyaWRlOiBNZXRhZGF0YU92ZXJyaWRlPERpcmVjdGl2ZT4pOiB2b2lkIHtcbiAgICB0aGlzLnZlcmlmeU5vU3RhbmRhbG9uZUZsYWdPdmVycmlkZXMoZGlyZWN0aXZlLCBvdmVycmlkZSk7XG4gICAgdGhpcy5yZXNvbHZlcnMuZGlyZWN0aXZlLmFkZE92ZXJyaWRlKGRpcmVjdGl2ZSwgb3ZlcnJpZGUpO1xuICAgIHRoaXMucGVuZGluZ0RpcmVjdGl2ZXMuYWRkKGRpcmVjdGl2ZSk7XG4gIH1cblxuICBvdmVycmlkZVBpcGUocGlwZTogVHlwZTxhbnk+LCBvdmVycmlkZTogTWV0YWRhdGFPdmVycmlkZTxQaXBlPik6IHZvaWQge1xuICAgIHRoaXMudmVyaWZ5Tm9TdGFuZGFsb25lRmxhZ092ZXJyaWRlcyhwaXBlLCBvdmVycmlkZSk7XG4gICAgdGhpcy5yZXNvbHZlcnMucGlwZS5hZGRPdmVycmlkZShwaXBlLCBvdmVycmlkZSk7XG4gICAgdGhpcy5wZW5kaW5nUGlwZXMuYWRkKHBpcGUpO1xuICB9XG5cbiAgcHJpdmF0ZSB2ZXJpZnlOb1N0YW5kYWxvbmVGbGFnT3ZlcnJpZGVzKFxuICAgICAgdHlwZTogVHlwZTxhbnk+LCBvdmVycmlkZTogTWV0YWRhdGFPdmVycmlkZTxDb21wb25lbnR8RGlyZWN0aXZlfFBpcGU+KSB7XG4gICAgaWYgKG92ZXJyaWRlLmFkZD8uaGFzT3duUHJvcGVydHkoJ3N0YW5kYWxvbmUnKSB8fCBvdmVycmlkZS5zZXQ/Lmhhc093blByb3BlcnR5KCdzdGFuZGFsb25lJykgfHxcbiAgICAgICAgb3ZlcnJpZGUucmVtb3ZlPy5oYXNPd25Qcm9wZXJ0eSgnc3RhbmRhbG9uZScpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYEFuIG92ZXJyaWRlIGZvciB0aGUgJHt0eXBlLm5hbWV9IGNsYXNzIGhhcyB0aGUgXFxgc3RhbmRhbG9uZVxcYCBmbGFnLiBgICtcbiAgICAgICAgICBgQ2hhbmdpbmcgdGhlIFxcYHN0YW5kYWxvbmVcXGAgZmxhZyB2aWEgVGVzdEJlZCBvdmVycmlkZXMgaXMgbm90IHN1cHBvcnRlZC5gKTtcbiAgICB9XG4gIH1cblxuICBvdmVycmlkZVByb3ZpZGVyKFxuICAgICAgdG9rZW46IGFueSxcbiAgICAgIHByb3ZpZGVyOiB7dXNlRmFjdG9yeT86IEZ1bmN0aW9uLCB1c2VWYWx1ZT86IGFueSwgZGVwcz86IGFueVtdLCBtdWx0aT86IGJvb2xlYW59KTogdm9pZCB7XG4gICAgbGV0IHByb3ZpZGVyRGVmOiBQcm92aWRlcjtcbiAgICBpZiAocHJvdmlkZXIudXNlRmFjdG9yeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBwcm92aWRlckRlZiA9IHtcbiAgICAgICAgcHJvdmlkZTogdG9rZW4sXG4gICAgICAgIHVzZUZhY3Rvcnk6IHByb3ZpZGVyLnVzZUZhY3RvcnksXG4gICAgICAgIGRlcHM6IHByb3ZpZGVyLmRlcHMgfHwgW10sXG4gICAgICAgIG11bHRpOiBwcm92aWRlci5tdWx0aVxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHByb3ZpZGVyLnVzZVZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHByb3ZpZGVyRGVmID0ge3Byb3ZpZGU6IHRva2VuLCB1c2VWYWx1ZTogcHJvdmlkZXIudXNlVmFsdWUsIG11bHRpOiBwcm92aWRlci5tdWx0aX07XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb3ZpZGVyRGVmID0ge3Byb3ZpZGU6IHRva2VufTtcbiAgICB9XG5cbiAgICBjb25zdCBpbmplY3RhYmxlRGVmOiBJbmplY3RhYmxlRGVjbGFyYXRpb248YW55PnxudWxsID1cbiAgICAgICAgdHlwZW9mIHRva2VuICE9PSAnc3RyaW5nJyA/IGdldEluamVjdGFibGVEZWYodG9rZW4pIDogbnVsbDtcbiAgICBjb25zdCBwcm92aWRlZEluID0gaW5qZWN0YWJsZURlZiA9PT0gbnVsbCA/IG51bGwgOiByZXNvbHZlRm9yd2FyZFJlZihpbmplY3RhYmxlRGVmLnByb3ZpZGVkSW4pO1xuICAgIGNvbnN0IG92ZXJyaWRlc0J1Y2tldCA9XG4gICAgICAgIHByb3ZpZGVkSW4gPT09ICdyb290JyA/IHRoaXMucm9vdFByb3ZpZGVyT3ZlcnJpZGVzIDogdGhpcy5wcm92aWRlck92ZXJyaWRlcztcbiAgICBvdmVycmlkZXNCdWNrZXQucHVzaChwcm92aWRlckRlZik7XG5cbiAgICAvLyBLZWVwIG92ZXJyaWRlcyBncm91cGVkIGJ5IHRva2VuIGFzIHdlbGwgZm9yIGZhc3QgbG9va3VwcyB1c2luZyB0b2tlblxuICAgIHRoaXMucHJvdmlkZXJPdmVycmlkZXNCeVRva2VuLnNldCh0b2tlbiwgcHJvdmlkZXJEZWYpO1xuICAgIGlmIChpbmplY3RhYmxlRGVmICE9PSBudWxsICYmIHByb3ZpZGVkSW4gIT09IG51bGwgJiYgdHlwZW9mIHByb3ZpZGVkSW4gIT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCBleGlzdGluZ092ZXJyaWRlcyA9IHRoaXMucHJvdmlkZXJPdmVycmlkZXNCeU1vZHVsZS5nZXQocHJvdmlkZWRJbik7XG4gICAgICBpZiAoZXhpc3RpbmdPdmVycmlkZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBleGlzdGluZ092ZXJyaWRlcy5wdXNoKHByb3ZpZGVyRGVmKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucHJvdmlkZXJPdmVycmlkZXNCeU1vZHVsZS5zZXQocHJvdmlkZWRJbiwgW3Byb3ZpZGVyRGVmXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb3ZlcnJpZGVUZW1wbGF0ZVVzaW5nVGVzdGluZ01vZHVsZSh0eXBlOiBUeXBlPGFueT4sIHRlbXBsYXRlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBkZWYgPSAodHlwZSBhcyBhbnkpW05HX0NPTVBfREVGXTtcbiAgICBjb25zdCBoYXNTdHlsZVVybHMgPSAoKTogYm9vbGVhbiA9PiB7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMucmVzb2x2ZXJzLmNvbXBvbmVudC5yZXNvbHZlKHR5cGUpISBhcyBDb21wb25lbnQ7XG4gICAgICByZXR1cm4gISFtZXRhZGF0YS5zdHlsZVVybHMgJiYgbWV0YWRhdGEuc3R5bGVVcmxzLmxlbmd0aCA+IDA7XG4gICAgfTtcbiAgICBjb25zdCBvdmVycmlkZVN0eWxlVXJscyA9ICEhZGVmICYmICFpc0NvbXBvbmVudERlZlBlbmRpbmdSZXNvbHV0aW9uKHR5cGUpICYmIGhhc1N0eWxlVXJscygpO1xuXG4gICAgLy8gSW4gSXZ5LCBjb21waWxpbmcgYSBjb21wb25lbnQgZG9lcyBub3QgcmVxdWlyZSBrbm93aW5nIHRoZSBtb2R1bGUgcHJvdmlkaW5nIHRoZVxuICAgIC8vIGNvbXBvbmVudCdzIHNjb3BlLCBzbyBvdmVycmlkZVRlbXBsYXRlVXNpbmdUZXN0aW5nTW9kdWxlIGNhbiBiZSBpbXBsZW1lbnRlZCBwdXJlbHkgdmlhXG4gICAgLy8gb3ZlcnJpZGVDb21wb25lbnQuIEltcG9ydGFudDogb3ZlcnJpZGluZyB0ZW1wbGF0ZSByZXF1aXJlcyBmdWxsIENvbXBvbmVudCByZS1jb21waWxhdGlvbixcbiAgICAvLyB3aGljaCBtYXkgZmFpbCBpbiBjYXNlIHN0eWxlVXJscyBhcmUgYWxzbyBwcmVzZW50ICh0aHVzIENvbXBvbmVudCBpcyBjb25zaWRlcmVkIGFzIHJlcXVpcmVkXG4gICAgLy8gcmVzb2x1dGlvbikuIEluIG9yZGVyIHRvIGF2b2lkIHRoaXMsIHdlIHByZWVtcHRpdmVseSBzZXQgc3R5bGVVcmxzIHRvIGFuIGVtcHR5IGFycmF5LFxuICAgIC8vIHByZXNlcnZlIGN1cnJlbnQgc3R5bGVzIGF2YWlsYWJsZSBvbiBDb21wb25lbnQgZGVmIGFuZCByZXN0b3JlIHN0eWxlcyBiYWNrIG9uY2UgY29tcGlsYXRpb25cbiAgICAvLyBpcyBjb21wbGV0ZS5cbiAgICBjb25zdCBvdmVycmlkZSA9IG92ZXJyaWRlU3R5bGVVcmxzID8ge3RlbXBsYXRlLCBzdHlsZXM6IFtdLCBzdHlsZVVybHM6IFtdfSA6IHt0ZW1wbGF0ZX07XG4gICAgdGhpcy5vdmVycmlkZUNvbXBvbmVudCh0eXBlLCB7c2V0OiBvdmVycmlkZX0pO1xuXG4gICAgaWYgKG92ZXJyaWRlU3R5bGVVcmxzICYmIGRlZi5zdHlsZXMgJiYgZGVmLnN0eWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmV4aXN0aW5nQ29tcG9uZW50U3R5bGVzLnNldCh0eXBlLCBkZWYuc3R5bGVzKTtcbiAgICB9XG5cbiAgICAvLyBTZXQgdGhlIGNvbXBvbmVudCdzIHNjb3BlIHRvIGJlIHRoZSB0ZXN0aW5nIG1vZHVsZS5cbiAgICB0aGlzLmNvbXBvbmVudFRvTW9kdWxlU2NvcGUuc2V0KHR5cGUsIFRlc3RpbmdNb2R1bGVPdmVycmlkZS5PVkVSUklERV9URU1QTEFURSk7XG4gIH1cblxuICBhc3luYyBjb21waWxlQ29tcG9uZW50cygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmNsZWFyQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlKCk7XG4gICAgLy8gUnVuIGNvbXBpbGVycyBmb3IgYWxsIHF1ZXVlZCB0eXBlcy5cbiAgICBsZXQgbmVlZHNBc3luY1Jlc291cmNlcyA9IHRoaXMuY29tcGlsZVR5cGVzU3luYygpO1xuXG4gICAgLy8gY29tcGlsZUNvbXBvbmVudHMoKSBzaG91bGQgbm90IGJlIGFzeW5jIHVubGVzcyBpdCBuZWVkcyB0byBiZS5cbiAgICBpZiAobmVlZHNBc3luY1Jlc291cmNlcykge1xuICAgICAgbGV0IHJlc291cmNlTG9hZGVyOiBSZXNvdXJjZUxvYWRlcjtcbiAgICAgIGxldCByZXNvbHZlciA9ICh1cmw6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gICAgICAgIGlmICghcmVzb3VyY2VMb2FkZXIpIHtcbiAgICAgICAgICByZXNvdXJjZUxvYWRlciA9IHRoaXMuaW5qZWN0b3IuZ2V0KFJlc291cmNlTG9hZGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc291cmNlTG9hZGVyLmdldCh1cmwpKTtcbiAgICAgIH07XG4gICAgICBhd2FpdCByZXNvbHZlQ29tcG9uZW50UmVzb3VyY2VzKHJlc29sdmVyKTtcbiAgICB9XG4gIH1cblxuICBmaW5hbGl6ZSgpOiBOZ01vZHVsZVJlZjxhbnk+IHtcbiAgICAvLyBPbmUgbGFzdCBjb21waWxlXG4gICAgdGhpcy5jb21waWxlVHlwZXNTeW5jKCk7XG5cbiAgICAvLyBDcmVhdGUgdGhlIHRlc3RpbmcgbW9kdWxlIGl0c2VsZi5cbiAgICB0aGlzLmNvbXBpbGVUZXN0TW9kdWxlKCk7XG5cbiAgICB0aGlzLmFwcGx5VHJhbnNpdGl2ZVNjb3BlcygpO1xuXG4gICAgdGhpcy5hcHBseVByb3ZpZGVyT3ZlcnJpZGVzKCk7XG5cbiAgICAvLyBQYXRjaCBwcmV2aW91c2x5IHN0b3JlZCBgc3R5bGVzYCBDb21wb25lbnQgdmFsdWVzICh0YWtlbiBmcm9tIMm1Y21wKSwgaW4gY2FzZSB0aGVzZVxuICAgIC8vIENvbXBvbmVudHMgaGF2ZSBgc3R5bGVVcmxzYCBmaWVsZHMgZGVmaW5lZCBhbmQgdGVtcGxhdGUgb3ZlcnJpZGUgd2FzIHJlcXVlc3RlZC5cbiAgICB0aGlzLnBhdGNoQ29tcG9uZW50c1dpdGhFeGlzdGluZ1N0eWxlcygpO1xuXG4gICAgLy8gQ2xlYXIgdGhlIGNvbXBvbmVudFRvTW9kdWxlU2NvcGUgbWFwLCBzbyB0aGF0IGZ1dHVyZSBjb21waWxhdGlvbnMgZG9uJ3QgcmVzZXQgdGhlIHNjb3BlIG9mXG4gICAgLy8gZXZlcnkgY29tcG9uZW50LlxuICAgIHRoaXMuY29tcG9uZW50VG9Nb2R1bGVTY29wZS5jbGVhcigpO1xuXG4gICAgY29uc3QgcGFyZW50SW5qZWN0b3IgPSB0aGlzLnBsYXRmb3JtLmluamVjdG9yO1xuICAgIHRoaXMudGVzdE1vZHVsZVJlZiA9IG5ldyBOZ01vZHVsZVJlZih0aGlzLnRlc3RNb2R1bGVUeXBlLCBwYXJlbnRJbmplY3RvciwgW10pO1xuXG4gICAgLy8gQXBwbGljYXRpb25Jbml0U3RhdHVzLnJ1bkluaXRpYWxpemVycygpIGlzIG1hcmtlZCBAaW50ZXJuYWwgdG8gY29yZS5cbiAgICAvLyBDYXN0IGl0IHRvIGFueSBiZWZvcmUgYWNjZXNzaW5nIGl0LlxuICAgICh0aGlzLnRlc3RNb2R1bGVSZWYuaW5qZWN0b3IuZ2V0KEFwcGxpY2F0aW9uSW5pdFN0YXR1cykgYXMgYW55KS5ydW5Jbml0aWFsaXplcnMoKTtcblxuICAgIC8vIFNldCBsb2NhbGUgSUQgYWZ0ZXIgcnVubmluZyBhcHAgaW5pdGlhbGl6ZXJzLCBzaW5jZSBsb2NhbGUgaW5mb3JtYXRpb24gbWlnaHQgYmUgdXBkYXRlZCB3aGlsZVxuICAgIC8vIHJ1bm5pbmcgaW5pdGlhbGl6ZXJzLiBUaGlzIGlzIGFsc28gY29uc2lzdGVudCB3aXRoIHRoZSBleGVjdXRpb24gb3JkZXIgd2hpbGUgYm9vdHN0cmFwcGluZyBhblxuICAgIC8vIGFwcCAoc2VlIGBwYWNrYWdlcy9jb3JlL3NyYy9hcHBsaWNhdGlvbl9yZWYudHNgIGZpbGUpLlxuICAgIGNvbnN0IGxvY2FsZUlkID0gdGhpcy50ZXN0TW9kdWxlUmVmLmluamVjdG9yLmdldChMT0NBTEVfSUQsIERFRkFVTFRfTE9DQUxFX0lEKTtcbiAgICBzZXRMb2NhbGVJZChsb2NhbGVJZCk7XG5cbiAgICByZXR1cm4gdGhpcy50ZXN0TW9kdWxlUmVmO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgX2NvbXBpbGVOZ01vZHVsZVN5bmMobW9kdWxlVHlwZTogVHlwZTxhbnk+KTogdm9pZCB7XG4gICAgdGhpcy5xdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheShbbW9kdWxlVHlwZV0pO1xuICAgIHRoaXMuY29tcGlsZVR5cGVzU3luYygpO1xuICAgIHRoaXMuYXBwbHlQcm92aWRlck92ZXJyaWRlcygpO1xuICAgIHRoaXMuYXBwbHlQcm92aWRlck92ZXJyaWRlc0luU2NvcGUobW9kdWxlVHlwZSk7XG4gICAgdGhpcy5hcHBseVRyYW5zaXRpdmVTY29wZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGFzeW5jIF9jb21waWxlTmdNb2R1bGVBc3luYyhtb2R1bGVUeXBlOiBUeXBlPGFueT4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnF1ZXVlVHlwZXNGcm9tTW9kdWxlc0FycmF5KFttb2R1bGVUeXBlXSk7XG4gICAgYXdhaXQgdGhpcy5jb21waWxlQ29tcG9uZW50cygpO1xuICAgIHRoaXMuYXBwbHlQcm92aWRlck92ZXJyaWRlcygpO1xuICAgIHRoaXMuYXBwbHlQcm92aWRlck92ZXJyaWRlc0luU2NvcGUobW9kdWxlVHlwZSk7XG4gICAgdGhpcy5hcHBseVRyYW5zaXRpdmVTY29wZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIF9nZXRNb2R1bGVSZXNvbHZlcigpOiBSZXNvbHZlcjxOZ01vZHVsZT4ge1xuICAgIHJldHVybiB0aGlzLnJlc29sdmVycy5tb2R1bGU7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBfZ2V0Q29tcG9uZW50RmFjdG9yaWVzKG1vZHVsZVR5cGU6IE5nTW9kdWxlVHlwZSk6IENvbXBvbmVudEZhY3Rvcnk8YW55PltdIHtcbiAgICByZXR1cm4gbWF5YmVVbndyYXBGbihtb2R1bGVUeXBlLsm1bW9kLmRlY2xhcmF0aW9ucykucmVkdWNlKChmYWN0b3JpZXMsIGRlY2xhcmF0aW9uKSA9PiB7XG4gICAgICBjb25zdCBjb21wb25lbnREZWYgPSAoZGVjbGFyYXRpb24gYXMgYW55KS7JtWNtcDtcbiAgICAgIGNvbXBvbmVudERlZiAmJiBmYWN0b3JpZXMucHVzaChuZXcgQ29tcG9uZW50RmFjdG9yeShjb21wb25lbnREZWYsIHRoaXMudGVzdE1vZHVsZVJlZiEpKTtcbiAgICAgIHJldHVybiBmYWN0b3JpZXM7XG4gICAgfSwgW10gYXMgQ29tcG9uZW50RmFjdG9yeTxhbnk+W10pO1xuICB9XG5cbiAgcHJpdmF0ZSBjb21waWxlVHlwZXNTeW5jKCk6IGJvb2xlYW4ge1xuICAgIC8vIENvbXBpbGUgYWxsIHF1ZXVlZCBjb21wb25lbnRzLCBkaXJlY3RpdmVzLCBwaXBlcy5cbiAgICBsZXQgbmVlZHNBc3luY1Jlc291cmNlcyA9IGZhbHNlO1xuICAgIHRoaXMucGVuZGluZ0NvbXBvbmVudHMuZm9yRWFjaChkZWNsYXJhdGlvbiA9PiB7XG4gICAgICBuZWVkc0FzeW5jUmVzb3VyY2VzID0gbmVlZHNBc3luY1Jlc291cmNlcyB8fCBpc0NvbXBvbmVudERlZlBlbmRpbmdSZXNvbHV0aW9uKGRlY2xhcmF0aW9uKTtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5yZXNvbHZlcnMuY29tcG9uZW50LnJlc29sdmUoZGVjbGFyYXRpb24pO1xuICAgICAgaWYgKG1ldGFkYXRhID09PSBudWxsKSB7XG4gICAgICAgIHRocm93IGludmFsaWRUeXBlRXJyb3IoZGVjbGFyYXRpb24ubmFtZSwgJ0NvbXBvbmVudCcpO1xuICAgICAgfVxuICAgICAgdGhpcy5tYXliZVN0b3JlTmdEZWYoTkdfQ09NUF9ERUYsIGRlY2xhcmF0aW9uKTtcbiAgICAgIGNvbXBpbGVDb21wb25lbnQoZGVjbGFyYXRpb24sIG1ldGFkYXRhKTtcbiAgICB9KTtcbiAgICB0aGlzLnBlbmRpbmdDb21wb25lbnRzLmNsZWFyKCk7XG5cbiAgICB0aGlzLnBlbmRpbmdEaXJlY3RpdmVzLmZvckVhY2goZGVjbGFyYXRpb24gPT4ge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnJlc29sdmVycy5kaXJlY3RpdmUucmVzb2x2ZShkZWNsYXJhdGlvbik7XG4gICAgICBpZiAobWV0YWRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgaW52YWxpZFR5cGVFcnJvcihkZWNsYXJhdGlvbi5uYW1lLCAnRGlyZWN0aXZlJyk7XG4gICAgICB9XG4gICAgICB0aGlzLm1heWJlU3RvcmVOZ0RlZihOR19ESVJfREVGLCBkZWNsYXJhdGlvbik7XG4gICAgICBjb21waWxlRGlyZWN0aXZlKGRlY2xhcmF0aW9uLCBtZXRhZGF0YSk7XG4gICAgfSk7XG4gICAgdGhpcy5wZW5kaW5nRGlyZWN0aXZlcy5jbGVhcigpO1xuXG4gICAgdGhpcy5wZW5kaW5nUGlwZXMuZm9yRWFjaChkZWNsYXJhdGlvbiA9PiB7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMucmVzb2x2ZXJzLnBpcGUucmVzb2x2ZShkZWNsYXJhdGlvbik7XG4gICAgICBpZiAobWV0YWRhdGEgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgaW52YWxpZFR5cGVFcnJvcihkZWNsYXJhdGlvbi5uYW1lLCAnUGlwZScpO1xuICAgICAgfVxuICAgICAgdGhpcy5tYXliZVN0b3JlTmdEZWYoTkdfUElQRV9ERUYsIGRlY2xhcmF0aW9uKTtcbiAgICAgIGNvbXBpbGVQaXBlKGRlY2xhcmF0aW9uLCBtZXRhZGF0YSk7XG4gICAgfSk7XG4gICAgdGhpcy5wZW5kaW5nUGlwZXMuY2xlYXIoKTtcblxuICAgIHJldHVybiBuZWVkc0FzeW5jUmVzb3VyY2VzO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseVRyYW5zaXRpdmVTY29wZXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMub3ZlcnJpZGRlbk1vZHVsZXMuc2l6ZSA+IDApIHtcbiAgICAgIC8vIE1vZHVsZSBvdmVycmlkZXMgKHZpYSBgVGVzdEJlZC5vdmVycmlkZU1vZHVsZWApIG1pZ2h0IGFmZmVjdCBzY29wZXMgdGhhdCB3ZXJlIHByZXZpb3VzbHlcbiAgICAgIC8vIGNhbGN1bGF0ZWQgYW5kIHN0b3JlZCBpbiBgdHJhbnNpdGl2ZUNvbXBpbGVTY29wZXNgLiBJZiBtb2R1bGUgb3ZlcnJpZGVzIGFyZSBwcmVzZW50LFxuICAgICAgLy8gY29sbGVjdCBhbGwgYWZmZWN0ZWQgbW9kdWxlcyBhbmQgcmVzZXQgc2NvcGVzIHRvIGZvcmNlIHRoZWlyIHJlLWNhbGN1bGF0aW9uLlxuICAgICAgY29uc3QgdGVzdGluZ01vZHVsZURlZiA9ICh0aGlzLnRlc3RNb2R1bGVUeXBlIGFzIGFueSlbTkdfTU9EX0RFRl07XG4gICAgICBjb25zdCBhZmZlY3RlZE1vZHVsZXMgPSB0aGlzLmNvbGxlY3RNb2R1bGVzQWZmZWN0ZWRCeU92ZXJyaWRlcyh0ZXN0aW5nTW9kdWxlRGVmLmltcG9ydHMpO1xuICAgICAgaWYgKGFmZmVjdGVkTW9kdWxlcy5zaXplID4gMCkge1xuICAgICAgICBhZmZlY3RlZE1vZHVsZXMuZm9yRWFjaChtb2R1bGVUeXBlID0+IHtcbiAgICAgICAgICB0aGlzLnN0b3JlRmllbGRPZkRlZk9uVHlwZShtb2R1bGVUeXBlIGFzIGFueSwgTkdfTU9EX0RFRiwgJ3RyYW5zaXRpdmVDb21waWxlU2NvcGVzJyk7XG4gICAgICAgICAgKG1vZHVsZVR5cGUgYXMgYW55KVtOR19NT0RfREVGXS50cmFuc2l0aXZlQ29tcGlsZVNjb3BlcyA9IG51bGw7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG1vZHVsZVRvU2NvcGUgPSBuZXcgTWFwPFR5cGU8YW55PnxUZXN0aW5nTW9kdWxlT3ZlcnJpZGUsIE5nTW9kdWxlVHJhbnNpdGl2ZVNjb3Blcz4oKTtcbiAgICBjb25zdCBnZXRTY29wZU9mTW9kdWxlID1cbiAgICAgICAgKG1vZHVsZVR5cGU6IFR5cGU8YW55PnxUZXN0aW5nTW9kdWxlT3ZlcnJpZGUpOiBOZ01vZHVsZVRyYW5zaXRpdmVTY29wZXMgPT4ge1xuICAgICAgICAgIGlmICghbW9kdWxlVG9TY29wZS5oYXMobW9kdWxlVHlwZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzVGVzdGluZ01vZHVsZSA9IGlzVGVzdGluZ01vZHVsZU92ZXJyaWRlKG1vZHVsZVR5cGUpO1xuICAgICAgICAgICAgY29uc3QgcmVhbFR5cGUgPSBpc1Rlc3RpbmdNb2R1bGUgPyB0aGlzLnRlc3RNb2R1bGVUeXBlIDogbW9kdWxlVHlwZSBhcyBUeXBlPGFueT47XG4gICAgICAgICAgICBtb2R1bGVUb1Njb3BlLnNldChtb2R1bGVUeXBlLCB0cmFuc2l0aXZlU2NvcGVzRm9yKHJlYWxUeXBlKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBtb2R1bGVUb1Njb3BlLmdldChtb2R1bGVUeXBlKSE7XG4gICAgICAgIH07XG5cbiAgICB0aGlzLmNvbXBvbmVudFRvTW9kdWxlU2NvcGUuZm9yRWFjaCgobW9kdWxlVHlwZSwgY29tcG9uZW50VHlwZSkgPT4ge1xuICAgICAgY29uc3QgbW9kdWxlU2NvcGUgPSBnZXRTY29wZU9mTW9kdWxlKG1vZHVsZVR5cGUpO1xuICAgICAgdGhpcy5zdG9yZUZpZWxkT2ZEZWZPblR5cGUoY29tcG9uZW50VHlwZSwgTkdfQ09NUF9ERUYsICdkaXJlY3RpdmVEZWZzJyk7XG4gICAgICB0aGlzLnN0b3JlRmllbGRPZkRlZk9uVHlwZShjb21wb25lbnRUeXBlLCBOR19DT01QX0RFRiwgJ3BpcGVEZWZzJyk7XG4gICAgICAvLyBgdFZpZXdgIHRoYXQgaXMgc3RvcmVkIG9uIGNvbXBvbmVudCBkZWYgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgZGlyZWN0aXZlcyBhbmQgcGlwZXNcbiAgICAgIC8vIHRoYXQgYXJlIGluIHRoZSBzY29wZSBvZiB0aGlzIGNvbXBvbmVudC4gUGF0Y2hpbmcgY29tcG9uZW50IHNjb3BlIHdpbGwgY2F1c2UgYHRWaWV3YCB0byBiZVxuICAgICAgLy8gY2hhbmdlZC4gU3RvcmUgb3JpZ2luYWwgYHRWaWV3YCBiZWZvcmUgcGF0Y2hpbmcgc2NvcGUsIHNvIHRoZSBgdFZpZXdgIChpbmNsdWRpbmcgc2NvcGVcbiAgICAgIC8vIGluZm9ybWF0aW9uKSBpcyByZXN0b3JlZCBiYWNrIHRvIGl0cyBwcmV2aW91cy9vcmlnaW5hbCBzdGF0ZSBiZWZvcmUgcnVubmluZyBuZXh0IHRlc3QuXG4gICAgICB0aGlzLnN0b3JlRmllbGRPZkRlZk9uVHlwZShjb21wb25lbnRUeXBlLCBOR19DT01QX0RFRiwgJ3RWaWV3Jyk7XG4gICAgICBwYXRjaENvbXBvbmVudERlZldpdGhTY29wZSgoY29tcG9uZW50VHlwZSBhcyBhbnkpLsm1Y21wLCBtb2R1bGVTY29wZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbXBvbmVudFRvTW9kdWxlU2NvcGUuY2xlYXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgYXBwbHlQcm92aWRlck92ZXJyaWRlcygpOiB2b2lkIHtcbiAgICBjb25zdCBtYXliZUFwcGx5T3ZlcnJpZGVzID0gKGZpZWxkOiBzdHJpbmcpID0+ICh0eXBlOiBUeXBlPGFueT4pID0+IHtcbiAgICAgIGNvbnN0IHJlc29sdmVyID0gZmllbGQgPT09IE5HX0NPTVBfREVGID8gdGhpcy5yZXNvbHZlcnMuY29tcG9uZW50IDogdGhpcy5yZXNvbHZlcnMuZGlyZWN0aXZlO1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSByZXNvbHZlci5yZXNvbHZlKHR5cGUpITtcbiAgICAgIGlmICh0aGlzLmhhc1Byb3ZpZGVyT3ZlcnJpZGVzKG1ldGFkYXRhLnByb3ZpZGVycykpIHtcbiAgICAgICAgdGhpcy5wYXRjaERlZldpdGhQcm92aWRlck92ZXJyaWRlcyh0eXBlLCBmaWVsZCk7XG4gICAgICB9XG4gICAgfTtcbiAgICB0aGlzLnNlZW5Db21wb25lbnRzLmZvckVhY2gobWF5YmVBcHBseU92ZXJyaWRlcyhOR19DT01QX0RFRikpO1xuICAgIHRoaXMuc2VlbkRpcmVjdGl2ZXMuZm9yRWFjaChtYXliZUFwcGx5T3ZlcnJpZGVzKE5HX0RJUl9ERUYpKTtcblxuICAgIHRoaXMuc2VlbkNvbXBvbmVudHMuY2xlYXIoKTtcbiAgICB0aGlzLnNlZW5EaXJlY3RpdmVzLmNsZWFyKCk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBBcHBsaWVzIHByb3ZpZGVyIG92ZXJyaWRlcyB0byBhIGdpdmVuIHR5cGUgKGVpdGhlciBhbiBOZ01vZHVsZSBvciBhIHN0YW5kYWxvbmUgY29tcG9uZW50KVxuICAgKiBhbmQgYWxsIGltcG9ydGVkIE5nTW9kdWxlcyBhbmQgc3RhbmRhbG9uZSBjb21wb25lbnRzIHJlY3Vyc2l2ZWx5LlxuICAgKi9cbiAgcHJpdmF0ZSBhcHBseVByb3ZpZGVyT3ZlcnJpZGVzSW5TY29wZSh0eXBlOiBUeXBlPGFueT4pOiB2b2lkIHtcbiAgICBjb25zdCBoYXNTY29wZSA9IGlzU3RhbmRhbG9uZUNvbXBvbmVudCh0eXBlKSB8fCBpc05nTW9kdWxlKHR5cGUpO1xuXG4gICAgLy8gVGhlIGZ1bmN0aW9uIGNhbiBiZSByZS1lbnRlcmVkIHJlY3Vyc2l2ZWx5IHdoaWxlIGluc3BlY3RpbmcgZGVwZW5kZW5jaWVzXG4gICAgLy8gb2YgYW4gTmdNb2R1bGUgb3IgYSBzdGFuZGFsb25lIGNvbXBvbmVudC4gRXhpdCBlYXJseSBpZiB3ZSBjb21lIGFjcm9zcyBhXG4gICAgLy8gdHlwZSB0aGF0IGNhbiBub3QgaGF2ZSBhIHNjb3BlIChkaXJlY3RpdmUgb3IgcGlwZSkgb3IgdGhlIHR5cGUgaXMgYWxyZWFkeVxuICAgIC8vIHByb2Nlc3NlZCBlYXJsaWVyLlxuICAgIGlmICghaGFzU2NvcGUgfHwgdGhpcy5zY29wZXNXaXRoT3ZlcnJpZGRlblByb3ZpZGVycy5oYXModHlwZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zY29wZXNXaXRoT3ZlcnJpZGRlblByb3ZpZGVycy5hZGQodHlwZSk7XG5cbiAgICAvLyBOT1RFOiB0aGUgbGluZSBiZWxvdyB0cmlnZ2VycyBKSVQgY29tcGlsYXRpb24gb2YgdGhlIG1vZHVsZSBpbmplY3RvcixcbiAgICAvLyB3aGljaCBhbHNvIGludm9rZXMgdmVyaWZpY2F0aW9uIG9mIHRoZSBOZ01vZHVsZSBzZW1hbnRpY3MsIHdoaWNoIHByb2R1Y2VzXG4gICAgLy8gZGV0YWlsZWQgZXJyb3IgbWVzc2FnZXMuIFRoZSBmYWN0IHRoYXQgdGhlIGNvZGUgcmVsaWVzIG9uIHRoaXMgbGluZSBiZWluZ1xuICAgIC8vIHByZXNlbnQgaGVyZSBpcyBzdXNwaWNpb3VzIGFuZCBzaG91bGQgYmUgcmVmYWN0b3JlZCBpbiBhIHdheSB0aGF0IHRoZSBsaW5lXG4gICAgLy8gYmVsb3cgY2FuIGJlIG1vdmVkIChmb3IgZXguIGFmdGVyIGFuIGVhcmx5IGV4aXQgY2hlY2sgYmVsb3cpLlxuICAgIGNvbnN0IGluamVjdG9yRGVmOiBhbnkgPSAodHlwZSBhcyBhbnkpW05HX0lOSl9ERUZdO1xuXG4gICAgLy8gTm8gcHJvdmlkZXIgb3ZlcnJpZGVzLCBleGl0IGVhcmx5LlxuICAgIGlmICh0aGlzLnByb3ZpZGVyT3ZlcnJpZGVzQnlUb2tlbi5zaXplID09PSAwKSByZXR1cm47XG5cbiAgICBpZiAoaXNTdGFuZGFsb25lQ29tcG9uZW50KHR5cGUpKSB7XG4gICAgICAvLyBWaXNpdCBhbGwgY29tcG9uZW50IGRlcGVuZGVuY2llcyBhbmQgb3ZlcnJpZGUgcHJvdmlkZXJzIHRoZXJlLlxuICAgICAgY29uc3QgZGVmID0gZ2V0Q29tcG9uZW50RGVmKHR5cGUpO1xuICAgICAgY29uc3QgZGVwZW5kZW5jaWVzID0gbWF5YmVVbndyYXBGbihkZWYuZGVwZW5kZW5jaWVzID8/IFtdKTtcbiAgICAgIGZvciAoY29uc3QgZGVwZW5kZW5jeSBvZiBkZXBlbmRlbmNpZXMpIHtcbiAgICAgICAgdGhpcy5hcHBseVByb3ZpZGVyT3ZlcnJpZGVzSW5TY29wZShkZXBlbmRlbmN5KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgcHJvdmlkZXJzOiBBcnJheTxQcm92aWRlcnxJbnRlcm5hbEVudmlyb25tZW50UHJvdmlkZXJzPiA9IFtcbiAgICAgICAgLi4uaW5qZWN0b3JEZWYucHJvdmlkZXJzLFxuICAgICAgICAuLi4odGhpcy5wcm92aWRlck92ZXJyaWRlc0J5TW9kdWxlLmdldCh0eXBlIGFzIEluamVjdG9yVHlwZTxhbnk+KSB8fCBbXSlcbiAgICAgIF07XG4gICAgICBpZiAodGhpcy5oYXNQcm92aWRlck92ZXJyaWRlcyhwcm92aWRlcnMpKSB7XG4gICAgICAgIHRoaXMubWF5YmVTdG9yZU5nRGVmKE5HX0lOSl9ERUYsIHR5cGUpO1xuXG4gICAgICAgIHRoaXMuc3RvcmVGaWVsZE9mRGVmT25UeXBlKHR5cGUsIE5HX0lOSl9ERUYsICdwcm92aWRlcnMnKTtcbiAgICAgICAgaW5qZWN0b3JEZWYucHJvdmlkZXJzID0gdGhpcy5nZXRPdmVycmlkZGVuUHJvdmlkZXJzKHByb3ZpZGVycyk7XG4gICAgICB9XG5cbiAgICAgIC8vIEFwcGx5IHByb3ZpZGVyIG92ZXJyaWRlcyB0byBpbXBvcnRlZCBtb2R1bGVzIHJlY3Vyc2l2ZWx5XG4gICAgICBjb25zdCBtb2R1bGVEZWYgPSAodHlwZSBhcyBhbnkpW05HX01PRF9ERUZdO1xuICAgICAgY29uc3QgaW1wb3J0cyA9IG1heWJlVW53cmFwRm4obW9kdWxlRGVmLmltcG9ydHMpO1xuICAgICAgZm9yIChjb25zdCBpbXBvcnRlZE1vZHVsZSBvZiBpbXBvcnRzKSB7XG4gICAgICAgIHRoaXMuYXBwbHlQcm92aWRlck92ZXJyaWRlc0luU2NvcGUoaW1wb3J0ZWRNb2R1bGUpO1xuICAgICAgfVxuICAgICAgLy8gQWxzbyBvdmVycmlkZSB0aGUgcHJvdmlkZXJzIG9uIGFueSBNb2R1bGVXaXRoUHJvdmlkZXJzIGltcG9ydHMgc2luY2UgdGhvc2UgZG9uJ3QgYXBwZWFyIGluXG4gICAgICAvLyB0aGUgbW9kdWxlRGVmLlxuICAgICAgZm9yIChjb25zdCBpbXBvcnRlZE1vZHVsZSBvZiBmbGF0dGVuKGluamVjdG9yRGVmLmltcG9ydHMpKSB7XG4gICAgICAgIGlmIChpc01vZHVsZVdpdGhQcm92aWRlcnMoaW1wb3J0ZWRNb2R1bGUpKSB7XG4gICAgICAgICAgdGhpcy5kZWZDbGVhbnVwT3BzLnB1c2goe1xuICAgICAgICAgICAgb2JqZWN0OiBpbXBvcnRlZE1vZHVsZSxcbiAgICAgICAgICAgIGZpZWxkTmFtZTogJ3Byb3ZpZGVycycsXG4gICAgICAgICAgICBvcmlnaW5hbFZhbHVlOiBpbXBvcnRlZE1vZHVsZS5wcm92aWRlcnNcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpbXBvcnRlZE1vZHVsZS5wcm92aWRlcnMgPSB0aGlzLmdldE92ZXJyaWRkZW5Qcm92aWRlcnMoXG4gICAgICAgICAgICAgIGltcG9ydGVkTW9kdWxlLnByb3ZpZGVycyBhcyBBcnJheTxQcm92aWRlcnxJbnRlcm5hbEVudmlyb25tZW50UHJvdmlkZXJzPik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHBhdGNoQ29tcG9uZW50c1dpdGhFeGlzdGluZ1N0eWxlcygpOiB2b2lkIHtcbiAgICB0aGlzLmV4aXN0aW5nQ29tcG9uZW50U3R5bGVzLmZvckVhY2goXG4gICAgICAgIChzdHlsZXMsIHR5cGUpID0+ICh0eXBlIGFzIGFueSlbTkdfQ09NUF9ERUZdLnN0eWxlcyA9IHN0eWxlcyk7XG4gICAgdGhpcy5leGlzdGluZ0NvbXBvbmVudFN0eWxlcy5jbGVhcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBxdWV1ZVR5cGVBcnJheShhcnI6IGFueVtdLCBtb2R1bGVUeXBlOiBUeXBlPGFueT58VGVzdGluZ01vZHVsZU92ZXJyaWRlKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCB2YWx1ZSBvZiBhcnIpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICB0aGlzLnF1ZXVlVHlwZUFycmF5KHZhbHVlLCBtb2R1bGVUeXBlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucXVldWVUeXBlKHZhbHVlLCBtb2R1bGVUeXBlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlY29tcGlsZU5nTW9kdWxlKG5nTW9kdWxlOiBUeXBlPGFueT4sIG1ldGFkYXRhOiBOZ01vZHVsZSk6IHZvaWQge1xuICAgIC8vIENhY2hlIHRoZSBpbml0aWFsIG5nTW9kdWxlRGVmIGFzIGl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4uXG4gICAgdGhpcy5tYXliZVN0b3JlTmdEZWYoTkdfTU9EX0RFRiwgbmdNb2R1bGUpO1xuICAgIHRoaXMubWF5YmVTdG9yZU5nRGVmKE5HX0lOSl9ERUYsIG5nTW9kdWxlKTtcblxuICAgIGNvbXBpbGVOZ01vZHVsZURlZnMobmdNb2R1bGUgYXMgTmdNb2R1bGVUeXBlPGFueT4sIG1ldGFkYXRhKTtcbiAgfVxuXG4gIHByaXZhdGUgcXVldWVUeXBlKHR5cGU6IFR5cGU8YW55PiwgbW9kdWxlVHlwZTogVHlwZTxhbnk+fFRlc3RpbmdNb2R1bGVPdmVycmlkZXxudWxsKTogdm9pZCB7XG4gICAgY29uc3QgY29tcG9uZW50ID0gdGhpcy5yZXNvbHZlcnMuY29tcG9uZW50LnJlc29sdmUodHlwZSk7XG4gICAgaWYgKGNvbXBvbmVudCkge1xuICAgICAgLy8gQ2hlY2sgd2hldGhlciBhIGdpdmUgVHlwZSBoYXMgcmVzcGVjdGl2ZSBORyBkZWYgKMm1Y21wKSBhbmQgY29tcGlsZSBpZiBkZWYgaXNcbiAgICAgIC8vIG1pc3NpbmcuIFRoYXQgbWlnaHQgaGFwcGVuIGluIGNhc2UgYSBjbGFzcyB3aXRob3V0IGFueSBBbmd1bGFyIGRlY29yYXRvcnMgZXh0ZW5kcyBhbm90aGVyXG4gICAgICAvLyBjbGFzcyB3aGVyZSBDb21wb25lbnQvRGlyZWN0aXZlL1BpcGUgZGVjb3JhdG9yIGlzIGRlZmluZWQuXG4gICAgICBpZiAoaXNDb21wb25lbnREZWZQZW5kaW5nUmVzb2x1dGlvbih0eXBlKSB8fCAhdHlwZS5oYXNPd25Qcm9wZXJ0eShOR19DT01QX0RFRikpIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nQ29tcG9uZW50cy5hZGQodHlwZSk7XG4gICAgICB9XG4gICAgICB0aGlzLnNlZW5Db21wb25lbnRzLmFkZCh0eXBlKTtcblxuICAgICAgLy8gS2VlcCB0cmFjayBvZiB0aGUgbW9kdWxlIHdoaWNoIGRlY2xhcmVzIHRoaXMgY29tcG9uZW50LCBzbyBsYXRlciB0aGUgY29tcG9uZW50J3Mgc2NvcGVcbiAgICAgIC8vIGNhbiBiZSBzZXQgY29ycmVjdGx5LiBJZiB0aGUgY29tcG9uZW50IGhhcyBhbHJlYWR5IGJlZW4gcmVjb3JkZWQgaGVyZSwgdGhlbiBvbmUgb2Ygc2V2ZXJhbFxuICAgICAgLy8gY2FzZXMgaXMgdHJ1ZTpcbiAgICAgIC8vICogdGhlIG1vZHVsZSBjb250YWluaW5nIHRoZSBjb21wb25lbnQgd2FzIGltcG9ydGVkIG11bHRpcGxlIHRpbWVzIChjb21tb24pLlxuICAgICAgLy8gKiB0aGUgY29tcG9uZW50IGlzIGRlY2xhcmVkIGluIG11bHRpcGxlIG1vZHVsZXMgKHdoaWNoIGlzIGFuIGVycm9yKS5cbiAgICAgIC8vICogdGhlIGNvbXBvbmVudCB3YXMgaW4gJ2RlY2xhcmF0aW9ucycgb2YgdGhlIHRlc3RpbmcgbW9kdWxlLCBhbmQgYWxzbyBpbiBhbiBpbXBvcnRlZCBtb2R1bGVcbiAgICAgIC8vICAgaW4gd2hpY2ggY2FzZSB0aGUgbW9kdWxlIHNjb3BlIHdpbGwgYmUgVGVzdGluZ01vZHVsZU92ZXJyaWRlLkRFQ0xBUkFUSU9OLlxuICAgICAgLy8gKiBvdmVycmlkZVRlbXBsYXRlVXNpbmdUZXN0aW5nTW9kdWxlIHdhcyBjYWxsZWQgZm9yIHRoZSBjb21wb25lbnQgaW4gd2hpY2ggY2FzZSB0aGUgbW9kdWxlXG4gICAgICAvLyAgIHNjb3BlIHdpbGwgYmUgVGVzdGluZ01vZHVsZU92ZXJyaWRlLk9WRVJSSURFX1RFTVBMQVRFLlxuICAgICAgLy9cbiAgICAgIC8vIElmIHRoZSBjb21wb25lbnQgd2FzIHByZXZpb3VzbHkgaW4gdGhlIHRlc3RpbmcgbW9kdWxlJ3MgJ2RlY2xhcmF0aW9ucycgKG1lYW5pbmcgdGhlXG4gICAgICAvLyBjdXJyZW50IHZhbHVlIGlzIFRlc3RpbmdNb2R1bGVPdmVycmlkZS5ERUNMQVJBVElPTiksIHRoZW4gYG1vZHVsZVR5cGVgIGlzIHRoZSBjb21wb25lbnQnc1xuICAgICAgLy8gcmVhbCBtb2R1bGUsIHdoaWNoIHdhcyBpbXBvcnRlZC4gVGhpcyBwYXR0ZXJuIGlzIHVuZGVyc3Rvb2QgdG8gbWVhbiB0aGF0IHRoZSBjb21wb25lbnRcbiAgICAgIC8vIHNob3VsZCB1c2UgaXRzIG9yaWdpbmFsIHNjb3BlLCBidXQgdGhhdCB0aGUgdGVzdGluZyBtb2R1bGUgc2hvdWxkIGFsc28gY29udGFpbiB0aGVcbiAgICAgIC8vIGNvbXBvbmVudCBpbiBpdHMgc2NvcGUuXG4gICAgICAvL1xuICAgICAgLy8gTm90ZTogc3RhbmRhbG9uZSBjb21wb25lbnRzIGhhdmUgbm8gYXNzb2NpYXRlZCBOZ01vZHVsZSwgc28gdGhlIGBtb2R1bGVUeXBlYCBjYW4gYmUgYG51bGxgLlxuICAgICAgaWYgKG1vZHVsZVR5cGUgIT09IG51bGwgJiZcbiAgICAgICAgICAoIXRoaXMuY29tcG9uZW50VG9Nb2R1bGVTY29wZS5oYXModHlwZSkgfHxcbiAgICAgICAgICAgdGhpcy5jb21wb25lbnRUb01vZHVsZVNjb3BlLmdldCh0eXBlKSA9PT0gVGVzdGluZ01vZHVsZU92ZXJyaWRlLkRFQ0xBUkFUSU9OKSkge1xuICAgICAgICB0aGlzLmNvbXBvbmVudFRvTW9kdWxlU2NvcGUuc2V0KHR5cGUsIG1vZHVsZVR5cGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGRpcmVjdGl2ZSA9IHRoaXMucmVzb2x2ZXJzLmRpcmVjdGl2ZS5yZXNvbHZlKHR5cGUpO1xuICAgIGlmIChkaXJlY3RpdmUpIHtcbiAgICAgIGlmICghdHlwZS5oYXNPd25Qcm9wZXJ0eShOR19ESVJfREVGKSkge1xuICAgICAgICB0aGlzLnBlbmRpbmdEaXJlY3RpdmVzLmFkZCh0eXBlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2VlbkRpcmVjdGl2ZXMuYWRkKHR5cGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHBpcGUgPSB0aGlzLnJlc29sdmVycy5waXBlLnJlc29sdmUodHlwZSk7XG4gICAgaWYgKHBpcGUgJiYgIXR5cGUuaGFzT3duUHJvcGVydHkoTkdfUElQRV9ERUYpKSB7XG4gICAgICB0aGlzLnBlbmRpbmdQaXBlcy5hZGQodHlwZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBxdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheShhcnI6IGFueVtdKTogdm9pZCB7XG4gICAgLy8gQmVjYXVzZSB3ZSBtYXkgZW5jb3VudGVyIHRoZSBzYW1lIE5nTW9kdWxlIHdoaWxlIHByb2Nlc3NpbmcgdGhlIGltcG9ydHMgYW5kIGV4cG9ydHMgb2YgYW5cbiAgICAvLyBOZ01vZHVsZSB0cmVlLCB3ZSBjYWNoZSB0aGVtIGluIHRoaXMgc2V0IHNvIHdlIGNhbiBza2lwIG9uZXMgdGhhdCBoYXZlIGFscmVhZHkgYmVlbiBzZWVuXG4gICAgLy8gZW5jb3VudGVyZWQuIEluIHNvbWUgdGVzdCBzZXR1cHMsIHRoaXMgY2FjaGluZyByZXN1bHRlZCBpbiAxMFggcnVudGltZSBpbXByb3ZlbWVudC5cbiAgICBjb25zdCBwcm9jZXNzZWROZ01vZHVsZURlZnMgPSBuZXcgU2V0KCk7XG4gICAgY29uc3QgcXVldWVUeXBlc0Zyb21Nb2R1bGVzQXJyYXlSZWN1ciA9IChhcnI6IGFueVtdKTogdm9pZCA9PiB7XG4gICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIGFycikge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICBxdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheVJlY3VyKHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChoYXNOZ01vZHVsZURlZih2YWx1ZSkpIHtcbiAgICAgICAgICBjb25zdCBkZWYgPSB2YWx1ZS7JtW1vZDtcbiAgICAgICAgICBpZiAocHJvY2Vzc2VkTmdNb2R1bGVEZWZzLmhhcyhkZWYpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcHJvY2Vzc2VkTmdNb2R1bGVEZWZzLmFkZChkZWYpO1xuICAgICAgICAgIC8vIExvb2sgdGhyb3VnaCBkZWNsYXJhdGlvbnMsIGltcG9ydHMsIGFuZCBleHBvcnRzLCBhbmQgcXVldWVcbiAgICAgICAgICAvLyBldmVyeXRoaW5nIGZvdW5kIHRoZXJlLlxuICAgICAgICAgIHRoaXMucXVldWVUeXBlQXJyYXkobWF5YmVVbndyYXBGbihkZWYuZGVjbGFyYXRpb25zKSwgdmFsdWUpO1xuICAgICAgICAgIHF1ZXVlVHlwZXNGcm9tTW9kdWxlc0FycmF5UmVjdXIobWF5YmVVbndyYXBGbihkZWYuaW1wb3J0cykpO1xuICAgICAgICAgIHF1ZXVlVHlwZXNGcm9tTW9kdWxlc0FycmF5UmVjdXIobWF5YmVVbndyYXBGbihkZWYuZXhwb3J0cykpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzTW9kdWxlV2l0aFByb3ZpZGVycyh2YWx1ZSkpIHtcbiAgICAgICAgICBxdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheVJlY3VyKFt2YWx1ZS5uZ01vZHVsZV0pO1xuICAgICAgICB9IGVsc2UgaWYgKGlzU3RhbmRhbG9uZUNvbXBvbmVudCh2YWx1ZSkpIHtcbiAgICAgICAgICB0aGlzLnF1ZXVlVHlwZSh2YWx1ZSwgbnVsbCk7XG4gICAgICAgICAgY29uc3QgZGVmID0gZ2V0Q29tcG9uZW50RGVmKHZhbHVlKTtcbiAgICAgICAgICBjb25zdCBkZXBlbmRlbmNpZXMgPSBtYXliZVVud3JhcEZuKGRlZi5kZXBlbmRlbmNpZXMgPz8gW10pO1xuICAgICAgICAgIGRlcGVuZGVuY2llcy5mb3JFYWNoKChkZXBlbmRlbmN5KSA9PiB7XG4gICAgICAgICAgICAvLyBOb3RlOiBpbiBBT1QsIHRoZSBgZGVwZW5kZW5jaWVzYCBtaWdodCBhbHNvIGNvbnRhaW4gcmVndWxhclxuICAgICAgICAgICAgLy8gKE5nTW9kdWxlLWJhc2VkKSBDb21wb25lbnQsIERpcmVjdGl2ZSBhbmQgUGlwZXMsIHNvIHdlIGhhbmRsZVxuICAgICAgICAgICAgLy8gdGhlbSBzZXBhcmF0ZWx5IGFuZCBwcm9jZWVkIHdpdGggcmVjdXJzaXZlIHByb2Nlc3MgZm9yIHN0YW5kYWxvbmVcbiAgICAgICAgICAgIC8vIENvbXBvbmVudHMgYW5kIE5nTW9kdWxlcyBvbmx5LlxuICAgICAgICAgICAgaWYgKGlzU3RhbmRhbG9uZUNvbXBvbmVudChkZXBlbmRlbmN5KSB8fCBoYXNOZ01vZHVsZURlZihkZXBlbmRlbmN5KSkge1xuICAgICAgICAgICAgICBxdWV1ZVR5cGVzRnJvbU1vZHVsZXNBcnJheVJlY3VyKFtkZXBlbmRlbmN5XSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLnF1ZXVlVHlwZShkZXBlbmRlbmN5LCBudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gICAgcXVldWVUeXBlc0Zyb21Nb2R1bGVzQXJyYXlSZWN1cihhcnIpO1xuICB9XG5cbiAgLy8gV2hlbiBtb2R1bGUgb3ZlcnJpZGVzICh2aWEgYFRlc3RCZWQub3ZlcnJpZGVNb2R1bGVgKSBhcmUgcHJlc2VudCwgaXQgbWlnaHQgYWZmZWN0IGFsbCBtb2R1bGVzXG4gIC8vIHRoYXQgaW1wb3J0IChldmVuIHRyYW5zaXRpdmVseSkgYW4gb3ZlcnJpZGRlbiBvbmUuIEZvciBhbGwgYWZmZWN0ZWQgbW9kdWxlcyB3ZSBuZWVkIHRvXG4gIC8vIHJlY2FsY3VsYXRlIHRoZWlyIHNjb3BlcyBmb3IgYSBnaXZlbiB0ZXN0IHJ1biBhbmQgcmVzdG9yZSBvcmlnaW5hbCBzY29wZXMgYXQgdGhlIGVuZC4gVGhlIGdvYWxcbiAgLy8gb2YgdGhpcyBmdW5jdGlvbiBpcyB0byBjb2xsZWN0IGFsbCBhZmZlY3RlZCBtb2R1bGVzIGluIGEgc2V0IGZvciBmdXJ0aGVyIHByb2Nlc3NpbmcuIEV4YW1wbGU6XG4gIC8vIGlmIHdlIGhhdmUgdGhlIGZvbGxvd2luZyBtb2R1bGUgaGllcmFyY2h5OiBBIC0+IEIgLT4gQyAod2hlcmUgYC0+YCBtZWFucyBgaW1wb3J0c2ApIGFuZCBtb2R1bGVcbiAgLy8gYENgIGlzIG92ZXJyaWRkZW4sIHdlIGNvbnNpZGVyIGBBYCBhbmQgYEJgIGFzIGFmZmVjdGVkLCBzaW5jZSB0aGVpciBzY29wZXMgbWlnaHQgYmVjb21lXG4gIC8vIGludmFsaWRhdGVkIHdpdGggdGhlIG92ZXJyaWRlLlxuICBwcml2YXRlIGNvbGxlY3RNb2R1bGVzQWZmZWN0ZWRCeU92ZXJyaWRlcyhhcnI6IGFueVtdKTogU2V0PE5nTW9kdWxlVHlwZTxhbnk+PiB7XG4gICAgY29uc3Qgc2Vlbk1vZHVsZXMgPSBuZXcgU2V0PE5nTW9kdWxlVHlwZTxhbnk+PigpO1xuICAgIGNvbnN0IGFmZmVjdGVkTW9kdWxlcyA9IG5ldyBTZXQ8TmdNb2R1bGVUeXBlPGFueT4+KCk7XG4gICAgY29uc3QgY2FsY0FmZmVjdGVkTW9kdWxlc1JlY3VyID0gKGFycjogYW55W10sIHBhdGg6IE5nTW9kdWxlVHlwZTxhbnk+W10pOiB2b2lkID0+IHtcbiAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgYXJyKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIC8vIElmIHRoZSB2YWx1ZSBpcyBhbiBhcnJheSwganVzdCBmbGF0dGVuIGl0IChieSBpbnZva2luZyB0aGlzIGZ1bmN0aW9uIHJlY3Vyc2l2ZWx5KSxcbiAgICAgICAgICAvLyBrZWVwaW5nIFwicGF0aFwiIHRoZSBzYW1lLlxuICAgICAgICAgIGNhbGNBZmZlY3RlZE1vZHVsZXNSZWN1cih2YWx1ZSwgcGF0aCk7XG4gICAgICAgIH0gZWxzZSBpZiAoaGFzTmdNb2R1bGVEZWYodmFsdWUpKSB7XG4gICAgICAgICAgaWYgKHNlZW5Nb2R1bGVzLmhhcyh2YWx1ZSkpIHtcbiAgICAgICAgICAgIC8vIElmIHdlJ3ZlIHNlZW4gdGhpcyBtb2R1bGUgYmVmb3JlIGFuZCBpdCdzIGluY2x1ZGVkIGludG8gXCJhZmZlY3RlZCBtb2R1bGVzXCIgbGlzdCwgbWFya1xuICAgICAgICAgICAgLy8gdGhlIHdob2xlIHBhdGggdGhhdCBsZWFkcyB0byB0aGF0IG1vZHVsZSBhcyBhZmZlY3RlZCwgYnV0IGRvIG5vdCBkZXNjZW5kIGludG8gaXRzXG4gICAgICAgICAgICAvLyBpbXBvcnRzLCBzaW5jZSB3ZSBhbHJlYWR5IGV4YW1pbmVkIHRoZW0gYmVmb3JlLlxuICAgICAgICAgICAgaWYgKGFmZmVjdGVkTW9kdWxlcy5oYXModmFsdWUpKSB7XG4gICAgICAgICAgICAgIHBhdGguZm9yRWFjaChpdGVtID0+IGFmZmVjdGVkTW9kdWxlcy5hZGQoaXRlbSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNlZW5Nb2R1bGVzLmFkZCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKHRoaXMub3ZlcnJpZGRlbk1vZHVsZXMuaGFzKHZhbHVlKSkge1xuICAgICAgICAgICAgcGF0aC5mb3JFYWNoKGl0ZW0gPT4gYWZmZWN0ZWRNb2R1bGVzLmFkZChpdGVtKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIEV4YW1pbmUgbW9kdWxlIGltcG9ydHMgcmVjdXJzaXZlbHkgdG8gbG9vayBmb3Igb3ZlcnJpZGRlbiBtb2R1bGVzLlxuICAgICAgICAgIGNvbnN0IG1vZHVsZURlZiA9ICh2YWx1ZSBhcyBhbnkpW05HX01PRF9ERUZdO1xuICAgICAgICAgIGNhbGNBZmZlY3RlZE1vZHVsZXNSZWN1cihtYXliZVVud3JhcEZuKG1vZHVsZURlZi5pbXBvcnRzKSwgcGF0aC5jb25jYXQodmFsdWUpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gICAgY2FsY0FmZmVjdGVkTW9kdWxlc1JlY3VyKGFyciwgW10pO1xuICAgIHJldHVybiBhZmZlY3RlZE1vZHVsZXM7XG4gIH1cblxuICAvKipcbiAgICogUHJlc2VydmUgYW4gb3JpZ2luYWwgZGVmIChzdWNoIGFzIMm1bW9kLCDJtWluaiwgZXRjKSBiZWZvcmUgYXBwbHlpbmcgYW4gb3ZlcnJpZGUuXG4gICAqIE5vdGU6IG9uZSBjbGFzcyBtYXkgaGF2ZSBtdWx0aXBsZSBkZWZzIChmb3IgZXhhbXBsZTogybVtb2QgYW5kIMm1aW5qIGluIGNhc2Ugb2ZcbiAgICogYW4gTmdNb2R1bGUpLiBJZiB0aGVyZSBpcyBhIGRlZiBpbiBhIHNldCBhbHJlYWR5LCBkb24ndCBvdmVycmlkZSBpdCwgc2luY2VcbiAgICogYW4gb3JpZ2luYWwgb25lIHNob3VsZCBiZSByZXN0b3JlZCBhdCB0aGUgZW5kIG9mIGEgdGVzdC5cbiAgICovXG4gIHByaXZhdGUgbWF5YmVTdG9yZU5nRGVmKHByb3A6IHN0cmluZywgdHlwZTogVHlwZTxhbnk+KSB7XG4gICAgaWYgKCF0aGlzLmluaXRpYWxOZ0RlZnMuaGFzKHR5cGUpKSB7XG4gICAgICB0aGlzLmluaXRpYWxOZ0RlZnMuc2V0KHR5cGUsIG5ldyBNYXAoKSk7XG4gICAgfVxuICAgIGNvbnN0IGN1cnJlbnREZWZzID0gdGhpcy5pbml0aWFsTmdEZWZzLmdldCh0eXBlKSE7XG4gICAgaWYgKCFjdXJyZW50RGVmcy5oYXMocHJvcCkpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnREZWYgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHR5cGUsIHByb3ApO1xuICAgICAgY3VycmVudERlZnMuc2V0KHByb3AsIGN1cnJlbnREZWYpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RvcmVGaWVsZE9mRGVmT25UeXBlKHR5cGU6IFR5cGU8YW55PiwgZGVmRmllbGQ6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBkZWY6IGFueSA9ICh0eXBlIGFzIGFueSlbZGVmRmllbGRdO1xuICAgIGNvbnN0IG9yaWdpbmFsVmFsdWU6IGFueSA9IGRlZltmaWVsZE5hbWVdO1xuICAgIHRoaXMuZGVmQ2xlYW51cE9wcy5wdXNoKHtvYmplY3Q6IGRlZiwgZmllbGROYW1lLCBvcmlnaW5hbFZhbHVlfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXJzIGN1cnJlbnQgY29tcG9uZW50cyByZXNvbHV0aW9uIHF1ZXVlLCBidXQgc3RvcmVzIHRoZSBzdGF0ZSBvZiB0aGUgcXVldWUsIHNvIHdlIGNhblxuICAgKiByZXN0b3JlIGl0IGxhdGVyLiBDbGVhcmluZyB0aGUgcXVldWUgaXMgcmVxdWlyZWQgYmVmb3JlIHdlIHRyeSB0byBjb21waWxlIGNvbXBvbmVudHMgKHZpYVxuICAgKiBgVGVzdEJlZC5jb21waWxlQ29tcG9uZW50c2ApLCBzbyB0aGF0IGNvbXBvbmVudCBkZWZzIGFyZSBpbiBzeW5jIHdpdGggdGhlIHJlc29sdXRpb24gcXVldWUuXG4gICAqL1xuICBwcml2YXRlIGNsZWFyQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlKCkge1xuICAgIGlmICh0aGlzLm9yaWdpbmFsQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlID09PSBudWxsKSB7XG4gICAgICB0aGlzLm9yaWdpbmFsQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICBjbGVhclJlc29sdXRpb25PZkNvbXBvbmVudFJlc291cmNlc1F1ZXVlKCkuZm9yRWFjaChcbiAgICAgICAgKHZhbHVlLCBrZXkpID0+IHRoaXMub3JpZ2luYWxDb21wb25lbnRSZXNvbHV0aW9uUXVldWUhLnNldChrZXksIHZhbHVlKSk7XG4gIH1cblxuICAvKlxuICAgKiBSZXN0b3JlcyBjb21wb25lbnQgcmVzb2x1dGlvbiBxdWV1ZSB0byB0aGUgcHJldmlvdXNseSBzYXZlZCBzdGF0ZS4gVGhpcyBvcGVyYXRpb24gaXMgcGVyZm9ybWVkXG4gICAqIGFzIGEgcGFydCBvZiByZXN0b3JpbmcgdGhlIHN0YXRlIGFmdGVyIGNvbXBsZXRpb24gb2YgdGhlIGN1cnJlbnQgc2V0IG9mIHRlc3RzICh0aGF0IG1pZ2h0XG4gICAqIHBvdGVudGlhbGx5IG11dGF0ZSB0aGUgc3RhdGUpLlxuICAgKi9cbiAgcHJpdmF0ZSByZXN0b3JlQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlKCkge1xuICAgIGlmICh0aGlzLm9yaWdpbmFsQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlICE9PSBudWxsKSB7XG4gICAgICByZXN0b3JlQ29tcG9uZW50UmVzb2x1dGlvblF1ZXVlKHRoaXMub3JpZ2luYWxDb21wb25lbnRSZXNvbHV0aW9uUXVldWUpO1xuICAgICAgdGhpcy5vcmlnaW5hbENvbXBvbmVudFJlc29sdXRpb25RdWV1ZSA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcmVzdG9yZU9yaWdpbmFsU3RhdGUoKTogdm9pZCB7XG4gICAgLy8gUHJvY2VzcyBjbGVhbnVwIG9wcyBpbiByZXZlcnNlIG9yZGVyIHNvIHRoZSBmaWVsZCdzIG9yaWdpbmFsIHZhbHVlIGlzIHJlc3RvcmVkIGNvcnJlY3RseSAoaW5cbiAgICAvLyBjYXNlIHRoZXJlIHdlcmUgbXVsdGlwbGUgb3ZlcnJpZGVzIGZvciB0aGUgc2FtZSBmaWVsZCkuXG4gICAgZm9yRWFjaFJpZ2h0KHRoaXMuZGVmQ2xlYW51cE9wcywgKG9wOiBDbGVhbnVwT3BlcmF0aW9uKSA9PiB7XG4gICAgICBvcC5vYmplY3Rbb3AuZmllbGROYW1lXSA9IG9wLm9yaWdpbmFsVmFsdWU7XG4gICAgfSk7XG4gICAgLy8gUmVzdG9yZSBpbml0aWFsIGNvbXBvbmVudC9kaXJlY3RpdmUvcGlwZSBkZWZzXG4gICAgdGhpcy5pbml0aWFsTmdEZWZzLmZvckVhY2goXG4gICAgICAgIChkZWZzOiBNYXA8c3RyaW5nLCBQcm9wZXJ0eURlc2NyaXB0b3J8dW5kZWZpbmVkPiwgdHlwZTogVHlwZTxhbnk+KSA9PiB7XG4gICAgICAgICAgZGVmcy5mb3JFYWNoKChkZXNjcmlwdG9yLCBwcm9wKSA9PiB7XG4gICAgICAgICAgICBpZiAoIWRlc2NyaXB0b3IpIHtcbiAgICAgICAgICAgICAgLy8gRGVsZXRlIG9wZXJhdGlvbnMgYXJlIGdlbmVyYWxseSB1bmRlc2lyYWJsZSBzaW5jZSB0aGV5IGhhdmUgcGVyZm9ybWFuY2VcbiAgICAgICAgICAgICAgLy8gaW1wbGljYXRpb25zIG9uIG9iamVjdHMgdGhleSB3ZXJlIGFwcGxpZWQgdG8uIEluIHRoaXMgcGFydGljdWxhciBjYXNlLCBzaXR1YXRpb25zXG4gICAgICAgICAgICAgIC8vIHdoZXJlIHRoaXMgY29kZSBpcyBpbnZva2VkIHNob3VsZCBiZSBxdWl0ZSByYXJlIHRvIGNhdXNlIGFueSBub3RpY2VhYmxlIGltcGFjdCxcbiAgICAgICAgICAgICAgLy8gc2luY2UgaXQncyBhcHBsaWVkIG9ubHkgdG8gc29tZSB0ZXN0IGNhc2VzIChmb3IgZXhhbXBsZSB3aGVuIGNsYXNzIHdpdGggbm9cbiAgICAgICAgICAgICAgLy8gYW5ub3RhdGlvbnMgZXh0ZW5kcyBzb21lIEBDb21wb25lbnQpIHdoZW4gd2UgbmVlZCB0byBjbGVhciAnybVjbXAnIGZpZWxkIG9uIGEgZ2l2ZW5cbiAgICAgICAgICAgICAgLy8gY2xhc3MgdG8gcmVzdG9yZSBpdHMgb3JpZ2luYWwgc3RhdGUgKGJlZm9yZSBhcHBseWluZyBvdmVycmlkZXMgYW5kIHJ1bm5pbmcgdGVzdHMpLlxuICAgICAgICAgICAgICBkZWxldGUgKHR5cGUgYXMgYW55KVtwcm9wXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0eXBlLCBwcm9wLCBkZXNjcmlwdG9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgdGhpcy5pbml0aWFsTmdEZWZzLmNsZWFyKCk7XG4gICAgdGhpcy5zY29wZXNXaXRoT3ZlcnJpZGRlblByb3ZpZGVycy5jbGVhcigpO1xuICAgIHRoaXMucmVzdG9yZUNvbXBvbmVudFJlc29sdXRpb25RdWV1ZSgpO1xuICAgIC8vIFJlc3RvcmUgdGhlIGxvY2FsZSBJRCB0byB0aGUgZGVmYXVsdCB2YWx1ZSwgdGhpcyBzaG91bGRuJ3QgYmUgbmVjZXNzYXJ5IGJ1dCB3ZSBuZXZlciBrbm93XG4gICAgc2V0TG9jYWxlSWQoREVGQVVMVF9MT0NBTEVfSUQpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb21waWxlVGVzdE1vZHVsZSgpOiB2b2lkIHtcbiAgICBjbGFzcyBSb290U2NvcGVNb2R1bGUge31cbiAgICBjb21waWxlTmdNb2R1bGVEZWZzKFJvb3RTY29wZU1vZHVsZSBhcyBOZ01vZHVsZVR5cGU8YW55Piwge1xuICAgICAgcHJvdmlkZXJzOiBbLi4udGhpcy5yb290UHJvdmlkZXJPdmVycmlkZXNdLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgbmdab25lID0gbmV3IE5nWm9uZSh7ZW5hYmxlTG9uZ1N0YWNrVHJhY2U6IHRydWV9KTtcbiAgICBjb25zdCBwcm92aWRlcnM6IFByb3ZpZGVyW10gPSBbXG4gICAgICBwcm92aWRlTmdab25lQ2hhbmdlRGV0ZWN0aW9uKG5nWm9uZSksXG4gICAgICB7cHJvdmlkZTogQ29tcGlsZXIsIHVzZUZhY3Rvcnk6ICgpID0+IG5ldyBSM1Rlc3RDb21waWxlcih0aGlzKX0sXG4gICAgICAuLi50aGlzLnByb3ZpZGVycyxcbiAgICAgIC4uLnRoaXMucHJvdmlkZXJPdmVycmlkZXMsXG4gICAgXTtcbiAgICBjb25zdCBpbXBvcnRzID0gW1Jvb3RTY29wZU1vZHVsZSwgdGhpcy5hZGRpdGlvbmFsTW9kdWxlVHlwZXMsIHRoaXMuaW1wb3J0cyB8fCBbXV07XG5cbiAgICAvLyBjbGFuZy1mb3JtYXQgb2ZmXG4gICAgY29tcGlsZU5nTW9kdWxlRGVmcyh0aGlzLnRlc3RNb2R1bGVUeXBlLCB7XG4gICAgICBkZWNsYXJhdGlvbnM6IHRoaXMuZGVjbGFyYXRpb25zLFxuICAgICAgaW1wb3J0cyxcbiAgICAgIHNjaGVtYXM6IHRoaXMuc2NoZW1hcyxcbiAgICAgIHByb3ZpZGVycyxcbiAgICB9LCAvKiBhbGxvd0R1cGxpY2F0ZURlY2xhcmF0aW9uc0luUm9vdCAqLyB0cnVlKTtcbiAgICAvLyBjbGFuZy1mb3JtYXQgb25cblxuICAgIHRoaXMuYXBwbHlQcm92aWRlck92ZXJyaWRlc0luU2NvcGUodGhpcy50ZXN0TW9kdWxlVHlwZSk7XG4gIH1cblxuICBnZXQgaW5qZWN0b3IoKTogSW5qZWN0b3Ige1xuICAgIGlmICh0aGlzLl9pbmplY3RvciAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2luamVjdG9yO1xuICAgIH1cblxuICAgIGNvbnN0IHByb3ZpZGVyczogUHJvdmlkZXJbXSA9IFtdO1xuICAgIGNvbnN0IGNvbXBpbGVyT3B0aW9ucyA9IHRoaXMucGxhdGZvcm0uaW5qZWN0b3IuZ2V0KENPTVBJTEVSX09QVElPTlMpO1xuICAgIGNvbXBpbGVyT3B0aW9ucy5mb3JFYWNoKG9wdHMgPT4ge1xuICAgICAgaWYgKG9wdHMucHJvdmlkZXJzKSB7XG4gICAgICAgIHByb3ZpZGVycy5wdXNoKG9wdHMucHJvdmlkZXJzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAodGhpcy5jb21waWxlclByb3ZpZGVycyAhPT0gbnVsbCkge1xuICAgICAgcHJvdmlkZXJzLnB1c2goLi4udGhpcy5jb21waWxlclByb3ZpZGVycyk7XG4gICAgfVxuXG4gICAgLy8gVE9ETyhvY29tYmUpOiBtYWtlIHRoaXMgd29yayB3aXRoIGFuIEluamVjdG9yIGRpcmVjdGx5IGluc3RlYWQgb2YgY3JlYXRpbmcgYSBtb2R1bGUgZm9yIGl0XG4gICAgY2xhc3MgQ29tcGlsZXJNb2R1bGUge31cbiAgICBjb21waWxlTmdNb2R1bGVEZWZzKENvbXBpbGVyTW9kdWxlIGFzIE5nTW9kdWxlVHlwZTxhbnk+LCB7cHJvdmlkZXJzfSk7XG5cbiAgICBjb25zdCBDb21waWxlck1vZHVsZUZhY3RvcnkgPSBuZXcgUjNOZ01vZHVsZUZhY3RvcnkoQ29tcGlsZXJNb2R1bGUpO1xuICAgIHRoaXMuX2luamVjdG9yID0gQ29tcGlsZXJNb2R1bGVGYWN0b3J5LmNyZWF0ZSh0aGlzLnBsYXRmb3JtLmluamVjdG9yKS5pbmplY3RvcjtcbiAgICByZXR1cm4gdGhpcy5faW5qZWN0b3I7XG4gIH1cblxuICAvLyBnZXQgb3ZlcnJpZGVzIGZvciBhIHNwZWNpZmljIHByb3ZpZGVyIChpZiBhbnkpXG4gIHByaXZhdGUgZ2V0U2luZ2xlUHJvdmlkZXJPdmVycmlkZXMocHJvdmlkZXI6IFByb3ZpZGVyKTogUHJvdmlkZXJ8bnVsbCB7XG4gICAgY29uc3QgdG9rZW4gPSBnZXRQcm92aWRlclRva2VuKHByb3ZpZGVyKTtcbiAgICByZXR1cm4gdGhpcy5wcm92aWRlck92ZXJyaWRlc0J5VG9rZW4uZ2V0KHRva2VuKSB8fCBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQcm92aWRlck92ZXJyaWRlcyhwcm92aWRlcnM/OiBBcnJheTxQcm92aWRlcnxJbnRlcm5hbEVudmlyb25tZW50UHJvdmlkZXJzPik6XG4gICAgICBQcm92aWRlcltdIHtcbiAgICBpZiAoIXByb3ZpZGVycyB8fCAhcHJvdmlkZXJzLmxlbmd0aCB8fCB0aGlzLnByb3ZpZGVyT3ZlcnJpZGVzQnlUb2tlbi5zaXplID09PSAwKSByZXR1cm4gW107XG4gICAgLy8gVGhlcmUgYXJlIHR3byBmbGF0dGVuaW5nIG9wZXJhdGlvbnMgaGVyZS4gVGhlIGlubmVyIGZsYXR0ZW5Qcm92aWRlcnMoKSBvcGVyYXRlcyBvbiB0aGVcbiAgICAvLyBtZXRhZGF0YSdzIHByb3ZpZGVycyBhbmQgYXBwbGllcyBhIG1hcHBpbmcgZnVuY3Rpb24gd2hpY2ggcmV0cmlldmVzIG92ZXJyaWRlcyBmb3IgZWFjaFxuICAgIC8vIGluY29taW5nIHByb3ZpZGVyLiBUaGUgb3V0ZXIgZmxhdHRlbigpIHRoZW4gZmxhdHRlbnMgdGhlIHByb2R1Y2VkIG92ZXJyaWRlcyBhcnJheS4gSWYgdGhpcyBpc1xuICAgIC8vIG5vdCBkb25lLCB0aGUgYXJyYXkgY2FuIGNvbnRhaW4gb3RoZXIgZW1wdHkgYXJyYXlzIChlLmcuIGBbW10sIFtdXWApIHdoaWNoIGxlYWsgaW50byB0aGVcbiAgICAvLyBwcm92aWRlcnMgYXJyYXkgYW5kIGNvbnRhbWluYXRlIGFueSBlcnJvciBtZXNzYWdlcyB0aGF0IG1pZ2h0IGJlIGdlbmVyYXRlZC5cbiAgICByZXR1cm4gZmxhdHRlbihmbGF0dGVuUHJvdmlkZXJzKFxuICAgICAgICBwcm92aWRlcnMsIChwcm92aWRlcjogUHJvdmlkZXIpID0+IHRoaXMuZ2V0U2luZ2xlUHJvdmlkZXJPdmVycmlkZXMocHJvdmlkZXIpIHx8IFtdKSk7XG4gIH1cblxuICBwcml2YXRlIGdldE92ZXJyaWRkZW5Qcm92aWRlcnMocHJvdmlkZXJzPzogQXJyYXk8UHJvdmlkZXJ8SW50ZXJuYWxFbnZpcm9ubWVudFByb3ZpZGVycz4pOlxuICAgICAgUHJvdmlkZXJbXSB7XG4gICAgaWYgKCFwcm92aWRlcnMgfHwgIXByb3ZpZGVycy5sZW5ndGggfHwgdGhpcy5wcm92aWRlck92ZXJyaWRlc0J5VG9rZW4uc2l6ZSA9PT0gMCkgcmV0dXJuIFtdO1xuXG4gICAgY29uc3QgZmxhdHRlbmVkUHJvdmlkZXJzID0gZmxhdHRlblByb3ZpZGVycyhwcm92aWRlcnMpO1xuICAgIGNvbnN0IG92ZXJyaWRlcyA9IHRoaXMuZ2V0UHJvdmlkZXJPdmVycmlkZXMoZmxhdHRlbmVkUHJvdmlkZXJzKTtcbiAgICBjb25zdCBvdmVycmlkZGVuUHJvdmlkZXJzID0gWy4uLmZsYXR0ZW5lZFByb3ZpZGVycywgLi4ub3ZlcnJpZGVzXTtcbiAgICBjb25zdCBmaW5hbDogUHJvdmlkZXJbXSA9IFtdO1xuICAgIGNvbnN0IHNlZW5PdmVycmlkZGVuUHJvdmlkZXJzID0gbmV3IFNldDxQcm92aWRlcj4oKTtcblxuICAgIC8vIFdlIGl0ZXJhdGUgdGhyb3VnaCB0aGUgbGlzdCBvZiBwcm92aWRlcnMgaW4gcmV2ZXJzZSBvcmRlciB0byBtYWtlIHN1cmUgcHJvdmlkZXIgb3ZlcnJpZGVzXG4gICAgLy8gdGFrZSBwcmVjZWRlbmNlIG92ZXIgdGhlIHZhbHVlcyBkZWZpbmVkIGluIHByb3ZpZGVyIGxpc3QuIFdlIGFsc28gZmlsdGVyIG91dCBhbGwgcHJvdmlkZXJzXG4gICAgLy8gdGhhdCBoYXZlIG92ZXJyaWRlcywga2VlcGluZyBvdmVycmlkZGVuIHZhbHVlcyBvbmx5LiBUaGlzIGlzIG5lZWRlZCwgc2luY2UgcHJlc2VuY2Ugb2YgYVxuICAgIC8vIHByb3ZpZGVyIHdpdGggYG5nT25EZXN0cm95YCBob29rIHdpbGwgY2F1c2UgdGhpcyBob29rIHRvIGJlIHJlZ2lzdGVyZWQgYW5kIGludm9rZWQgbGF0ZXIuXG4gICAgZm9yRWFjaFJpZ2h0KG92ZXJyaWRkZW5Qcm92aWRlcnMsIChwcm92aWRlcjogYW55KSA9PiB7XG4gICAgICBjb25zdCB0b2tlbjogYW55ID0gZ2V0UHJvdmlkZXJUb2tlbihwcm92aWRlcik7XG4gICAgICBpZiAodGhpcy5wcm92aWRlck92ZXJyaWRlc0J5VG9rZW4uaGFzKHRva2VuKSkge1xuICAgICAgICBpZiAoIXNlZW5PdmVycmlkZGVuUHJvdmlkZXJzLmhhcyh0b2tlbikpIHtcbiAgICAgICAgICBzZWVuT3ZlcnJpZGRlblByb3ZpZGVycy5hZGQodG9rZW4pO1xuICAgICAgICAgIC8vIFRyZWF0IGFsbCBvdmVycmlkZGVuIHByb3ZpZGVycyBhcyBge211bHRpOiBmYWxzZX1gIChldmVuIGlmIGl0J3MgYSBtdWx0aS1wcm92aWRlcikgdG9cbiAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhhdCBwcm92aWRlZCBvdmVycmlkZSB0YWtlcyBoaWdoZXN0IHByZWNlZGVuY2UgYW5kIGlzIG5vdCBjb21iaW5lZCB3aXRoXG4gICAgICAgICAgLy8gb3RoZXIgaW5zdGFuY2VzIG9mIHRoZSBzYW1lIG11bHRpIHByb3ZpZGVyLlxuICAgICAgICAgIGZpbmFsLnVuc2hpZnQoey4uLnByb3ZpZGVyLCBtdWx0aTogZmFsc2V9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZmluYWwudW5zaGlmdChwcm92aWRlcik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGZpbmFsO1xuICB9XG5cbiAgcHJpdmF0ZSBoYXNQcm92aWRlck92ZXJyaWRlcyhwcm92aWRlcnM/OiBBcnJheTxQcm92aWRlcnxJbnRlcm5hbEVudmlyb25tZW50UHJvdmlkZXJzPik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmdldFByb3ZpZGVyT3ZlcnJpZGVzKHByb3ZpZGVycykubGVuZ3RoID4gMDtcbiAgfVxuXG4gIHByaXZhdGUgcGF0Y2hEZWZXaXRoUHJvdmlkZXJPdmVycmlkZXMoZGVjbGFyYXRpb246IFR5cGU8YW55PiwgZmllbGQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGRlZiA9IChkZWNsYXJhdGlvbiBhcyBhbnkpW2ZpZWxkXTtcbiAgICBpZiAoZGVmICYmIGRlZi5wcm92aWRlcnNSZXNvbHZlcikge1xuICAgICAgdGhpcy5tYXliZVN0b3JlTmdEZWYoZmllbGQsIGRlY2xhcmF0aW9uKTtcblxuICAgICAgY29uc3QgcmVzb2x2ZXIgPSBkZWYucHJvdmlkZXJzUmVzb2x2ZXI7XG4gICAgICBjb25zdCBwcm9jZXNzUHJvdmlkZXJzRm4gPSAocHJvdmlkZXJzOiBQcm92aWRlcltdKSA9PiB0aGlzLmdldE92ZXJyaWRkZW5Qcm92aWRlcnMocHJvdmlkZXJzKTtcbiAgICAgIHRoaXMuc3RvcmVGaWVsZE9mRGVmT25UeXBlKGRlY2xhcmF0aW9uLCBmaWVsZCwgJ3Byb3ZpZGVyc1Jlc29sdmVyJyk7XG4gICAgICBkZWYucHJvdmlkZXJzUmVzb2x2ZXIgPSAobmdEZWY6IERpcmVjdGl2ZURlZjxhbnk+KSA9PiByZXNvbHZlcihuZ0RlZiwgcHJvY2Vzc1Byb3ZpZGVyc0ZuKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5pdFJlc29sdmVycygpOiBSZXNvbHZlcnMge1xuICByZXR1cm4ge1xuICAgIG1vZHVsZTogbmV3IE5nTW9kdWxlUmVzb2x2ZXIoKSxcbiAgICBjb21wb25lbnQ6IG5ldyBDb21wb25lbnRSZXNvbHZlcigpLFxuICAgIGRpcmVjdGl2ZTogbmV3IERpcmVjdGl2ZVJlc29sdmVyKCksXG4gICAgcGlwZTogbmV3IFBpcGVSZXNvbHZlcigpXG4gIH07XG59XG5cbmZ1bmN0aW9uIGlzU3RhbmRhbG9uZUNvbXBvbmVudDxUPih2YWx1ZTogVHlwZTxUPik6IHZhbHVlIGlzIENvbXBvbmVudFR5cGU8VD4ge1xuICBjb25zdCBkZWYgPSBnZXRDb21wb25lbnREZWYodmFsdWUpO1xuICByZXR1cm4gISFkZWY/LnN0YW5kYWxvbmU7XG59XG5cbmZ1bmN0aW9uIGdldENvbXBvbmVudERlZih2YWx1ZTogQ29tcG9uZW50VHlwZTx1bmtub3duPik6IENvbXBvbmVudERlZjx1bmtub3duPjtcbmZ1bmN0aW9uIGdldENvbXBvbmVudERlZih2YWx1ZTogVHlwZTx1bmtub3duPik6IENvbXBvbmVudERlZjx1bmtub3duPnxudWxsO1xuZnVuY3Rpb24gZ2V0Q29tcG9uZW50RGVmKHZhbHVlOiBUeXBlPHVua25vd24+KTogQ29tcG9uZW50RGVmPHVua25vd24+fG51bGwge1xuICByZXR1cm4gKHZhbHVlIGFzIGFueSkuybVjbXAgPz8gbnVsbDtcbn1cblxuZnVuY3Rpb24gaGFzTmdNb2R1bGVEZWY8VD4odmFsdWU6IFR5cGU8VD4pOiB2YWx1ZSBpcyBOZ01vZHVsZVR5cGU8VD4ge1xuICByZXR1cm4gdmFsdWUuaGFzT3duUHJvcGVydHkoJ8m1bW9kJyk7XG59XG5cbmZ1bmN0aW9uIGlzTmdNb2R1bGU8VD4odmFsdWU6IFR5cGU8VD4pOiBib29sZWFuIHtcbiAgcmV0dXJuIGhhc05nTW9kdWxlRGVmKHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gbWF5YmVVbndyYXBGbjxUPihtYXliZUZuOiAoKCkgPT4gVCl8VCk6IFQge1xuICByZXR1cm4gbWF5YmVGbiBpbnN0YW5jZW9mIEZ1bmN0aW9uID8gbWF5YmVGbigpIDogbWF5YmVGbjtcbn1cblxuZnVuY3Rpb24gZmxhdHRlbjxUPih2YWx1ZXM6IGFueVtdKTogVFtdIHtcbiAgY29uc3Qgb3V0OiBUW10gPSBbXTtcbiAgdmFsdWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgb3V0LnB1c2goLi4uZmxhdHRlbjxUPih2YWx1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXQucHVzaCh2YWx1ZSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gaWRlbnRpdHlGbjxUPih2YWx1ZTogVCk6IFQge1xuICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIGZsYXR0ZW5Qcm92aWRlcnM8VD4oXG4gICAgcHJvdmlkZXJzOiBBcnJheTxQcm92aWRlcnxJbnRlcm5hbEVudmlyb25tZW50UHJvdmlkZXJzPiwgbWFwRm46IChwcm92aWRlcjogUHJvdmlkZXIpID0+IFQpOiBUW107XG5mdW5jdGlvbiBmbGF0dGVuUHJvdmlkZXJzKHByb3ZpZGVyczogQXJyYXk8UHJvdmlkZXJ8SW50ZXJuYWxFbnZpcm9ubWVudFByb3ZpZGVycz4pOiBQcm92aWRlcltdO1xuZnVuY3Rpb24gZmxhdHRlblByb3ZpZGVycyhcbiAgICBwcm92aWRlcnM6IEFycmF5PFByb3ZpZGVyfEludGVybmFsRW52aXJvbm1lbnRQcm92aWRlcnM+LFxuICAgIG1hcEZuOiAocHJvdmlkZXI6IFByb3ZpZGVyKSA9PiBhbnkgPSBpZGVudGl0eUZuKTogYW55W10ge1xuICBjb25zdCBvdXQ6IGFueVtdID0gW107XG4gIGZvciAobGV0IHByb3ZpZGVyIG9mIHByb3ZpZGVycykge1xuICAgIGlmIChpc0Vudmlyb25tZW50UHJvdmlkZXJzKHByb3ZpZGVyKSkge1xuICAgICAgcHJvdmlkZXIgPSBwcm92aWRlci7JtXByb3ZpZGVycztcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocHJvdmlkZXIpKSB7XG4gICAgICBvdXQucHVzaCguLi5mbGF0dGVuUHJvdmlkZXJzKHByb3ZpZGVyLCBtYXBGbikpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXQucHVzaChtYXBGbihwcm92aWRlcikpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gb3V0O1xufVxuXG5mdW5jdGlvbiBnZXRQcm92aWRlckZpZWxkKHByb3ZpZGVyOiBQcm92aWRlciwgZmllbGQ6IHN0cmluZykge1xuICByZXR1cm4gcHJvdmlkZXIgJiYgdHlwZW9mIHByb3ZpZGVyID09PSAnb2JqZWN0JyAmJiAocHJvdmlkZXIgYXMgYW55KVtmaWVsZF07XG59XG5cbmZ1bmN0aW9uIGdldFByb3ZpZGVyVG9rZW4ocHJvdmlkZXI6IFByb3ZpZGVyKSB7XG4gIHJldHVybiBnZXRQcm92aWRlckZpZWxkKHByb3ZpZGVyLCAncHJvdmlkZScpIHx8IHByb3ZpZGVyO1xufVxuXG5mdW5jdGlvbiBpc01vZHVsZVdpdGhQcm92aWRlcnModmFsdWU6IGFueSk6IHZhbHVlIGlzIE1vZHVsZVdpdGhQcm92aWRlcnM8YW55PiB7XG4gIHJldHVybiB2YWx1ZS5oYXNPd25Qcm9wZXJ0eSgnbmdNb2R1bGUnKTtcbn1cblxuZnVuY3Rpb24gZm9yRWFjaFJpZ2h0PFQ+KHZhbHVlczogVFtdLCBmbjogKHZhbHVlOiBULCBpZHg6IG51bWJlcikgPT4gdm9pZCk6IHZvaWQge1xuICBmb3IgKGxldCBpZHggPSB2YWx1ZXMubGVuZ3RoIC0gMTsgaWR4ID49IDA7IGlkeC0tKSB7XG4gICAgZm4odmFsdWVzW2lkeF0sIGlkeCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW52YWxpZFR5cGVFcnJvcihuYW1lOiBzdHJpbmcsIGV4cGVjdGVkVHlwZTogc3RyaW5nKTogRXJyb3Ige1xuICByZXR1cm4gbmV3IEVycm9yKGAke25hbWV9IGNsYXNzIGRvZXNuJ3QgaGF2ZSBAJHtleHBlY3RlZFR5cGV9IGRlY29yYXRvciBvciBpcyBtaXNzaW5nIG1ldGFkYXRhLmApO1xufVxuXG5jbGFzcyBSM1Rlc3RDb21waWxlciBpbXBsZW1lbnRzIENvbXBpbGVyIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0ZXN0QmVkOiBUZXN0QmVkQ29tcGlsZXIpIHt9XG5cbiAgY29tcGlsZU1vZHVsZVN5bmM8VD4obW9kdWxlVHlwZTogVHlwZTxUPik6IE5nTW9kdWxlRmFjdG9yeTxUPiB7XG4gICAgdGhpcy50ZXN0QmVkLl9jb21waWxlTmdNb2R1bGVTeW5jKG1vZHVsZVR5cGUpO1xuICAgIHJldHVybiBuZXcgUjNOZ01vZHVsZUZhY3RvcnkobW9kdWxlVHlwZSk7XG4gIH1cblxuICBhc3luYyBjb21waWxlTW9kdWxlQXN5bmM8VD4obW9kdWxlVHlwZTogVHlwZTxUPik6IFByb21pc2U8TmdNb2R1bGVGYWN0b3J5PFQ+PiB7XG4gICAgYXdhaXQgdGhpcy50ZXN0QmVkLl9jb21waWxlTmdNb2R1bGVBc3luYyhtb2R1bGVUeXBlKTtcbiAgICByZXR1cm4gbmV3IFIzTmdNb2R1bGVGYWN0b3J5KG1vZHVsZVR5cGUpO1xuICB9XG5cbiAgY29tcGlsZU1vZHVsZUFuZEFsbENvbXBvbmVudHNTeW5jPFQ+KG1vZHVsZVR5cGU6IFR5cGU8VD4pOiBNb2R1bGVXaXRoQ29tcG9uZW50RmFjdG9yaWVzPFQ+IHtcbiAgICBjb25zdCBuZ01vZHVsZUZhY3RvcnkgPSB0aGlzLmNvbXBpbGVNb2R1bGVTeW5jKG1vZHVsZVR5cGUpO1xuICAgIGNvbnN0IGNvbXBvbmVudEZhY3RvcmllcyA9IHRoaXMudGVzdEJlZC5fZ2V0Q29tcG9uZW50RmFjdG9yaWVzKG1vZHVsZVR5cGUgYXMgTmdNb2R1bGVUeXBlPFQ+KTtcbiAgICByZXR1cm4gbmV3IE1vZHVsZVdpdGhDb21wb25lbnRGYWN0b3JpZXMobmdNb2R1bGVGYWN0b3J5LCBjb21wb25lbnRGYWN0b3JpZXMpO1xuICB9XG5cbiAgYXN5bmMgY29tcGlsZU1vZHVsZUFuZEFsbENvbXBvbmVudHNBc3luYzxUPihtb2R1bGVUeXBlOiBUeXBlPFQ+KTpcbiAgICAgIFByb21pc2U8TW9kdWxlV2l0aENvbXBvbmVudEZhY3RvcmllczxUPj4ge1xuICAgIGNvbnN0IG5nTW9kdWxlRmFjdG9yeSA9IGF3YWl0IHRoaXMuY29tcGlsZU1vZHVsZUFzeW5jKG1vZHVsZVR5cGUpO1xuICAgIGNvbnN0IGNvbXBvbmVudEZhY3RvcmllcyA9IHRoaXMudGVzdEJlZC5fZ2V0Q29tcG9uZW50RmFjdG9yaWVzKG1vZHVsZVR5cGUgYXMgTmdNb2R1bGVUeXBlPFQ+KTtcbiAgICByZXR1cm4gbmV3IE1vZHVsZVdpdGhDb21wb25lbnRGYWN0b3JpZXMobmdNb2R1bGVGYWN0b3J5LCBjb21wb25lbnRGYWN0b3JpZXMpO1xuICB9XG5cbiAgY2xlYXJDYWNoZSgpOiB2b2lkIHt9XG5cbiAgY2xlYXJDYWNoZUZvcih0eXBlOiBUeXBlPGFueT4pOiB2b2lkIHt9XG5cbiAgZ2V0TW9kdWxlSWQobW9kdWxlVHlwZTogVHlwZTxhbnk+KTogc3RyaW5nfHVuZGVmaW5lZCB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMudGVzdEJlZC5fZ2V0TW9kdWxlUmVzb2x2ZXIoKS5yZXNvbHZlKG1vZHVsZVR5cGUpO1xuICAgIHJldHVybiBtZXRhICYmIG1ldGEuaWQgfHwgdW5kZWZpbmVkO1xuICB9XG59XG4iXX0=
|