{"version":3,"file":"testing.mjs","sources":["../../../../../../packages/core/testing/src/async.ts","../../../../../../packages/core/testing/src/component_fixture.ts","../../../../../../packages/core/testing/src/fake_async.ts","../../../../../../packages/core/testing/src/test_bed_common.ts","../../../../../../packages/core/src/metadata/resource_loading.ts","../../../../../../packages/core/src/util/global.ts","../../../../../../packages/core/src/compiler/compiler_facade_interface.ts","../../../../../../packages/core/src/compiler/compiler_facade.ts","../../../../../../packages/core/src/util/property.ts","../../../../../../packages/core/src/util/stringify.ts","../../../../../../packages/core/src/di/forward_ref.ts","../../../../../../packages/core/src/di/interface/defs.ts","../../../../../../packages/core/src/error_details_base_url.ts","../../../../../../packages/core/src/errors.ts","../../../../../../packages/core/src/interface/type.ts","../../../../../../packages/core/src/util/assert.ts","../../../../../../packages/core/src/util/array_utils.ts","../../../../../../packages/core/src/util/closure.ts","../../../../../../packages/core/src/util/decorators.ts","../../../../../../packages/core/src/reflection/reflection_capabilities.ts","../../../../../../packages/core/src/util/ng_dev_mode.ts","../../../../../../packages/core/src/render3/debug/injector_profiler.ts","../../../../../../packages/core/src/di/interface/provider.ts","../../../../../../packages/core/src/render3/util/stringify_utils.ts","../../../../../../packages/core/src/render3/errors_di.ts","../../../../../../packages/core/src/di/interface/injector.ts","../../../../../../packages/core/src/di/inject_switch.ts","../../../../../../packages/core/src/di/injector_compatibility.ts","../../../../../../packages/core/src/di/metadata.ts","../../../../../../packages/core/src/change_detection/constants.ts","../../../../../../packages/core/src/metadata/view.ts","../../../../../../packages/core/src/util/empty.ts","../../../../../../packages/core/src/render3/fields.ts","../../../../../../packages/core/src/render3/styling/class_differ.ts","../../../../../../packages/core/src/render3/util/attrs_utils.ts","../../../../../../packages/core/src/render3/node_selector_matcher.ts","../../../../../../packages/core/src/render3/definition.ts","../../../../../../packages/core/src/render3/interfaces/view.ts","../../../../../../packages/core/src/render3/interfaces/container.ts","../../../../../../packages/core/src/render3/interfaces/type_checks.ts","../../../../../../packages/core/src/render3/assert.ts","../../../../../../packages/core/src/render3/definition_factory.ts","../../../../../../packages/core/src/signals/src/api.ts","../../../../../../packages/core/src/signals/src/graph.ts","../../../../../../packages/core/src/signals/src/computed.ts","../../../../../../packages/core/src/signals/src/errors.ts","../../../../../../packages/core/src/signals/src/signal.ts","../../../../../../packages/core/src/signals/src/untracked.ts","../../../../../../packages/core/src/signals/src/watch.ts","../../../../../../packages/core/src/signals/src/weak_ref.ts","../../../../../../packages/core/src/interface/simple_change.ts","../../../../../../packages/core/src/render3/features/ng_onchanges_feature.ts","../../../../../../packages/core/src/render3/profiler.ts","../../../../../../packages/core/src/render3/namespaces.ts","../../../../../../packages/core/src/render3/util/view_utils.ts","../../../../../../packages/core/src/render3/state.ts","../../../../../../packages/core/src/render3/hooks.ts","../../../../../../packages/core/src/render3/interfaces/injector.ts","../../../../../../packages/core/src/render3/interfaces/node.ts","../../../../../../packages/core/src/render3/node_assert.ts","../../../../../../packages/core/src/render3/util/injector_utils.ts","../../../../../../packages/core/src/render3/di.ts","../../../../../../packages/core/src/render3/instructions/di_attr.ts","../../../../../../packages/core/src/di/metadata_attr.ts","../../../../../../packages/core/src/di/jit/util.ts","../../../../../../packages/core/src/linker/ng_module_registration.ts","../../../../../../packages/core/src/di/injection_token.ts","../../../../../../packages/core/src/render3/interfaces/document.ts","../../../../../../packages/core/src/application_tokens.ts","../../../../../../packages/core/src/di/initializer_token.ts","../../../../../../packages/core/src/di/injector_token.ts","../../../../../../packages/core/src/di/internal_tokens.ts","../../../../../../packages/core/src/di/null_injector.ts","../../../../../../packages/core/src/di/provider_collection.ts","../../../../../../packages/core/src/di/scope.ts","../../../../../../packages/core/src/di/r3_injector.ts","../../../../../../packages/core/src/di/contextual.ts","../../../../../../packages/core/src/di/jit/environment.ts","../../../../../../packages/core/src/di/jit/injectable.ts","../../../../../../packages/core/src/di/injectable.ts","../../../../../../packages/core/src/di/create_injector.ts","../../../../../../packages/core/src/di/injector.ts","../../../../../../packages/core/src/di/index.ts","../../../../../../packages/core/src/di.ts","../../../../../../packages/core/src/render3/util/misc_utils.ts","../../../../../../packages/core/src/metadata/schema.ts","../../../../../../packages/core/src/render3/instructions/element_validation.ts","../../../../../../packages/core/src/hydration/skip_hydration.ts","../../../../../../packages/core/src/render/api_flags.ts","../../../../../../packages/core/src/util/dom.ts","../../../../../../packages/core/src/render3/interfaces/lview_tracking.ts","../../../../../../packages/core/src/render3/interfaces/context.ts","../../../../../../packages/core/src/render3/context_discovery.ts","../../../../../../packages/core/src/render3/i18n/i18n_tree_shaking.ts","../../../../../../packages/core/src/render3/util/view_traversal_utils.ts","../../../../../../packages/core/src/render3/node_manipulation.ts","../../../../../../packages/core/src/util/security/trusted_types.ts","../../../../../../packages/core/src/sanitization/iframe_attrs_validation.ts","../../../../../../packages/core/src/util/security/trusted_types_bypass.ts","../../../../../../packages/core/src/sanitization/bypass.ts","../../../../../../packages/core/src/sanitization/inert_body.ts","../../../../../../packages/core/src/sanitization/url_sanitizer.ts","../../../../../../packages/core/src/sanitization/html_sanitizer.ts","../../../../../../packages/core/src/sanitization/security.ts","../../../../../../packages/core/src/sanitization/sanitization.ts","../../../../../../packages/core/src/transfer_state.ts","../../../../../../packages/core/src/hydration/interfaces.ts","../../../../../../packages/core/src/hydration/utils.ts","../../../../../../packages/core/src/linker/component_factory.ts","../../../../../../packages/core/src/linker/component_factory_resolver.ts","../../../../../../packages/core/src/linker/element_ref.ts","../../../../../../packages/core/src/render/api.ts","../../../../../../packages/core/src/sanitization/sanitizer.ts","../../../../../../packages/core/src/version.ts","../../../../../../packages/core/src/view/provider_flags.ts","../../../../../../packages/core/src/util/errors.ts","../../../../../../packages/core/src/error_handler.ts","../../../../../../packages/core/src/linker/destroy_ref.ts","../../../../../../packages/core/src/event_emitter.ts","../../../../../../packages/core/src/util/noop.ts","../../../../../../packages/core/src/util/raf.ts","../../../../../../packages/core/src/zone/async-stack-tagging.ts","../../../../../../packages/core/src/zone/ng_zone.ts","../../../../../../packages/core/src/zone.ts","../../../../../../packages/core/src/render3/after_render_hooks.ts","../../../../../../packages/core/src/render3/instructions/mark_view_dirty.ts","../../../../../../packages/core/src/hydration/tokens.ts","../../../../../../packages/core/src/util/ng_reflect.ts","../../../../../../packages/core/src/render3/errors.ts","../../../../../../packages/core/src/render3/reactive_lview_consumer.ts","../../../../../../packages/core/src/render3/tokens.ts","../../../../../../packages/core/src/render3/instructions/advance.ts","../../../../../../packages/core/src/render3/instructions/di.ts","../../../../../../packages/core/src/render3/instructions/shared.ts","../../../../../../packages/core/src/render3/instructions/render.ts","../../../../../../packages/core/src/render3/reactivity/effect.ts","../../../../../../packages/core/src/render3/styling/static_styling.ts","../../../../../../packages/core/src/render3/collect_native_nodes.ts","../../../../../../packages/core/src/render3/instructions/change_detection.ts","../../../../../../packages/core/src/render3/view_ref.ts","../../../../../../packages/core/src/render3/component_ref.ts","../../../../../../packages/core/src/render3/features/inherit_definition_feature.ts","../../../../../../packages/core/src/render3/features/copy_definition_feature.ts","../../../../../../packages/core/src/render3/features/host_directives_feature.ts","../../../../../../packages/core/src/render3/features/input_transforms_feature.ts","../../../../../../packages/core/src/util/iterable.ts","../../../../../../packages/core/src/util/comparison.ts","../../../../../../packages/core/src/render3/bindings.ts","../../../../../../packages/core/src/render3/instructions/attribute.ts","../../../../../../packages/core/src/render3/instructions/interpolation.ts","../../../../../../packages/core/src/render3/instructions/attribute_interpolation.ts","../../../../../../packages/core/src/hydration/error_handling.ts","../../../../../../packages/core/src/hydration/compression.ts","../../../../../../packages/core/src/hydration/node_lookup_utils.ts","../../../../../../packages/core/src/render3/instructions/template.ts","../../../../../../packages/core/src/render3/instructions/storage.ts","../../../../../../packages/core/src/render3/instructions/property.ts","../../../../../../packages/core/src/render3/instructions/element.ts","../../../../../../packages/core/src/render3/instructions/element_container.ts","../../../../../../packages/core/src/render3/instructions/get_current_view.ts","../../../../../../packages/core/src/util/lang.ts","../../../../../../packages/core/src/render3/instructions/listener.ts","../../../../../../packages/core/src/render3/instructions/next_context.ts","../../../../../../packages/core/src/render3/instructions/projection.ts","../../../../../../packages/core/src/render3/instructions/property_interpolation.ts","../../../../../../packages/core/src/render3/interfaces/styling.ts","../../../../../../packages/core/src/render3/styling/style_binding_list.ts","../../../../../../packages/core/src/render3/styling/styling_parser.ts","../../../../../../packages/core/src/render3/instructions/styling.ts","../../../../../../packages/core/src/render3/instructions/text.ts","../../../../../../packages/core/src/render3/instructions/text_interpolation.ts","../../../../../../packages/core/src/render3/instructions/class_map_interpolation.ts","../../../../../../packages/core/src/render3/instructions/style_map_interpolation.ts","../../../../../../packages/core/src/render3/instructions/style_prop_interpolation.ts","../../../../../../packages/core/src/render3/instructions/host_property.ts","../../../../../../packages/core/src/util/ng_i18n_closure_mode.ts","../../../../../../packages/core/src/i18n/locale_en.ts","../../../../../../packages/core/src/i18n/locale_data_api.ts","../../../../../../packages/core/src/i18n/localization.ts","../../../../../../packages/core/src/render3/interfaces/i18n.ts","../../../../../../packages/core/src/render3/i18n/i18n_locale_id.ts","../../../../../../packages/core/src/render3/node_manipulation_i18n.ts","../../../../../../packages/core/src/render3/i18n/i18n_insert_before_index.ts","../../../../../../packages/core/src/render3/i18n/i18n_util.ts","../../../../../../packages/core/src/render3/i18n/i18n_apply.ts","../../../../../../packages/core/src/render3/instructions/i18n_icu_container_visitor.ts","../../../../../../packages/core/src/render3/i18n/i18n_debug.ts","../../../../../../packages/core/src/render3/i18n/i18n_parse.ts","../../../../../../packages/core/src/render3/i18n/i18n_postprocess.ts","../../../../../../packages/core/src/render3/instructions/i18n.ts","../../../../../../packages/core/src/render3/instructions/defer.ts","../../../../../../packages/core/src/render3/instructions/all.ts","../../../../../../packages/core/src/render3/di_setup.ts","../../../../../../packages/core/src/render3/features/providers_feature.ts","../../../../../../packages/core/src/linker/ng_module_factory.ts","../../../../../../packages/core/src/render3/ng_module_ref.ts","../../../../../../packages/core/src/render3/features/standalone_feature.ts","../../../../../../packages/core/src/render3/util/discovery_utils.ts","../../../../../../packages/core/src/render3/metadata.ts","../../../../../../packages/core/src/render3/pure_function.ts","../../../../../../packages/core/src/render3/pipe.ts","../../../../../../packages/core/src/linker/query_list.ts","../../../../../../packages/core/src/render3/view_manipulation.ts","../../../../../../packages/core/src/linker/template_ref.ts","../../../../../../packages/core/src/hydration/cleanup.ts","../../../../../../packages/core/src/hydration/views.ts","../../../../../../packages/core/src/linker/view_container_ref.ts","../../../../../../packages/core/src/render3/query.ts","../../../../../../packages/core/src/render3/view_engine_compatibility_prebound.ts","../../../../../../packages/core/src/render3/jit/environment.ts","../../../../../../packages/core/src/render3/jit/module_patch.ts","../../../../../../packages/core/src/render3/jit/util.ts","../../../../../../packages/core/src/render3/jit/module.ts","../../../../../../packages/core/testing/src/metadata_overrider.ts","../../../../../../packages/core/testing/src/resolvers.ts","../../../../../../packages/core/testing/src/test_bed_compiler.ts","../../../../../../packages/core/testing/src/test_bed.ts","../../../../../../packages/core/testing/src/test_hooks.ts","../../../../../../packages/core/testing/src/testing.ts","../../../../../../packages/core/testing/public_api.ts","../../../../../../packages/core/testing/index.ts","../../../../../../packages/core/testing/testing.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n/**\n * Wraps a test function in an asynchronous test zone. The test will automatically\n * complete when all asynchronous calls within this zone are done. Can be used\n * to wrap an {@link inject} call.\n *\n * Example:\n *\n * ```\n * it('...', waitForAsync(inject([AClass], (object) => {\n * object.doSomething.then(() => {\n * expect(...);\n * })\n * });\n * ```\n *\n * @publicApi\n */\nexport function waitForAsync(fn: Function): (done: any) => any {\n const _Zone: any = typeof Zone !== 'undefined' ? Zone : null;\n if (!_Zone) {\n return function() {\n return Promise.reject(\n 'Zone is needed for the waitForAsync() test helper but could not be found. ' +\n 'Please make sure that your environment includes zone.js');\n };\n }\n const asyncTest = _Zone && _Zone[_Zone.__symbol__('asyncTest')];\n if (typeof asyncTest === 'function') {\n return asyncTest(fn);\n }\n return function() {\n return Promise.reject(\n 'zone-testing.js is needed for the async() test helper but could not be found. ' +\n 'Please make sure that your environment includes zone.js/testing');\n };\n}\n\n/**\n * @deprecated use `waitForAsync()`, (expected removal in v12)\n * @see {@link waitForAsync}\n * @publicApi\n * */\nexport function async(fn: Function): (done: any) => any {\n return waitForAsync(fn);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {ChangeDetectorRef, ComponentRef, DebugElement, ElementRef, getDebugNode, NgZone, RendererFactory2} from '@angular/core';\nimport {Subscription} from 'rxjs';\n\n\n/**\n * Fixture for debugging and testing a component.\n *\n * @publicApi\n */\nexport class ComponentFixture {\n /**\n * The DebugElement associated with the root element of this component.\n */\n debugElement: DebugElement;\n\n /**\n * The instance of the root component class.\n */\n componentInstance: T;\n\n /**\n * The native element at the root of the component.\n */\n nativeElement: any;\n\n /**\n * The ElementRef for the element at the root of the component.\n */\n elementRef: ElementRef;\n\n /**\n * The ChangeDetectorRef for the component\n */\n changeDetectorRef: ChangeDetectorRef;\n\n private _renderer: RendererFactory2|null|undefined;\n private _isStable: boolean = true;\n private _isDestroyed: boolean = false;\n private _resolve: ((result: boolean) => void)|null = null;\n private _promise: Promise|null = null;\n private _onUnstableSubscription: Subscription|null = null;\n private _onStableSubscription: Subscription|null = null;\n private _onMicrotaskEmptySubscription: Subscription|null = null;\n private _onErrorSubscription: Subscription|null = null;\n\n constructor(\n public componentRef: ComponentRef, public ngZone: NgZone|null,\n private _autoDetect: boolean) {\n this.changeDetectorRef = componentRef.changeDetectorRef;\n this.elementRef = componentRef.location;\n this.debugElement = getDebugNode(this.elementRef.nativeElement);\n this.componentInstance = componentRef.instance;\n this.nativeElement = this.elementRef.nativeElement;\n this.componentRef = componentRef;\n this.ngZone = ngZone;\n\n if (ngZone) {\n // Create subscriptions outside the NgZone so that the callbacks run oustide\n // of NgZone.\n ngZone.runOutsideAngular(() => {\n this._onUnstableSubscription = ngZone.onUnstable.subscribe({\n next: () => {\n this._isStable = false;\n }\n });\n this._onMicrotaskEmptySubscription = ngZone.onMicrotaskEmpty.subscribe({\n next: () => {\n if (this._autoDetect) {\n // Do a change detection run with checkNoChanges set to true to check\n // there are no changes on the second run.\n this.detectChanges(true);\n }\n }\n });\n this._onStableSubscription = ngZone.onStable.subscribe({\n next: () => {\n this._isStable = true;\n // Check whether there is a pending whenStable() completer to resolve.\n if (this._promise !== null) {\n // If so check whether there are no pending macrotasks before resolving.\n // Do this check in the next tick so that ngZone gets a chance to update the state of\n // pending macrotasks.\n queueMicrotask(() => {\n if (!ngZone.hasPendingMacrotasks) {\n if (this._promise !== null) {\n this._resolve!(true);\n this._resolve = null;\n this._promise = null;\n }\n }\n });\n }\n }\n });\n\n this._onErrorSubscription = ngZone.onError.subscribe({\n next: (error: any) => {\n throw error;\n }\n });\n });\n }\n }\n\n private _tick(checkNoChanges: boolean) {\n this.changeDetectorRef.detectChanges();\n if (checkNoChanges) {\n this.checkNoChanges();\n }\n }\n\n /**\n * Trigger a change detection cycle for the component.\n */\n detectChanges(checkNoChanges: boolean = true): void {\n if (this.ngZone != null) {\n // Run the change detection inside the NgZone so that any async tasks as part of the change\n // detection are captured by the zone and can be waited for in isStable.\n this.ngZone.run(() => {\n this._tick(checkNoChanges);\n });\n } else {\n // Running without zone. Just do the change detection.\n this._tick(checkNoChanges);\n }\n }\n\n /**\n * Do a change detection run to make sure there were no changes.\n */\n checkNoChanges(): void {\n this.changeDetectorRef.checkNoChanges();\n }\n\n /**\n * Set whether the fixture should autodetect changes.\n *\n * Also runs detectChanges once so that any existing change is detected.\n */\n autoDetectChanges(autoDetect: boolean = true) {\n if (this.ngZone == null) {\n throw new Error('Cannot call autoDetectChanges when ComponentFixtureNoNgZone is set');\n }\n this._autoDetect = autoDetect;\n this.detectChanges();\n }\n\n /**\n * Return whether the fixture is currently stable or has async tasks that have not been completed\n * yet.\n */\n isStable(): boolean {\n return this._isStable && !this.ngZone!.hasPendingMacrotasks;\n }\n\n /**\n * Get a promise that resolves when the fixture is stable.\n *\n * This can be used to resume testing after events have triggered asynchronous activity or\n * asynchronous change detection.\n */\n whenStable(): Promise {\n if (this.isStable()) {\n return Promise.resolve(false);\n } else if (this._promise !== null) {\n return this._promise;\n } else {\n this._promise = new Promise(res => {\n this._resolve = res;\n });\n return this._promise;\n }\n }\n\n\n private _getRenderer() {\n if (this._renderer === undefined) {\n this._renderer = this.componentRef.injector.get(RendererFactory2, null);\n }\n return this._renderer as RendererFactory2 | null;\n }\n\n /**\n * Get a promise that resolves when the ui state is stable following animations.\n */\n whenRenderingDone(): Promise {\n const renderer = this._getRenderer();\n if (renderer && renderer.whenRenderingDone) {\n return renderer.whenRenderingDone();\n }\n return this.whenStable();\n }\n\n /**\n * Trigger component destruction.\n */\n destroy(): void {\n if (!this._isDestroyed) {\n this.componentRef.destroy();\n if (this._onUnstableSubscription != null) {\n this._onUnstableSubscription.unsubscribe();\n this._onUnstableSubscription = null;\n }\n if (this._onStableSubscription != null) {\n this._onStableSubscription.unsubscribe();\n this._onStableSubscription = null;\n }\n if (this._onMicrotaskEmptySubscription != null) {\n this._onMicrotaskEmptySubscription.unsubscribe();\n this._onMicrotaskEmptySubscription = null;\n }\n if (this._onErrorSubscription != null) {\n this._onErrorSubscription.unsubscribe();\n this._onErrorSubscription = null;\n }\n this._isDestroyed = true;\n }\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nconst _Zone: any = typeof Zone !== 'undefined' ? Zone : null;\nconst fakeAsyncTestModule = _Zone && _Zone[_Zone.__symbol__('fakeAsyncTest')];\n\nconst fakeAsyncTestModuleNotLoadedErrorMessage =\n `zone-testing.js is needed for the fakeAsync() test helper but could not be found.\n Please make sure that your environment includes zone.js/testing`;\n\n/**\n * Clears out the shared fake async zone for a test.\n * To be called in a global `beforeEach`.\n *\n * @publicApi\n */\nexport function resetFakeAsyncZone(): void {\n if (fakeAsyncTestModule) {\n return fakeAsyncTestModule.resetFakeAsyncZone();\n }\n throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);\n}\n\n/**\n * Wraps a function to be executed in the `fakeAsync` zone:\n * - Microtasks are manually executed by calling `flushMicrotasks()`.\n * - Timers are synchronous; `tick()` simulates the asynchronous passage of time.\n *\n * If there are any pending timers at the end of the function, an exception is thrown.\n *\n * Can be used to wrap `inject()` calls.\n *\n * @param fn The function that you want to wrap in the `fakeAsync` zone.\n *\n * @usageNotes\n * ### Example\n *\n * {@example core/testing/ts/fake_async.ts region='basic'}\n *\n *\n * @returns The function wrapped to be executed in the `fakeAsync` zone.\n * Any arguments passed when calling this returned function will be passed through to the `fn`\n * function in the parameters when it is called.\n *\n * @publicApi\n */\nexport function fakeAsync(fn: Function): (...args: any[]) => any {\n if (fakeAsyncTestModule) {\n return fakeAsyncTestModule.fakeAsync(fn);\n }\n throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);\n}\n\n/**\n * Simulates the asynchronous passage of time for the timers in the `fakeAsync` zone.\n *\n * The microtasks queue is drained at the very start of this function and after any timer callback\n * has been executed.\n *\n * @param millis The number of milliseconds to advance the virtual timer.\n * @param tickOptions The options to pass to the `tick()` function.\n *\n * @usageNotes\n *\n * The `tick()` option is a flag called `processNewMacroTasksSynchronously`,\n * which determines whether or not to invoke new macroTasks.\n *\n * If you provide a `tickOptions` object, but do not specify a\n * `processNewMacroTasksSynchronously` property (`tick(100, {})`),\n * then `processNewMacroTasksSynchronously` defaults to true.\n *\n * If you omit the `tickOptions` parameter (`tick(100))`), then\n * `tickOptions` defaults to `{processNewMacroTasksSynchronously: true}`.\n *\n * ### Example\n *\n * {@example core/testing/ts/fake_async.ts region='basic'}\n *\n * The following example includes a nested timeout (new macroTask), and\n * the `tickOptions` parameter is allowed to default. In this case,\n * `processNewMacroTasksSynchronously` defaults to true, and the nested\n * function is executed on each tick.\n *\n * ```\n * it ('test with nested setTimeout', fakeAsync(() => {\n * let nestedTimeoutInvoked = false;\n * function funcWithNestedTimeout() {\n * setTimeout(() => {\n * nestedTimeoutInvoked = true;\n * });\n * };\n * setTimeout(funcWithNestedTimeout);\n * tick();\n * expect(nestedTimeoutInvoked).toBe(true);\n * }));\n * ```\n *\n * In the following case, `processNewMacroTasksSynchronously` is explicitly\n * set to false, so the nested timeout function is not invoked.\n *\n * ```\n * it ('test with nested setTimeout', fakeAsync(() => {\n * let nestedTimeoutInvoked = false;\n * function funcWithNestedTimeout() {\n * setTimeout(() => {\n * nestedTimeoutInvoked = true;\n * });\n * };\n * setTimeout(funcWithNestedTimeout);\n * tick(0, {processNewMacroTasksSynchronously: false});\n * expect(nestedTimeoutInvoked).toBe(false);\n * }));\n * ```\n *\n *\n * @publicApi\n */\nexport function tick(\n millis: number = 0, tickOptions: {processNewMacroTasksSynchronously: boolean} = {\n processNewMacroTasksSynchronously: true\n }): void {\n if (fakeAsyncTestModule) {\n return fakeAsyncTestModule.tick(millis, tickOptions);\n }\n throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);\n}\n\n/**\n * Flushes any pending microtasks and simulates the asynchronous passage of time for the timers in\n * the `fakeAsync` zone by\n * draining the macrotask queue until it is empty.\n *\n * @param maxTurns The maximum number of times the scheduler attempts to clear its queue before\n * throwing an error.\n * @returns The simulated time elapsed, in milliseconds.\n *\n * @publicApi\n */\nexport function flush(maxTurns?: number): number {\n if (fakeAsyncTestModule) {\n return fakeAsyncTestModule.flush(maxTurns);\n }\n throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);\n}\n\n/**\n * Discard all remaining periodic tasks.\n *\n * @publicApi\n */\nexport function discardPeriodicTasks(): void {\n if (fakeAsyncTestModule) {\n return fakeAsyncTestModule.discardPeriodicTasks();\n }\n throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);\n}\n\n/**\n * Flush any pending microtasks.\n *\n * @publicApi\n */\nexport function flushMicrotasks(): void {\n if (fakeAsyncTestModule) {\n return fakeAsyncTestModule.flushMicrotasks();\n }\n throw new Error(fakeAsyncTestModuleNotLoadedErrorMessage);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {InjectionToken, SchemaMetadata} from '@angular/core';\n\n\n/** Whether test modules should be torn down by default. */\nexport const TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT = true;\n\n/** Whether unknown elements in templates should throw by default. */\nexport const THROW_ON_UNKNOWN_ELEMENTS_DEFAULT = false;\n\n/** Whether unknown properties in templates should throw by default. */\nexport const THROW_ON_UNKNOWN_PROPERTIES_DEFAULT = false;\n\n/**\n * An abstract class for inserting the root test component element in a platform independent way.\n *\n * @publicApi\n */\nexport class TestComponentRenderer {\n insertRootElement(rootElementId: string) {}\n removeAllRootElements?() {}\n}\n\n/**\n * @publicApi\n */\nexport const ComponentFixtureAutoDetect = new InjectionToken('ComponentFixtureAutoDetect');\n\n/**\n * @publicApi\n */\nexport const ComponentFixtureNoNgZone = new InjectionToken('ComponentFixtureNoNgZone');\n\n/**\n * @publicApi\n */\nexport interface TestModuleMetadata {\n providers?: any[];\n declarations?: any[];\n imports?: any[];\n schemas?: Array;\n teardown?: ModuleTeardownOptions;\n /**\n * Whether NG0304 runtime errors should be thrown when unknown elements are present in component's\n * template. Defaults to `false`, where the error is simply logged. If set to `true`, the error is\n * thrown.\n * @see [NG8001](/errors/NG8001) for the description of the problem and how to fix it\n */\n errorOnUnknownElements?: boolean;\n /**\n * Whether errors should be thrown when unknown properties are present in component's template.\n * Defaults to `false`, where the error is simply logged.\n * If set to `true`, the error is thrown.\n * @see [NG8002](/errors/NG8002) for the description of the error and how to fix it\n */\n errorOnUnknownProperties?: boolean;\n}\n\n/**\n * @publicApi\n */\nexport interface TestEnvironmentOptions {\n /**\n * Configures the test module teardown behavior in `TestBed`.\n */\n teardown?: ModuleTeardownOptions;\n /**\n * Whether errors should be thrown when unknown elements are present in component's template.\n * Defaults to `false`, where the error is simply logged.\n * If set to `true`, the error is thrown.\n * @see [NG8001](/errors/NG8001) for the description of the error and how to fix it\n */\n errorOnUnknownElements?: boolean;\n /**\n * Whether errors should be thrown when unknown properties are present in component's template.\n * Defaults to `false`, where the error is simply logged.\n * If set to `true`, the error is thrown.\n * @see [NG8002](/errors/NG8002) for the description of the error and how to fix it\n */\n errorOnUnknownProperties?: boolean;\n}\n\n/**\n * Configures the test module teardown behavior in `TestBed`.\n * @publicApi\n */\nexport interface ModuleTeardownOptions {\n /** Whether the test module should be destroyed after every test. Defaults to `true`. */\n destroyAfterEach: boolean;\n\n /** Whether errors during test module destruction should be re-thrown. Defaults to `true`. */\n rethrowErrors?: boolean;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Type} from '../interface/type';\nimport {Component} from './directives';\n\n\n/**\n * Used to resolve resource URLs on `@Component` when used with JIT compilation.\n *\n * Example:\n * ```\n * @Component({\n * selector: 'my-comp',\n * templateUrl: 'my-comp.html', // This requires asynchronous resolution\n * })\n * class MyComponent{\n * }\n *\n * // Calling `renderComponent` will fail because `renderComponent` is a synchronous process\n * // and `MyComponent`'s `@Component.templateUrl` needs to be resolved asynchronously.\n *\n * // Calling `resolveComponentResources()` will resolve `@Component.templateUrl` into\n * // `@Component.template`, which allows `renderComponent` to proceed in a synchronous manner.\n *\n * // Use browser's `fetch()` function as the default resource resolution strategy.\n * resolveComponentResources(fetch).then(() => {\n * // After resolution all URLs have been converted into `template` strings.\n * renderComponent(MyComponent);\n * });\n *\n * ```\n *\n * NOTE: In AOT the resolution happens during compilation, and so there should be no need\n * to call this method outside JIT mode.\n *\n * @param resourceResolver a function which is responsible for returning a `Promise` to the\n * contents of the resolved URL. Browser's `fetch()` method is a good default implementation.\n */\nexport function resolveComponentResources(\n resourceResolver: (url: string) => (Promise}>)): Promise {\n // Store all promises which are fetching the resources.\n const componentResolved: Promise[] = [];\n\n // Cache so that we don't fetch the same resource more than once.\n const urlMap = new Map>();\n function cachedResourceResolve(url: string): Promise {\n let promise = urlMap.get(url);\n if (!promise) {\n const resp = resourceResolver(url);\n urlMap.set(url, promise = resp.then(unwrapResponse));\n }\n return promise;\n }\n\n componentResourceResolutionQueue.forEach((component: Component, type: Type) => {\n const promises: Promise[] = [];\n if (component.templateUrl) {\n promises.push(cachedResourceResolve(component.templateUrl).then((template) => {\n component.template = template;\n }));\n }\n const styleUrls = component.styleUrls;\n const styles = component.styles || (component.styles = []);\n const styleOffset = component.styles.length;\n styleUrls && styleUrls.forEach((styleUrl, index) => {\n styles.push(''); // pre-allocate array.\n promises.push(cachedResourceResolve(styleUrl).then((style) => {\n styles[styleOffset + index] = style;\n styleUrls.splice(styleUrls.indexOf(styleUrl), 1);\n if (styleUrls.length == 0) {\n component.styleUrls = undefined;\n }\n }));\n });\n const fullyResolved = Promise.all(promises).then(() => componentDefResolved(type));\n componentResolved.push(fullyResolved);\n });\n clearResolutionOfComponentResourcesQueue();\n return Promise.all(componentResolved).then(() => undefined);\n}\n\nlet componentResourceResolutionQueue = new Map, Component>();\n\n// Track when existing ɵcmp for a Type is waiting on resources.\nconst componentDefPendingResolution = new Set>();\n\nexport function maybeQueueResolutionOfComponentResources(type: Type, metadata: Component) {\n if (componentNeedsResolution(metadata)) {\n componentResourceResolutionQueue.set(type, metadata);\n componentDefPendingResolution.add(type);\n }\n}\n\nexport function isComponentDefPendingResolution(type: Type): boolean {\n return componentDefPendingResolution.has(type);\n}\n\nexport function componentNeedsResolution(component: Component): boolean {\n return !!(\n (component.templateUrl && !component.hasOwnProperty('template')) ||\n component.styleUrls && component.styleUrls.length);\n}\nexport function clearResolutionOfComponentResourcesQueue(): Map, Component> {\n const old = componentResourceResolutionQueue;\n componentResourceResolutionQueue = new Map();\n return old;\n}\n\nexport function restoreComponentResolutionQueue(queue: Map, Component>): void {\n componentDefPendingResolution.clear();\n queue.forEach((_, type) => componentDefPendingResolution.add(type));\n componentResourceResolutionQueue = queue;\n}\n\nexport function isComponentResourceResolutionQueueEmpty() {\n return componentResourceResolutionQueue.size === 0;\n}\n\nfunction unwrapResponse(response: string|{text(): Promise}): string|Promise {\n return typeof response == 'string' ? response : response.text();\n}\n\nfunction componentDefResolved(type: Type): void {\n componentDefPendingResolution.delete(type);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nconst _global: any = globalThis;\n\n/**\n * Attention: whenever providing a new value, be sure to add an\n * entry into the corresponding `....externs.js` file,\n * so that closure won't use that global for its purposes.\n */\nexport {_global as global};\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * A set of interfaces which are shared between `@angular/core` and `@angular/compiler` to allow\n * for late binding of `@angular/compiler` for JIT purposes.\n *\n * This file has two copies. Please ensure that they are in sync:\n * - packages/compiler/src/compiler_facade_interface.ts (main)\n * - packages/core/src/compiler/compiler_facade_interface.ts (replica)\n *\n * Please ensure that the two files are in sync using this command:\n * ```\n * cp packages/compiler/src/compiler_facade_interface.ts \\\n * packages/core/src/compiler/compiler_facade_interface.ts\n * ```\n */\n\nexport interface ExportedCompilerFacade {\n ɵcompilerFacade: CompilerFacade;\n}\n\nexport interface CompilerFacade {\n compilePipe(angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3PipeMetadataFacade):\n any;\n compilePipeDeclaration(\n angularCoreEnv: CoreEnvironment, sourceMapUrl: string, declaration: R3DeclarePipeFacade): any;\n compileInjectable(\n angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3InjectableMetadataFacade): any;\n compileInjectableDeclaration(\n angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3DeclareInjectableFacade): any;\n compileInjector(\n angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3InjectorMetadataFacade): any;\n compileInjectorDeclaration(\n angularCoreEnv: CoreEnvironment, sourceMapUrl: string,\n declaration: R3DeclareInjectorFacade): any;\n compileNgModule(\n angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3NgModuleMetadataFacade): any;\n compileNgModuleDeclaration(\n angularCoreEnv: CoreEnvironment, sourceMapUrl: string,\n declaration: R3DeclareNgModuleFacade): any;\n compileDirective(\n angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3DirectiveMetadataFacade): any;\n compileDirectiveDeclaration(\n angularCoreEnv: CoreEnvironment, sourceMapUrl: string,\n declaration: R3DeclareDirectiveFacade): any;\n compileComponent(\n angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3ComponentMetadataFacade): any;\n compileComponentDeclaration(\n angularCoreEnv: CoreEnvironment, sourceMapUrl: string,\n declaration: R3DeclareComponentFacade): any;\n compileFactory(\n angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3FactoryDefMetadataFacade): any;\n compileFactoryDeclaration(\n angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3DeclareFactoryFacade): any;\n\n createParseSourceSpan(kind: string, typeName: string, sourceUrl: string): ParseSourceSpan;\n\n FactoryTarget: typeof FactoryTarget;\n // Note that we do not use `{new(): ResourceLoader}` here because\n // the resource loader class is abstract and not constructable.\n ResourceLoader: Function&{prototype: ResourceLoader};\n}\n\nexport interface CoreEnvironment {\n [name: string]: Function;\n}\n\nexport type ResourceLoader = {\n get(url: string): Promise|string;\n};\n\nexport type InputMap = {\n [key: string]: {\n bindingPropertyName: string,\n classPropertyName: string,\n required: boolean,\n transformFunction: InputTransformFunction,\n };\n};\n\nexport type Provider = unknown;\nexport type Type = Function;\nexport type OpaqueValue = unknown;\nexport type InputTransformFunction = any;\n\nexport enum FactoryTarget {\n Directive = 0,\n Component = 1,\n Injectable = 2,\n Pipe = 3,\n NgModule = 4,\n}\n\nexport interface R3DependencyMetadataFacade {\n token: OpaqueValue;\n attribute: string|null;\n host: boolean;\n optional: boolean;\n self: boolean;\n skipSelf: boolean;\n}\n\nexport interface R3DeclareDependencyMetadataFacade {\n token: OpaqueValue;\n attribute?: boolean;\n host?: boolean;\n optional?: boolean;\n self?: boolean;\n skipSelf?: boolean;\n}\n\nexport interface R3PipeMetadataFacade {\n name: string;\n type: Type;\n pipeName: string;\n pure: boolean;\n isStandalone: boolean;\n}\n\nexport interface R3InjectableMetadataFacade {\n name: string;\n type: Type;\n typeArgumentCount: number;\n providedIn?: Type|'root'|'platform'|'any'|null;\n useClass?: OpaqueValue;\n useFactory?: OpaqueValue;\n useExisting?: OpaqueValue;\n useValue?: OpaqueValue;\n deps?: R3DependencyMetadataFacade[];\n}\n\nexport interface R3NgModuleMetadataFacade {\n type: Type;\n bootstrap: Function[];\n declarations: Function[];\n imports: Function[];\n exports: Function[];\n schemas: {name: string}[]|null;\n id: string|null;\n}\n\nexport interface R3InjectorMetadataFacade {\n name: string;\n type: Type;\n providers: Provider[];\n imports: OpaqueValue[];\n}\n\nexport interface R3HostDirectiveMetadataFacade {\n directive: Type;\n inputs?: string[];\n outputs?: string[];\n}\n\nexport interface R3DirectiveMetadataFacade {\n name: string;\n type: Type;\n typeSourceSpan: ParseSourceSpan;\n selector: string|null;\n queries: R3QueryMetadataFacade[];\n host: {[key: string]: string};\n propMetadata: {[key: string]: OpaqueValue[]};\n lifecycle: {usesOnChanges: boolean;};\n inputs: (string|{name: string, alias?: string, required?: boolean})[];\n outputs: string[];\n usesInheritance: boolean;\n exportAs: string[]|null;\n providers: Provider[]|null;\n viewQueries: R3QueryMetadataFacade[];\n isStandalone: boolean;\n isSignal: boolean;\n hostDirectives: R3HostDirectiveMetadataFacade[]|null;\n}\n\nexport interface R3ComponentMetadataFacade extends R3DirectiveMetadataFacade {\n template: string;\n preserveWhitespaces: boolean;\n animations: OpaqueValue[]|undefined;\n declarations: R3TemplateDependencyFacade[];\n styles: string[];\n encapsulation: ViewEncapsulation;\n viewProviders: Provider[]|null;\n interpolation?: [string, string];\n changeDetection?: ChangeDetectionStrategy;\n}\n\nexport interface R3DeclareDirectiveFacade {\n selector?: string;\n type: Type;\n inputs?: {\n [classPropertyName: string]: string|\n [bindingPropertyName: string,\n classPropertyName: string, transformFunction?: InputTransformFunction]\n };\n outputs?: {[classPropertyName: string]: string};\n host?: {\n attributes?: {[key: string]: OpaqueValue};\n listeners?: {[key: string]: string};\n properties?: {[key: string]: string};\n classAttribute?: string;\n styleAttribute?: string;\n };\n queries?: R3DeclareQueryMetadataFacade[];\n viewQueries?: R3DeclareQueryMetadataFacade[];\n providers?: OpaqueValue;\n exportAs?: string[];\n usesInheritance?: boolean;\n usesOnChanges?: boolean;\n isStandalone?: boolean;\n hostDirectives?: R3HostDirectiveMetadataFacade[]|null;\n isSignal?: boolean;\n}\n\nexport interface R3DeclareComponentFacade extends R3DeclareDirectiveFacade {\n template: string;\n isInline?: boolean;\n styles?: string[];\n\n // Post-standalone libraries use a unified dependencies field.\n dependencies?: R3DeclareTemplateDependencyFacade[];\n\n // Pre-standalone libraries have separate component/directive/pipe fields:\n components?: R3DeclareDirectiveDependencyFacade[];\n directives?: R3DeclareDirectiveDependencyFacade[];\n pipes?: {[pipeName: string]: OpaqueValue|(() => OpaqueValue)};\n\n\n viewProviders?: OpaqueValue;\n animations?: OpaqueValue;\n changeDetection?: ChangeDetectionStrategy;\n encapsulation?: ViewEncapsulation;\n interpolation?: [string, string];\n preserveWhitespaces?: boolean;\n}\n\nexport type R3DeclareTemplateDependencyFacade = {\n kind: string\n}&(R3DeclareDirectiveDependencyFacade|R3DeclarePipeDependencyFacade|\n R3DeclareNgModuleDependencyFacade);\n\nexport interface R3DeclareDirectiveDependencyFacade {\n kind?: 'directive'|'component';\n selector: string;\n type: OpaqueValue|(() => OpaqueValue);\n inputs?: string[];\n outputs?: string[];\n exportAs?: string[];\n}\n\nexport interface R3DeclarePipeDependencyFacade {\n kind?: 'pipe';\n name: string;\n type: OpaqueValue|(() => OpaqueValue);\n}\n\nexport interface R3DeclareNgModuleDependencyFacade {\n kind: 'ngmodule';\n type: OpaqueValue|(() => OpaqueValue);\n}\n\nexport enum R3TemplateDependencyKind {\n Directive = 0,\n Pipe = 1,\n NgModule = 2,\n}\n\nexport interface R3TemplateDependencyFacade {\n kind: R3TemplateDependencyKind;\n type: OpaqueValue|(() => OpaqueValue);\n}\nexport interface R3FactoryDefMetadataFacade {\n name: string;\n type: Type;\n typeArgumentCount: number;\n deps: R3DependencyMetadataFacade[]|null;\n target: FactoryTarget;\n}\n\nexport interface R3DeclareFactoryFacade {\n type: Type;\n deps: R3DeclareDependencyMetadataFacade[]|'invalid'|null;\n target: FactoryTarget;\n}\n\nexport interface R3DeclareInjectableFacade {\n type: Type;\n providedIn?: Type|'root'|'platform'|'any'|null;\n useClass?: OpaqueValue;\n useFactory?: OpaqueValue;\n useExisting?: OpaqueValue;\n useValue?: OpaqueValue;\n deps?: R3DeclareDependencyMetadataFacade[];\n}\n\nexport enum ViewEncapsulation {\n Emulated = 0,\n // Historically the 1 value was for `Native` encapsulation which has been removed as of v11.\n None = 2,\n ShadowDom = 3\n}\n\nexport type ChangeDetectionStrategy = number;\n\nexport interface R3QueryMetadataFacade {\n propertyName: string;\n first: boolean;\n predicate: OpaqueValue|string[];\n descendants: boolean;\n emitDistinctChangesOnly: boolean;\n read: OpaqueValue|null;\n static: boolean;\n}\n\nexport interface R3DeclareQueryMetadataFacade {\n propertyName: string;\n first?: boolean;\n predicate: OpaqueValue|string[];\n descendants?: boolean;\n read?: OpaqueValue;\n static?: boolean;\n emitDistinctChangesOnly?: boolean;\n}\n\nexport interface R3DeclareInjectorFacade {\n type: Type;\n imports?: OpaqueValue[];\n providers?: OpaqueValue[];\n}\n\nexport interface R3DeclareNgModuleFacade {\n type: Type;\n bootstrap?: OpaqueValue[]|(() => OpaqueValue[]);\n declarations?: OpaqueValue[]|(() => OpaqueValue[]);\n imports?: OpaqueValue[]|(() => OpaqueValue[]);\n exports?: OpaqueValue[]|(() => OpaqueValue[]);\n schemas?: OpaqueValue[];\n id?: OpaqueValue;\n}\n\nexport interface R3DeclarePipeFacade {\n type: Type;\n name: string;\n pure?: boolean;\n isStandalone?: boolean;\n}\n\nexport interface ParseSourceSpan {\n start: any;\n end: any;\n details: any;\n fullStart: any;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport {global} from '../util/global';\nimport {CompilerFacade, ExportedCompilerFacade, Type} from './compiler_facade_interface';\nexport * from './compiler_facade_interface';\n\nexport const enum JitCompilerUsage {\n Decorator,\n PartialDeclaration,\n}\n\ninterface JitCompilerUsageRequest {\n usage: JitCompilerUsage;\n kind: 'directive'|'component'|'pipe'|'injectable'|'NgModule';\n type: Type;\n}\n\nexport function getCompilerFacade(request: JitCompilerUsageRequest): CompilerFacade {\n const globalNg: ExportedCompilerFacade = global['ng'];\n if (globalNg && globalNg.ɵcompilerFacade) {\n return globalNg.ɵcompilerFacade;\n }\n\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n // Log the type as an error so that a developer can easily navigate to the type from the\n // console.\n console.error(`JIT compilation failed for ${request.kind}`, request.type);\n\n let message = `The ${request.kind} '${\n request\n .type.name}' needs to be compiled using the JIT compiler, but '@angular/compiler' is not available.\\n\\n`;\n if (request.usage === JitCompilerUsage.PartialDeclaration) {\n message += `The ${request.kind} is part of a library that has been partially compiled.\\n`;\n message +=\n `However, the Angular Linker has not processed the library such that JIT compilation is used as fallback.\\n`;\n message += '\\n';\n message +=\n `Ideally, the library is processed using the Angular Linker to become fully AOT compiled.\\n`;\n } else {\n message +=\n `JIT compilation is discouraged for production use-cases! Consider using AOT mode instead.\\n`;\n }\n message +=\n `Alternatively, the JIT compiler should be loaded by bootstrapping using '@angular/platform-browser-dynamic' or '@angular/platform-server',\\n`;\n message +=\n `or manually provide the compiler with 'import \"@angular/compiler\";' before bootstrapping.`;\n throw new Error(message);\n } else {\n throw new Error('JIT compiler unavailable');\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nexport function getClosureSafeProperty(objWithPropertyToExtract: T): string {\n for (let key in objWithPropertyToExtract) {\n if (objWithPropertyToExtract[key] === getClosureSafeProperty as any) {\n return key;\n }\n }\n throw Error('Could not find renamed property on target object.');\n}\n\n/**\n * Sets properties on a target object from a source object, but only if\n * the property doesn't already exist on the target object.\n * @param target The target to set properties on\n * @param source The source of the property keys and values to set\n */\nexport function fillProperties(target: Record, source: Record) {\n for (const key in source) {\n if (source.hasOwnProperty(key) && !target.hasOwnProperty(key)) {\n target[key] = source[key];\n }\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nexport function stringify(token: any): string {\n if (typeof token === 'string') {\n return token;\n }\n\n if (Array.isArray(token)) {\n return '[' + token.map(stringify).join(', ') + ']';\n }\n\n if (token == null) {\n return '' + token;\n }\n\n if (token.overriddenName) {\n return `${token.overriddenName}`;\n }\n\n if (token.name) {\n return `${token.name}`;\n }\n\n const res = token.toString();\n\n if (res == null) {\n return '' + res;\n }\n\n const newLineIndex = res.indexOf('\\n');\n return newLineIndex === -1 ? res : res.substring(0, newLineIndex);\n}\n\n/**\n * Concatenates two strings with separator, allocating new strings only when necessary.\n *\n * @param before before string.\n * @param separator separator string.\n * @param after after string.\n * @returns concatenated string.\n */\nexport function concatStringsWithSpace(before: string|null, after: string|null): string {\n return (before == null || before === '') ?\n (after === null ? '' : after) :\n ((after == null || after === '') ? before : before + ' ' + after);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Type} from '../interface/type';\nimport {getClosureSafeProperty} from '../util/property';\nimport {stringify} from '../util/stringify';\n\n\n\n/**\n * An interface that a function passed into {@link forwardRef} has to implement.\n *\n * @usageNotes\n * ### Example\n *\n * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref_fn'}\n * @publicApi\n */\nexport interface ForwardRefFn {\n (): any;\n}\n\nconst __forward_ref__ = getClosureSafeProperty({__forward_ref__: getClosureSafeProperty});\n\n/**\n * Allows to refer to references which are not yet defined.\n *\n * For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of\n * DI is declared, but not yet defined. It is also used when the `token` which we use when creating\n * a query is not yet defined.\n *\n * `forwardRef` is also used to break circularities in standalone components imports.\n *\n * @usageNotes\n * ### Circular dependency example\n * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}\n *\n * ### Circular standalone reference import example\n * ```ts\n * @Component({\n * standalone: true,\n * imports: [ChildComponent],\n * selector: 'app-parent',\n * template: ``,\n * })\n * export class ParentComponent {\n * @Input() hideParent: boolean;\n * }\n *\n *\n * @Component({\n * standalone: true,\n * imports: [CommonModule, forwardRef(() => ParentComponent)],\n * selector: 'app-child',\n * template: ``,\n * })\n * export class ChildComponent {\n * @Input() hideParent: boolean;\n * }\n * ```\n *\n * @publicApi\n */\nexport function forwardRef(forwardRefFn: ForwardRefFn): Type {\n (forwardRefFn).__forward_ref__ = forwardRef;\n (forwardRefFn).toString = function() {\n return stringify(this());\n };\n return (>forwardRefFn);\n}\n\n/**\n * Lazily retrieves the reference value from a forwardRef.\n *\n * Acts as the identity function when given a non-forward-ref value.\n *\n * @usageNotes\n * ### Example\n *\n * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}\n *\n * @see {@link forwardRef}\n * @publicApi\n */\nexport function resolveForwardRef(type: T): T {\n return isForwardRef(type) ? type() : type;\n}\n\n/** Checks whether a function is wrapped by a `forwardRef`. */\nexport function isForwardRef(fn: any): fn is() => any {\n return typeof fn === 'function' && fn.hasOwnProperty(__forward_ref__) &&\n fn.__forward_ref__ === forwardRef;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Type} from '../../interface/type';\nimport {getClosureSafeProperty} from '../../util/property';\n\nimport {ClassProvider, ConstructorProvider, EnvironmentProviders, ExistingProvider, FactoryProvider, StaticClassProvider, ValueProvider} from './provider';\n\n\n\n/**\n * Information about how a type or `InjectionToken` interfaces with the DI system.\n *\n * At a minimum, this includes a `factory` which defines how to create the given type `T`, possibly\n * requesting injection of other types if necessary.\n *\n * Optionally, a `providedIn` parameter specifies that the given type belongs to a particular\n * `Injector`, `NgModule`, or a special scope (e.g. `'root'`). A value of `null` indicates\n * that the injectable does not belong to any scope.\n *\n * @codeGenApi\n * @publicApi The ViewEngine compiler emits code with this type for injectables. This code is\n * deployed to npm, and should be treated as public api.\n\n */\nexport interface ɵɵInjectableDeclaration {\n /**\n * Specifies that the given type belongs to a particular injector:\n * - `InjectorType` such as `NgModule`,\n * - `'root'` the root injector\n * - `'any'` all injectors.\n * - `null`, does not belong to any injector. Must be explicitly listed in the injector\n * `providers`.\n */\n providedIn: InjectorType|'root'|'platform'|'any'|'environment'|null;\n\n /**\n * The token to which this definition belongs.\n *\n * Note that this may not be the same as the type that the `factory` will create.\n */\n token: unknown;\n\n /**\n * Factory method to execute to create an instance of the injectable.\n */\n factory: (t?: Type) => T;\n\n /**\n * In a case of no explicit injector, a location where the instance of the injectable is stored.\n */\n value: T|undefined;\n}\n\n/**\n * Information about the providers to be included in an `Injector` as well as how the given type\n * which carries the information should be created by the DI system.\n *\n * An `InjectorDef` can import other types which have `InjectorDefs`, forming a deep nested\n * structure of providers with a defined priority (identically to how `NgModule`s also have\n * an import/dependency structure).\n *\n * NOTE: This is a private type and should not be exported\n *\n * @codeGenApi\n */\nexport interface ɵɵInjectorDef {\n // TODO(alxhub): Narrow down the type here once decorators properly change the return type of the\n // class they are decorating (to add the ɵprov property for example).\n providers: (Type|ValueProvider|ExistingProvider|FactoryProvider|ConstructorProvider|\n StaticClassProvider|ClassProvider|EnvironmentProviders|any[])[];\n\n imports: (InjectorType|InjectorTypeWithProviders)[];\n}\n\n/**\n * A `Type` which has a `ɵprov: ɵɵInjectableDeclaration` static field.\n *\n * `InjectableType`s contain their own Dependency Injection metadata and are usable in an\n * `InjectorDef`-based `StaticInjector`.\n *\n * @publicApi\n */\nexport interface InjectableType extends Type {\n /**\n * Opaque type whose structure is highly version dependent. Do not rely on any properties.\n */\n ɵprov: unknown;\n}\n\n/**\n * A type which has an `InjectorDef` static field.\n *\n * `InjectorTypes` can be used to configure a `StaticInjector`.\n *\n * This is an opaque type whose structure is highly version dependent. Do not rely on any\n * properties.\n *\n * @publicApi\n */\nexport interface InjectorType extends Type {\n ɵfac?: unknown;\n ɵinj: unknown;\n}\n\n/**\n * Describes the `InjectorDef` equivalent of a `ModuleWithProviders`, an `InjectorType` with an\n * associated array of providers.\n *\n * Objects of this type can be listed in the imports section of an `InjectorDef`.\n *\n * NOTE: This is a private type and should not be exported\n */\nexport interface InjectorTypeWithProviders {\n ngModule: InjectorType;\n providers?: (Type|ValueProvider|ExistingProvider|FactoryProvider|ConstructorProvider|\n StaticClassProvider|ClassProvider|EnvironmentProviders|any[])[];\n}\n\n\n/**\n * Construct an injectable definition which defines how a token will be constructed by the DI\n * system, and in which injectors (if any) it will be available.\n *\n * This should be assigned to a static `ɵprov` field on a type, which will then be an\n * `InjectableType`.\n *\n * Options:\n * * `providedIn` determines which injectors will include the injectable, by either associating it\n * with an `@NgModule` or other `InjectorType`, or by specifying that this injectable should be\n * provided in the `'root'` injector, which will be the application-level injector in most apps.\n * * `factory` gives the zero argument function which will create an instance of the injectable.\n * The factory can call [`inject`](api/core/inject) to access the `Injector` and request injection\n * of dependencies.\n *\n * @codeGenApi\n * @publicApi This instruction has been emitted by ViewEngine for some time and is deployed to npm.\n */\nexport function ɵɵdefineInjectable(opts: {\n token: unknown,\n providedIn?: Type|'root'|'platform'|'any'|'environment'|null, factory: () => T,\n}): unknown {\n return {\n token: opts.token,\n providedIn: opts.providedIn as any || null,\n factory: opts.factory,\n value: undefined,\n } as ɵɵInjectableDeclaration;\n}\n\n/**\n * @deprecated in v8, delete after v10. This API should be used only by generated code, and that\n * code should now use ɵɵdefineInjectable instead.\n * @publicApi\n */\nexport const defineInjectable = ɵɵdefineInjectable;\n\n/**\n * Construct an `InjectorDef` which configures an injector.\n *\n * This should be assigned to a static injector def (`ɵinj`) field on a type, which will then be an\n * `InjectorType`.\n *\n * Options:\n *\n * * `providers`: an optional array of providers to add to the injector. Each provider must\n * either have a factory or point to a type which has a `ɵprov` static property (the\n * type must be an `InjectableType`).\n * * `imports`: an optional array of imports of other `InjectorType`s or `InjectorTypeWithModule`s\n * whose providers will also be added to the injector. Locally provided types will override\n * providers from imports.\n *\n * @codeGenApi\n */\nexport function ɵɵdefineInjector(options: {providers?: any[], imports?: any[]}): unknown {\n return {providers: options.providers || [], imports: options.imports || []};\n}\n\n/**\n * Read the injectable def (`ɵprov`) for `type` in a way which is immune to accidentally reading\n * inherited value.\n *\n * @param type A type which may have its own (non-inherited) `ɵprov`.\n */\nexport function getInjectableDef(type: any): ɵɵInjectableDeclaration|null {\n return getOwnDefinition(type, NG_PROV_DEF) || getOwnDefinition(type, NG_INJECTABLE_DEF);\n}\n\nexport function isInjectable(type: any): boolean {\n return getInjectableDef(type) !== null;\n}\n\n/**\n * Return definition only if it is defined directly on `type` and is not inherited from a base\n * class of `type`.\n */\nfunction getOwnDefinition(type: any, field: string): ɵɵInjectableDeclaration|null {\n return type.hasOwnProperty(field) ? type[field] : null;\n}\n\n/**\n * Read the injectable def (`ɵprov`) for `type` or read the `ɵprov` from one of its ancestors.\n *\n * @param type A type which may have `ɵprov`, via inheritance.\n *\n * @deprecated Will be removed in a future version of Angular, where an error will occur in the\n * scenario if we find the `ɵprov` on an ancestor only.\n */\nexport function getInheritedInjectableDef(type: any): ɵɵInjectableDeclaration|null {\n const def = type && (type[NG_PROV_DEF] || type[NG_INJECTABLE_DEF]);\n\n if (def) {\n ngDevMode &&\n console.warn(\n `DEPRECATED: DI is instantiating a token \"${\n type.name}\" that inherits its @Injectable decorator but does not provide one itself.\\n` +\n `This will become an error in a future version of Angular. Please add @Injectable() to the \"${\n type.name}\" class.`);\n return def;\n } else {\n return null;\n }\n}\n\n/**\n * Read the injector def type in a way which is immune to accidentally reading inherited value.\n *\n * @param type type which may have an injector def (`ɵinj`)\n */\nexport function getInjectorDef(type: any): ɵɵInjectorDef|null {\n return type && (type.hasOwnProperty(NG_INJ_DEF) || type.hasOwnProperty(NG_INJECTOR_DEF)) ?\n (type as any)[NG_INJ_DEF] :\n null;\n}\n\nexport const NG_PROV_DEF = getClosureSafeProperty({ɵprov: getClosureSafeProperty});\nexport const NG_INJ_DEF = getClosureSafeProperty({ɵinj: getClosureSafeProperty});\n\n// We need to keep these around so we can read off old defs if new defs are unavailable\nexport const NG_INJECTABLE_DEF = getClosureSafeProperty({ngInjectableDef: getClosureSafeProperty});\nexport const NG_INJECTOR_DEF = getClosureSafeProperty({ngInjectorDef: getClosureSafeProperty});\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Base URL for the error details page.\n *\n * Keep this constant in sync across:\n * - packages/compiler-cli/src/ngtsc/diagnostics/src/error_details_base_url.ts\n * - packages/core/src/error_details_base_url.ts\n */\nexport const ERROR_DETAILS_PAGE_BASE_URL = 'https://angular.io/errors';\n\n/**\n * URL for the XSS security documentation.\n */\nexport const XSS_SECURITY_URL = 'https://g.co/ng/security#xss';\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {ERROR_DETAILS_PAGE_BASE_URL} from './error_details_base_url';\n\n/**\n * The list of error codes used in runtime code of the `core` package.\n * Reserved error code range: 100-999.\n *\n * Note: the minus sign denotes the fact that a particular code has a detailed guide on\n * angular.io. This extra annotation is needed to avoid introducing a separate set to store\n * error codes which have guides, which might leak into runtime code.\n *\n * Full list of available error guides can be found at https://angular.io/errors.\n *\n * Error code ranges per package:\n * - core (this package): 100-999\n * - forms: 1000-1999\n * - common: 2000-2999\n * - animations: 3000-3999\n * - router: 4000-4999\n * - platform-browser: 5000-5500\n */\nexport const enum RuntimeErrorCode {\n // Change Detection Errors\n EXPRESSION_CHANGED_AFTER_CHECKED = -100,\n RECURSIVE_APPLICATION_REF_TICK = 101,\n RECURSIVE_APPLICATION_RENDER = 102,\n\n // Dependency Injection Errors\n CYCLIC_DI_DEPENDENCY = -200,\n PROVIDER_NOT_FOUND = -201,\n INVALID_FACTORY_DEPENDENCY = 202,\n MISSING_INJECTION_CONTEXT = -203,\n INVALID_INJECTION_TOKEN = 204,\n INJECTOR_ALREADY_DESTROYED = 205,\n PROVIDER_IN_WRONG_CONTEXT = 207,\n MISSING_INJECTION_TOKEN = 208,\n INVALID_MULTI_PROVIDER = -209,\n MISSING_DOCUMENT = 210,\n\n // Template Errors\n MULTIPLE_COMPONENTS_MATCH = -300,\n EXPORT_NOT_FOUND = -301,\n PIPE_NOT_FOUND = -302,\n UNKNOWN_BINDING = 303,\n UNKNOWN_ELEMENT = 304,\n TEMPLATE_STRUCTURE_ERROR = 305,\n INVALID_EVENT_BINDING = 306,\n HOST_DIRECTIVE_UNRESOLVABLE = 307,\n HOST_DIRECTIVE_NOT_STANDALONE = 308,\n DUPLICATE_DIRECTITVE = 309,\n HOST_DIRECTIVE_COMPONENT = 310,\n HOST_DIRECTIVE_UNDEFINED_BINDING = 311,\n HOST_DIRECTIVE_CONFLICTING_ALIAS = 312,\n MULTIPLE_MATCHING_PIPES = 313,\n\n // Bootstrap Errors\n MULTIPLE_PLATFORMS = 400,\n PLATFORM_NOT_FOUND = 401,\n MISSING_REQUIRED_INJECTABLE_IN_BOOTSTRAP = 402,\n BOOTSTRAP_COMPONENTS_NOT_FOUND = -403,\n PLATFORM_ALREADY_DESTROYED = 404,\n ASYNC_INITIALIZERS_STILL_RUNNING = 405,\n APPLICATION_REF_ALREADY_DESTROYED = 406,\n RENDERER_NOT_FOUND = 407,\n\n // Hydration Errors\n HYDRATION_NODE_MISMATCH = -500,\n HYDRATION_MISSING_SIBLINGS = -501,\n HYDRATION_MISSING_NODE = -502,\n UNSUPPORTED_PROJECTION_DOM_NODES = -503,\n INVALID_SKIP_HYDRATION_HOST = -504,\n MISSING_HYDRATION_ANNOTATIONS = -505,\n HYDRATION_STABLE_TIMEDOUT = -506,\n MISSING_SSR_CONTENT_INTEGRITY_MARKER = -507,\n\n // Signal Errors\n SIGNAL_WRITE_FROM_ILLEGAL_CONTEXT = 600,\n REQUIRE_SYNC_WITHOUT_SYNC_EMIT = 601,\n\n // Styling Errors\n\n // Declarations Errors\n\n // i18n Errors\n INVALID_I18N_STRUCTURE = 700,\n MISSING_LOCALE_DATA = 701,\n\n // standalone errors\n IMPORT_PROVIDERS_FROM_STANDALONE = 800,\n\n // JIT Compilation Errors\n // Other\n INVALID_DIFFER_INPUT = 900,\n NO_SUPPORTING_DIFFER_FACTORY = 901,\n VIEW_ALREADY_ATTACHED = 902,\n INVALID_INHERITANCE = 903,\n UNSAFE_VALUE_IN_RESOURCE_URL = 904,\n UNSAFE_VALUE_IN_SCRIPT = 905,\n MISSING_GENERATED_DEF = 906,\n TYPE_IS_NOT_STANDALONE = 907,\n MISSING_ZONEJS = 908,\n UNEXPECTED_ZONE_STATE = 909,\n UNSAFE_IFRAME_ATTRS = -910,\n VIEW_ALREADY_DESTROYED = 911,\n COMPONENT_ID_COLLISION = -912,\n\n // Runtime dependency tracker errors\n RUNTIME_DEPS_INVALID_IMPORTED_TYPE = 1000,\n}\n\n\n/**\n * Class that represents a runtime error.\n * Formats and outputs the error message in a consistent way.\n *\n * Example:\n * ```\n * throw new RuntimeError(\n * RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED,\n * ngDevMode && 'Injector has already been destroyed.');\n * ```\n *\n * Note: the `message` argument contains a descriptive error message as a string in development\n * mode (when the `ngDevMode` is defined). In production mode (after tree-shaking pass), the\n * `message` argument becomes `false`, thus we account for it in the typings and the runtime\n * logic.\n */\nexport class RuntimeError extends Error {\n constructor(public code: T, message: null|false|string) {\n super(formatRuntimeError(code, message));\n }\n}\n\n/**\n * Called to format a runtime error.\n * See additional info on the `message` argument type in the `RuntimeError` class description.\n */\nexport function formatRuntimeError(\n code: T, message: null|false|string): string {\n // Error code might be a negative number, which is a special marker that instructs the logic to\n // generate a link to the error details page on angular.io.\n // We also prepend `0` to non-compile-time errors.\n const fullCode = `NG0${Math.abs(code)}`;\n\n let errorMessage = `${fullCode}${message ? ': ' + message : ''}`;\n\n if (ngDevMode && code < 0) {\n const addPeriodSeparator = !errorMessage.match(/[.,;!?\\n]$/);\n const separator = addPeriodSeparator ? '.' : '';\n errorMessage =\n `${errorMessage}${separator} Find more at ${ERROR_DETAILS_PAGE_BASE_URL}/${fullCode}`;\n }\n return errorMessage;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @description\n *\n * Represents a type that a Component or other object is instances of.\n *\n * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is represented by\n * the `MyCustomComponent` constructor function.\n *\n * @publicApi\n */\nexport const Type = Function;\n\nexport function isType(v: any): v is Type {\n return typeof v === 'function';\n}\n\n/**\n * @description\n *\n * Represents an abstract class `T`, if applied to a concrete class it would stop being\n * instantiable.\n *\n * @publicApi\n */\nexport interface AbstractType extends Function {\n prototype: T;\n}\n\nexport interface Type extends Function {\n new(...args: any[]): T;\n}\n\nexport type Mutable = {\n [P in K]: T[P];\n};\n\n/**\n * Returns a writable type version of type.\n *\n * USAGE:\n * Given:\n * ```\n * interface Person {readonly name: string}\n * ```\n *\n * We would like to get a read/write version of `Person`.\n * ```\n * const WritablePerson = Writable;\n * ```\n *\n * The result is that you can do:\n *\n * ```\n * const readonlyPerson: Person = {name: 'Marry'};\n * readonlyPerson.name = 'John'; // TypeError\n * (readonlyPerson as WritablePerson).name = 'John'; // OK\n *\n * // Error: Correctly detects that `Person` did not have `age` property.\n * (readonlyPerson as WritablePerson).age = 30;\n * ```\n */\nexport type Writable = {\n -readonly[K in keyof T]: T[K];\n};\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n// The functions in this file verify that the assumptions we are making\n// about state in an instruction are correct before implementing any logic.\n// They are meant only to be called in dev mode as sanity checks.\n\nimport {stringify} from './stringify';\n\nexport function assertNumber(actual: any, msg: string): asserts actual is number {\n if (!(typeof actual === 'number')) {\n throwError(msg, typeof actual, 'number', '===');\n }\n}\n\nexport function assertNumberInRange(\n actual: any, minInclusive: number, maxInclusive: number): asserts actual is number {\n assertNumber(actual, 'Expected a number');\n assertLessThanOrEqual(actual, maxInclusive, 'Expected number to be less than or equal to');\n assertGreaterThanOrEqual(actual, minInclusive, 'Expected number to be greater than or equal to');\n}\n\nexport function assertString(actual: any, msg: string): asserts actual is string {\n if (!(typeof actual === 'string')) {\n throwError(msg, actual === null ? 'null' : typeof actual, 'string', '===');\n }\n}\n\nexport function assertFunction(actual: any, msg: string): asserts actual is Function {\n if (!(typeof actual === 'function')) {\n throwError(msg, actual === null ? 'null' : typeof actual, 'function', '===');\n }\n}\n\nexport function assertEqual(actual: T, expected: T, msg: string) {\n if (!(actual == expected)) {\n throwError(msg, actual, expected, '==');\n }\n}\n\nexport function assertNotEqual(actual: T, expected: T, msg: string): asserts actual is T {\n if (!(actual != expected)) {\n throwError(msg, actual, expected, '!=');\n }\n}\n\nexport function assertSame(actual: T, expected: T, msg: string): asserts actual is T {\n if (!(actual === expected)) {\n throwError(msg, actual, expected, '===');\n }\n}\n\nexport function assertNotSame(actual: T, expected: T, msg: string) {\n if (!(actual !== expected)) {\n throwError(msg, actual, expected, '!==');\n }\n}\n\nexport function assertLessThan(actual: T, expected: T, msg: string): asserts actual is T {\n if (!(actual < expected)) {\n throwError(msg, actual, expected, '<');\n }\n}\n\nexport function assertLessThanOrEqual(actual: T, expected: T, msg: string): asserts actual is T {\n if (!(actual <= expected)) {\n throwError(msg, actual, expected, '<=');\n }\n}\n\nexport function assertGreaterThan(actual: T, expected: T, msg: string): asserts actual is T {\n if (!(actual > expected)) {\n throwError(msg, actual, expected, '>');\n }\n}\n\nexport function assertGreaterThanOrEqual(\n actual: T, expected: T, msg: string): asserts actual is T {\n if (!(actual >= expected)) {\n throwError(msg, actual, expected, '>=');\n }\n}\n\nexport function assertNotDefined(actual: T, msg: string) {\n if (actual != null) {\n throwError(msg, actual, null, '==');\n }\n}\n\nexport function assertDefined(actual: T|null|undefined, msg: string): asserts actual is T {\n if (actual == null) {\n throwError(msg, actual, null, '!=');\n }\n}\n\nexport function throwError(msg: string): never;\nexport function throwError(msg: string, actual: any, expected: any, comparison: string): never;\nexport function throwError(msg: string, actual?: any, expected?: any, comparison?: string): never {\n throw new Error(\n `ASSERTION ERROR: ${msg}` +\n (comparison == null ? '' : ` [Expected=> ${expected} ${comparison} ${actual} <=Actual]`));\n}\n\nexport function assertDomNode(node: any): asserts node is Node {\n if (!(node instanceof Node)) {\n throwError(`The provided value must be an instance of a DOM Node but got ${stringify(node)}`);\n }\n}\n\nexport function assertIndexInRange(arr: any[], index: number) {\n assertDefined(arr, 'Array must be defined.');\n const maxLen = arr.length;\n if (index < 0 || index >= maxLen) {\n throwError(`Index expected to be less than ${maxLen} but got ${index}`);\n }\n}\n\nexport function assertOneOf(value: any, ...validValues: any[]) {\n if (validValues.indexOf(value) !== -1) return true;\n throwError(`Expected value to be one of ${JSON.stringify(validValues)} but was ${\n JSON.stringify(value)}.`);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertEqual, assertLessThanOrEqual} from './assert';\n\n/**\n * Determines if the contents of two arrays is identical\n *\n * @param a first array\n * @param b second array\n * @param identityAccessor Optional function for extracting stable object identity from a value in\n * the array.\n */\nexport function arrayEquals(a: T[], b: T[], identityAccessor?: (value: T) => unknown): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n let valueA = a[i];\n let valueB = b[i];\n if (identityAccessor) {\n valueA = identityAccessor(valueA) as any;\n valueB = identityAccessor(valueB) as any;\n }\n if (valueB !== valueA) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Flattens an array.\n */\nexport function flatten(list: any[]): any[] {\n return list.flat(Number.POSITIVE_INFINITY);\n}\n\nexport function deepForEach(input: (T|any[])[], fn: (value: T) => void): void {\n input.forEach(value => Array.isArray(value) ? deepForEach(value, fn) : fn(value));\n}\n\nexport function addToArray(arr: any[], index: number, value: any): void {\n // perf: array.push is faster than array.splice!\n if (index >= arr.length) {\n arr.push(value);\n } else {\n arr.splice(index, 0, value);\n }\n}\n\nexport function removeFromArray(arr: any[], index: number): any {\n // perf: array.pop is faster than array.splice!\n if (index >= arr.length - 1) {\n return arr.pop();\n } else {\n return arr.splice(index, 1)[0];\n }\n}\n\nexport function newArray(size: number): T[];\nexport function newArray(size: number, value: T): T[];\nexport function newArray(size: number, value?: T): T[] {\n const list: T[] = [];\n for (let i = 0; i < size; i++) {\n list.push(value!);\n }\n return list;\n}\n\n/**\n * Remove item from array (Same as `Array.splice()` but faster.)\n *\n * `Array.splice()` is not as fast because it has to allocate an array for the elements which were\n * removed. This causes memory pressure and slows down code when most of the time we don't\n * care about the deleted items array.\n *\n * https://jsperf.com/fast-array-splice (About 20x faster)\n *\n * @param array Array to splice\n * @param index Index of element in array to remove.\n * @param count Number of items to remove.\n */\nexport function arraySplice(array: any[], index: number, count: number): void {\n const length = array.length - count;\n while (index < length) {\n array[index] = array[index + count];\n index++;\n }\n while (count--) {\n array.pop(); // shrink the array\n }\n}\n\n/**\n * Same as `Array.splice(index, 0, value)` but faster.\n *\n * `Array.splice()` is not fast because it has to allocate an array for the elements which were\n * removed. This causes memory pressure and slows down code when most of the time we don't\n * care about the deleted items array.\n *\n * @param array Array to splice.\n * @param index Index in array where the `value` should be added.\n * @param value Value to add to array.\n */\nexport function arrayInsert(array: any[], index: number, value: any): void {\n ngDevMode && assertLessThanOrEqual(index, array.length, 'Can\\'t insert past array end.');\n let end = array.length;\n while (end > index) {\n const previousEnd = end - 1;\n array[end] = array[previousEnd];\n end = previousEnd;\n }\n array[index] = value;\n}\n\n/**\n * Same as `Array.splice2(index, 0, value1, value2)` but faster.\n *\n * `Array.splice()` is not fast because it has to allocate an array for the elements which were\n * removed. This causes memory pressure and slows down code when most of the time we don't\n * care about the deleted items array.\n *\n * @param array Array to splice.\n * @param index Index in array where the `value` should be added.\n * @param value1 Value to add to array.\n * @param value2 Value to add to array.\n */\nexport function arrayInsert2(array: any[], index: number, value1: any, value2: any): void {\n ngDevMode && assertLessThanOrEqual(index, array.length, 'Can\\'t insert past array end.');\n let end = array.length;\n if (end == index) {\n // inserting at the end.\n array.push(value1, value2);\n } else if (end === 1) {\n // corner case when we have less items in array than we have items to insert.\n array.push(value2, array[0]);\n array[0] = value1;\n } else {\n end--;\n array.push(array[end - 1], array[end]);\n while (end > index) {\n const previousEnd = end - 2;\n array[end] = array[previousEnd];\n end--;\n }\n array[index] = value1;\n array[index + 1] = value2;\n }\n}\n\n\n/**\n * Get an index of an `value` in a sorted `array`.\n *\n * NOTE:\n * - This uses binary search algorithm for fast removals.\n *\n * @param array A sorted array to binary search.\n * @param value The value to look for.\n * @returns index of the value.\n * - positive index if value found.\n * - negative index if value not found. (`~index` to get the value where it should have been\n * located)\n */\nexport function arrayIndexOfSorted(array: string[], value: string): number {\n return _arrayIndexOfSorted(array, value, 0);\n}\n\n\n/**\n * `KeyValueArray` is an array where even positions contain keys and odd positions contain values.\n *\n * `KeyValueArray` provides a very efficient way of iterating over its contents. For small\n * sets (~10) the cost of binary searching an `KeyValueArray` has about the same performance\n * characteristics that of a `Map` with significantly better memory footprint.\n *\n * If used as a `Map` the keys are stored in alphabetical order so that they can be binary searched\n * for retrieval.\n *\n * See: `keyValueArraySet`, `keyValueArrayGet`, `keyValueArrayIndexOf`, `keyValueArrayDelete`.\n */\nexport interface KeyValueArray extends Array {\n __brand__: 'array-map';\n}\n\n/**\n * Set a `value` for a `key`.\n *\n * @param keyValueArray to modify.\n * @param key The key to locate or create.\n * @param value The value to set for a `key`.\n * @returns index (always even) of where the value vas set.\n */\nexport function keyValueArraySet(\n keyValueArray: KeyValueArray, key: string, value: V): number {\n let index = keyValueArrayIndexOf(keyValueArray, key);\n if (index >= 0) {\n // if we found it set it.\n keyValueArray[index | 1] = value;\n } else {\n index = ~index;\n arrayInsert2(keyValueArray, index, key, value);\n }\n return index;\n}\n\n/**\n * Retrieve a `value` for a `key` (on `undefined` if not found.)\n *\n * @param keyValueArray to search.\n * @param key The key to locate.\n * @return The `value` stored at the `key` location or `undefined if not found.\n */\nexport function keyValueArrayGet(keyValueArray: KeyValueArray, key: string): V|undefined {\n const index = keyValueArrayIndexOf(keyValueArray, key);\n if (index >= 0) {\n // if we found it retrieve it.\n return keyValueArray[index | 1] as V;\n }\n return undefined;\n}\n\n/**\n * Retrieve a `key` index value in the array or `-1` if not found.\n *\n * @param keyValueArray to search.\n * @param key The key to locate.\n * @returns index of where the key is (or should have been.)\n * - positive (even) index if key found.\n * - negative index if key not found. (`~index` (even) to get the index where it should have\n * been inserted.)\n */\nexport function keyValueArrayIndexOf(keyValueArray: KeyValueArray, key: string): number {\n return _arrayIndexOfSorted(keyValueArray as string[], key, 1);\n}\n\n/**\n * Delete a `key` (and `value`) from the `KeyValueArray`.\n *\n * @param keyValueArray to modify.\n * @param key The key to locate or delete (if exist).\n * @returns index of where the key was (or should have been.)\n * - positive (even) index if key found and deleted.\n * - negative index if key not found. (`~index` (even) to get the index where it should have\n * been.)\n */\nexport function keyValueArrayDelete(keyValueArray: KeyValueArray, key: string): number {\n const index = keyValueArrayIndexOf(keyValueArray, key);\n if (index >= 0) {\n // if we found it remove it.\n arraySplice(keyValueArray, index, 2);\n }\n return index;\n}\n\n\n/**\n * INTERNAL: Get an index of an `value` in a sorted `array` by grouping search by `shift`.\n *\n * NOTE:\n * - This uses binary search algorithm for fast removals.\n *\n * @param array A sorted array to binary search.\n * @param value The value to look for.\n * @param shift grouping shift.\n * - `0` means look at every location\n * - `1` means only look at every other (even) location (the odd locations are to be ignored as\n * they are values.)\n * @returns index of the value.\n * - positive index if value found.\n * - negative index if value not found. (`~index` to get the value where it should have been\n * inserted)\n */\nfunction _arrayIndexOfSorted(array: string[], value: string, shift: number): number {\n ngDevMode && assertEqual(Array.isArray(array), true, 'Expecting an array');\n let start = 0;\n let end = array.length >> shift;\n while (end !== start) {\n const middle = start + ((end - start) >> 1); // find the middle.\n const current = array[middle << shift];\n if (value === current) {\n return (middle << shift);\n } else if (current > value) {\n end = middle;\n } else {\n start = middle + 1; // We already searched middle so make it non-inclusive by adding 1\n }\n }\n return ~(end << shift);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Convince closure compiler that the wrapped function has no side-effects.\n *\n * Closure compiler always assumes that `toString` has no side-effects. We use this quirk to\n * allow us to execute a function but have closure compiler mark the call as no-side-effects.\n * It is important that the return value for the `noSideEffects` function be assigned\n * to something which is retained otherwise the call to `noSideEffects` will be removed by closure\n * compiler.\n */\nexport function noSideEffects(fn: () => T): T {\n return {toString: fn}.toString() as unknown as T;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Type} from '../interface/type';\n\nimport {noSideEffects} from './closure';\n\n\n\n/**\n * An interface implemented by all Angular type decorators, which allows them to be used as\n * decorators as well as Angular syntax.\n *\n * ```\n * @ng.Component({...})\n * class MyClass {...}\n * ```\n *\n * @publicApi\n */\nexport interface TypeDecorator {\n /**\n * Invoke as decorator.\n */\n >(type: T): T;\n\n // Make TypeDecorator assignable to built-in ParameterDecorator type.\n // ParameterDecorator is declared in lib.d.ts as a `declare type`\n // so we cannot declare this interface as a subtype.\n // see https://github.com/angular/angular/issues/3379#issuecomment-126169417\n (target: Object, propertyKey?: string|symbol, parameterIndex?: number): void;\n // Standard (non-experimental) Decorator signature that avoids direct usage of\n // any TS 5.0+ specific types.\n (target: unknown, context: unknown): void;\n}\n\nexport const ANNOTATIONS = '__annotations__';\nexport const PARAMETERS = '__parameters__';\nexport const PROP_METADATA = '__prop__metadata__';\n\n/**\n * @suppress {globalThis}\n */\nexport function makeDecorator(\n name: string, props?: (...args: any[]) => any, parentClass?: any,\n additionalProcessing?: (type: Type) => void,\n typeFn?: (type: Type, ...args: any[]) => void):\n {new (...args: any[]): any; (...args: any[]): any; (...args: any[]): (cls: any) => any;} {\n return noSideEffects(() => {\n const metaCtor = makeMetadataCtor(props);\n\n function DecoratorFactory(\n this: unknown|typeof DecoratorFactory, ...args: any[]): (cls: Type) => any {\n if (this instanceof DecoratorFactory) {\n metaCtor.call(this, ...args);\n return this as typeof DecoratorFactory;\n }\n\n const annotationInstance = new (DecoratorFactory as any)(...args);\n return function TypeDecorator(cls: Type) {\n if (typeFn) typeFn(cls, ...args);\n // Use of Object.defineProperty is important since it creates non-enumerable property which\n // prevents the property is copied during subclassing.\n const annotations = cls.hasOwnProperty(ANNOTATIONS) ?\n (cls as any)[ANNOTATIONS] :\n (Object.defineProperty(cls, ANNOTATIONS, {value: []}) as any)[ANNOTATIONS];\n annotations.push(annotationInstance);\n\n\n if (additionalProcessing) additionalProcessing(cls);\n\n return cls;\n };\n }\n\n if (parentClass) {\n DecoratorFactory.prototype = Object.create(parentClass.prototype);\n }\n\n DecoratorFactory.prototype.ngMetadataName = name;\n (DecoratorFactory as any).annotationCls = DecoratorFactory;\n return DecoratorFactory as any;\n });\n}\n\nfunction makeMetadataCtor(props?: (...args: any[]) => any): any {\n return function ctor(this: any, ...args: any[]) {\n if (props) {\n const values = props(...args);\n for (const propName in values) {\n this[propName] = values[propName];\n }\n }\n };\n}\n\nexport function makeParamDecorator(\n name: string, props?: (...args: any[]) => any, parentClass?: any): any {\n return noSideEffects(() => {\n const metaCtor = makeMetadataCtor(props);\n function ParamDecoratorFactory(\n this: unknown|typeof ParamDecoratorFactory, ...args: any[]): any {\n if (this instanceof ParamDecoratorFactory) {\n metaCtor.apply(this, args);\n return this;\n }\n const annotationInstance = new (ParamDecoratorFactory)(...args);\n\n (ParamDecorator).annotation = annotationInstance;\n return ParamDecorator;\n\n function ParamDecorator(cls: any, unusedKey: any, index: number): any {\n // Use of Object.defineProperty is important since it creates non-enumerable property which\n // prevents the property is copied during subclassing.\n const parameters = cls.hasOwnProperty(PARAMETERS) ?\n (cls as any)[PARAMETERS] :\n Object.defineProperty(cls, PARAMETERS, {value: []})[PARAMETERS];\n\n // there might be gaps if some in between parameters do not have annotations.\n // we pad with nulls.\n while (parameters.length <= index) {\n parameters.push(null);\n }\n\n (parameters[index] = parameters[index] || []).push(annotationInstance);\n return cls;\n }\n }\n if (parentClass) {\n ParamDecoratorFactory.prototype = Object.create(parentClass.prototype);\n }\n ParamDecoratorFactory.prototype.ngMetadataName = name;\n (ParamDecoratorFactory).annotationCls = ParamDecoratorFactory;\n return ParamDecoratorFactory;\n });\n}\n\nexport function makePropDecorator(\n name: string, props?: (...args: any[]) => any, parentClass?: any,\n additionalProcessing?: (target: any, name: string, ...args: any[]) => void): any {\n return noSideEffects(() => {\n const metaCtor = makeMetadataCtor(props);\n\n function PropDecoratorFactory(this: unknown|typeof PropDecoratorFactory, ...args: any[]): any {\n if (this instanceof PropDecoratorFactory) {\n metaCtor.apply(this, args);\n return this;\n }\n\n const decoratorInstance = new (PropDecoratorFactory)(...args);\n\n function PropDecorator(target: any, name: string) {\n // target is undefined with standard decorators. This case is not supported and will throw\n // if this decorator is used in JIT mode with standard decorators.\n if (target === undefined) {\n throw new Error('Standard Angular field decorators are not supported in JIT mode.');\n }\n\n const constructor = target.constructor;\n // Use of Object.defineProperty is important because it creates a non-enumerable property\n // which prevents the property from being copied during subclassing.\n const meta = constructor.hasOwnProperty(PROP_METADATA) ?\n (constructor as any)[PROP_METADATA] :\n Object.defineProperty(constructor, PROP_METADATA, {value: {}})[PROP_METADATA];\n meta[name] = meta.hasOwnProperty(name) && meta[name] || [];\n meta[name].unshift(decoratorInstance);\n\n if (additionalProcessing) additionalProcessing(target, name, ...args);\n }\n\n return PropDecorator;\n }\n\n if (parentClass) {\n PropDecoratorFactory.prototype = Object.create(parentClass.prototype);\n }\n\n PropDecoratorFactory.prototype.ngMetadataName = name;\n (PropDecoratorFactory).annotationCls = PropDecoratorFactory;\n return PropDecoratorFactory;\n });\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {isType, Type} from '../interface/type';\nimport {newArray} from '../util/array_utils';\nimport {ANNOTATIONS, PARAMETERS, PROP_METADATA} from '../util/decorators';\nimport {global} from '../util/global';\n\nimport {PlatformReflectionCapabilities} from './platform_reflection_capabilities';\n\n\n\n/*\n * #########################\n * Attention: These Regular expressions have to hold even if the code is minified!\n * ##########################\n */\n\n/**\n * Regular expression that detects pass-through constructors for ES5 output. This Regex\n * intends to capture the common delegation pattern emitted by TypeScript and Babel. Also\n * it intends to capture the pattern where existing constructors have been downleveled from\n * ES2015 to ES5 using TypeScript w/ downlevel iteration. e.g.\n *\n * ```\n * function MyClass() {\n * var _this = _super.apply(this, arguments) || this;\n * ```\n *\n * downleveled to ES5 with `downlevelIteration` for TypeScript < 4.2:\n * ```\n * function MyClass() {\n * var _this = _super.apply(this, __spread(arguments)) || this;\n * ```\n *\n * or downleveled to ES5 with `downlevelIteration` for TypeScript >= 4.2:\n * ```\n * function MyClass() {\n * var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;\n * ```\n *\n * More details can be found in: https://github.com/angular/angular/issues/38453.\n */\nexport const ES5_DELEGATE_CTOR =\n /^function\\s+\\S+\\(\\)\\s*{[\\s\\S]+\\.apply\\(this,\\s*(arguments|(?:[^()]+\\(\\[\\],)?[^()]+\\(arguments\\).*)\\)/;\n/** Regular expression that detects ES2015 classes which extend from other classes. */\nexport const ES2015_INHERITED_CLASS = /^class\\s+[A-Za-z\\d$_]*\\s*extends\\s+[^{]+{/;\n/**\n * Regular expression that detects ES2015 classes which extend from other classes and\n * have an explicit constructor defined.\n */\nexport const ES2015_INHERITED_CLASS_WITH_CTOR =\n /^class\\s+[A-Za-z\\d$_]*\\s*extends\\s+[^{]+{[\\s\\S]*constructor\\s*\\(/;\n/**\n * Regular expression that detects ES2015 classes which extend from other classes\n * and inherit a constructor.\n */\nexport const ES2015_INHERITED_CLASS_WITH_DELEGATE_CTOR =\n /^class\\s+[A-Za-z\\d$_]*\\s*extends\\s+[^{]+{[\\s\\S]*constructor\\s*\\(\\)\\s*{[^}]*super\\(\\.\\.\\.arguments\\)/;\n\n/**\n * Determine whether a stringified type is a class which delegates its constructor\n * to its parent.\n *\n * This is not trivial since compiled code can actually contain a constructor function\n * even if the original source code did not. For instance, when the child class contains\n * an initialized instance property.\n */\nexport function isDelegateCtor(typeStr: string): boolean {\n return ES5_DELEGATE_CTOR.test(typeStr) ||\n ES2015_INHERITED_CLASS_WITH_DELEGATE_CTOR.test(typeStr) ||\n (ES2015_INHERITED_CLASS.test(typeStr) && !ES2015_INHERITED_CLASS_WITH_CTOR.test(typeStr));\n}\n\nexport class ReflectionCapabilities implements PlatformReflectionCapabilities {\n private _reflect: any;\n\n constructor(reflect?: any) {\n this._reflect = reflect || global['Reflect'];\n }\n\n factory(t: Type): (args: any[]) => T {\n return (...args: any[]) => new t(...args);\n }\n\n /** @internal */\n _zipTypesAndAnnotations(paramTypes: any[], paramAnnotations: any[]): any[][] {\n let result: any[][];\n\n if (typeof paramTypes === 'undefined') {\n result = newArray(paramAnnotations.length);\n } else {\n result = newArray(paramTypes.length);\n }\n\n for (let i = 0; i < result.length; i++) {\n // TS outputs Object for parameters without types, while Traceur omits\n // the annotations. For now we preserve the Traceur behavior to aid\n // migration, but this can be revisited.\n if (typeof paramTypes === 'undefined') {\n result[i] = [];\n } else if (paramTypes[i] && paramTypes[i] != Object) {\n result[i] = [paramTypes[i]];\n } else {\n result[i] = [];\n }\n if (paramAnnotations && paramAnnotations[i] != null) {\n result[i] = result[i].concat(paramAnnotations[i]);\n }\n }\n return result;\n }\n\n private _ownParameters(type: Type, parentCtor: any): any[][]|null {\n const typeStr = type.toString();\n // If we have no decorators, we only have function.length as metadata.\n // In that case, to detect whether a child class declared an own constructor or not,\n // we need to look inside of that constructor to check whether it is\n // just calling the parent.\n // This also helps to work around for https://github.com/Microsoft/TypeScript/issues/12439\n // that sets 'design:paramtypes' to []\n // if a class inherits from another class but has no ctor declared itself.\n if (isDelegateCtor(typeStr)) {\n return null;\n }\n\n // Prefer the direct API.\n if ((type).parameters && (type).parameters !== parentCtor.parameters) {\n return (type).parameters;\n }\n\n // API of tsickle for lowering decorators to properties on the class.\n const tsickleCtorParams = (type).ctorParameters;\n if (tsickleCtorParams && tsickleCtorParams !== parentCtor.ctorParameters) {\n // Newer tsickle uses a function closure\n // Retain the non-function case for compatibility with older tsickle\n const ctorParameters =\n typeof tsickleCtorParams === 'function' ? tsickleCtorParams() : tsickleCtorParams;\n const paramTypes = ctorParameters.map((ctorParam: any) => ctorParam && ctorParam.type);\n const paramAnnotations = ctorParameters.map(\n (ctorParam: any) =>\n ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators));\n return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);\n }\n\n // API for metadata created by invoking the decorators.\n const paramAnnotations = type.hasOwnProperty(PARAMETERS) && (type as any)[PARAMETERS];\n const paramTypes = this._reflect && this._reflect.getOwnMetadata &&\n this._reflect.getOwnMetadata('design:paramtypes', type);\n if (paramTypes || paramAnnotations) {\n return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);\n }\n\n // If a class has no decorators, at least create metadata\n // based on function.length.\n // Note: We know that this is a real constructor as we checked\n // the content of the constructor above.\n return newArray(type.length);\n }\n\n parameters(type: Type): any[][] {\n // Note: only report metadata if we have at least one class decorator\n // to stay in sync with the static reflector.\n if (!isType(type)) {\n return [];\n }\n const parentCtor = getParentCtor(type);\n let parameters = this._ownParameters(type, parentCtor);\n if (!parameters && parentCtor !== Object) {\n parameters = this.parameters(parentCtor);\n }\n return parameters || [];\n }\n\n private _ownAnnotations(typeOrFunc: Type, parentCtor: any): any[]|null {\n // Prefer the direct API.\n if ((typeOrFunc).annotations && (typeOrFunc).annotations !== parentCtor.annotations) {\n let annotations = (typeOrFunc).annotations;\n if (typeof annotations === 'function' && annotations.annotations) {\n annotations = annotations.annotations;\n }\n return annotations;\n }\n\n // API of tsickle for lowering decorators to properties on the class.\n if ((typeOrFunc).decorators && (typeOrFunc).decorators !== parentCtor.decorators) {\n return convertTsickleDecoratorIntoMetadata((typeOrFunc).decorators);\n }\n\n // API for metadata created by invoking the decorators.\n if (typeOrFunc.hasOwnProperty(ANNOTATIONS)) {\n return (typeOrFunc as any)[ANNOTATIONS];\n }\n return null;\n }\n\n annotations(typeOrFunc: Type): any[] {\n if (!isType(typeOrFunc)) {\n return [];\n }\n const parentCtor = getParentCtor(typeOrFunc);\n const ownAnnotations = this._ownAnnotations(typeOrFunc, parentCtor) || [];\n const parentAnnotations = parentCtor !== Object ? this.annotations(parentCtor) : [];\n return parentAnnotations.concat(ownAnnotations);\n }\n\n private _ownPropMetadata(typeOrFunc: any, parentCtor: any): {[key: string]: any[]}|null {\n // Prefer the direct API.\n if ((typeOrFunc).propMetadata &&\n (typeOrFunc).propMetadata !== parentCtor.propMetadata) {\n let propMetadata = (typeOrFunc).propMetadata;\n if (typeof propMetadata === 'function' && propMetadata.propMetadata) {\n propMetadata = propMetadata.propMetadata;\n }\n return propMetadata;\n }\n\n // API of tsickle for lowering decorators to properties on the class.\n if ((typeOrFunc).propDecorators &&\n (typeOrFunc).propDecorators !== parentCtor.propDecorators) {\n const propDecorators = (typeOrFunc).propDecorators;\n const propMetadata = <{[key: string]: any[]}>{};\n Object.keys(propDecorators).forEach(prop => {\n propMetadata[prop] = convertTsickleDecoratorIntoMetadata(propDecorators[prop]);\n });\n return propMetadata;\n }\n\n // API for metadata created by invoking the decorators.\n if (typeOrFunc.hasOwnProperty(PROP_METADATA)) {\n return (typeOrFunc as any)[PROP_METADATA];\n }\n return null;\n }\n\n propMetadata(typeOrFunc: any): {[key: string]: any[]} {\n if (!isType(typeOrFunc)) {\n return {};\n }\n const parentCtor = getParentCtor(typeOrFunc);\n const propMetadata: {[key: string]: any[]} = {};\n if (parentCtor !== Object) {\n const parentPropMetadata = this.propMetadata(parentCtor);\n Object.keys(parentPropMetadata).forEach((propName) => {\n propMetadata[propName] = parentPropMetadata[propName];\n });\n }\n const ownPropMetadata = this._ownPropMetadata(typeOrFunc, parentCtor);\n if (ownPropMetadata) {\n Object.keys(ownPropMetadata).forEach((propName) => {\n const decorators: any[] = [];\n if (propMetadata.hasOwnProperty(propName)) {\n decorators.push(...propMetadata[propName]);\n }\n decorators.push(...ownPropMetadata[propName]);\n propMetadata[propName] = decorators;\n });\n }\n return propMetadata;\n }\n\n ownPropMetadata(typeOrFunc: any): {[key: string]: any[]} {\n if (!isType(typeOrFunc)) {\n return {};\n }\n return this._ownPropMetadata(typeOrFunc, getParentCtor(typeOrFunc)) || {};\n }\n\n hasLifecycleHook(type: any, lcProperty: string): boolean {\n return type instanceof Type && lcProperty in type.prototype;\n }\n}\n\nfunction convertTsickleDecoratorIntoMetadata(decoratorInvocations: any[]): any[] {\n if (!decoratorInvocations) {\n return [];\n }\n return decoratorInvocations.map(decoratorInvocation => {\n const decoratorType = decoratorInvocation.type;\n const annotationCls = decoratorType.annotationCls;\n const annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];\n return new annotationCls(...annotationArgs);\n });\n}\n\nfunction getParentCtor(ctor: Function): Type {\n const parentProto = ctor.prototype ? Object.getPrototypeOf(ctor.prototype) : null;\n const parentCtor = parentProto ? parentProto.constructor : null;\n // Note: We always use `Object` as the null value\n // to simplify checking later on.\n return parentCtor || Object;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {global} from './global';\n\ndeclare global {\n /**\n * Values of ngDevMode\n * Depending on the current state of the application, ngDevMode may have one of several values.\n *\n * For convenience, the “truthy” value which enables dev mode is also an object which contains\n * Angular’s performance counters. This is not necessary, but cuts down on boilerplate for the\n * perf counters.\n *\n * ngDevMode may also be set to false. This can happen in one of a few ways:\n * - The user explicitly sets `window.ngDevMode = false` somewhere in their app.\n * - The user calls `enableProdMode()`.\n * - The URL contains a `ngDevMode=false` text.\n * Finally, ngDevMode may not have been defined at all.\n */\n const ngDevMode: null|NgDevModePerfCounters;\n\n interface NgDevModePerfCounters {\n namedConstructors: boolean;\n firstCreatePass: number;\n tNode: number;\n tView: number;\n rendererCreateTextNode: number;\n rendererSetText: number;\n rendererCreateElement: number;\n rendererAddEventListener: number;\n rendererSetAttribute: number;\n rendererRemoveAttribute: number;\n rendererSetProperty: number;\n rendererSetClassName: number;\n rendererAddClass: number;\n rendererRemoveClass: number;\n rendererSetStyle: number;\n rendererRemoveStyle: number;\n rendererDestroy: number;\n rendererDestroyNode: number;\n rendererMoveNode: number;\n rendererRemoveNode: number;\n rendererAppendChild: number;\n rendererInsertBefore: number;\n rendererCreateComment: number;\n hydratedNodes: number;\n hydratedComponents: number;\n dehydratedViewsRemoved: number;\n dehydratedViewsCleanupRuns: number;\n componentsSkippedHydration: number;\n }\n}\n\nexport function ngDevModeResetPerfCounters(): NgDevModePerfCounters {\n const locationString = typeof location !== 'undefined' ? location.toString() : '';\n const newCounters: NgDevModePerfCounters = {\n namedConstructors: locationString.indexOf('ngDevMode=namedConstructors') != -1,\n firstCreatePass: 0,\n tNode: 0,\n tView: 0,\n rendererCreateTextNode: 0,\n rendererSetText: 0,\n rendererCreateElement: 0,\n rendererAddEventListener: 0,\n rendererSetAttribute: 0,\n rendererRemoveAttribute: 0,\n rendererSetProperty: 0,\n rendererSetClassName: 0,\n rendererAddClass: 0,\n rendererRemoveClass: 0,\n rendererSetStyle: 0,\n rendererRemoveStyle: 0,\n rendererDestroy: 0,\n rendererDestroyNode: 0,\n rendererMoveNode: 0,\n rendererRemoveNode: 0,\n rendererAppendChild: 0,\n rendererInsertBefore: 0,\n rendererCreateComment: 0,\n hydratedNodes: 0,\n hydratedComponents: 0,\n dehydratedViewsRemoved: 0,\n dehydratedViewsCleanupRuns: 0,\n componentsSkippedHydration: 0,\n };\n\n // Make sure to refer to ngDevMode as ['ngDevMode'] for closure.\n const allowNgDevModeTrue = locationString.indexOf('ngDevMode=false') === -1;\n global['ngDevMode'] = allowNgDevModeTrue && newCounters;\n return newCounters;\n}\n\n/**\n * This function checks to see if the `ngDevMode` has been set. If yes,\n * then we honor it, otherwise we default to dev mode with additional checks.\n *\n * The idea is that unless we are doing production build where we explicitly\n * set `ngDevMode == false` we should be helping the developer by providing\n * as much early warning and errors as possible.\n *\n * `ɵɵdefineComponent` is guaranteed to have been called before any component template functions\n * (and thus Ivy instructions), so a single initialization there is sufficient to ensure ngDevMode\n * is defined for the entire instruction set.\n *\n * When checking `ngDevMode` on toplevel, always init it before referencing it\n * (e.g. `((typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode())`), otherwise you can\n * get a `ReferenceError` like in https://github.com/angular/angular/issues/31595.\n *\n * Details on possible values for `ngDevMode` can be found on its docstring.\n *\n * NOTE:\n * - changes to the `ngDevMode` name must be synced with `compiler-cli/src/tooling.ts`.\n */\nexport function initNgDevMode(): boolean {\n // The below checks are to ensure that calling `initNgDevMode` multiple times does not\n // reset the counters.\n // If the `ngDevMode` is not an object, then it means we have not created the perf counters\n // yet.\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (typeof ngDevMode !== 'object') {\n ngDevModeResetPerfCounters();\n }\n return typeof ngDevMode !== 'undefined' && !!ngDevMode;\n }\n return false;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {resolveForwardRef} from '../../di/forward_ref';\nimport {InjectionToken} from '../../di/injection_token';\nimport type {Injector} from '../../di/injector';\nimport {InjectFlags, InjectOptions, InternalInjectFlags} from '../../di/interface/injector';\nimport type {SingleProvider} from '../../di/provider_collection';\nimport {Type} from '../../interface/type';\nimport {throwError} from '../../util/assert';\n\n/**\n * An enum describing the types of events that can be emitted from the injector profiler\n */\nexport const enum InjectorProfilerEventType {\n /**\n * Emits when a service is injected.\n */\n Inject,\n\n /**\n * Emits when an Angular class instance is created by an injector.\n */\n InstanceCreatedByInjector,\n\n /**\n * Emits when an injector configures a provider.\n */\n ProviderConfigured\n}\n\n/**\n * An object that defines an injection context for the injector profiler.\n */\nexport interface InjectorProfilerContext {\n /**\n * The Injector that service is being injected into.\n * - Example: if ModuleA --provides--> ServiceA --injects--> ServiceB\n * then inject(ServiceB) in ServiceA has ModuleA as an injector context\n */\n injector: Injector;\n\n /**\n * The class where the constructor that is calling `inject` is located\n * - Example: if ModuleA --provides--> ServiceA --injects--> ServiceB\n * then inject(ServiceB) in ServiceA has ServiceA as a construction context\n */\n token: Type|null;\n}\n\n\nexport interface InjectedServiceEvent {\n type: InjectorProfilerEventType.Inject;\n context: InjectorProfilerContext;\n service: InjectedService;\n}\n\nexport interface InjectorCreatedInstanceEvent {\n type: InjectorProfilerEventType.InstanceCreatedByInjector;\n context: InjectorProfilerContext;\n instance: InjectorCreatedInstance;\n}\n\nexport interface ProviderConfiguredEvent {\n type: InjectorProfilerEventType.ProviderConfigured;\n context: InjectorProfilerContext;\n providerRecord: ProviderRecord;\n}\n\n/**\n * An object representing an event that is emitted through the injector profiler\n */\n\nexport type InjectorProfilerEvent =\n InjectedServiceEvent|InjectorCreatedInstanceEvent|ProviderConfiguredEvent;\n\n/**\n * An object that contains information about a provider that has been configured\n */\nexport interface ProviderRecord {\n /**\n * DI token that this provider is configuring\n */\n token: Type;\n\n /**\n * Determines if provider is configured as view provider.\n */\n isViewProvider: boolean;\n\n /**\n * The raw provider associated with this ProviderRecord.\n */\n provider: SingleProvider;\n\n /**\n * The path of DI containers that were followed to import this provider\n */\n importPath?: Type[];\n}\n\n/**\n * An object that contains information about a value that has been constructed within an injector\n */\nexport interface InjectorCreatedInstance {\n /**\n * Value of the created instance\n */\n value: unknown;\n}\n\n/**\n * An object that contains information a service that has been injected within an\n * InjectorProfilerContext\n */\nexport interface InjectedService {\n /**\n * DI token of the Service that is injected\n */\n token?: Type|InjectionToken;\n\n /**\n * Value of the injected service\n */\n value: unknown;\n\n /**\n * Flags that this service was injected with\n */\n flags?: InternalInjectFlags|InjectFlags|InjectOptions;\n\n /**\n * Injector that this service was provided in.\n */\n providedIn?: Injector;\n}\n\nexport interface InjectorProfiler {\n (event: InjectorProfilerEvent): void;\n}\n\nlet _injectorProfilerContext: InjectorProfilerContext;\nexport function getInjectorProfilerContext() {\n !ngDevMode && throwError('getInjectorProfilerContext should never be called in production mode');\n return _injectorProfilerContext;\n}\n\nexport function setInjectorProfilerContext(context: InjectorProfilerContext) {\n !ngDevMode && throwError('setInjectorProfilerContext should never be called in production mode');\n\n const previous = _injectorProfilerContext;\n _injectorProfilerContext = context;\n return previous;\n}\n\nlet injectorProfilerCallback: InjectorProfiler|null = null;\n\n/**\n * Sets the callback function which will be invoked during certain DI events within the\n * runtime (for example: injecting services, creating injectable instances, configuring providers)\n *\n * Warning: this function is *INTERNAL* and should not be relied upon in application's code.\n * The contract of the function might be changed in any release and/or the function can be removed\n * completely.\n *\n * @param profiler function provided by the caller or null value to disable profiling.\n */\nexport const setInjectorProfiler = (injectorProfiler: InjectorProfiler|null) => {\n !ngDevMode && throwError('setInjectorProfiler should never be called in production mode');\n injectorProfilerCallback = injectorProfiler;\n};\n\n/**\n * Injector profiler function which emits on DI events executed by the runtime.\n *\n * @param event InjectorProfilerEvent corresponding to the DI event being emitted\n */\nfunction injectorProfiler(event: InjectorProfilerEvent): void {\n !ngDevMode && throwError('Injector profiler should never be called in production mode');\n\n if (injectorProfilerCallback != null /* both `null` and `undefined` */) {\n injectorProfilerCallback!(event);\n }\n}\n\n/**\n * Emits an InjectorProfilerEventType.ProviderConfigured to the injector profiler. The data in the\n * emitted event includes the raw provider, as well as the token that provider is providing.\n *\n * @param provider A provider object\n */\nexport function emitProviderConfiguredEvent(\n provider: SingleProvider, isViewProvider: boolean = false): void {\n !ngDevMode && throwError('Injector profiler should never be called in production mode');\n\n injectorProfiler({\n type: InjectorProfilerEventType.ProviderConfigured,\n context: getInjectorProfilerContext(),\n providerRecord: {\n token: typeof provider === 'function' ? provider : resolveForwardRef(provider.provide),\n provider,\n isViewProvider\n }\n });\n}\n\n/**\n * Emits an event to the injector profiler with the instance that was created. Note that\n * the injector associated with this emission can be accessed by using getDebugInjectContext()\n *\n * @param instance an object created by an injector\n */\nexport function emitInstanceCreatedByInjectorEvent(instance: unknown): void {\n !ngDevMode && throwError('Injector profiler should never be called in production mode');\n\n injectorProfiler({\n type: InjectorProfilerEventType.InstanceCreatedByInjector,\n context: getInjectorProfilerContext(),\n instance: {value: instance}\n });\n}\n\n/**\n * @param token DI token associated with injected service\n * @param value the instance of the injected service (i.e the result of `inject(token)`)\n * @param flags the flags that the token was injected with\n */\nexport function emitInjectEvent(token: Type, value: unknown, flags: InjectFlags): void {\n !ngDevMode && throwError('Injector profiler should never be called in production mode');\n\n injectorProfiler({\n type: InjectorProfilerEventType.Inject,\n context: getInjectorProfilerContext(),\n service: {token, value, flags}\n });\n}\n\nexport function runInInjectorProfilerContext(\n injector: Injector, token: Type, callback: () => void): void {\n !ngDevMode &&\n throwError('runInInjectorProfilerContext should never be called in production mode');\n\n const prevInjectContext = setInjectorProfilerContext({injector, token});\n try {\n callback();\n } finally {\n setInjectorProfilerContext(prevInjectContext);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Type} from '../../interface/type';\n\n/**\n * Configures the `Injector` to return a value for a token.\n * Base for `ValueProvider` decorator.\n *\n * @publicApi\n */\nexport interface ValueSansProvider {\n /**\n * The value to inject.\n */\n useValue: any;\n}\n\n/**\n * Configures the `Injector` to return a value for a token.\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection).\n *\n * @usageNotes\n *\n * ### Example\n *\n * {@example core/di/ts/provider_spec.ts region='ValueProvider'}\n *\n * ### Multi-value example\n *\n * {@example core/di/ts/provider_spec.ts region='MultiProviderAspect'}\n *\n * @publicApi\n */\nexport interface ValueProvider extends ValueSansProvider {\n /**\n * An injection token. Typically an instance of `Type` or `InjectionToken`, but can be `any`.\n */\n provide: any;\n\n /**\n * When true, injector returns an array of instances. This is useful to allow multiple\n * providers spread across many files to provide configuration information to a common token.\n */\n multi?: boolean;\n}\n\n/**\n * Configures the `Injector` to return an instance of `useClass` for a token.\n * Base for `StaticClassProvider` decorator.\n *\n * @publicApi\n */\nexport interface StaticClassSansProvider {\n /**\n * An optional class to instantiate for the `token`. By default, the `provide`\n * class is instantiated.\n */\n useClass: Type;\n\n /**\n * A list of `token`s to be resolved by the injector. The list of values is then\n * used as arguments to the `useClass` constructor.\n */\n deps: any[];\n}\n\n/**\n * Configures the `Injector` to return an instance of `useClass` for a token.\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection).\n *\n * @usageNotes\n *\n * {@example core/di/ts/provider_spec.ts region='StaticClassProvider'}\n *\n * Note that following two providers are not equal:\n *\n * {@example core/di/ts/provider_spec.ts region='StaticClassProviderDifference'}\n *\n * ### Multi-value example\n *\n * {@example core/di/ts/provider_spec.ts region='MultiProviderAspect'}\n *\n * @publicApi\n */\nexport interface StaticClassProvider extends StaticClassSansProvider {\n /**\n * An injection token. Typically an instance of `Type` or `InjectionToken`, but can be `any`.\n */\n provide: any;\n\n /**\n * When true, injector returns an array of instances. This is useful to allow multiple\n * providers spread across many files to provide configuration information to a common token.\n */\n multi?: boolean;\n}\n\n/**\n * Configures the `Injector` to return an instance of a token.\n *\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection).\n *\n * @usageNotes\n *\n * ```ts\n * @Injectable(SomeModule, {deps: []})\n * class MyService {}\n * ```\n *\n * @publicApi\n */\nexport interface ConstructorSansProvider {\n /**\n * A list of `token`s to be resolved by the injector.\n */\n deps?: any[];\n}\n\n/**\n * Configures the `Injector` to return an instance of a token.\n *\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection).\n *\n * @usageNotes\n *\n * {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}\n *\n * ### Multi-value example\n *\n * {@example core/di/ts/provider_spec.ts region='MultiProviderAspect'}\n *\n * @publicApi\n */\nexport interface ConstructorProvider extends ConstructorSansProvider {\n /**\n * An injection token. Typically an instance of `Type` or `InjectionToken`, but can be `any`.\n */\n provide: Type;\n\n /**\n * When true, injector returns an array of instances. This is useful to allow multiple\n * providers spread across many files to provide configuration information to a common token.\n */\n multi?: boolean;\n}\n\n/**\n * Configures the `Injector` to return a value of another `useExisting` token.\n *\n * @see {@link ExistingProvider}\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection).\n *\n * @publicApi\n */\nexport interface ExistingSansProvider {\n /**\n * Existing `token` to return. (Equivalent to `injector.get(useExisting)`)\n */\n useExisting: any;\n}\n\n/**\n * Configures the `Injector` to return a value of another `useExisting` token.\n *\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection).\n *\n * @usageNotes\n *\n * {@example core/di/ts/provider_spec.ts region='ExistingProvider'}\n *\n * ### Multi-value example\n *\n * {@example core/di/ts/provider_spec.ts region='MultiProviderAspect'}\n *\n * @publicApi\n */\nexport interface ExistingProvider extends ExistingSansProvider {\n /**\n * An injection token. Typically an instance of `Type` or `InjectionToken`, but can be `any`.\n */\n provide: any;\n\n /**\n * When true, injector returns an array of instances. This is useful to allow multiple\n * providers spread across many files to provide configuration information to a common token.\n */\n multi?: boolean;\n}\n\n/**\n * Configures the `Injector` to return a value by invoking a `useFactory` function.\n *\n * @see {@link FactoryProvider}\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection).\n *\n * @publicApi\n */\nexport interface FactorySansProvider {\n /**\n * A function to invoke to create a value for this `token`. The function is invoked with\n * resolved values of `token`s in the `deps` field.\n */\n useFactory: Function;\n\n /**\n * A list of `token`s to be resolved by the injector. The list of values is then\n * used as arguments to the `useFactory` function.\n */\n deps?: any[];\n}\n\n/**\n * Configures the `Injector` to return a value by invoking a `useFactory` function.\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection).\n *\n * @usageNotes\n *\n * {@example core/di/ts/provider_spec.ts region='FactoryProvider'}\n *\n * Dependencies can also be marked as optional:\n *\n * {@example core/di/ts/provider_spec.ts region='FactoryProviderOptionalDeps'}\n *\n * ### Multi-value example\n *\n * {@example core/di/ts/provider_spec.ts region='MultiProviderAspect'}\n *\n * @publicApi\n */\nexport interface FactoryProvider extends FactorySansProvider {\n /**\n * An injection token. (Typically an instance of `Type` or `InjectionToken`, but can be `any`).\n */\n provide: any;\n\n /**\n * When true, injector returns an array of instances. This is useful to allow multiple\n * providers spread across many files to provide configuration information to a common token.\n */\n multi?: boolean;\n}\n\n/**\n * Describes how an `Injector` should be configured as static (that is, without reflection).\n * A static provider provides tokens to an injector for various types of dependencies.\n *\n * @see {@link Injector.create()}\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection-providers).\n *\n * @publicApi\n */\nexport type StaticProvider =\n ValueProvider|ExistingProvider|StaticClassProvider|ConstructorProvider|FactoryProvider|any[];\n\n\n/**\n * Configures the `Injector` to return an instance of `Type` when `Type' is used as the token.\n *\n * Create an instance by invoking the `new` operator and supplying additional arguments.\n * This form is a short form of `TypeProvider`;\n *\n * For more details, see the [\"Dependency Injection Guide\"](guide/dependency-injection).\n *\n * @usageNotes\n *\n * {@example core/di/ts/provider_spec.ts region='TypeProvider'}\n *\n * @publicApi\n */\nexport interface TypeProvider extends Type {}\n\n/**\n * Configures the `Injector` to return a value by invoking a `useClass` function.\n * Base for `ClassProvider` decorator.\n *\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection).\n *\n * @publicApi\n */\nexport interface ClassSansProvider {\n /**\n * Class to instantiate for the `token`.\n */\n useClass: Type;\n}\n\n/**\n * Configures the `Injector` to return an instance of `useClass` for a token.\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection).\n *\n * @usageNotes\n *\n * {@example core/di/ts/provider_spec.ts region='ClassProvider'}\n *\n * Note that following two providers are not equal:\n *\n * {@example core/di/ts/provider_spec.ts region='ClassProviderDifference'}\n *\n * ### Multi-value example\n *\n * {@example core/di/ts/provider_spec.ts region='MultiProviderAspect'}\n *\n * @publicApi\n */\nexport interface ClassProvider extends ClassSansProvider {\n /**\n * An injection token. (Typically an instance of `Type` or `InjectionToken`, but can be `any`).\n */\n provide: any;\n\n /**\n * When true, injector returns an array of instances. This is useful to allow multiple\n * providers spread across many files to provide configuration information to a common token.\n */\n multi?: boolean;\n}\n\n/**\n * Describes how the `Injector` should be configured.\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection).\n *\n * @see {@link StaticProvider}\n *\n * @publicApi\n */\nexport type Provider = TypeProvider|ValueProvider|ClassProvider|ConstructorProvider|\n ExistingProvider|FactoryProvider|any[];\n\n/**\n * Encapsulated `Provider`s that are only accepted during creation of an `EnvironmentInjector` (e.g.\n * in an `NgModule`).\n *\n * Using this wrapper type prevents providers which are only designed to work in\n * application/environment injectors from being accidentally included in\n * `@Component.providers` and ending up in a component injector.\n *\n * This wrapper type prevents access to the `Provider`s inside.\n *\n * @see {@link makeEnvironmentProviders}\n * @see {@link importProvidersFrom}\n *\n * @publicApi\n */\nexport type EnvironmentProviders = {\n ɵbrand: 'EnvironmentProviders';\n};\n\nexport interface InternalEnvironmentProviders extends EnvironmentProviders {\n ɵproviders: (Provider|EnvironmentProviders)[];\n\n /**\n * If present, indicates that the `EnvironmentProviders` were derived from NgModule providers.\n *\n * This is used to produce clearer error messages.\n */\n ɵfromNgModule?: true;\n}\n\nexport function isEnvironmentProviders(\n value: Provider|EnvironmentProviders|\n InternalEnvironmentProviders): value is InternalEnvironmentProviders {\n return value && !!(value as InternalEnvironmentProviders).ɵproviders;\n}\n\n/**\n * Describes a function that is used to process provider lists (such as provider\n * overrides).\n */\nexport type ProcessProvidersFunction = (providers: Provider[]) => Provider[];\n\n\n/**\n * A wrapper around an NgModule that associates it with [providers](guide/glossary#provider\n * \"Definition\"). Usage without a generic type is deprecated.\n *\n * @see [Deprecations](guide/deprecations#modulewithproviders-type-without-a-generic)\n *\n * @publicApi\n */\nexport interface ModuleWithProviders {\n ngModule: Type;\n providers?: Array;\n}\n\n/**\n * Providers that were imported from NgModules via the `importProvidersFrom` function.\n *\n * These providers are meant for use in an application injector (or other environment injectors) and\n * should not be used in component injectors.\n *\n * This type cannot be directly implemented. It's returned from the `importProvidersFrom` function\n * and serves to prevent the extracted NgModule providers from being used in the wrong contexts.\n *\n * @see {@link importProvidersFrom}\n *\n * @publicApi\n * @deprecated replaced by `EnvironmentProviders`\n */\nexport type ImportedNgModuleProviders = EnvironmentProviders;\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Used for stringify render output in Ivy.\n * Important! This function is very performance-sensitive and we should\n * be extra careful not to introduce megamorphic reads in it.\n * Check `core/test/render3/perf/render_stringify` for benchmarks and alternate implementations.\n */\nexport function renderStringify(value: any): string {\n if (typeof value === 'string') return value;\n if (value == null) return '';\n // Use `String` so that it invokes the `toString` method of the value. Note that this\n // appears to be faster than calling `value.toString` (see `render_stringify` benchmark).\n return String(value);\n}\n\n\n/**\n * Used to stringify a value so that it can be displayed in an error message.\n * Important! This function contains a megamorphic read and should only be\n * used for error messages.\n */\nexport function stringifyForError(value: any): string {\n if (typeof value === 'function') return value.name || value.toString();\n if (typeof value === 'object' && value != null && typeof value.type === 'function') {\n return value.type.name || value.type.toString();\n }\n\n return renderStringify(value);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {isEnvironmentProviders} from '../di/interface/provider';\nimport {RuntimeError, RuntimeErrorCode} from '../errors';\nimport {Type} from '../interface/type';\nimport {stringify} from '../util/stringify';\n\nimport {stringifyForError} from './util/stringify_utils';\n\n\n/** Called when directives inject each other (creating a circular dependency) */\nexport function throwCyclicDependencyError(token: string, path?: string[]): never {\n const depPath = path ? `. Dependency path: ${path.join(' > ')} > ${token}` : '';\n throw new RuntimeError(\n RuntimeErrorCode.CYCLIC_DI_DEPENDENCY,\n `Circular dependency in DI detected for ${token}${depPath}`);\n}\n\nexport function throwMixedMultiProviderError() {\n throw new Error(`Cannot mix multi providers and regular providers`);\n}\n\nexport function throwInvalidProviderError(\n ngModuleType?: Type, providers?: any[], provider?: any): never {\n if (ngModuleType && providers) {\n const providerDetail = providers.map(v => v == provider ? '?' + provider + '?' : '...');\n throw new Error(`Invalid provider for the NgModule '${\n stringify(ngModuleType)}' - only instances of Provider and Type are allowed, got: [${\n providerDetail.join(', ')}]`);\n } else if (isEnvironmentProviders(provider)) {\n if (provider.ɵfromNgModule) {\n throw new RuntimeError(\n RuntimeErrorCode.PROVIDER_IN_WRONG_CONTEXT,\n `Invalid providers from 'importProvidersFrom' present in a non-environment injector. 'importProvidersFrom' can't be used for component providers.`);\n } else {\n throw new RuntimeError(\n RuntimeErrorCode.PROVIDER_IN_WRONG_CONTEXT,\n `Invalid providers present in a non-environment injector. 'EnvironmentProviders' can't be used for component providers.`);\n }\n } else {\n throw new Error('Invalid provider');\n }\n}\n\n\n/** Throws an error when a token is not found in DI. */\nexport function throwProviderNotFoundError(token: any, injectorName?: string): never {\n const injectorDetails = injectorName ? ` in ${injectorName}` : '';\n throw new RuntimeError(\n RuntimeErrorCode.PROVIDER_NOT_FOUND,\n ngDevMode && `No provider for ${stringifyForError(token)} found${injectorDetails}`);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\n/**\n * Special flag indicating that a decorator is of type `Inject`. It's used to make `Inject`\n * decorator tree-shakable (so we don't have to rely on the `instanceof` checks).\n * Note: this flag is not included into the `InjectFlags` since it's an internal-only API.\n */\nexport const enum DecoratorFlags {\n Inject = -1\n}\n\n/**\n * Injection flags for DI.\n *\n * @publicApi\n * @deprecated use an options object for [`inject`](api/core/inject) instead.\n */\nexport enum InjectFlags {\n // TODO(alxhub): make this 'const' (and remove `InternalInjectFlags` enum) when ngc no longer\n // writes exports of it into ngfactory files.\n\n /** Check self and check parent injector if needed */\n Default = 0b0000,\n\n /**\n * Specifies that an injector should retrieve a dependency from any injector until reaching the\n * host element of the current component. (Only used with Element Injector)\n */\n Host = 0b0001,\n\n /** Don't ascend to ancestors of the node requesting injection. */\n Self = 0b0010,\n\n /** Skip the node that is requesting injection. */\n SkipSelf = 0b0100,\n\n /** Inject `defaultValue` instead if token not found. */\n Optional = 0b1000,\n}\n\n/**\n * This enum is an exact copy of the `InjectFlags` enum above, but the difference is that this is a\n * const enum, so actual enum values would be inlined in generated code. The `InjectFlags` enum can\n * be turned into a const enum when ViewEngine is removed (see TODO at the `InjectFlags` enum\n * above). The benefit of inlining is that we can use these flags at the top level without affecting\n * tree-shaking (see \"no-toplevel-property-access\" tslint rule for more info).\n * Keep this enum in sync with `InjectFlags` enum above.\n */\nexport const enum InternalInjectFlags {\n /** Check self and check parent injector if needed */\n Default = 0b0000,\n\n /**\n * Specifies that an injector should retrieve a dependency from any injector until reaching the\n * host element of the current component. (Only used with Element Injector)\n */\n Host = 0b0001,\n\n /** Don't ascend to ancestors of the node requesting injection. */\n Self = 0b0010,\n\n /** Skip the node that is requesting injection. */\n SkipSelf = 0b0100,\n\n /** Inject `defaultValue` instead if token not found. */\n Optional = 0b1000,\n\n /**\n * This token is being injected into a pipe.\n *\n * This flag is intentionally not in the public facing `InjectFlags` because it is only added by\n * the compiler and is not a developer applicable flag.\n */\n ForPipe = 0b10000,\n}\n\n/**\n * Type of the options argument to [`inject`](api/core/inject).\n *\n * @publicApi\n */\nexport interface InjectOptions {\n /**\n * Use optional injection, and return `null` if the requested token is not found.\n */\n optional?: boolean;\n\n /**\n * Start injection at the parent of the current injector.\n */\n skipSelf?: boolean;\n\n /**\n * Only query the current injector for the token, and don't fall back to the parent injector if\n * it's not found.\n */\n self?: boolean;\n\n /**\n * Stop injection at the host component's injector. Only relevant when injecting from an element\n * injector, and a no-op for environment injectors.\n */\n host?: boolean;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {throwProviderNotFoundError} from '../render3/errors_di';\nimport {assertNotEqual} from '../util/assert';\nimport {stringify} from '../util/stringify';\n\nimport {getInjectableDef, ɵɵInjectableDeclaration} from './interface/defs';\nimport {InjectFlags} from './interface/injector';\nimport {ProviderToken} from './provider_token';\n\n\n/**\n * Current implementation of inject.\n *\n * By default, it is `injectInjectorOnly`, which makes it `Injector`-only aware. It can be changed\n * to `directiveInject`, which brings in the `NodeInjector` system of ivy. It is designed this\n * way for two reasons:\n * 1. `Injector` should not depend on ivy logic.\n * 2. To maintain tree shake-ability we don't want to bring in unnecessary code.\n */\nlet _injectImplementation: ((token: ProviderToken, flags?: InjectFlags) => T | null)|\n undefined;\nexport function getInjectImplementation() {\n return _injectImplementation;\n}\n\n\n/**\n * Sets the current inject implementation.\n */\nexport function setInjectImplementation(\n impl: ((token: ProviderToken, flags?: InjectFlags) => T | null)|\n undefined): ((token: ProviderToken, flags?: InjectFlags) => T | null)|undefined {\n const previous = _injectImplementation;\n _injectImplementation = impl;\n return previous;\n}\n\n\n/**\n * Injects `root` tokens in limp mode.\n *\n * If no injector exists, we can still inject tree-shakable providers which have `providedIn` set to\n * `\"root\"`. This is known as the limp mode injection. In such case the value is stored in the\n * injectable definition.\n */\nexport function injectRootLimpMode(\n token: ProviderToken, notFoundValue: T|undefined, flags: InjectFlags): T|null {\n const injectableDef: ɵɵInjectableDeclaration|null = getInjectableDef(token);\n if (injectableDef && injectableDef.providedIn == 'root') {\n return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() :\n injectableDef.value;\n }\n if (flags & InjectFlags.Optional) return null;\n if (notFoundValue !== undefined) return notFoundValue;\n throwProviderNotFoundError(stringify(token), 'Injector');\n}\n\n\n/**\n * Assert that `_injectImplementation` is not `fn`.\n *\n * This is useful, to prevent infinite recursion.\n *\n * @param fn Function which it should not equal to\n */\nexport function assertInjectImplementationNotEqual(\n fn: ((token: ProviderToken, flags?: InjectFlags) => T | null)) {\n ngDevMode &&\n assertNotEqual(_injectImplementation, fn, 'Calling ɵɵinject would cause infinite recursion');\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport '../util/ng_dev_mode';\n\nimport {RuntimeError, RuntimeErrorCode} from '../errors';\nimport {Type} from '../interface/type';\nimport {emitInjectEvent} from '../render3/debug/injector_profiler';\nimport {stringify} from '../util/stringify';\n\nimport {resolveForwardRef} from './forward_ref';\nimport {getInjectImplementation, injectRootLimpMode} from './inject_switch';\nimport {Injector} from './injector';\nimport {DecoratorFlags, InjectFlags, InjectOptions, InternalInjectFlags} from './interface/injector';\nimport {ProviderToken} from './provider_token';\n\n\nconst _THROW_IF_NOT_FOUND = {};\nexport const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;\n\n/*\n * Name of a property (that we patch onto DI decorator), which is used as an annotation of which\n * InjectFlag this decorator represents. This allows to avoid direct references to the DI decorators\n * in the code, thus making them tree-shakable.\n */\nconst DI_DECORATOR_FLAG = '__NG_DI_FLAG__';\n\nexport const NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';\nconst NG_TOKEN_PATH = 'ngTokenPath';\nconst NEW_LINE = /\\n/gm;\nconst NO_NEW_LINE = 'ɵ';\nexport const SOURCE = '__source';\n\n/**\n * Current injector value used by `inject`.\n * - `undefined`: it is an error to call `inject`\n * - `null`: `inject` can be called but there is no injector (limp-mode).\n * - Injector instance: Use the injector for resolution.\n */\nlet _currentInjector: Injector|undefined|null = undefined;\n\nexport function getCurrentInjector(): Injector|undefined|null {\n return _currentInjector;\n}\n\nexport function setCurrentInjector(injector: Injector|null|undefined): Injector|undefined|null {\n const former = _currentInjector;\n _currentInjector = injector;\n return former;\n}\n\nexport function injectInjectorOnly(token: ProviderToken): T;\nexport function injectInjectorOnly(token: ProviderToken, flags?: InjectFlags): T|null;\nexport function injectInjectorOnly(token: ProviderToken, flags = InjectFlags.Default): T|\n null {\n if (_currentInjector === undefined) {\n throw new RuntimeError(\n RuntimeErrorCode.MISSING_INJECTION_CONTEXT,\n ngDevMode &&\n `inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with \\`runInInjectionContext\\`.`);\n } else if (_currentInjector === null) {\n return injectRootLimpMode(token, undefined, flags);\n } else {\n const value =\n _currentInjector.get(token, flags & InjectFlags.Optional ? null : undefined, flags);\n ngDevMode && emitInjectEvent(token as Type, value, flags);\n return value;\n }\n}\n\n/**\n * Generated instruction: injects a token from the currently active injector.\n *\n * (Additional documentation moved to `inject`, as it is the public API, and an alias for this\n * instruction)\n *\n * @see inject\n * @codeGenApi\n * @publicApi This instruction has been emitted by ViewEngine for some time and is deployed to npm.\n */\nexport function ɵɵinject(token: ProviderToken): T;\nexport function ɵɵinject(token: ProviderToken, flags?: InjectFlags): T|null;\nexport function ɵɵinject(token: ProviderToken, flags = InjectFlags.Default): T|null {\n return (getInjectImplementation() || injectInjectorOnly)(resolveForwardRef(token), flags);\n}\n\n/**\n * Throws an error indicating that a factory function could not be generated by the compiler for a\n * particular class.\n *\n * The name of the class is not mentioned here, but will be in the generated factory function name\n * and thus in the stack trace.\n *\n * @codeGenApi\n */\nexport function ɵɵinvalidFactoryDep(index: number): never {\n throw new RuntimeError(\n RuntimeErrorCode.INVALID_FACTORY_DEPENDENCY,\n ngDevMode &&\n `This constructor is not compatible with Angular Dependency Injection because its dependency at index ${\n index} of the parameter list is invalid.\nThis can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.\n\nPlease check that 1) the type for the parameter at index ${\n index} is correct and 2) the correct Angular decorators are defined for this class and its ancestors.`);\n}\n\n/**\n * @param token A token that represents a dependency that should be injected.\n * @returns the injected value if operation is successful, `null` otherwise.\n * @throws if called outside of a supported context.\n *\n * @publicApi\n */\nexport function inject(token: ProviderToken): T;\n/**\n * @param token A token that represents a dependency that should be injected.\n * @param flags Control how injection is executed. The flags correspond to injection strategies that\n * can be specified with parameter decorators `@Host`, `@Self`, `@SkipSelf`, and `@Optional`.\n * @returns the injected value if operation is successful, `null` otherwise.\n * @throws if called outside of a supported context.\n *\n * @publicApi\n * @deprecated prefer an options object instead of `InjectFlags`\n */\nexport function inject(token: ProviderToken, flags?: InjectFlags): T|null;\n/**\n * @param token A token that represents a dependency that should be injected.\n * @param options Control how injection is executed. Options correspond to injection strategies\n * that can be specified with parameter decorators `@Host`, `@Self`, `@SkipSelf`, and\n * `@Optional`.\n * @returns the injected value if operation is successful.\n * @throws if called outside of a supported context, or if the token is not found.\n *\n * @publicApi\n */\nexport function inject(token: ProviderToken, options: InjectOptions&{optional?: false}): T;\n/**\n * @param token A token that represents a dependency that should be injected.\n * @param options Control how injection is executed. Options correspond to injection strategies\n * that can be specified with parameter decorators `@Host`, `@Self`, `@SkipSelf`, and\n * `@Optional`.\n * @returns the injected value if operation is successful, `null` if the token is not\n * found and optional injection has been requested.\n * @throws if called outside of a supported context, or if the token is not found and optional\n * injection was not requested.\n *\n * @publicApi\n */\nexport function inject(token: ProviderToken, options: InjectOptions): T|null;\n/**\n * Injects a token from the currently active injector.\n * `inject` is only supported in an [injection context](/guide/dependency-injection-context). It can\n * be used during:\n * - Construction (via the `constructor`) of a class being instantiated by the DI system, such\n * as an `@Injectable` or `@Component`.\n * - In the initializer for fields of such classes.\n * - In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.\n * - In the `factory` function specified for an `InjectionToken`.\n * - In a stackframe of a function call in a DI context\n *\n * @param token A token that represents a dependency that should be injected.\n * @param flags Optional flags that control how injection is executed.\n * The flags correspond to injection strategies that can be specified with\n * parameter decorators `@Host`, `@Self`, `@SkipSelf`, and `@Optional`.\n * @returns the injected value if operation is successful, `null` otherwise.\n * @throws if called outside of a supported context.\n *\n * @usageNotes\n * In practice the `inject()` calls are allowed in a constructor, a constructor parameter and a\n * field initializer:\n *\n * ```typescript\n * @Injectable({providedIn: 'root'})\n * export class Car {\n * radio: Radio|undefined;\n * // OK: field initializer\n * spareTyre = inject(Tyre);\n *\n * constructor() {\n * // OK: constructor body\n * this.radio = inject(Radio);\n * }\n * }\n * ```\n *\n * It is also legal to call `inject` from a provider's factory:\n *\n * ```typescript\n * providers: [\n * {provide: Car, useFactory: () => {\n * // OK: a class factory\n * const engine = inject(Engine);\n * return new Car(engine);\n * }}\n * ]\n * ```\n *\n * Calls to the `inject()` function outside of the class creation context will result in error. Most\n * notably, calls to `inject()` are disallowed after a class instance was created, in methods\n * (including lifecycle hooks):\n *\n * ```typescript\n * @Component({ ... })\n * export class CarComponent {\n * ngOnInit() {\n * // ERROR: too late, the component instance was already created\n * const engine = inject(Engine);\n * engine.start();\n * }\n * }\n * ```\n *\n * @publicApi\n */\nexport function inject(\n token: ProviderToken, flags: InjectFlags|InjectOptions = InjectFlags.Default): T|null {\n return ɵɵinject(token, convertToBitFlags(flags));\n}\n\n// Converts object-based DI flags (`InjectOptions`) to bit flags (`InjectFlags`).\nexport function convertToBitFlags(flags: InjectOptions|InjectFlags|undefined): InjectFlags|\n undefined {\n if (typeof flags === 'undefined' || typeof flags === 'number') {\n return flags;\n }\n\n // While TypeScript doesn't accept it without a cast, bitwise OR with false-y values in\n // JavaScript is a no-op. We can use that for a very codesize-efficient conversion from\n // `InjectOptions` to `InjectFlags`.\n return (InternalInjectFlags.Default | // comment to force a line break in the formatter\n ((flags.optional && InternalInjectFlags.Optional) as number) |\n ((flags.host && InternalInjectFlags.Host) as number) |\n ((flags.self && InternalInjectFlags.Self) as number) |\n ((flags.skipSelf && InternalInjectFlags.SkipSelf) as number)) as InjectFlags;\n}\n\nexport function injectArgs(types: (ProviderToken|any[])[]): any[] {\n const args: any[] = [];\n for (let i = 0; i < types.length; i++) {\n const arg = resolveForwardRef(types[i]);\n if (Array.isArray(arg)) {\n if (arg.length === 0) {\n throw new RuntimeError(\n RuntimeErrorCode.INVALID_DIFFER_INPUT,\n ngDevMode && 'Arguments array must have arguments.');\n }\n let type: Type|undefined = undefined;\n let flags: InjectFlags = InjectFlags.Default;\n\n for (let j = 0; j < arg.length; j++) {\n const meta = arg[j];\n const flag = getInjectFlag(meta);\n if (typeof flag === 'number') {\n // Special case when we handle @Inject decorator.\n if (flag === DecoratorFlags.Inject) {\n type = meta.token;\n } else {\n flags |= flag;\n }\n } else {\n type = meta;\n }\n }\n\n args.push(ɵɵinject(type!, flags));\n } else {\n args.push(ɵɵinject(arg));\n }\n }\n return args;\n}\n\n/**\n * Attaches a given InjectFlag to a given decorator using monkey-patching.\n * Since DI decorators can be used in providers `deps` array (when provider is configured using\n * `useFactory`) without initialization (e.g. `Host`) and as an instance (e.g. `new Host()`), we\n * attach the flag to make it available both as a static property and as a field on decorator\n * instance.\n *\n * @param decorator Provided DI decorator.\n * @param flag InjectFlag that should be applied.\n */\nexport function attachInjectFlag(decorator: any, flag: InternalInjectFlags|DecoratorFlags): any {\n decorator[DI_DECORATOR_FLAG] = flag;\n decorator.prototype[DI_DECORATOR_FLAG] = flag;\n return decorator;\n}\n\n/**\n * Reads monkey-patched property that contains InjectFlag attached to a decorator.\n *\n * @param token Token that may contain monkey-patched DI flags property.\n */\nexport function getInjectFlag(token: any): number|undefined {\n return token[DI_DECORATOR_FLAG];\n}\n\nexport function catchInjectorError(\n e: any, token: any, injectorErrorName: string, source: string|null): never {\n const tokenPath: any[] = e[NG_TEMP_TOKEN_PATH];\n if (token[SOURCE]) {\n tokenPath.unshift(token[SOURCE]);\n }\n e.message = formatError('\\n' + e.message, tokenPath, injectorErrorName, source);\n e[NG_TOKEN_PATH] = tokenPath;\n e[NG_TEMP_TOKEN_PATH] = null;\n throw e;\n}\n\nexport function formatError(\n text: string, obj: any, injectorErrorName: string, source: string|null = null): string {\n text = text && text.charAt(0) === '\\n' && text.charAt(1) == NO_NEW_LINE ? text.slice(2) : text;\n let context = stringify(obj);\n if (Array.isArray(obj)) {\n context = obj.map(stringify).join(' -> ');\n } else if (typeof obj === 'object') {\n let parts = [];\n for (let key in obj) {\n if (obj.hasOwnProperty(key)) {\n let value = obj[key];\n parts.push(\n key + ':' + (typeof value === 'string' ? JSON.stringify(value) : stringify(value)));\n }\n }\n context = `{${parts.join(', ')}}`;\n }\n return `${injectorErrorName}${source ? '(' + source + ')' : ''}[${context}]: ${\n text.replace(NEW_LINE, '\\n ')}`;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {makeParamDecorator} from '../util/decorators';\n\nimport {attachInjectFlag} from './injector_compatibility';\nimport {DecoratorFlags, InternalInjectFlags} from './interface/injector';\n\n\n/**\n * Type of the Inject decorator / constructor function.\n *\n * @publicApi\n */\nexport interface InjectDecorator {\n /**\n * Parameter decorator on a dependency parameter of a class constructor\n * that specifies a custom provider of the dependency.\n *\n * @usageNotes\n * The following example shows a class constructor that specifies a\n * custom provider of a dependency using the parameter decorator.\n *\n * When `@Inject()` is not present, the injector uses the type annotation of the\n * parameter as the provider.\n *\n * \n * \n *\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection)\n *\n */\n (token: any): any;\n new(token: any): Inject;\n}\n\n/**\n * Type of the Inject metadata.\n *\n * @publicApi\n */\nexport interface Inject {\n /**\n * A [DI token](guide/glossary#di-token) that maps to the dependency to be injected.\n */\n token: any;\n}\n\n/**\n * Inject decorator and metadata.\n *\n * @Annotation\n * @publicApi\n */\nexport const Inject: InjectDecorator = attachInjectFlag(\n // Disable tslint because `DecoratorFlags` is a const enum which gets inlined.\n // tslint:disable-next-line: no-toplevel-property-access\n makeParamDecorator('Inject', (token: any) => ({token})), DecoratorFlags.Inject);\n\n/**\n * Type of the Optional decorator / constructor function.\n *\n * @publicApi\n */\nexport interface OptionalDecorator {\n /**\n * Parameter decorator to be used on constructor parameters,\n * which marks the parameter as being an optional dependency.\n * The DI framework provides `null` if the dependency is not found.\n *\n * Can be used together with other parameter decorators\n * that modify how dependency injection operates.\n *\n * @usageNotes\n *\n * The following code allows the possibility of a `null` result:\n *\n * \n * \n *\n * @see [\"Dependency Injection Guide\"](guide/dependency-injection).\n */\n (): any;\n new(): Optional;\n}\n\n/**\n * Type of the Optional metadata.\n *\n * @publicApi\n */\nexport interface Optional {}\n\n/**\n * Optional decorator and metadata.\n *\n * @Annotation\n * @publicApi\n */\nexport const Optional: OptionalDecorator =\n // Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.\n // tslint:disable-next-line: no-toplevel-property-access\n attachInjectFlag(makeParamDecorator('Optional'), InternalInjectFlags.Optional);\n\n/**\n * Type of the Self decorator / constructor function.\n *\n * @publicApi\n */\nexport interface SelfDecorator {\n /**\n * Parameter decorator to be used on constructor parameters,\n * which tells the DI framework to start dependency resolution from the local injector.\n *\n * Resolution works upward through the injector hierarchy, so the children\n * of this class must configure their own providers or be prepared for a `null` result.\n *\n * @usageNotes\n *\n * In the following example, the dependency can be resolved\n * by the local injector when instantiating the class itself, but not\n * when instantiating a child.\n *\n * \n * \n *\n * @see {@link SkipSelf}\n * @see {@link Optional}\n *\n */\n (): any;\n new(): Self;\n}\n\n/**\n * Type of the Self metadata.\n *\n * @publicApi\n */\nexport interface Self {}\n\n/**\n * Self decorator and metadata.\n *\n * @Annotation\n * @publicApi\n */\nexport const Self: SelfDecorator =\n // Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.\n // tslint:disable-next-line: no-toplevel-property-access\n attachInjectFlag(makeParamDecorator('Self'), InternalInjectFlags.Self);\n\n\n/**\n * Type of the `SkipSelf` decorator / constructor function.\n *\n * @publicApi\n */\nexport interface SkipSelfDecorator {\n /**\n * Parameter decorator to be used on constructor parameters,\n * which tells the DI framework to start dependency resolution from the parent injector.\n * Resolution works upward through the injector hierarchy, so the local injector\n * is not checked for a provider.\n *\n * @usageNotes\n *\n * In the following example, the dependency can be resolved when\n * instantiating a child, but not when instantiating the class itself.\n *\n * \n * \n *\n * @see [Dependency Injection guide](guide/dependency-injection-in-action#skip).\n * @see {@link Self}\n * @see {@link Optional}\n *\n */\n (): any;\n new(): SkipSelf;\n}\n\n/**\n * Type of the `SkipSelf` metadata.\n *\n * @publicApi\n */\nexport interface SkipSelf {}\n\n/**\n * `SkipSelf` decorator and metadata.\n *\n * @Annotation\n * @publicApi\n */\nexport const SkipSelf: SkipSelfDecorator =\n // Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.\n // tslint:disable-next-line: no-toplevel-property-access\n attachInjectFlag(makeParamDecorator('SkipSelf'), InternalInjectFlags.SkipSelf);\n\n/**\n * Type of the `Host` decorator / constructor function.\n *\n * @publicApi\n */\nexport interface HostDecorator {\n /**\n * Parameter decorator on a view-provider parameter of a class constructor\n * that tells the DI framework to resolve the view by checking injectors of child\n * elements, and stop when reaching the host element of the current component.\n *\n * @usageNotes\n *\n * The following shows use with the `@Optional` decorator, and allows for a `null` result.\n *\n * \n * \n *\n * For an extended example, see [\"Dependency Injection\n * Guide\"](guide/dependency-injection-in-action#optional).\n */\n (): any;\n new(): Host;\n}\n\n/**\n * Type of the Host metadata.\n *\n * @publicApi\n */\nexport interface Host {}\n\n/**\n * Host decorator and metadata.\n *\n * @Annotation\n * @publicApi\n */\nexport const Host: HostDecorator =\n // Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.\n // tslint:disable-next-line: no-toplevel-property-access\n attachInjectFlag(makeParamDecorator('Host'), InternalInjectFlags.Host);\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\n/**\n * The strategy that the default change detector uses to detect changes.\n * When set, takes effect the next time change detection is triggered.\n *\n * @see {@link ChangeDetectorRef#usage-notes Change detection usage}\n *\n * @publicApi\n */\nexport enum ChangeDetectionStrategy {\n /**\n * Use the `CheckOnce` strategy, meaning that automatic change detection is deactivated\n * until reactivated by setting the strategy to `Default` (`CheckAlways`).\n * Change detection can still be explicitly invoked.\n * This strategy applies to all child directives and cannot be overridden.\n */\n OnPush = 0,\n\n /**\n * Use the default `CheckAlways` strategy, in which change detection is automatic until\n * explicitly deactivated.\n */\n Default = 1,\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Defines the CSS styles encapsulation policies for the {@link Component} decorator's\n * `encapsulation` option.\n *\n * See {@link Component#encapsulation encapsulation}.\n *\n * @usageNotes\n * ### Example\n *\n * {@example core/ts/metadata/encapsulation.ts region='longform'}\n *\n * @publicApi\n */\nexport enum ViewEncapsulation {\n // TODO: consider making `ViewEncapsulation` a `const enum` instead. See\n // https://github.com/angular/angular/issues/44119 for additional information.\n\n /**\n * Emulates a native Shadow DOM encapsulation behavior by adding a specific attribute to the\n * component's host element and applying the same attribute to all the CSS selectors provided\n * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls}.\n *\n * This is the default option.\n */\n Emulated = 0,\n\n // Historically the 1 value was for `Native` encapsulation which has been removed as of v11.\n\n /**\n * Doesn't provide any sort of CSS style encapsulation, meaning that all the styles provided\n * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls} are applicable\n * to any HTML element of the application regardless of their host Component.\n */\n None = 2,\n\n /**\n * Uses the browser's native Shadow DOM API to encapsulate CSS styles, meaning that it creates\n * a ShadowRoot for the component's host element which is then used to encapsulate\n * all the Component's styling.\n */\n ShadowDom = 3\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport {initNgDevMode} from './ng_dev_mode';\n\n/**\n * This file contains reuseable \"empty\" symbols that can be used as default return values\n * in different parts of the rendering code. Because the same symbols are returned, this\n * allows for identity checks against these values to be consistently used by the framework\n * code.\n */\n\nexport const EMPTY_OBJ: {} = {};\nexport const EMPTY_ARRAY: any[] = [];\n\n// freezing the values prevents any code from accidentally inserting new values in\nif ((typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode()) {\n // These property accesses can be ignored because ngDevMode will be set to false\n // when optimizing code and the whole if statement will be dropped.\n // tslint:disable-next-line:no-toplevel-property-access\n Object.freeze(EMPTY_OBJ);\n // tslint:disable-next-line:no-toplevel-property-access\n Object.freeze(EMPTY_ARRAY);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {getClosureSafeProperty} from '../util/property';\n\nexport const NG_COMP_DEF = getClosureSafeProperty({ɵcmp: getClosureSafeProperty});\nexport const NG_DIR_DEF = getClosureSafeProperty({ɵdir: getClosureSafeProperty});\nexport const NG_PIPE_DEF = getClosureSafeProperty({ɵpipe: getClosureSafeProperty});\nexport const NG_MOD_DEF = getClosureSafeProperty({ɵmod: getClosureSafeProperty});\nexport const NG_FACTORY_DEF = getClosureSafeProperty({ɵfac: getClosureSafeProperty});\n\n/**\n * If a directive is diPublic, bloomAdd sets a property on the type with this constant as\n * the key and the directive's unique ID as the value. This allows us to map directives to their\n * bloom filter bit for DI.\n */\n// TODO(misko): This is wrong. The NG_ELEMENT_ID should never be minified.\nexport const NG_ELEMENT_ID = getClosureSafeProperty({__NG_ELEMENT_ID__: getClosureSafeProperty});\n\n/**\n * The `NG_ENV_ID` field on a DI token indicates special processing in the `EnvironmentInjector`:\n * getting such tokens from the `EnvironmentInjector` will bypass the standard DI resolution\n * strategy and instead will return implementation produced by the `NG_ENV_ID` factory function.\n *\n * This particular retrieval of DI tokens is mostly done to eliminate circular dependencies and\n * improve tree-shaking.\n */\nexport const NG_ENV_ID = getClosureSafeProperty({__NG_ENV_ID__: getClosureSafeProperty});\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertNotEqual} from '../../util/assert';\nimport {CharCode} from '../../util/char_code';\n\n\n/**\n * Returns an index of `classToSearch` in `className` taking token boundaries into account.\n *\n * `classIndexOf('AB A', 'A', 0)` will be 3 (not 0 since `AB!==A`)\n *\n * @param className A string containing classes (whitespace separated)\n * @param classToSearch A class name to locate\n * @param startingIndex Starting location of search\n * @returns an index of the located class (or -1 if not found)\n */\nexport function classIndexOf(\n className: string, classToSearch: string, startingIndex: number): number {\n ngDevMode && assertNotEqual(classToSearch, '', 'can not look for \"\" string.');\n let end = className.length;\n while (true) {\n const foundIndex = className.indexOf(classToSearch, startingIndex);\n if (foundIndex === -1) return foundIndex;\n if (foundIndex === 0 || className.charCodeAt(foundIndex - 1) <= CharCode.SPACE) {\n // Ensure that it has leading whitespace\n const length = classToSearch.length;\n if (foundIndex + length === end ||\n className.charCodeAt(foundIndex + length) <= CharCode.SPACE) {\n // Ensure that it has trailing whitespace\n return foundIndex;\n }\n }\n // False positive, keep searching from where we left off.\n startingIndex = foundIndex + 1;\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport {CharCode} from '../../util/char_code';\nimport {AttributeMarker, TAttributes} from '../interfaces/node';\nimport {CssSelector} from '../interfaces/projection';\nimport {Renderer} from '../interfaces/renderer';\nimport {RElement} from '../interfaces/renderer_dom';\n\n\n\n/**\n * Assigns all attribute values to the provided element via the inferred renderer.\n *\n * This function accepts two forms of attribute entries:\n *\n * default: (key, value):\n * attrs = [key1, value1, key2, value2]\n *\n * namespaced: (NAMESPACE_MARKER, uri, name, value)\n * attrs = [NAMESPACE_MARKER, uri, name, value, NAMESPACE_MARKER, uri, name, value]\n *\n * The `attrs` array can contain a mix of both the default and namespaced entries.\n * The \"default\" values are set without a marker, but if the function comes across\n * a marker value then it will attempt to set a namespaced value. If the marker is\n * not of a namespaced value then the function will quit and return the index value\n * where it stopped during the iteration of the attrs array.\n *\n * See [AttributeMarker] to understand what the namespace marker value is.\n *\n * Note that this instruction does not support assigning style and class values to\n * an element. See `elementStart` and `elementHostAttrs` to learn how styling values\n * are applied to an element.\n * @param renderer The renderer to be used\n * @param native The element that the attributes will be assigned to\n * @param attrs The attribute array of values that will be assigned to the element\n * @returns the index value that was last accessed in the attributes array\n */\nexport function setUpAttributes(renderer: Renderer, native: RElement, attrs: TAttributes): number {\n let i = 0;\n while (i < attrs.length) {\n const value = attrs[i];\n if (typeof value === 'number') {\n // only namespaces are supported. Other value types (such as style/class\n // entries) are not supported in this function.\n if (value !== AttributeMarker.NamespaceURI) {\n break;\n }\n\n // we just landed on the marker value ... therefore\n // we should skip to the next entry\n i++;\n\n const namespaceURI = attrs[i++] as string;\n const attrName = attrs[i++] as string;\n const attrVal = attrs[i++] as string;\n ngDevMode && ngDevMode.rendererSetAttribute++;\n renderer.setAttribute(native, attrName, attrVal, namespaceURI);\n } else {\n // attrName is string;\n const attrName = value as string;\n const attrVal = attrs[++i];\n // Standard attributes\n ngDevMode && ngDevMode.rendererSetAttribute++;\n if (isAnimationProp(attrName)) {\n renderer.setProperty(native, attrName, attrVal);\n } else {\n renderer.setAttribute(native, attrName, attrVal as string);\n }\n i++;\n }\n }\n\n // another piece of code may iterate over the same attributes array. Therefore\n // it may be helpful to return the exact spot where the attributes array exited\n // whether by running into an unsupported marker or if all the static values were\n // iterated over.\n return i;\n}\n\n/**\n * Test whether the given value is a marker that indicates that the following\n * attribute values in a `TAttributes` array are only the names of attributes,\n * and not name-value pairs.\n * @param marker The attribute marker to test.\n * @returns true if the marker is a \"name-only\" marker (e.g. `Bindings`, `Template` or `I18n`).\n */\nexport function isNameOnlyAttributeMarker(marker: string|AttributeMarker|CssSelector) {\n return marker === AttributeMarker.Bindings || marker === AttributeMarker.Template ||\n marker === AttributeMarker.I18n;\n}\n\nexport function isAnimationProp(name: string): boolean {\n // Perf note: accessing charCodeAt to check for the first character of a string is faster as\n // compared to accessing a character at index 0 (ex. name[0]). The main reason for this is that\n // charCodeAt doesn't allocate memory to return a substring.\n return name.charCodeAt(0) === CharCode.AT_SIGN;\n}\n\n/**\n * Merges `src` `TAttributes` into `dst` `TAttributes` removing any duplicates in the process.\n *\n * This merge function keeps the order of attrs same.\n *\n * @param dst Location of where the merged `TAttributes` should end up.\n * @param src `TAttributes` which should be appended to `dst`\n */\nexport function mergeHostAttrs(dst: TAttributes|null, src: TAttributes|null): TAttributes|null {\n if (src === null || src.length === 0) {\n // do nothing\n } else if (dst === null || dst.length === 0) {\n // We have source, but dst is empty, just make a copy.\n dst = src.slice();\n } else {\n let srcMarker: AttributeMarker = AttributeMarker.ImplicitAttributes;\n for (let i = 0; i < src.length; i++) {\n const item = src[i];\n if (typeof item === 'number') {\n srcMarker = item;\n } else {\n if (srcMarker === AttributeMarker.NamespaceURI) {\n // Case where we need to consume `key1`, `key2`, `value` items.\n } else if (\n srcMarker === AttributeMarker.ImplicitAttributes ||\n srcMarker === AttributeMarker.Styles) {\n // Case where we have to consume `key1` and `value` only.\n mergeHostAttribute(dst, srcMarker, item as string, null, src[++i] as string);\n } else {\n // Case where we have to consume `key1` only.\n mergeHostAttribute(dst, srcMarker, item as string, null, null);\n }\n }\n }\n }\n return dst;\n}\n\n/**\n * Append `key`/`value` to existing `TAttributes` taking region marker and duplicates into account.\n *\n * @param dst `TAttributes` to append to.\n * @param marker Region where the `key`/`value` should be added.\n * @param key1 Key to add to `TAttributes`\n * @param key2 Key to add to `TAttributes` (in case of `AttributeMarker.NamespaceURI`)\n * @param value Value to add or to overwrite to `TAttributes` Only used if `marker` is not Class.\n */\nexport function mergeHostAttribute(\n dst: TAttributes, marker: AttributeMarker, key1: string, key2: string|null,\n value: string|null): void {\n let i = 0;\n // Assume that new markers will be inserted at the end.\n let markerInsertPosition = dst.length;\n // scan until correct type.\n if (marker === AttributeMarker.ImplicitAttributes) {\n markerInsertPosition = -1;\n } else {\n while (i < dst.length) {\n const dstValue = dst[i++];\n if (typeof dstValue === 'number') {\n if (dstValue === marker) {\n markerInsertPosition = -1;\n break;\n } else if (dstValue > marker) {\n // We need to save this as we want the markers to be inserted in specific order.\n markerInsertPosition = i - 1;\n break;\n }\n }\n }\n }\n\n // search until you find place of insertion\n while (i < dst.length) {\n const item = dst[i];\n if (typeof item === 'number') {\n // since `i` started as the index after the marker, we did not find it if we are at the next\n // marker\n break;\n } else if (item === key1) {\n // We already have same token\n if (key2 === null) {\n if (value !== null) {\n dst[i + 1] = value;\n }\n return;\n } else if (key2 === dst[i + 1]) {\n dst[i + 2] = value!;\n return;\n }\n }\n // Increment counter.\n i++;\n if (key2 !== null) i++;\n if (value !== null) i++;\n }\n\n // insert at location.\n if (markerInsertPosition !== -1) {\n dst.splice(markerInsertPosition, 0, marker);\n i = markerInsertPosition + 1;\n }\n dst.splice(i++, 0, key1);\n if (key2 !== null) {\n dst.splice(i++, 0, key2);\n }\n if (value !== null) {\n dst.splice(i++, 0, value);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport '../util/ng_dev_mode';\n\nimport {assertDefined, assertEqual, assertNotEqual} from '../util/assert';\n\nimport {AttributeMarker, TAttributes, TNode, TNodeType} from './interfaces/node';\nimport {CssSelector, CssSelectorList, SelectorFlags} from './interfaces/projection';\nimport {classIndexOf} from './styling/class_differ';\nimport {isNameOnlyAttributeMarker} from './util/attrs_utils';\n\nconst NG_TEMPLATE_SELECTOR = 'ng-template';\n\n/**\n * Search the `TAttributes` to see if it contains `cssClassToMatch` (case insensitive)\n *\n * @param attrs `TAttributes` to search through.\n * @param cssClassToMatch class to match (lowercase)\n * @param isProjectionMode Whether or not class matching should look into the attribute `class` in\n * addition to the `AttributeMarker.Classes`.\n */\nfunction isCssClassMatching(\n attrs: TAttributes, cssClassToMatch: string, isProjectionMode: boolean): boolean {\n // TODO(misko): The fact that this function needs to know about `isProjectionMode` seems suspect.\n // It is strange to me that sometimes the class information comes in form of `class` attribute\n // and sometimes in form of `AttributeMarker.Classes`. Some investigation is needed to determine\n // if that is the right behavior.\n ngDevMode &&\n assertEqual(\n cssClassToMatch, cssClassToMatch.toLowerCase(), 'Class name expected to be lowercase.');\n let i = 0;\n // Indicates whether we are processing value from the implicit\n // attribute section (i.e. before the first marker in the array).\n let isImplicitAttrsSection = true;\n while (i < attrs.length) {\n let item = attrs[i++];\n if (typeof item === 'string' && isImplicitAttrsSection) {\n const value = attrs[i++] as string;\n if (isProjectionMode && item === 'class') {\n // We found a `class` attribute in the implicit attribute section,\n // check if it matches the value of the `cssClassToMatch` argument.\n if (classIndexOf(value.toLowerCase(), cssClassToMatch, 0) !== -1) {\n return true;\n }\n }\n } else if (item === AttributeMarker.Classes) {\n // We found the classes section. Start searching for the class.\n while (i < attrs.length && typeof (item = attrs[i++]) == 'string') {\n // while we have strings\n if (item.toLowerCase() === cssClassToMatch) return true;\n }\n return false;\n } else if (typeof item === 'number') {\n // We've came across a first marker, which indicates\n // that the implicit attribute section is over.\n isImplicitAttrsSection = false;\n }\n }\n return false;\n}\n\n/**\n * Checks whether the `tNode` represents an inline template (e.g. `*ngFor`).\n *\n * @param tNode current TNode\n */\nexport function isInlineTemplate(tNode: TNode): boolean {\n return tNode.type === TNodeType.Container && tNode.value !== NG_TEMPLATE_SELECTOR;\n}\n\n/**\n * Function that checks whether a given tNode matches tag-based selector and has a valid type.\n *\n * Matching can be performed in 2 modes: projection mode (when we project nodes) and regular\n * directive matching mode:\n * - in the \"directive matching\" mode we do _not_ take TContainer's tagName into account if it is\n * different from NG_TEMPLATE_SELECTOR (value different from NG_TEMPLATE_SELECTOR indicates that a\n * tag name was extracted from * syntax so we would match the same directive twice);\n * - in the \"projection\" mode, we use a tag name potentially extracted from the * syntax processing\n * (applicable to TNodeType.Container only).\n */\nfunction hasTagAndTypeMatch(\n tNode: TNode, currentSelector: string, isProjectionMode: boolean): boolean {\n const tagNameToCompare =\n tNode.type === TNodeType.Container && !isProjectionMode ? NG_TEMPLATE_SELECTOR : tNode.value;\n return currentSelector === tagNameToCompare;\n}\n\n/**\n * A utility function to match an Ivy node static data against a simple CSS selector\n *\n * @param node static data of the node to match\n * @param selector The selector to try matching against the node.\n * @param isProjectionMode if `true` we are matching for content projection, otherwise we are doing\n * directive matching.\n * @returns true if node matches the selector.\n */\nexport function isNodeMatchingSelector(\n tNode: TNode, selector: CssSelector, isProjectionMode: boolean): boolean {\n ngDevMode && assertDefined(selector[0], 'Selector should have a tag name');\n let mode: SelectorFlags = SelectorFlags.ELEMENT;\n const nodeAttrs = tNode.attrs || [];\n\n // Find the index of first attribute that has no value, only a name.\n const nameOnlyMarkerIdx = getNameOnlyMarkerIndex(nodeAttrs);\n\n // When processing \":not\" selectors, we skip to the next \":not\" if the\n // current one doesn't match\n let skipToNextSelector = false;\n\n for (let i = 0; i < selector.length; i++) {\n const current = selector[i];\n if (typeof current === 'number') {\n // If we finish processing a :not selector and it hasn't failed, return false\n if (!skipToNextSelector && !isPositive(mode) && !isPositive(current)) {\n return false;\n }\n // If we are skipping to the next :not() and this mode flag is positive,\n // it's a part of the current :not() selector, and we should keep skipping\n if (skipToNextSelector && isPositive(current)) continue;\n skipToNextSelector = false;\n mode = (current as number) | (mode & SelectorFlags.NOT);\n continue;\n }\n\n if (skipToNextSelector) continue;\n\n if (mode & SelectorFlags.ELEMENT) {\n mode = SelectorFlags.ATTRIBUTE | mode & SelectorFlags.NOT;\n if (current !== '' && !hasTagAndTypeMatch(tNode, current, isProjectionMode) ||\n current === '' && selector.length === 1) {\n if (isPositive(mode)) return false;\n skipToNextSelector = true;\n }\n } else {\n const selectorAttrValue = mode & SelectorFlags.CLASS ? current : selector[++i];\n\n // special case for matching against classes when a tNode has been instantiated with\n // class and style values as separate attribute values (e.g. ['title', CLASS, 'foo'])\n if ((mode & SelectorFlags.CLASS) && tNode.attrs !== null) {\n if (!isCssClassMatching(tNode.attrs, selectorAttrValue as string, isProjectionMode)) {\n if (isPositive(mode)) return false;\n skipToNextSelector = true;\n }\n continue;\n }\n\n const attrName = (mode & SelectorFlags.CLASS) ? 'class' : current;\n const attrIndexInNode =\n findAttrIndexInNode(attrName, nodeAttrs, isInlineTemplate(tNode), isProjectionMode);\n\n if (attrIndexInNode === -1) {\n if (isPositive(mode)) return false;\n skipToNextSelector = true;\n continue;\n }\n\n if (selectorAttrValue !== '') {\n let nodeAttrValue: string;\n if (attrIndexInNode > nameOnlyMarkerIdx) {\n nodeAttrValue = '';\n } else {\n ngDevMode &&\n assertNotEqual(\n nodeAttrs[attrIndexInNode], AttributeMarker.NamespaceURI,\n 'We do not match directives on namespaced attributes');\n // we lowercase the attribute value to be able to match\n // selectors without case-sensitivity\n // (selectors are already in lowercase when generated)\n nodeAttrValue = (nodeAttrs[attrIndexInNode + 1] as string).toLowerCase();\n }\n\n const compareAgainstClassName = mode & SelectorFlags.CLASS ? nodeAttrValue : null;\n if (compareAgainstClassName &&\n classIndexOf(compareAgainstClassName, selectorAttrValue as string, 0) !== -1 ||\n mode & SelectorFlags.ATTRIBUTE && selectorAttrValue !== nodeAttrValue) {\n if (isPositive(mode)) return false;\n skipToNextSelector = true;\n }\n }\n }\n }\n\n return isPositive(mode) || skipToNextSelector;\n}\n\nfunction isPositive(mode: SelectorFlags): boolean {\n return (mode & SelectorFlags.NOT) === 0;\n}\n\n/**\n * Examines the attribute's definition array for a node to find the index of the\n * attribute that matches the given `name`.\n *\n * NOTE: This will not match namespaced attributes.\n *\n * Attribute matching depends upon `isInlineTemplate` and `isProjectionMode`.\n * The following table summarizes which types of attributes we attempt to match:\n *\n * ===========================================================================================================\n * Modes | Normal Attributes | Bindings Attributes | Template Attributes | I18n\n * Attributes\n * ===========================================================================================================\n * Inline + Projection | YES | YES | NO | YES\n * -----------------------------------------------------------------------------------------------------------\n * Inline + Directive | NO | NO | YES | NO\n * -----------------------------------------------------------------------------------------------------------\n * Non-inline + Projection | YES | YES | NO | YES\n * -----------------------------------------------------------------------------------------------------------\n * Non-inline + Directive | YES | YES | NO | YES\n * ===========================================================================================================\n *\n * @param name the name of the attribute to find\n * @param attrs the attribute array to examine\n * @param isInlineTemplate true if the node being matched is an inline template (e.g. `*ngFor`)\n * rather than a manually expanded template node (e.g ``).\n * @param isProjectionMode true if we are matching against content projection otherwise we are\n * matching against directives.\n */\nfunction findAttrIndexInNode(\n name: string, attrs: TAttributes|null, isInlineTemplate: boolean,\n isProjectionMode: boolean): number {\n if (attrs === null) return -1;\n\n let i = 0;\n\n if (isProjectionMode || !isInlineTemplate) {\n let bindingsMode = false;\n while (i < attrs.length) {\n const maybeAttrName = attrs[i];\n if (maybeAttrName === name) {\n return i;\n } else if (\n maybeAttrName === AttributeMarker.Bindings || maybeAttrName === AttributeMarker.I18n) {\n bindingsMode = true;\n } else if (\n maybeAttrName === AttributeMarker.Classes || maybeAttrName === AttributeMarker.Styles) {\n let value = attrs[++i];\n // We should skip classes here because we have a separate mechanism for\n // matching classes in projection mode.\n while (typeof value === 'string') {\n value = attrs[++i];\n }\n continue;\n } else if (maybeAttrName === AttributeMarker.Template) {\n // We do not care about Template attributes in this scenario.\n break;\n } else if (maybeAttrName === AttributeMarker.NamespaceURI) {\n // Skip the whole namespaced attribute and value. This is by design.\n i += 4;\n continue;\n }\n // In binding mode there are only names, rather than name-value pairs.\n i += bindingsMode ? 1 : 2;\n }\n // We did not match the attribute\n return -1;\n } else {\n return matchTemplateAttribute(attrs, name);\n }\n}\n\nexport function isNodeMatchingSelectorList(\n tNode: TNode, selector: CssSelectorList, isProjectionMode: boolean = false): boolean {\n for (let i = 0; i < selector.length; i++) {\n if (isNodeMatchingSelector(tNode, selector[i], isProjectionMode)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function getProjectAsAttrValue(tNode: TNode): CssSelector|null {\n const nodeAttrs = tNode.attrs;\n if (nodeAttrs != null) {\n const ngProjectAsAttrIdx = nodeAttrs.indexOf(AttributeMarker.ProjectAs);\n // only check for ngProjectAs in attribute names, don't accidentally match attribute's value\n // (attribute names are stored at even indexes)\n if ((ngProjectAsAttrIdx & 1) === 0) {\n return nodeAttrs[ngProjectAsAttrIdx + 1] as CssSelector;\n }\n }\n return null;\n}\n\nfunction getNameOnlyMarkerIndex(nodeAttrs: TAttributes) {\n for (let i = 0; i < nodeAttrs.length; i++) {\n const nodeAttr = nodeAttrs[i];\n if (isNameOnlyAttributeMarker(nodeAttr)) {\n return i;\n }\n }\n return nodeAttrs.length;\n}\n\nfunction matchTemplateAttribute(attrs: TAttributes, name: string): number {\n let i = attrs.indexOf(AttributeMarker.Template);\n if (i > -1) {\n i++;\n while (i < attrs.length) {\n const attr = attrs[i];\n // Return in case we checked all template attrs and are switching to the next section in the\n // attrs array (that starts with a number that represents an attribute marker).\n if (typeof attr === 'number') return -1;\n if (attr === name) return i;\n i++;\n }\n }\n return -1;\n}\n\n/**\n * Checks whether a selector is inside a CssSelectorList\n * @param selector Selector to be checked.\n * @param list List in which to look for the selector.\n */\nexport function isSelectorInSelectorList(selector: CssSelector, list: CssSelectorList): boolean {\n selectorListLoop: for (let i = 0; i < list.length; i++) {\n const currentSelectorInList = list[i];\n if (selector.length !== currentSelectorInList.length) {\n continue;\n }\n for (let j = 0; j < selector.length; j++) {\n if (selector[j] !== currentSelectorInList[j]) {\n continue selectorListLoop;\n }\n }\n return true;\n }\n return false;\n}\n\nfunction maybeWrapInNotSelector(isNegativeMode: boolean, chunk: string): string {\n return isNegativeMode ? ':not(' + chunk.trim() + ')' : chunk;\n}\n\nfunction stringifyCSSSelector(selector: CssSelector): string {\n let result = selector[0] as string;\n let i = 1;\n let mode = SelectorFlags.ATTRIBUTE;\n let currentChunk = '';\n let isNegativeMode = false;\n while (i < selector.length) {\n let valueOrMarker = selector[i];\n if (typeof valueOrMarker === 'string') {\n if (mode & SelectorFlags.ATTRIBUTE) {\n const attrValue = selector[++i] as string;\n currentChunk +=\n '[' + valueOrMarker + (attrValue.length > 0 ? '=\"' + attrValue + '\"' : '') + ']';\n } else if (mode & SelectorFlags.CLASS) {\n currentChunk += '.' + valueOrMarker;\n } else if (mode & SelectorFlags.ELEMENT) {\n currentChunk += ' ' + valueOrMarker;\n }\n } else {\n //\n // Append current chunk to the final result in case we come across SelectorFlag, which\n // indicates that the previous section of a selector is over. We need to accumulate content\n // between flags to make sure we wrap the chunk later in :not() selector if needed, e.g.\n // ```\n // ['', Flags.CLASS, '.classA', Flags.CLASS | Flags.NOT, '.classB', '.classC']\n // ```\n // should be transformed to `.classA :not(.classB .classC)`.\n //\n // Note: for negative selector part, we accumulate content between flags until we find the\n // next negative flag. This is needed to support a case where `:not()` rule contains more than\n // one chunk, e.g. the following selector:\n // ```\n // ['', Flags.ELEMENT | Flags.NOT, 'p', Flags.CLASS, 'foo', Flags.CLASS | Flags.NOT, 'bar']\n // ```\n // should be stringified to `:not(p.foo) :not(.bar)`\n //\n if (currentChunk !== '' && !isPositive(valueOrMarker)) {\n result += maybeWrapInNotSelector(isNegativeMode, currentChunk);\n currentChunk = '';\n }\n mode = valueOrMarker;\n // According to CssSelector spec, once we come across `SelectorFlags.NOT` flag, the negative\n // mode is maintained for remaining chunks of a selector.\n isNegativeMode = isNegativeMode || !isPositive(mode);\n }\n i++;\n }\n if (currentChunk !== '') {\n result += maybeWrapInNotSelector(isNegativeMode, currentChunk);\n }\n return result;\n}\n\n/**\n * Generates string representation of CSS selector in parsed form.\n *\n * ComponentDef and DirectiveDef are generated with the selector in parsed form to avoid doing\n * additional parsing at runtime (for example, for directive matching). However in some cases (for\n * example, while bootstrapping a component), a string version of the selector is required to query\n * for the host element on the page. This function takes the parsed form of a selector and returns\n * its string representation.\n *\n * @param selectorList selector in parsed form\n * @returns string representation of a given selector\n */\nexport function stringifyCSSSelectorList(selectorList: CssSelectorList): string {\n return selectorList.map(stringifyCSSSelector).join(',');\n}\n\n/**\n * Extracts attributes and classes information from a given CSS selector.\n *\n * This function is used while creating a component dynamically. In this case, the host element\n * (that is created dynamically) should contain attributes and classes specified in component's CSS\n * selector.\n *\n * @param selector CSS selector in parsed form (in a form of array)\n * @returns object with `attrs` and `classes` fields that contain extracted information\n */\nexport function extractAttrsAndClassesFromSelector(selector: CssSelector):\n {attrs: string[], classes: string[]} {\n const attrs: string[] = [];\n const classes: string[] = [];\n let i = 1;\n let mode = SelectorFlags.ATTRIBUTE;\n while (i < selector.length) {\n let valueOrMarker = selector[i];\n if (typeof valueOrMarker === 'string') {\n if (mode === SelectorFlags.ATTRIBUTE) {\n if (valueOrMarker !== '') {\n attrs.push(valueOrMarker, selector[++i] as string);\n }\n } else if (mode === SelectorFlags.CLASS) {\n classes.push(valueOrMarker);\n }\n } else {\n // According to CssSelector spec, once we come across `SelectorFlags.NOT` flag, the negative\n // mode is maintained for remaining chunks of a selector. Since attributes and classes are\n // extracted only for \"positive\" part of the selector, we can stop here.\n if (!isPositive(mode)) break;\n mode = valueOrMarker;\n }\n i++;\n }\n return {attrs, classes};\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {ChangeDetectionStrategy} from '../change_detection/constants';\nimport {formatRuntimeError, RuntimeErrorCode} from '../errors';\nimport {Mutable, Type} from '../interface/type';\nimport {NgModuleDef} from '../metadata/ng_module_def';\nimport {SchemaMetadata} from '../metadata/schema';\nimport {ViewEncapsulation} from '../metadata/view';\nimport {noSideEffects} from '../util/closure';\nimport {EMPTY_ARRAY, EMPTY_OBJ} from '../util/empty';\nimport {initNgDevMode} from '../util/ng_dev_mode';\nimport {stringify} from '../util/stringify';\n\nimport {NG_COMP_DEF, NG_DIR_DEF, NG_MOD_DEF, NG_PIPE_DEF} from './fields';\nimport {ComponentDef, ComponentDefFeature, ComponentTemplate, ComponentType, ContentQueriesFunction, DependencyTypeList, DirectiveDef, DirectiveDefFeature, DirectiveDefListOrFactory, HostBindingsFunction, InputTransformFunction, NgModuleScopeInfoFromDecorator, PipeDef, PipeDefListOrFactory, TypeOrFactory, ViewQueriesFunction} from './interfaces/definition';\nimport {TAttributes, TConstantsOrFactory} from './interfaces/node';\nimport {CssSelectorList} from './interfaces/projection';\nimport {stringifyCSSSelectorList} from './node_selector_matcher';\n\ninterface DirectiveDefinition {\n /**\n * Directive type, needed to configure the injector.\n */\n type: Type;\n\n /** The selectors that will be used to match nodes to this directive. */\n selectors?: CssSelectorList;\n\n /**\n * A map of input names.\n *\n * The format is in: `{[actualPropertyName: string]:(string|[string, string, Function])}`.\n *\n * Given:\n * ```\n * class MyComponent {\n * @Input()\n * publicInput1: string;\n *\n * @Input('publicInput2')\n * declaredInput2: string;\n *\n * @Input({transform: (value: boolean) => value ? 1 : 0})\n * transformedInput3: number;\n * }\n * ```\n *\n * is described as:\n * ```\n * {\n * publicInput1: 'publicInput1',\n * declaredInput2: ['declaredInput2', 'publicInput2'],\n * transformedInput3: [\n * 'transformedInput3',\n * 'transformedInput3',\n * (value: boolean) => value ? 1 : 0\n * ]\n * }\n * ```\n *\n * Which the minifier may translate to:\n * ```\n * {\n * minifiedPublicInput1: 'publicInput1',\n * minifiedDeclaredInput2: [ 'publicInput2', 'declaredInput2'],\n * minifiedTransformedInput3: [\n * 'transformedInput3',\n * 'transformedInput3',\n * (value: boolean) => value ? 1 : 0\n * ]\n * }\n * ```\n *\n * This allows the render to re-construct the minified, public, and declared names\n * of properties.\n *\n * NOTE:\n * - Because declared and public name are usually same we only generate the array\n * `['declared', 'public']` format when they differ.\n * - The reason why this API and `outputs` API is not the same is that `NgOnChanges` has\n * inconsistent behavior in that it uses declared names rather than minified or public. For\n * this reason `NgOnChanges` will be deprecated and removed in future version and this\n * API will be simplified to be consistent with `output`.\n */\n inputs?: {[P in keyof T]?: string|[string, string, InputTransformFunction?]};\n\n /**\n * A map of output names.\n *\n * The format is in: `{[actualPropertyName: string]:string}`.\n *\n * Which the minifier may translate to: `{[minifiedPropertyName: string]:string}`.\n *\n * This allows the render to re-construct the minified and non-minified names\n * of properties.\n */\n outputs?: {[P in keyof T]?: string};\n\n /**\n * A list of optional features to apply.\n *\n * See: {@link NgOnChangesFeature}, {@link ProvidersFeature}, {@link InheritDefinitionFeature}\n */\n features?: DirectiveDefFeature[];\n\n /**\n * Function executed by the parent template to allow child directive to apply host bindings.\n */\n hostBindings?: HostBindingsFunction;\n\n /**\n * The number of bindings in this directive `hostBindings` (including pure fn bindings).\n *\n * Used to calculate the length of the component's LView array, so we\n * can pre-fill the array and set the host binding start index.\n */\n hostVars?: number;\n\n /**\n * Assign static attribute values to a host element.\n *\n * This property will assign static attribute values as well as class and style\n * values to a host element. Since attribute values can consist of different types of values,\n * the `hostAttrs` array must include the values in the following format:\n *\n * attrs = [\n * // static attributes (like `title`, `name`, `id`...)\n * attr1, value1, attr2, value,\n *\n * // a single namespace value (like `x:id`)\n * NAMESPACE_MARKER, namespaceUri1, name1, value1,\n *\n * // another single namespace value (like `x:name`)\n * NAMESPACE_MARKER, namespaceUri2, name2, value2,\n *\n * // a series of CSS classes that will be applied to the element (no spaces)\n * CLASSES_MARKER, class1, class2, class3,\n *\n * // a series of CSS styles (property + value) that will be applied to the element\n * STYLES_MARKER, prop1, value1, prop2, value2\n * ]\n *\n * All non-class and non-style attributes must be defined at the start of the list\n * first before all class and style values are set. When there is a change in value\n * type (like when classes and styles are introduced) a marker must be used to separate\n * the entries. The marker values themselves are set via entries found in the\n * [AttributeMarker] enum.\n */\n hostAttrs?: TAttributes;\n\n /**\n * Function to create instances of content queries associated with a given directive.\n */\n contentQueries?: ContentQueriesFunction;\n\n /**\n * Additional set of instructions specific to view query processing. This could be seen as a\n * set of instructions to be inserted into the template function.\n */\n viewQuery?: ViewQueriesFunction|null;\n\n /**\n * Defines the name that can be used in the template to assign this directive to a variable.\n *\n * See: {@link Directive.exportAs}\n */\n exportAs?: string[];\n\n /**\n * Whether this directive/component is standalone.\n */\n standalone?: boolean;\n\n /**\n * Whether this directive/component is signal-based.\n */\n signals?: boolean;\n}\n\ninterface ComponentDefinition extends Omit, 'features'> {\n /**\n * The number of nodes, local refs, and pipes in this component template.\n *\n * Used to calculate the length of this component's LView array, so we\n * can pre-fill the array and set the binding start index.\n */\n decls: number;\n\n /**\n * The number of bindings in this component template (including pure fn bindings).\n *\n * Used to calculate the length of this component's LView array, so we\n * can pre-fill the array and set the host binding start index.\n */\n vars: number;\n\n /**\n * Template function use for rendering DOM.\n *\n * This function has following structure.\n *\n * ```\n * function Template(ctx:T, creationMode: boolean) {\n * if (creationMode) {\n * // Contains creation mode instructions.\n * }\n * // Contains binding update instructions\n * }\n * ```\n *\n * Common instructions are:\n * Creation mode instructions:\n * - `elementStart`, `elementEnd`\n * - `text`\n * - `container`\n * - `listener`\n *\n * Binding update instructions:\n * - `bind`\n * - `elementAttribute`\n * - `elementProperty`\n * - `elementClass`\n * - `elementStyle`\n *\n */\n template: ComponentTemplate;\n\n /**\n * Constants for the nodes in the component's view.\n * Includes attribute arrays, local definition arrays etc.\n */\n consts?: TConstantsOrFactory;\n\n /**\n * An array of `ngContent[selector]` values that were found in the template.\n */\n ngContentSelectors?: string[];\n /**\n * A list of optional features to apply.\n *\n * See: {@link NgOnChangesFeature}, {@link ProvidersFeature}\n */\n features?: ComponentDefFeature[];\n\n /**\n * Defines template and style encapsulation options available for Component's {@link Component}.\n */\n encapsulation?: ViewEncapsulation;\n\n /**\n * Defines arbitrary developer-defined data to be stored on a renderer instance.\n * This is useful for renderers that delegate to other renderers.\n *\n * see: animation\n */\n data?: {[kind: string]: any};\n\n /**\n * A set of styles that the component needs to be present for component to render correctly.\n */\n styles?: string[];\n\n /**\n * The strategy that the default change detector uses to detect changes.\n * When set, takes effect the next time change detection is triggered.\n */\n changeDetection?: ChangeDetectionStrategy;\n\n /**\n * Registry of directives, components, and pipes that may be found in this component's view.\n *\n * This property is either an array of types or a function that returns the array of types. This\n * function may be necessary to support forward declarations.\n */\n dependencies?: TypeOrFactory;\n\n /**\n * The set of schemas that declare elements to be allowed in the component's template.\n */\n schemas?: SchemaMetadata[]|null;\n}\n\n/**\n * Create a component definition object.\n *\n *\n * # Example\n * ```\n * class MyComponent {\n * // Generated by Angular Template Compiler\n * // [Symbol] syntax will not be supported by TypeScript until v2.7\n * static ɵcmp = defineComponent({\n * ...\n * });\n * }\n * ```\n * @codeGenApi\n */\nexport function ɵɵdefineComponent(componentDefinition: ComponentDefinition):\n Mutable, keyof ComponentDef> {\n return noSideEffects(() => {\n // Initialize ngDevMode. This must be the first statement in ɵɵdefineComponent.\n // See the `initNgDevMode` docstring for more information.\n (typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode();\n\n const baseDef = getNgDirectiveDef(componentDefinition as DirectiveDefinition);\n const def: Mutable, keyof ComponentDef> = {\n ...baseDef,\n decls: componentDefinition.decls,\n vars: componentDefinition.vars,\n template: componentDefinition.template,\n consts: componentDefinition.consts || null,\n ngContentSelectors: componentDefinition.ngContentSelectors,\n onPush: componentDefinition.changeDetection === ChangeDetectionStrategy.OnPush,\n directiveDefs: null!, // assigned in noSideEffects\n pipeDefs: null!, // assigned in noSideEffects\n dependencies: baseDef.standalone && componentDefinition.dependencies || null,\n getStandaloneInjector: null,\n signals: componentDefinition.signals ?? false,\n data: componentDefinition.data || {},\n encapsulation: componentDefinition.encapsulation || ViewEncapsulation.Emulated,\n styles: componentDefinition.styles || EMPTY_ARRAY,\n _: null,\n schemas: componentDefinition.schemas || null,\n tView: null,\n id: '',\n };\n\n initFeatures(def);\n const dependencies = componentDefinition.dependencies;\n def.directiveDefs = extractDefListOrFactory(dependencies, /* pipeDef */ false);\n def.pipeDefs = extractDefListOrFactory(dependencies, /* pipeDef */ true);\n def.id = getComponentId(def);\n\n return def;\n });\n}\n\n/**\n * Generated next to NgModules to monkey-patch directive and pipe references onto a component's\n * definition, when generating a direct reference in the component file would otherwise create an\n * import cycle.\n *\n * See [this explanation](https://hackmd.io/Odw80D0pR6yfsOjg_7XCJg?view) for more details.\n *\n * @codeGenApi\n */\nexport function ɵɵsetComponentScope(\n type: ComponentType, directives: Type[]|(() => Type[]),\n pipes: Type[]|(() => Type[])): void {\n const def = type.ɵcmp as ComponentDef;\n def.directiveDefs = extractDefListOrFactory(directives, /* pipeDef */ false);\n def.pipeDefs = extractDefListOrFactory(pipes, /* pipeDef */ true);\n}\n\nexport function extractDirectiveDef(type: Type): DirectiveDef|ComponentDef|null {\n return getComponentDef(type) || getDirectiveDef(type);\n}\n\nfunction nonNull(value: T|null): value is T {\n return value !== null;\n}\n\n/**\n * @codeGenApi\n */\nexport function ɵɵdefineNgModule(def: {\n /** Token representing the module. Used by DI. */\n type: T;\n\n /** List of components to bootstrap. */\n bootstrap?: Type[] | (() => Type[]);\n\n /** List of components, directives, and pipes declared by this module. */\n declarations?: Type[] | (() => Type[]);\n\n /** List of modules or `ModuleWithProviders` imported by this module. */\n imports?: Type[] | (() => Type[]);\n\n /**\n * List of modules, `ModuleWithProviders`, components, directives, or pipes exported by this\n * module.\n */\n exports?: Type[] | (() => Type[]);\n\n /** The set of schemas that declare elements to be allowed in the NgModule. */\n schemas?: SchemaMetadata[] | null;\n\n /** Unique ID for the module that is used with `getModuleFactory`. */\n id?: string | null;\n}): unknown {\n return noSideEffects(() => {\n const res: NgModuleDef = {\n type: def.type,\n bootstrap: def.bootstrap || EMPTY_ARRAY,\n declarations: def.declarations || EMPTY_ARRAY,\n imports: def.imports || EMPTY_ARRAY,\n exports: def.exports || EMPTY_ARRAY,\n transitiveCompileScopes: null,\n schemas: def.schemas || null,\n id: def.id || null,\n };\n return res;\n });\n}\n\n/**\n * Adds the module metadata that is necessary to compute the module's transitive scope to an\n * existing module definition.\n *\n * Scope metadata of modules is not used in production builds, so calls to this function can be\n * marked pure to tree-shake it from the bundle, allowing for all referenced declarations\n * to become eligible for tree-shaking as well.\n *\n * @codeGenApi\n */\nexport function ɵɵsetNgModuleScope(type: any, scope: NgModuleScopeInfoFromDecorator): unknown {\n return noSideEffects(() => {\n const ngModuleDef = getNgModuleDef(type, true);\n ngModuleDef.declarations = scope.declarations || EMPTY_ARRAY;\n ngModuleDef.imports = scope.imports || EMPTY_ARRAY;\n ngModuleDef.exports = scope.exports || EMPTY_ARRAY;\n });\n}\n\n/**\n * Inverts an inputs or outputs lookup such that the keys, which were the\n * minified keys, are part of the values, and the values are parsed so that\n * the publicName of the property is the new key\n *\n * e.g. for\n *\n * ```\n * class Comp {\n * @Input()\n * propName1: string;\n *\n * @Input('publicName2')\n * declaredPropName2: number;\n * }\n * ```\n *\n * will be serialized as\n *\n * ```\n * {\n * propName1: 'propName1',\n * declaredPropName2: ['publicName2', 'declaredPropName2'],\n * }\n * ```\n *\n * which is than translated by the minifier as:\n *\n * ```\n * {\n * minifiedPropName1: 'propName1',\n * minifiedPropName2: ['publicName2', 'declaredPropName2'],\n * }\n * ```\n *\n * becomes: (public name => minifiedName)\n *\n * ```\n * {\n * 'propName1': 'minifiedPropName1',\n * 'publicName2': 'minifiedPropName2',\n * }\n * ```\n *\n * Optionally the function can take `secondary` which will result in: (public name => declared name)\n *\n * ```\n * {\n * 'propName1': 'propName1',\n * 'publicName2': 'declaredPropName2',\n * }\n * ```\n *\n\n */\nfunction invertObject(\n obj?: {[P in keyof T]?: string|[string, string, ...unknown[]]},\n secondary?: Record): {[P in keyof T]: string} {\n if (obj == null) return EMPTY_OBJ as any;\n const newLookup: any = {};\n for (const minifiedKey in obj) {\n if (obj.hasOwnProperty(minifiedKey)) {\n let publicName: string|[string, string, ...unknown[]] = obj[minifiedKey]!;\n let declaredName = publicName;\n if (Array.isArray(publicName)) {\n declaredName = publicName[1];\n publicName = publicName[0];\n }\n newLookup[publicName] = minifiedKey;\n if (secondary) {\n (secondary[publicName] = declaredName as string);\n }\n }\n }\n return newLookup;\n}\n\n/**\n * Create a directive definition object.\n *\n * # Example\n * ```ts\n * class MyDirective {\n * // Generated by Angular Template Compiler\n * // [Symbol] syntax will not be supported by TypeScript until v2.7\n * static ɵdir = ɵɵdefineDirective({\n * ...\n * });\n * }\n * ```\n *\n * @codeGenApi\n */\nexport function ɵɵdefineDirective(directiveDefinition: DirectiveDefinition):\n Mutable, keyof DirectiveDef> {\n return noSideEffects(() => {\n const def = getNgDirectiveDef(directiveDefinition);\n initFeatures(def);\n\n return def;\n });\n}\n\n/**\n * Create a pipe definition object.\n *\n * # Example\n * ```\n * class MyPipe implements PipeTransform {\n * // Generated by Angular Template Compiler\n * static ɵpipe = definePipe({\n * ...\n * });\n * }\n * ```\n * @param pipeDef Pipe definition generated by the compiler\n *\n * @codeGenApi\n */\nexport function ɵɵdefinePipe(pipeDef: {\n /** Name of the pipe. Used for matching pipes in template to pipe defs. */\n name: string;\n\n /** Pipe class reference. Needed to extract pipe lifecycle hooks. */\n type: Type;\n\n /** Whether the pipe is pure. */\n pure?: boolean;\n\n /**\n * Whether the pipe is standalone.\n */\n standalone?: boolean;\n}): unknown {\n return (>{\n type: pipeDef.type,\n name: pipeDef.name,\n factory: null,\n pure: pipeDef.pure !== false,\n standalone: pipeDef.standalone === true,\n onDestroy: pipeDef.type.prototype.ngOnDestroy || null\n });\n}\n\n/**\n * The following getter methods retrieve the definition from the type. Currently the retrieval\n * honors inheritance, but in the future we may change the rule to require that definitions are\n * explicit. This would require some sort of migration strategy.\n */\n\nexport function getComponentDef(type: any): ComponentDef|null {\n return type[NG_COMP_DEF] || null;\n}\n\nexport function getDirectiveDef(type: any): DirectiveDef|null {\n return type[NG_DIR_DEF] || null;\n}\n\nexport function getPipeDef(type: any): PipeDef|null {\n return type[NG_PIPE_DEF] || null;\n}\n\n/**\n * Checks whether a given Component, Directive or Pipe is marked as standalone.\n * This will return false if passed anything other than a Component, Directive, or Pipe class\n * See [this guide](/guide/standalone-components) for additional information:\n *\n * @param type A reference to a Component, Directive or Pipe.\n * @publicApi\n */\nexport function isStandalone(type: Type): boolean {\n const def = getComponentDef(type) || getDirectiveDef(type) || getPipeDef(type);\n return def !== null ? def.standalone : false;\n}\n\nexport function getNgModuleDef(type: any, throwNotFound: true): NgModuleDef;\nexport function getNgModuleDef(type: any): NgModuleDef|null;\nexport function getNgModuleDef(type: any, throwNotFound?: boolean): NgModuleDef|null {\n const ngModuleDef = type[NG_MOD_DEF] || null;\n if (!ngModuleDef && throwNotFound === true) {\n throw new Error(`Type ${stringify(type)} does not have 'ɵmod' property.`);\n }\n return ngModuleDef;\n}\n\nfunction getNgDirectiveDef(directiveDefinition: DirectiveDefinition):\n Mutable, keyof DirectiveDef> {\n const declaredInputs: Record = {};\n\n return {\n type: directiveDefinition.type,\n providersResolver: null,\n factory: null,\n hostBindings: directiveDefinition.hostBindings || null,\n hostVars: directiveDefinition.hostVars || 0,\n hostAttrs: directiveDefinition.hostAttrs || null,\n contentQueries: directiveDefinition.contentQueries || null,\n declaredInputs,\n inputTransforms: null,\n inputConfig: directiveDefinition.inputs || EMPTY_OBJ,\n exportAs: directiveDefinition.exportAs || null,\n standalone: directiveDefinition.standalone === true,\n signals: directiveDefinition.signals === true,\n selectors: directiveDefinition.selectors || EMPTY_ARRAY,\n viewQuery: directiveDefinition.viewQuery || null,\n features: directiveDefinition.features || null,\n setInput: null,\n findHostDirectiveDefs: null,\n hostDirectives: null,\n inputs: invertObject(directiveDefinition.inputs, declaredInputs),\n outputs: invertObject(directiveDefinition.outputs),\n };\n}\n\nfunction initFeatures(definition:|Mutable, keyof DirectiveDef>|\n Mutable, keyof ComponentDef>): void {\n definition.features?.forEach((fn) => fn(definition));\n}\n\nfunction extractDefListOrFactory(\n dependencies: TypeOrFactory|undefined,\n pipeDef: false): DirectiveDefListOrFactory|null;\nfunction extractDefListOrFactory(\n dependencies: TypeOrFactory|undefined, pipeDef: true): PipeDefListOrFactory|\n null;\nfunction extractDefListOrFactory(\n dependencies: TypeOrFactory|undefined, pipeDef: boolean): unknown {\n if (!dependencies) {\n return null;\n }\n\n const defExtractor = pipeDef ? getPipeDef : extractDirectiveDef;\n\n return () => (typeof dependencies === 'function' ? dependencies() : dependencies)\n .map(dep => defExtractor(dep))\n .filter(nonNull);\n}\n\n/**\n * A map that contains the generated component IDs and type.\n */\nexport const GENERATED_COMP_IDS = new Map>();\n\n/**\n * A method can returns a component ID from the component definition using a variant of DJB2 hash\n * algorithm.\n */\nfunction getComponentId(componentDef: ComponentDef): string {\n let hash = 0;\n\n // We cannot rely solely on the component selector as the same selector can be used in different\n // modules.\n //\n // `componentDef.style` is not used, due to it causing inconsistencies. Ex: when server\n // component styles has no sourcemaps and browsers do.\n //\n // Example:\n // https://github.com/angular/components/blob/d9f82c8f95309e77a6d82fd574c65871e91354c2/src/material/core/option/option.ts#L248\n // https://github.com/angular/components/blob/285f46dc2b4c5b127d356cb7c4714b221f03ce50/src/material/legacy-core/option/option.ts#L32\n\n const hashSelectors = [\n componentDef.selectors,\n componentDef.ngContentSelectors,\n componentDef.hostVars,\n componentDef.hostAttrs,\n componentDef.consts,\n componentDef.vars,\n componentDef.decls,\n componentDef.encapsulation,\n componentDef.standalone,\n componentDef.signals,\n componentDef.exportAs,\n JSON.stringify(componentDef.inputs),\n JSON.stringify(componentDef.outputs),\n // We cannot use 'componentDef.type.name' as the name of the symbol will change and will not\n // match in the server and browser bundles.\n Object.getOwnPropertyNames(componentDef.type.prototype),\n !!componentDef.contentQueries,\n !!componentDef.viewQuery,\n ].join('|');\n\n for (const char of hashSelectors) {\n hash = Math.imul(31, hash) + char.charCodeAt(0) << 0;\n }\n\n // Force positive number hash.\n // 2147483647 = equivalent of Integer.MAX_VALUE.\n hash += 2147483647 + 1;\n\n const compId = 'c' + hash;\n\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (GENERATED_COMP_IDS.has(compId)) {\n const previousCompDefType = GENERATED_COMP_IDS.get(compId)!;\n if (previousCompDefType !== componentDef.type) {\n console.warn(formatRuntimeError(\n RuntimeErrorCode.COMPONENT_ID_COLLISION,\n `Component ID generation collision detected. Components '${\n previousCompDefType.name}' and '${componentDef.type.name}' with selector '${\n stringifyCSSSelectorList(\n componentDef\n .selectors)}' generated the same component ID. To fix this, you can change the selector of one of those components or add an extra host attribute to force a different ID.`));\n }\n } else {\n GENERATED_COMP_IDS.set(compId, componentDef.type);\n }\n }\n\n return compId;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Injector} from '../../di/injector';\nimport {ProviderToken} from '../../di/provider_token';\nimport {DehydratedView} from '../../hydration/interfaces';\nimport {SchemaMetadata} from '../../metadata/schema';\nimport {Sanitizer} from '../../sanitization/sanitizer';\nimport type {ReactiveLViewConsumer} from '../reactive_lview_consumer';\nimport type {EffectManager} from '../reactivity/effect';\nimport type {AfterRenderEventManager} from '../after_render_hooks';\n\nimport {LContainer} from './container';\nimport {ComponentDef, ComponentTemplate, DirectiveDef, DirectiveDefList, HostBindingsFunction, PipeDef, PipeDefList, ViewQueriesFunction} from './definition';\nimport {I18nUpdateOpCodes, TI18n, TIcu} from './i18n';\nimport {TConstants, TNode} from './node';\nimport {LQueries, TQueries} from './query';\nimport {Renderer, RendererFactory} from './renderer';\nimport {RElement} from './renderer_dom';\nimport {TStylingKey, TStylingRange} from './styling';\n\n\n\n// Below are constants for LView indices to help us look up LView members\n// without having to remember the specific indices.\n// Uglify will inline these when minifying so there shouldn't be a cost.\nexport const HOST = 0;\nexport const TVIEW = 1;\nexport const FLAGS = 2;\nexport const PARENT = 3;\nexport const NEXT = 4;\nexport const DESCENDANT_VIEWS_TO_REFRESH = 5;\nexport const T_HOST = 6;\nexport const CLEANUP = 7;\nexport const CONTEXT = 8;\nexport const INJECTOR = 9;\nexport const ENVIRONMENT = 10;\nexport const RENDERER = 11;\nexport const CHILD_HEAD = 12;\nexport const CHILD_TAIL = 13;\n// FIXME(misko): Investigate if the three declarations aren't all same thing.\nexport const DECLARATION_VIEW = 14;\nexport const DECLARATION_COMPONENT_VIEW = 15;\nexport const DECLARATION_LCONTAINER = 16;\nexport const PREORDER_HOOK_FLAGS = 17;\nexport const QUERIES = 18;\nexport const ID = 19;\nexport const EMBEDDED_VIEW_INJECTOR = 20;\nexport const ON_DESTROY_HOOKS = 21;\nexport const HYDRATION = 22;\nexport const REACTIVE_TEMPLATE_CONSUMER = 23;\nexport const REACTIVE_HOST_BINDING_CONSUMER = 24;\n/**\n * Size of LView's header. Necessary to adjust for it when setting slots.\n *\n * IMPORTANT: `HEADER_OFFSET` should only be referred to the in the `ɵɵ*` instructions to translate\n * instruction index into `LView` index. All other indexes should be in the `LView` index space and\n * there should be no need to refer to `HEADER_OFFSET` anywhere else.\n */\nexport const HEADER_OFFSET = 25;\n\n\n// This interface replaces the real LView interface if it is an arg or a\n// return value of a public instruction. This ensures we don't need to expose\n// the actual interface, which should be kept private.\nexport interface OpaqueViewState {\n '__brand__': 'Brand for OpaqueViewState that nothing will match';\n}\n\n\n/**\n * `LView` stores all of the information needed to process the instructions as\n * they are invoked from the template. Each embedded view and component view has its\n * own `LView`. When processing a particular view, we set the `viewData` to that\n * `LView`. When that view is done processing, the `viewData` is set back to\n * whatever the original `viewData` was before (the parent `LView`).\n *\n * Keeping separate state for each view facilities view insertion / deletion, so we\n * don't have to edit the data array based on which views are present.\n */\nexport interface LView extends Array {\n /**\n * The node into which this `LView` is inserted.\n */\n [HOST]: RElement|null;\n\n /**\n * The static data for this view. We need a reference to this so we can easily walk up the\n * node tree in DI and get the TView.data array associated with a node (where the\n * directive defs are stored).\n */\n readonly[TVIEW]: TView;\n\n /** Flags for this view. See LViewFlags for more info. */\n [FLAGS]: LViewFlags;\n\n /**\n * This may store an {@link LView} or {@link LContainer}.\n *\n * `LView` - The parent view. This is needed when we exit the view and must restore the previous\n * LView. Without this, the render method would have to keep a stack of\n * views as it is recursively rendering templates.\n *\n * `LContainer` - The current view is part of a container, and is an embedded view.\n */\n [PARENT]: LView|LContainer|null;\n\n /**\n *\n * The next sibling LView or LContainer.\n *\n * Allows us to propagate between sibling view states that aren't in the same\n * container. Embedded views already have a node.next, but it is only set for\n * views in the same container. We need a way to link component views and views\n * across containers as well.\n */\n [NEXT]: LView|LContainer|null;\n\n /** Queries active for this view - nodes from a view are reported to those queries. */\n [QUERIES]: LQueries|null;\n\n /**\n * Store the `TNode` of the location where the current `LView` is inserted into.\n *\n * Given:\n * ```\n *
\n * \n *
\n * ```\n *\n * We end up with two `TView`s.\n * - `parent` `TView` which contains `
`\n * - `child` `TView` which contains ``\n *\n * Typically the `child` is inserted into the declaration location of the `parent`, but it can be\n * inserted anywhere. Because it can be inserted anywhere it is not possible to store the\n * insertion information in the `TView` and instead we must store it in the `LView[T_HOST]`.\n *\n * So to determine where is our insertion parent we would execute:\n * ```\n * const parentLView = lView[PARENT];\n * const parentTNode = lView[T_HOST];\n * const insertionParent = parentLView[parentTNode.index];\n * ```\n *\n *\n * If `null`, this is the root view of an application (root component is in this view) and it has\n * no parents.\n */\n [T_HOST]: TNode|null;\n\n /**\n * When a view is destroyed, listeners need to be released and outputs need to be\n * unsubscribed. This context array stores both listener functions wrapped with\n * their context and output subscription instances for a particular view.\n *\n * These change per LView instance, so they cannot be stored on TView. Instead,\n * TView.cleanup saves an index to the necessary context in this array.\n *\n * After `LView` is created it is possible to attach additional instance specific functions at the\n * end of the `lView[CLEANUP]` because we know that no more `T` level cleanup functions will be\n * added here.\n */\n [CLEANUP]: any[]|null;\n\n /**\n * - For dynamic views, this is the context with which to render the template (e.g.\n * `NgForContext`), or `{}` if not defined explicitly.\n * - For root view of the root component it's a reference to the component instance itself.\n * - For components, the context is a reference to the component instance itself.\n * - For inline views, the context is null.\n */\n [CONTEXT]: T;\n\n /** An optional Module Injector to be used as fall back after Element Injectors are consulted. */\n readonly[INJECTOR]: Injector|null;\n\n /**\n * Contextual data that is shared across multiple instances of `LView` in the same application.\n */\n [ENVIRONMENT]: LViewEnvironment;\n\n /** Renderer to be used for this view. */\n [RENDERER]: Renderer;\n\n /**\n * Reference to the first LView or LContainer beneath this LView in\n * the hierarchy.\n *\n * Necessary to store this so views can traverse through their nested views\n * to remove listeners and call onDestroy callbacks.\n */\n [CHILD_HEAD]: LView|LContainer|null;\n\n /**\n * The last LView or LContainer beneath this LView in the hierarchy.\n *\n * The tail allows us to quickly add a new state to the end of the view list\n * without having to propagate starting from the first child.\n */\n [CHILD_TAIL]: LView|LContainer|null;\n\n /**\n * View where this view's template was declared.\n *\n * The template for a dynamically created view may be declared in a different view than\n * it is inserted. We already track the \"insertion view\" (view where the template was\n * inserted) in LView[PARENT], but we also need access to the \"declaration view\"\n * (view where the template was declared). Otherwise, we wouldn't be able to call the\n * view's template function with the proper contexts. Context should be inherited from\n * the declaration view tree, not the insertion view tree.\n *\n * Example (AppComponent template):\n *\n * <-- declared here -->\n * <-- inserted inside this component -->\n *\n * The above is declared in the AppComponent template, but it will be passed into\n * SomeComp and inserted there. In this case, the declaration view would be the AppComponent,\n * but the insertion view would be SomeComp. When we are removing views, we would want to\n * traverse through the insertion view to clean up listeners. When we are calling the\n * template function during change detection, we need the declaration view to get inherited\n * context.\n */\n [DECLARATION_VIEW]: LView|null;\n\n\n /**\n * Points to the declaration component view, used to track transplanted `LView`s.\n *\n * See: `DECLARATION_VIEW` which points to the actual `LView` where it was declared, whereas\n * `DECLARATION_COMPONENT_VIEW` points to the component which may not be same as\n * `DECLARATION_VIEW`.\n *\n * Example:\n * ```\n * <#VIEW #myComp>\n *
\n * ...\n *
\n * \n * ```\n * In the above case `DECLARATION_VIEW` for `myTmpl` points to the `LView` of `ngIf` whereas\n * `DECLARATION_COMPONENT_VIEW` points to `LView` of the `myComp` which owns the template.\n *\n * The reason for this is that all embedded views are always check-always whereas the component\n * view can be check-always or on-push. When we have a transplanted view it is important to\n * determine if we have transplanted a view from check-always declaration to on-push insertion\n * point. In such a case the transplanted view needs to be added to the `LContainer` in the\n * declared `LView` and CD during the declared view CD (in addition to the CD at the insertion\n * point.) (Any transplanted views which are intra Component are of no interest because the CD\n * strategy of declaration and insertion will always be the same, because it is the same\n * component.)\n *\n * Queries already track moved views in `LView[DECLARATION_LCONTAINER]` and\n * `LContainer[MOVED_VIEWS]`. However the queries also track `LView`s which moved within the same\n * component `LView`. Transplanted views are a subset of moved views, and we use\n * `DECLARATION_COMPONENT_VIEW` to differentiate them. As in this example.\n *\n * Example showing intra component `LView` movement.\n * ```\n * <#VIEW #myComp>\n *
\n * Content to render when condition is true.\n * Content to render when condition is false.\n * \n * ```\n * The `thenBlock` and `elseBlock` is moved but not transplanted.\n *\n * Example showing inter component `LView` movement (transplanted view).\n * ```\n * <#VIEW #myComp>\n * ...\n * \n * \n * ```\n * In the above example `myTmpl` is passed into a different component. If `insertion-component`\n * instantiates `myTmpl` and `insertion-component` is on-push then the `LContainer` needs to be\n * marked as containing transplanted views and those views need to be CD as part of the\n * declaration CD.\n *\n *\n * When change detection runs, it iterates over `[MOVED_VIEWS]` and CDs any child `LView`s where\n * the `DECLARATION_COMPONENT_VIEW` of the current component and the child `LView` does not match\n * (it has been transplanted across components.)\n *\n * Note: `[DECLARATION_COMPONENT_VIEW]` points to itself if the LView is a component view (the\n * simplest / most common case).\n *\n * see also:\n * - https://hackmd.io/@mhevery/rJUJsvv9H write up of the problem\n * - `LContainer[HAS_TRANSPLANTED_VIEWS]` which marks which `LContainer` has transplanted views.\n * - `LContainer[TRANSPLANT_HEAD]` and `LContainer[TRANSPLANT_TAIL]` storage for transplanted\n * - `LView[DECLARATION_LCONTAINER]` similar problem for queries\n * - `LContainer[MOVED_VIEWS]` similar problem for queries\n */\n [DECLARATION_COMPONENT_VIEW]: LView;\n\n /**\n * A declaration point of embedded views (ones instantiated based on the content of a\n * ), null for other types of views.\n *\n * We need to track all embedded views created from a given declaration point so we can prepare\n * query matches in a proper order (query matches are ordered based on their declaration point and\n * _not_ the insertion point).\n */\n [DECLARATION_LCONTAINER]: LContainer|null;\n\n /**\n * More flags for this view. See PreOrderHookFlags for more info.\n */\n [PREORDER_HOOK_FLAGS]: PreOrderHookFlags;\n\n /**\n * The number of direct transplanted views which need a refresh or have descendants themselves\n * that need a refresh but have not marked their ancestors as Dirty. This tells us that during\n * change detection we should still descend to find those children to refresh, even if the parents\n * are not `Dirty`/`CheckAlways`.\n */\n [DESCENDANT_VIEWS_TO_REFRESH]: number;\n\n /** Unique ID of the view. Used for `__ngContext__` lookups in the `LView` registry. */\n [ID]: number;\n\n /**\n * A container related to hydration annotation information that's associated with this LView.\n */\n [HYDRATION]: DehydratedView|null;\n\n /**\n * Optional injector assigned to embedded views that takes\n * precedence over the element and module injectors.\n */\n readonly[EMBEDDED_VIEW_INJECTOR]: Injector|null;\n\n /**\n * A collection of callbacks functions that are executed when a given LView is destroyed. Those\n * are user defined, LView-specific destroy callbacks that don't have any corresponding TView\n * entries.\n */\n [ON_DESTROY_HOOKS]: Array<() => void>|null;\n\n /**\n * The `Consumer` for this `LView`'s template so that signal reads can be tracked.\n *\n * This is initially `null` and gets assigned a consumer after template execution\n * if any signals were read.\n */\n [REACTIVE_TEMPLATE_CONSUMER]: ReactiveLViewConsumer|null;\n\n /**\n * Same as REACTIVE_TEMPLATE_CONSUMER, but for the host bindings of the LView.\n */\n [REACTIVE_HOST_BINDING_CONSUMER]: ReactiveLViewConsumer|null;\n}\n\n/**\n * Contextual data that is shared across multiple instances of `LView` in the same application.\n */\nexport interface LViewEnvironment {\n /** Factory to be used for creating Renderer. */\n rendererFactory: RendererFactory;\n\n /** An optional custom sanitizer. */\n sanitizer: Sanitizer|null;\n\n /** Container for reactivity system `effect`s. */\n effectManager: EffectManager|null;\n\n /** Container for after render hooks */\n afterRenderEventManager: AfterRenderEventManager|null;\n}\n\n/** Flags associated with an LView (saved in LView[FLAGS]) */\nexport const enum LViewFlags {\n /** The state of the init phase on the first 2 bits */\n InitPhaseStateIncrementer = 0b00000000001,\n InitPhaseStateMask = 0b00000000011,\n\n /**\n * Whether or not the view is in creationMode.\n *\n * This must be stored in the view rather than using `data` as a marker so that\n * we can properly support embedded views. Otherwise, when exiting a child view\n * back into the parent view, `data` will be defined and `creationMode` will be\n * improperly reported as false.\n */\n CreationMode = 1 << 2,\n\n /**\n * Whether or not this LView instance is on its first processing pass.\n *\n * An LView instance is considered to be on its \"first pass\" until it\n * has completed one creation mode run and one update mode run. At this\n * time, the flag is turned off.\n */\n FirstLViewPass = 1 << 3,\n\n /** Whether this view has default change detection strategy (checks always) or onPush */\n CheckAlways = 1 << 4,\n\n /** Whether there are any i18n blocks inside this LView. */\n HasI18n = 1 << 5,\n\n /** Whether or not this view is currently dirty (needing check) */\n Dirty = 1 << 6,\n\n /** Whether or not this view is currently attached to change detection tree. */\n Attached = 1 << 7,\n\n /** Whether or not this view is destroyed. */\n Destroyed = 1 << 8,\n\n /** Whether or not this view is the root view */\n IsRoot = 1 << 9,\n\n /**\n * Whether this moved LView was needs to be refreshed. Similar to the Dirty flag, but used for\n * transplanted and signal views where the parent/ancestor views are not marked dirty as well.\n * i.e. \"Refresh just this view\". Used in conjunction with the DESCENDANT_VIEWS_TO_REFRESH\n * counter.\n */\n RefreshView = 1 << 10,\n\n /** Indicates that the view **or any of its ancestors** have an embedded view injector. */\n HasEmbeddedViewInjector = 1 << 11,\n\n /** Indicates that the view was created with `signals: true`. */\n SignalView = 1 << 12,\n\n /**\n * This is the count of the bits the 1 was shifted above (base 10)\n */\n IndexWithinInitPhaseShift = 13,\n\n /**\n * Index of the current init phase on last 21 bits\n */\n IndexWithinInitPhaseIncrementer = 1 << IndexWithinInitPhaseShift,\n\n // Subtracting 1 gives all 1s to the right of the initial shift\n // So `(1 << 3) - 1` would give 3 1s: 1 << 3 = 0b01000, subtract 1 = 0b00111\n IndexWithinInitPhaseReset = (1 << IndexWithinInitPhaseShift) - 1,\n}\n\n/**\n * Possible states of the init phase:\n * - 00: OnInit hooks to be run.\n * - 01: AfterContentInit hooks to be run\n * - 10: AfterViewInit hooks to be run\n * - 11: All init hooks have been run\n */\nexport const enum InitPhaseState {\n OnInitHooksToBeRun = 0b00,\n AfterContentInitHooksToBeRun = 0b01,\n AfterViewInitHooksToBeRun = 0b10,\n InitPhaseCompleted = 0b11,\n}\n\n/** More flags associated with an LView (saved in LView[PREORDER_HOOK_FLAGS]) */\nexport const enum PreOrderHookFlags {\n /**\n The index of the next pre-order hook to be called in the hooks array, on the first 16\n bits\n */\n IndexOfTheNextPreOrderHookMaskMask = 0b01111111111111111,\n\n /**\n * The number of init hooks that have already been called, on the last 16 bits\n */\n NumberOfInitHooksCalledIncrementer = 0b010000000000000000,\n NumberOfInitHooksCalledShift = 16,\n NumberOfInitHooksCalledMask = 0b11111111111111110000000000000000,\n}\n\n/**\n * Stores a set of OpCodes to process `HostBindingsFunction` associated with a current view.\n *\n * In order to invoke `HostBindingsFunction` we need:\n * 1. 'elementIdx`: Index to the element associated with the `HostBindingsFunction`.\n * 2. 'directiveIdx`: Index to the directive associated with the `HostBindingsFunction`. (This will\n * become the context for the `HostBindingsFunction` invocation.)\n * 3. `bindingRootIdx`: Location where the bindings for the `HostBindingsFunction` start. Internally\n * `HostBindingsFunction` binding indexes start from `0` so we need to add `bindingRootIdx` to\n * it.\n * 4. `HostBindingsFunction`: A host binding function to execute.\n *\n * The above information needs to be encoded into the `HostBindingOpCodes` in an efficient manner.\n *\n * 1. `elementIdx` is encoded into the `HostBindingOpCodes` as `~elementIdx` (so a negative number);\n * 2. `directiveIdx`\n * 3. `bindingRootIdx`\n * 4. `HostBindingsFunction` is passed in as is.\n *\n * The `HostBindingOpCodes` array contains:\n * - negative number to select the element index.\n * - followed by 1 or more of:\n * - a number to select the directive index\n * - a number to select the bindingRoot index\n * - and a function to invoke.\n *\n * ## Example\n *\n * ```\n * const hostBindingOpCodes = [\n * ~30, // Select element 30\n * 40, 45, MyDir.ɵdir.hostBindings // Invoke host bindings on MyDir on element 30;\n * // directiveIdx = 40; bindingRootIdx = 45;\n * 50, 55, OtherDir.ɵdir.hostBindings // Invoke host bindings on OtherDire on element 30\n * // directiveIdx = 50; bindingRootIdx = 55;\n * ]\n * ```\n *\n * ## Pseudocode\n * ```\n * const hostBindingOpCodes = tView.hostBindingOpCodes;\n * if (hostBindingOpCodes === null) return;\n * for (let i = 0; i < hostBindingOpCodes.length; i++) {\n * const opCode = hostBindingOpCodes[i] as number;\n * if (opCode < 0) {\n * // Negative numbers are element indexes.\n * setSelectedIndex(~opCode);\n * } else {\n * // Positive numbers are NumberTuple which store bindingRootIndex and directiveIndex.\n * const directiveIdx = opCode;\n * const bindingRootIndx = hostBindingOpCodes[++i] as number;\n * const hostBindingFn = hostBindingOpCodes[++i] as HostBindingsFunction;\n * setBindingRootForHostBindings(bindingRootIndx, directiveIdx);\n * const context = lView[directiveIdx];\n * hostBindingFn(RenderFlags.Update, context);\n * }\n * }\n * ```\n *\n */\nexport interface HostBindingOpCodes extends Array> {\n __brand__: 'HostBindingOpCodes';\n debug?: string[];\n}\n\n/**\n * Explicitly marks `TView` as a specific type in `ngDevMode`\n *\n * It is useful to know conceptually what time of `TView` we are dealing with when\n * debugging an application (even if the runtime does not need it.) For this reason\n * we store this information in the `ngDevMode` `TView` and than use it for\n * better debugging experience.\n */\nexport const enum TViewType {\n /**\n * Root `TView` is the used to bootstrap components into. It is used in conjunction with\n * `LView` which takes an existing DOM node not owned by Angular and wraps it in `TView`/`LView`\n * so that other components can be loaded into it.\n */\n Root = 0,\n\n /**\n * `TView` associated with a Component. This would be the `TView` directly associated with the\n * component view (as opposed an `Embedded` `TView` which would be a child of `Component` `TView`)\n */\n Component = 1,\n\n /**\n * `TView` associated with a template. Such as `*ngIf`, `` etc... A `Component`\n * can have zero or more `Embedded` `TView`s.\n */\n Embedded = 2,\n}\n\n/**\n * The static data for an LView (shared between all templates of a\n * given type).\n *\n * Stored on the `ComponentDef.tView`.\n */\nexport interface TView {\n /**\n * Type of `TView` (`Root`|`Component`|`Embedded`).\n */\n type: TViewType;\n\n /**\n * This is a blueprint used to generate LView instances for this TView. Copying this\n * blueprint is faster than creating a new LView from scratch.\n */\n blueprint: LView;\n\n /**\n * The template function used to refresh the view of dynamically created views\n * and components. Will be null for inline views.\n */\n template: ComponentTemplate<{}>|null;\n\n /**\n * A function containing query-related instructions.\n */\n viewQuery: ViewQueriesFunction<{}>|null;\n\n /**\n * A `TNode` representing the declaration location of this `TView` (not part of this TView).\n */\n declTNode: TNode|null;\n\n // FIXME(misko): Why does `TView` not have `declarationTView` property?\n\n /** Whether or not this template has been processed in creation mode. */\n firstCreatePass: boolean;\n\n /**\n * Whether or not this template has been processed in update mode (e.g. change detected)\n *\n * `firstUpdatePass` is used by styling to set up `TData` to contain metadata about the styling\n * instructions. (Mainly to build up a linked list of styling priority order.)\n *\n * Typically this function gets cleared after first execution. If exception is thrown then this\n * flag can remain turned un until there is first successful (no exception) pass. This means that\n * individual styling instructions keep track of if they have already been added to the linked\n * list to prevent double adding.\n */\n firstUpdatePass: boolean;\n\n /** Static data equivalent of LView.data[]. Contains TNodes, PipeDefInternal or TI18n. */\n data: TData;\n\n /**\n * The binding start index is the index at which the data array\n * starts to store bindings only. Saving this value ensures that we\n * will begin reading bindings at the correct point in the array when\n * we are in update mode.\n *\n * -1 means that it has not been initialized.\n */\n bindingStartIndex: number;\n\n /**\n * The index where the \"expando\" section of `LView` begins. The expando\n * section contains injectors, directive instances, and host binding values.\n * Unlike the \"decls\" and \"vars\" sections of `LView`, the length of this\n * section cannot be calculated at compile-time because directives are matched\n * at runtime to preserve locality.\n *\n * We store this start index so we know where to start checking host bindings\n * in `setHostBindings`.\n */\n expandoStartIndex: number;\n\n /**\n * Whether or not there are any static view queries tracked on this view.\n *\n * We store this so we know whether or not we should do a view query\n * refresh after creation mode to collect static query results.\n */\n staticViewQueries: boolean;\n\n /**\n * Whether or not there are any static content queries tracked on this view.\n *\n * We store this so we know whether or not we should do a content query\n * refresh after creation mode to collect static query results.\n */\n staticContentQueries: boolean;\n\n /**\n * A reference to the first child node located in the view.\n */\n firstChild: TNode|null;\n\n /**\n * Stores the OpCodes to be replayed during change-detection to process the `HostBindings`\n *\n * See `HostBindingOpCodes` for encoding details.\n */\n hostBindingOpCodes: HostBindingOpCodes|null;\n\n /**\n * Full registry of directives and components that may be found in this view.\n *\n * It's necessary to keep a copy of the full def list on the TView so it's possible\n * to render template functions without a host component.\n */\n directiveRegistry: DirectiveDefList|null;\n\n /**\n * Full registry of pipes that may be found in this view.\n *\n * The property is either an array of `PipeDefs`s or a function which returns the array of\n * `PipeDefs`s. The function is necessary to be able to support forward declarations.\n *\n * It's necessary to keep a copy of the full def list on the TView so it's possible\n * to render template functions without a host component.\n */\n pipeRegistry: PipeDefList|null;\n\n /**\n * Array of ngOnInit, ngOnChanges and ngDoCheck hooks that should be executed for this view in\n * creation mode.\n *\n * This array has a flat structure and contains TNode indices, directive indices (where an\n * instance can be found in `LView`) and hook functions. TNode index is followed by the directive\n * index and a hook function. If there are multiple hooks for a given TNode, the TNode index is\n * not repeated and the next lifecycle hook information is stored right after the previous hook\n * function. This is done so that at runtime the system can efficiently iterate over all of the\n * functions to invoke without having to make any decisions/lookups.\n */\n preOrderHooks: HookData|null;\n\n /**\n * Array of ngOnChanges and ngDoCheck hooks that should be executed for this view in update mode.\n *\n * This array has the same structure as the `preOrderHooks` one.\n */\n preOrderCheckHooks: HookData|null;\n\n /**\n * Array of ngAfterContentInit and ngAfterContentChecked hooks that should be executed\n * for this view in creation mode.\n *\n * Even indices: Directive index\n * Odd indices: Hook function\n */\n contentHooks: HookData|null;\n\n /**\n * Array of ngAfterContentChecked hooks that should be executed for this view in update\n * mode.\n *\n * Even indices: Directive index\n * Odd indices: Hook function\n */\n contentCheckHooks: HookData|null;\n\n /**\n * Array of ngAfterViewInit and ngAfterViewChecked hooks that should be executed for\n * this view in creation mode.\n *\n * Even indices: Directive index\n * Odd indices: Hook function\n */\n viewHooks: HookData|null;\n\n /**\n * Array of ngAfterViewChecked hooks that should be executed for this view in\n * update mode.\n *\n * Even indices: Directive index\n * Odd indices: Hook function\n */\n viewCheckHooks: HookData|null;\n\n /**\n * Array of ngOnDestroy hooks that should be executed when this view is destroyed.\n *\n * Even indices: Directive index\n * Odd indices: Hook function\n */\n destroyHooks: DestroyHookData|null;\n\n /**\n * When a view is destroyed, listeners need to be released and outputs need to be\n * unsubscribed. This cleanup array stores both listener data (in chunks of 4)\n * and output data (in chunks of 2) for a particular view. Combining the arrays\n * saves on memory (70 bytes per array) and on a few bytes of code size (for two\n * separate for loops).\n *\n * If it's a native DOM listener or output subscription being stored:\n * 1st index is: event name `name = tView.cleanup[i+0]`\n * 2nd index is: index of native element or a function that retrieves global target (window,\n * document or body) reference based on the native element:\n * `typeof idxOrTargetGetter === 'function'`: global target getter function\n * `typeof idxOrTargetGetter === 'number'`: index of native element\n *\n * 3rd index is: index of listener function `listener = lView[CLEANUP][tView.cleanup[i+2]]`\n * 4th index is: `useCaptureOrIndx = tView.cleanup[i+3]`\n * `typeof useCaptureOrIndx == 'boolean' : useCapture boolean\n * `typeof useCaptureOrIndx == 'number':\n * `useCaptureOrIndx >= 0` `removeListener = LView[CLEANUP][useCaptureOrIndx]`\n * `useCaptureOrIndx < 0` `subscription = LView[CLEANUP][-useCaptureOrIndx]`\n *\n * If it's an output subscription or query list destroy hook:\n * 1st index is: output unsubscribe function / query list destroy function\n * 2nd index is: index of function context in LView.cleanupInstances[]\n * `tView.cleanup[i+0].call(lView[CLEANUP][tView.cleanup[i+1]])`\n */\n cleanup: any[]|null;\n\n /**\n * A list of element indices for child components that will need to be\n * refreshed when the current view has finished its check. These indices have\n * already been adjusted for the HEADER_OFFSET.\n *\n */\n components: number[]|null;\n\n /**\n * A collection of queries tracked in a given view.\n */\n queries: TQueries|null;\n\n /**\n * An array of indices pointing to directives with content queries alongside with the\n * corresponding query index. Each entry in this array is a tuple of:\n * - index of the first content query index declared by a given directive;\n * - index of a directive.\n *\n * We are storing those indexes so we can refresh content queries as part of a view refresh\n * process.\n */\n contentQueries: number[]|null;\n\n /**\n * Set of schemas that declare elements to be allowed inside the view.\n */\n schemas: SchemaMetadata[]|null;\n\n /**\n * Array of constants for the view. Includes attribute arrays, local definition arrays etc.\n * Used for directive matching, attribute bindings, local definitions and more.\n */\n consts: TConstants|null;\n\n /**\n * Indicates that there was an error before we managed to complete the first create pass of the\n * view. This means that the view is likely corrupted and we should try to recover it.\n */\n incompleteFirstPass: boolean;\n\n /**\n * Unique id of this TView for hydration purposes:\n * - TViewType.Embedded: a unique id generated during serialization on the server\n * - TViewType.Component: an id generated based on component properties\n * (see `getComponentId` function for details)\n */\n ssrId: string|null;\n}\n\n/** Single hook callback function. */\nexport type HookFn = () => void;\n\n/**\n * Information necessary to call a hook. E.g. the callback that\n * needs to invoked and the index at which to find its context.\n */\nexport type HookEntry = number|HookFn;\n\n/**\n * Array of hooks that should be executed for a view and their directive indices.\n *\n * For each node of the view, the following data is stored:\n * 1) Node index (optional)\n * 2) A series of number/function pairs where:\n * - even indices are directive indices\n * - odd indices are hook functions\n *\n * Special cases:\n * - a negative directive index flags an init hook (ngOnInit, ngAfterContentInit, ngAfterViewInit)\n */\nexport type HookData = HookEntry[];\n\n/**\n * Array of destroy hooks that should be executed for a view and their directive indices.\n *\n * The array is set up as a series of number/function or number/(number|function)[]:\n * - Even indices represent the context with which hooks should be called.\n * - Odd indices are the hook functions themselves. If a value at an odd index is an array,\n * it represents the destroy hooks of a `multi` provider where:\n * - Even indices represent the index of the provider for which we've registered a destroy hook,\n * inside of the `multi` provider array.\n * - Odd indices are the destroy hook functions.\n * For example:\n * LView: `[0, 1, 2, AService, 4, [BService, CService, DService]]`\n * destroyHooks: `[3, AService.ngOnDestroy, 5, [0, BService.ngOnDestroy, 2, DService.ngOnDestroy]]`\n *\n * In the example above `AService` is a type provider with an `ngOnDestroy`, whereas `BService`,\n * `CService` and `DService` are part of a `multi` provider where only `BService` and `DService`\n * have an `ngOnDestroy` hook.\n */\nexport type DestroyHookData = (HookEntry|HookData)[];\n\n/**\n * Static data that corresponds to the instance-specific data array on an LView.\n *\n * Each node's static data is stored in tData at the same index that it's stored\n * in the data array. Any nodes that do not have static data store a null value in\n * tData to avoid a sparse array.\n *\n * Each pipe's definition is stored here at the same index as its pipe instance in\n * the data array.\n *\n * Each host property's name is stored here at the same index as its value in the\n * data array.\n *\n * Each property binding name is stored here at the same index as its value in\n * the data array. If the binding is an interpolation, the static string values\n * are stored parallel to the dynamic values. Example:\n *\n * id=\"prefix {{ v0 }} a {{ v1 }} b {{ v2 }} suffix\"\n *\n * LView | TView.data\n *------------------------\n * v0 value | 'a'\n * v1 value | 'b'\n * v2 value | id � prefix � suffix\n *\n * Injector bloom filters are also stored here.\n */\nexport type TData = (TNode|PipeDef|DirectiveDef|ComponentDef|number|TStylingRange|\n TStylingKey|ProviderToken|TI18n|I18nUpdateOpCodes|TIcu|null|string)[];\n\n// Note: This hack is necessary so we don't erroneously get a circular dependency\n// failure based on types.\nexport const unusedValueExportToPlacateAjd = 1;\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {DehydratedContainerView} from '../../hydration/interfaces';\n\nimport {TNode} from './node';\nimport {RComment, RElement} from './renderer_dom';\nimport {DESCENDANT_VIEWS_TO_REFRESH, HOST, LView, NEXT, PARENT, T_HOST} from './view';\n\n\n\n/**\n * Special location which allows easy identification of type. If we have an array which was\n * retrieved from the `LView` and that array has `true` at `TYPE` location, we know it is\n * `LContainer`.\n */\nexport const TYPE = 1;\n\n/**\n * Below are constants for LContainer indices to help us look up LContainer members\n * without having to remember the specific indices.\n * Uglify will inline these when minifying so there shouldn't be a cost.\n */\n\n/**\n * Flag to signify that this `LContainer` may have transplanted views which need to be change\n * detected. (see: `LView[DECLARATION_COMPONENT_VIEW])`.\n *\n * This flag, once set, is never unset for the `LContainer`. This means that when unset we can skip\n * a lot of work in `refreshEmbeddedViews`. But when set we still need to verify\n * that the `MOVED_VIEWS` are transplanted and on-push.\n */\nexport const HAS_TRANSPLANTED_VIEWS = 2;\n\n// PARENT, NEXT, DESCENDANT_VIEWS_TO_REFRESH are indices 3, 4, and 5\n// As we already have these constants in LView, we don't need to re-create them.\n\n// T_HOST is index 6\n// We already have this constants in LView, we don't need to re-create it.\n\nexport const NATIVE = 7;\nexport const VIEW_REFS = 8;\nexport const MOVED_VIEWS = 9;\nexport const DEHYDRATED_VIEWS = 10;\n\n\n/**\n * Size of LContainer's header. Represents the index after which all views in the\n * container will be inserted. We need to keep a record of current views so we know\n * which views are already in the DOM (and don't need to be re-added) and so we can\n * remove views from the DOM when they are no longer required.\n */\nexport const CONTAINER_HEADER_OFFSET = 11;\n\n/**\n * The state associated with a container.\n *\n * This is an array so that its structure is closer to LView. This helps\n * when traversing the view tree (which is a mix of containers and component\n * views), so we can jump to viewOrContainer[NEXT] in the same way regardless\n * of type.\n */\nexport interface LContainer extends Array {\n /**\n * The host element of this LContainer.\n *\n * The host could be an LView if this container is on a component node.\n * In that case, the component LView is its HOST.\n */\n readonly[HOST]: RElement|RComment|LView;\n\n /**\n * This is a type field which allows us to differentiate `LContainer` from `StylingContext` in an\n * efficient way. The value is always set to `true`\n */\n [TYPE]: true;\n\n /**\n * Flag to signify that this `LContainer` may have transplanted views which need to be change\n * detected. (see: `LView[DECLARATION_COMPONENT_VIEW])`.\n *\n * This flag, once set, is never unset for the `LContainer`.\n */\n [HAS_TRANSPLANTED_VIEWS]: boolean;\n\n /**\n * Access to the parent view is necessary so we can propagate back\n * up from inside a container to parent[NEXT].\n */\n [PARENT]: LView;\n\n /**\n * This allows us to jump from a container to a sibling container or component\n * view with the same parent, so we can remove listeners efficiently.\n */\n [NEXT]: LView|LContainer|null;\n\n /**\n * The number of direct transplanted views which need a refresh or have descendants themselves\n * that need a refresh but have not marked their ancestors as Dirty. This tells us that during\n * change detection we should still descend to find those children to refresh, even if the parents\n * are not `Dirty`/`CheckAlways`.\n */\n [DESCENDANT_VIEWS_TO_REFRESH]: number;\n\n /**\n * A collection of views created based on the underlying `` element but inserted into\n * a different `LContainer`. We need to track views created from a given declaration point since\n * queries collect matches from the embedded view declaration point and _not_ the insertion point.\n */\n [MOVED_VIEWS]: LView[]|null;\n\n /**\n * Pointer to the `TNode` which represents the host of the container.\n */\n [T_HOST]: TNode;\n\n /** The comment element that serves as an anchor for this LContainer. */\n [NATIVE]: RComment;\n\n /**\n * Array of `ViewRef`s used by any `ViewContainerRef`s that point to this container.\n *\n * This is lazily initialized by `ViewContainerRef` when the first view is inserted.\n *\n * NOTE: This is stored as `any[]` because render3 should really not be aware of `ViewRef` and\n * doing so creates circular dependency.\n */\n [VIEW_REFS]: unknown[]|null;\n\n /**\n * Array of dehydrated views within this container.\n *\n * This information is used during the hydration process on the client.\n * The hydration logic tries to find a matching dehydrated view, \"claim\" it\n * and use this information to do further matching. After that, this \"claimed\"\n * view is removed from the list. The remaining \"unclaimed\" views are\n * \"garbage-collected\" later on, i.e. removed from the DOM once the hydration\n * logic finishes.\n */\n [DEHYDRATED_VIEWS]: DehydratedContainerView[]|null;\n}\n\n// Note: This hack is necessary so we don't erroneously get a circular dependency\n// failure based on types.\nexport const unusedValueExportToPlacateAjd = 1;\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {LContainer, TYPE} from './container';\nimport {ComponentDef, DirectiveDef} from './definition';\nimport {TNode, TNodeFlags, TNodeType} from './node';\nimport {RNode} from './renderer_dom';\nimport {FLAGS, LView, LViewFlags} from './view';\n\n\n/**\n * True if `value` is `LView`.\n * @param value wrapped value of `RNode`, `LView`, `LContainer`\n */\nexport function isLView(value: RNode|LView|LContainer|{}|null): value is LView {\n return Array.isArray(value) && typeof value[TYPE] === 'object';\n}\n\n/**\n * True if `value` is `LContainer`.\n * @param value wrapped value of `RNode`, `LView`, `LContainer`\n */\nexport function isLContainer(value: RNode|LView|LContainer|{}|null): value is LContainer {\n return Array.isArray(value) && value[TYPE] === true;\n}\n\nexport function isContentQueryHost(tNode: TNode): boolean {\n return (tNode.flags & TNodeFlags.hasContentQuery) !== 0;\n}\n\nexport function isComponentHost(tNode: TNode): boolean {\n return tNode.componentOffset > -1;\n}\n\nexport function isDirectiveHost(tNode: TNode): boolean {\n return (tNode.flags & TNodeFlags.isDirectiveHost) === TNodeFlags.isDirectiveHost;\n}\n\nexport function isComponentDef(def: DirectiveDef): def is ComponentDef {\n return !!(def as ComponentDef).template;\n}\n\nexport function isRootView(target: LView): boolean {\n return (target[FLAGS] & LViewFlags.IsRoot) !== 0;\n}\n\nexport function isProjectionTNode(tNode: TNode): boolean {\n return (tNode.type & TNodeType.Projection) === TNodeType.Projection;\n}\n\nexport function hasI18n(lView: LView): boolean {\n return (lView[FLAGS] & LViewFlags.HasI18n) === LViewFlags.HasI18n;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertDefined, assertEqual, assertNumber, throwError} from '../util/assert';\n\nimport {getComponentDef, getNgModuleDef} from './definition';\nimport {LContainer} from './interfaces/container';\nimport {DirectiveDef} from './interfaces/definition';\nimport {TIcu} from './interfaces/i18n';\nimport {NodeInjectorOffset} from './interfaces/injector';\nimport {TNode} from './interfaces/node';\nimport {isLContainer, isLView} from './interfaces/type_checks';\nimport {DECLARATION_COMPONENT_VIEW, FLAGS, HEADER_OFFSET, LView, LViewFlags, T_HOST, TVIEW, TView} from './interfaces/view';\n\n// [Assert functions do not constraint type when they are guarded by a truthy\n// expression.](https://github.com/microsoft/TypeScript/issues/37295)\n\n\nexport function assertTNodeForLView(tNode: TNode, lView: LView) {\n assertTNodeForTView(tNode, lView[TVIEW]);\n}\n\nexport function assertTNodeForTView(tNode: TNode, tView: TView) {\n assertTNode(tNode);\n const tData = tView.data;\n for (let i = HEADER_OFFSET; i < tData.length; i++) {\n if (tData[i] === tNode) {\n return;\n }\n }\n throwError('This TNode does not belong to this TView.');\n}\n\nexport function assertTNode(tNode: TNode) {\n assertDefined(tNode, 'TNode must be defined');\n if (!(tNode && typeof tNode === 'object' && tNode.hasOwnProperty('directiveStylingLast'))) {\n throwError('Not of type TNode, got: ' + tNode);\n }\n}\n\n\nexport function assertTIcu(tIcu: TIcu) {\n assertDefined(tIcu, 'Expected TIcu to be defined');\n if (!(typeof tIcu.currentCaseLViewIndex === 'number')) {\n throwError('Object is not of TIcu type.');\n }\n}\n\nexport function assertComponentType(\n actual: any,\n msg: string = 'Type passed in is not ComponentType, it does not have \\'ɵcmp\\' property.') {\n if (!getComponentDef(actual)) {\n throwError(msg);\n }\n}\n\nexport function assertNgModuleType(\n actual: any,\n msg: string = 'Type passed in is not NgModuleType, it does not have \\'ɵmod\\' property.') {\n if (!getNgModuleDef(actual)) {\n throwError(msg);\n }\n}\n\nexport function assertCurrentTNodeIsParent(isParent: boolean) {\n assertEqual(isParent, true, 'currentTNode should be a parent');\n}\n\nexport function assertHasParent(tNode: TNode|null) {\n assertDefined(tNode, 'currentTNode should exist!');\n assertDefined(tNode!.parent, 'currentTNode should have a parent');\n}\n\nexport function assertLContainer(value: any): asserts value is LContainer {\n assertDefined(value, 'LContainer must be defined');\n assertEqual(isLContainer(value), true, 'Expecting LContainer');\n}\n\nexport function assertLViewOrUndefined(value: any): asserts value is LView|null|undefined {\n value && assertEqual(isLView(value), true, 'Expecting LView or undefined or null');\n}\n\nexport function assertLView(value: any): asserts value is LView {\n assertDefined(value, 'LView must be defined');\n assertEqual(isLView(value), true, 'Expecting LView');\n}\n\nexport function assertFirstCreatePass(tView: TView, errMessage?: string) {\n assertEqual(\n tView.firstCreatePass, true, errMessage || 'Should only be called in first create pass.');\n}\n\nexport function assertFirstUpdatePass(tView: TView, errMessage?: string) {\n assertEqual(\n tView.firstUpdatePass, true, errMessage || 'Should only be called in first update pass.');\n}\n\n/**\n * This is a basic sanity check that an object is probably a directive def. DirectiveDef is\n * an interface, so we can't do a direct instanceof check.\n */\nexport function assertDirectiveDef(obj: any): asserts obj is DirectiveDef {\n if (obj.type === undefined || obj.selectors == undefined || obj.inputs === undefined) {\n throwError(\n `Expected a DirectiveDef/ComponentDef and this object does not seem to have the expected shape.`);\n }\n}\n\nexport function assertIndexInDeclRange(lView: LView, index: number) {\n const tView = lView[1];\n assertBetween(HEADER_OFFSET, tView.bindingStartIndex, index);\n}\n\nexport function assertIndexInExpandoRange(lView: LView, index: number) {\n const tView = lView[1];\n assertBetween(tView.expandoStartIndex, lView.length, index);\n}\n\nexport function assertBetween(lower: number, upper: number, index: number) {\n if (!(lower <= index && index < upper)) {\n throwError(`Index out of range (expecting ${lower} <= ${index} < ${upper})`);\n }\n}\n\nexport function assertProjectionSlots(lView: LView, errMessage?: string) {\n assertDefined(lView[DECLARATION_COMPONENT_VIEW], 'Component views should exist.');\n assertDefined(\n lView[DECLARATION_COMPONENT_VIEW][T_HOST]!.projection,\n errMessage ||\n 'Components with projection nodes () must have projection slots defined.');\n}\n\nexport function assertParentView(lView: LView|null, errMessage?: string) {\n assertDefined(\n lView,\n errMessage || 'Component views should always have a parent view (component\\'s host view)');\n}\n\n\n/**\n * This is a basic sanity check that the `injectorIndex` seems to point to what looks like a\n * NodeInjector data structure.\n *\n * @param lView `LView` which should be checked.\n * @param injectorIndex index into the `LView` where the `NodeInjector` is expected.\n */\nexport function assertNodeInjector(lView: LView, injectorIndex: number) {\n assertIndexInExpandoRange(lView, injectorIndex);\n assertIndexInExpandoRange(lView, injectorIndex + NodeInjectorOffset.PARENT);\n assertNumber(lView[injectorIndex + 0], 'injectorIndex should point to a bloom filter');\n assertNumber(lView[injectorIndex + 1], 'injectorIndex should point to a bloom filter');\n assertNumber(lView[injectorIndex + 2], 'injectorIndex should point to a bloom filter');\n assertNumber(lView[injectorIndex + 3], 'injectorIndex should point to a bloom filter');\n assertNumber(lView[injectorIndex + 4], 'injectorIndex should point to a bloom filter');\n assertNumber(lView[injectorIndex + 5], 'injectorIndex should point to a bloom filter');\n assertNumber(lView[injectorIndex + 6], 'injectorIndex should point to a bloom filter');\n assertNumber(lView[injectorIndex + 7], 'injectorIndex should point to a bloom filter');\n assertNumber(\n lView[injectorIndex + NodeInjectorOffset.PARENT],\n 'injectorIndex should point to parent injector');\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Type} from '../interface/type';\nimport {stringify} from '../util/stringify';\nimport {NG_FACTORY_DEF} from './fields';\n\n\n/**\n * Definition of what a factory function should look like.\n */\nexport type FactoryFn = {\n /**\n * Subclasses without an explicit constructor call through to the factory of their base\n * definition, providing it with their own constructor to instantiate.\n */\n (t?: Type): U;\n\n /**\n * If no constructor to instantiate is provided, an instance of type T itself is created.\n */\n (t?: undefined): T;\n};\n\n\nexport function getFactoryDef(type: any, throwNotFound: true): FactoryFn;\nexport function getFactoryDef(type: any): FactoryFn|null;\nexport function getFactoryDef(type: any, throwNotFound?: boolean): FactoryFn|null {\n const hasFactoryDef = type.hasOwnProperty(NG_FACTORY_DEF);\n if (!hasFactoryDef && throwNotFound === true && ngDevMode) {\n throw new Error(`Type ${stringify(type)} does not have 'ɵfac' property.`);\n }\n return hasFactoryDef ? type[NG_FACTORY_DEF] : null;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Symbol used to tell `Signal`s apart from other functions.\n *\n * This can be used to auto-unwrap signals in various cases, or to auto-wrap non-signal values.\n */\nexport const SIGNAL = /* @__PURE__ */ Symbol('SIGNAL');\n\n/**\n * A reactive value which notifies consumers of any changes.\n *\n * Signals are functions which returns their current value. To access the current value of a signal,\n * call it.\n *\n * Ordinary values can be turned into `Signal`s with the `signal` function.\n *\n * @developerPreview\n */\nexport type Signal = (() => T)&{\n [SIGNAL]: unknown;\n};\n\n/**\n * Checks if the given `value` is a reactive `Signal`.\n *\n * @developerPreview\n */\nexport function isSignal(value: unknown): value is Signal {\n return typeof value === 'function' && (value as Signal)[SIGNAL] !== undefined;\n}\n\n/**\n * A comparison function which can determine if two values are equal.\n *\n * @developerPreview\n */\nexport type ValueEqualityFn = (a: T, b: T) => boolean;\n\n/**\n * The default equality function used for `signal` and `computed`, which treats objects and arrays\n * as never equal, and all other primitive values using identity semantics.\n *\n * This allows signals to hold non-primitive values (arrays, objects, other collections) and still\n * propagate change notification upon explicit mutation without identity change.\n *\n * @developerPreview\n */\nexport function defaultEquals(a: T, b: T) {\n // `Object.is` compares two values using identity semantics which is desired behavior for\n // primitive values. If `Object.is` determines two values to be equal we need to make sure that\n // those don't represent objects (we want to make sure that 2 objects are always considered\n // \"unequal\"). The null check is needed for the special case of JavaScript reporting null values\n // as objects (`typeof null === 'object'`).\n return (a === null || typeof a !== 'object') && Object.is(a, b);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n// Required as the signals library is in a separate package, so we need to explicitly ensure the\n// global `ngDevMode` type is defined.\nimport '../../util/ng_dev_mode';\n\ntype Version = number&{__brand: 'Version'};\n\n/**\n * The currently active consumer `ReactiveNode`, if running code in a reactive context.\n *\n * Change this via `setActiveConsumer`.\n */\nlet activeConsumer: ReactiveNode|null = null;\nlet inNotificationPhase = false;\n\nexport function setActiveConsumer(consumer: ReactiveNode|null): ReactiveNode|null {\n const prev = activeConsumer;\n activeConsumer = consumer;\n return prev;\n}\n\nexport const REACTIVE_NODE: ReactiveNode = {\n version: 0 as Version,\n dirty: false,\n producerNode: undefined,\n producerLastReadVersion: undefined,\n producerIndexOfThis: undefined,\n nextProducerIndex: 0,\n liveConsumerNode: undefined,\n liveConsumerIndexOfThis: undefined,\n consumerAllowSignalWrites: false,\n consumerIsAlwaysLive: false,\n producerMustRecompute: () => false,\n producerRecomputeValue: () => {},\n consumerMarkedDirty: () => {},\n};\n\n/**\n * A producer and/or consumer which participates in the reactive graph.\n *\n * Producer `ReactiveNode`s which are accessed when a consumer `ReactiveNode` is the\n * `activeConsumer` are tracked as dependencies of that consumer.\n *\n * Certain consumers are also tracked as \"live\" consumers and create edges in the other direction,\n * from producer to consumer. These edges are used to propagate change notifications when a\n * producer's value is updated.\n *\n * A `ReactiveNode` may be both a producer and consumer.\n */\nexport interface ReactiveNode {\n /**\n * Version of the value that this node produces.\n *\n * This is incremented whenever a new value is produced by this node which is not equal to the\n * previous value (by whatever definition of equality is in use).\n */\n version: Version;\n\n /**\n * Whether this node (in its consumer capacity) is dirty.\n *\n * Only live consumers become dirty, when receiving a change notification from a dependency\n * producer.\n */\n dirty: boolean;\n\n /**\n * Producers which are dependencies of this consumer.\n *\n * Uses the same indices as the `producerLastReadVersion` and `producerIndexOfThis` arrays.\n */\n producerNode: ReactiveNode[]|undefined;\n\n /**\n * `Version` of the value last read by a given producer.\n *\n * Uses the same indices as the `producerNode` and `producerIndexOfThis` arrays.\n */\n producerLastReadVersion: Version[]|undefined;\n\n /**\n * Index of `this` (consumer) in each producer's `liveConsumers` array.\n *\n * This value is only meaningful if this node is live (`liveConsumers.length > 0`). Otherwise\n * these indices are stale.\n *\n * Uses the same indices as the `producerNode` and `producerLastReadVersion` arrays.\n */\n producerIndexOfThis: number[]|undefined;\n\n /**\n * Index into the producer arrays that the next dependency of this node as a consumer will use.\n *\n * This index is zeroed before this node as a consumer begins executing. When a producer is read,\n * it gets inserted into the producers arrays at this index. There may be an existing dependency\n * in this location which may or may not match the incoming producer, depending on whether the\n * same producers were read in the same order as the last computation.\n */\n nextProducerIndex: number;\n\n /**\n * Array of consumers of this producer that are \"live\" (they require push notifications).\n *\n * `liveConsumerNode.length` is effectively our reference count for this node.\n */\n liveConsumerNode: ReactiveNode[]|undefined;\n\n /**\n * Index of `this` (producer) in each consumer's `producerNode` array.\n *\n * Uses the same indices as the `liveConsumerNode` array.\n */\n liveConsumerIndexOfThis: number[]|undefined;\n\n /**\n * Whether writes to signals are allowed when this consumer is the `activeConsumer`.\n *\n * This is used to enforce guardrails such as preventing writes to writable signals in the\n * computation function of computed signals, which is supposed to be pure.\n */\n consumerAllowSignalWrites: boolean;\n\n readonly consumerIsAlwaysLive: boolean;\n\n /**\n * Tracks whether producers need to recompute their value independently of the reactive graph (for\n * example, if no initial value has been computed).\n */\n producerMustRecompute(node: unknown): boolean;\n producerRecomputeValue(node: unknown): void;\n consumerMarkedDirty(node: unknown): void;\n}\n\ninterface ConsumerNode extends ReactiveNode {\n producerNode: NonNullable;\n producerIndexOfThis: NonNullable;\n producerLastReadVersion: NonNullable;\n}\n\ninterface ProducerNode extends ReactiveNode {\n liveConsumerNode: NonNullable;\n liveConsumerIndexOfThis: NonNullable;\n}\n\n/**\n * Called by implementations when a producer's signal is read.\n */\nexport function producerAccessed(node: ReactiveNode): void {\n if (inNotificationPhase) {\n throw new Error(\n typeof ngDevMode !== 'undefined' && ngDevMode ?\n `Assertion error: signal read during notification phase` :\n '');\n }\n\n if (activeConsumer === null) {\n // Accessed outside of a reactive context, so nothing to record.\n return;\n }\n\n // This producer is the `idx`th dependency of `activeConsumer`.\n const idx = activeConsumer.nextProducerIndex++;\n\n assertConsumerNode(activeConsumer);\n\n if (idx < activeConsumer.producerNode.length && activeConsumer.producerNode[idx] !== node) {\n // There's been a change in producers since the last execution of `activeConsumer`.\n // `activeConsumer.producerNode[idx]` holds a stale dependency which will be be removed and\n // replaced with `this`.\n //\n // If `activeConsumer` isn't live, then this is a no-op, since we can replace the producer in\n // `activeConsumer.producerNode` directly. However, if `activeConsumer` is live, then we need\n // to remove it from the stale producer's `liveConsumer`s.\n if (consumerIsLive(activeConsumer)) {\n const staleProducer = activeConsumer.producerNode[idx];\n producerRemoveLiveConsumerAtIndex(staleProducer, activeConsumer.producerIndexOfThis[idx]);\n\n // At this point, the only record of `staleProducer` is the reference at\n // `activeConsumer.producerNode[idx]` which will be overwritten below.\n }\n }\n\n if (activeConsumer.producerNode[idx] !== node) {\n // We're a new dependency of the consumer (at `idx`).\n activeConsumer.producerNode[idx] = node;\n\n // If the active consumer is live, then add it as a live consumer. If not, then use 0 as a\n // placeholder value.\n activeConsumer.producerIndexOfThis[idx] =\n consumerIsLive(activeConsumer) ? producerAddLiveConsumer(node, activeConsumer, idx) : 0;\n }\n activeConsumer.producerLastReadVersion[idx] = node.version;\n}\n\n/**\n * Ensure this producer's `version` is up-to-date.\n */\nexport function producerUpdateValueVersion(node: ReactiveNode): void {\n if (consumerIsLive(node) && !node.dirty) {\n // A live consumer will be marked dirty by producers, so a clean state means that its version\n // is guaranteed to be up-to-date.\n return;\n }\n\n if (!node.producerMustRecompute(node) && !consumerPollProducersForChange(node)) {\n // None of our producers report a change since the last time they were read, so no\n // recomputation of our value is necessary, and we can consider ourselves clean.\n node.dirty = false;\n return;\n }\n\n node.producerRecomputeValue(node);\n\n // After recomputing the value, we're no longer dirty.\n node.dirty = false;\n}\n\n/**\n * Propagate a dirty notification to live consumers of this producer.\n */\nexport function producerNotifyConsumers(node: ReactiveNode): void {\n if (node.liveConsumerNode === undefined) {\n return;\n }\n\n // Prevent signal reads when we're updating the graph\n const prev = inNotificationPhase;\n inNotificationPhase = true;\n try {\n for (const consumer of node.liveConsumerNode) {\n if (!consumer.dirty) {\n consumerMarkDirty(consumer);\n }\n }\n } finally {\n inNotificationPhase = prev;\n }\n}\n\n/**\n * Whether this `ReactiveNode` in its producer capacity is currently allowed to initiate updates,\n * based on the current consumer context.\n */\nexport function producerUpdatesAllowed(): boolean {\n return activeConsumer?.consumerAllowSignalWrites !== false;\n}\n\nexport function consumerMarkDirty(node: ReactiveNode): void {\n node.dirty = true;\n producerNotifyConsumers(node);\n node.consumerMarkedDirty?.(node);\n}\n\n/**\n * Prepare this consumer to run a computation in its reactive context.\n *\n * Must be called by subclasses which represent reactive computations, before those computations\n * begin.\n */\nexport function consumerBeforeComputation(node: ReactiveNode|null): ReactiveNode|null {\n node && (node.nextProducerIndex = 0);\n return setActiveConsumer(node);\n}\n\n/**\n * Finalize this consumer's state after a reactive computation has run.\n *\n * Must be called by subclasses which represent reactive computations, after those computations\n * have finished.\n */\nexport function consumerAfterComputation(\n node: ReactiveNode|null, prevConsumer: ReactiveNode|null): void {\n setActiveConsumer(prevConsumer);\n\n if (!node || node.producerNode === undefined || node.producerIndexOfThis === undefined ||\n node.producerLastReadVersion === undefined) {\n return;\n }\n\n if (consumerIsLive(node)) {\n // For live consumers, we need to remove the producer -> consumer edge for any stale producers\n // which weren't dependencies after the recomputation.\n for (let i = node.nextProducerIndex; i < node.producerNode.length; i++) {\n producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);\n }\n }\n\n // Truncate the producer tracking arrays.\n // Perf note: this is essentially truncating the length to `node.nextProducerIndex`, but\n // benchmarking has shown that individual pop operations are faster.\n while (node.producerNode.length > node.nextProducerIndex) {\n node.producerNode.pop();\n node.producerLastReadVersion.pop();\n node.producerIndexOfThis.pop();\n }\n}\n\n/**\n * Determine whether this consumer has any dependencies which have changed since the last time\n * they were read.\n */\nexport function consumerPollProducersForChange(node: ReactiveNode): boolean {\n assertConsumerNode(node);\n\n // Poll producers for change.\n for (let i = 0; i < node.producerNode.length; i++) {\n const producer = node.producerNode[i];\n const seenVersion = node.producerLastReadVersion[i];\n\n // First check the versions. A mismatch means that the producer's value is known to have\n // changed since the last time we read it.\n if (seenVersion !== producer.version) {\n return true;\n }\n\n // The producer's version is the same as the last time we read it, but it might itself be\n // stale. Force the producer to recompute its version (calculating a new value if necessary).\n producerUpdateValueVersion(producer);\n\n // Now when we do this check, `producer.version` is guaranteed to be up to date, so if the\n // versions still match then it has not changed since the last time we read it.\n if (seenVersion !== producer.version) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Disconnect this consumer from the graph.\n */\nexport function consumerDestroy(node: ReactiveNode): void {\n assertConsumerNode(node);\n if (consumerIsLive(node)) {\n // Drop all connections from the graph to this node.\n for (let i = 0; i < node.producerNode.length; i++) {\n producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);\n }\n }\n\n // Truncate all the arrays to drop all connection from this node to the graph.\n node.producerNode.length = node.producerLastReadVersion.length = node.producerIndexOfThis.length =\n 0;\n if (node.liveConsumerNode) {\n node.liveConsumerNode.length = node.liveConsumerIndexOfThis!.length = 0;\n }\n}\n\n/**\n * Add `consumer` as a live consumer of this node.\n *\n * Note that this operation is potentially transitive. If this node becomes live, then it becomes\n * a live consumer of all of its current producers.\n */\nfunction producerAddLiveConsumer(\n node: ReactiveNode, consumer: ReactiveNode, indexOfThis: number): number {\n assertProducerNode(node);\n assertConsumerNode(node);\n if (node.liveConsumerNode.length === 0) {\n // When going from 0 to 1 live consumers, we become a live consumer to our producers.\n for (let i = 0; i < node.producerNode.length; i++) {\n node.producerIndexOfThis[i] = producerAddLiveConsumer(node.producerNode[i], node, i);\n }\n }\n node.liveConsumerIndexOfThis.push(indexOfThis);\n return node.liveConsumerNode.push(consumer) - 1;\n}\n\n/**\n * Remove the live consumer at `idx`.\n */\nfunction producerRemoveLiveConsumerAtIndex(node: ReactiveNode, idx: number): void {\n assertProducerNode(node);\n assertConsumerNode(node);\n\n if (typeof ngDevMode !== 'undefined' && ngDevMode && idx >= node.liveConsumerNode.length) {\n throw new Error(`Assertion error: active consumer index ${idx} is out of bounds of ${\n node.liveConsumerNode.length} consumers)`);\n }\n\n if (node.liveConsumerNode.length === 1) {\n // When removing the last live consumer, we will no longer be live. We need to remove\n // ourselves from our producers' tracking (which may cause consumer-producers to lose\n // liveness as well).\n for (let i = 0; i < node.producerNode.length; i++) {\n producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);\n }\n }\n\n // Move the last value of `liveConsumers` into `idx`. Note that if there's only a single\n // live consumer, this is a no-op.\n const lastIdx = node.liveConsumerNode.length - 1;\n node.liveConsumerNode[idx] = node.liveConsumerNode[lastIdx];\n node.liveConsumerIndexOfThis[idx] = node.liveConsumerIndexOfThis[lastIdx];\n\n // Truncate the array.\n node.liveConsumerNode.length--;\n node.liveConsumerIndexOfThis.length--;\n\n // If the index is still valid, then we need to fix the index pointer from the producer to this\n // consumer, and update it from `lastIdx` to `idx` (accounting for the move above).\n if (idx < node.liveConsumerNode.length) {\n const idxProducer = node.liveConsumerIndexOfThis[idx];\n const consumer = node.liveConsumerNode[idx];\n assertConsumerNode(consumer);\n consumer.producerIndexOfThis[idxProducer] = idx;\n }\n}\n\nfunction consumerIsLive(node: ReactiveNode): boolean {\n return node.consumerIsAlwaysLive || (node?.liveConsumerNode?.length ?? 0) > 0;\n}\n\n\nfunction assertConsumerNode(node: ReactiveNode): asserts node is ConsumerNode {\n node.producerNode ??= [];\n node.producerIndexOfThis ??= [];\n node.producerLastReadVersion ??= [];\n}\n\nfunction assertProducerNode(node: ReactiveNode): asserts node is ProducerNode {\n node.liveConsumerNode ??= [];\n node.liveConsumerIndexOfThis ??= [];\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {defaultEquals, SIGNAL, Signal, ValueEqualityFn} from './api';\nimport {consumerAfterComputation, consumerBeforeComputation, producerAccessed, producerUpdateValueVersion, REACTIVE_NODE, ReactiveNode} from './graph';\n\n/**\n * Options passed to the `computed` creation function.\n *\n * @developerPreview\n */\nexport interface CreateComputedOptions {\n /**\n * A comparison function which defines equality for computed values.\n */\n equal?: ValueEqualityFn;\n}\n\n/**\n * Create a computed `Signal` which derives a reactive value from an expression.\n *\n * @developerPreview\n */\nexport function computed(computation: () => T, options?: CreateComputedOptions): Signal {\n const node: ComputedNode = Object.create(COMPUTED_NODE);\n node.computation = computation;\n options?.equal && (node.equal = options.equal);\n\n const computed = () => {\n // Check if the value needs updating before returning it.\n producerUpdateValueVersion(node);\n\n // Record that someone looked at this signal.\n producerAccessed(node);\n\n if (node.value === ERRORED) {\n throw node.error;\n }\n\n return node.value;\n };\n (computed as any)[SIGNAL] = node;\n return computed as any as Signal;\n}\n\n\n/**\n * A dedicated symbol used before a computed value has been calculated for the first time.\n * Explicitly typed as `any` so we can use it as signal's value.\n */\nconst UNSET: any = /* @__PURE__ */ Symbol('UNSET');\n\n/**\n * A dedicated symbol used in place of a computed signal value to indicate that a given computation\n * is in progress. Used to detect cycles in computation chains.\n * Explicitly typed as `any` so we can use it as signal's value.\n */\nconst COMPUTING: any = /* @__PURE__ */ Symbol('COMPUTING');\n\n/**\n * A dedicated symbol used in place of a computed signal value to indicate that a given computation\n * failed. The thrown error is cached until the computation gets dirty again.\n * Explicitly typed as `any` so we can use it as signal's value.\n */\nconst ERRORED: any = /* @__PURE__ */ Symbol('ERRORED');\n\n/**\n * A computation, which derives a value from a declarative reactive expression.\n *\n * `Computed`s are both producers and consumers of reactivity.\n */\ninterface ComputedNode extends ReactiveNode {\n /**\n * Current value of the computation, or one of the sentinel values above (`UNSET`, `COMPUTING`,\n * `ERROR`).\n */\n value: T;\n\n /**\n * If `value` is `ERRORED`, the error caught from the last computation attempt which will\n * be re-thrown.\n */\n error: unknown;\n\n /**\n * The computation function which will produce a new value.\n */\n computation: () => T;\n\n equal: ValueEqualityFn;\n}\n\n// Note: Using an IIFE here to ensure that the spread assignment is not considered\n// a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`.\n// TODO: remove when https://github.com/evanw/esbuild/issues/3392 is resolved.\nconst COMPUTED_NODE = /* @__PURE__ */ (() => {\n return {\n ...REACTIVE_NODE,\n value: UNSET,\n dirty: true,\n error: null,\n equal: defaultEquals,\n\n producerMustRecompute(node: ComputedNode): boolean {\n // Force a recomputation if there's no current value, or if the current value is in the\n // process of being calculated (which should throw an error).\n return node.value === UNSET || node.value === COMPUTING;\n },\n\n producerRecomputeValue(node: ComputedNode): void {\n if (node.value === COMPUTING) {\n // Our computation somehow led to a cyclic read of itself.\n throw new Error('Detected cycle in computations.');\n }\n\n const oldValue = node.value;\n node.value = COMPUTING;\n\n const prevConsumer = consumerBeforeComputation(node);\n let newValue: unknown;\n try {\n newValue = node.computation();\n } catch (err) {\n newValue = ERRORED;\n node.error = err;\n } finally {\n consumerAfterComputation(node, prevConsumer);\n }\n\n if (oldValue !== UNSET && oldValue !== ERRORED && newValue !== ERRORED &&\n node.equal(oldValue, newValue)) {\n // No change to `valueVersion` - old and new values are\n // semantically equivalent.\n node.value = oldValue;\n return;\n }\n\n node.value = newValue;\n node.version++;\n },\n };\n})();\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nfunction defaultThrowError(): never {\n throw new Error();\n}\n\nlet throwInvalidWriteToSignalErrorFn = defaultThrowError;\n\nexport function throwInvalidWriteToSignalError() {\n throwInvalidWriteToSignalErrorFn();\n}\n\nexport function setThrowInvalidWriteToSignalError(fn: () => never): void {\n throwInvalidWriteToSignalErrorFn = fn;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {defaultEquals, SIGNAL, Signal, ValueEqualityFn} from './api';\nimport {throwInvalidWriteToSignalError} from './errors';\nimport {producerAccessed, producerNotifyConsumers, producerUpdatesAllowed, REACTIVE_NODE, ReactiveNode,} from './graph';\n\n/**\n * If set, called after `WritableSignal`s are updated.\n *\n * This hook can be used to achieve various effects, such as running effects synchronously as part\n * of setting a signal.\n */\nlet postSignalSetFn: (() => void)|null = null;\n\n/**\n * A `Signal` with a value that can be mutated via a setter interface.\n *\n * @developerPreview\n */\nexport interface WritableSignal extends Signal {\n /**\n * Directly set the signal to a new value, and notify any dependents.\n */\n set(value: T): void;\n\n /**\n * Update the value of the signal based on its current value, and\n * notify any dependents.\n */\n update(updateFn: (value: T) => T): void;\n\n /**\n * Update the current value by mutating it in-place, and\n * notify any dependents.\n */\n mutate(mutatorFn: (value: T) => void): void;\n\n /**\n * Returns a readonly version of this signal. Readonly signals can be accessed to read their value\n * but can't be changed using set, update or mutate methods. The readonly signals do _not_ have\n * any built-in mechanism that would prevent deep-mutation of their value.\n */\n asReadonly(): Signal;\n}\n\n/**\n * Options passed to the `signal` creation function.\n *\n * @developerPreview\n */\nexport interface CreateSignalOptions {\n /**\n * A comparison function which defines equality for signal values.\n */\n equal?: ValueEqualityFn;\n}\n\n\n/**\n * Create a `Signal` that can be set or updated directly.\n *\n * @developerPreview\n */\nexport function signal(initialValue: T, options?: CreateSignalOptions): WritableSignal {\n const node: SignalNode = Object.create(SIGNAL_NODE);\n node.value = initialValue;\n options?.equal && (node.equal = options.equal);\n\n function signalFn() {\n producerAccessed(node);\n return node.value;\n }\n\n signalFn.set = signalSetFn;\n signalFn.update = signalUpdateFn;\n signalFn.mutate = signalMutateFn;\n signalFn.asReadonly = signalAsReadonlyFn;\n (signalFn as any)[SIGNAL] = node;\n\n return signalFn as WritableSignal;\n}\n\nexport function setPostSignalSetFn(fn: (() => void)|null): (() => void)|null {\n const prev = postSignalSetFn;\n postSignalSetFn = fn;\n return prev;\n}\n\ninterface SignalNode extends ReactiveNode {\n value: T;\n equal: ValueEqualityFn;\n readonlyFn: Signal|null;\n}\n\ninterface SignalFn extends Signal {\n [SIGNAL]: SignalNode;\n}\n\n// Note: Using an IIFE here to ensure that the spread assignment is not considered\n// a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`.\n// TODO: remove when https://github.com/evanw/esbuild/issues/3392 is resolved.\nconst SIGNAL_NODE = /* @__PURE__ */ (() => {\n return {\n ...REACTIVE_NODE,\n equal: defaultEquals,\n readonlyFn: undefined,\n };\n})();\n\nfunction signalValueChanged(node: SignalNode): void {\n node.version++;\n producerNotifyConsumers(node);\n\n postSignalSetFn?.();\n}\n\nfunction signalSetFn(this: SignalFn, newValue: T) {\n const node = this[SIGNAL];\n if (!producerUpdatesAllowed()) {\n throwInvalidWriteToSignalError();\n }\n\n if (!node.equal(node.value, newValue)) {\n node.value = newValue;\n signalValueChanged(node);\n }\n}\n\nfunction signalUpdateFn(this: SignalFn, updater: (value: T) => T): void {\n if (!producerUpdatesAllowed()) {\n throwInvalidWriteToSignalError();\n }\n\n signalSetFn.call(this as any, updater(this[SIGNAL].value) as any);\n}\n\nfunction signalMutateFn(this: SignalFn, mutator: (value: T) => void): void {\n const node = this[SIGNAL];\n if (!producerUpdatesAllowed()) {\n throwInvalidWriteToSignalError();\n }\n // Mutate bypasses equality checks as it's by definition changing the value.\n mutator(node.value);\n signalValueChanged(node);\n}\n\nfunction signalAsReadonlyFn(this: SignalFn) {\n const node = this[SIGNAL];\n if (node.readonlyFn === undefined) {\n const readonlyFn = () => this();\n (readonlyFn as any)[SIGNAL] = node;\n node.readonlyFn = readonlyFn as Signal;\n }\n return node.readonlyFn;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {setActiveConsumer} from './graph';\n\n/**\n * Execute an arbitrary function in a non-reactive (non-tracking) context. The executed function\n * can, optionally, return a value.\n *\n * @developerPreview\n */\nexport function untracked(nonReactiveReadsFn: () => T): T {\n const prevConsumer = setActiveConsumer(null);\n // We are not trying to catch any particular errors here, just making sure that the consumers\n // stack is restored in case of errors.\n try {\n return nonReactiveReadsFn();\n } finally {\n setActiveConsumer(prevConsumer);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {consumerAfterComputation, consumerBeforeComputation, consumerMarkDirty, consumerPollProducersForChange, REACTIVE_NODE, ReactiveNode} from './graph';\n\n/**\n * A cleanup function that can be optionally registered from the watch logic. If registered, the\n * cleanup logic runs before the next watch execution.\n */\nexport type WatchCleanupFn = () => void;\n\n/**\n * A callback passed to the watch function that makes it possible to register cleanup logic.\n */\nexport type WatchCleanupRegisterFn = (cleanupFn: WatchCleanupFn) => void;\n\nexport interface Watch {\n notify(): void;\n\n /**\n * Execute the reactive expression in the context of this `Watch` consumer.\n *\n * Should be called by the user scheduling algorithm when the provided\n * `schedule` hook is called by `Watch`.\n */\n run(): void;\n cleanup(): void;\n}\n\nexport function watch(\n fn: (onCleanup: WatchCleanupRegisterFn) => void, schedule: (watch: Watch) => void,\n allowSignalWrites: boolean): Watch {\n const node: WatchNode = Object.create(WATCH_NODE);\n if (allowSignalWrites) {\n node.consumerAllowSignalWrites = true;\n }\n\n node.fn = fn;\n node.schedule = schedule;\n\n const registerOnCleanup = (cleanupFn: WatchCleanupFn) => {\n node.cleanupFn = cleanupFn;\n };\n\n const run = () => {\n node.dirty = false;\n if (node.hasRun && !consumerPollProducersForChange(node)) {\n return;\n }\n node.hasRun = true;\n\n const prevConsumer = consumerBeforeComputation(node);\n try {\n node.cleanupFn();\n node.cleanupFn = NOOP_CLEANUP_FN;\n node.fn(registerOnCleanup);\n } finally {\n consumerAfterComputation(node, prevConsumer);\n }\n };\n\n node.ref = {\n notify: () => consumerMarkDirty(node),\n run,\n cleanup: () => node.cleanupFn(),\n };\n\n return node.ref;\n}\n\nconst NOOP_CLEANUP_FN: WatchCleanupFn = () => {};\n\ninterface WatchNode extends ReactiveNode {\n hasRun: boolean;\n fn: (onCleanup: WatchCleanupRegisterFn) => void;\n schedule: (watch: Watch) => void;\n cleanupFn: WatchCleanupFn;\n ref: Watch;\n}\n\n// Note: Using an IIFE here to ensure that the spread assignment is not considered\n// a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`.\n// TODO: remove when https://github.com/evanw/esbuild/issues/3392 is resolved.\nconst WATCH_NODE: Partial = /* @__PURE__ */ (() => {\n return {\n ...REACTIVE_NODE,\n consumerIsAlwaysLive: true,\n consumerAllowSignalWrites: false,\n consumerMarkedDirty: (node: WatchNode) => {\n node.schedule(node.ref);\n },\n hasRun: false,\n cleanupFn: NOOP_CLEANUP_FN,\n };\n})();\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nexport function setAlternateWeakRefImpl(impl: unknown) {\n // TODO: remove this function\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Represents a basic change from a previous to a new value for a single\n * property on a directive instance. Passed as a value in a\n * {@link SimpleChanges} object to the `ngOnChanges` hook.\n *\n * @see {@link OnChanges}\n *\n * @publicApi\n */\nexport class SimpleChange {\n constructor(public previousValue: any, public currentValue: any, public firstChange: boolean) {}\n /**\n * Check whether the new value is the first value assigned.\n */\n isFirstChange(): boolean {\n return this.firstChange;\n }\n}\n\n/**\n * A hashtable of changes represented by {@link SimpleChange} objects stored\n * at the declared property name they belong to on a Directive or Component. This is\n * the type passed to the `ngOnChanges` hook.\n *\n * @see {@link OnChanges}\n *\n * @publicApi\n */\nexport interface SimpleChanges {\n [propName: string]: SimpleChange;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {OnChanges} from '../../interface/lifecycle_hooks';\nimport {SimpleChange, SimpleChanges} from '../../interface/simple_change';\nimport {assertString} from '../../util/assert';\nimport {EMPTY_OBJ} from '../../util/empty';\nimport {DirectiveDef, DirectiveDefFeature} from '../interfaces/definition';\n\n/**\n * The NgOnChangesFeature decorates a component with support for the ngOnChanges\n * lifecycle hook, so it should be included in any component that implements\n * that hook.\n *\n * If the component or directive uses inheritance, the NgOnChangesFeature MUST\n * be included as a feature AFTER {@link InheritDefinitionFeature}, otherwise\n * inherited properties will not be propagated to the ngOnChanges lifecycle\n * hook.\n *\n * Example usage:\n *\n * ```\n * static ɵcmp = defineComponent({\n * ...\n * inputs: {name: 'publicName'},\n * features: [NgOnChangesFeature]\n * });\n * ```\n *\n * @codeGenApi\n */\nexport function ɵɵNgOnChangesFeature(): DirectiveDefFeature {\n return NgOnChangesFeatureImpl;\n}\n\nexport function NgOnChangesFeatureImpl(definition: DirectiveDef) {\n if (definition.type.prototype.ngOnChanges) {\n definition.setInput = ngOnChangesSetInput;\n }\n return rememberChangeHistoryAndInvokeOnChangesHook;\n}\n\n// This option ensures that the ngOnChanges lifecycle hook will be inherited\n// from superclasses (in InheritDefinitionFeature).\n/** @nocollapse */\n// tslint:disable-next-line:no-toplevel-property-access\n(ɵɵNgOnChangesFeature as DirectiveDefFeature).ngInherit = true;\n\n/**\n * This is a synthetic lifecycle hook which gets inserted into `TView.preOrderHooks` to simulate\n * `ngOnChanges`.\n *\n * The hook reads the `NgSimpleChangesStore` data from the component instance and if changes are\n * found it invokes `ngOnChanges` on the component instance.\n *\n * @param this Component instance. Because this function gets inserted into `TView.preOrderHooks`,\n * it is guaranteed to be called with component instance.\n */\nfunction rememberChangeHistoryAndInvokeOnChangesHook(this: OnChanges) {\n const simpleChangesStore = getSimpleChangesStore(this);\n const current = simpleChangesStore?.current;\n\n if (current) {\n const previous = simpleChangesStore!.previous;\n if (previous === EMPTY_OBJ) {\n simpleChangesStore!.previous = current;\n } else {\n // New changes are copied to the previous store, so that we don't lose history for inputs\n // which were not changed this time\n for (let key in current) {\n previous[key] = current[key];\n }\n }\n simpleChangesStore!.current = null;\n this.ngOnChanges(current);\n }\n}\n\n\nfunction ngOnChangesSetInput(\n this: DirectiveDef, instance: T, value: any, publicName: string, privateName: string): void {\n const declaredName = (this.declaredInputs as {[key: string]: string})[publicName];\n ngDevMode && assertString(declaredName, 'Name of input in ngOnChanges has to be a string');\n const simpleChangesStore = getSimpleChangesStore(instance) ||\n setSimpleChangesStore(instance, {previous: EMPTY_OBJ, current: null});\n const current = simpleChangesStore.current || (simpleChangesStore.current = {});\n const previous = simpleChangesStore.previous;\n const previousChange = previous[declaredName];\n current[declaredName] = new SimpleChange(\n previousChange && previousChange.currentValue, value, previous === EMPTY_OBJ);\n\n (instance as any)[privateName] = value;\n}\n\nconst SIMPLE_CHANGES_STORE = '__ngSimpleChanges__';\n\nfunction getSimpleChangesStore(instance: any): null|NgSimpleChangesStore {\n return instance[SIMPLE_CHANGES_STORE] || null;\n}\n\nfunction setSimpleChangesStore(instance: any, store: NgSimpleChangesStore): NgSimpleChangesStore {\n return instance[SIMPLE_CHANGES_STORE] = store;\n}\n\n/**\n * Data structure which is monkey-patched on the component instance and used by `ngOnChanges`\n * life-cycle hook to track previous input values.\n */\ninterface NgSimpleChangesStore {\n previous: SimpleChanges;\n current: SimpleChanges|null;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Profiler events is an enum used by the profiler to distinguish between different calls of user\n * code invoked throughout the application lifecycle.\n */\nexport const enum ProfilerEvent {\n /**\n * Corresponds to the point in time before the runtime has called the template function of a\n * component with `RenderFlags.Create`.\n */\n TemplateCreateStart,\n\n /**\n * Corresponds to the point in time after the runtime has called the template function of a\n * component with `RenderFlags.Create`.\n */\n TemplateCreateEnd,\n\n /**\n * Corresponds to the point in time before the runtime has called the template function of a\n * component with `RenderFlags.Update`.\n */\n TemplateUpdateStart,\n\n /**\n * Corresponds to the point in time after the runtime has called the template function of a\n * component with `RenderFlags.Update`.\n */\n TemplateUpdateEnd,\n\n /**\n * Corresponds to the point in time before the runtime has called a lifecycle hook of a component\n * or directive.\n */\n LifecycleHookStart,\n\n /**\n * Corresponds to the point in time after the runtime has called a lifecycle hook of a component\n * or directive.\n */\n LifecycleHookEnd,\n\n /**\n * Corresponds to the point in time before the runtime has evaluated an expression associated with\n * an event or an output.\n */\n OutputStart,\n\n /**\n * Corresponds to the point in time after the runtime has evaluated an expression associated with\n * an event or an output.\n */\n OutputEnd,\n}\n\n/**\n * Profiler function which the runtime will invoke before and after user code.\n */\nexport interface Profiler {\n (event: ProfilerEvent, instance: {}|null, hookOrListener?: (e?: any) => any): void;\n}\n\n\nlet profilerCallback: Profiler|null = null;\n\n/**\n * Sets the callback function which will be invoked before and after performing certain actions at\n * runtime (for example, before and after running change detection).\n *\n * Warning: this function is *INTERNAL* and should not be relied upon in application's code.\n * The contract of the function might be changed in any release and/or the function can be removed\n * completely.\n *\n * @param profiler function provided by the caller or null value to disable profiling.\n */\nexport const setProfiler = (profiler: Profiler|null) => {\n profilerCallback = profiler;\n};\n\n/**\n * Profiler function which wraps user code executed by the runtime.\n *\n * @param event ProfilerEvent corresponding to the execution context\n * @param instance component instance\n * @param hookOrListener lifecycle hook function or output listener. The value depends on the\n * execution context\n * @returns\n */\nexport const profiler: Profiler = function(\n event: ProfilerEvent, instance: {}|null, hookOrListener?: (e?: any) => any) {\n if (profilerCallback != null /* both `null` and `undefined` */) {\n profilerCallback(event, instance, hookOrListener);\n }\n};\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nexport const SVG_NAMESPACE = 'svg';\nexport const MATH_ML_NAMESPACE = 'math';\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {RuntimeError, RuntimeErrorCode} from '../../errors';\nimport {assertGreaterThan, assertGreaterThanOrEqual, assertIndexInRange, assertLessThan} from '../../util/assert';\nimport {assertTNode, assertTNodeForLView} from '../assert';\nimport {LContainer, TYPE} from '../interfaces/container';\nimport {TConstants, TNode} from '../interfaces/node';\nimport {RNode} from '../interfaces/renderer_dom';\nimport {isLContainer, isLView} from '../interfaces/type_checks';\nimport {DESCENDANT_VIEWS_TO_REFRESH, FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, ON_DESTROY_HOOKS, PARENT, PREORDER_HOOK_FLAGS, PreOrderHookFlags, TData, TView} from '../interfaces/view';\n\n\n\n/**\n * For efficiency reasons we often put several different data types (`RNode`, `LView`, `LContainer`)\n * in same location in `LView`. This is because we don't want to pre-allocate space for it\n * because the storage is sparse. This file contains utilities for dealing with such data types.\n *\n * How do we know what is stored at a given location in `LView`.\n * - `Array.isArray(value) === false` => `RNode` (The normal storage value)\n * - `Array.isArray(value) === true` => then the `value[0]` represents the wrapped value.\n * - `typeof value[TYPE] === 'object'` => `LView`\n * - This happens when we have a component at a given location\n * - `typeof value[TYPE] === true` => `LContainer`\n * - This happens when we have `LContainer` binding at a given location.\n *\n *\n * NOTE: it is assumed that `Array.isArray` and `typeof` operations are very efficient.\n */\n\n/**\n * Returns `RNode`.\n * @param value wrapped value of `RNode`, `LView`, `LContainer`\n */\nexport function unwrapRNode(value: RNode|LView|LContainer): RNode {\n while (Array.isArray(value)) {\n value = value[HOST] as any;\n }\n return value as RNode;\n}\n\n/**\n * Returns `LView` or `null` if not found.\n * @param value wrapped value of `RNode`, `LView`, `LContainer`\n */\nexport function unwrapLView(value: RNode|LView|LContainer): LView|null {\n while (Array.isArray(value)) {\n // This check is same as `isLView()` but we don't call at as we don't want to call\n // `Array.isArray()` twice and give JITer more work for inlining.\n if (typeof value[TYPE] === 'object') return value as LView;\n value = value[HOST] as any;\n }\n return null;\n}\n\n/**\n * Retrieves an element value from the provided `viewData`, by unwrapping\n * from any containers, component views, or style contexts.\n */\nexport function getNativeByIndex(index: number, lView: LView): RNode {\n ngDevMode && assertIndexInRange(lView, index);\n ngDevMode && assertGreaterThanOrEqual(index, HEADER_OFFSET, 'Expected to be past HEADER_OFFSET');\n return unwrapRNode(lView[index]);\n}\n\n/**\n * Retrieve an `RNode` for a given `TNode` and `LView`.\n *\n * This function guarantees in dev mode to retrieve a non-null `RNode`.\n *\n * @param tNode\n * @param lView\n */\nexport function getNativeByTNode(tNode: TNode, lView: LView): RNode {\n ngDevMode && assertTNodeForLView(tNode, lView);\n ngDevMode && assertIndexInRange(lView, tNode.index);\n const node: RNode = unwrapRNode(lView[tNode.index]);\n return node;\n}\n\n/**\n * Retrieve an `RNode` or `null` for a given `TNode` and `LView`.\n *\n * Some `TNode`s don't have associated `RNode`s. For example `Projection`\n *\n * @param tNode\n * @param lView\n */\nexport function getNativeByTNodeOrNull(tNode: TNode|null, lView: LView): RNode|null {\n const index = tNode === null ? -1 : tNode.index;\n if (index !== -1) {\n ngDevMode && assertTNodeForLView(tNode!, lView);\n const node: RNode|null = unwrapRNode(lView[index]);\n return node;\n }\n return null;\n}\n\n\n// fixme(misko): The return Type should be `TNode|null`\nexport function getTNode(tView: TView, index: number): TNode {\n ngDevMode && assertGreaterThan(index, -1, 'wrong index for TNode');\n ngDevMode && assertLessThan(index, tView.data.length, 'wrong index for TNode');\n const tNode = tView.data[index] as TNode;\n ngDevMode && tNode !== null && assertTNode(tNode);\n return tNode;\n}\n\n/** Retrieves a value from any `LView` or `TData`. */\nexport function load(view: LView|TData, index: number): T {\n ngDevMode && assertIndexInRange(view, index);\n return view[index];\n}\n\nexport function getComponentLViewByIndex(nodeIndex: number, hostView: LView): LView {\n // Could be an LView or an LContainer. If LContainer, unwrap to find LView.\n ngDevMode && assertIndexInRange(hostView, nodeIndex);\n const slotValue = hostView[nodeIndex];\n const lView = isLView(slotValue) ? slotValue : slotValue[HOST];\n return lView;\n}\n\n/** Checks whether a given view is in creation mode */\nexport function isCreationMode(view: LView): boolean {\n return (view[FLAGS] & LViewFlags.CreationMode) === LViewFlags.CreationMode;\n}\n\n/**\n * Returns a boolean for whether the view is attached to the change detection tree.\n *\n * Note: This determines whether a view should be checked, not whether it's inserted\n * into a container. For that, you'll want `viewAttachedToContainer` below.\n */\nexport function viewAttachedToChangeDetector(view: LView): boolean {\n return (view[FLAGS] & LViewFlags.Attached) === LViewFlags.Attached;\n}\n\n/** Returns a boolean for whether the view is attached to a container. */\nexport function viewAttachedToContainer(view: LView): boolean {\n return isLContainer(view[PARENT]);\n}\n\n/** Returns a constant from `TConstants` instance. */\nexport function getConstant(consts: TConstants|null, index: null|undefined): null;\nexport function getConstant(consts: TConstants, index: number): T|null;\nexport function getConstant(consts: TConstants|null, index: number|null|undefined): T|null;\nexport function getConstant(consts: TConstants|null, index: number|null|undefined): T|null {\n if (index === null || index === undefined) return null;\n ngDevMode && assertIndexInRange(consts!, index);\n return consts![index] as unknown as T;\n}\n\n/**\n * Resets the pre-order hook flags of the view.\n * @param lView the LView on which the flags are reset\n */\nexport function resetPreOrderHookFlags(lView: LView) {\n lView[PREORDER_HOOK_FLAGS] = 0 as PreOrderHookFlags;\n}\n\n/**\n * Adds the `RefreshView` flag from the lView and updates DESCENDANT_VIEWS_TO_REFRESH counters of\n * parents.\n */\nexport function markViewForRefresh(lView: LView) {\n if ((lView[FLAGS] & LViewFlags.RefreshView) === 0) {\n lView[FLAGS] |= LViewFlags.RefreshView;\n updateViewsToRefresh(lView, 1);\n }\n}\n\n/**\n * Removes the `RefreshView` flag from the lView and updates DESCENDANT_VIEWS_TO_REFRESH counters of\n * parents.\n */\nexport function clearViewRefreshFlag(lView: LView) {\n if (lView[FLAGS] & LViewFlags.RefreshView) {\n lView[FLAGS] &= ~LViewFlags.RefreshView;\n updateViewsToRefresh(lView, -1);\n }\n}\n\n/**\n * Updates the `DESCENDANT_VIEWS_TO_REFRESH` counter on the parents of the `LView` as well as the\n * parents above that whose\n * 1. counter goes from 0 to 1, indicating that there is a new child that has a view to refresh\n * or\n * 2. counter goes from 1 to 0, indicating there are no more descendant views to refresh\n */\nfunction updateViewsToRefresh(lView: LView, amount: 1|- 1) {\n let parent: LView|LContainer|null = lView[PARENT];\n if (parent === null) {\n return;\n }\n parent[DESCENDANT_VIEWS_TO_REFRESH] += amount;\n let viewOrContainer: LView|LContainer = parent;\n parent = parent[PARENT];\n while (parent !== null &&\n ((amount === 1 && viewOrContainer[DESCENDANT_VIEWS_TO_REFRESH] === 1) ||\n (amount === -1 && viewOrContainer[DESCENDANT_VIEWS_TO_REFRESH] === 0))) {\n parent[DESCENDANT_VIEWS_TO_REFRESH] += amount;\n viewOrContainer = parent;\n parent = parent[PARENT];\n }\n}\n\n/**\n * Stores a LView-specific destroy callback.\n */\nexport function storeLViewOnDestroy(lView: LView, onDestroyCallback: () => void) {\n if ((lView[FLAGS] & LViewFlags.Destroyed) === LViewFlags.Destroyed) {\n throw new RuntimeError(\n RuntimeErrorCode.VIEW_ALREADY_DESTROYED, ngDevMode && 'View has already been destroyed.');\n }\n if (lView[ON_DESTROY_HOOKS] === null) {\n lView[ON_DESTROY_HOOKS] = [];\n }\n lView[ON_DESTROY_HOOKS].push(onDestroyCallback);\n}\n\n/**\n * Removes previously registered LView-specific destroy callback.\n */\nexport function removeLViewOnDestroy(lView: LView, onDestroyCallback: () => void) {\n if (lView[ON_DESTROY_HOOKS] === null) return;\n\n const destroyCBIdx = lView[ON_DESTROY_HOOKS].indexOf(onDestroyCallback);\n if (destroyCBIdx !== -1) {\n lView[ON_DESTROY_HOOKS].splice(destroyCBIdx, 1);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {InjectFlags} from '../di/interface/injector';\nimport {assertDefined, assertEqual, assertGreaterThanOrEqual, assertLessThan, assertNotEqual, throwError} from '../util/assert';\n\nimport {assertLViewOrUndefined, assertTNodeForLView, assertTNodeForTView} from './assert';\nimport {DirectiveDef} from './interfaces/definition';\nimport {TNode, TNodeType} from './interfaces/node';\nimport {CONTEXT, DECLARATION_VIEW, HEADER_OFFSET, LView, OpaqueViewState, T_HOST, TData, TVIEW, TView, TViewType} from './interfaces/view';\nimport {MATH_ML_NAMESPACE, SVG_NAMESPACE} from './namespaces';\nimport {getTNode} from './util/view_utils';\n\n\n/**\n *\n */\ninterface LFrame {\n /**\n * Parent LFrame.\n *\n * This is needed when `leaveView` is called to restore the previous state.\n */\n parent: LFrame;\n\n /**\n * Child LFrame.\n *\n * This is used to cache existing LFrames to relieve the memory pressure.\n */\n child: LFrame|null;\n\n /**\n * State of the current view being processed.\n *\n * An array of nodes (text, element, container, etc), pipes, their bindings, and\n * any local variables that need to be stored between invocations.\n */\n lView: LView;\n\n /**\n * Current `TView` associated with the `LFrame.lView`.\n *\n * One can get `TView` from `lFrame[TVIEW]` however because it is so common it makes sense to\n * store it in `LFrame` for perf reasons.\n */\n tView: TView;\n\n /**\n * Used to set the parent property when nodes are created and track query results.\n *\n * This is used in conjunction with `isParent`.\n */\n currentTNode: TNode|null;\n\n /**\n * If `isParent` is:\n * - `true`: then `currentTNode` points to a parent node.\n * - `false`: then `currentTNode` points to previous node (sibling).\n */\n isParent: boolean;\n\n /**\n * Index of currently selected element in LView.\n *\n * Used by binding instructions. Updated as part of advance instruction.\n */\n selectedIndex: number;\n\n /**\n * Current pointer to the binding index.\n */\n bindingIndex: number;\n\n /**\n * The last viewData retrieved by nextContext().\n * Allows building nextContext() and reference() calls.\n *\n * e.g. const inner = x().$implicit; const outer = x().$implicit;\n */\n contextLView: LView|null;\n\n /**\n * Store the element depth count. This is used to identify the root elements of the template\n * so that we can then attach patch data `LView` to only those elements. We know that those\n * are the only places where the patch data could change, this way we will save on number\n * of places where tha patching occurs.\n */\n elementDepthCount: number;\n\n /**\n * Current namespace to be used when creating elements\n */\n currentNamespace: string|null;\n\n\n /**\n * The root index from which pure function instructions should calculate their binding\n * indices. In component views, this is TView.bindingStartIndex. In a host binding\n * context, this is the TView.expandoStartIndex + any dirs/hostVars before the given dir.\n */\n bindingRootIndex: number;\n\n /**\n * Current index of a View or Content Query which needs to be processed next.\n * We iterate over the list of Queries and increment current query index at every step.\n */\n currentQueryIndex: number;\n\n /**\n * When host binding is executing this points to the directive index.\n * `TView.data[currentDirectiveIndex]` is `DirectiveDef`\n * `LView[currentDirectiveIndex]` is directive instance.\n */\n currentDirectiveIndex: number;\n\n /**\n * Are we currently in i18n block as denoted by `ɵɵelementStart` and `ɵɵelementEnd`.\n *\n * This information is needed because while we are in i18n block all elements must be pre-declared\n * in the translation. (i.e. `Hello �#2�World�/#2�!` pre-declares element at `�#2�` location.)\n * This allocates `TNodeType.Placeholder` element at location `2`. If translator removes `�#2�`\n * from translation than the runtime must also ensure tha element at `2` does not get inserted\n * into the DOM. The translation does not carry information about deleted elements. Therefor the\n * only way to know that an element is deleted is that it was not pre-declared in the translation.\n *\n * This flag works by ensuring that elements which are created without pre-declaration\n * (`TNodeType.Placeholder`) are not inserted into the DOM render tree. (It does mean that the\n * element still gets instantiated along with all of its behavior [directives])\n */\n inI18n: boolean;\n}\n\n/**\n * All implicit instruction state is stored here.\n *\n * It is useful to have a single object where all of the state is stored as a mental model\n * (rather it being spread across many different variables.)\n *\n * PERF NOTE: Turns out that writing to a true global variable is slower than\n * having an intermediate object with properties.\n */\ninterface InstructionState {\n /**\n * Current `LFrame`\n *\n * `null` if we have not called `enterView`\n */\n lFrame: LFrame;\n\n /**\n * Stores whether directives should be matched to elements.\n *\n * When template contains `ngNonBindable` then we need to prevent the runtime from matching\n * directives on children of that element.\n *\n * Example:\n * ```\n * \n * Should match component / directive.\n * \n *
\n * \n * Should not match component / directive because we are in ngNonBindable.\n * \n *
\n * ```\n */\n bindingsEnabled: boolean;\n\n /**\n * Stores the root TNode that has the 'ngSkipHydration' attribute on it for later reference.\n *\n * Example:\n * ```\n * \n * Should reference this root node\n * \n * ```\n */\n skipHydrationRootTNode: TNode|null;\n}\n\nconst instructionState: InstructionState = {\n lFrame: createLFrame(null),\n bindingsEnabled: true,\n skipHydrationRootTNode: null,\n};\n\n/**\n * In this mode, any changes in bindings will throw an ExpressionChangedAfterChecked error.\n *\n * Necessary to support ChangeDetectorRef.checkNoChanges().\n *\n * The `checkNoChanges` function is invoked only in ngDevMode=true and verifies that no unintended\n * changes exist in the change detector or its children.\n */\nlet _isInCheckNoChangesMode = false;\n\n/**\n * Returns true if the instruction state stack is empty.\n *\n * Intended to be called from tests only (tree shaken otherwise).\n */\nexport function specOnlyIsInstructionStateEmpty(): boolean {\n return instructionState.lFrame.parent === null;\n}\n\n\nexport function getElementDepthCount() {\n return instructionState.lFrame.elementDepthCount;\n}\n\nexport function increaseElementDepthCount() {\n instructionState.lFrame.elementDepthCount++;\n}\n\nexport function decreaseElementDepthCount() {\n instructionState.lFrame.elementDepthCount--;\n}\n\nexport function getBindingsEnabled(): boolean {\n return instructionState.bindingsEnabled;\n}\n\n/**\n * Returns true if currently inside a skip hydration block.\n * @returns boolean\n */\nexport function isInSkipHydrationBlock(): boolean {\n return instructionState.skipHydrationRootTNode !== null;\n}\n\n/**\n * Returns true if this is the root TNode of the skip hydration block.\n * @param tNode the current TNode\n * @returns boolean\n */\nexport function isSkipHydrationRootTNode(tNode: TNode): boolean {\n return instructionState.skipHydrationRootTNode === tNode;\n}\n\n/**\n * Enables directive matching on elements.\n *\n * * Example:\n * ```\n * \n * Should match component / directive.\n * \n *
\n * \n * \n * Should not match component / directive because we are in ngNonBindable.\n * \n * \n *
\n * ```\n *\n * @codeGenApi\n */\nexport function ɵɵenableBindings(): void {\n instructionState.bindingsEnabled = true;\n}\n\n/**\n * Sets a flag to specify that the TNode is in a skip hydration block.\n * @param tNode the current TNode\n */\nexport function enterSkipHydrationBlock(tNode: TNode): void {\n instructionState.skipHydrationRootTNode = tNode;\n}\n\n/**\n * Disables directive matching on element.\n *\n * * Example:\n * ```\n * \n * Should match component / directive.\n * \n *
\n * \n * \n * Should not match component / directive because we are in ngNonBindable.\n * \n * \n *
\n * ```\n *\n * @codeGenApi\n */\nexport function ɵɵdisableBindings(): void {\n instructionState.bindingsEnabled = false;\n}\n\n/**\n * Clears the root skip hydration node when leaving a skip hydration block.\n */\nexport function leaveSkipHydrationBlock(): void {\n instructionState.skipHydrationRootTNode = null;\n}\n\n/**\n * Return the current `LView`.\n */\nexport function getLView(): LView {\n return instructionState.lFrame.lView as LView;\n}\n\n/**\n * Return the current `TView`.\n */\nexport function getTView(): TView {\n return instructionState.lFrame.tView;\n}\n\n/**\n * Restores `contextViewData` to the given OpaqueViewState instance.\n *\n * Used in conjunction with the getCurrentView() instruction to save a snapshot\n * of the current view and restore it when listeners are invoked. This allows\n * walking the declaration view tree in listeners to get vars from parent views.\n *\n * @param viewToRestore The OpaqueViewState instance to restore.\n * @returns Context of the restored OpaqueViewState instance.\n *\n * @codeGenApi\n */\nexport function ɵɵrestoreView(viewToRestore: OpaqueViewState): T {\n instructionState.lFrame.contextLView = viewToRestore as any as LView;\n return (viewToRestore as any as LView)[CONTEXT] as unknown as T;\n}\n\n\n/**\n * Clears the view set in `ɵɵrestoreView` from memory. Returns the passed in\n * value so that it can be used as a return value of an instruction.\n *\n * @codeGenApi\n */\nexport function ɵɵresetView(value?: T): T|undefined {\n instructionState.lFrame.contextLView = null;\n return value;\n}\n\n\nexport function getCurrentTNode(): TNode|null {\n let currentTNode = getCurrentTNodePlaceholderOk();\n while (currentTNode !== null && currentTNode.type === TNodeType.Placeholder) {\n currentTNode = currentTNode.parent;\n }\n return currentTNode;\n}\n\nexport function getCurrentTNodePlaceholderOk(): TNode|null {\n return instructionState.lFrame.currentTNode;\n}\n\nexport function getCurrentParentTNode(): TNode|null {\n const lFrame = instructionState.lFrame;\n const currentTNode = lFrame.currentTNode;\n return lFrame.isParent ? currentTNode : currentTNode!.parent;\n}\n\nexport function setCurrentTNode(tNode: TNode|null, isParent: boolean) {\n ngDevMode && tNode && assertTNodeForTView(tNode, instructionState.lFrame.tView);\n const lFrame = instructionState.lFrame;\n lFrame.currentTNode = tNode;\n lFrame.isParent = isParent;\n}\n\nexport function isCurrentTNodeParent(): boolean {\n return instructionState.lFrame.isParent;\n}\n\nexport function setCurrentTNodeAsNotParent(): void {\n instructionState.lFrame.isParent = false;\n}\n\nexport function getContextLView(): LView {\n const contextLView = instructionState.lFrame.contextLView;\n ngDevMode && assertDefined(contextLView, 'contextLView must be defined.');\n return contextLView!;\n}\n\nexport function isInCheckNoChangesMode(): boolean {\n !ngDevMode && throwError('Must never be called in production mode');\n return _isInCheckNoChangesMode;\n}\n\nexport function setIsInCheckNoChangesMode(mode: boolean): void {\n !ngDevMode && throwError('Must never be called in production mode');\n _isInCheckNoChangesMode = mode;\n}\n\n// top level variables should not be exported for performance reasons (PERF_NOTES.md)\nexport function getBindingRoot() {\n const lFrame = instructionState.lFrame;\n let index = lFrame.bindingRootIndex;\n if (index === -1) {\n index = lFrame.bindingRootIndex = lFrame.tView.bindingStartIndex;\n }\n return index;\n}\n\nexport function getBindingIndex(): number {\n return instructionState.lFrame.bindingIndex;\n}\n\nexport function setBindingIndex(value: number): number {\n return instructionState.lFrame.bindingIndex = value;\n}\n\nexport function nextBindingIndex(): number {\n return instructionState.lFrame.bindingIndex++;\n}\n\nexport function incrementBindingIndex(count: number): number {\n const lFrame = instructionState.lFrame;\n const index = lFrame.bindingIndex;\n lFrame.bindingIndex = lFrame.bindingIndex + count;\n return index;\n}\n\nexport function isInI18nBlock() {\n return instructionState.lFrame.inI18n;\n}\n\nexport function setInI18nBlock(isInI18nBlock: boolean): void {\n instructionState.lFrame.inI18n = isInI18nBlock;\n}\n\n/**\n * Set a new binding root index so that host template functions can execute.\n *\n * Bindings inside the host template are 0 index. But because we don't know ahead of time\n * how many host bindings we have we can't pre-compute them. For this reason they are all\n * 0 index and we just shift the root so that they match next available location in the LView.\n *\n * @param bindingRootIndex Root index for `hostBindings`\n * @param currentDirectiveIndex `TData[currentDirectiveIndex]` will point to the current directive\n * whose `hostBindings` are being processed.\n */\nexport function setBindingRootForHostBindings(\n bindingRootIndex: number, currentDirectiveIndex: number) {\n const lFrame = instructionState.lFrame;\n lFrame.bindingIndex = lFrame.bindingRootIndex = bindingRootIndex;\n setCurrentDirectiveIndex(currentDirectiveIndex);\n}\n\n/**\n * When host binding is executing this points to the directive index.\n * `TView.data[getCurrentDirectiveIndex()]` is `DirectiveDef`\n * `LView[getCurrentDirectiveIndex()]` is directive instance.\n */\nexport function getCurrentDirectiveIndex(): number {\n return instructionState.lFrame.currentDirectiveIndex;\n}\n\n/**\n * Sets an index of a directive whose `hostBindings` are being processed.\n *\n * @param currentDirectiveIndex `TData` index where current directive instance can be found.\n */\nexport function setCurrentDirectiveIndex(currentDirectiveIndex: number): void {\n instructionState.lFrame.currentDirectiveIndex = currentDirectiveIndex;\n}\n\n/**\n * Retrieve the current `DirectiveDef` which is active when `hostBindings` instruction is being\n * executed.\n *\n * @param tData Current `TData` where the `DirectiveDef` will be looked up at.\n */\nexport function getCurrentDirectiveDef(tData: TData): DirectiveDef|null {\n const currentDirectiveIndex = instructionState.lFrame.currentDirectiveIndex;\n return currentDirectiveIndex === -1 ? null : tData[currentDirectiveIndex] as DirectiveDef;\n}\n\nexport function getCurrentQueryIndex(): number {\n return instructionState.lFrame.currentQueryIndex;\n}\n\nexport function setCurrentQueryIndex(value: number): void {\n instructionState.lFrame.currentQueryIndex = value;\n}\n\n/**\n * Returns a `TNode` of the location where the current `LView` is declared at.\n *\n * @param lView an `LView` that we want to find parent `TNode` for.\n */\nfunction getDeclarationTNode(lView: LView): TNode|null {\n const tView = lView[TVIEW];\n\n // Return the declaration parent for embedded views\n if (tView.type === TViewType.Embedded) {\n ngDevMode && assertDefined(tView.declTNode, 'Embedded TNodes should have declaration parents.');\n return tView.declTNode;\n }\n\n // Components don't have `TView.declTNode` because each instance of component could be\n // inserted in different location, hence `TView.declTNode` is meaningless.\n // Falling back to `T_HOST` in case we cross component boundary.\n if (tView.type === TViewType.Component) {\n return lView[T_HOST];\n }\n\n // Remaining TNode type is `TViewType.Root` which doesn't have a parent TNode.\n return null;\n}\n\n/**\n * This is a light weight version of the `enterView` which is needed by the DI system.\n *\n * @param lView `LView` location of the DI context.\n * @param tNode `TNode` for DI context\n * @param flags DI context flags. if `SkipSelf` flag is set than we walk up the declaration\n * tree from `tNode` until we find parent declared `TElementNode`.\n * @returns `true` if we have successfully entered DI associated with `tNode` (or with declared\n * `TNode` if `flags` has `SkipSelf`). Failing to enter DI implies that no associated\n * `NodeInjector` can be found and we should instead use `ModuleInjector`.\n * - If `true` than this call must be fallowed by `leaveDI`\n * - If `false` than this call failed and we should NOT call `leaveDI`\n */\nexport function enterDI(lView: LView, tNode: TNode, flags: InjectFlags) {\n ngDevMode && assertLViewOrUndefined(lView);\n\n if (flags & InjectFlags.SkipSelf) {\n ngDevMode && assertTNodeForTView(tNode, lView[TVIEW]);\n\n let parentTNode = tNode as TNode | null;\n let parentLView = lView;\n\n while (true) {\n ngDevMode && assertDefined(parentTNode, 'Parent TNode should be defined');\n parentTNode = parentTNode!.parent as TNode | null;\n if (parentTNode === null && !(flags & InjectFlags.Host)) {\n parentTNode = getDeclarationTNode(parentLView);\n if (parentTNode === null) break;\n\n // In this case, a parent exists and is definitely an element. So it will definitely\n // have an existing lView as the declaration view, which is why we can assume it's defined.\n ngDevMode && assertDefined(parentLView, 'Parent LView should be defined');\n parentLView = parentLView[DECLARATION_VIEW]!;\n\n // In Ivy there are Comment nodes that correspond to ngIf and NgFor embedded directives\n // We want to skip those and look only at Elements and ElementContainers to ensure\n // we're looking at true parent nodes, and not content or other types.\n if (parentTNode.type & (TNodeType.Element | TNodeType.ElementContainer)) {\n break;\n }\n } else {\n break;\n }\n }\n if (parentTNode === null) {\n // If we failed to find a parent TNode this means that we should use module injector.\n return false;\n } else {\n tNode = parentTNode;\n lView = parentLView;\n }\n }\n\n ngDevMode && assertTNodeForLView(tNode, lView);\n const lFrame = instructionState.lFrame = allocLFrame();\n lFrame.currentTNode = tNode;\n lFrame.lView = lView;\n\n return true;\n}\n\n/**\n * Swap the current lView with a new lView.\n *\n * For performance reasons we store the lView in the top level of the module.\n * This way we minimize the number of properties to read. Whenever a new view\n * is entered we have to store the lView for later, and when the view is\n * exited the state has to be restored\n *\n * @param newView New lView to become active\n * @returns the previously active lView;\n */\nexport function enterView(newView: LView): void {\n ngDevMode && assertNotEqual(newView[0], newView[1] as any, '????');\n ngDevMode && assertLViewOrUndefined(newView);\n const newLFrame = allocLFrame();\n if (ngDevMode) {\n assertEqual(newLFrame.isParent, true, 'Expected clean LFrame');\n assertEqual(newLFrame.lView, null, 'Expected clean LFrame');\n assertEqual(newLFrame.tView, null, 'Expected clean LFrame');\n assertEqual(newLFrame.selectedIndex, -1, 'Expected clean LFrame');\n assertEqual(newLFrame.elementDepthCount, 0, 'Expected clean LFrame');\n assertEqual(newLFrame.currentDirectiveIndex, -1, 'Expected clean LFrame');\n assertEqual(newLFrame.currentNamespace, null, 'Expected clean LFrame');\n assertEqual(newLFrame.bindingRootIndex, -1, 'Expected clean LFrame');\n assertEqual(newLFrame.currentQueryIndex, 0, 'Expected clean LFrame');\n }\n const tView = newView[TVIEW];\n instructionState.lFrame = newLFrame;\n ngDevMode && tView.firstChild && assertTNodeForTView(tView.firstChild, tView);\n newLFrame.currentTNode = tView.firstChild!;\n newLFrame.lView = newView;\n newLFrame.tView = tView;\n newLFrame.contextLView = newView;\n newLFrame.bindingIndex = tView.bindingStartIndex;\n newLFrame.inI18n = false;\n}\n\n/**\n * Allocates next free LFrame. This function tries to reuse the `LFrame`s to lower memory pressure.\n */\nfunction allocLFrame() {\n const currentLFrame = instructionState.lFrame;\n const childLFrame = currentLFrame === null ? null : currentLFrame.child;\n const newLFrame = childLFrame === null ? createLFrame(currentLFrame) : childLFrame;\n return newLFrame;\n}\n\nfunction createLFrame(parent: LFrame|null): LFrame {\n const lFrame: LFrame = {\n currentTNode: null,\n isParent: true,\n lView: null!,\n tView: null!,\n selectedIndex: -1,\n contextLView: null,\n elementDepthCount: 0,\n currentNamespace: null,\n currentDirectiveIndex: -1,\n bindingRootIndex: -1,\n bindingIndex: -1,\n currentQueryIndex: 0,\n parent: parent!,\n child: null,\n inI18n: false,\n };\n parent !== null && (parent.child = lFrame); // link the new LFrame for reuse.\n return lFrame;\n}\n\n/**\n * A lightweight version of leave which is used with DI.\n *\n * This function only resets `currentTNode` and `LView` as those are the only properties\n * used with DI (`enterDI()`).\n *\n * NOTE: This function is reexported as `leaveDI`. However `leaveDI` has return type of `void` where\n * as `leaveViewLight` has `LFrame`. This is so that `leaveViewLight` can be used in `leaveView`.\n */\nfunction leaveViewLight(): LFrame {\n const oldLFrame = instructionState.lFrame;\n instructionState.lFrame = oldLFrame.parent;\n oldLFrame.currentTNode = null!;\n oldLFrame.lView = null!;\n return oldLFrame;\n}\n\n/**\n * This is a lightweight version of the `leaveView` which is needed by the DI system.\n *\n * NOTE: this function is an alias so that we can change the type of the function to have `void`\n * return type.\n */\nexport const leaveDI: () => void = leaveViewLight;\n\n/**\n * Leave the current `LView`\n *\n * This pops the `LFrame` with the associated `LView` from the stack.\n *\n * IMPORTANT: We must zero out the `LFrame` values here otherwise they will be retained. This is\n * because for performance reasons we don't release `LFrame` but rather keep it for next use.\n */\nexport function leaveView() {\n const oldLFrame = leaveViewLight();\n oldLFrame.isParent = true;\n oldLFrame.tView = null!;\n oldLFrame.selectedIndex = -1;\n oldLFrame.contextLView = null;\n oldLFrame.elementDepthCount = 0;\n oldLFrame.currentDirectiveIndex = -1;\n oldLFrame.currentNamespace = null;\n oldLFrame.bindingRootIndex = -1;\n oldLFrame.bindingIndex = -1;\n oldLFrame.currentQueryIndex = 0;\n}\n\nexport function nextContextImpl(level: number): T {\n const contextLView = instructionState.lFrame.contextLView =\n walkUpViews(level, instructionState.lFrame.contextLView!);\n return contextLView[CONTEXT] as unknown as T;\n}\n\nfunction walkUpViews(nestingLevel: number, currentView: LView): LView {\n while (nestingLevel > 0) {\n ngDevMode &&\n assertDefined(\n currentView[DECLARATION_VIEW],\n 'Declaration view should be defined if nesting level is greater than 0.');\n currentView = currentView[DECLARATION_VIEW]!;\n nestingLevel--;\n }\n return currentView;\n}\n\n/**\n * Gets the currently selected element index.\n *\n * Used with {@link property} instruction (and more in the future) to identify the index in the\n * current `LView` to act on.\n */\nexport function getSelectedIndex() {\n return instructionState.lFrame.selectedIndex;\n}\n\n/**\n * Sets the most recent index passed to {@link select}\n *\n * Used with {@link property} instruction (and more in the future) to identify the index in the\n * current `LView` to act on.\n *\n * (Note that if an \"exit function\" was set earlier (via `setElementExitFn()`) then that will be\n * run if and when the provided `index` value is different from the current selected index value.)\n */\nexport function setSelectedIndex(index: number) {\n ngDevMode && index !== -1 &&\n assertGreaterThanOrEqual(index, HEADER_OFFSET, 'Index must be past HEADER_OFFSET (or -1).');\n ngDevMode &&\n assertLessThan(\n index, instructionState.lFrame.lView.length, 'Can\\'t set index passed end of LView');\n instructionState.lFrame.selectedIndex = index;\n}\n\n/**\n * Gets the `tNode` that represents currently selected element.\n */\nexport function getSelectedTNode() {\n const lFrame = instructionState.lFrame;\n return getTNode(lFrame.tView, lFrame.selectedIndex);\n}\n\n/**\n * Sets the namespace used to create elements to `'http://www.w3.org/2000/svg'` in global state.\n *\n * @codeGenApi\n */\nexport function ɵɵnamespaceSVG() {\n instructionState.lFrame.currentNamespace = SVG_NAMESPACE;\n}\n\n/**\n * Sets the namespace used to create elements to `'http://www.w3.org/1998/MathML/'` in global state.\n *\n * @codeGenApi\n */\nexport function ɵɵnamespaceMathML() {\n instructionState.lFrame.currentNamespace = MATH_ML_NAMESPACE;\n}\n\n/**\n * Sets the namespace used to create elements to `null`, which forces element creation to use\n * `createElement` rather than `createElementNS`.\n *\n * @codeGenApi\n */\nexport function ɵɵnamespaceHTML() {\n namespaceHTMLInternal();\n}\n\n/**\n * Sets the namespace used to create elements to `null`, which forces element creation to use\n * `createElement` rather than `createElementNS`.\n */\nexport function namespaceHTMLInternal() {\n instructionState.lFrame.currentNamespace = null;\n}\n\nexport function getNamespace(): string|null {\n return instructionState.lFrame.currentNamespace;\n}\n\nlet _wasLastNodeCreated = true;\n\n/**\n * Retrieves a global flag that indicates whether the most recent DOM node\n * was created or hydrated.\n */\nexport function wasLastNodeCreated(): boolean {\n return _wasLastNodeCreated;\n}\n\n/**\n * Sets a global flag to indicate whether the most recent DOM node\n * was created or hydrated.\n */\nexport function lastNodeWasCreated(flag: boolean): void {\n _wasLastNodeCreated = flag;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, DoCheck, OnChanges, OnDestroy, OnInit} from '../interface/lifecycle_hooks';\nimport {setActiveConsumer} from '../signals';\nimport {assertDefined, assertEqual, assertNotEqual} from '../util/assert';\n\nimport {assertFirstCreatePass} from './assert';\nimport {NgOnChangesFeatureImpl} from './features/ng_onchanges_feature';\nimport {DirectiveDef} from './interfaces/definition';\nimport {TNode} from './interfaces/node';\nimport {FLAGS, HookData, InitPhaseState, LView, LViewFlags, PREORDER_HOOK_FLAGS, PreOrderHookFlags, TView} from './interfaces/view';\nimport {profiler, ProfilerEvent} from './profiler';\nimport {isInCheckNoChangesMode} from './state';\n\n\n\n/**\n * Adds all directive lifecycle hooks from the given `DirectiveDef` to the given `TView`.\n *\n * Must be run *only* on the first template pass.\n *\n * Sets up the pre-order hooks on the provided `tView`,\n * see {@link HookData} for details about the data structure.\n *\n * @param directiveIndex The index of the directive in LView\n * @param directiveDef The definition containing the hooks to setup in tView\n * @param tView The current TView\n */\nexport function registerPreOrderHooks(\n directiveIndex: number, directiveDef: DirectiveDef, tView: TView): void {\n ngDevMode && assertFirstCreatePass(tView);\n const {ngOnChanges, ngOnInit, ngDoCheck} =\n directiveDef.type.prototype as OnChanges & OnInit & DoCheck;\n\n if (ngOnChanges as Function | undefined) {\n const wrappedOnChanges = NgOnChangesFeatureImpl(directiveDef);\n (tView.preOrderHooks ??= []).push(directiveIndex, wrappedOnChanges);\n (tView.preOrderCheckHooks ??= []).push(directiveIndex, wrappedOnChanges);\n }\n\n if (ngOnInit) {\n (tView.preOrderHooks ??= []).push(0 - directiveIndex, ngOnInit);\n }\n\n if (ngDoCheck) {\n (tView.preOrderHooks ??= []).push(directiveIndex, ngDoCheck);\n (tView.preOrderCheckHooks ??= []).push(directiveIndex, ngDoCheck);\n }\n}\n\n/**\n *\n * Loops through the directives on the provided `tNode` and queues hooks to be\n * run that are not initialization hooks.\n *\n * Should be executed during `elementEnd()` and similar to\n * preserve hook execution order. Content, view, and destroy hooks for projected\n * components and directives must be called *before* their hosts.\n *\n * Sets up the content, view, and destroy hooks on the provided `tView`,\n * see {@link HookData} for details about the data structure.\n *\n * NOTE: This does not set up `onChanges`, `onInit` or `doCheck`, those are set up\n * separately at `elementStart`.\n *\n * @param tView The current TView\n * @param tNode The TNode whose directives are to be searched for hooks to queue\n */\nexport function registerPostOrderHooks(tView: TView, tNode: TNode): void {\n ngDevMode && assertFirstCreatePass(tView);\n // It's necessary to loop through the directives at elementEnd() (rather than processing in\n // directiveCreate) so we can preserve the current hook order. Content, view, and destroy\n // hooks for projected components and directives must be called *before* their hosts.\n for (let i = tNode.directiveStart, end = tNode.directiveEnd; i < end; i++) {\n const directiveDef = tView.data[i] as DirectiveDef;\n ngDevMode && assertDefined(directiveDef, 'Expecting DirectiveDef');\n const lifecycleHooks: AfterContentInit&AfterContentChecked&AfterViewInit&AfterViewChecked&\n OnDestroy = directiveDef.type.prototype;\n const {\n ngAfterContentInit,\n ngAfterContentChecked,\n ngAfterViewInit,\n ngAfterViewChecked,\n ngOnDestroy\n } = lifecycleHooks;\n\n if (ngAfterContentInit) {\n (tView.contentHooks ??= []).push(-i, ngAfterContentInit);\n }\n\n if (ngAfterContentChecked) {\n (tView.contentHooks ??= []).push(i, ngAfterContentChecked);\n (tView.contentCheckHooks ??= []).push(i, ngAfterContentChecked);\n }\n\n if (ngAfterViewInit) {\n (tView.viewHooks ??= []).push(-i, ngAfterViewInit);\n }\n\n if (ngAfterViewChecked) {\n (tView.viewHooks ??= []).push(i, ngAfterViewChecked);\n (tView.viewCheckHooks ??= []).push(i, ngAfterViewChecked);\n }\n\n if (ngOnDestroy != null) {\n (tView.destroyHooks ??= []).push(i, ngOnDestroy);\n }\n }\n}\n\n/**\n * Executing hooks requires complex logic as we need to deal with 2 constraints.\n *\n * 1. Init hooks (ngOnInit, ngAfterContentInit, ngAfterViewInit) must all be executed once and only\n * once, across many change detection cycles. This must be true even if some hooks throw, or if\n * some recursively trigger a change detection cycle.\n * To solve that, it is required to track the state of the execution of these init hooks.\n * This is done by storing and maintaining flags in the view: the {@link InitPhaseState},\n * and the index within that phase. They can be seen as a cursor in the following structure:\n * [[onInit1, onInit2], [afterContentInit1], [afterViewInit1, afterViewInit2, afterViewInit3]]\n * They are stored as flags in LView[FLAGS].\n *\n * 2. Pre-order hooks can be executed in batches, because of the select instruction.\n * To be able to pause and resume their execution, we also need some state about the hook's array\n * that is being processed:\n * - the index of the next hook to be executed\n * - the number of init hooks already found in the processed part of the array\n * They are stored as flags in LView[PREORDER_HOOK_FLAGS].\n */\n\n\n/**\n * Executes pre-order check hooks ( OnChanges, DoChanges) given a view where all the init hooks were\n * executed once. This is a light version of executeInitAndCheckPreOrderHooks where we can skip read\n * / write of the init-hooks related flags.\n * @param lView The LView where hooks are defined\n * @param hooks Hooks to be run\n * @param nodeIndex 3 cases depending on the value:\n * - undefined: all hooks from the array should be executed (post-order case)\n * - null: execute hooks only from the saved index until the end of the array (pre-order case, when\n * flushing the remaining hooks)\n * - number: execute hooks only from the saved index until that node index exclusive (pre-order\n * case, when executing select(number))\n */\nexport function executeCheckHooks(lView: LView, hooks: HookData, nodeIndex?: number|null) {\n callHooks(lView, hooks, InitPhaseState.InitPhaseCompleted, nodeIndex);\n}\n\n/**\n * Executes post-order init and check hooks (one of AfterContentInit, AfterContentChecked,\n * AfterViewInit, AfterViewChecked) given a view where there are pending init hooks to be executed.\n * @param lView The LView where hooks are defined\n * @param hooks Hooks to be run\n * @param initPhase A phase for which hooks should be run\n * @param nodeIndex 3 cases depending on the value:\n * - undefined: all hooks from the array should be executed (post-order case)\n * - null: execute hooks only from the saved index until the end of the array (pre-order case, when\n * flushing the remaining hooks)\n * - number: execute hooks only from the saved index until that node index exclusive (pre-order\n * case, when executing select(number))\n */\nexport function executeInitAndCheckHooks(\n lView: LView, hooks: HookData, initPhase: InitPhaseState, nodeIndex?: number|null) {\n ngDevMode &&\n assertNotEqual(\n initPhase, InitPhaseState.InitPhaseCompleted,\n 'Init pre-order hooks should not be called more than once');\n if ((lView[FLAGS] & LViewFlags.InitPhaseStateMask) === initPhase) {\n callHooks(lView, hooks, initPhase, nodeIndex);\n }\n}\n\nexport function incrementInitPhaseFlags(lView: LView, initPhase: InitPhaseState): void {\n ngDevMode &&\n assertNotEqual(\n initPhase, InitPhaseState.InitPhaseCompleted,\n 'Init hooks phase should not be incremented after all init hooks have been run.');\n let flags = lView[FLAGS];\n if ((flags & LViewFlags.InitPhaseStateMask) === initPhase) {\n flags &= LViewFlags.IndexWithinInitPhaseReset;\n flags += LViewFlags.InitPhaseStateIncrementer;\n lView[FLAGS] = flags;\n }\n}\n\n/**\n * Calls lifecycle hooks with their contexts, skipping init hooks if it's not\n * the first LView pass\n *\n * @param currentView The current view\n * @param arr The array in which the hooks are found\n * @param initPhaseState the current state of the init phase\n * @param currentNodeIndex 3 cases depending on the value:\n * - undefined: all hooks from the array should be executed (post-order case)\n * - null: execute hooks only from the saved index until the end of the array (pre-order case, when\n * flushing the remaining hooks)\n * - number: execute hooks only from the saved index until that node index exclusive (pre-order\n * case, when executing select(number))\n */\nfunction callHooks(\n currentView: LView, arr: HookData, initPhase: InitPhaseState,\n currentNodeIndex: number|null|undefined): void {\n ngDevMode &&\n assertEqual(\n isInCheckNoChangesMode(), false,\n 'Hooks should never be run when in check no changes mode.');\n const startIndex = currentNodeIndex !== undefined ?\n (currentView[PREORDER_HOOK_FLAGS] & PreOrderHookFlags.IndexOfTheNextPreOrderHookMaskMask) :\n 0;\n const nodeIndexLimit = currentNodeIndex != null ? currentNodeIndex : -1;\n const max = arr.length - 1; // Stop the loop at length - 1, because we look for the hook at i + 1\n let lastNodeIndexFound = 0;\n for (let i = startIndex; i < max; i++) {\n const hook = arr[i + 1] as number | (() => void);\n if (typeof hook === 'number') {\n lastNodeIndexFound = arr[i] as number;\n if (currentNodeIndex != null && lastNodeIndexFound >= currentNodeIndex) {\n break;\n }\n } else {\n const isInitHook = (arr[i] as number) < 0;\n if (isInitHook) {\n currentView[PREORDER_HOOK_FLAGS] += PreOrderHookFlags.NumberOfInitHooksCalledIncrementer;\n }\n if (lastNodeIndexFound < nodeIndexLimit || nodeIndexLimit == -1) {\n callHook(currentView, initPhase, arr, i);\n currentView[PREORDER_HOOK_FLAGS] =\n (currentView[PREORDER_HOOK_FLAGS] & PreOrderHookFlags.NumberOfInitHooksCalledMask) + i +\n 2;\n }\n i++;\n }\n }\n}\n\n/**\n * Executes a single lifecycle hook, making sure that:\n * - it is called in the non-reactive context;\n * - profiling data are registered.\n */\nfunction callHookInternal(directive: any, hook: () => void) {\n profiler(ProfilerEvent.LifecycleHookStart, directive, hook);\n const prevConsumer = setActiveConsumer(null);\n try {\n hook.call(directive);\n } finally {\n setActiveConsumer(prevConsumer);\n profiler(ProfilerEvent.LifecycleHookEnd, directive, hook);\n }\n}\n\n/**\n * Execute one hook against the current `LView`.\n *\n * @param currentView The current view\n * @param initPhaseState the current state of the init phase\n * @param arr The array in which the hooks are found\n * @param i The current index within the hook data array\n */\nfunction callHook(currentView: LView, initPhase: InitPhaseState, arr: HookData, i: number) {\n const isInitHook = (arr[i] as number) < 0;\n const hook = arr[i + 1] as () => void;\n const directiveIndex = isInitHook ? -arr[i] : arr[i] as number;\n const directive = currentView[directiveIndex];\n if (isInitHook) {\n const indexWithintInitPhase = currentView[FLAGS] >> LViewFlags.IndexWithinInitPhaseShift;\n // The init phase state must be always checked here as it may have been recursively updated.\n if (indexWithintInitPhase <\n (currentView[PREORDER_HOOK_FLAGS] >> PreOrderHookFlags.NumberOfInitHooksCalledShift) &&\n (currentView[FLAGS] & LViewFlags.InitPhaseStateMask) === initPhase) {\n currentView[FLAGS] += LViewFlags.IndexWithinInitPhaseIncrementer;\n callHookInternal(directive, hook);\n }\n } else {\n callHookInternal(directive, hook);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {InjectFlags} from '../../di/interface/injector';\nimport {ProviderToken} from '../../di/provider_token';\nimport {assertDefined, assertEqual} from '../../util/assert';\n\nimport {TDirectiveHostNode} from './node';\nimport {LView, TData} from './view';\n\n/**\n * Offsets of the `NodeInjector` data structure in the expando.\n *\n * `NodeInjector` is stored in both `LView` as well as `TView.data`. All storage requires 9 words.\n * First 8 are reserved for bloom filter and the 9th is reserved for the associated `TNode` as well\n * as parent `NodeInjector` pointer. All indexes are starting with `index` and have an offset as\n * shown.\n *\n * `LView` layout:\n * ```\n * index + 0: cumulative bloom filter\n * index + 1: cumulative bloom filter\n * index + 2: cumulative bloom filter\n * index + 3: cumulative bloom filter\n * index + 4: cumulative bloom filter\n * index + 5: cumulative bloom filter\n * index + 6: cumulative bloom filter\n * index + 7: cumulative bloom filter\n * index + 8: cumulative bloom filter\n * index + PARENT: Index to the parent injector. See `RelativeInjectorLocation`\n * `const parent = lView[index + NodeInjectorOffset.PARENT]`\n * ```\n *\n * `TViewData` layout:\n * ```\n * index + 0: cumulative bloom filter\n * index + 1: cumulative bloom filter\n * index + 2: cumulative bloom filter\n * index + 3: cumulative bloom filter\n * index + 4: cumulative bloom filter\n * index + 5: cumulative bloom filter\n * index + 6: cumulative bloom filter\n * index + 7: cumulative bloom filter\n * index + 8: cumulative bloom filter\n * index + TNODE: TNode associated with this `NodeInjector`\n * `const tNode = tView.data[index + NodeInjectorOffset.TNODE]`\n * ```\n */\nexport const enum NodeInjectorOffset {\n TNODE = 8,\n PARENT = 8,\n BLOOM_SIZE = 8,\n SIZE = 9,\n}\n\n/**\n * Represents a relative location of parent injector.\n *\n * The interfaces encodes number of parents `LView`s to traverse and index in the `LView`\n * pointing to the parent injector.\n */\nexport type RelativeInjectorLocation = number&{\n __brand__: 'RelativeInjectorLocationFlags';\n};\n\nexport const enum RelativeInjectorLocationFlags {\n InjectorIndexMask = 0b111111111111111,\n ViewOffsetShift = 16,\n NO_PARENT = -1,\n}\n\nexport const NO_PARENT_INJECTOR = -1 as RelativeInjectorLocation;\n\n/**\n * Each injector is saved in 9 contiguous slots in `LView` and 9 contiguous slots in\n * `TView.data`. This allows us to store information about the current node's tokens (which\n * can be shared in `TView`) as well as the tokens of its ancestor nodes (which cannot be\n * shared, so they live in `LView`).\n *\n * Each of these slots (aside from the last slot) contains a bloom filter. This bloom filter\n * determines whether a directive is available on the associated node or not. This prevents us\n * from searching the directives array at this level unless it's probable the directive is in it.\n *\n * See: https://en.wikipedia.org/wiki/Bloom_filter for more about bloom filters.\n *\n * Because all injectors have been flattened into `LView` and `TViewData`, they cannot typed\n * using interfaces as they were previously. The start index of each `LInjector` and `TInjector`\n * will differ based on where it is flattened into the main array, so it's not possible to know\n * the indices ahead of time and save their types here. The interfaces are still included here\n * for documentation purposes.\n *\n * export interface LInjector extends Array {\n *\n * // Cumulative bloom for directive IDs 0-31 (IDs are % BLOOM_SIZE)\n * [0]: number;\n *\n * // Cumulative bloom for directive IDs 32-63\n * [1]: number;\n *\n * // Cumulative bloom for directive IDs 64-95\n * [2]: number;\n *\n * // Cumulative bloom for directive IDs 96-127\n * [3]: number;\n *\n * // Cumulative bloom for directive IDs 128-159\n * [4]: number;\n *\n * // Cumulative bloom for directive IDs 160 - 191\n * [5]: number;\n *\n * // Cumulative bloom for directive IDs 192 - 223\n * [6]: number;\n *\n * // Cumulative bloom for directive IDs 224 - 255\n * [7]: number;\n *\n * // We need to store a reference to the injector's parent so DI can keep looking up\n * // the injector tree until it finds the dependency it's looking for.\n * [PARENT_INJECTOR]: number;\n * }\n *\n * export interface TInjector extends Array {\n *\n * // Shared node bloom for directive IDs 0-31 (IDs are % BLOOM_SIZE)\n * [0]: number;\n *\n * // Shared node bloom for directive IDs 32-63\n * [1]: number;\n *\n * // Shared node bloom for directive IDs 64-95\n * [2]: number;\n *\n * // Shared node bloom for directive IDs 96-127\n * [3]: number;\n *\n * // Shared node bloom for directive IDs 128-159\n * [4]: number;\n *\n * // Shared node bloom for directive IDs 160 - 191\n * [5]: number;\n *\n * // Shared node bloom for directive IDs 192 - 223\n * [6]: number;\n *\n * // Shared node bloom for directive IDs 224 - 255\n * [7]: number;\n *\n * // Necessary to find directive indices for a particular node.\n * [TNODE]: TElementNode|TElementContainerNode|TContainerNode;\n * }\n */\n\n/**\n * Factory for creating instances of injectors in the NodeInjector.\n *\n * This factory is complicated by the fact that it can resolve `multi` factories as well.\n *\n * NOTE: Some of the fields are optional which means that this class has two hidden classes.\n * - One without `multi` support (most common)\n * - One with `multi` values, (rare).\n *\n * Since VMs can cache up to 4 inline hidden classes this is OK.\n *\n * - Single factory: Only `resolving` and `factory` is defined.\n * - `providers` factory: `componentProviders` is a number and `index = -1`.\n * - `viewProviders` factory: `componentProviders` is a number and `index` points to `providers`.\n */\nexport class NodeInjectorFactory {\n /**\n * The inject implementation to be activated when using the factory.\n */\n injectImpl: null|((token: ProviderToken, flags?: InjectFlags) => T);\n\n /**\n * Marker set to true during factory invocation to see if we get into recursive loop.\n * Recursive loop causes an error to be displayed.\n */\n resolving = false;\n\n /**\n * Marks that the token can see other Tokens declared in `viewProviders` on the same node.\n */\n canSeeViewProviders: boolean;\n\n /**\n * An array of factories to use in case of `multi` provider.\n */\n multi?: Array<() => any>;\n\n /**\n * Number of `multi`-providers which belong to the component.\n *\n * This is needed because when multiple components and directives declare the `multi` provider\n * they have to be concatenated in the correct order.\n *\n * Example:\n *\n * If we have a component and directive active an a single element as declared here\n * ```\n * component:\n * providers: [ {provide: String, useValue: 'component', multi: true} ],\n * viewProviders: [ {provide: String, useValue: 'componentView', multi: true} ],\n *\n * directive:\n * providers: [ {provide: String, useValue: 'directive', multi: true} ],\n * ```\n *\n * Then the expected results are:\n *\n * ```\n * providers: ['component', 'directive']\n * viewProviders: ['component', 'componentView', 'directive']\n * ```\n *\n * The way to think about it is that the `viewProviders` have been inserted after the component\n * but before the directives, which is why we need to know how many `multi`s have been declared by\n * the component.\n */\n componentProviders?: number;\n\n /**\n * Current index of the Factory in the `data`. Needed for `viewProviders` and `providers` merging.\n * See `providerFactory`.\n */\n index?: number;\n\n /**\n * Because the same `multi` provider can be declared in `providers` and `viewProviders` it is\n * possible for `viewProviders` to shadow the `providers`. For this reason we store the\n * `provideFactory` of the `providers` so that `providers` can be extended with `viewProviders`.\n *\n * Example:\n *\n * Given:\n * ```\n * providers: [ {provide: String, useValue: 'all', multi: true} ],\n * viewProviders: [ {provide: String, useValue: 'viewOnly', multi: true} ],\n * ```\n *\n * We have to return `['all']` in case of content injection, but `['all', 'viewOnly']` in case\n * of view injection. We further have to make sure that the shared instances (in our case\n * `all`) are the exact same instance in both the content as well as the view injection. (We\n * have to make sure that we don't double instantiate.) For this reason the `viewProviders`\n * `Factory` has a pointer to the shadowed `providers` factory so that it can instantiate the\n * `providers` (`['all']`) and then extend it with `viewProviders` (`['all'] + ['viewOnly'] =\n * ['all', 'viewOnly']`).\n */\n providerFactory?: NodeInjectorFactory|null;\n\n\n constructor(\n /**\n * Factory to invoke in order to create a new instance.\n */\n public factory:\n (this: NodeInjectorFactory, _: undefined,\n /**\n * array where injectables tokens are stored. This is used in\n * case of an error reporting to produce friendlier errors.\n */\n tData: TData,\n /**\n * array where existing instances of injectables are stored. This is used in case\n * of multi shadow is needed. See `multi` field documentation.\n */\n lView: LView,\n /**\n * The TNode of the same element injector.\n */\n tNode: TDirectiveHostNode) => any,\n /**\n * Set to `true` if the token is declared in `viewProviders` (or if it is component).\n */\n isViewProvider: boolean,\n injectImplementation: null|((token: ProviderToken, flags?: InjectFlags) => T)) {\n ngDevMode && assertDefined(factory, 'Factory not specified');\n ngDevMode && assertEqual(typeof factory, 'function', 'Expected factory function.');\n this.canSeeViewProviders = isViewProvider;\n this.injectImpl = injectImplementation;\n }\n}\n\nexport function isFactory(obj: any): obj is NodeInjectorFactory {\n return obj instanceof NodeInjectorFactory;\n}\n\n// Note: This hack is necessary so we don't erroneously get a circular dependency\n// failure based on types.\nexport const unusedValueExportToPlacateAjd = 1;\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport {KeyValueArray} from '../../util/array_utils';\nimport {TStylingRange} from '../interfaces/styling';\n\nimport {TIcu} from './i18n';\nimport {CssSelector} from './projection';\nimport {RNode} from './renderer_dom';\nimport {LView, TView} from './view';\n\n\n/**\n * TNodeType corresponds to the {@link TNode} `type` property.\n *\n * NOTE: type IDs are such that we use each bit to denote a type. This is done so that we can easily\n * check if the `TNode` is of more than one type.\n *\n * `if (tNode.type === TNodeType.Text || tNode.type === TNode.Element)`\n * can be written as:\n * `if (tNode.type & (TNodeType.Text | TNodeType.Element))`\n *\n * However any given `TNode` can only be of one type.\n */\nexport const enum TNodeType {\n /**\n * The TNode contains information about a DOM element aka {@link RText}.\n */\n Text = 0b1,\n\n /**\n * The TNode contains information about a DOM element aka {@link RElement}.\n */\n Element = 0b10,\n\n /**\n * The TNode contains information about an {@link LContainer} for embedded views.\n */\n Container = 0b100,\n\n /**\n * The TNode contains information about an `` element {@link RNode}.\n */\n ElementContainer = 0b1000,\n\n /**\n * The TNode contains information about an `` projection\n */\n Projection = 0b10000,\n\n /**\n * The TNode contains information about an ICU comment used in `i18n`.\n */\n Icu = 0b100000,\n\n /**\n * Special node type representing a placeholder for future `TNode` at this location.\n *\n * I18n translation blocks are created before the element nodes which they contain. (I18n blocks\n * can span over many elements.) Because i18n `TNode`s (representing text) are created first they\n * often may need to point to element `TNode`s which are not yet created. In such a case we create\n * a `Placeholder` `TNode`. This allows the i18n to structurally link the `TNode`s together\n * without knowing any information about the future nodes which will be at that location.\n *\n * On `firstCreatePass` When element instruction executes it will try to create a `TNode` at that\n * location. Seeing a `Placeholder` `TNode` already there tells the system that it should reuse\n * existing `TNode` (rather than create a new one) and just update the missing information.\n */\n Placeholder = 0b1000000,\n\n // Combined Types These should never be used for `TNode.type` only as a useful way to check\n // if `TNode.type` is one of several choices.\n\n // See: https://github.com/microsoft/TypeScript/issues/35875 why we can't refer to existing enum.\n AnyRNode = 0b11, // Text | Element,\n AnyContainer = 0b1100, // Container | ElementContainer, // See:\n}\n\n/**\n * Converts `TNodeType` into human readable text.\n * Make sure this matches with `TNodeType`\n */\nexport function toTNodeTypeAsString(tNodeType: TNodeType): string {\n let text = '';\n (tNodeType & TNodeType.Text) && (text += '|Text');\n (tNodeType & TNodeType.Element) && (text += '|Element');\n (tNodeType & TNodeType.Container) && (text += '|Container');\n (tNodeType & TNodeType.ElementContainer) && (text += '|ElementContainer');\n (tNodeType & TNodeType.Projection) && (text += '|Projection');\n (tNodeType & TNodeType.Icu) && (text += '|IcuContainer');\n (tNodeType & TNodeType.Placeholder) && (text += '|Placeholder');\n return text.length > 0 ? text.substring(1) : text;\n}\n\n/**\n * Corresponds to the TNode.flags property.\n */\nexport const enum TNodeFlags {\n /** Bit #1 - This bit is set if the node is a host for any directive (including a component) */\n isDirectiveHost = 0x1,\n\n /** Bit #2 - This bit is set if the node has been projected */\n isProjected = 0x2,\n\n /** Bit #3 - This bit is set if any directive on this node has content queries */\n hasContentQuery = 0x4,\n\n /** Bit #4 - This bit is set if the node has any \"class\" inputs */\n hasClassInput = 0x8,\n\n /** Bit #5 - This bit is set if the node has any \"style\" inputs */\n hasStyleInput = 0x10,\n\n /** Bit #6 - This bit is set if the node has been detached by i18n */\n isDetached = 0x20,\n\n /**\n * Bit #7 - This bit is set if the node has directives with host bindings.\n *\n * This flags allows us to guard host-binding logic and invoke it only on nodes\n * that actually have directives with host bindings.\n */\n hasHostBindings = 0x40,\n\n /**\n * Bit #8 - This bit is set if the node is a located inside skip hydration block.\n */\n inSkipHydrationBlock = 0x80,\n}\n\n/**\n * Corresponds to the TNode.providerIndexes property.\n */\nexport const enum TNodeProviderIndexes {\n /** The index of the first provider on this node is encoded on the least significant bits. */\n ProvidersStartIndexMask = 0b00000000000011111111111111111111,\n\n /**\n * The count of view providers from the component on this node is\n * encoded on the 20 most significant bits.\n */\n CptViewProvidersCountShift = 20,\n CptViewProvidersCountShifter = 0b00000000000100000000000000000000,\n}\n\n/**\n * A set of marker values to be used in the attributes arrays. These markers indicate that some\n * items are not regular attributes and the processing should be adapted accordingly.\n */\nexport const enum AttributeMarker {\n /**\n * An implicit marker which indicates that the value in the array are of `attributeKey`,\n * `attributeValue` format.\n *\n * NOTE: This is implicit as it is the type when no marker is present in array. We indicate that\n * it should not be present at runtime by the negative number.\n */\n ImplicitAttributes = -1,\n\n /**\n * Marker indicates that the following 3 values in the attributes array are:\n * namespaceUri, attributeName, attributeValue\n * in that order.\n */\n NamespaceURI = 0,\n\n /**\n * Signals class declaration.\n *\n * Each value following `Classes` designates a class name to include on the element.\n * ## Example:\n *\n * Given:\n * ```\n *
...\n * ```\n *\n * the generated code is:\n * ```\n * var _c1 = [AttributeMarker.Classes, 'foo', 'bar', 'baz'];\n * ```\n */\n Classes = 1,\n\n /**\n * Signals style declaration.\n *\n * Each pair of values following `Styles` designates a style name and value to include on the\n * element.\n * ## Example:\n *\n * Given:\n * ```\n *
...
\n * ```\n *\n * the generated code is:\n * ```\n * var _c1 = [AttributeMarker.Styles, 'width', '100px', 'height'. '200px', 'color', 'red'];\n * ```\n */\n Styles = 2,\n\n /**\n * Signals that the following attribute names were extracted from input or output bindings.\n *\n * For example, given the following HTML:\n *\n * ```\n *
\n * ```\n *\n * the generated code is:\n *\n * ```\n * var _c1 = ['moo', 'car', AttributeMarker.Bindings, 'foo', 'bar'];\n * ```\n */\n Bindings = 3,\n\n /**\n * Signals that the following attribute names were hoisted from an inline-template declaration.\n *\n * For example, given the following HTML:\n *\n * ```\n *
\n * ```\n *\n * the generated code for the `template()` instruction would include:\n *\n * ```\n * ['dirA', '', AttributeMarker.Bindings, 'dirB', AttributeMarker.Template, 'ngFor', 'ngForOf',\n * 'ngForTrackBy', 'let-value']\n * ```\n *\n * while the generated code for the `element()` instruction inside the template function would\n * include:\n *\n * ```\n * ['dirA', '', AttributeMarker.Bindings, 'dirB']\n * ```\n */\n Template = 4,\n\n /**\n * Signals that the following attribute is `ngProjectAs` and its value is a parsed\n * `CssSelector`.\n *\n * For example, given the following HTML:\n *\n * ```\n *

\n * ```\n *\n * the generated code for the `element()` instruction would include:\n *\n * ```\n * ['attr', 'value', AttributeMarker.ProjectAs, ['', 'title', '']]\n * ```\n */\n ProjectAs = 5,\n\n /**\n * Signals that the following attribute will be translated by runtime i18n\n *\n * For example, given the following HTML:\n *\n * ```\n *
\n * ```\n *\n * the generated code is:\n *\n * ```\n * var _c1 = ['moo', 'car', AttributeMarker.I18n, 'foo', 'bar'];\n */\n I18n = 6,\n}\n\n/**\n * A combination of:\n * - Attribute names and values.\n * - Special markers acting as flags to alter attributes processing.\n * - Parsed ngProjectAs selectors.\n */\nexport type TAttributes = (string|AttributeMarker|CssSelector)[];\n\n/**\n * Constants that are associated with a view. Includes:\n * - Attribute arrays.\n * - Local definition arrays.\n * - Translated messages (i18n).\n */\nexport type TConstants = (TAttributes|string)[];\n\n/**\n * Factory function that returns an array of consts. Consts can be represented as a function in\n * case any additional statements are required to define consts in the list. An example is i18n\n * where additional i18n calls are generated, which should be executed when consts are requested\n * for the first time.\n */\nexport type TConstantsFactory = () => TConstants;\n\n/**\n * TConstants type that describes how the `consts` field is generated on ComponentDef: it can be\n * either an array or a factory function that returns that array.\n */\nexport type TConstantsOrFactory = TConstants|TConstantsFactory;\n\n/**\n * Binding data (flyweight) for a particular node that is shared between all templates\n * of a specific type.\n *\n * If a property is:\n * - PropertyAliases: that property's data was generated and this is it\n * - Null: that property's data was already generated and nothing was found.\n * - Undefined: that property's data has not yet been generated\n *\n * see: https://en.wikipedia.org/wiki/Flyweight_pattern for more on the Flyweight pattern\n */\nexport interface TNode {\n /** The type of the TNode. See TNodeType. */\n type: TNodeType;\n\n /**\n * Index of the TNode in TView.data and corresponding native element in LView.\n *\n * This is necessary to get from any TNode to its corresponding native element when\n * traversing the node tree.\n *\n * If index is -1, this is a dynamically created container node or embedded view node.\n */\n index: number;\n\n /**\n * Insert before existing DOM node index.\n *\n * When DOM nodes are being inserted, normally they are being appended as they are created.\n * Under i18n case, the translated text nodes are created ahead of time as part of the\n * `ɵɵi18nStart` instruction which means that this `TNode` can't just be appended and instead\n * needs to be inserted using `insertBeforeIndex` semantics.\n *\n * Additionally sometimes it is necessary to insert new text nodes as a child of this `TNode`. In\n * such a case the value stores an array of text nodes to insert.\n *\n * Example:\n * ```\n *
\n * Hello World!\n *
\n * ```\n * In the above example the `ɵɵi18nStart` instruction can create `Hello `, `World` and `!` text\n * nodes. It can also insert `Hello ` and `!` text node as a child of `
`, but it can't\n * insert `World` because the `` node has not yet been created. In such a case the\n * `` `TNode` will have an array which will direct the `` to not only insert\n * itself in front of `!` but also to insert the `World` (created by `ɵɵi18nStart`) into\n * `` itself.\n *\n * Pseudo code:\n * ```\n * if (insertBeforeIndex === null) {\n * // append as normal\n * } else if (Array.isArray(insertBeforeIndex)) {\n * // First insert current `TNode` at correct location\n * const currentNode = lView[this.index];\n * parentNode.insertBefore(currentNode, lView[this.insertBeforeIndex[0]]);\n * // Now append all of the children\n * for(let i=1; i`\n * - a component is referenced, ex.: ``\n * - a directive is referenced, ex.: ``.\n *\n * A given element might have different local names and those names can be associated\n * with a directive. We store local names at even indexes while odd indexes are reserved\n * for directive index in a view (or `-1` if there is no associated directive).\n *\n * Some examples:\n * - `
` => `[\"foo\", -1]`\n * - `` => `[\"foo\", myCmptIdx]`\n * - `` => `[\"foo\", myCmptIdx, \"bar\", directiveIdx]`\n * - `
` => `[\"foo\", -1, \"bar\", directiveIdx]`\n */\n localNames: (string|number)[]|null;\n\n /** Information about input properties that need to be set once from attribute data. */\n initialInputs: InitialInputData|null|undefined;\n\n /**\n * Input data for all directives on this node. `null` means that there are no directives with\n * inputs on this node.\n */\n inputs: PropertyAliases|null;\n\n /**\n * Output data for all directives on this node. `null` means that there are no directives with\n * outputs on this node.\n */\n outputs: PropertyAliases|null;\n\n /**\n * The TView attached to this node.\n *\n * If this TNode corresponds to an LContainer with a template (e.g. structural\n * directive), the template's TView will be stored here.\n *\n * If this TNode corresponds to an element, tView will be `null`.\n */\n tView: TView|null;\n\n /**\n * The next sibling node. Necessary so we can propagate through the root nodes of a view\n * to insert them or remove them from the DOM.\n */\n next: TNode|null;\n\n /**\n * The previous sibling node.\n * This simplifies operations when we need a pointer to the previous node.\n */\n prev: TNode|null;\n\n /**\n * The next projected sibling. Since in Angular content projection works on the node-by-node\n * basis the act of projecting nodes might change nodes relationship at the insertion point\n * (target view). At the same time we need to keep initial relationship between nodes as\n * expressed in content view.\n */\n projectionNext: TNode|null;\n\n /**\n * First child of the current node.\n *\n * For component nodes, the child will always be a ContentChild (in same view).\n * For embedded view nodes, the child will be in their child view.\n */\n child: TNode|null;\n\n /**\n * Parent node (in the same view only).\n *\n * We need a reference to a node's parent so we can append the node to its parent's native\n * element at the appropriate time.\n *\n * If the parent would be in a different view (e.g. component host), this property will be null.\n * It's important that we don't try to cross component boundaries when retrieving the parent\n * because the parent will change (e.g. index, attrs) depending on where the component was\n * used (and thus shouldn't be stored on TNode). In these cases, we retrieve the parent through\n * LView.node instead (which will be instance-specific).\n *\n * If this is an inline view node (V), the parent will be its container.\n */\n parent: TElementNode|TContainerNode|null;\n\n /**\n * List of projected TNodes for a given component host element OR index into the said nodes.\n *\n * For easier discussion assume this example:\n * ``'s view definition:\n * ```\n * content1\n * content2\n * ```\n * ``'s view definition:\n * ```\n * \n * ```\n *\n * If `Array.isArray(projection)` then `TNode` is a host element:\n * - `projection` stores the content nodes which are to be projected.\n * - The nodes represent categories defined by the selector: For example:\n * `` would represent the heads for ``\n * and `` respectively.\n * - The nodes we store in `projection` are heads only, we used `.next` to get their\n * siblings.\n * - The nodes `.next` is sorted/rewritten as part of the projection setup.\n * - `projection` size is equal to the number of projections ``. The size of\n * `c1` will be `1` because `` has only one ``.\n * - we store `projection` with the host (`c1`, `c2`) rather than the `` (`cont1`)\n * because the same component (``) can be used in multiple locations (`c1`, `c2`) and\n * as a result have different set of nodes to project.\n * - without `projection` it would be difficult to efficiently traverse nodes to be projected.\n *\n * If `typeof projection == 'number'` then `TNode` is a `` element:\n * - `projection` is an index of the host's `projection`Nodes.\n * - This would return the first head node to project:\n * `getHost(currentTNode).projection[currentTNode.projection]`.\n * - When projecting nodes the parent node retrieved may be a `` node, in which case\n * the process is recursive in nature.\n *\n * If `projection` is of type `RNode[][]` than we have a collection of native nodes passed as\n * projectable nodes during dynamic component creation.\n */\n projection: (TNode|RNode[])[]|number|null;\n\n /**\n * A collection of all `style` static values for an element (including from host).\n *\n * This field will be populated if and when:\n *\n * - There are one or more initial `style`s on an element (e.g. `
`)\n * - There are one or more initial `style`s on a directive/component host\n * (e.g. `@Directive({host: {style: \"width:200px;\" } }`)\n */\n styles: string|null;\n\n\n /**\n * A collection of all `style` static values for an element excluding host sources.\n *\n * Populated when there are one or more initial `style`s on an element\n * (e.g. `
`)\n * Must be stored separately from `tNode.styles` to facilitate setting directive\n * inputs that shadow the `style` property. If we used `tNode.styles` as is for shadowed inputs,\n * we would feed host styles back into directives as \"inputs\". If we used `tNode.attrs`, we\n * would have to concatenate the attributes on every template pass. Instead, we process once on\n * first create pass and store here.\n */\n stylesWithoutHost: string|null;\n\n /**\n * A `KeyValueArray` version of residual `styles`.\n *\n * When there are styling instructions than each instruction stores the static styling\n * which is of lower priority than itself. This means that there may be a higher priority\n * styling than the instruction.\n *\n * Imagine:\n * ```\n *
\n *\n * @Directive({\n * host: {\n * style: 'color: lowest; ',\n * '[styles.color]': 'exp' // ɵɵstyleProp('color', ctx.exp);\n * }\n * })\n * ```\n *\n * In the above case:\n * - `color: lowest` is stored with `ɵɵstyleProp('color', ctx.exp);` instruction\n * - `color: highest` is the residual and is stored here.\n *\n * - `undefined': not initialized.\n * - `null`: initialized but `styles` is `null`\n * - `KeyValueArray`: parsed version of `styles`.\n */\n residualStyles: KeyValueArray|undefined|null;\n\n /**\n * A collection of all class static values for an element (including from host).\n *\n * This field will be populated if and when:\n *\n * - There are one or more initial classes on an element (e.g. `
`)\n * - There are one or more initial classes on an directive/component host\n * (e.g. `@Directive({host: {class: \"SOME_CLASS\" } }`)\n */\n classes: string|null;\n\n /**\n * A collection of all class static values for an element excluding host sources.\n *\n * Populated when there are one or more initial classes on an element\n * (e.g. `
`)\n * Must be stored separately from `tNode.classes` to facilitate setting directive\n * inputs that shadow the `class` property. If we used `tNode.classes` as is for shadowed\n * inputs, we would feed host classes back into directives as \"inputs\". If we used\n * `tNode.attrs`, we would have to concatenate the attributes on every template pass. Instead,\n * we process once on first create pass and store here.\n */\n classesWithoutHost: string|null;\n\n /**\n * A `KeyValueArray` version of residual `classes`.\n *\n * Same as `TNode.residualStyles` but for classes.\n *\n * - `undefined': not initialized.\n * - `null`: initialized but `classes` is `null`\n * - `KeyValueArray`: parsed version of `classes`.\n */\n residualClasses: KeyValueArray|undefined|null;\n\n /**\n * Stores the head/tail index of the class bindings.\n *\n * - If no bindings, the head and tail will both be 0.\n * - If there are template bindings, stores the head/tail of the class bindings in the template.\n * - If no template bindings but there are host bindings, the head value will point to the last\n * host binding for \"class\" (not the head of the linked list), tail will be 0.\n *\n * See: `style_binding_list.ts` for details.\n *\n * This is used by `insertTStylingBinding` to know where the next styling binding should be\n * inserted so that they can be sorted in priority order.\n */\n classBindings: TStylingRange;\n\n /**\n * Stores the head/tail index of the class bindings.\n *\n * - If no bindings, the head and tail will both be 0.\n * - If there are template bindings, stores the head/tail of the style bindings in the template.\n * - If no template bindings but there are host bindings, the head value will point to the last\n * host binding for \"style\" (not the head of the linked list), tail will be 0.\n *\n * See: `style_binding_list.ts` for details.\n *\n * This is used by `insertTStylingBinding` to know where the next styling binding should be\n * inserted so that they can be sorted in priority order.\n */\n styleBindings: TStylingRange;\n}\n\n/**\n * See `TNode.insertBeforeIndex`\n */\nexport type InsertBeforeIndex = null|number|number[];\n\n/** Static data for an element */\nexport interface TElementNode extends TNode {\n /** Index in the data[] array */\n index: number;\n child: TElementNode|TTextNode|TElementContainerNode|TContainerNode|TProjectionNode|null;\n /**\n * Element nodes will have parents unless they are the first node of a component or\n * embedded view (which means their parent is in a different view and must be\n * retrieved using viewData[HOST_NODE]).\n */\n parent: TElementNode|TElementContainerNode|null;\n tView: null;\n\n /**\n * If this is a component TNode with projection, this will be an array of projected\n * TNodes or native nodes (see TNode.projection for more info). If it's a regular element node\n * or a component without projection, it will be null.\n */\n projection: (TNode|RNode[])[]|null;\n\n /**\n * Stores TagName\n */\n value: string;\n}\n\n/** Static data for a text node */\nexport interface TTextNode extends TNode {\n /** Index in the data[] array */\n index: number;\n child: null;\n /**\n * Text nodes will have parents unless they are the first node of a component or\n * embedded view (which means their parent is in a different view and must be\n * retrieved using LView.node).\n */\n parent: TElementNode|TElementContainerNode|null;\n tView: null;\n projection: null;\n}\n\n/** Static data for an LContainer */\nexport interface TContainerNode extends TNode {\n /**\n * Index in the data[] array.\n *\n * If it's -1, this is a dynamically created container node that isn't stored in\n * data[] (e.g. when you inject ViewContainerRef) .\n */\n index: number;\n child: null;\n\n /**\n * Container nodes will have parents unless:\n *\n * - They are the first node of a component or embedded view\n * - They are dynamically created\n */\n parent: TElementNode|TElementContainerNode|null;\n tView: TView|null;\n projection: null;\n value: null;\n}\n\n/** Static data for an */\nexport interface TElementContainerNode extends TNode {\n /** Index in the LView[] array. */\n index: number;\n child: TElementNode|TTextNode|TContainerNode|TElementContainerNode|TProjectionNode|null;\n parent: TElementNode|TElementContainerNode|null;\n tView: null;\n projection: null;\n}\n\n/** Static data for an ICU expression */\nexport interface TIcuContainerNode extends TNode {\n /** Index in the LView[] array. */\n index: number;\n child: null;\n parent: TElementNode|TElementContainerNode|null;\n tView: null;\n projection: null;\n value: TIcu;\n}\n\n/** Static data for an LProjectionNode */\nexport interface TProjectionNode extends TNode {\n /** Index in the data[] array */\n child: null;\n /**\n * Projection nodes will have parents unless they are the first node of a component\n * or embedded view (which means their parent is in a different view and must be\n * retrieved using LView.node).\n */\n parent: TElementNode|TElementContainerNode|null;\n tView: null;\n\n /** Index of the projection node. (See TNode.projection for more info.) */\n projection: number;\n value: null;\n}\n\n/**\n * A union type representing all TNode types that can host a directive.\n */\nexport type TDirectiveHostNode = TElementNode|TContainerNode|TElementContainerNode;\n\n/**\n * This mapping is necessary so we can set input properties and output listeners\n * properly at runtime when property names are minified or aliased.\n *\n * Key: unminified / public input or output name\n * Value: array containing minified / internal name and related directive index\n *\n * The value must be an array to support inputs and outputs with the same name\n * on the same node.\n */\nexport type PropertyAliases = {\n // This uses an object map because using the Map type would be too slow\n [key: string]: PropertyAliasValue\n};\n\n/**\n * Store the runtime input or output names for all the directives.\n *\n * i+0: directive instance index\n * i+1: privateName\n *\n * e.g. [0, 'change-minified']\n */\nexport type PropertyAliasValue = (number|string)[];\n\n/**\n * This array contains information about input properties that\n * need to be set once from attribute data. It's ordered by\n * directive index (relative to element) so it's simple to\n * look up a specific directive's initial input data.\n *\n * Within each sub-array:\n *\n * i+0: attribute name\n * i+1: minified/internal input name\n * i+2: initial value\n *\n * If a directive on a node does not have any input properties\n * that should be set from attributes, its index is set to null\n * to avoid a sparse array.\n *\n * e.g. [null, ['role-min', 'minified-input', 'button']]\n */\nexport type InitialInputData = (InitialInputs|null)[];\n\n/**\n * Used by InitialInputData to store input properties\n * that should be set once from attributes.\n *\n * i+0: attribute name\n * i+1: minified/internal input name\n * i+2: initial value\n *\n * e.g. ['role-min', 'minified-input', 'button']\n */\nexport type InitialInputs = string[];\n\n// Note: This hack is necessary so we don't erroneously get a circular dependency\n// failure based on types.\nexport const unusedValueExportToPlacateAjd = 1;\n\n/**\n * Type representing a set of TNodes that can have local refs (`#foo`) placed on them.\n */\nexport type TNodeWithLocalRefs = TContainerNode|TElementNode|TElementContainerNode;\n\n/**\n * Type for a function that extracts a value for a local refs.\n * Example:\n * - `
` - `nativeDivEl` should point to the native `
` element;\n * - `` - `tplRef` should point to the `TemplateRef` instance;\n */\nexport type LocalRefExtractor = (tNode: TNodeWithLocalRefs, currentView: LView) => any;\n\n/**\n * Returns `true` if the `TNode` has a directive which has `@Input()` for `class` binding.\n *\n * ```\n *
\n * ```\n * and\n * ```\n * @Directive({\n * })\n * class MyDirective {\n * @Input()\n * class: string;\n * }\n * ```\n *\n * In the above case it is necessary to write the reconciled styling information into the\n * directive's input.\n *\n * @param tNode\n */\nexport function hasClassInput(tNode: TNode) {\n return (tNode.flags & TNodeFlags.hasClassInput) !== 0;\n}\n\n/**\n * Returns `true` if the `TNode` has a directive which has `@Input()` for `style` binding.\n *\n * ```\n *
\n * ```\n * and\n * ```\n * @Directive({\n * })\n * class MyDirective {\n * @Input()\n * class: string;\n * }\n * ```\n *\n * In the above case it is necessary to write the reconciled styling information into the\n * directive's input.\n *\n * @param tNode\n */\nexport function hasStyleInput(tNode: TNode) {\n return (tNode.flags & TNodeFlags.hasStyleInput) !== 0;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertDefined, throwError} from '../util/assert';\nimport {TNode, TNodeType, toTNodeTypeAsString} from './interfaces/node';\n\nexport function assertTNodeType(\n tNode: TNode|null, expectedTypes: TNodeType, message?: string): void {\n assertDefined(tNode, 'should be called with a TNode');\n if ((tNode.type & expectedTypes) === 0) {\n throwError(\n message ||\n `Expected [${toTNodeTypeAsString(expectedTypes)}] but got ${\n toTNodeTypeAsString(tNode.type)}.`);\n }\n}\n\nexport function assertPureTNodeType(type: TNodeType) {\n if (!(type === TNodeType.Element || //\n type === TNodeType.Text || //\n type === TNodeType.Container || //\n type === TNodeType.ElementContainer || //\n type === TNodeType.Icu || //\n type === TNodeType.Projection || //\n type === TNodeType.Placeholder)) {\n throwError(`Expected TNodeType to have only a single type selected, but got ${\n toTNodeTypeAsString(type)}.`);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertGreaterThan, assertNotEqual, assertNumber} from '../../util/assert';\nimport {NO_PARENT_INJECTOR, RelativeInjectorLocation, RelativeInjectorLocationFlags} from '../interfaces/injector';\nimport {DECLARATION_VIEW, HEADER_OFFSET, LView} from '../interfaces/view';\n\n\n/// Parent Injector Utils ///////////////////////////////////////////////////////////////\nexport function hasParentInjector(parentLocation: RelativeInjectorLocation): boolean {\n return parentLocation !== NO_PARENT_INJECTOR;\n}\n\nexport function getParentInjectorIndex(parentLocation: RelativeInjectorLocation): number {\n ngDevMode && assertNumber(parentLocation, 'Number expected');\n ngDevMode && assertNotEqual(parentLocation as any, -1, 'Not a valid state.');\n const parentInjectorIndex = parentLocation & RelativeInjectorLocationFlags.InjectorIndexMask;\n ngDevMode &&\n assertGreaterThan(\n parentInjectorIndex, HEADER_OFFSET,\n 'Parent injector must be pointing past HEADER_OFFSET.');\n return parentLocation & RelativeInjectorLocationFlags.InjectorIndexMask;\n}\n\nexport function getParentInjectorViewOffset(parentLocation: RelativeInjectorLocation): number {\n return parentLocation >> RelativeInjectorLocationFlags.ViewOffsetShift;\n}\n\n/**\n * Unwraps a parent injector location number to find the view offset from the current injector,\n * then walks up the declaration view tree until the view is found that contains the parent\n * injector.\n *\n * @param location The location of the parent injector, which contains the view offset\n * @param startView The LView instance from which to start walking up the view tree\n * @returns The LView instance that contains the parent injector\n */\nexport function getParentInjectorView(location: RelativeInjectorLocation, startView: LView): LView {\n let viewOffset = getParentInjectorViewOffset(location);\n let parentView = startView;\n // For most cases, the parent injector can be found on the host node (e.g. for component\n // or container), but we must keep the loop here to support the rarer case of deeply nested\n // tags or inline views, where the parent injector might live many views\n // above the child injector.\n while (viewOffset > 0) {\n parentView = parentView[DECLARATION_VIEW]!;\n viewOffset--;\n }\n return parentView;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {isForwardRef, resolveForwardRef} from '../di/forward_ref';\nimport {injectRootLimpMode, setInjectImplementation} from '../di/inject_switch';\nimport {Injector} from '../di/injector';\nimport {convertToBitFlags} from '../di/injector_compatibility';\nimport {InjectorMarkers} from '../di/injector_marker';\nimport {InjectFlags, InjectOptions} from '../di/interface/injector';\nimport {ProviderToken} from '../di/provider_token';\nimport {Type} from '../interface/type';\nimport {assertDefined, assertEqual, assertIndexInRange} from '../util/assert';\nimport {noSideEffects} from '../util/closure';\n\nimport {assertDirectiveDef, assertNodeInjector, assertTNodeForLView} from './assert';\nimport {emitInstanceCreatedByInjectorEvent, InjectorProfilerContext, runInInjectorProfilerContext, setInjectorProfilerContext} from './debug/injector_profiler';\nimport {getFactoryDef} from './definition_factory';\nimport {throwCyclicDependencyError, throwProviderNotFoundError} from './errors_di';\nimport {NG_ELEMENT_ID, NG_FACTORY_DEF} from './fields';\nimport {registerPreOrderHooks} from './hooks';\nimport {ComponentDef, DirectiveDef} from './interfaces/definition';\nimport {isFactory, NO_PARENT_INJECTOR, NodeInjectorFactory, NodeInjectorOffset, RelativeInjectorLocation, RelativeInjectorLocationFlags} from './interfaces/injector';\nimport {AttributeMarker, TContainerNode, TDirectiveHostNode, TElementContainerNode, TElementNode, TNode, TNodeProviderIndexes, TNodeType} from './interfaces/node';\nimport {isComponentDef, isComponentHost} from './interfaces/type_checks';\nimport {DECLARATION_COMPONENT_VIEW, DECLARATION_VIEW, EMBEDDED_VIEW_INJECTOR, FLAGS, INJECTOR, LView, LViewFlags, T_HOST, TData, TVIEW, TView, TViewType} from './interfaces/view';\nimport {assertTNodeType} from './node_assert';\nimport {enterDI, getCurrentTNode, getLView, leaveDI} from './state';\nimport {isNameOnlyAttributeMarker} from './util/attrs_utils';\nimport {getParentInjectorIndex, getParentInjectorView, hasParentInjector} from './util/injector_utils';\nimport {stringifyForError} from './util/stringify_utils';\n\n\n\n/**\n * Defines if the call to `inject` should include `viewProviders` in its resolution.\n *\n * This is set to true when we try to instantiate a component. This value is reset in\n * `getNodeInjectable` to a value which matches the declaration location of the token about to be\n * instantiated. This is done so that if we are injecting a token which was declared outside of\n * `viewProviders` we don't accidentally pull `viewProviders` in.\n *\n * Example:\n *\n * ```\n * @Injectable()\n * class MyService {\n * constructor(public value: String) {}\n * }\n *\n * @Component({\n * providers: [\n * MyService,\n * {provide: String, value: 'providers' }\n * ]\n * viewProviders: [\n * {provide: String, value: 'viewProviders'}\n * ]\n * })\n * class MyComponent {\n * constructor(myService: MyService, value: String) {\n * // We expect that Component can see into `viewProviders`.\n * expect(value).toEqual('viewProviders');\n * // `MyService` was not declared in `viewProviders` hence it can't see it.\n * expect(myService.value).toEqual('providers');\n * }\n * }\n *\n * ```\n */\nlet includeViewProviders = true;\n\nexport function setIncludeViewProviders(v: boolean): boolean {\n const oldValue = includeViewProviders;\n includeViewProviders = v;\n return oldValue;\n}\n\n/**\n * The number of slots in each bloom filter (used by DI). The larger this number, the fewer\n * directives that will share slots, and thus, the fewer false positives when checking for\n * the existence of a directive.\n */\nconst BLOOM_SIZE = 256;\nconst BLOOM_MASK = BLOOM_SIZE - 1;\n\n/**\n * The number of bits that is represented by a single bloom bucket. JS bit operations are 32 bits,\n * so each bucket represents 32 distinct tokens which accounts for log2(32) = 5 bits of a bloom hash\n * number.\n */\nconst BLOOM_BUCKET_BITS = 5;\n\n/** Counter used to generate unique IDs for directives. */\nlet nextNgElementId = 0;\n\n/** Value used when something wasn't found by an injector. */\nconst NOT_FOUND = {};\n\n/**\n * Registers this directive as present in its node's injector by flipping the directive's\n * corresponding bit in the injector's bloom filter.\n *\n * @param injectorIndex The index of the node injector where this token should be registered\n * @param tView The TView for the injector's bloom filters\n * @param type The directive token to register\n */\nexport function bloomAdd(\n injectorIndex: number, tView: TView, type: ProviderToken|string): void {\n ngDevMode && assertEqual(tView.firstCreatePass, true, 'expected firstCreatePass to be true');\n let id: number|undefined;\n if (typeof type === 'string') {\n id = type.charCodeAt(0) || 0;\n } else if (type.hasOwnProperty(NG_ELEMENT_ID)) {\n id = (type as any)[NG_ELEMENT_ID];\n }\n\n // Set a unique ID on the directive type, so if something tries to inject the directive,\n // we can easily retrieve the ID and hash it into the bloom bit that should be checked.\n if (id == null) {\n id = (type as any)[NG_ELEMENT_ID] = nextNgElementId++;\n }\n\n // We only have BLOOM_SIZE (256) slots in our bloom filter (8 buckets * 32 bits each),\n // so all unique IDs must be modulo-ed into a number from 0 - 255 to fit into the filter.\n const bloomHash = id & BLOOM_MASK;\n\n // Create a mask that targets the specific bit associated with the directive.\n // JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding\n // to bit positions 0 - 31 in a 32 bit integer.\n const mask = 1 << bloomHash;\n\n // Each bloom bucket in `tData` represents `BLOOM_BUCKET_BITS` number of bits of `bloomHash`.\n // Any bits in `bloomHash` beyond `BLOOM_BUCKET_BITS` indicate the bucket offset that the mask\n // should be written to.\n (tView.data as number[])[injectorIndex + (bloomHash >> BLOOM_BUCKET_BITS)] |= mask;\n}\n\n/**\n * Creates (or gets an existing) injector for a given element or container.\n *\n * @param tNode for which an injector should be retrieved / created.\n * @param lView View where the node is stored\n * @returns Node injector\n */\nexport function getOrCreateNodeInjectorForNode(\n tNode: TElementNode|TContainerNode|TElementContainerNode, lView: LView): number {\n const existingInjectorIndex = getInjectorIndex(tNode, lView);\n if (existingInjectorIndex !== -1) {\n return existingInjectorIndex;\n }\n\n const tView = lView[TVIEW];\n if (tView.firstCreatePass) {\n tNode.injectorIndex = lView.length;\n insertBloom(tView.data, tNode); // foundation for node bloom\n insertBloom(lView, null); // foundation for cumulative bloom\n insertBloom(tView.blueprint, null);\n }\n\n const parentLoc = getParentInjectorLocation(tNode, lView);\n const injectorIndex = tNode.injectorIndex;\n\n // If a parent injector can't be found, its location is set to -1.\n // In that case, we don't need to set up a cumulative bloom\n if (hasParentInjector(parentLoc)) {\n const parentIndex = getParentInjectorIndex(parentLoc);\n const parentLView = getParentInjectorView(parentLoc, lView);\n const parentData = parentLView[TVIEW].data as any;\n // Creates a cumulative bloom filter that merges the parent's bloom filter\n // and its own cumulative bloom (which contains tokens for all ancestors)\n for (let i = 0; i < NodeInjectorOffset.BLOOM_SIZE; i++) {\n lView[injectorIndex + i] = parentLView[parentIndex + i] | parentData[parentIndex + i];\n }\n }\n\n lView[injectorIndex + NodeInjectorOffset.PARENT] = parentLoc;\n return injectorIndex;\n}\n\nfunction insertBloom(arr: any[], footer: TNode|null): void {\n arr.push(0, 0, 0, 0, 0, 0, 0, 0, footer);\n}\n\n\nexport function getInjectorIndex(tNode: TNode, lView: LView): number {\n if (tNode.injectorIndex === -1 ||\n // If the injector index is the same as its parent's injector index, then the index has been\n // copied down from the parent node. No injector has been created yet on this node.\n (tNode.parent && tNode.parent.injectorIndex === tNode.injectorIndex) ||\n // After the first template pass, the injector index might exist but the parent values\n // might not have been calculated yet for this instance\n lView[tNode.injectorIndex + NodeInjectorOffset.PARENT] === null) {\n return -1;\n } else {\n ngDevMode && assertIndexInRange(lView, tNode.injectorIndex);\n return tNode.injectorIndex;\n }\n}\n\n/**\n * Finds the index of the parent injector, with a view offset if applicable. Used to set the\n * parent injector initially.\n *\n * @returns Returns a number that is the combination of the number of LViews that we have to go up\n * to find the LView containing the parent inject AND the index of the injector within that LView.\n */\nexport function getParentInjectorLocation(tNode: TNode, lView: LView): RelativeInjectorLocation {\n if (tNode.parent && tNode.parent.injectorIndex !== -1) {\n // If we have a parent `TNode` and there is an injector associated with it we are done, because\n // the parent injector is within the current `LView`.\n return tNode.parent.injectorIndex as RelativeInjectorLocation; // ViewOffset is 0\n }\n\n // When parent injector location is computed it may be outside of the current view. (ie it could\n // be pointing to a declared parent location). This variable stores number of declaration parents\n // we need to walk up in order to find the parent injector location.\n let declarationViewOffset = 0;\n let parentTNode: TNode|null = null;\n let lViewCursor: LView|null = lView;\n\n // The parent injector is not in the current `LView`. We will have to walk the declared parent\n // `LView` hierarchy and look for it. If we walk of the top, that means that there is no parent\n // `NodeInjector`.\n while (lViewCursor !== null) {\n parentTNode = getTNodeFromLView(lViewCursor);\n\n if (parentTNode === null) {\n // If we have no parent, than we are done.\n return NO_PARENT_INJECTOR;\n }\n\n ngDevMode && parentTNode && assertTNodeForLView(parentTNode!, lViewCursor[DECLARATION_VIEW]!);\n // Every iteration of the loop requires that we go to the declared parent.\n declarationViewOffset++;\n lViewCursor = lViewCursor[DECLARATION_VIEW];\n\n if (parentTNode.injectorIndex !== -1) {\n // We found a NodeInjector which points to something.\n return (parentTNode.injectorIndex |\n (declarationViewOffset << RelativeInjectorLocationFlags.ViewOffsetShift)) as\n RelativeInjectorLocation;\n }\n }\n return NO_PARENT_INJECTOR;\n}\n/**\n * Makes a type or an injection token public to the DI system by adding it to an\n * injector's bloom filter.\n *\n * @param di The node injector in which a directive will be added\n * @param token The type or the injection token to be made public\n */\nexport function diPublicInInjector(\n injectorIndex: number, tView: TView, token: ProviderToken): void {\n bloomAdd(injectorIndex, tView, token);\n}\n\n/**\n * Inject static attribute value into directive constructor.\n *\n * This method is used with `factory` functions which are generated as part of\n * `defineDirective` or `defineComponent`. The method retrieves the static value\n * of an attribute. (Dynamic attributes are not supported since they are not resolved\n * at the time of injection and can change over time.)\n *\n * # Example\n * Given:\n * ```\n * @Component(...)\n * class MyComponent {\n * constructor(@Attribute('title') title: string) { ... }\n * }\n * ```\n * When instantiated with\n * ```\n * \n * ```\n *\n * Then factory method generated is:\n * ```\n * MyComponent.ɵcmp = defineComponent({\n * factory: () => new MyComponent(injectAttribute('title'))\n * ...\n * })\n * ```\n *\n * @publicApi\n */\nexport function injectAttributeImpl(tNode: TNode, attrNameToInject: string): string|null {\n ngDevMode && assertTNodeType(tNode, TNodeType.AnyContainer | TNodeType.AnyRNode);\n ngDevMode && assertDefined(tNode, 'expecting tNode');\n if (attrNameToInject === 'class') {\n return tNode.classes;\n }\n if (attrNameToInject === 'style') {\n return tNode.styles;\n }\n\n const attrs = tNode.attrs;\n if (attrs) {\n const attrsLength = attrs.length;\n let i = 0;\n while (i < attrsLength) {\n const value = attrs[i];\n\n // If we hit a `Bindings` or `Template` marker then we are done.\n if (isNameOnlyAttributeMarker(value)) break;\n\n // Skip namespaced attributes\n if (value === AttributeMarker.NamespaceURI) {\n // we skip the next two values\n // as namespaced attributes looks like\n // [..., AttributeMarker.NamespaceURI, 'http://someuri.com/test', 'test:exist',\n // 'existValue', ...]\n i = i + 2;\n } else if (typeof value === 'number') {\n // Skip to the first value of the marked attribute.\n i++;\n while (i < attrsLength && typeof attrs[i] === 'string') {\n i++;\n }\n } else if (value === attrNameToInject) {\n return attrs[i + 1] as string;\n } else {\n i = i + 2;\n }\n }\n }\n return null;\n}\n\n\nfunction notFoundValueOrThrow(\n notFoundValue: T|null, token: ProviderToken, flags: InjectFlags): T|null {\n if ((flags & InjectFlags.Optional) || notFoundValue !== undefined) {\n return notFoundValue;\n } else {\n throwProviderNotFoundError(token, 'NodeInjector');\n }\n}\n\n/**\n * Returns the value associated to the given token from the ModuleInjector or throws exception\n *\n * @param lView The `LView` that contains the `tNode`\n * @param token The token to look for\n * @param flags Injection flags\n * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`\n * @returns the value from the injector or throws an exception\n */\nfunction lookupTokenUsingModuleInjector(\n lView: LView, token: ProviderToken, flags: InjectFlags, notFoundValue?: any): T|null {\n if ((flags & InjectFlags.Optional) && notFoundValue === undefined) {\n // This must be set or the NullInjector will throw for optional deps\n notFoundValue = null;\n }\n\n if ((flags & (InjectFlags.Self | InjectFlags.Host)) === 0) {\n const moduleInjector = lView[INJECTOR];\n // switch to `injectInjectorOnly` implementation for module injector, since module injector\n // should not have access to Component/Directive DI scope (that may happen through\n // `directiveInject` implementation)\n const previousInjectImplementation = setInjectImplementation(undefined);\n try {\n if (moduleInjector) {\n return moduleInjector.get(token, notFoundValue, flags & InjectFlags.Optional);\n } else {\n return injectRootLimpMode(token, notFoundValue, flags & InjectFlags.Optional);\n }\n } finally {\n setInjectImplementation(previousInjectImplementation);\n }\n }\n return notFoundValueOrThrow(notFoundValue, token, flags);\n}\n\n/**\n * Returns the value associated to the given token from the NodeInjectors => ModuleInjector.\n *\n * Look for the injector providing the token by walking up the node injector tree and then\n * the module injector tree.\n *\n * This function patches `token` with `__NG_ELEMENT_ID__` which contains the id for the bloom\n * filter. `-1` is reserved for injecting `Injector` (implemented by `NodeInjector`)\n *\n * @param tNode The Node where the search for the injector should start\n * @param lView The `LView` that contains the `tNode`\n * @param token The token to look for\n * @param flags Injection flags\n * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`\n * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided\n */\nexport function getOrCreateInjectable(\n tNode: TDirectiveHostNode|null, lView: LView, token: ProviderToken,\n flags: InjectFlags = InjectFlags.Default, notFoundValue?: any): T|null {\n if (tNode !== null) {\n // If the view or any of its ancestors have an embedded\n // view injector, we have to look it up there first.\n if (lView[FLAGS] & LViewFlags.HasEmbeddedViewInjector &&\n // The token must be present on the current node injector when the `Self`\n // flag is set, so the lookup on embedded view injector(s) can be skipped.\n !(flags & InjectFlags.Self)) {\n const embeddedInjectorValue =\n lookupTokenUsingEmbeddedInjector(tNode, lView, token, flags, NOT_FOUND);\n if (embeddedInjectorValue !== NOT_FOUND) {\n return embeddedInjectorValue;\n }\n }\n\n // Otherwise try the node injector.\n const value = lookupTokenUsingNodeInjector(tNode, lView, token, flags, NOT_FOUND);\n if (value !== NOT_FOUND) {\n return value;\n }\n }\n\n // Finally, fall back to the module injector.\n return lookupTokenUsingModuleInjector(lView, token, flags, notFoundValue);\n}\n\n/**\n * Returns the value associated to the given token from the node injector.\n *\n * @param tNode The Node where the search for the injector should start\n * @param lView The `LView` that contains the `tNode`\n * @param token The token to look for\n * @param flags Injection flags\n * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`\n * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided\n */\nfunction lookupTokenUsingNodeInjector(\n tNode: TDirectiveHostNode, lView: LView, token: ProviderToken, flags: InjectFlags,\n notFoundValue?: any) {\n const bloomHash = bloomHashBitOrFactory(token);\n // If the ID stored here is a function, this is a special object like ElementRef or TemplateRef\n // so just call the factory function to create it.\n if (typeof bloomHash === 'function') {\n if (!enterDI(lView, tNode, flags)) {\n // Failed to enter DI, try module injector instead. If a token is injected with the @Host\n // flag, the module injector is not searched for that token in Ivy.\n return (flags & InjectFlags.Host) ?\n notFoundValueOrThrow(notFoundValue, token, flags) :\n lookupTokenUsingModuleInjector(lView, token, flags, notFoundValue);\n }\n try {\n let value: unknown;\n\n if (ngDevMode) {\n runInInjectorProfilerContext(\n new NodeInjector(getCurrentTNode() as TElementNode, getLView()), token as Type,\n () => {\n value = bloomHash(flags);\n\n if (value != null) {\n emitInstanceCreatedByInjectorEvent(value);\n }\n });\n } else {\n value = bloomHash(flags);\n }\n\n if (value == null && !(flags & InjectFlags.Optional)) {\n throwProviderNotFoundError(token);\n } else {\n return value;\n }\n } finally {\n leaveDI();\n }\n } else if (typeof bloomHash === 'number') {\n // A reference to the previous injector TView that was found while climbing the element\n // injector tree. This is used to know if viewProviders can be accessed on the current\n // injector.\n let previousTView: TView|null = null;\n let injectorIndex = getInjectorIndex(tNode, lView);\n let parentLocation = NO_PARENT_INJECTOR;\n let hostTElementNode: TNode|null =\n flags & InjectFlags.Host ? lView[DECLARATION_COMPONENT_VIEW][T_HOST] : null;\n\n // If we should skip this injector, or if there is no injector on this node, start by\n // searching the parent injector.\n if (injectorIndex === -1 || flags & InjectFlags.SkipSelf) {\n parentLocation = injectorIndex === -1 ? getParentInjectorLocation(tNode, lView) :\n lView[injectorIndex + NodeInjectorOffset.PARENT];\n\n if (parentLocation === NO_PARENT_INJECTOR || !shouldSearchParent(flags, false)) {\n injectorIndex = -1;\n } else {\n previousTView = lView[TVIEW];\n injectorIndex = getParentInjectorIndex(parentLocation);\n lView = getParentInjectorView(parentLocation, lView);\n }\n }\n\n // Traverse up the injector tree until we find a potential match or until we know there\n // *isn't* a match.\n while (injectorIndex !== -1) {\n ngDevMode && assertNodeInjector(lView, injectorIndex);\n\n // Check the current injector. If it matches, see if it contains token.\n const tView = lView[TVIEW];\n ngDevMode &&\n assertTNodeForLView(tView.data[injectorIndex + NodeInjectorOffset.TNODE] as TNode, lView);\n if (bloomHasToken(bloomHash, injectorIndex, tView.data)) {\n // At this point, we have an injector which *may* contain the token, so we step through\n // the providers and directives associated with the injector's corresponding node to get\n // the instance.\n const instance: T|{}|null = searchTokensOnInjector(\n injectorIndex, lView, token, previousTView, flags, hostTElementNode);\n if (instance !== NOT_FOUND) {\n return instance;\n }\n }\n parentLocation = lView[injectorIndex + NodeInjectorOffset.PARENT];\n if (parentLocation !== NO_PARENT_INJECTOR &&\n shouldSearchParent(\n flags,\n lView[TVIEW].data[injectorIndex + NodeInjectorOffset.TNODE] === hostTElementNode) &&\n bloomHasToken(bloomHash, injectorIndex, lView)) {\n // The def wasn't found anywhere on this node, so it was a false positive.\n // Traverse up the tree and continue searching.\n previousTView = tView;\n injectorIndex = getParentInjectorIndex(parentLocation);\n lView = getParentInjectorView(parentLocation, lView);\n } else {\n // If we should not search parent OR If the ancestor bloom filter value does not have the\n // bit corresponding to the directive we can give up on traversing up to find the specific\n // injector.\n injectorIndex = -1;\n }\n }\n }\n\n return notFoundValue;\n}\n\nfunction searchTokensOnInjector(\n injectorIndex: number, lView: LView, token: ProviderToken, previousTView: TView|null,\n flags: InjectFlags, hostTElementNode: TNode|null) {\n const currentTView = lView[TVIEW];\n const tNode = currentTView.data[injectorIndex + NodeInjectorOffset.TNODE] as TNode;\n // First, we need to determine if view providers can be accessed by the starting element.\n // There are two possibilities\n const canAccessViewProviders = previousTView == null ?\n // 1) This is the first invocation `previousTView == null` which means that we are at the\n // `TNode` of where injector is starting to look. In such a case the only time we are allowed\n // to look into the ViewProviders is if:\n // - we are on a component\n // - AND the injector set `includeViewProviders` to true (implying that the token can see\n // ViewProviders because it is the Component or a Service which itself was declared in\n // ViewProviders)\n (isComponentHost(tNode) && includeViewProviders) :\n // 2) `previousTView != null` which means that we are now walking across the parent nodes.\n // In such a case we are only allowed to look into the ViewProviders if:\n // - We just crossed from child View to Parent View `previousTView != currentTView`\n // - AND the parent TNode is an Element.\n // This means that we just came from the Component's View and therefore are allowed to see\n // into the ViewProviders.\n (previousTView != currentTView && ((tNode.type & TNodeType.AnyRNode) !== 0));\n\n // This special case happens when there is a @host on the inject and when we are searching\n // on the host element node.\n const isHostSpecialCase = (flags & InjectFlags.Host) && hostTElementNode === tNode;\n\n const injectableIdx = locateDirectiveOrProvider(\n tNode, currentTView, token, canAccessViewProviders, isHostSpecialCase);\n if (injectableIdx !== null) {\n return getNodeInjectable(lView, currentTView, injectableIdx, tNode as TElementNode);\n } else {\n return NOT_FOUND;\n }\n}\n\n/**\n * Searches for the given token among the node's directives and providers.\n *\n * @param tNode TNode on which directives are present.\n * @param tView The tView we are currently processing\n * @param token Provider token or type of a directive to look for.\n * @param canAccessViewProviders Whether view providers should be considered.\n * @param isHostSpecialCase Whether the host special case applies.\n * @returns Index of a found directive or provider, or null when none found.\n */\nexport function locateDirectiveOrProvider(\n tNode: TNode, tView: TView, token: ProviderToken|string, canAccessViewProviders: boolean,\n isHostSpecialCase: boolean|number): number|null {\n const nodeProviderIndexes = tNode.providerIndexes;\n const tInjectables = tView.data;\n\n const injectablesStart = nodeProviderIndexes & TNodeProviderIndexes.ProvidersStartIndexMask;\n const directivesStart = tNode.directiveStart;\n const directiveEnd = tNode.directiveEnd;\n const cptViewProvidersCount =\n nodeProviderIndexes >> TNodeProviderIndexes.CptViewProvidersCountShift;\n const startingIndex =\n canAccessViewProviders ? injectablesStart : injectablesStart + cptViewProvidersCount;\n // When the host special case applies, only the viewProviders and the component are visible\n const endIndex = isHostSpecialCase ? injectablesStart + cptViewProvidersCount : directiveEnd;\n for (let i = startingIndex; i < endIndex; i++) {\n const providerTokenOrDef = tInjectables[i] as ProviderToken| DirectiveDef| string;\n if (i < directivesStart && token === providerTokenOrDef ||\n i >= directivesStart && (providerTokenOrDef as DirectiveDef).type === token) {\n return i;\n }\n }\n if (isHostSpecialCase) {\n const dirDef = tInjectables[directivesStart] as DirectiveDef;\n if (dirDef && isComponentDef(dirDef) && dirDef.type === token) {\n return directivesStart;\n }\n }\n return null;\n}\n\n/**\n * Retrieve or instantiate the injectable from the `LView` at particular `index`.\n *\n * This function checks to see if the value has already been instantiated and if so returns the\n * cached `injectable`. Otherwise if it detects that the value is still a factory it\n * instantiates the `injectable` and caches the value.\n */\nexport function getNodeInjectable(\n lView: LView, tView: TView, index: number, tNode: TDirectiveHostNode): any {\n let value = lView[index];\n const tData = tView.data;\n if (isFactory(value)) {\n const factory: NodeInjectorFactory = value;\n if (factory.resolving) {\n throwCyclicDependencyError(stringifyForError(tData[index]));\n }\n const previousIncludeViewProviders = setIncludeViewProviders(factory.canSeeViewProviders);\n factory.resolving = true;\n\n let prevInjectContext: InjectorProfilerContext|undefined;\n if (ngDevMode) {\n // tData indexes mirror the concrete instances in its corresponding LView.\n // lView[index] here is either the injectable instace itself or a factory,\n // therefore tData[index] is the constructor of that injectable or a\n // definition object that contains the constructor in a `.type` field.\n const token =\n (tData[index] as (DirectiveDef| ComponentDef)).type || tData[index];\n const injector = new NodeInjector(tNode, lView);\n prevInjectContext = setInjectorProfilerContext({injector, token});\n }\n\n const previousInjectImplementation =\n factory.injectImpl ? setInjectImplementation(factory.injectImpl) : null;\n const success = enterDI(lView, tNode, InjectFlags.Default);\n ngDevMode &&\n assertEqual(\n success, true,\n 'Because flags do not contain \\`SkipSelf\\' we expect this to always succeed.');\n try {\n value = lView[index] = factory.factory(undefined, tData, lView, tNode);\n\n ngDevMode && emitInstanceCreatedByInjectorEvent(value);\n\n // This code path is hit for both directives and providers.\n // For perf reasons, we want to avoid searching for hooks on providers.\n // It does no harm to try (the hooks just won't exist), but the extra\n // checks are unnecessary and this is a hot path. So we check to see\n // if the index of the dependency is in the directive range for this\n // tNode. If it's not, we know it's a provider and skip hook registration.\n if (tView.firstCreatePass && index >= tNode.directiveStart) {\n ngDevMode && assertDirectiveDef(tData[index]);\n registerPreOrderHooks(index, tData[index] as DirectiveDef, tView);\n }\n } finally {\n ngDevMode && setInjectorProfilerContext(prevInjectContext!);\n\n previousInjectImplementation !== null &&\n setInjectImplementation(previousInjectImplementation);\n setIncludeViewProviders(previousIncludeViewProviders);\n factory.resolving = false;\n leaveDI();\n }\n }\n return value;\n}\n\n/**\n * Returns the bit in an injector's bloom filter that should be used to determine whether or not\n * the directive might be provided by the injector.\n *\n * When a directive is public, it is added to the bloom filter and given a unique ID that can be\n * retrieved on the Type. When the directive isn't public or the token is not a directive `null`\n * is returned as the node injector can not possibly provide that token.\n *\n * @param token the injection token\n * @returns the matching bit to check in the bloom filter or `null` if the token is not known.\n * When the returned value is negative then it represents special values such as `Injector`.\n */\nexport function bloomHashBitOrFactory(token: ProviderToken|string): number|Function|undefined {\n ngDevMode && assertDefined(token, 'token must be defined');\n if (typeof token === 'string') {\n return token.charCodeAt(0) || 0;\n }\n const tokenId: number|undefined =\n // First check with `hasOwnProperty` so we don't get an inherited ID.\n token.hasOwnProperty(NG_ELEMENT_ID) ? (token as any)[NG_ELEMENT_ID] : undefined;\n // Negative token IDs are used for special objects such as `Injector`\n if (typeof tokenId === 'number') {\n if (tokenId >= 0) {\n return tokenId & BLOOM_MASK;\n } else {\n ngDevMode &&\n assertEqual(tokenId, InjectorMarkers.Injector, 'Expecting to get Special Injector Id');\n return createNodeInjector;\n }\n } else {\n return tokenId;\n }\n}\n\nexport function bloomHasToken(bloomHash: number, injectorIndex: number, injectorView: LView|TData) {\n // Create a mask that targets the specific bit associated with the directive we're looking for.\n // JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding\n // to bit positions 0 - 31 in a 32 bit integer.\n const mask = 1 << bloomHash;\n\n // Each bloom bucket in `injectorView` represents `BLOOM_BUCKET_BITS` number of bits of\n // `bloomHash`. Any bits in `bloomHash` beyond `BLOOM_BUCKET_BITS` indicate the bucket offset\n // that should be used.\n const value = injectorView[injectorIndex + (bloomHash >> BLOOM_BUCKET_BITS)];\n\n // If the bloom filter value has the bit corresponding to the directive's bloomBit flipped on,\n // this injector is a potential match.\n return !!(value & mask);\n}\n\n/** Returns true if flags prevent parent injector from being searched for tokens */\nfunction shouldSearchParent(flags: InjectFlags, isFirstHostTNode: boolean): boolean|number {\n return !(flags & InjectFlags.Self) && !(flags & InjectFlags.Host && isFirstHostTNode);\n}\n\nexport function getNodeInjectorLView(nodeInjector: NodeInjector): LView {\n return (nodeInjector as any)._lView as LView;\n}\n\nexport function getNodeInjectorTNode(nodeInjector: NodeInjector): TElementNode|TContainerNode|\n TElementContainerNode|null {\n return (nodeInjector as any)._tNode as TElementNode | TContainerNode | TElementContainerNode |\n null;\n}\n\nexport class NodeInjector implements Injector {\n constructor(\n private _tNode: TElementNode|TContainerNode|TElementContainerNode|null,\n private _lView: LView) {}\n\n get(token: any, notFoundValue?: any, flags?: InjectFlags|InjectOptions): any {\n return getOrCreateInjectable(\n this._tNode, this._lView, token, convertToBitFlags(flags), notFoundValue);\n }\n}\n\n/** Creates a `NodeInjector` for the current node. */\nexport function createNodeInjector(): Injector {\n return new NodeInjector(getCurrentTNode()! as TDirectiveHostNode, getLView()) as any;\n}\n\n/**\n * @codeGenApi\n */\nexport function ɵɵgetInheritedFactory(type: Type): (type: Type) => T {\n return noSideEffects(() => {\n const ownConstructor = type.prototype.constructor;\n const ownFactory = ownConstructor[NG_FACTORY_DEF] || getFactoryOf(ownConstructor);\n const objectPrototype = Object.prototype;\n let parent = Object.getPrototypeOf(type.prototype).constructor;\n\n // Go up the prototype until we hit `Object`.\n while (parent && parent !== objectPrototype) {\n const factory = parent[NG_FACTORY_DEF] || getFactoryOf(parent);\n\n // If we hit something that has a factory and the factory isn't the same as the type,\n // we've found the inherited factory. Note the check that the factory isn't the type's\n // own factory is redundant in most cases, but if the user has custom decorators on the\n // class, this lookup will start one level down in the prototype chain, causing us to\n // find the own factory first and potentially triggering an infinite loop downstream.\n if (factory && factory !== ownFactory) {\n return factory;\n }\n\n parent = Object.getPrototypeOf(parent);\n }\n\n // There is no factory defined. Either this was improper usage of inheritance\n // (no Angular decorator on the superclass) or there is no constructor at all\n // in the inheritance chain. Since the two cases cannot be distinguished, the\n // latter has to be assumed.\n return (t: Type) => new t();\n });\n}\n\nfunction getFactoryOf(type: Type): ((type?: Type) => T | null)|null {\n if (isForwardRef(type)) {\n return () => {\n const factory = getFactoryOf(resolveForwardRef(type));\n return factory && factory();\n };\n }\n return getFactoryDef(type);\n}\n\n/**\n * Returns a value from the closest embedded or node injector.\n *\n * @param tNode The Node where the search for the injector should start\n * @param lView The `LView` that contains the `tNode`\n * @param token The token to look for\n * @param flags Injection flags\n * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`\n * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided\n */\nfunction lookupTokenUsingEmbeddedInjector(\n tNode: TDirectiveHostNode, lView: LView, token: ProviderToken, flags: InjectFlags,\n notFoundValue?: any) {\n let currentTNode: TDirectiveHostNode|null = tNode;\n let currentLView: LView|null = lView;\n\n // When an LView with an embedded view injector is inserted, it'll likely be interlaced with\n // nodes who may have injectors (e.g. node injector -> embedded view injector -> node injector).\n // Since the bloom filters for the node injectors have already been constructed and we don't\n // have a way of extracting the records from an injector, the only way to maintain the correct\n // hierarchy when resolving the value is to walk it node-by-node while attempting to resolve\n // the token at each level.\n while (currentTNode !== null && currentLView !== null &&\n (currentLView[FLAGS] & LViewFlags.HasEmbeddedViewInjector) &&\n !(currentLView[FLAGS] & LViewFlags.IsRoot)) {\n ngDevMode && assertTNodeForLView(currentTNode, currentLView);\n\n // Note that this lookup on the node injector is using the `Self` flag, because\n // we don't want the node injector to look at any parent injectors since we\n // may hit the embedded view injector first.\n const nodeInjectorValue = lookupTokenUsingNodeInjector(\n currentTNode, currentLView, token, flags | InjectFlags.Self, NOT_FOUND);\n if (nodeInjectorValue !== NOT_FOUND) {\n return nodeInjectorValue;\n }\n\n // Has an explicit type due to a TS bug: https://github.com/microsoft/TypeScript/issues/33191\n let parentTNode: TElementNode|TContainerNode|null = currentTNode.parent;\n\n // `TNode.parent` includes the parent within the current view only. If it doesn't exist,\n // it means that we've hit the view boundary and we need to go up to the next view.\n if (!parentTNode) {\n // Before we go to the next LView, check if the token exists on the current embedded injector.\n const embeddedViewInjector = currentLView[EMBEDDED_VIEW_INJECTOR];\n if (embeddedViewInjector) {\n const embeddedViewInjectorValue =\n embeddedViewInjector.get(token, NOT_FOUND as T | {}, flags);\n if (embeddedViewInjectorValue !== NOT_FOUND) {\n return embeddedViewInjectorValue;\n }\n }\n\n // Otherwise keep going up the tree.\n parentTNode = getTNodeFromLView(currentLView);\n currentLView = currentLView[DECLARATION_VIEW];\n }\n\n currentTNode = parentTNode;\n }\n\n return notFoundValue;\n}\n\n/** Gets the TNode associated with an LView inside of the declaration view. */\nfunction getTNodeFromLView(lView: LView): TElementNode|TElementContainerNode|null {\n const tView = lView[TVIEW];\n const tViewType = tView.type;\n\n // The parent pointer differs based on `TView.type`.\n if (tViewType === TViewType.Embedded) {\n ngDevMode && assertDefined(tView.declTNode, 'Embedded TNodes should have declaration parents.');\n return tView.declTNode as TElementContainerNode;\n } else if (tViewType === TViewType.Component) {\n // Components don't have `TView.declTNode` because each instance of component could be\n // inserted in different location, hence `TView.declTNode` is meaningless.\n return lView[T_HOST] as TElementNode;\n }\n\n return null;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport {injectAttributeImpl} from '../di';\nimport {getCurrentTNode} from '../state';\n\n/**\n * Facade for the attribute injection from DI.\n *\n * @codeGenApi\n */\nexport function ɵɵinjectAttribute(attrNameToInject: string): string|null {\n return injectAttributeImpl(getCurrentTNode()!, attrNameToInject);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {ɵɵinjectAttribute} from '../render3/instructions/di_attr';\nimport {makeParamDecorator} from '../util/decorators';\n\n\n/**\n * Type of the Attribute decorator / constructor function.\n *\n * @publicApi\n */\nexport interface AttributeDecorator {\n /**\n * Parameter decorator for a directive constructor that designates\n * a host-element attribute whose value is injected as a constant string literal.\n *\n * @usageNotes\n *\n * Suppose we have an `` element and want to know its `type`.\n *\n * ```html\n * \n * ```\n *\n * The following example uses the decorator to inject the string literal `text` in a directive.\n *\n * {@example core/ts/metadata/metadata.ts region='attributeMetadata'}\n *\n * The following example uses the decorator in a component constructor.\n *\n * {@example core/ts/metadata/metadata.ts region='attributeFactory'}\n *\n */\n (name: string): any;\n new(name: string): Attribute;\n}\n\n/**\n * Type of the Attribute metadata.\n *\n * @publicApi\n */\nexport interface Attribute {\n /**\n * The name of the attribute whose value can be injected.\n */\n attributeName: string;\n}\n\n/**\n * Attribute decorator and metadata.\n *\n * @Annotation\n * @publicApi\n */\nexport const Attribute: AttributeDecorator = makeParamDecorator(\n 'Attribute',\n (attributeName?: string) =>\n ({attributeName, __NG_ELEMENT_ID__: () => ɵɵinjectAttribute(attributeName!)}));\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {R3DependencyMetadataFacade} from '../../compiler/compiler_facade';\nimport {RuntimeError, RuntimeErrorCode} from '../../errors';\nimport {Type} from '../../interface/type';\nimport {ReflectionCapabilities} from '../../reflection/reflection_capabilities';\nimport {Host, Inject, Optional, Self, SkipSelf} from '../metadata';\nimport {Attribute} from '../metadata_attr';\n\nlet _reflect: ReflectionCapabilities|null = null;\n\nexport function getReflect(): ReflectionCapabilities {\n return (_reflect = _reflect || new ReflectionCapabilities());\n}\n\nexport function reflectDependencies(type: Type): R3DependencyMetadataFacade[] {\n return convertDependencies(getReflect().parameters(type));\n}\n\nexport function convertDependencies(deps: any[]): R3DependencyMetadataFacade[] {\n return deps.map(dep => reflectDependency(dep));\n}\n\nfunction reflectDependency(dep: any|any[]): R3DependencyMetadataFacade {\n const meta: R3DependencyMetadataFacade = {\n token: null,\n attribute: null,\n host: false,\n optional: false,\n self: false,\n skipSelf: false,\n };\n\n if (Array.isArray(dep) && dep.length > 0) {\n for (let j = 0; j < dep.length; j++) {\n const param = dep[j];\n if (param === undefined) {\n // param may be undefined if type of dep is not set by ngtsc\n continue;\n }\n\n const proto = Object.getPrototypeOf(param);\n\n if (param instanceof Optional || proto.ngMetadataName === 'Optional') {\n meta.optional = true;\n } else if (param instanceof SkipSelf || proto.ngMetadataName === 'SkipSelf') {\n meta.skipSelf = true;\n } else if (param instanceof Self || proto.ngMetadataName === 'Self') {\n meta.self = true;\n } else if (param instanceof Host || proto.ngMetadataName === 'Host') {\n meta.host = true;\n } else if (param instanceof Inject) {\n meta.token = param.token;\n } else if (param instanceof Attribute) {\n if (param.attributeName === undefined) {\n throw new RuntimeError(\n RuntimeErrorCode.INVALID_INJECTION_TOKEN,\n ngDevMode && `Attribute name must be defined.`);\n }\n meta.attribute = param.attributeName;\n } else {\n meta.token = param;\n }\n }\n } else if (dep === undefined || (Array.isArray(dep) && dep.length === 0)) {\n meta.token = null;\n } else {\n meta.token = dep;\n }\n return meta;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nimport {Type} from '../interface/type';\nimport {NgModuleType} from '../metadata/ng_module_def';\nimport {getNgModuleDef} from '../render3/definition';\nimport {stringify} from '../util/stringify';\n\n/**\n * Map of module-id to the corresponding NgModule.\n */\nconst modules = new Map();\n\n/**\n * Whether to check for duplicate NgModule registrations.\n *\n * This can be disabled for testing.\n */\nlet checkForDuplicateNgModules = true;\n\nfunction assertSameOrNotExisting(id: string, type: Type|null, incoming: Type): void {\n if (type && type !== incoming && checkForDuplicateNgModules) {\n throw new Error(\n `Duplicate module registered for ${id} - ${stringify(type)} vs ${stringify(type.name)}`);\n }\n}\n\n/**\n * Adds the given NgModule type to Angular's NgModule registry.\n *\n * This is generated as a side-effect of NgModule compilation. Note that the `id` is passed in\n * explicitly and not read from the NgModule definition. This is for two reasons: it avoids a\n * megamorphic read, and in JIT there's a chicken-and-egg problem where the NgModule may not be\n * fully resolved when it's registered.\n *\n * @codeGenApi\n */\nexport function registerNgModuleType(ngModuleType: NgModuleType, id: string): void {\n const existing = modules.get(id) || null;\n assertSameOrNotExisting(id, existing, ngModuleType);\n modules.set(id, ngModuleType);\n}\n\nexport function clearModulesForTest(): void {\n modules.clear();\n}\n\nexport function getRegisteredNgModuleType(id: string): NgModuleType|undefined {\n return modules.get(id);\n}\n\n/**\n * Control whether the NgModule registration system enforces that each NgModule type registered has\n * a unique id.\n *\n * This is useful for testing as the NgModule registry cannot be properly reset between tests with\n * Angular's current API.\n */\nexport function setAllowDuplicateNgModuleIdsForTest(allowDuplicates: boolean): void {\n checkForDuplicateNgModules = !allowDuplicates;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Type} from '../interface/type';\nimport {assertLessThan} from '../util/assert';\n\nimport {ɵɵdefineInjectable} from './interface/defs';\n\n/**\n * Creates a token that can be used in a DI Provider.\n *\n * Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a\n * runtime representation) such as when injecting an interface, callable type, array or\n * parameterized type.\n *\n * `InjectionToken` is parameterized on `T` which is the type of object which will be returned by\n * the `Injector`. This provides an additional level of type safety.\n *\n *
\n *\n * **Important Note**: Ensure that you use the same instance of the `InjectionToken` in both the\n * provider and the injection call. Creating a new instance of `InjectionToken` in different places,\n * even with the same description, will be treated as different tokens by Angular's DI system,\n * leading to a `NullInjectorError`.\n *\n *
\n *\n * \n *\n * When creating an `InjectionToken`, you can optionally specify a factory function which returns\n * (possibly by creating) a default value of the parameterized type `T`. This sets up the\n * `InjectionToken` using this factory as a provider as if it was defined explicitly in the\n * application's root injector. If the factory function, which takes zero arguments, needs to inject\n * dependencies, it can do so using the [`inject`](api/core/inject) function.\n * As you can see in the Tree-shakable InjectionToken example below.\n *\n * Additionally, if a `factory` is specified you can also specify the `providedIn` option, which\n * overrides the above behavior and marks the token as belonging to a particular `@NgModule` (note:\n * this option is now deprecated). As mentioned above, `'root'` is the default value for\n * `providedIn`.\n *\n * The `providedIn: NgModule` and `providedIn: 'any'` options are deprecated.\n *\n * @usageNotes\n * ### Basic Examples\n *\n * ### Plain InjectionToken\n *\n * {@example core/di/ts/injector_spec.ts region='InjectionToken'}\n *\n * ### Tree-shakable InjectionToken\n *\n * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}\n *\n * @publicApi\n */\nexport class InjectionToken {\n /** @internal */\n readonly ngMetadataName = 'InjectionToken';\n\n readonly ɵprov: unknown;\n\n /**\n * @param _desc Description for the token,\n * used only for debugging purposes,\n * it should but does not need to be unique\n * @param options Options for the token's usage, as described above\n */\n constructor(protected _desc: string, options?: {\n providedIn?: Type|'root'|'platform'|'any'|null, factory: () => T\n }) {\n this.ɵprov = undefined;\n if (typeof options == 'number') {\n (typeof ngDevMode === 'undefined' || ngDevMode) &&\n assertLessThan(options, 0, 'Only negative numbers are supported here');\n // This is a special hack to assign __NG_ELEMENT_ID__ to this instance.\n // See `InjectorMarkers`\n (this as any).__NG_ELEMENT_ID__ = options;\n } else if (options !== undefined) {\n this.ɵprov = ɵɵdefineInjectable({\n token: this,\n providedIn: options.providedIn || 'root',\n factory: options.factory,\n });\n }\n }\n\n /**\n * @internal\n */\n get multi(): InjectionToken> {\n return this as InjectionToken>;\n }\n\n toString(): string {\n return `InjectionToken ${this._desc}`;\n }\n}\n\nexport interface InjectableDefToken extends InjectionToken {\n ɵprov: unknown;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {RuntimeError, RuntimeErrorCode} from '../../errors';\n\n/**\n * Most of the use of `document` in Angular is from within the DI system so it is possible to simply\n * inject the `DOCUMENT` token and are done.\n *\n * Ivy is special because it does not rely upon the DI and must get hold of the document some other\n * way.\n *\n * The solution is to define `getDocument()` and `setDocument()` top-level functions for ivy.\n * Wherever ivy needs the global document, it calls `getDocument()` instead.\n *\n * When running ivy outside of a browser environment, it is necessary to call `setDocument()` to\n * tell ivy what the global `document` is.\n *\n * Angular does this for us in each of the standard platforms (`Browser` and `Server`)\n * by calling `setDocument()` when providing the `DOCUMENT` token.\n */\nlet DOCUMENT: Document|undefined = undefined;\n\n/**\n * Tell ivy what the `document` is for this platform.\n *\n * It is only necessary to call this if the current platform is not a browser.\n *\n * @param document The object representing the global `document` in this environment.\n */\nexport function setDocument(document: Document|undefined): void {\n DOCUMENT = document;\n}\n\n/**\n * Access the object that represents the `document` for this platform.\n *\n * Ivy calls this whenever it needs to access the `document` object.\n * For example to create the renderer or to do sanitization.\n */\nexport function getDocument(): Document {\n if (DOCUMENT !== undefined) {\n return DOCUMENT;\n } else if (typeof document !== 'undefined') {\n return document;\n }\n\n throw new RuntimeError(\n RuntimeErrorCode.MISSING_DOCUMENT,\n (typeof ngDevMode === 'undefined' || ngDevMode) &&\n `The document object is not available in this context. Make sure the DOCUMENT injection token is provided.`);\n\n // No \"document\" can be found. This should only happen if we are running ivy outside Angular and\n // the current platform is not a browser. Since this is not a supported scenario at the moment\n // this should not happen in Angular apps.\n // Once we support running ivy outside of Angular we will need to publish `setDocument()` as a\n // public API.\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {InjectionToken} from './di/injection_token';\nimport {getDocument} from './render3/interfaces/document';\n\n/**\n * A [DI token](guide/glossary#di-token \"DI token definition\") representing a string ID, used\n * primarily for prefixing application attributes and CSS styles when\n * {@link ViewEncapsulation#Emulated} is being used.\n *\n * The token is needed in cases when multiple applications are bootstrapped on a page\n * (for example, using `bootstrapApplication` calls). In this case, ensure that those applications\n * have different `APP_ID` value setup. For example:\n *\n * ```\n * bootstrapApplication(ComponentA, {\n * providers: [\n * { provide: APP_ID, useValue: 'app-a' },\n * // ... other providers ...\n * ]\n * });\n *\n * bootstrapApplication(ComponentB, {\n * providers: [\n * { provide: APP_ID, useValue: 'app-b' },\n * // ... other providers ...\n * ]\n * });\n * ```\n *\n * By default, when there is only one application bootstrapped, you don't need to provide the\n * `APP_ID` token (the `ng` will be used as an app ID).\n *\n * @publicApi\n */\nexport const APP_ID = new InjectionToken('AppId', {\n providedIn: 'root',\n factory: () => DEFAULT_APP_ID,\n});\n\n/** Default value of the `APP_ID` token. */\nconst DEFAULT_APP_ID = 'ng';\n\n/**\n * A function that is executed when a platform is initialized.\n * @publicApi\n */\nexport const PLATFORM_INITIALIZER = new InjectionToken void>>('Platform Initializer');\n\n/**\n * A token that indicates an opaque platform ID.\n * @publicApi\n */\nexport const PLATFORM_ID = new InjectionToken('Platform ID', {\n providedIn: 'platform',\n factory: () => 'unknown', // set a default platform name, when none set explicitly\n});\n\n/**\n * A [DI token](guide/glossary#di-token \"DI token definition\") that indicates the root directory of\n * the application\n * @publicApi\n * @deprecated\n */\nexport const PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');\n\n// We keep this token here, rather than the animations package, so that modules that only care\n// about which animations module is loaded (e.g. the CDK) can retrieve it without having to\n// include extra dependencies. See #44970 for more context.\n\n/**\n * A [DI token](guide/glossary#di-token \"DI token definition\") that indicates which animations\n * module has been loaded.\n * @publicApi\n */\nexport const ANIMATION_MODULE_TYPE =\n new InjectionToken<'NoopAnimations'|'BrowserAnimations'>('AnimationModuleType');\n\n// TODO(crisbeto): link to CSP guide here.\n/**\n * Token used to configure the [Content Security Policy](https://web.dev/strict-csp/) nonce that\n * Angular will apply when inserting inline styles. If not provided, Angular will look up its value\n * from the `ngCspNonce` attribute of the application root node.\n *\n * @publicApi\n */\nexport const CSP_NONCE = new InjectionToken('CSP nonce', {\n providedIn: 'root',\n factory: () => {\n // Ideally we wouldn't have to use `querySelector` here since we know that the nonce will be on\n // the root node, but because the token value is used in renderers, it has to be available\n // *very* early in the bootstrapping process. This should be a fairly shallow search, because\n // the app won't have been added to the DOM yet. Some approaches that were considered:\n // 1. Find the root node through `ApplicationRef.components[i].location` - normally this would\n // be enough for our purposes, but the token is injected very early so the `components` array\n // isn't populated yet.\n // 2. Find the root `LView` through the current `LView` - renderers are a prerequisite to\n // creating the `LView`. This means that no `LView` will have been entered when this factory is\n // invoked for the root component.\n // 3. Have the token factory return `() => string` which is invoked when a nonce is requested -\n // the slightly later execution does allow us to get an `LView` reference, but the fact that\n // it is a function means that it could be executed at *any* time (including immediately) which\n // may lead to weird bugs.\n // 4. Have the `ComponentFactory` read the attribute and provide it to the injector under the\n // hood - has the same problem as #1 and #2 in that the renderer is used to query for the root\n // node and the nonce value needs to be available when the renderer is created.\n return getDocument().body?.querySelector('[ngCspNonce]')?.getAttribute('ngCspNonce') || null;\n },\n});\n\n/**\n * Internal token to collect all SSR-related features enabled for this application.\n *\n * Note: the token is in `core` to let other packages register features (the `core`\n * package is imported in other packages).\n */\nexport const ENABLED_SSR_FEATURES = new InjectionToken>(\n (typeof ngDevMode === 'undefined' || ngDevMode) ? 'ENABLED_SSR_FEATURES' : '', {\n providedIn: 'root',\n factory: () => new Set(),\n });\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {InjectionToken} from './injection_token';\n\n/**\n * A multi-provider token for initialization functions that will run upon construction of an\n * environment injector.\n *\n * @publicApi\n */\nexport const ENVIRONMENT_INITIALIZER = new InjectionToken<() => void>('ENVIRONMENT_INITIALIZER');\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {InjectionToken} from './injection_token';\nimport {Injector} from './injector';\nimport {InjectorMarkers} from './injector_marker';\n\n\n\n/**\n * An InjectionToken that gets the current `Injector` for `createInjector()`-style injectors.\n *\n * Requesting this token instead of `Injector` allows `StaticInjector` to be tree-shaken from a\n * project.\n *\n * @publicApi\n */\nexport const INJECTOR = new InjectionToken(\n 'INJECTOR',\n // Disable tslint because this is const enum which gets inlined not top level prop access.\n // tslint:disable-next-line: no-toplevel-property-access\n InjectorMarkers.Injector as any, // Special value used by Ivy to identify `Injector`.\n);\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Type} from '../interface/type';\n\nimport {InjectionToken} from './injection_token';\n\nexport const INJECTOR_DEF_TYPES = new InjectionToken>('INJECTOR_DEF_TYPES');\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {stringify} from '../util/stringify';\nimport {Injector} from './injector';\nimport {THROW_IF_NOT_FOUND} from './injector_compatibility';\n\nexport class NullInjector implements Injector {\n get(token: any, notFoundValue: any = THROW_IF_NOT_FOUND): any {\n if (notFoundValue === THROW_IF_NOT_FOUND) {\n const error = new Error(`NullInjectorError: No provider for ${stringify(token)}!`);\n error.name = 'NullInjectorError';\n throw error;\n }\n return notFoundValue;\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {RuntimeError, RuntimeErrorCode} from '../errors';\nimport {Type} from '../interface/type';\nimport {getComponentDef} from '../render3/definition';\nimport {getFactoryDef} from '../render3/definition_factory';\nimport {throwCyclicDependencyError, throwInvalidProviderError} from '../render3/errors_di';\nimport {stringifyForError} from '../render3/util/stringify_utils';\nimport {deepForEach} from '../util/array_utils';\nimport {EMPTY_ARRAY} from '../util/empty';\nimport {getClosureSafeProperty} from '../util/property';\nimport {stringify} from '../util/stringify';\n\nimport {resolveForwardRef} from './forward_ref';\nimport {ENVIRONMENT_INITIALIZER} from './initializer_token';\nimport {ɵɵinject as inject} from './injector_compatibility';\nimport {getInjectorDef, InjectorType, InjectorTypeWithProviders} from './interface/defs';\nimport {ClassProvider, ConstructorProvider, EnvironmentProviders, ExistingProvider, FactoryProvider, ImportedNgModuleProviders, InternalEnvironmentProviders, isEnvironmentProviders, ModuleWithProviders, Provider, StaticClassProvider, TypeProvider, ValueProvider} from './interface/provider';\nimport {INJECTOR_DEF_TYPES} from './internal_tokens';\n\n/**\n * Wrap an array of `Provider`s into `EnvironmentProviders`, preventing them from being accidentally\n * referenced in `@Component` in a component injector.\n */\nexport function makeEnvironmentProviders(providers: (Provider|EnvironmentProviders)[]):\n EnvironmentProviders {\n return {\n ɵproviders: providers,\n } as unknown as EnvironmentProviders;\n}\n\n/**\n * A source of providers for the `importProvidersFrom` function.\n *\n * @publicApi\n */\nexport type ImportProvidersSource =\n Type|ModuleWithProviders|Array;\n\ntype WalkProviderTreeVisitor =\n (provider: SingleProvider, container: Type|InjectorType) => void;\n\n/**\n * Collects providers from all NgModules and standalone components, including transitively imported\n * ones.\n *\n * Providers extracted via `importProvidersFrom` are only usable in an application injector or\n * another environment injector (such as a route injector). They should not be used in component\n * providers.\n *\n * More information about standalone components can be found in [this\n * guide](guide/standalone-components).\n *\n * @usageNotes\n * The results of the `importProvidersFrom` call can be used in the `bootstrapApplication` call:\n *\n * ```typescript\n * await bootstrapApplication(RootComponent, {\n * providers: [\n * importProvidersFrom(NgModuleOne, NgModuleTwo)\n * ]\n * });\n * ```\n *\n * You can also use the `importProvidersFrom` results in the `providers` field of a route, when a\n * standalone component is used:\n *\n * ```typescript\n * export const ROUTES: Route[] = [\n * {\n * path: 'foo',\n * providers: [\n * importProvidersFrom(NgModuleOne, NgModuleTwo)\n * ],\n * component: YourStandaloneComponent\n * }\n * ];\n * ```\n *\n * @returns Collected providers from the specified list of types.\n * @publicApi\n */\nexport function importProvidersFrom(...sources: ImportProvidersSource[]): EnvironmentProviders {\n return {\n ɵproviders: internalImportProvidersFrom(true, sources),\n ɵfromNgModule: true,\n } as InternalEnvironmentProviders;\n}\n\nexport function internalImportProvidersFrom(\n checkForStandaloneCmp: boolean, ...sources: ImportProvidersSource[]): Provider[] {\n const providersOut: SingleProvider[] = [];\n const dedup = new Set>(); // already seen types\n let injectorTypesWithProviders: InjectorTypeWithProviders[]|undefined;\n\n const collectProviders: WalkProviderTreeVisitor = (provider) => {\n providersOut.push(provider);\n };\n\n deepForEach(sources, source => {\n if ((typeof ngDevMode === 'undefined' || ngDevMode) && checkForStandaloneCmp) {\n const cmpDef = getComponentDef(source);\n if (cmpDef?.standalone) {\n throw new RuntimeError(\n RuntimeErrorCode.IMPORT_PROVIDERS_FROM_STANDALONE,\n `Importing providers supports NgModule or ModuleWithProviders but got a standalone component \"${\n stringifyForError(source)}\"`);\n }\n }\n\n // Narrow `source` to access the internal type analogue for `ModuleWithProviders`.\n const internalSource = source as Type| InjectorTypeWithProviders;\n if (walkProviderTree(internalSource, collectProviders, [], dedup)) {\n injectorTypesWithProviders ||= [];\n injectorTypesWithProviders.push(internalSource);\n }\n });\n // Collect all providers from `ModuleWithProviders` types.\n if (injectorTypesWithProviders !== undefined) {\n processInjectorTypesWithProviders(injectorTypesWithProviders, collectProviders);\n }\n\n return providersOut;\n}\n\n/**\n * Collects all providers from the list of `ModuleWithProviders` and appends them to the provided\n * array.\n */\nfunction processInjectorTypesWithProviders(\n typesWithProviders: InjectorTypeWithProviders[],\n visitor: WalkProviderTreeVisitor): void {\n for (let i = 0; i < typesWithProviders.length; i++) {\n const {ngModule, providers} = typesWithProviders[i];\n deepForEachProvider(providers! as Array, provider => {\n ngDevMode && validateProvider(provider, providers || EMPTY_ARRAY, ngModule);\n visitor(provider, ngModule);\n });\n }\n}\n\n/**\n * Internal type for a single provider in a deep provider array.\n */\nexport type SingleProvider = TypeProvider|ValueProvider|ClassProvider|ConstructorProvider|\n ExistingProvider|FactoryProvider|StaticClassProvider;\n\n/**\n * The logic visits an `InjectorType`, an `InjectorTypeWithProviders`, or a standalone\n * `ComponentType`, and all of its transitive providers and collects providers.\n *\n * If an `InjectorTypeWithProviders` that declares providers besides the type is specified,\n * the function will return \"true\" to indicate that the providers of the type definition need\n * to be processed. This allows us to process providers of injector types after all imports of\n * an injector definition are processed. (following View Engine semantics: see FW-1349)\n */\nexport function walkProviderTree(\n container: Type|InjectorTypeWithProviders, visitor: WalkProviderTreeVisitor,\n parents: Type[],\n dedup: Set>): container is InjectorTypeWithProviders {\n container = resolveForwardRef(container);\n if (!container) return false;\n\n // The actual type which had the definition. Usually `container`, but may be an unwrapped type\n // from `InjectorTypeWithProviders`.\n let defType: Type|null = null;\n\n let injDef = getInjectorDef(container);\n const cmpDef = !injDef && getComponentDef(container);\n if (!injDef && !cmpDef) {\n // `container` is not an injector type or a component type. It might be:\n // * An `InjectorTypeWithProviders` that wraps an injector type.\n // * A standalone directive or pipe that got pulled in from a standalone component's\n // dependencies.\n // Try to unwrap it as an `InjectorTypeWithProviders` first.\n const ngModule: Type|undefined =\n (container as InjectorTypeWithProviders).ngModule as Type| undefined;\n injDef = getInjectorDef(ngModule);\n if (injDef) {\n defType = ngModule!;\n } else {\n // Not a component or injector type, so ignore it.\n return false;\n }\n } else if (cmpDef && !cmpDef.standalone) {\n return false;\n } else {\n defType = container as Type;\n }\n\n // Check for circular dependencies.\n if (ngDevMode && parents.indexOf(defType) !== -1) {\n const defName = stringify(defType);\n const path = parents.map(stringify);\n throwCyclicDependencyError(defName, path);\n }\n\n // Check for multiple imports of the same module\n const isDuplicate = dedup.has(defType);\n\n if (cmpDef) {\n if (isDuplicate) {\n // This component definition has already been processed.\n return false;\n }\n dedup.add(defType);\n\n if (cmpDef.dependencies) {\n const deps =\n typeof cmpDef.dependencies === 'function' ? cmpDef.dependencies() : cmpDef.dependencies;\n for (const dep of deps) {\n walkProviderTree(dep, visitor, parents, dedup);\n }\n }\n } else if (injDef) {\n // First, include providers from any imports.\n if (injDef.imports != null && !isDuplicate) {\n // Before processing defType's imports, add it to the set of parents. This way, if it ends\n // up deeply importing itself, this can be detected.\n ngDevMode && parents.push(defType);\n // Add it to the set of dedups. This way we can detect multiple imports of the same module\n dedup.add(defType);\n\n let importTypesWithProviders: (InjectorTypeWithProviders[])|undefined;\n try {\n deepForEach(injDef.imports, imported => {\n if (walkProviderTree(imported, visitor, parents, dedup)) {\n importTypesWithProviders ||= [];\n // If the processed import is an injector type with providers, we store it in the\n // list of import types with providers, so that we can process those afterwards.\n importTypesWithProviders.push(imported);\n }\n });\n } finally {\n // Remove it from the parents set when finished.\n ngDevMode && parents.pop();\n }\n\n // Imports which are declared with providers (TypeWithProviders) need to be processed\n // after all imported modules are processed. This is similar to how View Engine\n // processes/merges module imports in the metadata resolver. See: FW-1349.\n if (importTypesWithProviders !== undefined) {\n processInjectorTypesWithProviders(importTypesWithProviders, visitor);\n }\n }\n\n if (!isDuplicate) {\n // Track the InjectorType and add a provider for it.\n // It's important that this is done after the def's imports.\n const factory = getFactoryDef(defType) || (() => new defType!());\n\n // Append extra providers to make more info available for consumers (to retrieve an injector\n // type), as well as internally (to calculate an injection scope correctly and eagerly\n // instantiate a `defType` when an injector is created).\n\n // Provider to create `defType` using its factory.\n visitor({provide: defType, useFactory: factory, deps: EMPTY_ARRAY}, defType);\n\n // Make this `defType` available to an internal logic that calculates injector scope.\n visitor({provide: INJECTOR_DEF_TYPES, useValue: defType, multi: true}, defType);\n\n // Provider to eagerly instantiate `defType` via `INJECTOR_INITIALIZER`.\n visitor(\n {provide: ENVIRONMENT_INITIALIZER, useValue: () => inject(defType!), multi: true},\n defType);\n }\n\n // Next, include providers listed on the definition itself.\n const defProviders = injDef.providers as Array;\n if (defProviders != null && !isDuplicate) {\n const injectorType = container as InjectorType;\n deepForEachProvider(defProviders, provider => {\n ngDevMode && validateProvider(provider as SingleProvider, defProviders, injectorType);\n visitor(provider, injectorType);\n });\n }\n } else {\n // Should not happen, but just in case.\n return false;\n }\n\n return (\n defType !== container &&\n (container as InjectorTypeWithProviders).providers !== undefined);\n}\n\nfunction validateProvider(\n provider: SingleProvider, providers: Array,\n containerType: Type): void {\n if (isTypeProvider(provider) || isValueProvider(provider) || isFactoryProvider(provider) ||\n isExistingProvider(provider)) {\n return;\n }\n\n // Here we expect the provider to be a `useClass` provider (by elimination).\n const classRef = resolveForwardRef(\n provider && ((provider as StaticClassProvider | ClassProvider).useClass || provider.provide));\n if (!classRef) {\n throwInvalidProviderError(containerType, providers, provider);\n }\n}\n\nfunction deepForEachProvider(\n providers: Array,\n fn: (provider: SingleProvider) => void): void {\n for (let provider of providers) {\n if (isEnvironmentProviders(provider)) {\n provider = provider.ɵproviders;\n }\n if (Array.isArray(provider)) {\n deepForEachProvider(provider, fn);\n } else {\n fn(provider);\n }\n }\n}\n\nexport const USE_VALUE =\n getClosureSafeProperty({provide: String, useValue: getClosureSafeProperty});\n\nexport function isValueProvider(value: SingleProvider): value is ValueProvider {\n return value !== null && typeof value == 'object' && USE_VALUE in value;\n}\n\nexport function isExistingProvider(value: SingleProvider): value is ExistingProvider {\n return !!(value && (value as ExistingProvider).useExisting);\n}\n\nexport function isFactoryProvider(value: SingleProvider): value is FactoryProvider {\n return !!(value && (value as FactoryProvider).useFactory);\n}\n\nexport function isTypeProvider(value: SingleProvider): value is TypeProvider {\n return typeof value === 'function';\n}\n\nexport function isClassProvider(value: SingleProvider): value is ClassProvider {\n return !!(value as StaticClassProvider | ClassProvider).useClass;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {InjectionToken} from './injection_token';\n\n\nexport type InjectorScope = 'root'|'platform'|'environment';\n\n/**\n * An internal token whose presence in an injector indicates that the injector should treat itself\n * as a root scoped injector when processing requests for unknown tokens which may indicate\n * they are provided in the root scope.\n */\nexport const INJECTOR_SCOPE = new InjectionToken('Set Injector scope.');\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport '../util/ng_dev_mode';\n\nimport {RuntimeError, RuntimeErrorCode} from '../errors';\nimport {OnDestroy} from '../interface/lifecycle_hooks';\nimport {Type} from '../interface/type';\nimport {emitInstanceCreatedByInjectorEvent, emitProviderConfiguredEvent, InjectorProfilerContext, runInInjectorProfilerContext, setInjectorProfilerContext} from '../render3/debug/injector_profiler';\nimport {FactoryFn, getFactoryDef} from '../render3/definition_factory';\nimport {throwCyclicDependencyError, throwInvalidProviderError, throwMixedMultiProviderError} from '../render3/errors_di';\nimport {NG_ENV_ID} from '../render3/fields';\nimport {newArray} from '../util/array_utils';\nimport {EMPTY_ARRAY} from '../util/empty';\nimport {stringify} from '../util/stringify';\n\nimport {resolveForwardRef} from './forward_ref';\nimport {ENVIRONMENT_INITIALIZER} from './initializer_token';\nimport {setInjectImplementation} from './inject_switch';\nimport {InjectionToken} from './injection_token';\nimport {Injector} from './injector';\nimport {catchInjectorError, convertToBitFlags, injectArgs, NG_TEMP_TOKEN_PATH, setCurrentInjector, THROW_IF_NOT_FOUND, ɵɵinject} from './injector_compatibility';\nimport {INJECTOR} from './injector_token';\nimport {getInheritedInjectableDef, getInjectableDef, InjectorType, ɵɵInjectableDeclaration} from './interface/defs';\nimport {InjectFlags, InjectOptions} from './interface/injector';\nimport {ClassProvider, ConstructorProvider, EnvironmentProviders, InternalEnvironmentProviders, isEnvironmentProviders, Provider, StaticClassProvider} from './interface/provider';\nimport {INJECTOR_DEF_TYPES} from './internal_tokens';\nimport {NullInjector} from './null_injector';\nimport {isExistingProvider, isFactoryProvider, isTypeProvider, isValueProvider, SingleProvider} from './provider_collection';\nimport {ProviderToken} from './provider_token';\nimport {INJECTOR_SCOPE, InjectorScope} from './scope';\n\n/**\n * Marker which indicates that a value has not yet been created from the factory function.\n */\nconst NOT_YET = {};\n\n/**\n * Marker which indicates that the factory function for a token is in the process of being called.\n *\n * If the injector is asked to inject a token with its value set to CIRCULAR, that indicates\n * injection of a dependency has recursively attempted to inject the original token, and there is\n * a circular dependency among the providers.\n */\nconst CIRCULAR = {};\n\n/**\n * A lazily initialized NullInjector.\n */\nlet NULL_INJECTOR: Injector|undefined = undefined;\n\nexport function getNullInjector(): Injector {\n if (NULL_INJECTOR === undefined) {\n NULL_INJECTOR = new NullInjector();\n }\n return NULL_INJECTOR;\n}\n\n/**\n * An entry in the injector which tracks information about the given token, including a possible\n * current value.\n */\ninterface Record {\n factory: (() => T)|undefined;\n value: T|{};\n multi: any[]|undefined;\n}\n\n/**\n * An `Injector` that's part of the environment injector hierarchy, which exists outside of the\n * component tree.\n */\nexport abstract class EnvironmentInjector implements Injector {\n /**\n * Retrieves an instance from the injector based on the provided token.\n * @returns The instance from the injector if defined, otherwise the `notFoundValue`.\n * @throws When the `notFoundValue` is `undefined` or `Injector.THROW_IF_NOT_FOUND`.\n */\n abstract get(token: ProviderToken, notFoundValue: undefined, options: InjectOptions&{\n optional?: false;\n }): T;\n /**\n * Retrieves an instance from the injector based on the provided token.\n * @returns The instance from the injector if defined, otherwise the `notFoundValue`.\n * @throws When the `notFoundValue` is `undefined` or `Injector.THROW_IF_NOT_FOUND`.\n */\n abstract get(token: ProviderToken, notFoundValue: null|undefined, options: InjectOptions): T\n |null;\n /**\n * Retrieves an instance from the injector based on the provided token.\n * @returns The instance from the injector if defined, otherwise the `notFoundValue`.\n * @throws When the `notFoundValue` is `undefined` or `Injector.THROW_IF_NOT_FOUND`.\n */\n abstract get(token: ProviderToken, notFoundValue?: T, options?: InjectOptions): T;\n /**\n * Retrieves an instance from the injector based on the provided token.\n * @returns The instance from the injector if defined, otherwise the `notFoundValue`.\n * @throws When the `notFoundValue` is `undefined` or `Injector.THROW_IF_NOT_FOUND`.\n * @deprecated use object-based flags (`InjectOptions`) instead.\n */\n abstract get(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T;\n /**\n * @deprecated from v4.0.0 use ProviderToken\n * @suppress {duplicate}\n */\n abstract get(token: any, notFoundValue?: any): any;\n\n /**\n * Runs the given function in the context of this `EnvironmentInjector`.\n *\n * Within the function's stack frame, [`inject`](api/core/inject) can be used to inject\n * dependencies from this injector. Note that `inject` is only usable synchronously, and cannot be\n * used in any asynchronous callbacks or after any `await` points.\n *\n * @param fn the closure to be run in the context of this injector\n * @returns the return value of the function, if any\n * @deprecated use the standalone function `runInInjectionContext` instead\n */\n abstract runInContext(fn: () => ReturnT): ReturnT;\n\n abstract destroy(): void;\n\n /**\n * @internal\n */\n abstract onDestroy(callback: () => void): () => void;\n}\n\nexport class R3Injector extends EnvironmentInjector {\n /**\n * Map of tokens to records which contain the instances of those tokens.\n * - `null` value implies that we don't have the record. Used by tree-shakable injectors\n * to prevent further searches.\n */\n private records = new Map, Record|null>();\n\n /**\n * Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.\n */\n private _ngOnDestroyHooks = new Set();\n\n private _onDestroyHooks: Array<() => void> = [];\n\n /**\n * Flag indicating that this injector was previously destroyed.\n */\n get destroyed(): boolean {\n return this._destroyed;\n }\n private _destroyed = false;\n\n private injectorDefTypes: Set>;\n\n constructor(\n providers: Array, readonly parent: Injector,\n readonly source: string|null, readonly scopes: Set) {\n super();\n // Start off by creating Records for every provider.\n forEachSingleProvider(\n providers as Array,\n provider => this.processProvider(provider));\n\n // Make sure the INJECTOR token provides this injector.\n this.records.set(INJECTOR, makeRecord(undefined, this));\n\n // And `EnvironmentInjector` if the current injector is supposed to be env-scoped.\n if (scopes.has('environment')) {\n this.records.set(EnvironmentInjector, makeRecord(undefined, this));\n }\n\n // Detect whether this injector has the APP_ROOT_SCOPE token and thus should provide\n // any injectable scoped to APP_ROOT_SCOPE.\n const record = this.records.get(INJECTOR_SCOPE) as Record;\n if (record != null && typeof record.value === 'string') {\n this.scopes.add(record.value as InjectorScope);\n }\n\n this.injectorDefTypes =\n new Set(this.get(INJECTOR_DEF_TYPES.multi, EMPTY_ARRAY, InjectFlags.Self));\n }\n\n /**\n * Destroy the injector and release references to every instance or provider associated with it.\n *\n * Also calls the `OnDestroy` lifecycle hooks of every instance that was created for which a\n * hook was found.\n */\n override destroy(): void {\n this.assertNotDestroyed();\n\n // Set destroyed = true first, in case lifecycle hooks re-enter destroy().\n this._destroyed = true;\n try {\n // Call all the lifecycle hooks.\n for (const service of this._ngOnDestroyHooks) {\n service.ngOnDestroy();\n }\n const onDestroyHooks = this._onDestroyHooks;\n // Reset the _onDestroyHooks array before iterating over it to prevent hooks that unregister\n // themselves from mutating the array during iteration.\n this._onDestroyHooks = [];\n for (const hook of onDestroyHooks) {\n hook();\n }\n } finally {\n // Release all references.\n this.records.clear();\n this._ngOnDestroyHooks.clear();\n this.injectorDefTypes.clear();\n }\n }\n\n override onDestroy(callback: () => void): () => void {\n this.assertNotDestroyed();\n this._onDestroyHooks.push(callback);\n return () => this.removeOnDestroy(callback);\n }\n\n override runInContext(fn: () => ReturnT): ReturnT {\n this.assertNotDestroyed();\n\n const previousInjector = setCurrentInjector(this);\n const previousInjectImplementation = setInjectImplementation(undefined);\n\n let prevInjectContext: InjectorProfilerContext|undefined;\n if (ngDevMode) {\n prevInjectContext = setInjectorProfilerContext({injector: this, token: null});\n }\n\n try {\n return fn();\n } finally {\n setCurrentInjector(previousInjector);\n setInjectImplementation(previousInjectImplementation);\n ngDevMode && setInjectorProfilerContext(prevInjectContext!);\n }\n }\n\n override get(\n token: ProviderToken, notFoundValue: any = THROW_IF_NOT_FOUND,\n flags: InjectFlags|InjectOptions = InjectFlags.Default): T {\n this.assertNotDestroyed();\n\n if (token.hasOwnProperty(NG_ENV_ID)) {\n return (token as any)[NG_ENV_ID](this);\n }\n\n flags = convertToBitFlags(flags) as InjectFlags;\n\n // Set the injection context.\n let prevInjectContext: InjectorProfilerContext;\n if (ngDevMode) {\n prevInjectContext = setInjectorProfilerContext({injector: this, token: token as Type});\n }\n const previousInjector = setCurrentInjector(this);\n const previousInjectImplementation = setInjectImplementation(undefined);\n try {\n // Check for the SkipSelf flag.\n if (!(flags & InjectFlags.SkipSelf)) {\n // SkipSelf isn't set, check if the record belongs to this injector.\n let record: Record|undefined|null = this.records.get(token);\n if (record === undefined) {\n // No record, but maybe the token is scoped to this injector. Look for an injectable\n // def with a scope matching this injector.\n const def = couldBeInjectableType(token) && getInjectableDef(token);\n if (def && this.injectableDefInScope(def)) {\n // Found an injectable def and it's scoped to this injector. Pretend as if it was here\n // all along.\n record = makeRecord(injectableDefOrInjectorDefFactory(token), NOT_YET);\n } else {\n record = null;\n }\n this.records.set(token, record);\n }\n // If a record was found, get the instance for it and return it.\n if (record != null /* NOT null || undefined */) {\n return this.hydrate(token, record);\n }\n }\n\n // Select the next injector based on the Self flag - if self is set, the next injector is\n // the NullInjector, otherwise it's the parent.\n const nextInjector = !(flags & InjectFlags.Self) ? this.parent : getNullInjector();\n // Set the notFoundValue based on the Optional flag - if optional is set and notFoundValue\n // is undefined, the value is null, otherwise it's the notFoundValue.\n notFoundValue = (flags & InjectFlags.Optional) && notFoundValue === THROW_IF_NOT_FOUND ?\n null :\n notFoundValue;\n return nextInjector.get(token, notFoundValue);\n } catch (e: any) {\n if (e.name === 'NullInjectorError') {\n const path: any[] = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];\n path.unshift(stringify(token));\n if (previousInjector) {\n // We still have a parent injector, keep throwing\n throw e;\n } else {\n // Format & throw the final error message when we don't have any previous injector\n return catchInjectorError(e, token, 'R3InjectorError', this.source);\n }\n } else {\n throw e;\n }\n } finally {\n // Lastly, restore the previous injection context.\n setInjectImplementation(previousInjectImplementation);\n setCurrentInjector(previousInjector);\n ngDevMode && setInjectorProfilerContext(prevInjectContext!);\n }\n }\n\n /** @internal */\n resolveInjectorInitializers() {\n const previousInjector = setCurrentInjector(this);\n const previousInjectImplementation = setInjectImplementation(undefined);\n let prevInjectContext: InjectorProfilerContext|undefined;\n if (ngDevMode) {\n prevInjectContext = setInjectorProfilerContext({injector: this, token: null});\n }\n\n try {\n const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, InjectFlags.Self);\n if (ngDevMode && !Array.isArray(initializers)) {\n throw new RuntimeError(\n RuntimeErrorCode.INVALID_MULTI_PROVIDER,\n 'Unexpected type of the `ENVIRONMENT_INITIALIZER` token value ' +\n `(expected an array, but got ${typeof initializers}). ` +\n 'Please check that the `ENVIRONMENT_INITIALIZER` token is configured as a ' +\n '`multi: true` provider.');\n }\n for (const initializer of initializers) {\n initializer();\n }\n } finally {\n setCurrentInjector(previousInjector);\n setInjectImplementation(previousInjectImplementation);\n ngDevMode && setInjectorProfilerContext(prevInjectContext!);\n }\n }\n\n override toString() {\n const tokens: string[] = [];\n const records = this.records;\n for (const token of records.keys()) {\n tokens.push(stringify(token));\n }\n return `R3Injector[${tokens.join(', ')}]`;\n }\n\n assertNotDestroyed(): void {\n if (this._destroyed) {\n throw new RuntimeError(\n RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED,\n ngDevMode && 'Injector has already been destroyed.');\n }\n }\n\n /**\n * Process a `SingleProvider` and add it.\n */\n private processProvider(provider: SingleProvider): void {\n // Determine the token from the provider. Either it's its own token, or has a {provide: ...}\n // property.\n provider = resolveForwardRef(provider);\n let token: any =\n isTypeProvider(provider) ? provider : resolveForwardRef(provider && provider.provide);\n\n // Construct a `Record` for the provider.\n const record = providerToRecord(provider);\n if (ngDevMode) {\n runInInjectorProfilerContext(this, token, () => {\n // Emit InjectorProfilerEventType.Create if provider is a value provider because\n // these are the only providers that do not go through the value hydration logic\n // where this event would normally be emitted from.\n if (isValueProvider(provider)) {\n emitInstanceCreatedByInjectorEvent(provider.useValue);\n }\n\n emitProviderConfiguredEvent(provider);\n });\n }\n\n if (!isTypeProvider(provider) && provider.multi === true) {\n // If the provider indicates that it's a multi-provider, process it specially.\n // First check whether it's been defined already.\n let multiRecord = this.records.get(token);\n if (multiRecord) {\n // It has. Throw a nice error if\n if (ngDevMode && multiRecord.multi === undefined) {\n throwMixedMultiProviderError();\n }\n } else {\n multiRecord = makeRecord(undefined, NOT_YET, true);\n multiRecord.factory = () => injectArgs(multiRecord!.multi!);\n this.records.set(token, multiRecord);\n }\n token = provider;\n multiRecord.multi!.push(provider);\n } else {\n const existing = this.records.get(token);\n if (ngDevMode && existing && existing.multi !== undefined) {\n throwMixedMultiProviderError();\n }\n }\n this.records.set(token, record);\n }\n\n private hydrate(token: ProviderToken, record: Record): T {\n if (ngDevMode && record.value === CIRCULAR) {\n throwCyclicDependencyError(stringify(token));\n } else if (record.value === NOT_YET) {\n record.value = CIRCULAR;\n\n if (ngDevMode) {\n runInInjectorProfilerContext(this, token as Type, () => {\n record.value = record.factory!();\n emitInstanceCreatedByInjectorEvent(record.value);\n });\n } else {\n record.value = record.factory!();\n }\n }\n if (typeof record.value === 'object' && record.value && hasOnDestroy(record.value)) {\n this._ngOnDestroyHooks.add(record.value);\n }\n return record.value as T;\n }\n\n private injectableDefInScope(def: ɵɵInjectableDeclaration): boolean {\n if (!def.providedIn) {\n return false;\n }\n const providedIn = resolveForwardRef(def.providedIn);\n if (typeof providedIn === 'string') {\n return providedIn === 'any' || (this.scopes.has(providedIn));\n } else {\n return this.injectorDefTypes.has(providedIn);\n }\n }\n\n private removeOnDestroy(callback: () => void): void {\n const destroyCBIdx = this._onDestroyHooks.indexOf(callback);\n if (destroyCBIdx !== -1) {\n this._onDestroyHooks.splice(destroyCBIdx, 1);\n }\n }\n}\n\nfunction injectableDefOrInjectorDefFactory(token: ProviderToken): FactoryFn {\n // Most tokens will have an injectable def directly on them, which specifies a factory directly.\n const injectableDef = getInjectableDef(token);\n const factory = injectableDef !== null ? injectableDef.factory : getFactoryDef(token);\n\n if (factory !== null) {\n return factory;\n }\n\n // InjectionTokens should have an injectable def (ɵprov) and thus should be handled above.\n // If it's missing that, it's an error.\n if (token instanceof InjectionToken) {\n throw new RuntimeError(\n RuntimeErrorCode.INVALID_INJECTION_TOKEN,\n ngDevMode && `Token ${stringify(token)} is missing a ɵprov definition.`);\n }\n\n // Undecorated types can sometimes be created if they have no constructor arguments.\n if (token instanceof Function) {\n return getUndecoratedInjectableFactory(token);\n }\n\n // There was no way to resolve a factory for this token.\n throw new RuntimeError(RuntimeErrorCode.INVALID_INJECTION_TOKEN, ngDevMode && 'unreachable');\n}\n\nfunction getUndecoratedInjectableFactory(token: Function) {\n // If the token has parameters then it has dependencies that we cannot resolve implicitly.\n const paramLength = token.length;\n if (paramLength > 0) {\n const args: string[] = newArray(paramLength, '?');\n throw new RuntimeError(\n RuntimeErrorCode.INVALID_INJECTION_TOKEN,\n ngDevMode && `Can't resolve all parameters for ${stringify(token)}: (${args.join(', ')}).`);\n }\n\n // The constructor function appears to have no parameters.\n // This might be because it inherits from a super-class. In which case, use an injectable\n // def from an ancestor if there is one.\n // Otherwise this really is a simple class with no dependencies, so return a factory that\n // just instantiates the zero-arg constructor.\n const inheritedInjectableDef = getInheritedInjectableDef(token);\n if (inheritedInjectableDef !== null) {\n return () => inheritedInjectableDef.factory(token as Type);\n } else {\n return () => new (token as Type)();\n }\n}\n\nfunction providerToRecord(provider: SingleProvider): Record {\n if (isValueProvider(provider)) {\n return makeRecord(undefined, provider.useValue);\n } else {\n const factory: (() => any)|undefined = providerToFactory(provider);\n return makeRecord(factory, NOT_YET);\n }\n}\n\n/**\n * Converts a `SingleProvider` into a factory function.\n *\n * @param provider provider to convert to factory\n */\nexport function providerToFactory(\n provider: SingleProvider, ngModuleType?: InjectorType, providers?: any[]): () => any {\n let factory: (() => any)|undefined = undefined;\n if (ngDevMode && isEnvironmentProviders(provider)) {\n throwInvalidProviderError(undefined, providers, provider);\n }\n\n if (isTypeProvider(provider)) {\n const unwrappedProvider = resolveForwardRef(provider);\n return getFactoryDef(unwrappedProvider) || injectableDefOrInjectorDefFactory(unwrappedProvider);\n } else {\n if (isValueProvider(provider)) {\n factory = () => resolveForwardRef(provider.useValue);\n } else if (isFactoryProvider(provider)) {\n factory = () => provider.useFactory(...injectArgs(provider.deps || []));\n } else if (isExistingProvider(provider)) {\n factory = () => ɵɵinject(resolveForwardRef(provider.useExisting));\n } else {\n const classRef = resolveForwardRef(\n provider &&\n ((provider as StaticClassProvider | ClassProvider).useClass || provider.provide));\n if (ngDevMode && !classRef) {\n throwInvalidProviderError(ngModuleType, providers, provider);\n }\n if (hasDeps(provider)) {\n factory = () => new (classRef)(...injectArgs(provider.deps));\n } else {\n return getFactoryDef(classRef) || injectableDefOrInjectorDefFactory(classRef);\n }\n }\n }\n return factory;\n}\n\nfunction makeRecord(\n factory: (() => T)|undefined, value: T|{}, multi: boolean = false): Record {\n return {\n factory: factory,\n value: value,\n multi: multi ? [] : undefined,\n };\n}\n\nfunction hasDeps(value: ClassProvider|ConstructorProvider|\n StaticClassProvider): value is ClassProvider&{deps: any[]} {\n return !!(value as any).deps;\n}\n\nfunction hasOnDestroy(value: any): value is OnDestroy {\n return value !== null && typeof value === 'object' &&\n typeof (value as OnDestroy).ngOnDestroy === 'function';\n}\n\nfunction couldBeInjectableType(value: any): value is ProviderToken {\n return (typeof value === 'function') ||\n (typeof value === 'object' && value instanceof InjectionToken);\n}\n\nfunction forEachSingleProvider(\n providers: Array, fn: (provider: SingleProvider) => void): void {\n for (const provider of providers) {\n if (Array.isArray(provider)) {\n forEachSingleProvider(provider, fn);\n } else if (provider && isEnvironmentProviders(provider)) {\n forEachSingleProvider(provider.ɵproviders, fn);\n } else {\n fn(provider as SingleProvider);\n }\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {RuntimeError, RuntimeErrorCode} from '../errors';\nimport {InjectorProfilerContext, setInjectorProfilerContext} from '../render3/debug/injector_profiler';\nimport type {Injector} from './injector';\nimport {getCurrentInjector, setCurrentInjector} from './injector_compatibility';\nimport {getInjectImplementation, setInjectImplementation} from './inject_switch';\nimport {R3Injector} from './r3_injector';\n\n/**\n * Runs the given function in the [context](guide/dependency-injection-context) of the given\n * `Injector`.\n *\n * Within the function's stack frame, [`inject`](api/core/inject) can be used to inject dependencies\n * from the given `Injector`. Note that `inject` is only usable synchronously, and cannot be used in\n * any asynchronous callbacks or after any `await` points.\n *\n * @param injector the injector which will satisfy calls to [`inject`](api/core/inject) while `fn`\n * is executing\n * @param fn the closure to be run in the context of `injector`\n * @returns the return value of the function, if any\n * @publicApi\n */\nexport function runInInjectionContext(injector: Injector, fn: () => ReturnT): ReturnT {\n if (injector instanceof R3Injector) {\n injector.assertNotDestroyed();\n }\n\n let prevInjectorProfilerContext: InjectorProfilerContext;\n if (ngDevMode) {\n prevInjectorProfilerContext = setInjectorProfilerContext({injector, token: null});\n }\n const prevInjector = setCurrentInjector(injector);\n const previousInjectImplementation = setInjectImplementation(undefined);\n try {\n return fn();\n } finally {\n setCurrentInjector(prevInjector);\n ngDevMode && setInjectorProfilerContext(prevInjectorProfilerContext!);\n setInjectImplementation(previousInjectImplementation);\n }\n}\n\n/**\n * Asserts that the current stack frame is within an [injection\n * context](guide/dependency-injection-context) and has access to `inject`.\n *\n * @param debugFn a reference to the function making the assertion (used for the error message).\n *\n * @publicApi\n */\nexport function assertInInjectionContext(debugFn: Function): void {\n // Taking a `Function` instead of a string name here prevents the unminified name of the function\n // from being retained in the bundle regardless of minification.\n if (!getInjectImplementation() && !getCurrentInjector()) {\n throw new RuntimeError(\n RuntimeErrorCode.MISSING_INJECTION_CONTEXT,\n ngDevMode &&\n (debugFn.name +\n '() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`'));\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport {resolveForwardRef} from '../forward_ref';\nimport {ɵɵinject, ɵɵinvalidFactoryDep} from '../injector_compatibility';\nimport {ɵɵdefineInjectable, ɵɵdefineInjector} from '../interface/defs';\n\n/**\n * A mapping of the @angular/core API surface used in generated expressions to the actual symbols.\n *\n * This should be kept up to date with the public exports of @angular/core.\n */\nexport const angularCoreDiEnv: {[name: string]: Function} = {\n 'ɵɵdefineInjectable': ɵɵdefineInjectable,\n 'ɵɵdefineInjector': ɵɵdefineInjector,\n 'ɵɵinject': ɵɵinject,\n 'ɵɵinvalidFactoryDep': ɵɵinvalidFactoryDep,\n 'resolveForwardRef': resolveForwardRef,\n};\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {getCompilerFacade, JitCompilerUsage, R3InjectableMetadataFacade} from '../../compiler/compiler_facade';\nimport {Type} from '../../interface/type';\nimport {NG_FACTORY_DEF} from '../../render3/fields';\nimport {getClosureSafeProperty} from '../../util/property';\nimport {resolveForwardRef} from '../forward_ref';\nimport {Injectable} from '../injectable';\nimport {NG_PROV_DEF} from '../interface/defs';\nimport {ClassSansProvider, ExistingSansProvider, FactorySansProvider, ValueProvider, ValueSansProvider} from '../interface/provider';\n\nimport {angularCoreDiEnv} from './environment';\nimport {convertDependencies, reflectDependencies} from './util';\n\n\n\n/**\n * Compile an Angular injectable according to its `Injectable` metadata, and patch the resulting\n * injectable def (`ɵprov`) onto the injectable type.\n */\nexport function compileInjectable(type: Type, meta?: Injectable): void {\n let ngInjectableDef: any = null;\n let ngFactoryDef: any = null;\n\n // if NG_PROV_DEF is already defined on this class then don't overwrite it\n if (!type.hasOwnProperty(NG_PROV_DEF)) {\n Object.defineProperty(type, NG_PROV_DEF, {\n get: () => {\n if (ngInjectableDef === null) {\n const compiler =\n getCompilerFacade({usage: JitCompilerUsage.Decorator, kind: 'injectable', type});\n ngInjectableDef = compiler.compileInjectable(\n angularCoreDiEnv, `ng:///${type.name}/ɵprov.js`, getInjectableMetadata(type, meta));\n }\n return ngInjectableDef;\n },\n });\n }\n\n // if NG_FACTORY_DEF is already defined on this class then don't overwrite it\n if (!type.hasOwnProperty(NG_FACTORY_DEF)) {\n Object.defineProperty(type, NG_FACTORY_DEF, {\n get: () => {\n if (ngFactoryDef === null) {\n const compiler =\n getCompilerFacade({usage: JitCompilerUsage.Decorator, kind: 'injectable', type});\n ngFactoryDef = compiler.compileFactory(angularCoreDiEnv, `ng:///${type.name}/ɵfac.js`, {\n name: type.name,\n type,\n typeArgumentCount: 0, // In JIT mode types are not available nor used.\n deps: reflectDependencies(type),\n target: compiler.FactoryTarget.Injectable\n });\n }\n return ngFactoryDef;\n },\n // Leave this configurable so that the factories from directives or pipes can take precedence.\n configurable: true\n });\n }\n}\n\ntype UseClassProvider = Injectable&ClassSansProvider&{deps?: any[]};\n\nconst USE_VALUE =\n getClosureSafeProperty({provide: String, useValue: getClosureSafeProperty});\n\nfunction isUseClassProvider(meta: Injectable): meta is UseClassProvider {\n return (meta as UseClassProvider).useClass !== undefined;\n}\n\nfunction isUseValueProvider(meta: Injectable): meta is Injectable&ValueSansProvider {\n return USE_VALUE in meta;\n}\n\nfunction isUseFactoryProvider(meta: Injectable): meta is Injectable&FactorySansProvider {\n return (meta as FactorySansProvider).useFactory !== undefined;\n}\n\nfunction isUseExistingProvider(meta: Injectable): meta is Injectable&ExistingSansProvider {\n return (meta as ExistingSansProvider).useExisting !== undefined;\n}\n\nfunction getInjectableMetadata(type: Type, srcMeta?: Injectable): R3InjectableMetadataFacade {\n // Allow the compilation of a class with a `@Injectable()` decorator without parameters\n const meta: Injectable = srcMeta || {providedIn: null};\n const compilerMeta: R3InjectableMetadataFacade = {\n name: type.name,\n type: type,\n typeArgumentCount: 0,\n providedIn: meta.providedIn,\n };\n if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {\n compilerMeta.deps = convertDependencies(meta.deps);\n }\n // Check to see if the user explicitly provided a `useXxxx` property.\n if (isUseClassProvider(meta)) {\n compilerMeta.useClass = meta.useClass;\n } else if (isUseValueProvider(meta)) {\n compilerMeta.useValue = meta.useValue;\n } else if (isUseFactoryProvider(meta)) {\n compilerMeta.useFactory = meta.useFactory;\n } else if (isUseExistingProvider(meta)) {\n compilerMeta.useExisting = meta.useExisting;\n }\n return compilerMeta;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Type} from '../interface/type';\nimport {makeDecorator, TypeDecorator} from '../util/decorators';\n\nimport {ClassSansProvider, ConstructorSansProvider, ExistingSansProvider, FactorySansProvider, StaticClassSansProvider, ValueSansProvider} from './interface/provider';\nimport {compileInjectable} from './jit/injectable';\n\nexport {compileInjectable};\n\n/**\n * Injectable providers used in `@Injectable` decorator.\n *\n * @publicApi\n */\nexport type InjectableProvider = ValueSansProvider|ExistingSansProvider|StaticClassSansProvider|\n ConstructorSansProvider|FactorySansProvider|ClassSansProvider;\n\n/**\n * Type of the Injectable decorator / constructor function.\n *\n * @publicApi\n */\nexport interface InjectableDecorator {\n /**\n * Decorator that marks a class as available to be\n * provided and injected as a dependency.\n *\n * @see [Introduction to Services and DI](guide/architecture-services)\n * @see [Dependency Injection Guide](guide/dependency-injection)\n *\n * @usageNotes\n *\n * Marking a class with `@Injectable` ensures that the compiler\n * will generate the necessary metadata to create the class's\n * dependencies when the class is injected.\n *\n * The following example shows how a service class is properly\n * marked so that a supporting service can be injected upon creation.\n *\n * \n *\n */\n (): TypeDecorator;\n (options?: {providedIn: Type|'root'|'platform'|'any'|null}&\n InjectableProvider): TypeDecorator;\n new(): Injectable;\n new(options?: {providedIn: Type|'root'|'platform'|'any'|null}&\n InjectableProvider): Injectable;\n}\n\n/**\n * Type of the Injectable metadata.\n *\n * @publicApi\n */\nexport interface Injectable {\n /**\n * Determines which injectors will provide the injectable.\n *\n * - `Type` - associates the injectable with an `@NgModule` or other `InjectorType`. This\n * option is DEPRECATED.\n * - 'null' : Equivalent to `undefined`. The injectable is not provided in any scope automatically\n * and must be added to a `providers` array of an [@NgModule](api/core/NgModule#providers),\n * [@Component](api/core/Directive#providers) or [@Directive](api/core/Directive#providers).\n *\n * The following options specify that this injectable should be provided in one of the following\n * injectors:\n * - 'root' : The application-level injector in most apps.\n * - 'platform' : A special singleton platform injector shared by all\n * applications on the page.\n * - 'any' : Provides a unique instance in each lazy loaded module while all eagerly loaded\n * modules share one instance. This option is DEPRECATED.\n *\n */\n providedIn?: Type|'root'|'platform'|'any'|null;\n}\n\n/**\n * Injectable decorator and metadata.\n *\n * @Annotation\n * @publicApi\n */\nexport const Injectable: InjectableDecorator = makeDecorator(\n 'Injectable', undefined, undefined, undefined,\n (type: Type, meta: Injectable) => compileInjectable(type as any, meta));\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {EMPTY_ARRAY} from '../util/empty';\nimport {stringify} from '../util/stringify';\n\nimport {Injector} from './injector';\nimport {Provider, StaticProvider} from './interface/provider';\nimport {importProvidersFrom} from './provider_collection';\nimport {getNullInjector, R3Injector} from './r3_injector';\nimport {InjectorScope} from './scope';\n\n/**\n * Create a new `Injector` which is configured using a `defType` of `InjectorType`s.\n */\nexport function createInjector(\n defType: /* InjectorType */ any, parent: Injector|null = null,\n additionalProviders: Array|null = null, name?: string): Injector {\n const injector =\n createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);\n injector.resolveInjectorInitializers();\n return injector;\n}\n\n/**\n * Creates a new injector without eagerly resolving its injector types. Can be used in places\n * where resolving the injector types immediately can lead to an infinite loop. The injector types\n * should be resolved at a later point by calling `_resolveInjectorDefTypes`.\n */\nexport function createInjectorWithoutInjectorInstances(\n defType: /* InjectorType */ any, parent: Injector|null = null,\n additionalProviders: Array|null = null, name?: string,\n scopes = new Set()): R3Injector {\n const providers = [\n additionalProviders || EMPTY_ARRAY,\n importProvidersFrom(defType),\n ];\n name = name || (typeof defType === 'object' ? undefined : stringify(defType));\n\n return new R3Injector(providers, parent || getNullInjector(), name || null, scopes);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nimport {createInjector} from './create_injector';\nimport {THROW_IF_NOT_FOUND, ɵɵinject} from './injector_compatibility';\nimport {InjectorMarkers} from './injector_marker';\nimport {INJECTOR} from './injector_token';\nimport {ɵɵdefineInjectable} from './interface/defs';\nimport {InjectFlags, InjectOptions} from './interface/injector';\nimport {Provider, StaticProvider} from './interface/provider';\nimport {NullInjector} from './null_injector';\nimport {ProviderToken} from './provider_token';\n\n/**\n * Concrete injectors implement this interface. Injectors are configured\n * with [providers](guide/glossary#provider) that associate\n * dependencies of various types with [injection tokens](guide/glossary#di-token).\n *\n * @see [\"DI Providers\"](guide/dependency-injection-providers).\n * @see {@link StaticProvider}\n *\n * @usageNotes\n *\n * The following example creates a service injector instance.\n *\n * {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}\n *\n * ### Usage example\n *\n * {@example core/di/ts/injector_spec.ts region='Injector'}\n *\n * `Injector` returns itself when given `Injector` as a token:\n *\n * {@example core/di/ts/injector_spec.ts region='injectInjector'}\n *\n * @publicApi\n */\nexport abstract class Injector {\n static THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;\n static NULL: Injector = (/* @__PURE__ */ new NullInjector());\n\n /**\n * Internal note on the `options?: InjectOptions|InjectFlags` override of the `get`\n * method: consider dropping the `InjectFlags` part in one of the major versions.\n * It can **not** be done in minor/patch, since it's breaking for custom injectors\n * that only implement the old `InjectorFlags` interface.\n */\n\n /**\n * Retrieves an instance from the injector based on the provided token.\n * @returns The instance from the injector if defined, otherwise the `notFoundValue`.\n * @throws When the `notFoundValue` is `undefined` or `Injector.THROW_IF_NOT_FOUND`.\n */\n abstract get(token: ProviderToken, notFoundValue: undefined, options: InjectOptions&{\n optional?: false;\n }): T;\n /**\n * Retrieves an instance from the injector based on the provided token.\n * @returns The instance from the injector if defined, otherwise the `notFoundValue`.\n * @throws When the `notFoundValue` is `undefined` or `Injector.THROW_IF_NOT_FOUND`.\n */\n abstract get(token: ProviderToken, notFoundValue: null|undefined, options: InjectOptions): T\n |null;\n /**\n * Retrieves an instance from the injector based on the provided token.\n * @returns The instance from the injector if defined, otherwise the `notFoundValue`.\n * @throws When the `notFoundValue` is `undefined` or `Injector.THROW_IF_NOT_FOUND`.\n */\n abstract get(token: ProviderToken, notFoundValue?: T, options?: InjectOptions|InjectFlags):\n T;\n /**\n * Retrieves an instance from the injector based on the provided token.\n * @returns The instance from the injector if defined, otherwise the `notFoundValue`.\n * @throws When the `notFoundValue` is `undefined` or `Injector.THROW_IF_NOT_FOUND`.\n * @deprecated use object-based flags (`InjectOptions`) instead.\n */\n abstract get(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T;\n /**\n * @deprecated from v4.0.0 use ProviderToken\n * @suppress {duplicate}\n */\n abstract get(token: any, notFoundValue?: any): any;\n\n /**\n * @deprecated from v5 use the new signature Injector.create(options)\n */\n static create(providers: StaticProvider[], parent?: Injector): Injector;\n\n /**\n * Creates a new injector instance that provides one or more dependencies,\n * according to a given type or types of `StaticProvider`.\n *\n * @param options An object with the following properties:\n * * `providers`: An array of providers of the [StaticProvider type](api/core/StaticProvider).\n * * `parent`: (optional) A parent injector.\n * * `name`: (optional) A developer-defined identifying name for the new injector.\n *\n * @returns The new injector instance.\n *\n */\n static create(options:\n {providers: Array, parent?: Injector, name?: string}):\n Injector;\n\n\n static create(\n options: StaticProvider[]|\n {providers: Array, parent?: Injector, name?: string},\n parent?: Injector): Injector {\n if (Array.isArray(options)) {\n return createInjector({name: ''}, parent, options, '');\n } else {\n const name = options.name ?? '';\n return createInjector({name}, options.parent, options.providers, name);\n }\n }\n\n /** @nocollapse */\n static ɵprov = /** @pureOrBreakMyCode */ ɵɵdefineInjectable({\n token: Injector,\n providedIn: 'any',\n factory: () => ɵɵinject(INJECTOR),\n });\n\n /**\n * @internal\n * @nocollapse\n */\n static __NG_ELEMENT_ID__ = InjectorMarkers.Injector;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @module\n * @description\n * The `di` module provides dependency injection container services.\n */\n\nexport * from './metadata';\nexport {assertInInjectionContext, runInInjectionContext} from './contextual';\nexport {InjectFlags} from './interface/injector';\nexport {ɵɵdefineInjectable, defineInjectable, ɵɵdefineInjector, InjectableType, InjectorType} from './interface/defs';\nexport {forwardRef, resolveForwardRef, ForwardRefFn} from './forward_ref';\nexport {Injectable, InjectableDecorator, InjectableProvider} from './injectable';\nexport {Injector} from './injector';\nexport {EnvironmentInjector} from './r3_injector';\nexport {importProvidersFrom, ImportProvidersSource, makeEnvironmentProviders} from './provider_collection';\nexport {ENVIRONMENT_INITIALIZER} from './initializer_token';\nexport {ProviderToken} from './provider_token';\nexport {ɵɵinject, inject, ɵɵinvalidFactoryDep} from './injector_compatibility';\nexport {InjectOptions} from './interface/injector';\nexport {INJECTOR} from './injector_token';\nexport {ClassProvider, ModuleWithProviders, ClassSansProvider, ImportedNgModuleProviders, ConstructorProvider, EnvironmentProviders, ConstructorSansProvider, ExistingProvider, ExistingSansProvider, FactoryProvider, FactorySansProvider, Provider, StaticClassProvider, StaticClassSansProvider, StaticProvider, TypeProvider, ValueProvider, ValueSansProvider} from './interface/provider';\nexport {InjectionToken} from './injection_token';\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * This file should not be necessary because node resolution should just default to `./di/index`!\n *\n * However it does not seem to work and it breaks:\n * - //packages/animations/browser/test:test_web_chromium-local\n * - //packages/compiler-cli/test:extract_i18n\n * - //packages/compiler-cli/test:ngc\n * - //packages/compiler-cli/test:perform_watch\n * - //packages/compiler-cli/test/diagnostics:check_types\n * - //packages/compiler-cli/test/transformers:test\n * - //packages/compiler/test:test\n * - //tools/public_api_guard:core_api\n *\n * Remove this file once the above is solved or wait until `ngc` is deleted and then it should be\n * safe to delete this file.\n */\n\nexport * from './di/index';\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {PLATFORM_ID} from '../../application_tokens';\nimport {Injector} from '../../di';\nimport {inject} from '../../di/injector_compatibility';\nimport {RElement} from '../interfaces/renderer_dom';\n\n/**\n *\n * @codeGenApi\n */\nexport function ɵɵresolveWindow(element: RElement&{ownerDocument: Document}) {\n return element.ownerDocument.defaultView;\n}\n\n/**\n *\n * @codeGenApi\n */\nexport function ɵɵresolveDocument(element: RElement&{ownerDocument: Document}) {\n return element.ownerDocument;\n}\n\n/**\n *\n * @codeGenApi\n */\nexport function ɵɵresolveBody(element: RElement&{ownerDocument: Document}) {\n return element.ownerDocument.body;\n}\n\n/**\n * The special delimiter we use to separate property names, prefixes, and suffixes\n * in property binding metadata. See storeBindingMetadata().\n *\n * We intentionally use the Unicode \"REPLACEMENT CHARACTER\" (U+FFFD) as a delimiter\n * because it is a very uncommon character that is unlikely to be part of a user's\n * property names or interpolation strings. If it is in fact used in a property\n * binding, DebugElement.properties will not return the correct value for that\n * binding. However, there should be no runtime effect for real applications.\n *\n * This character is typically rendered as a question mark inside of a diamond.\n * See https://en.wikipedia.org/wiki/Specials_(Unicode_block)\n *\n */\nexport const INTERPOLATION_DELIMITER = `�`;\n\n/**\n * Unwrap a value which might be behind a closure (for forward declaration reasons).\n */\nexport function maybeUnwrapFn(value: T|(() => T)): T {\n if (value instanceof Function) {\n return value();\n } else {\n return value;\n }\n}\n\n/**\n * Detects whether the code is invoked in a browser.\n * Later on, this check should be replaced with a tree-shakable\n * flag (e.g. `!isServer`).\n */\nexport function isPlatformBrowser(injector?: Injector): boolean {\n return (injector ?? inject(Injector)).get(PLATFORM_ID) === 'browser';\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\n/**\n * A schema definition associated with an NgModule.\n *\n * @see {@link NgModule}\n * @see {@link CUSTOM_ELEMENTS_SCHEMA}\n * @see {@link NO_ERRORS_SCHEMA}\n *\n * @param name The name of a defined schema.\n *\n * @publicApi\n */\nexport interface SchemaMetadata {\n name: string;\n}\n\n/**\n * Defines a schema that allows an NgModule to contain the following:\n * - Non-Angular elements named with dash case (`-`).\n * - Element properties named with dash case (`-`).\n * Dash case is the naming convention for custom elements.\n *\n * @publicApi\n */\nexport const CUSTOM_ELEMENTS_SCHEMA: SchemaMetadata = {\n name: 'custom-elements'\n};\n\n/**\n * Defines a schema that allows any property on any element.\n *\n * This schema allows you to ignore the errors related to any unknown elements or properties in a\n * template. The usage of this schema is generally discouraged because it prevents useful validation\n * and may hide real errors in your template. Consider using the `CUSTOM_ELEMENTS_SCHEMA` instead.\n *\n * @publicApi\n */\nexport const NO_ERRORS_SCHEMA: SchemaMetadata = {\n name: 'no-errors-schema'\n};\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {formatRuntimeError, RuntimeError, RuntimeErrorCode} from '../../errors';\nimport {Type} from '../../interface/type';\nimport {CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA, SchemaMetadata} from '../../metadata/schema';\nimport {throwError} from '../../util/assert';\nimport {getComponentDef} from '../definition';\nimport {ComponentDef} from '../interfaces/definition';\nimport {TNodeType} from '../interfaces/node';\nimport {RComment, RElement} from '../interfaces/renderer_dom';\nimport {CONTEXT, DECLARATION_COMPONENT_VIEW, LView} from '../interfaces/view';\nimport {isAnimationProp} from '../util/attrs_utils';\n\nlet shouldThrowErrorOnUnknownElement = false;\n\n/**\n * Sets a strict mode for JIT-compiled components to throw an error on unknown elements,\n * instead of just logging the error.\n * (for AOT-compiled ones this check happens at build time).\n */\nexport function ɵsetUnknownElementStrictMode(shouldThrow: boolean) {\n shouldThrowErrorOnUnknownElement = shouldThrow;\n}\n\n/**\n * Gets the current value of the strict mode.\n */\nexport function ɵgetUnknownElementStrictMode() {\n return shouldThrowErrorOnUnknownElement;\n}\n\nlet shouldThrowErrorOnUnknownProperty = false;\n\n/**\n * Sets a strict mode for JIT-compiled components to throw an error on unknown properties,\n * instead of just logging the error.\n * (for AOT-compiled ones this check happens at build time).\n */\nexport function ɵsetUnknownPropertyStrictMode(shouldThrow: boolean) {\n shouldThrowErrorOnUnknownProperty = shouldThrow;\n}\n\n/**\n * Gets the current value of the strict mode.\n */\nexport function ɵgetUnknownPropertyStrictMode() {\n return shouldThrowErrorOnUnknownProperty;\n}\n\n/**\n * Validates that the element is known at runtime and produces\n * an error if it's not the case.\n * This check is relevant for JIT-compiled components (for AOT-compiled\n * ones this check happens at build time).\n *\n * The element is considered known if either:\n * - it's a known HTML element\n * - it's a known custom element\n * - the element matches any directive\n * - the element is allowed by one of the schemas\n *\n * @param element Element to validate\n * @param lView An `LView` that represents a current component that is being rendered\n * @param tagName Name of the tag to check\n * @param schemas Array of schemas\n * @param hasDirectives Boolean indicating that the element matches any directive\n */\nexport function validateElementIsKnown(\n element: RElement, lView: LView, tagName: string|null, schemas: SchemaMetadata[]|null,\n hasDirectives: boolean): void {\n // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT\n // mode where this check happens at compile time. In JIT mode, `schemas` is always present and\n // defined as an array (as an empty array in case `schemas` field is not defined) and we should\n // execute the check below.\n if (schemas === null) return;\n\n // If the element matches any directive, it's considered as valid.\n if (!hasDirectives && tagName !== null) {\n // The element is unknown if it's an instance of HTMLUnknownElement, or it isn't registered\n // as a custom element. Note that unknown elements with a dash in their name won't be instances\n // of HTMLUnknownElement in browsers that support web components.\n const isUnknown =\n // Note that we can't check for `typeof HTMLUnknownElement === 'function'` because\n // Domino doesn't expose HTMLUnknownElement globally.\n (typeof HTMLUnknownElement !== 'undefined' && HTMLUnknownElement &&\n element instanceof HTMLUnknownElement) ||\n (typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 &&\n !customElements.get(tagName));\n\n if (isUnknown && !matchingSchemas(schemas, tagName)) {\n const isHostStandalone = isHostComponentStandalone(lView);\n const templateLocation = getTemplateLocationDetails(lView);\n const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;\n\n let message = `'${tagName}' is not a known element${templateLocation}:\\n`;\n message += `1. If '${tagName}' is an Angular component, then verify that it is ${\n isHostStandalone ? 'included in the \\'@Component.imports\\' of this component' :\n 'a part of an @NgModule where this component is declared'}.\\n`;\n if (tagName && tagName.indexOf('-') > -1) {\n message +=\n `2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the ${\n schemas} of this component to suppress this message.`;\n } else {\n message +=\n `2. To allow any element add 'NO_ERRORS_SCHEMA' to the ${schemas} of this component.`;\n }\n if (shouldThrowErrorOnUnknownElement) {\n throw new RuntimeError(RuntimeErrorCode.UNKNOWN_ELEMENT, message);\n } else {\n console.error(formatRuntimeError(RuntimeErrorCode.UNKNOWN_ELEMENT, message));\n }\n }\n }\n}\n\n/**\n * Validates that the property of the element is known at runtime and returns\n * false if it's not the case.\n * This check is relevant for JIT-compiled components (for AOT-compiled\n * ones this check happens at build time).\n *\n * The property is considered known if either:\n * - it's a known property of the element\n * - the element is allowed by one of the schemas\n * - the property is used for animations\n *\n * @param element Element to validate\n * @param propName Name of the property to check\n * @param tagName Name of the tag hosting the property\n * @param schemas Array of schemas\n */\nexport function isPropertyValid(\n element: RElement|RComment, propName: string, tagName: string|null,\n schemas: SchemaMetadata[]|null): boolean {\n // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT\n // mode where this check happens at compile time. In JIT mode, `schemas` is always present and\n // defined as an array (as an empty array in case `schemas` field is not defined) and we should\n // execute the check below.\n if (schemas === null) return true;\n\n // The property is considered valid if the element matches the schema, it exists on the element,\n // or it is synthetic.\n if (matchingSchemas(schemas, tagName) || propName in element || isAnimationProp(propName)) {\n return true;\n }\n\n // Note: `typeof Node` returns 'function' in most browsers, but is undefined with domino.\n return typeof Node === 'undefined' || Node === null || !(element instanceof Node);\n}\n\n/**\n * Logs or throws an error that a property is not supported on an element.\n *\n * @param propName Name of the invalid property\n * @param tagName Name of the tag hosting the property\n * @param nodeType Type of the node hosting the property\n * @param lView An `LView` that represents a current component\n */\nexport function handleUnknownPropertyError(\n propName: string, tagName: string|null, nodeType: TNodeType, lView: LView): void {\n // Special-case a situation when a structural directive is applied to\n // an `` element, for example: ``.\n // In this case the compiler generates the `ɵɵtemplate` instruction with\n // the `null` as the tagName. The directive matching logic at runtime relies\n // on this effect (see `isInlineTemplate`), thus using the 'ng-template' as\n // a default value of the `tNode.value` is not feasible at this moment.\n if (!tagName && nodeType === TNodeType.Container) {\n tagName = 'ng-template';\n }\n\n const isHostStandalone = isHostComponentStandalone(lView);\n const templateLocation = getTemplateLocationDetails(lView);\n\n let message = `Can't bind to '${propName}' since it isn't a known property of '${tagName}'${\n templateLocation}.`;\n\n const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;\n const importLocation = isHostStandalone ?\n 'included in the \\'@Component.imports\\' of this component' :\n 'a part of an @NgModule where this component is declared';\n if (KNOWN_CONTROL_FLOW_DIRECTIVES.has(propName)) {\n // Most likely this is a control flow directive (such as `*ngIf`) used in\n // a template, but the directive or the `CommonModule` is not imported.\n const correspondingImport = KNOWN_CONTROL_FLOW_DIRECTIVES.get(propName);\n message += `\\nIf the '${propName}' is an Angular control flow directive, ` +\n `please make sure that either the '${\n correspondingImport}' directive or the 'CommonModule' is ${importLocation}.`;\n } else {\n // May be an Angular component, which is not imported/declared?\n message += `\\n1. If '${tagName}' is an Angular component and it has the ` +\n `'${propName}' input, then verify that it is ${importLocation}.`;\n // May be a Web Component?\n if (tagName && tagName.indexOf('-') > -1) {\n message += `\\n2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' ` +\n `to the ${schemas} of this component to suppress this message.`;\n message += `\\n3. To allow any property add 'NO_ERRORS_SCHEMA' to ` +\n `the ${schemas} of this component.`;\n } else {\n // If it's expected, the error can be suppressed by the `NO_ERRORS_SCHEMA` schema.\n message += `\\n2. To allow any property add 'NO_ERRORS_SCHEMA' to ` +\n `the ${schemas} of this component.`;\n }\n }\n\n reportUnknownPropertyError(message);\n}\n\nexport function reportUnknownPropertyError(message: string) {\n if (shouldThrowErrorOnUnknownProperty) {\n throw new RuntimeError(RuntimeErrorCode.UNKNOWN_BINDING, message);\n } else {\n console.error(formatRuntimeError(RuntimeErrorCode.UNKNOWN_BINDING, message));\n }\n}\n\n/**\n * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)\n * and must **not** be used in production bundles. The function makes megamorphic reads, which might\n * be too slow for production mode and also it relies on the constructor function being available.\n *\n * Gets a reference to the host component def (where a current component is declared).\n *\n * @param lView An `LView` that represents a current component that is being rendered.\n */\nexport function getDeclarationComponentDef(lView: LView): ComponentDef|null {\n !ngDevMode && throwError('Must never be called in production mode');\n\n const declarationLView = lView[DECLARATION_COMPONENT_VIEW] as LView>;\n const context = declarationLView[CONTEXT];\n\n // Unable to obtain a context.\n if (!context) return null;\n\n return context.constructor ? getComponentDef(context.constructor) : null;\n}\n\n/**\n * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)\n * and must **not** be used in production bundles. The function makes megamorphic reads, which might\n * be too slow for production mode.\n *\n * Checks if the current component is declared inside of a standalone component template.\n *\n * @param lView An `LView` that represents a current component that is being rendered.\n */\nexport function isHostComponentStandalone(lView: LView): boolean {\n !ngDevMode && throwError('Must never be called in production mode');\n\n const componentDef = getDeclarationComponentDef(lView);\n // Treat host component as non-standalone if we can't obtain the def.\n return !!componentDef?.standalone;\n}\n\n/**\n * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)\n * and must **not** be used in production bundles. The function makes megamorphic reads, which might\n * be too slow for production mode.\n *\n * Constructs a string describing the location of the host component template. The function is used\n * in dev mode to produce error messages.\n *\n * @param lView An `LView` that represents a current component that is being rendered.\n */\nexport function getTemplateLocationDetails(lView: LView): string {\n !ngDevMode && throwError('Must never be called in production mode');\n\n const hostComponentDef = getDeclarationComponentDef(lView);\n const componentClassName = hostComponentDef?.type?.name;\n return componentClassName ? ` (used in the '${componentClassName}' component template)` : '';\n}\n\n/**\n * The set of known control flow directives and their corresponding imports.\n * We use this set to produce a more precises error message with a note\n * that the `CommonModule` should also be included.\n */\nexport const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([\n ['ngIf', 'NgIf'], ['ngFor', 'NgFor'], ['ngSwitchCase', 'NgSwitchCase'],\n ['ngSwitchDefault', 'NgSwitchDefault']\n]);\n/**\n * Returns true if the tag name is allowed by specified schemas.\n * @param schemas Array of schemas\n * @param tagName Name of the tag\n */\nexport function matchingSchemas(schemas: SchemaMetadata[]|null, tagName: string|null): boolean {\n if (schemas !== null) {\n for (let i = 0; i < schemas.length; i++) {\n const schema = schemas[i];\n if (schema === NO_ERRORS_SCHEMA ||\n schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {\n return true;\n }\n }\n }\n\n return false;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {TNode, TNodeFlags} from '../render3/interfaces/node';\nimport {RElement} from '../render3/interfaces/renderer_dom';\n\n/**\n * The name of an attribute that can be added to the hydration boundary node\n * (component host node) to disable hydration for the content within that boundary.\n */\nexport const SKIP_HYDRATION_ATTR_NAME = 'ngSkipHydration';\n\n/**\n * Helper function to check if a given TNode has the 'ngSkipHydration' attribute.\n */\nexport function hasSkipHydrationAttrOnTNode(tNode: TNode): boolean {\n const SKIP_HYDRATION_ATTR_NAME_LOWER_CASE = SKIP_HYDRATION_ATTR_NAME.toLowerCase();\n\n const attrs = tNode.mergedAttrs;\n if (attrs === null) return false;\n // only ever look at the attribute name and skip the values\n for (let i = 0; i < attrs.length; i += 2) {\n const value = attrs[i];\n // This is a marker, which means that the static attributes section is over,\n // so we can exit early.\n if (typeof value === 'number') return false;\n if (typeof value === 'string' && value.toLowerCase() === SKIP_HYDRATION_ATTR_NAME_LOWER_CASE) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Helper function to check if a given RElement has the 'ngSkipHydration' attribute.\n */\nexport function hasSkipHydrationAttrOnRElement(rNode: RElement): boolean {\n return rNode.hasAttribute(SKIP_HYDRATION_ATTR_NAME);\n}\n\n/**\n * Checks whether a TNode has a flag to indicate that it's a part of\n * a skip hydration block.\n */\nexport function hasInSkipHydrationBlockFlag(tNode: TNode): boolean {\n return (tNode.flags & TNodeFlags.inSkipHydrationBlock) === TNodeFlags.inSkipHydrationBlock;\n}\n\n/**\n * Helper function that determines if a given node is within a skip hydration block\n * by navigating up the TNode tree to see if any parent nodes have skip hydration\n * attribute.\n *\n * TODO(akushnir): this function should contain the logic of `hasInSkipHydrationBlockFlag`,\n * there is no need to traverse parent nodes when we have a TNode flag (which would also\n * make this lookup O(1)).\n */\nexport function isInSkipHydrationBlock(tNode: TNode): boolean {\n let currentTNode: TNode|null = tNode.parent;\n while (currentTNode) {\n if (hasSkipHydrationAttrOnTNode(currentTNode)) {\n return true;\n }\n currentTNode = currentTNode.parent;\n }\n return false;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {ViewEncapsulation} from '../metadata/view';\n\n\n/**\n * Used by `RendererFactory2` to associate custom rendering data and styles\n * with a rendering implementation.\n * @publicApi\n */\nexport interface RendererType2 {\n /**\n * A unique identifying string for the new renderer, used when creating\n * unique styles for encapsulation.\n */\n id: string;\n /**\n * The view encapsulation type, which determines how styles are applied to\n * DOM elements. One of\n * - `Emulated` (default): Emulate native scoping of styles.\n * - `Native`: Use the native encapsulation mechanism of the renderer.\n * - `ShadowDom`: Use modern [Shadow\n * DOM](https://w3c.github.io/webcomponents/spec/shadow/) and\n * create a ShadowRoot for component's host element.\n * - `None`: Do not provide any template or style encapsulation.\n */\n encapsulation: ViewEncapsulation;\n /**\n * Defines CSS styles to be stored on a renderer instance.\n */\n styles: string[];\n /**\n * Defines arbitrary developer-defined data to be stored on a renderer instance.\n * This is useful for renderers that delegate to other renderers.\n */\n data: {[kind: string]: any};\n}\n\n\n/**\n * Flags for renderer-specific style modifiers.\n * @publicApi\n */\nexport enum RendererStyleFlags2 {\n // TODO(misko): This needs to be refactored into a separate file so that it can be imported from\n // `node_manipulation.ts` Currently doing the import cause resolution order to change and fails\n // the tests. The work around is to have hard coded value in `node_manipulation.ts` for now.\n /**\n * Marks a style as important.\n */\n Important = 1 << 0,\n /**\n * Marks a style as using dash case naming (this-is-dash-case).\n */\n DashCase = 1 << 1\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Disallowed strings in the comment.\n *\n * see: https://html.spec.whatwg.org/multipage/syntax.html#comments\n */\nconst COMMENT_DISALLOWED = /^>|^->||--!>|)/g;\nconst COMMENT_DELIMITER_ESCAPED = '\\u200B$1\\u200B';\n\n/**\n * Escape the content of comment strings so that it can be safely inserted into a comment node.\n *\n * The issue is that HTML does not specify any way to escape comment end text inside the comment.\n * Consider: `\" or\n * \"--!>\" at the end. -->`. Above the `\"-->\"` is meant to be text not an end to the comment. This\n * can be created programmatically through DOM APIs. (`` or `--!>`) the\n * text it will render normally but it will not cause the HTML parser to close/open the comment.\n *\n * @param value text to make safe for comment node by escaping the comment open/close character\n * sequence.\n */\nexport function escapeCommentText(value: string): string {\n return value.replace(\n COMMENT_DISALLOWED, (text) => text.replace(COMMENT_DELIMITER, COMMENT_DELIMITER_ESCAPED));\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertNumber} from '../../util/assert';\n\nimport {ID, LView} from './view';\n\n// Keeps track of the currently-active LViews.\nconst TRACKED_LVIEWS = new Map();\n\n// Used for generating unique IDs for LViews.\nlet uniqueIdCounter = 0;\n\n/** Gets a unique ID that can be assigned to an LView. */\nexport function getUniqueLViewId(): number {\n return uniqueIdCounter++;\n}\n\n/** Starts tracking an LView. */\nexport function registerLView(lView: LView): void {\n ngDevMode && assertNumber(lView[ID], 'LView must have an ID in order to be registered');\n TRACKED_LVIEWS.set(lView[ID], lView);\n}\n\n/** Gets an LView by its unique ID. */\nexport function getLViewById(id: number): LView|null {\n ngDevMode && assertNumber(id, 'ID used for LView lookup must be a number');\n return TRACKED_LVIEWS.get(id) || null;\n}\n\n/** Stops tracking an LView. */\nexport function unregisterLView(lView: LView): void {\n ngDevMode && assertNumber(lView[ID], 'Cannot stop tracking an LView that does not have an ID');\n TRACKED_LVIEWS.delete(lView[ID]);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nimport {getLViewById} from './lview_tracking';\nimport {RNode} from './renderer_dom';\nimport {LView} from './view';\n\n\n/**\n * The internal view context which is specific to a given DOM element, directive or\n * component instance. Each value in here (besides the LView and element node details)\n * can be present, null or undefined. If undefined then it implies the value has not been\n * looked up yet, otherwise, if null, then a lookup was executed and nothing was found.\n *\n * Each value will get filled when the respective value is examined within the getContext\n * function. The component, element and each directive instance will share the same instance\n * of the context.\n */\nexport class LContext {\n /**\n * The instance of the Component node.\n */\n public component: {}|null|undefined;\n\n /**\n * The list of active directives that exist on this element.\n */\n public directives: any[]|null|undefined;\n\n /**\n * The map of local references (local reference name => element or directive instance) that\n * exist on this element.\n */\n public localRefs: {[key: string]: any}|null|undefined;\n\n /** Component's parent view data. */\n get lView(): LView|null {\n return getLViewById(this.lViewId);\n }\n\n constructor(\n /**\n * ID of the component's parent view data.\n */\n private lViewId: number,\n\n /**\n * The index instance of the node.\n */\n public nodeIndex: number,\n\n /**\n * The instance of the DOM node that is attached to the lNode.\n */\n public native: RNode) {}\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport '../util/ng_dev_mode';\n\nimport {assertDefined, assertDomNode} from '../util/assert';\nimport {EMPTY_ARRAY} from '../util/empty';\n\nimport {assertLView} from './assert';\nimport {LContext} from './interfaces/context';\nimport {getLViewById, registerLView} from './interfaces/lview_tracking';\nimport {TNode} from './interfaces/node';\nimport {RElement, RNode} from './interfaces/renderer_dom';\nimport {isLView} from './interfaces/type_checks';\nimport {CONTEXT, HEADER_OFFSET, HOST, ID, LView, TVIEW} from './interfaces/view';\nimport {getComponentLViewByIndex, unwrapRNode} from './util/view_utils';\n\n\n\n/**\n * Returns the matching `LContext` data for a given DOM node, directive or component instance.\n *\n * This function will examine the provided DOM element, component, or directive instance\\'s\n * monkey-patched property to derive the `LContext` data. Once called then the monkey-patched\n * value will be that of the newly created `LContext`.\n *\n * If the monkey-patched value is the `LView` instance then the context value for that\n * target will be created and the monkey-patch reference will be updated. Therefore when this\n * function is called it may mutate the provided element\\'s, component\\'s or any of the associated\n * directive\\'s monkey-patch values.\n *\n * If the monkey-patch value is not detected then the code will walk up the DOM until an element\n * is found which contains a monkey-patch reference. When that occurs then the provided element\n * will be updated with a new context (which is then returned). If the monkey-patch value is not\n * detected for a component/directive instance then it will throw an error (all components and\n * directives should be automatically monkey-patched by ivy).\n *\n * @param target Component, Directive or DOM Node.\n */\nexport function getLContext(target: any): LContext|null {\n let mpValue = readPatchedData(target);\n if (mpValue) {\n // only when it's an array is it considered an LView instance\n // ... otherwise it's an already constructed LContext instance\n if (isLView(mpValue)) {\n const lView: LView = mpValue!;\n let nodeIndex: number;\n let component: any = undefined;\n let directives: any[]|null|undefined = undefined;\n\n if (isComponentInstance(target)) {\n nodeIndex = findViaComponent(lView, target);\n if (nodeIndex == -1) {\n throw new Error('The provided component was not found in the application');\n }\n component = target;\n } else if (isDirectiveInstance(target)) {\n nodeIndex = findViaDirective(lView, target);\n if (nodeIndex == -1) {\n throw new Error('The provided directive was not found in the application');\n }\n directives = getDirectivesAtNodeIndex(nodeIndex, lView);\n } else {\n nodeIndex = findViaNativeElement(lView, target as RElement);\n if (nodeIndex == -1) {\n return null;\n }\n }\n\n // the goal is not to fill the entire context full of data because the lookups\n // are expensive. Instead, only the target data (the element, component, container, ICU\n // expression or directive details) are filled into the context. If called multiple times\n // with different target values then the missing target data will be filled in.\n const native = unwrapRNode(lView[nodeIndex]);\n const existingCtx = readPatchedData(native);\n const context: LContext = (existingCtx && !Array.isArray(existingCtx)) ?\n existingCtx :\n createLContext(lView, nodeIndex, native);\n\n // only when the component has been discovered then update the monkey-patch\n if (component && context.component === undefined) {\n context.component = component;\n attachPatchData(context.component, context);\n }\n\n // only when the directives have been discovered then update the monkey-patch\n if (directives && context.directives === undefined) {\n context.directives = directives;\n for (let i = 0; i < directives.length; i++) {\n attachPatchData(directives[i], context);\n }\n }\n\n attachPatchData(context.native, context);\n mpValue = context;\n }\n } else {\n const rElement = target as RElement;\n ngDevMode && assertDomNode(rElement);\n\n // if the context is not found then we need to traverse upwards up the DOM\n // to find the nearest element that has already been monkey patched with data\n let parent = rElement as any;\n while (parent = parent.parentNode) {\n const parentContext = readPatchedData(parent);\n if (parentContext) {\n const lView = Array.isArray(parentContext) ? parentContext as LView : parentContext.lView;\n\n // the edge of the app was also reached here through another means\n // (maybe because the DOM was changed manually).\n if (!lView) {\n return null;\n }\n\n const index = findViaNativeElement(lView, rElement);\n if (index >= 0) {\n const native = unwrapRNode(lView[index]);\n const context = createLContext(lView, index, native);\n attachPatchData(native, context);\n mpValue = context;\n break;\n }\n }\n }\n }\n return (mpValue as LContext) || null;\n}\n\n/**\n * Creates an empty instance of a `LContext` context\n */\nfunction createLContext(lView: LView, nodeIndex: number, native: RNode): LContext {\n return new LContext(lView[ID], nodeIndex, native);\n}\n\n/**\n * Takes a component instance and returns the view for that component.\n *\n * @param componentInstance\n * @returns The component's view\n */\nexport function getComponentViewByInstance(componentInstance: {}): LView {\n let patchedData = readPatchedData(componentInstance);\n let lView: LView;\n\n if (isLView(patchedData)) {\n const contextLView: LView = patchedData;\n const nodeIndex = findViaComponent(contextLView, componentInstance);\n lView = getComponentLViewByIndex(nodeIndex, contextLView);\n const context = createLContext(contextLView, nodeIndex, lView[HOST] as RElement);\n context.component = componentInstance;\n attachPatchData(componentInstance, context);\n attachPatchData(context.native, context);\n } else {\n const context = patchedData as unknown as LContext;\n const contextLView = context.lView!;\n ngDevMode && assertLView(contextLView);\n lView = getComponentLViewByIndex(context.nodeIndex, contextLView);\n }\n return lView;\n}\n\n/**\n * This property will be monkey-patched on elements, components and directives.\n */\nconst MONKEY_PATCH_KEY_NAME = '__ngContext__';\n\n/**\n * Assigns the given data to the given target (which could be a component,\n * directive or DOM node instance) using monkey-patching.\n */\nexport function attachPatchData(target: any, data: LView|LContext) {\n ngDevMode && assertDefined(target, 'Target expected');\n // Only attach the ID of the view in order to avoid memory leaks (see #41047). We only do this\n // for `LView`, because we have control over when an `LView` is created and destroyed, whereas\n // we can't know when to remove an `LContext`.\n if (isLView(data)) {\n target[MONKEY_PATCH_KEY_NAME] = data[ID];\n registerLView(data);\n } else {\n target[MONKEY_PATCH_KEY_NAME] = data;\n }\n}\n\n/**\n * Returns the monkey-patch value data present on the target (which could be\n * a component, directive or a DOM node).\n */\nexport function readPatchedData(target: any): LView|LContext|null {\n ngDevMode && assertDefined(target, 'Target expected');\n const data = target[MONKEY_PATCH_KEY_NAME];\n return (typeof data === 'number') ? getLViewById(data) : data || null;\n}\n\nexport function readPatchedLView(target: any): LView|null {\n const value = readPatchedData(target);\n if (value) {\n return (isLView(value) ? value : value.lView) as LView;\n }\n return null;\n}\n\nexport function isComponentInstance(instance: any): boolean {\n return instance && instance.constructor && instance.constructor.ɵcmp;\n}\n\nexport function isDirectiveInstance(instance: any): boolean {\n return instance && instance.constructor && instance.constructor.ɵdir;\n}\n\n/**\n * Locates the element within the given LView and returns the matching index\n */\nfunction findViaNativeElement(lView: LView, target: RElement): number {\n const tView = lView[TVIEW];\n for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {\n if (unwrapRNode(lView[i]) === target) {\n return i;\n }\n }\n\n return -1;\n}\n\n/**\n * Locates the next tNode (child, sibling or parent).\n */\nfunction traverseNextElement(tNode: TNode): TNode|null {\n if (tNode.child) {\n return tNode.child;\n } else if (tNode.next) {\n return tNode.next;\n } else {\n // Let's take the following template:
text
\n // After checking the text node, we need to find the next parent that has a \"next\" TNode,\n // in this case the parent `div`, so that we can find the component.\n while (tNode.parent && !tNode.parent.next) {\n tNode = tNode.parent;\n }\n return tNode.parent && tNode.parent.next;\n }\n}\n\n/**\n * Locates the component within the given LView and returns the matching index\n */\nfunction findViaComponent(lView: LView, componentInstance: {}): number {\n const componentIndices = lView[TVIEW].components;\n if (componentIndices) {\n for (let i = 0; i < componentIndices.length; i++) {\n const elementComponentIndex = componentIndices[i];\n const componentView = getComponentLViewByIndex(elementComponentIndex, lView);\n if (componentView[CONTEXT] === componentInstance) {\n return elementComponentIndex;\n }\n }\n } else {\n const rootComponentView = getComponentLViewByIndex(HEADER_OFFSET, lView);\n const rootComponent = rootComponentView[CONTEXT];\n if (rootComponent === componentInstance) {\n // we are dealing with the root element here therefore we know that the\n // element is the very first element after the HEADER data in the lView\n return HEADER_OFFSET;\n }\n }\n return -1;\n}\n\n/**\n * Locates the directive within the given LView and returns the matching index\n */\nfunction findViaDirective(lView: LView, directiveInstance: {}): number {\n // if a directive is monkey patched then it will (by default)\n // have a reference to the LView of the current view. The\n // element bound to the directive being search lives somewhere\n // in the view data. We loop through the nodes and check their\n // list of directives for the instance.\n let tNode = lView[TVIEW].firstChild;\n while (tNode) {\n const directiveIndexStart = tNode.directiveStart;\n const directiveIndexEnd = tNode.directiveEnd;\n for (let i = directiveIndexStart; i < directiveIndexEnd; i++) {\n if (lView[i] === directiveInstance) {\n return tNode.index;\n }\n }\n tNode = traverseNextElement(tNode);\n }\n return -1;\n}\n\n/**\n * Returns a list of directives applied to a node at a specific index. The list includes\n * directives matched by selector and any host directives, but it excludes components.\n * Use `getComponentAtNodeIndex` to find the component applied to a node.\n *\n * @param nodeIndex The node index\n * @param lView The target view data\n */\nexport function getDirectivesAtNodeIndex(nodeIndex: number, lView: LView): any[]|null {\n const tNode = lView[TVIEW].data[nodeIndex] as TNode;\n if (tNode.directiveStart === 0) return EMPTY_ARRAY;\n const results: any[] = [];\n for (let i = tNode.directiveStart; i < tNode.directiveEnd; i++) {\n const directiveInstance = lView[i];\n if (!isComponentInstance(directiveInstance)) {\n results.push(directiveInstance);\n }\n }\n return results;\n}\n\nexport function getComponentAtNodeIndex(nodeIndex: number, lView: LView): {}|null {\n const tNode = lView[TVIEW].data[nodeIndex] as TNode;\n const {directiveStart, componentOffset} = tNode;\n return componentOffset > -1 ? lView[directiveStart + componentOffset] : null;\n}\n\n/**\n * Returns a map of local references (local reference name => element or directive instance) that\n * exist on a given element.\n */\nexport function discoverLocalRefs(lView: LView, nodeIndex: number): {[key: string]: any}|null {\n const tNode = lView[TVIEW].data[nodeIndex] as TNode;\n if (tNode && tNode.localNames) {\n const result: {[key: string]: any} = {};\n let localIndex = tNode.index + 1;\n for (let i = 0; i < tNode.localNames.length; i += 2) {\n result[tNode.localNames[i]] = lView[localIndex];\n localIndex++;\n }\n return result;\n }\n\n return null;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @fileoverview\n *\n * This file provides mechanism by which code relevant to the `TIcuContainerNode` is only loaded if\n * ICU is present in the template.\n */\n\nimport {TIcuContainerNode} from '../interfaces/node';\nimport {RNode} from '../interfaces/renderer_dom';\nimport {LView} from '../interfaces/view';\n\n\nlet _icuContainerIterate: (tIcuContainerNode: TIcuContainerNode, lView: LView) =>\n (() => RNode | null);\n\n/**\n * Iterator which provides ability to visit all of the `TIcuContainerNode` root `RNode`s.\n */\nexport function icuContainerIterate(tIcuContainerNode: TIcuContainerNode, lView: LView): () =>\n RNode | null {\n return _icuContainerIterate(tIcuContainerNode, lView);\n}\n\n/**\n * Ensures that `IcuContainerVisitor`'s implementation is present.\n *\n * This function is invoked when i18n instruction comes across an ICU. The purpose is to allow the\n * bundler to tree shake ICU logic and only load it if ICU instruction is executed.\n */\nexport function ensureIcuContainerVisitorLoaded(\n loader: () => ((tIcuContainerNode: TIcuContainerNode, lView: LView) => (() => RNode | null))) {\n if (_icuContainerIterate === undefined) {\n // Do not inline this function. We want to keep `ensureIcuContainerVisitorLoaded` light, so it\n // can be inlined into call-site.\n _icuContainerIterate = loader();\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {assertDefined} from '../../util/assert';\nimport {assertLView} from '../assert';\nimport {readPatchedLView} from '../context_discovery';\nimport {LContainer} from '../interfaces/container';\nimport {isLContainer, isLView} from '../interfaces/type_checks';\nimport {CHILD_HEAD, CONTEXT, FLAGS, LView, LViewFlags, NEXT, PARENT} from '../interfaces/view';\n\n\n/**\n * Gets the parent LView of the passed LView, if the PARENT is an LContainer, will get the parent of\n * that LContainer, which is an LView\n * @param lView the lView whose parent to get\n */\nexport function getLViewParent(lView: LView): LView|null {\n ngDevMode && assertLView(lView);\n const parent = lView[PARENT];\n return isLContainer(parent) ? parent[PARENT]! : parent;\n}\n\n/**\n * Retrieve the root view from any component or `LView` by walking the parent `LView` until\n * reaching the root `LView`.\n *\n * @param componentOrLView any component or `LView`\n */\nexport function getRootView(componentOrLView: LView|{}): LView {\n ngDevMode && assertDefined(componentOrLView, 'component');\n let lView = isLView(componentOrLView) ? componentOrLView : readPatchedLView(componentOrLView)!;\n while (lView && !(lView[FLAGS] & LViewFlags.IsRoot)) {\n lView = getLViewParent(lView)!;\n }\n ngDevMode && assertLView(lView);\n return lView as LView;\n}\n\n/**\n * Returns the context information associated with the application where the target is situated. It\n * does this by walking the parent views until it gets to the root view, then getting the context\n * off of that.\n *\n * @param viewOrComponent the `LView` or component to get the root context for.\n */\nexport function getRootContext(viewOrComponent: LView|{}): T {\n const rootView = getRootView(viewOrComponent);\n ngDevMode &&\n assertDefined(rootView[CONTEXT], 'Root view has no context. Perhaps it is disconnected?');\n return rootView[CONTEXT] as T;\n}\n\n\n/**\n * Gets the first `LContainer` in the LView or `null` if none exists.\n */\nexport function getFirstLContainer(lView: LView): LContainer|null {\n return getNearestLContainer(lView[CHILD_HEAD]);\n}\n\n/**\n * Gets the next `LContainer` that is a sibling of the given container.\n */\nexport function getNextLContainer(container: LContainer): LContainer|null {\n return getNearestLContainer(container[NEXT]);\n}\n\nfunction getNearestLContainer(viewOrContainer: LContainer|LView|null) {\n while (viewOrContainer !== null && !isLContainer(viewOrContainer)) {\n viewOrContainer = viewOrContainer[NEXT];\n }\n return viewOrContainer as LContainer | null;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {hasInSkipHydrationBlockFlag} from '../hydration/skip_hydration';\nimport {ViewEncapsulation} from '../metadata/view';\nimport {RendererStyleFlags2} from '../render/api_flags';\nimport {consumerDestroy} from '../signals';\nimport {addToArray, removeFromArray} from '../util/array_utils';\nimport {assertDefined, assertEqual, assertFunction, assertNumber, assertString} from '../util/assert';\nimport {escapeCommentText} from '../util/dom';\n\nimport {assertLContainer, assertLView, assertParentView, assertProjectionSlots, assertTNodeForLView} from './assert';\nimport {attachPatchData} from './context_discovery';\nimport {icuContainerIterate} from './i18n/i18n_tree_shaking';\nimport {CONTAINER_HEADER_OFFSET, HAS_TRANSPLANTED_VIEWS, LContainer, MOVED_VIEWS, NATIVE} from './interfaces/container';\nimport {ComponentDef} from './interfaces/definition';\nimport {NodeInjectorFactory} from './interfaces/injector';\nimport {unregisterLView} from './interfaces/lview_tracking';\nimport {TElementNode, TIcuContainerNode, TNode, TNodeFlags, TNodeType, TProjectionNode} from './interfaces/node';\nimport {Renderer} from './interfaces/renderer';\nimport {RComment, RElement, RNode, RTemplate, RText} from './interfaces/renderer_dom';\nimport {isLContainer, isLView} from './interfaces/type_checks';\nimport {CHILD_HEAD, CLEANUP, DECLARATION_COMPONENT_VIEW, DECLARATION_LCONTAINER, DestroyHookData, FLAGS, HookData, HookFn, HOST, LView, LViewFlags, NEXT, ON_DESTROY_HOOKS, PARENT, QUERIES, REACTIVE_HOST_BINDING_CONSUMER, REACTIVE_TEMPLATE_CONSUMER, RENDERER, T_HOST, TVIEW, TView, TViewType} from './interfaces/view';\nimport {assertTNodeType} from './node_assert';\nimport {profiler, ProfilerEvent} from './profiler';\nimport {setUpAttributes} from './util/attrs_utils';\nimport {getLViewParent} from './util/view_traversal_utils';\nimport {clearViewRefreshFlag, getNativeByTNode, unwrapRNode} from './util/view_utils';\n\nconst enum WalkTNodeTreeAction {\n /** node create in the native environment. Run on initial creation. */\n Create = 0,\n\n /**\n * node insert in the native environment.\n * Run when existing node has been detached and needs to be re-attached.\n */\n Insert = 1,\n\n /** node detach from the native environment */\n Detach = 2,\n\n /** node destruction using the renderer's API */\n Destroy = 3,\n}\n\n\n\n/**\n * NOTE: for performance reasons, the possible actions are inlined within the function instead of\n * being passed as an argument.\n */\nfunction applyToElementOrContainer(\n action: WalkTNodeTreeAction, renderer: Renderer, parent: RElement|null,\n lNodeToHandle: RNode|LContainer|LView, beforeNode?: RNode|null) {\n // If this slot was allocated for a text node dynamically created by i18n, the text node itself\n // won't be created until i18nApply() in the update block, so this node should be skipped.\n // For more info, see \"ICU expressions should work inside an ngTemplateOutlet inside an ngFor\"\n // in `i18n_spec.ts`.\n if (lNodeToHandle != null) {\n let lContainer: LContainer|undefined;\n let isComponent = false;\n // We are expecting an RNode, but in the case of a component or LContainer the `RNode` is\n // wrapped in an array which needs to be unwrapped. We need to know if it is a component and if\n // it has LContainer so that we can process all of those cases appropriately.\n if (isLContainer(lNodeToHandle)) {\n lContainer = lNodeToHandle;\n } else if (isLView(lNodeToHandle)) {\n isComponent = true;\n ngDevMode && assertDefined(lNodeToHandle[HOST], 'HOST must be defined for a component LView');\n lNodeToHandle = lNodeToHandle[HOST]!;\n }\n const rNode: RNode = unwrapRNode(lNodeToHandle);\n\n if (action === WalkTNodeTreeAction.Create && parent !== null) {\n if (beforeNode == null) {\n nativeAppendChild(renderer, parent, rNode);\n } else {\n nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);\n }\n } else if (action === WalkTNodeTreeAction.Insert && parent !== null) {\n nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);\n } else if (action === WalkTNodeTreeAction.Detach) {\n nativeRemoveNode(renderer, rNode, isComponent);\n } else if (action === WalkTNodeTreeAction.Destroy) {\n ngDevMode && ngDevMode.rendererDestroyNode++;\n renderer.destroyNode!(rNode);\n }\n if (lContainer != null) {\n applyContainer(renderer, action, lContainer, parent, beforeNode);\n }\n }\n}\n\nexport function createTextNode(renderer: Renderer, value: string): RText {\n ngDevMode && ngDevMode.rendererCreateTextNode++;\n ngDevMode && ngDevMode.rendererSetText++;\n return renderer.createText(value);\n}\n\nexport function updateTextNode(renderer: Renderer, rNode: RText, value: string): void {\n ngDevMode && ngDevMode.rendererSetText++;\n renderer.setValue(rNode, value);\n}\n\nexport function createCommentNode(renderer: Renderer, value: string): RComment {\n ngDevMode && ngDevMode.rendererCreateComment++;\n return renderer.createComment(escapeCommentText(value));\n}\n\n/**\n * Creates a native element from a tag name, using a renderer.\n * @param renderer A renderer to use\n * @param name the tag name\n * @param namespace Optional namespace for element.\n * @returns the element created\n */\nexport function createElementNode(\n renderer: Renderer, name: string, namespace: string|null): RElement {\n ngDevMode && ngDevMode.rendererCreateElement++;\n return renderer.createElement(name, namespace);\n}\n\n\n/**\n * Removes all DOM elements associated with a view.\n *\n * Because some root nodes of the view may be containers, we sometimes need\n * to propagate deeply into the nested containers to remove all elements in the\n * views beneath it.\n *\n * @param tView The `TView' of the `LView` from which elements should be added or removed\n * @param lView The view from which elements should be added or removed\n */\nexport function removeViewFromDOM(tView: TView, lView: LView): void {\n const renderer = lView[RENDERER];\n applyView(tView, lView, renderer, WalkTNodeTreeAction.Detach, null, null);\n lView[HOST] = null;\n lView[T_HOST] = null;\n}\n\n/**\n * Adds all DOM elements associated with a view.\n *\n * Because some root nodes of the view may be containers, we sometimes need\n * to propagate deeply into the nested containers to add all elements in the\n * views beneath it.\n *\n * @param tView The `TView' of the `LView` from which elements should be added or removed\n * @param parentTNode The `TNode` where the `LView` should be attached to.\n * @param renderer Current renderer to use for DOM manipulations.\n * @param lView The view from which elements should be added or removed\n * @param parentNativeNode The parent `RElement` where it should be inserted into.\n * @param beforeNode The node before which elements should be added, if insert mode\n */\nexport function addViewToDOM(\n tView: TView, parentTNode: TNode, renderer: Renderer, lView: LView, parentNativeNode: RElement,\n beforeNode: RNode|null): void {\n lView[HOST] = parentNativeNode;\n lView[T_HOST] = parentTNode;\n applyView(tView, lView, renderer, WalkTNodeTreeAction.Insert, parentNativeNode, beforeNode);\n}\n\n\n/**\n * Detach a `LView` from the DOM by detaching its nodes.\n *\n * @param tView The `TView' of the `LView` to be detached\n * @param lView the `LView` to be detached.\n */\nexport function detachViewFromDOM(tView: TView, lView: LView) {\n applyView(tView, lView, lView[RENDERER], WalkTNodeTreeAction.Detach, null, null);\n}\n\n/**\n * Traverses down and up the tree of views and containers to remove listeners and\n * call onDestroy callbacks.\n *\n * Notes:\n * - Because it's used for onDestroy calls, it needs to be bottom-up.\n * - Must process containers instead of their views to avoid splicing\n * when views are destroyed and re-added.\n * - Using a while loop because it's faster than recursion\n * - Destroy only called on movement to sibling or movement to parent (laterally or up)\n *\n * @param rootView The view to destroy\n */\nexport function destroyViewTree(rootView: LView): void {\n // If the view has no children, we can clean it up and return early.\n let lViewOrLContainer = rootView[CHILD_HEAD];\n if (!lViewOrLContainer) {\n return cleanUpView(rootView[TVIEW], rootView);\n }\n\n while (lViewOrLContainer) {\n let next: LView|LContainer|null = null;\n\n if (isLView(lViewOrLContainer)) {\n // If LView, traverse down to child.\n next = lViewOrLContainer[CHILD_HEAD];\n } else {\n ngDevMode && assertLContainer(lViewOrLContainer);\n // If container, traverse down to its first LView.\n const firstView: LView|undefined = lViewOrLContainer[CONTAINER_HEADER_OFFSET];\n if (firstView) next = firstView;\n }\n\n if (!next) {\n // Only clean up view when moving to the side or up, as destroy hooks\n // should be called in order from the bottom up.\n while (lViewOrLContainer && !lViewOrLContainer![NEXT] && lViewOrLContainer !== rootView) {\n if (isLView(lViewOrLContainer)) {\n cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer);\n }\n lViewOrLContainer = lViewOrLContainer[PARENT];\n }\n if (lViewOrLContainer === null) lViewOrLContainer = rootView;\n if (isLView(lViewOrLContainer)) {\n cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer);\n }\n next = lViewOrLContainer && lViewOrLContainer![NEXT];\n }\n lViewOrLContainer = next;\n }\n}\n\n/**\n * Inserts a view into a container.\n *\n * This adds the view to the container's array of active views in the correct\n * position. It also adds the view's elements to the DOM if the container isn't a\n * root node of another view (in that case, the view's elements will be added when\n * the container's parent view is added later).\n *\n * @param tView The `TView' of the `LView` to insert\n * @param lView The view to insert\n * @param lContainer The container into which the view should be inserted\n * @param index Which index in the container to insert the child view into\n */\nexport function insertView(tView: TView, lView: LView, lContainer: LContainer, index: number) {\n ngDevMode && assertLView(lView);\n ngDevMode && assertLContainer(lContainer);\n const indexInContainer = CONTAINER_HEADER_OFFSET + index;\n const containerLength = lContainer.length;\n\n if (index > 0) {\n // This is a new view, we need to add it to the children.\n lContainer[indexInContainer - 1][NEXT] = lView;\n }\n if (index < containerLength - CONTAINER_HEADER_OFFSET) {\n lView[NEXT] = lContainer[indexInContainer];\n addToArray(lContainer, CONTAINER_HEADER_OFFSET + index, lView);\n } else {\n lContainer.push(lView);\n lView[NEXT] = null;\n }\n\n lView[PARENT] = lContainer;\n\n // track views where declaration and insertion points are different\n const declarationLContainer = lView[DECLARATION_LCONTAINER];\n if (declarationLContainer !== null && lContainer !== declarationLContainer) {\n trackMovedView(declarationLContainer, lView);\n }\n\n // notify query that a new view has been added\n const lQueries = lView[QUERIES];\n if (lQueries !== null) {\n lQueries.insertView(tView);\n }\n\n // Sets the attached flag\n lView[FLAGS] |= LViewFlags.Attached;\n}\n\n/**\n * Track views created from the declaration container (TemplateRef) and inserted into a\n * different LContainer.\n */\nfunction trackMovedView(declarationContainer: LContainer, lView: LView) {\n ngDevMode && assertDefined(lView, 'LView required');\n ngDevMode && assertLContainer(declarationContainer);\n const movedViews = declarationContainer[MOVED_VIEWS];\n const insertedLContainer = lView[PARENT] as LContainer;\n ngDevMode && assertLContainer(insertedLContainer);\n const insertedComponentLView = insertedLContainer[PARENT]![DECLARATION_COMPONENT_VIEW];\n ngDevMode && assertDefined(insertedComponentLView, 'Missing insertedComponentLView');\n const declaredComponentLView = lView[DECLARATION_COMPONENT_VIEW];\n ngDevMode && assertDefined(declaredComponentLView, 'Missing declaredComponentLView');\n if (declaredComponentLView !== insertedComponentLView) {\n // At this point the declaration-component is not same as insertion-component; this means that\n // this is a transplanted view. Mark the declared lView as having transplanted views so that\n // those views can participate in CD.\n declarationContainer[HAS_TRANSPLANTED_VIEWS] = true;\n }\n if (movedViews === null) {\n declarationContainer[MOVED_VIEWS] = [lView];\n } else {\n movedViews.push(lView);\n }\n}\n\nfunction detachMovedView(declarationContainer: LContainer, lView: LView) {\n ngDevMode && assertLContainer(declarationContainer);\n ngDevMode &&\n assertDefined(\n declarationContainer[MOVED_VIEWS],\n 'A projected view should belong to a non-empty projected views collection');\n const movedViews = declarationContainer[MOVED_VIEWS]!;\n const declarationViewIndex = movedViews.indexOf(lView);\n const insertionLContainer = lView[PARENT] as LContainer;\n ngDevMode && assertLContainer(insertionLContainer);\n\n // If the view was marked for refresh but then detached before it was checked (where the flag\n // would be cleared and the counter decremented), we need to update the status here.\n clearViewRefreshFlag(lView);\n\n movedViews.splice(declarationViewIndex, 1);\n}\n\n/**\n * Detaches a view from a container.\n *\n * This method removes the view from the container's array of active views. It also\n * removes the view's elements from the DOM.\n *\n * @param lContainer The container from which to detach a view\n * @param removeIndex The index of the view to detach\n * @returns Detached LView instance.\n */\nexport function detachView(lContainer: LContainer, removeIndex: number): LView|undefined {\n if (lContainer.length <= CONTAINER_HEADER_OFFSET) return;\n\n const indexInContainer = CONTAINER_HEADER_OFFSET + removeIndex;\n const viewToDetach = lContainer[indexInContainer];\n\n if (viewToDetach) {\n const declarationLContainer = viewToDetach[DECLARATION_LCONTAINER];\n if (declarationLContainer !== null && declarationLContainer !== lContainer) {\n detachMovedView(declarationLContainer, viewToDetach);\n }\n\n\n if (removeIndex > 0) {\n lContainer[indexInContainer - 1][NEXT] = viewToDetach[NEXT] as LView;\n }\n const removedLView = removeFromArray(lContainer, CONTAINER_HEADER_OFFSET + removeIndex);\n removeViewFromDOM(viewToDetach[TVIEW], viewToDetach);\n\n // notify query that a view has been removed\n const lQueries = removedLView[QUERIES];\n if (lQueries !== null) {\n lQueries.detachView(removedLView[TVIEW]);\n }\n\n viewToDetach[PARENT] = null;\n viewToDetach[NEXT] = null;\n // Unsets the attached flag\n viewToDetach[FLAGS] &= ~LViewFlags.Attached;\n }\n return viewToDetach;\n}\n\n/**\n * A standalone function which destroys an LView,\n * conducting clean up (e.g. removing listeners, calling onDestroys).\n *\n * @param tView The `TView' of the `LView` to be destroyed\n * @param lView The view to be destroyed.\n */\nexport function destroyLView(tView: TView, lView: LView) {\n if (!(lView[FLAGS] & LViewFlags.Destroyed)) {\n const renderer = lView[RENDERER];\n\n lView[REACTIVE_TEMPLATE_CONSUMER] && consumerDestroy(lView[REACTIVE_TEMPLATE_CONSUMER]);\n lView[REACTIVE_HOST_BINDING_CONSUMER] && consumerDestroy(lView[REACTIVE_HOST_BINDING_CONSUMER]);\n\n if (renderer.destroyNode) {\n applyView(tView, lView, renderer, WalkTNodeTreeAction.Destroy, null, null);\n }\n\n destroyViewTree(lView);\n }\n}\n\n/**\n * Calls onDestroys hooks for all directives and pipes in a given view and then removes all\n * listeners. Listeners are removed as the last step so events delivered in the onDestroys hooks\n * can be propagated to @Output listeners.\n *\n * @param tView `TView` for the `LView` to clean up.\n * @param lView The LView to clean up\n */\nfunction cleanUpView(tView: TView, lView: LView): void {\n if (!(lView[FLAGS] & LViewFlags.Destroyed)) {\n // Usually the Attached flag is removed when the view is detached from its parent, however\n // if it's a root view, the flag won't be unset hence why we're also removing on destroy.\n lView[FLAGS] &= ~LViewFlags.Attached;\n\n // Mark the LView as destroyed *before* executing the onDestroy hooks. An onDestroy hook\n // runs arbitrary user code, which could include its own `viewRef.destroy()` (or similar). If\n // We don't flag the view as destroyed before the hooks, this could lead to an infinite loop.\n // This also aligns with the ViewEngine behavior. It also means that the onDestroy hook is\n // really more of an \"afterDestroy\" hook if you think about it.\n lView[FLAGS] |= LViewFlags.Destroyed;\n\n executeOnDestroys(tView, lView);\n processCleanups(tView, lView);\n // For component views only, the local renderer is destroyed at clean up time.\n if (lView[TVIEW].type === TViewType.Component) {\n ngDevMode && ngDevMode.rendererDestroy++;\n lView[RENDERER].destroy();\n }\n\n const declarationContainer = lView[DECLARATION_LCONTAINER];\n // we are dealing with an embedded view that is still inserted into a container\n if (declarationContainer !== null && isLContainer(lView[PARENT])) {\n // and this is a projected view\n if (declarationContainer !== lView[PARENT]) {\n detachMovedView(declarationContainer, lView);\n }\n\n // For embedded views still attached to a container: remove query result from this view.\n const lQueries = lView[QUERIES];\n if (lQueries !== null) {\n lQueries.detachView(tView);\n }\n }\n\n // Unregister the view once everything else has been cleaned up.\n unregisterLView(lView);\n }\n}\n\n/** Removes listeners and unsubscribes from output subscriptions */\nfunction processCleanups(tView: TView, lView: LView): void {\n const tCleanup = tView.cleanup;\n const lCleanup = lView[CLEANUP]!;\n if (tCleanup !== null) {\n for (let i = 0; i < tCleanup.length - 1; i += 2) {\n if (typeof tCleanup[i] === 'string') {\n // This is a native DOM listener. It will occupy 4 entries in the TCleanup array (hence i +=\n // 2 at the end of this block).\n const targetIdx = tCleanup[i + 3];\n ngDevMode && assertNumber(targetIdx, 'cleanup target must be a number');\n if (targetIdx >= 0) {\n // unregister\n lCleanup[targetIdx]();\n } else {\n // Subscription\n lCleanup[-targetIdx].unsubscribe();\n }\n i += 2;\n } else {\n // This is a cleanup function that is grouped with the index of its context\n const context = lCleanup[tCleanup[i + 1]];\n tCleanup[i].call(context);\n }\n }\n }\n if (lCleanup !== null) {\n lView[CLEANUP] = null;\n }\n const destroyHooks = lView[ON_DESTROY_HOOKS];\n if (destroyHooks !== null) {\n // Reset the ON_DESTROY_HOOKS array before iterating over it to prevent hooks that unregister\n // themselves from mutating the array during iteration.\n lView[ON_DESTROY_HOOKS] = null;\n for (let i = 0; i < destroyHooks.length; i++) {\n const destroyHooksFn = destroyHooks[i];\n ngDevMode && assertFunction(destroyHooksFn, 'Expecting destroy hook to be a function.');\n destroyHooksFn();\n }\n }\n}\n\n/** Calls onDestroy hooks for this view */\nfunction executeOnDestroys(tView: TView, lView: LView): void {\n let destroyHooks: DestroyHookData|null;\n\n if (tView != null && (destroyHooks = tView.destroyHooks) != null) {\n for (let i = 0; i < destroyHooks.length; i += 2) {\n const context = lView[destroyHooks[i] as number];\n\n // Only call the destroy hook if the context has been requested.\n if (!(context instanceof NodeInjectorFactory)) {\n const toCall = destroyHooks[i + 1] as HookFn | HookData;\n\n if (Array.isArray(toCall)) {\n for (let j = 0; j < toCall.length; j += 2) {\n const callContext = context[toCall[j] as number];\n const hook = toCall[j + 1] as HookFn;\n profiler(ProfilerEvent.LifecycleHookStart, callContext, hook);\n try {\n hook.call(callContext);\n } finally {\n profiler(ProfilerEvent.LifecycleHookEnd, callContext, hook);\n }\n }\n } else {\n profiler(ProfilerEvent.LifecycleHookStart, context, toCall);\n try {\n toCall.call(context);\n } finally {\n profiler(ProfilerEvent.LifecycleHookEnd, context, toCall);\n }\n }\n }\n }\n }\n}\n\n/**\n * Returns a native element if a node can be inserted into the given parent.\n *\n * There are two reasons why we may not be able to insert a element immediately.\n * - Projection: When creating a child content element of a component, we have to skip the\n * insertion because the content of a component will be projected.\n * `delayed due to projection`\n * - Parent container is disconnected: This can happen when we are inserting a view into\n * parent container, which itself is disconnected. For example the parent container is part\n * of a View which has not be inserted or is made for projection but has not been inserted\n * into destination.\n *\n * @param tView: Current `TView`.\n * @param tNode: `TNode` for which we wish to retrieve render parent.\n * @param lView: Current `LView`.\n */\nexport function getParentRElement(tView: TView, tNode: TNode, lView: LView): RElement|null {\n return getClosestRElement(tView, tNode.parent, lView);\n}\n\n/**\n * Get closest `RElement` or `null` if it can't be found.\n *\n * If `TNode` is `TNodeType.Element` => return `RElement` at `LView[tNode.index]` location.\n * If `TNode` is `TNodeType.ElementContainer|IcuContain` => return the parent (recursively).\n * If `TNode` is `null` then return host `RElement`:\n * - return `null` if projection\n * - return `null` if parent container is disconnected (we have no parent.)\n *\n * @param tView: Current `TView`.\n * @param tNode: `TNode` for which we wish to retrieve `RElement` (or `null` if host element is\n * needed).\n * @param lView: Current `LView`.\n * @returns `null` if the `RElement` can't be determined at this time (no parent / projection)\n */\nexport function getClosestRElement(tView: TView, tNode: TNode|null, lView: LView): RElement|null {\n let parentTNode: TNode|null = tNode;\n // Skip over element and ICU containers as those are represented by a comment node and\n // can't be used as a render parent.\n while (parentTNode !== null &&\n (parentTNode.type & (TNodeType.ElementContainer | TNodeType.Icu))) {\n tNode = parentTNode;\n parentTNode = tNode.parent;\n }\n\n // If the parent tNode is null, then we are inserting across views: either into an embedded view\n // or a component view.\n if (parentTNode === null) {\n // We are inserting a root element of the component view into the component host element and\n // it should always be eager.\n return lView[HOST];\n } else {\n ngDevMode && assertTNodeType(parentTNode, TNodeType.AnyRNode | TNodeType.Container);\n const {componentOffset} = parentTNode;\n if (componentOffset > -1) {\n ngDevMode && assertTNodeForLView(parentTNode, lView);\n const {encapsulation} =\n (tView.data[parentTNode.directiveStart + componentOffset] as ComponentDef);\n // We've got a parent which is an element in the current view. We just need to verify if the\n // parent element is not a component. Component's content nodes are not inserted immediately\n // because they will be projected, and so doing insert at this point would be wasteful.\n // Since the projection would then move it to its final destination. Note that we can't\n // make this assumption when using the Shadow DOM, because the native projection placeholders\n // ( or ) have to be in place as elements are being inserted.\n if (encapsulation === ViewEncapsulation.None ||\n encapsulation === ViewEncapsulation.Emulated) {\n return null;\n }\n }\n\n return getNativeByTNode(parentTNode, lView) as RElement;\n }\n}\n\n/**\n * Inserts a native node before another native node for a given parent.\n * This is a utility function that can be used when native nodes were determined.\n */\nexport function nativeInsertBefore(\n renderer: Renderer, parent: RElement, child: RNode, beforeNode: RNode|null,\n isMove: boolean): void {\n ngDevMode && ngDevMode.rendererInsertBefore++;\n renderer.insertBefore(parent, child, beforeNode, isMove);\n}\n\nfunction nativeAppendChild(renderer: Renderer, parent: RElement, child: RNode): void {\n ngDevMode && ngDevMode.rendererAppendChild++;\n ngDevMode && assertDefined(parent, 'parent node must be defined');\n renderer.appendChild(parent, child);\n}\n\nfunction nativeAppendOrInsertBefore(\n renderer: Renderer, parent: RElement, child: RNode, beforeNode: RNode|null, isMove: boolean) {\n if (beforeNode !== null) {\n nativeInsertBefore(renderer, parent, child, beforeNode, isMove);\n } else {\n nativeAppendChild(renderer, parent, child);\n }\n}\n\n/** Removes a node from the DOM given its native parent. */\nfunction nativeRemoveChild(\n renderer: Renderer, parent: RElement, child: RNode, isHostElement?: boolean): void {\n renderer.removeChild(parent, child, isHostElement);\n}\n\n/** Checks if an element is a `