@angular/core 21.0.0-next.3 → 21.0.0-next.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/api.d.d.ts +1 -1
  2. package/chrome_dev_tools_performance.d.d.ts +1 -1
  3. package/discovery.d.d.ts +44 -18
  4. package/effect.d.d.ts +1 -1
  5. package/event_dispatcher.d.d.ts +1 -1
  6. package/fesm2022/attribute.mjs +1 -1
  7. package/fesm2022/attribute.mjs.map +1 -1
  8. package/fesm2022/core.mjs +221 -64
  9. package/fesm2022/core.mjs.map +1 -1
  10. package/fesm2022/debug_node.mjs +516 -690
  11. package/fesm2022/debug_node.mjs.map +1 -1
  12. package/fesm2022/effect.mjs +1 -1
  13. package/fesm2022/effect.mjs.map +1 -1
  14. package/fesm2022/not_found.mjs +1 -1
  15. package/fesm2022/not_found.mjs.map +1 -1
  16. package/fesm2022/primitives/di.mjs +1 -1
  17. package/fesm2022/primitives/di.mjs.map +1 -1
  18. package/fesm2022/primitives/event-dispatch.mjs +1 -1
  19. package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
  20. package/fesm2022/primitives/signals.mjs +2 -2
  21. package/fesm2022/primitives/signals.mjs.map +1 -1
  22. package/fesm2022/resource.mjs +1 -1
  23. package/fesm2022/resource.mjs.map +1 -1
  24. package/fesm2022/root_effect_scheduler.mjs +55 -39
  25. package/fesm2022/root_effect_scheduler.mjs.map +1 -1
  26. package/fesm2022/rxjs-interop.mjs +3 -1
  27. package/fesm2022/rxjs-interop.mjs.map +1 -1
  28. package/fesm2022/signal.mjs +32 -11
  29. package/fesm2022/signal.mjs.map +1 -1
  30. package/fesm2022/testing.mjs +4 -4
  31. package/fesm2022/testing.mjs.map +1 -1
  32. package/fesm2022/weak_ref.mjs +1 -1
  33. package/fesm2022/weak_ref.mjs.map +1 -1
  34. package/graph.d.d.ts +24 -4
  35. package/index.d.ts +11 -129
  36. package/package.json +2 -2
  37. package/primitives/di/index.d.ts +1 -1
  38. package/primitives/event-dispatch/index.d.ts +1 -1
  39. package/primitives/signals/index.d.ts +2 -2
  40. package/rxjs-interop/index.d.ts +3 -1
  41. package/schematics/bundles/add-bootstrap-context-to-server-main.cjs +5 -5
  42. package/schematics/bundles/application-config-core.cjs +6 -6
  43. package/schematics/bundles/{apply_import_manager-tNexl58m.cjs → apply_import_manager-DroqamMP.cjs} +3 -3
  44. package/schematics/bundles/bootstrap-options-migration.cjs +715 -0
  45. package/schematics/bundles/cleanup-unused-imports.cjs +5 -5
  46. package/schematics/bundles/{compiler_host-Df7s6Riz.cjs → compiler_host-aKaS4KRz.cjs} +2 -2
  47. package/schematics/bundles/control-flow-migration.cjs +4 -4
  48. package/schematics/bundles/{imports-26VeX8i-.cjs → imports-DwPXlGFl.cjs} +27 -1
  49. package/schematics/bundles/{index-CBaykQBv.cjs → index-BI97t1U8.cjs} +107 -32
  50. package/schematics/bundles/{index-Clvp4COX.cjs → index-DaB-z4lP.cjs} +4 -4
  51. package/schematics/bundles/inject-migration.cjs +5 -5
  52. package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
  53. package/schematics/bundles/{migrate_ts_type_references-C_gTvDtH.cjs → migrate_ts_type_references-DPuwhGod.cjs} +5 -5
  54. package/schematics/bundles/{ng_component_template-HYGPuVhy.cjs → ng_component_template-CytqBs-q.cjs} +3 -3
  55. package/schematics/bundles/{ng_decorators-CtYwz9Lw.cjs → ng_decorators-BI0uV7KI.cjs} +2 -2
  56. package/schematics/bundles/ngclass-to-class-migration.cjs +9 -9
  57. package/schematics/bundles/ngstyle-to-style-migration.cjs +490 -0
  58. package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
  59. package/schematics/bundles/output-migration.cjs +6 -6
  60. package/schematics/bundles/parse_html-CeQjkdOK.cjs +132 -0
  61. package/schematics/bundles/{project_paths-BJTqcWvC.cjs → project_paths-Cz4x-QiT.cjs} +3 -3
  62. package/schematics/bundles/{project_tsconfig_paths-bRwOJEk9.cjs → project_tsconfig_paths-Clg7WX1w.cjs} +168 -198
  63. package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
  64. package/schematics/bundles/route-lazy-loading.cjs +48 -4
  65. package/schematics/bundles/router-current-navigation.cjs +6 -6
  66. package/schematics/bundles/router-last-successful-navigation.cjs +6 -6
  67. package/schematics/bundles/self-closing-tags-migration.cjs +8 -8
  68. package/schematics/bundles/signal-input-migration.cjs +17 -9
  69. package/schematics/bundles/signal-queries-migration.cjs +7 -7
  70. package/schematics/bundles/signals.cjs +7 -7
  71. package/schematics/bundles/standalone-migration.cjs +7 -7
  72. package/schematics/bundles/{symbol-VPWguRxr.cjs → symbol-BObKoqes.cjs} +3 -2
  73. package/schematics/collection.json +6 -0
  74. package/schematics/migrations/ngstyle-to-style-migration/schema.json +20 -0
  75. package/schematics/migrations.json +5 -0
  76. package/testing/index.d.ts +1 -1
  77. package/weak_ref.d.d.ts +1 -1
  78. package/schematics/bundles/parse_html-CLFKoiOK.cjs +0 -41
@@ -1,10 +1,10 @@
1
1
  /**
2
- * @license Angular v21.0.0-next.3
2
+ * @license Angular v21.0.0-next.4
3
3
  * (c) 2010-2025 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
6
6
 
7
- import { attachInjectFlag, _global, ɵɵdefineInjectable as __defineInjectable, ɵɵdefineInjector as __defineInjector, ɵɵinject as __inject, ɵɵinvalidFactoryDep as __invalidFactoryDep, resolveForwardRef, newArray, EMPTY_OBJ, assertString, assertNotEqual, FLAGS, assertEqual, isInCheckNoChangesMode, PREORDER_HOOK_FLAGS, assertFirstCreatePass, assertDefined, throwError, assertNumber, assertGreaterThan, HEADER_OFFSET, DECLARATION_VIEW, NG_FACTORY_DEF, isForwardRef, getFactoryDef, assertIndexInRange, assertTNodeForLView, enterDI, runInInjectorProfilerContext, getCurrentTNode, getLView, emitInjectorToCreateInstanceEvent, emitInstanceCreatedByInjectorEvent, throwProviderNotFoundError, leaveDI, assertNodeInjector, stringifyForError, cyclicDependencyErrorWithDetails, cyclicDependencyError, setInjectorProfilerContext, setInjectImplementation, assertDirectiveDef, NG_ELEMENT_ID, convertToBitFlags, isRootView, T_HOST, TVIEW, injectRootLimpMode, isComponentDef, EMBEDDED_VIEW_INJECTOR, INJECTOR$1 as INJECTOR, DECLARATION_COMPONENT_VIEW, isComponentHost, RuntimeError, NG_PROV_DEF, getClosureSafeProperty, getNativeByTNode, flatten, arrayEquals, ID, isLView, assertDomNode, unwrapRNode, getComponentLViewByIndex, CONTEXT, EMPTY_ARRAY, assertLView, HOST, CHILD_HEAD, NEXT, isLContainer, getLViewParent, Injector, CLEANUP, getComponentDef, getDirectiveDef, InjectionToken, inject, isInSkipHydrationBlock as isInSkipHydrationBlock$1, HYDRATION, isContentQueryHost, setCurrentQueryIndex, XSS_SECURITY_URL, renderStringify, ENVIRONMENT, makeEnvironmentProviders, isDirectiveHost, formatRuntimeError, resetPreOrderHookFlags, PARENT, RENDERER, CHILD_TAIL, assertSame, assertFirstUpdatePass, getSelectedIndex, getTView, assertIndexInDeclRange, setSelectedIndex, assertLContainer, MOVED_VIEWS, isDestroyed, REACTIVE_TEMPLATE_CONSUMER, DECLARATION_LCONTAINER, QUERIES, assertNotReactive, ON_DESTROY_HOOKS, assertFunction, EFFECTS, assertProjectionSlots, NATIVE, assertParentView, CONTAINER_HEADER_OFFSET, assertNotSame, setCurrentDirectiveIndex, setCurrentTNode, getElementDepthCount, increaseElementDepthCount, wasLastNodeCreated, isCurrentTNodeParent, setCurrentTNodeAsNotParent, assertHasParent, INTERNAL_APPLICATION_ERROR_HANDLER, stringify, getCurrentDirectiveIndex, unwrapLView, isCreationMode, enterView, leaveView, AFTER_RENDER_SEQUENCES_TO_ADD, markAncestorsForTraversal, markViewForRefresh, setIsRefreshingViews, isExhaustiveCheckNoChanges, requiresRefreshOrTraversal, setIsInCheckNoChangesMode, CheckNoChangesMode, setBindingIndex, EFFECTS_TO_SCHEDULE, viewAttachedToChangeDetector, setBindingRootForHostBindings, isRefreshingViews, removeFromArray, addToArray, updateAncestorTraversalFlagsOnAttach, storeLViewOnDestroy, VIEW_REFS, assertGreaterThanOrEqual, isInI18nBlock, assertTNodeForTView, getCurrentParentTNode, getCurrentTNodePlaceholderOk, assertTNode, assertTIcu, assertNumberInRange, DEHYDRATED_VIEWS, getNgModuleDef, getPipeDef as getPipeDef$1, getNgModuleDefOrThrow, isStandalone, concatStringsWithSpace, assertInjectImplementationNotEqual, emitInjectEvent, getConstant, assertLessThan, getOrCreateTViewCleanup, getOrCreateLViewCleanup, assertNotDefined, nextBindingIndex, getSelectedTNode, getDirectiveDefOrThrow, getTNode, assertComponentType, debugStringifyTypeForError, ChangeDetectionScheduler, EnvironmentInjector, SVG_NAMESPACE, MATH_ML_NAMESPACE, viewAttachedToContainer, storeCleanupWithContext, signal, createInjectorWithoutInjectorInstances, R3Injector, getNullInjector, internalImportProvidersFrom, initNgDevMode, fillProperties, getBindingsEnabled, lastNodeWasCreated, NgZone, ErrorHandler, assertNotInReactiveContext, assertInInjectionContext, DestroyRef, ViewContext, removeLViewOnDestroy, walkUpViews, getNativeByIndex, assertElement, arrayInsert2, arraySplice, setInjectorProfiler, NullInjector, ENVIRONMENT_INITIALIZER, INJECTOR_DEF_TYPES, walkProviderTree, getInjectorDef, deepForEach, isTypeProvider, isSignal, isInInjectionContext, runInInjectionContext, ZONELESS_ENABLED, EffectScheduler, PendingTasksInternal, PendingTasks, getAnimationElementRemovalRegistry, assertTNodeCreationIndex, isSkipHydrationRootTNode, leaveSkipHydrationBlock, decreaseElementDepthCount, getNamespace, enterSkipHydrationBlock, getCurrentDirectiveDef, assertIndexInExpandoRange, getBindingIndex, assertOneOf, setInI18nBlock, nextContextImpl, getCurrentQueryIndex, getContextLView, load, keyValueArrayIndexOf, keyValueArraySet, keyValueArrayGet, incrementBindingIndex, isWritableSignal, store, providerToFactory, emitProviderConfiguredEvent, isClassProvider, setAnimationElementRemovalRegistry, getBindingRoot, NG_COMP_DEF, ɵɵresetView as __resetView, ɵɵnamespaceHTML as __namespaceHTML, ɵɵnamespaceMathML as __namespaceMathML, ɵɵnamespaceSVG as __namespaceSVG, ɵɵenableBindings as __enableBindings, ɵɵdisableBindings as __disableBindings, ɵɵrestoreView as __restoreView, forwardRef, NG_MOD_DEF, NG_INJ_DEF, NG_DIR_DEF, NG_PIPE_DEF, SCHEDULE_IN_ROOT_ZONE, SCHEDULE_IN_ROOT_ZONE_DEFAULT, ZONELESS_SCHEDULER_DISABLED, angularZoneInstanceIdProperty, NoopNgZone, scheduleCallbackWithMicrotask, PROVIDED_ZONELESS, scheduleCallbackWithRafRace, getNativeByTNodeOrNull } from './root_effect_scheduler.mjs';
7
+ import { attachInjectFlag, _global, ɵɵdefineInjectable as __defineInjectable, ɵɵdefineInjector as __defineInjector, ɵɵinject as __inject, ɵɵinvalidFactoryDep as __invalidFactoryDep, resolveForwardRef, newArray, EMPTY_OBJ, assertString, assertNotEqual, FLAGS, assertEqual, isInCheckNoChangesMode, PREORDER_HOOK_FLAGS, assertFirstCreatePass, assertDefined, throwError, assertNumber, assertGreaterThan, HEADER_OFFSET, DECLARATION_VIEW, NG_FACTORY_DEF, isForwardRef, getFactoryDef, assertIndexInRange, assertTNodeForLView, enterDI, runInInjectorProfilerContext, getCurrentTNode, getLView, emitInjectorToCreateInstanceEvent, emitInstanceCreatedByInjectorEvent, throwProviderNotFoundError, leaveDI, assertNodeInjector, stringifyForError, cyclicDependencyErrorWithDetails, cyclicDependencyError, setInjectorProfilerContext, setInjectImplementation, assertDirectiveDef, NG_ELEMENT_ID, convertToBitFlags, isRootView, T_HOST, TVIEW, injectRootLimpMode, isComponentDef, EMBEDDED_VIEW_INJECTOR, INJECTOR$1 as INJECTOR, DECLARATION_COMPONENT_VIEW, isComponentHost, RuntimeError, NG_PROV_DEF, getClosureSafeProperty, getNativeByTNode, flatten, arrayEquals, ID, isLView, assertDomNode, unwrapRNode, getComponentLViewByIndex, CONTEXT, EMPTY_ARRAY, assertLView, HOST, CHILD_HEAD, NEXT, isLContainer, getLViewParent, Injector, CLEANUP, getComponentDef, getDirectiveDef, InjectionToken, inject, isInSkipHydrationBlock as isInSkipHydrationBlock$1, HYDRATION, isContentQueryHost, setCurrentQueryIndex, XSS_SECURITY_URL, renderStringify, ENVIRONMENT, makeEnvironmentProviders, isDirectiveHost, formatRuntimeError, resetPreOrderHookFlags, PARENT, RENDERER, CHILD_TAIL, assertSame, assertFirstUpdatePass, getSelectedIndex, getTView, assertIndexInDeclRange, setSelectedIndex, assertLContainer, MOVED_VIEWS, isDestroyed, REACTIVE_TEMPLATE_CONSUMER, DECLARATION_LCONTAINER, QUERIES, assertNotReactive, ON_DESTROY_HOOKS, assertFunction, EFFECTS, assertProjectionSlots, NATIVE, ANIMATIONS, assertParentView, CONTAINER_HEADER_OFFSET, assertNotSame, setCurrentDirectiveIndex, setCurrentTNode, getElementDepthCount, increaseElementDepthCount, wasLastNodeCreated, isCurrentTNodeParent, setCurrentTNodeAsNotParent, assertHasParent, INTERNAL_APPLICATION_ERROR_HANDLER, stringify, getCurrentDirectiveIndex, unwrapLView, isCreationMode, enterView, leaveView, AFTER_RENDER_SEQUENCES_TO_ADD, markAncestorsForTraversal, markViewForRefresh, setIsRefreshingViews, isExhaustiveCheckNoChanges, requiresRefreshOrTraversal, setIsInCheckNoChangesMode, CheckNoChangesMode, setBindingIndex, EFFECTS_TO_SCHEDULE, viewAttachedToChangeDetector, setBindingRootForHostBindings, isRefreshingViews, removeFromArray, addToArray, updateAncestorTraversalFlagsOnAttach, storeLViewOnDestroy, VIEW_REFS, assertGreaterThanOrEqual, isInI18nBlock, assertTNodeForTView, getCurrentParentTNode, getCurrentTNodePlaceholderOk, assertTNode, assertTIcu, assertNumberInRange, DEHYDRATED_VIEWS, getNgModuleDef, getPipeDef as getPipeDef$1, getNgModuleDefOrThrow, isStandalone, concatStringsWithSpace, assertInjectImplementationNotEqual, emitInjectEvent, getConstant, assertLessThan, getOrCreateTViewCleanup, getOrCreateLViewCleanup, assertNotDefined, nextBindingIndex, getSelectedTNode, getDirectiveDefOrThrow, getTNode, assertComponentType, debugStringifyTypeForError, ChangeDetectionScheduler, EnvironmentInjector, SVG_NAMESPACE, MATH_ML_NAMESPACE, viewAttachedToContainer, storeCleanupWithContext, signal, createInjectorWithoutInjectorInstances, R3Injector, getNullInjector, internalImportProvidersFrom, initNgDevMode, fillProperties, getBindingsEnabled, lastNodeWasCreated, NgZone, ErrorHandler, assertNotInReactiveContext, assertInInjectionContext, DestroyRef, ViewContext, removeLViewOnDestroy, walkUpViews, getNativeByIndex, assertElement, arrayInsert2, arraySplice, setInjectorProfiler, NullInjector, ENVIRONMENT_INITIALIZER, INJECTOR_DEF_TYPES, walkProviderTree, getInjectorDef, deepForEach, isTypeProvider, isSignal, isInInjectionContext, runInInjectionContext, ZONELESS_ENABLED, EffectScheduler, PendingTasksInternal, PendingTasks, assertTNodeCreationIndex, isSkipHydrationRootTNode, leaveSkipHydrationBlock, decreaseElementDepthCount, getNamespace, enterSkipHydrationBlock, getCurrentDirectiveDef, assertIndexInExpandoRange, getBindingIndex, assertOneOf, setInI18nBlock, nextContextImpl, getCurrentQueryIndex, getContextLView, load, keyValueArrayIndexOf, keyValueArraySet, keyValueArrayGet, incrementBindingIndex, isWritableSignal, store, providerToFactory, emitProviderConfiguredEvent, isClassProvider, getBindingRoot, NG_COMP_DEF, ɵɵresetView as __resetView, ɵɵnamespaceHTML as __namespaceHTML, ɵɵnamespaceMathML as __namespaceMathML, ɵɵnamespaceSVG as __namespaceSVG, ɵɵenableBindings as __enableBindings, ɵɵdisableBindings as __disableBindings, ɵɵrestoreView as __restoreView, forwardRef, NG_MOD_DEF, NG_INJ_DEF, NG_DIR_DEF, NG_PIPE_DEF, angularZoneInstanceIdProperty, SCHEDULE_IN_ROOT_ZONE, scheduleCallbackWithMicrotask, PROVIDED_ZONELESS, NoopNgZone, scheduleCallbackWithRafRace, getNativeByTNodeOrNull } from './root_effect_scheduler.mjs';
8
8
  import { setActiveConsumer, SIGNAL, consumerDestroy, REACTIVE_NODE, consumerPollProducersForChange, consumerBeforeComputation, getActiveConsumer, consumerAfterComputation, createComputed, setThrowInvalidWriteToSignalError } from './signal.mjs';
9
9
  import { Subject, Subscription } from 'rxjs';
10
10
  import { setActiveConsumer as setActiveConsumer$1 } from '@angular/core/primitives/signals';
@@ -7208,11 +7208,123 @@ function ensureIcuContainerVisitorLoaded(loader) {
7208
7208
  }
7209
7209
  }
7210
7210
 
7211
+ /** Parses a CSS time value to milliseconds. */
7212
+ function parseCssTimeUnitsToMs(value) {
7213
+ // Some browsers will return it in seconds, whereas others will return milliseconds.
7214
+ const multiplier = value.toLowerCase().indexOf('ms') > -1 ? 1 : 1000;
7215
+ return parseFloat(value) * multiplier;
7216
+ }
7217
+ /** Parses out multiple values from a computed style into an array. */
7218
+ function parseCssPropertyValue(computedStyle, name) {
7219
+ const value = computedStyle.getPropertyValue(name);
7220
+ return value.split(',').map((part) => part.trim());
7221
+ }
7222
+ /** Gets the transform transition duration, including the delay, of an element in milliseconds. */
7223
+ function getLongestComputedTransition(computedStyle) {
7224
+ const transitionedProperties = parseCssPropertyValue(computedStyle, 'transition-property');
7225
+ const rawDurations = parseCssPropertyValue(computedStyle, 'transition-duration');
7226
+ const rawDelays = parseCssPropertyValue(computedStyle, 'transition-delay');
7227
+ const longest = { propertyName: '', duration: 0, animationName: undefined };
7228
+ for (let i = 0; i < transitionedProperties.length; i++) {
7229
+ const duration = parseCssTimeUnitsToMs(rawDelays[i]) + parseCssTimeUnitsToMs(rawDurations[i]);
7230
+ if (duration > longest.duration) {
7231
+ longest.propertyName = transitionedProperties[i];
7232
+ longest.duration = duration;
7233
+ }
7234
+ }
7235
+ return longest;
7236
+ }
7237
+ function getLongestComputedAnimation(computedStyle) {
7238
+ const rawNames = parseCssPropertyValue(computedStyle, 'animation-name');
7239
+ const rawDelays = parseCssPropertyValue(computedStyle, 'animation-delay');
7240
+ const rawDurations = parseCssPropertyValue(computedStyle, 'animation-duration');
7241
+ const longest = { animationName: '', propertyName: undefined, duration: 0 };
7242
+ for (let i = 0; i < rawNames.length; i++) {
7243
+ const duration = parseCssTimeUnitsToMs(rawDelays[i]) + parseCssTimeUnitsToMs(rawDurations[i]);
7244
+ if (duration > longest.duration) {
7245
+ longest.animationName = rawNames[i];
7246
+ longest.duration = duration;
7247
+ }
7248
+ }
7249
+ return longest;
7250
+ }
7251
+ function isShorterThanExistingAnimation(existing, longest) {
7252
+ return existing !== undefined && existing.duration > longest.duration;
7253
+ }
7254
+ function longestExists(longest) {
7255
+ return ((longest.animationName != undefined || longest.propertyName != undefined) &&
7256
+ longest.duration > 0);
7257
+ }
7258
+ /**
7259
+ * Determines the longest animation, but with `getComputedStyles` instead of `getAnimations`. This
7260
+ * is ultimately safer than getAnimations because it can be used when recalculations are in
7261
+ * progress. `getAnimations()` will be empty in that case.
7262
+ */
7263
+ function determineLongestAnimationFromComputedStyles(el, animationsMap) {
7264
+ const computedStyle = getComputedStyle(el);
7265
+ const longestAnimation = getLongestComputedAnimation(computedStyle);
7266
+ const longestTransition = getLongestComputedTransition(computedStyle);
7267
+ const longest = longestAnimation.duration > longestTransition.duration ? longestAnimation : longestTransition;
7268
+ if (isShorterThanExistingAnimation(animationsMap.get(el), longest))
7269
+ return;
7270
+ if (longestExists(longest)) {
7271
+ animationsMap.set(el, longest);
7272
+ }
7273
+ }
7274
+ /**
7275
+ * Multiple animations can be set on an element. This grabs an element and
7276
+ * determines which of those will be the longest duration. If we didn't do
7277
+ * this, elements would be removed whenever the first animation completes.
7278
+ * This ensures we get the longest running animation and only remove when
7279
+ * that animation completes.
7280
+ */
7281
+ function determineLongestAnimation(el, animationsMap, areAnimationSupported) {
7282
+ if (!areAnimationSupported)
7283
+ return;
7284
+ const animations = el.getAnimations();
7285
+ return animations.length === 0
7286
+ ? // fallback to computed styles if getAnimations is empty. This would happen if styles are
7287
+ // currently recalculating due to a reflow happening elsewhere.
7288
+ determineLongestAnimationFromComputedStyles(el, animationsMap)
7289
+ : determineLongestAnimationFromElementAnimations(el, animationsMap, animations);
7290
+ }
7291
+ function determineLongestAnimationFromElementAnimations(el, animationsMap, animations) {
7292
+ let longest = {
7293
+ animationName: undefined,
7294
+ propertyName: undefined,
7295
+ duration: 0,
7296
+ };
7297
+ for (const animation of animations) {
7298
+ const timing = animation.effect?.getTiming();
7299
+ // duration can be a string 'auto' or a number.
7300
+ const animDuration = typeof timing?.duration === 'number' ? timing.duration : 0;
7301
+ let duration = (timing?.delay ?? 0) + animDuration;
7302
+ let propertyName;
7303
+ let animationName;
7304
+ if (animation.animationName) {
7305
+ animationName = animation.animationName;
7306
+ }
7307
+ else {
7308
+ // Check for CSSTransition specific property
7309
+ propertyName = animation.transitionProperty;
7310
+ }
7311
+ if (duration >= longest.duration) {
7312
+ longest = { animationName, propertyName, duration };
7313
+ }
7314
+ }
7315
+ if (isShorterThanExistingAnimation(animationsMap.get(el), longest))
7316
+ return;
7317
+ if (longestExists(longest)) {
7318
+ animationsMap.set(el, longest);
7319
+ }
7320
+ }
7321
+ const allLeavingAnimations = new Set();
7322
+
7211
7323
  /**
7212
7324
  * NOTE: for performance reasons, the possible actions are inlined within the function instead of
7213
7325
  * being passed as an argument.
7214
7326
  */
7215
- function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, beforeNode) {
7327
+ function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, beforeNode, parentLView) {
7216
7328
  // If this slot was allocated for a text node dynamically created by i18n, the text node itself
7217
7329
  // won't be created until i18nApply() in the update block, so this node should be skipped.
7218
7330
  // For more info, see "ICU expressions should work inside an ngTemplateOutlet inside an ngFor"
@@ -7244,10 +7356,14 @@ function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, befo
7244
7356
  nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
7245
7357
  }
7246
7358
  else if (action === 2 /* WalkTNodeTreeAction.Detach */) {
7247
- nativeRemoveNode(renderer, rNode, isComponent);
7359
+ runLeaveAnimationsWithCallback(parentLView, () => {
7360
+ nativeRemoveNode(renderer, rNode, isComponent);
7361
+ });
7248
7362
  }
7249
7363
  else if (action === 3 /* WalkTNodeTreeAction.Destroy */) {
7250
- renderer.destroyNode(rNode);
7364
+ runLeaveAnimationsWithCallback(parentLView, () => {
7365
+ renderer.destroyNode(rNode);
7366
+ });
7251
7367
  }
7252
7368
  if (lContainer != null) {
7253
7369
  applyContainer(renderer, action, lContainer, parent, beforeNode);
@@ -7427,6 +7543,37 @@ function cleanUpView(tView, lView) {
7427
7543
  setActiveConsumer(prevConsumer);
7428
7544
  }
7429
7545
  }
7546
+ function runLeaveAnimationsWithCallback(lView, callback) {
7547
+ if (lView && lView[ANIMATIONS] && lView[ANIMATIONS].leave) {
7548
+ if (lView[ANIMATIONS].skipLeaveAnimations) {
7549
+ lView[ANIMATIONS].skipLeaveAnimations = false;
7550
+ }
7551
+ else {
7552
+ const leaveAnimations = lView[ANIMATIONS].leave;
7553
+ const runningAnimations = [];
7554
+ for (let index = 0; index < leaveAnimations.length; index++) {
7555
+ const animateFn = leaveAnimations[index];
7556
+ runningAnimations.push(animateFn());
7557
+ }
7558
+ lView[ANIMATIONS].running = Promise.allSettled(runningAnimations);
7559
+ lView[ANIMATIONS].leave = undefined;
7560
+ }
7561
+ }
7562
+ runAfterLeaveAnimations(lView, callback);
7563
+ }
7564
+ function runAfterLeaveAnimations(lView, callback) {
7565
+ if (lView && lView[ANIMATIONS] && lView[ANIMATIONS].running) {
7566
+ lView[ANIMATIONS].running.then(() => {
7567
+ if (lView[ANIMATIONS] && lView[ANIMATIONS].running) {
7568
+ lView[ANIMATIONS].running = undefined;
7569
+ }
7570
+ allLeavingAnimations.delete(lView);
7571
+ callback();
7572
+ });
7573
+ return;
7574
+ }
7575
+ callback();
7576
+ }
7430
7577
  /** Removes listeners and unsubscribes from output subscriptions */
7431
7578
  function processCleanups(tView, lView) {
7432
7579
  ngDevMode && assertNotReactive(processCleanups.name);
@@ -7764,22 +7911,22 @@ function applyNodes(renderer, action, tNode, lView, parentRElement, beforeNode,
7764
7911
  if (!isDetachedByI18n(tNode)) {
7765
7912
  if (tNodeType & 8 /* TNodeType.ElementContainer */) {
7766
7913
  applyNodes(renderer, action, tNode.child, lView, parentRElement, beforeNode, false);
7767
- applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
7914
+ applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode, lView);
7768
7915
  }
7769
7916
  else if (tNodeType & 32 /* TNodeType.Icu */) {
7770
7917
  const nextRNode = icuContainerIterate(tNode, lView);
7771
7918
  let rNode;
7772
7919
  while ((rNode = nextRNode())) {
7773
- applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode);
7920
+ applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode, lView);
7774
7921
  }
7775
- applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
7922
+ applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode, lView);
7776
7923
  }
7777
7924
  else if (tNodeType & 16 /* TNodeType.Projection */) {
7778
7925
  applyProjectionRecursive(renderer, action, lView, tNode, parentRElement, beforeNode);
7779
7926
  }
7780
7927
  else {
7781
7928
  ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */);
7782
- applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
7929
+ applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode, lView);
7783
7930
  }
7784
7931
  }
7785
7932
  tNode = isProjection ? tNode.projectionNext : tNode.next;
@@ -7833,7 +7980,7 @@ function applyProjectionRecursive(renderer, action, lView, tProjectionNode, pare
7833
7980
  // This should be refactored and cleaned up.
7834
7981
  for (let i = 0; i < nodeToProjectOrRNodes.length; i++) {
7835
7982
  const rNode = nodeToProjectOrRNodes[i];
7836
- applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode);
7983
+ applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode, lView);
7837
7984
  }
7838
7985
  }
7839
7986
  else {
@@ -8975,6 +9122,7 @@ function refreshView(tView, lView, templateFn, context) {
8975
9122
  if (templateFn !== null) {
8976
9123
  executeTemplate(tView, lView, templateFn, 2 /* RenderFlags.Update */, context);
8977
9124
  }
9125
+ runEnterAnimations(lView);
8978
9126
  const hooksInitPhaseCompleted = (flags & 3 /* LViewFlags.InitPhaseStateMask */) === 3 /* InitPhaseState.InitPhaseCompleted */;
8979
9127
  // execute pre-order hooks (OnInit, OnChanges, DoCheck)
8980
9128
  // PERF WARNING: do NOT extract this to a separate function without running benchmarks
@@ -9102,6 +9250,15 @@ function refreshView(tView, lView, templateFn, context) {
9102
9250
  leaveView();
9103
9251
  }
9104
9252
  }
9253
+ function runEnterAnimations(lView) {
9254
+ const animationData = lView[ANIMATIONS];
9255
+ if (animationData?.enter) {
9256
+ for (const animateFn of animationData.enter) {
9257
+ animateFn();
9258
+ }
9259
+ animationData.enter = undefined;
9260
+ }
9261
+ }
9105
9262
  /**
9106
9263
  * Goes over embedded views (ones created through ViewContainerRef APIs) and refreshes
9107
9264
  * them by executing an associated template function.
@@ -9741,15 +9898,20 @@ class ViewRef {
9741
9898
  * introduce other changes.
9742
9899
  */
9743
9900
  checkNoChanges() {
9744
- if (!ngDevMode)
9745
- return;
9746
- try {
9747
- this.exhaustive ??= this._lView[INJECTOR].get(UseExhaustiveCheckNoChanges, USE_EXHAUSTIVE_CHECK_NO_CHANGES_DEFAULT);
9748
- }
9749
- catch {
9750
- this.exhaustive = USE_EXHAUSTIVE_CHECK_NO_CHANGES_DEFAULT;
9901
+ // Note: we use `if (ngDevMode) { ... }` instead of an early return.
9902
+ // ESBuild is conservative about removing dead code that follows `return;`
9903
+ // inside a function body, so the block may remain in the bundle.
9904
+ // Using a conditional ensures the dev-only logic is reliably tree-shaken
9905
+ // in production builds.
9906
+ if (ngDevMode) {
9907
+ try {
9908
+ this.exhaustive ??= this._lView[INJECTOR].get(UseExhaustiveCheckNoChanges, USE_EXHAUSTIVE_CHECK_NO_CHANGES_DEFAULT);
9909
+ }
9910
+ catch {
9911
+ this.exhaustive = USE_EXHAUSTIVE_CHECK_NO_CHANGES_DEFAULT;
9912
+ }
9913
+ checkNoChangesInternal(this._lView, this.exhaustive);
9751
9914
  }
9752
- checkNoChangesInternal(this._lView, this.exhaustive);
9753
9915
  }
9754
9916
  attachToViewContainerRef() {
9755
9917
  if (this._appRef) {
@@ -13054,13 +13216,21 @@ function listenToDomEvent(tNode, tView, lView, eventTargetResolver, renderer, ev
13054
13216
  const target = eventTargetResolver ? eventTargetResolver(native) : native;
13055
13217
  stashEventListenerImpl(lView, target, eventName, wrappedListener);
13056
13218
  const cleanupFn = renderer.listen(target, eventName, wrappedListener);
13057
- const idxOrTargetGetter = eventTargetResolver
13058
- ? (_lView) => eventTargetResolver(unwrapRNode(_lView[tNode.index]))
13059
- : tNode.index;
13060
- storeListenerCleanup(idxOrTargetGetter, tView, lView, eventName, wrappedListener, cleanupFn, false);
13219
+ // We skip cleaning up animation event types to ensure leaving animation events can be used.
13220
+ // These events should be automatically garbage collected anyway after the element is
13221
+ // removed from the DOM.
13222
+ if (!isAnimationEventType(eventName)) {
13223
+ const idxOrTargetGetter = eventTargetResolver
13224
+ ? (_lView) => eventTargetResolver(unwrapRNode(_lView[tNode.index]))
13225
+ : tNode.index;
13226
+ storeListenerCleanup(idxOrTargetGetter, tView, lView, eventName, wrappedListener, cleanupFn, false);
13227
+ }
13061
13228
  }
13062
13229
  return hasCoalesced;
13063
13230
  }
13231
+ function isAnimationEventType(eventName) {
13232
+ return eventName.startsWith('animation') || eventName.startsWith('transition');
13233
+ }
13064
13234
  /**
13065
13235
  * A utility function that checks if a given element has already an event handler registered for an
13066
13236
  * event with a specified name. The TView.cleanup data structure is used to find out which events
@@ -13522,7 +13692,7 @@ class ComponentFactory extends ComponentFactory$1 {
13522
13692
  }
13523
13693
  function createRootTView(rootSelectorOrNode, componentDef, componentBindings, directives) {
13524
13694
  const tAttributes = rootSelectorOrNode
13525
- ? ['ng-version', '21.0.0-next.3']
13695
+ ? ['ng-version', '21.0.0-next.4']
13526
13696
  : // Extract attributes and classes from the first selector only to match VE behavior.
13527
13697
  extractAttrsAndClassesFromSelector(componentDef.selectors[0]);
13528
13698
  let creationBindings = null;
@@ -19911,6 +20081,22 @@ function remove(list, el) {
19911
20081
  }
19912
20082
  }
19913
20083
 
20084
+ /**
20085
+ * Replace with `Promise.withResolvers()` once it's available.
20086
+ * NET September 2026
20087
+ *
20088
+ * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers.
20089
+ */
20090
+ function promiseWithResolvers() {
20091
+ let resolve;
20092
+ let reject;
20093
+ const promise = new Promise((res, rej) => {
20094
+ resolve = res;
20095
+ reject = rej;
20096
+ });
20097
+ return { promise, resolve, reject };
20098
+ }
20099
+
19914
20100
  /**
19915
20101
  * Schedules triggering of a defer block for `on idle` and `on timer` conditions.
19916
20102
  */
@@ -20280,7 +20466,7 @@ function cleanupRemainingHydrationQueue(hydrationQueue, dehydratedBlockRegistry)
20280
20466
  */
20281
20467
  function populateHydratingStateForQueue(registry, queue) {
20282
20468
  for (let blockId of queue) {
20283
- registry.hydrating.set(blockId, Promise.withResolvers());
20469
+ registry.hydrating.set(blockId, promiseWithResolvers());
20284
20470
  }
20285
20471
  }
20286
20472
  // Waits for the next render cycle to complete
@@ -21128,278 +21314,88 @@ const MAX_ANIMATION_TIMEOUT = new InjectionToken(typeof ngDevMode !== 'undefined
21128
21314
  });
21129
21315
  const MAX_ANIMATION_TIMEOUT_DEFAULT = 4000;
21130
21316
 
21317
+ const DEFAULT_ANIMATIONS_DISABLED = false;
21318
+ const areAnimationSupported = (typeof ngServerMode === 'undefined' || !ngServerMode) &&
21319
+ typeof document !== 'undefined' &&
21320
+ // tslint:disable-next-line:no-toplevel-property-access
21321
+ typeof document?.documentElement?.getAnimations === 'function';
21131
21322
  /**
21132
- * Registers elements for delayed removal action for animation in the case
21133
- * that `animate.leave` is used. This stores the target element and any
21134
- * classes, class resolvers, and callback functions that may be needed
21135
- * to apply the removal animation, and then stashes the actual element
21136
- * removal function from the dom renderer to be called after the
21137
- * animation is finished.
21138
- */
21139
- class ElementRegistry {
21140
- outElements = new WeakMap();
21141
- remove(el) {
21142
- this.outElements.delete(el);
21143
- }
21144
- /** Used when animate.leave is only applying classes */
21145
- trackClasses(details, classes) {
21146
- const classList = getClassListFromValue(classes);
21147
- if (!classList)
21148
- return;
21149
- for (let klass of classList) {
21150
- details.classes?.add(klass);
21151
- }
21323
+ * Helper function to check if animations are disabled via injection token
21324
+ */
21325
+ function areAnimationsDisabled(lView) {
21326
+ const injector = lView[INJECTOR];
21327
+ return injector.get(ANIMATIONS_DISABLED, DEFAULT_ANIMATIONS_DISABLED);
21328
+ }
21329
+ /**
21330
+ * Asserts a value passed in is actually an animation type and not something else
21331
+ */
21332
+ function assertAnimationTypes(value, instruction) {
21333
+ if (value == null || (typeof value !== 'string' && typeof value !== 'function')) {
21334
+ throw new RuntimeError(650 /* RuntimeErrorCode.ANIMATE_INVALID_VALUE */, `'${instruction}' value must be a string of CSS classes or an animation function, got ${stringify(value)}`);
21152
21335
  }
21153
- /** Used when animate.leave is applying classes via a bound attribute
21154
- * which requires resolving the binding function at the right time
21155
- * to get the proper class list. There may be multiple resolvers due
21156
- * to composition via host bindings.
21157
- */
21158
- trackResolver(details, resolver) {
21159
- if (!details.classFns) {
21160
- details.classFns = [resolver];
21161
- }
21162
- else {
21163
- details.classFns.push(resolver);
21164
- }
21336
+ }
21337
+ /**
21338
+ * Asserts a given native element is an actual Element node and not something like a comment node.
21339
+ */
21340
+ function assertElementNodes(nativeElement, instruction) {
21341
+ if (nativeElement.nodeType !== Node.ELEMENT_NODE) {
21342
+ throw new RuntimeError(650 /* RuntimeErrorCode.ANIMATE_INVALID_VALUE */, `'${instruction}' can only be used on an element node, got ${stringify(nativeElement.nodeType)}`);
21165
21343
  }
21166
- /** Used when `animate.leave` is using the function signature and will have a
21167
- * callback function, rather than a list of classes.
21168
- */
21169
- addCallback(el, value, animateWrapperFn) {
21170
- const details = this.outElements.get(el) ?? {
21171
- classes: null,
21172
- animateFn: () => { },
21173
- isEventBinding: true,
21174
- };
21175
- details.animateFn = animateWrapperFn(el, value);
21176
- this.outElements.set(el, details);
21177
- }
21178
- /** Used when `animate.leave` is using classes. */
21179
- add(el, value, animateWrapperFn) {
21180
- const details = this.outElements.get(el) ?? {
21181
- classes: new Set(),
21182
- animateFn: () => { },
21183
- isEventBinding: false,
21184
- };
21185
- if (typeof value === 'function') {
21186
- this.trackResolver(details, value);
21344
+ }
21345
+ /**
21346
+ * trackEnterClasses is necessary in the case of composition where animate.enter
21347
+ * is used on the same element in multiple places, like on the element and in a
21348
+ * host binding. When removing classes, we need the entire list of animation classes
21349
+ * added to properly remove them when the longest animation fires.
21350
+ */
21351
+ function trackEnterClasses(el, classList, cleanupFns) {
21352
+ const elementData = enterClassMap.get(el);
21353
+ if (elementData) {
21354
+ for (const klass of classList) {
21355
+ elementData.classList.push(klass);
21187
21356
  }
21188
- else {
21189
- this.trackClasses(details, value);
21357
+ for (const fn of cleanupFns) {
21358
+ elementData.cleanupFns.push(fn);
21190
21359
  }
21191
- details.animateFn = animateWrapperFn(el, details.classes, details.classFns);
21192
- this.outElements.set(el, details);
21193
21360
  }
21194
- has(el) {
21195
- return this.outElements.has(el);
21361
+ else {
21362
+ enterClassMap.set(el, { classList, cleanupFns });
21196
21363
  }
21197
- /** This is called by the dom renderer to actually initiate the animation
21198
- * using the animateFn stored in the registry. The DOM renderer passes in
21199
- * the removal function to be fired off when the animation finishes.
21200
- */
21201
- animate(el, removeFn, maxAnimationTimeout) {
21202
- if (!this.outElements.has(el))
21203
- return removeFn();
21204
- const details = this.outElements.get(el);
21205
- let timeoutId;
21206
- let called = false;
21207
- const remove = () => {
21208
- // This called check is to prevent a rare race condition where the timing of removal
21209
- // might result in the removal function being called twice.
21210
- if (called)
21211
- return;
21212
- called = true;
21213
- clearTimeout(timeoutId);
21214
- this.remove(el);
21215
- removeFn();
21216
- };
21217
- // this timeout is used to ensure elements actually get removed in the case
21218
- // that the user forgot to call the remove callback. The timeout is cleared
21219
- // in the DOM renderer during the remove child process. It only applies
21220
- // to the event binding use case.
21221
- if (details.isEventBinding) {
21222
- timeoutId = setTimeout(remove, maxAnimationTimeout);
21364
+ }
21365
+ /**
21366
+ * Helper function to cleanup enterClassMap data safely
21367
+ */
21368
+ function cleanupEnterClassData(element) {
21369
+ const elementData = enterClassMap.get(element);
21370
+ if (elementData) {
21371
+ for (const fn of elementData.cleanupFns) {
21372
+ fn();
21223
21373
  }
21224
- details.animateFn(remove);
21374
+ enterClassMap.delete(element);
21225
21375
  }
21376
+ longestAnimations.delete(element);
21226
21377
  }
21227
- function getClassListFromValue(value) {
21228
- const classes = typeof value === 'function' ? value() : value;
21229
- let classList = Array.isArray(classes) ? classes : null;
21230
- if (typeof classes === 'string') {
21231
- classList = classes
21232
- .trim()
21233
- .split(/\s+/)
21234
- .filter((k) => k);
21235
- }
21236
- return classList;
21237
- }
21238
-
21239
- /** Parses a CSS time value to milliseconds. */
21240
- function parseCssTimeUnitsToMs(value) {
21241
- // Some browsers will return it in seconds, whereas others will return milliseconds.
21242
- const multiplier = value.toLowerCase().indexOf('ms') > -1 ? 1 : 1000;
21243
- return parseFloat(value) * multiplier;
21244
- }
21245
- /** Parses out multiple values from a computed style into an array. */
21246
- function parseCssPropertyValue(computedStyle, name) {
21247
- const value = computedStyle.getPropertyValue(name);
21248
- return value.split(',').map((part) => part.trim());
21249
- }
21250
- /** Gets the transform transition duration, including the delay, of an element in milliseconds. */
21251
- function getLongestComputedTransition(computedStyle) {
21252
- const transitionedProperties = parseCssPropertyValue(computedStyle, 'transition-property');
21253
- const rawDurations = parseCssPropertyValue(computedStyle, 'transition-duration');
21254
- const rawDelays = parseCssPropertyValue(computedStyle, 'transition-delay');
21255
- const longest = { propertyName: '', duration: 0, animationName: undefined };
21256
- for (let i = 0; i < transitionedProperties.length; i++) {
21257
- const duration = parseCssTimeUnitsToMs(rawDelays[i]) + parseCssTimeUnitsToMs(rawDurations[i]);
21258
- if (duration > longest.duration) {
21259
- longest.propertyName = transitionedProperties[i];
21260
- longest.duration = duration;
21261
- }
21262
- }
21263
- return longest;
21264
- }
21265
- function getLongestComputedAnimation(computedStyle) {
21266
- const rawNames = parseCssPropertyValue(computedStyle, 'animation-name');
21267
- const rawDelays = parseCssPropertyValue(computedStyle, 'animation-delay');
21268
- const rawDurations = parseCssPropertyValue(computedStyle, 'animation-duration');
21269
- const longest = { animationName: '', propertyName: undefined, duration: 0 };
21270
- for (let i = 0; i < rawNames.length; i++) {
21271
- const duration = parseCssTimeUnitsToMs(rawDelays[i]) + parseCssTimeUnitsToMs(rawDurations[i]);
21272
- if (duration > longest.duration) {
21273
- longest.animationName = rawNames[i];
21274
- longest.duration = duration;
21275
- }
21276
- }
21277
- return longest;
21278
- }
21279
- function isShorterThanExistingAnimation(existing, longest) {
21280
- return existing !== undefined && existing.duration > longest.duration;
21281
- }
21282
- function longestExists(longest) {
21283
- return ((longest.animationName != undefined || longest.propertyName != undefined) &&
21284
- longest.duration > 0);
21285
- }
21286
- /**
21287
- * Determines the longest animation, but with `getComputedStyles` instead of `getAnimations`. This
21288
- * is ultimately safer than getAnimations because it can be used when recalculations are in
21289
- * progress. `getAnimations()` will be empty in that case.
21290
- */
21291
- function determineLongestAnimationFromComputedStyles(el, animationsMap) {
21292
- const computedStyle = getComputedStyle(el);
21293
- const longestAnimation = getLongestComputedAnimation(computedStyle);
21294
- const longestTransition = getLongestComputedTransition(computedStyle);
21295
- const longest = longestAnimation.duration > longestTransition.duration ? longestAnimation : longestTransition;
21296
- if (isShorterThanExistingAnimation(animationsMap.get(el), longest))
21297
- return;
21298
- if (longestExists(longest)) {
21299
- animationsMap.set(el, longest);
21300
- }
21301
- }
21302
- /**
21303
- * Multiple animations can be set on an element. This grabs an element and
21304
- * determines which of those will be the longest duration. If we didn't do
21305
- * this, elements would be removed whenever the first animation completes.
21306
- * This ensures we get the longest running animation and only remove when
21307
- * that animation completes.
21308
- */
21309
- function determineLongestAnimation(el, animationsMap, areAnimationSupported) {
21310
- if (!areAnimationSupported)
21311
- return;
21312
- const animations = el.getAnimations();
21313
- return animations.length === 0
21314
- ? // fallback to computed styles if getAnimations is empty. This would happen if styles are
21315
- // currently recalculating due to a reflow happening elsewhere.
21316
- determineLongestAnimationFromComputedStyles(el, animationsMap)
21317
- : determineLongestAnimationFromElementAnimations(el, animationsMap, animations);
21318
- }
21319
- function determineLongestAnimationFromElementAnimations(el, animationsMap, animations) {
21320
- let longest = {
21321
- animationName: undefined,
21322
- propertyName: undefined,
21323
- duration: 0,
21324
- };
21325
- for (const animation of animations) {
21326
- const timing = animation.effect?.getTiming();
21327
- // duration can be a string 'auto' or a number.
21328
- const animDuration = typeof timing?.duration === 'number' ? timing.duration : 0;
21329
- let duration = (timing?.delay ?? 0) + animDuration;
21330
- let propertyName;
21331
- let animationName;
21332
- if (animation.animationName) {
21333
- animationName = animation.animationName;
21334
- }
21335
- else {
21336
- // Check for CSSTransition specific property
21337
- propertyName = animation.transitionProperty;
21338
- }
21339
- if (duration >= longest.duration) {
21340
- longest = { animationName, propertyName, duration };
21341
- }
21342
- }
21343
- if (isShorterThanExistingAnimation(animationsMap.get(el), longest))
21344
- return;
21345
- if (longestExists(longest)) {
21346
- animationsMap.set(el, longest);
21347
- }
21348
- }
21349
-
21350
- const DEFAULT_ANIMATIONS_DISABLED = false;
21351
- const areAnimationSupported = (typeof ngServerMode === 'undefined' || !ngServerMode) &&
21352
- typeof document !== 'undefined' &&
21353
- // tslint:disable-next-line:no-toplevel-property-access
21354
- typeof document?.documentElement?.getAnimations === 'function';
21355
- /**
21356
- * Helper function to check if animations are disabled via injection token
21357
- */
21358
- function areAnimationsDisabled(lView) {
21359
- const injector = lView[INJECTOR];
21360
- return injector.get(ANIMATIONS_DISABLED, DEFAULT_ANIMATIONS_DISABLED);
21361
- }
21362
- /**
21363
- * Helper function to setup element registry cleanup when LView is destroyed
21364
- */
21365
- function setupElementRegistryCleanup(elementRegistry, lView, tView, nativeElement) {
21366
- if (lView[FLAGS] & 8 /* LViewFlags.FirstLViewPass */) {
21367
- storeCleanupWithContext(tView, lView, nativeElement, (elToClean) => {
21368
- elementRegistry.elements.remove(elToClean);
21369
- });
21370
- }
21371
- }
21372
- /**
21373
- * Helper function to cleanup enterClassMap data safely
21374
- */
21375
- function cleanupEnterClassData(element) {
21376
- const elementData = enterClassMap.get(element);
21377
- if (elementData) {
21378
- for (const fn of elementData.cleanupFns) {
21379
- fn();
21380
- }
21381
- enterClassMap.delete(element);
21382
- }
21383
- longestAnimations.delete(element);
21384
- }
21385
- const noOpAnimationComplete = () => { };
21386
- // Tracks the list of classes added to a DOM node from `animate.enter` calls to ensure
21387
- // we remove all of the classes in the case of animation composition via host bindings.
21388
- const enterClassMap = new WeakMap();
21389
- const longestAnimations = new WeakMap();
21390
- // Tracks nodes that are animating away for the duration of the animation. This is
21391
- // used to prevent duplicate nodes from showing up when nodes have been toggled quickly
21392
- // from an `@if` or `@for`.
21393
- const leavingNodes = new WeakMap();
21394
- function clearLeavingNodes(tNode, el) {
21395
- const nodes = leavingNodes.get(tNode);
21396
- if (nodes && nodes.length > 0) {
21397
- const ix = nodes.findIndex((node) => node === el);
21398
- if (ix > -1)
21399
- nodes.splice(ix, 1);
21400
- }
21401
- if (nodes?.length === 0) {
21402
- leavingNodes.delete(tNode);
21378
+ const noOpAnimationComplete = () => { };
21379
+ // Tracks the list of classes added to a DOM node from `animate.enter` calls to ensure
21380
+ // we remove all of the classes in the case of animation composition via host bindings.
21381
+ const enterClassMap = new WeakMap();
21382
+ const longestAnimations = new WeakMap();
21383
+ // Tracks nodes that are animating away for the duration of the animation. This is
21384
+ // used to prevent duplicate nodes from showing up when nodes have been toggled quickly
21385
+ // from an `@if` or `@for`.
21386
+ const leavingNodes = new WeakMap();
21387
+ /**
21388
+ * This actually removes the leaving HTML Element in the TNode
21389
+ */
21390
+ function clearLeavingNodes(tNode, el) {
21391
+ const nodes = leavingNodes.get(tNode);
21392
+ if (nodes && nodes.length > 0) {
21393
+ const ix = nodes.findIndex((node) => node === el);
21394
+ if (ix > -1)
21395
+ nodes.splice(ix, 1);
21396
+ }
21397
+ if (nodes?.length === 0) {
21398
+ leavingNodes.delete(tNode);
21403
21399
  }
21404
21400
  }
21405
21401
  /**
@@ -21414,7 +21410,9 @@ function cancelLeavingNodes(tNode, lView) {
21414
21410
  // this is the insertion point for the new TNode element.
21415
21411
  // it will be inserted before the declaring containers anchor.
21416
21412
  const beforeNode = getBeforeNodeForView(tNode.index, lContainer);
21417
- // here we need to check the previous sibling of that anchor
21413
+ // here we need to check the previous sibling of that anchor. The first
21414
+ // previousSibling node will be the new element added. The second
21415
+ // previousSibling will be the one that's being removed.
21418
21416
  const previousNode = beforeNode?.previousSibling;
21419
21417
  // We really only want to cancel animations if the leaving node is the
21420
21418
  // same as the node before where the new node will be inserted. This is
@@ -21424,6 +21422,11 @@ function cancelLeavingNodes(tNode, lView) {
21424
21422
  }
21425
21423
  }
21426
21424
  }
21425
+ /**
21426
+ * Tracks the nodes list of nodes that are leaving the DOM so we can cancel any leave animations
21427
+ * and remove the node before adding a new entering instance of the DOM node. This prevents
21428
+ * duplicates from showing up on screen mid-animation.
21429
+ */
21427
21430
  function trackLeavingNodes(tNode, el) {
21428
21431
  // We need to track this tNode's element just to be sure we don't add
21429
21432
  // a new RNode for this TNode while this one is still animating away.
@@ -21435,6 +21438,80 @@ function trackLeavingNodes(tNode, el) {
21435
21438
  leavingNodes.set(tNode, [el]);
21436
21439
  }
21437
21440
  }
21441
+ /**
21442
+ * Retrieves the list of specified enter animations from the lView
21443
+ */
21444
+ function getLViewEnterAnimations(lView) {
21445
+ const animationData = (lView[ANIMATIONS] ??= {});
21446
+ return (animationData.enter ??= []);
21447
+ }
21448
+ /**
21449
+ * Retrieves the list of specified leave animations from the lView
21450
+ */
21451
+ function getLViewLeaveAnimations(lView) {
21452
+ const animationData = (lView[ANIMATIONS] ??= {});
21453
+ return (animationData.leave ??= []);
21454
+ }
21455
+ /**
21456
+ * Gets the list of classes from a passed in value
21457
+ */
21458
+ function getClassListFromValue(value) {
21459
+ const classes = typeof value === 'function' ? value() : value;
21460
+ let classList = Array.isArray(classes) ? classes : null;
21461
+ if (typeof classes === 'string') {
21462
+ classList = classes
21463
+ .trim()
21464
+ .split(/\s+/)
21465
+ .filter((k) => k);
21466
+ }
21467
+ return classList;
21468
+ }
21469
+ /**
21470
+ * Cancels any running enter animations on a given element to prevent them from interfering
21471
+ * with leave animations.
21472
+ */
21473
+ function cancelAnimationsIfRunning(element, renderer) {
21474
+ if (!areAnimationSupported)
21475
+ return;
21476
+ const elementData = enterClassMap.get(element);
21477
+ if (elementData &&
21478
+ elementData.classList.length > 0 &&
21479
+ elementHasClassList(element, elementData.classList)) {
21480
+ for (const klass of elementData.classList) {
21481
+ renderer.removeClass(element, klass);
21482
+ }
21483
+ }
21484
+ // We need to prevent any enter animation listeners from firing if they exist.
21485
+ cleanupEnterClassData(element);
21486
+ }
21487
+ /**
21488
+ * Checks if a given element contains the classes is a provided list
21489
+ */
21490
+ function elementHasClassList(element, classList) {
21491
+ for (const className of classList) {
21492
+ if (element.classList.contains(className))
21493
+ return true;
21494
+ }
21495
+ return false;
21496
+ }
21497
+ /**
21498
+ * Determines if the animation or transition event is currently the expected longest animation
21499
+ * based on earlier determined data in `longestAnimations`
21500
+ *
21501
+ * @param event
21502
+ * @param nativeElement
21503
+ * @returns
21504
+ */
21505
+ function isLongestAnimation(event, nativeElement) {
21506
+ const longestAnimation = longestAnimations.get(nativeElement);
21507
+ return (nativeElement === event.target &&
21508
+ longestAnimation !== undefined &&
21509
+ ((longestAnimation.animationName !== undefined &&
21510
+ event.animationName === longestAnimation.animationName) ||
21511
+ (longestAnimation.propertyName !== undefined &&
21512
+ event.propertyName === longestAnimation.propertyName)));
21513
+ }
21514
+
21438
21515
  /**
21439
21516
  * Instruction to handle the `animate.enter` behavior for class bindings.
21440
21517
  *
@@ -21454,6 +21531,11 @@ function ɵɵanimateEnter(value) {
21454
21531
  return ɵɵanimateEnter;
21455
21532
  }
21456
21533
  const tNode = getCurrentTNode();
21534
+ cancelLeavingNodes(tNode, lView);
21535
+ getLViewEnterAnimations(lView).push(() => runEnterAnimation(lView, tNode, value));
21536
+ return ɵɵanimateEnter; // For chaining
21537
+ }
21538
+ function runEnterAnimation(lView, tNode, value) {
21457
21539
  const nativeElement = getNativeByTNode(tNode, lView);
21458
21540
  ngDevMode && assertElementNodes(nativeElement, 'animate.enter');
21459
21541
  const renderer = lView[RENDERER];
@@ -21466,23 +21548,22 @@ function ɵɵanimateEnter(value) {
21466
21548
  // to get the longest animation to ensure we don't complete animations early.
21467
21549
  // This also allows us to setup cancellation of animations in progress if the
21468
21550
  // gets removed early.
21469
- const handleAnimationStart = (event) => {
21551
+ const handleEnterAnimationStart = (event) => {
21470
21552
  const eventName = event instanceof AnimationEvent ? 'animationend' : 'transitionend';
21471
21553
  ngZone.runOutsideAngular(() => {
21472
- cleanupFns.push(renderer.listen(nativeElement, eventName, handleInAnimationEnd));
21554
+ cleanupFns.push(renderer.listen(nativeElement, eventName, handleEnterAnimationEnd));
21473
21555
  });
21474
21556
  };
21475
21557
  // When the longest animation ends, we can remove all the classes
21476
- const handleInAnimationEnd = (event) => {
21477
- animationEnd(event, nativeElement, renderer);
21558
+ const handleEnterAnimationEnd = (event) => {
21559
+ enterAnimationEnd(event, nativeElement, renderer);
21478
21560
  };
21479
21561
  // We only need to add these event listeners if there are actual classes to apply
21480
21562
  if (activeClasses && activeClasses.length > 0) {
21481
21563
  ngZone.runOutsideAngular(() => {
21482
- cleanupFns.push(renderer.listen(nativeElement, 'animationstart', handleAnimationStart));
21483
- cleanupFns.push(renderer.listen(nativeElement, 'transitionstart', handleAnimationStart));
21564
+ cleanupFns.push(renderer.listen(nativeElement, 'animationstart', handleEnterAnimationStart));
21565
+ cleanupFns.push(renderer.listen(nativeElement, 'transitionstart', handleEnterAnimationStart));
21484
21566
  });
21485
- cancelLeavingNodes(tNode, lView);
21486
21567
  trackEnterClasses(nativeElement, activeClasses, cleanupFns);
21487
21568
  for (const klass of activeClasses) {
21488
21569
  renderer.addClass(nativeElement, klass);
@@ -21502,26 +21583,21 @@ function ɵɵanimateEnter(value) {
21502
21583
  });
21503
21584
  });
21504
21585
  }
21505
- return ɵɵanimateEnter; // For chaining
21506
21586
  }
21507
- /**
21508
- * trackEnterClasses is necessary in the case of composition where animate.enter
21509
- * is used on the same element in multiple places, like on the element and in a
21510
- * host binding. When removing classes, we need the entire list of animation classes
21511
- * added to properly remove them when the longest animation fires.
21512
- */
21513
- function trackEnterClasses(el, classList, cleanupFns) {
21514
- const elementData = enterClassMap.get(el);
21515
- if (elementData) {
21516
- for (const klass of classList) {
21517
- elementData.classList.push(klass);
21518
- }
21519
- for (const fn of cleanupFns) {
21520
- elementData.cleanupFns.push(fn);
21587
+ function enterAnimationEnd(event, nativeElement, renderer) {
21588
+ const elementData = enterClassMap.get(nativeElement);
21589
+ if (!elementData)
21590
+ return;
21591
+ if (isLongestAnimation(event, nativeElement)) {
21592
+ // Now that we've found the longest animation, there's no need
21593
+ // to keep bubbling up this event as it's not going to apply to
21594
+ // other elements further up. We don't want it to inadvertently
21595
+ // affect any other animations on the page.
21596
+ event.stopImmediatePropagation();
21597
+ for (const klass of elementData.classList) {
21598
+ renderer.removeClass(nativeElement, klass);
21521
21599
  }
21522
- }
21523
- else {
21524
- enterClassMap.set(el, { classList, cleanupFns });
21600
+ cleanupEnterClassData(nativeElement);
21525
21601
  }
21526
21602
  }
21527
21603
  /**
@@ -21544,16 +21620,22 @@ function ɵɵanimateEnterListener(value) {
21544
21620
  return ɵɵanimateEnterListener;
21545
21621
  }
21546
21622
  const tNode = getCurrentTNode();
21623
+ cancelLeavingNodes(tNode, lView);
21624
+ getLViewEnterAnimations(lView).push(() => runEnterAnimationFunction(lView, tNode, value));
21625
+ return ɵɵanimateEnterListener;
21626
+ }
21627
+ /**
21628
+ * runs enter animations when a custom function is provided
21629
+ */
21630
+ function runEnterAnimationFunction(lView, tNode, value) {
21547
21631
  const nativeElement = getNativeByTNode(tNode, lView);
21548
21632
  ngDevMode && assertElementNodes(nativeElement, 'animate.enter');
21549
- cancelLeavingNodes(tNode, lView);
21550
21633
  value.call(lView[CONTEXT], { target: nativeElement, animationComplete: noOpAnimationComplete });
21551
- return ɵɵanimateEnterListener;
21552
21634
  }
21553
21635
  /**
21554
21636
  * Instruction to handle the `animate.leave` behavior for class animations.
21555
- * It registers an animation with the ElementRegistry to be run when the element
21556
- * is scheduled for removal from the DOM.
21637
+ * It creates a leave animation function that's tracked in the LView to
21638
+ * be run before DOM node removal and cleanup.
21557
21639
  *
21558
21640
  * @param value The value bound to `animate.leave`, which can be a string or a function.
21559
21641
  * @returns This function returns itself so that it may be chained.
@@ -21571,170 +21653,34 @@ function ɵɵanimateLeave(value) {
21571
21653
  if (animationsDisabled) {
21572
21654
  return ɵɵanimateLeave;
21573
21655
  }
21574
- const tView = getTView();
21575
21656
  const tNode = getCurrentTNode();
21576
- const nativeElement = getNativeByTNode(tNode, lView);
21577
- ngDevMode && assertElementNodes(nativeElement, 'animate.leave');
21578
- // This instruction is called in the update pass.
21579
- const renderer = lView[RENDERER];
21580
- const elementRegistry = getAnimationElementRemovalRegistry();
21581
- ngDevMode &&
21582
- assertDefined(elementRegistry.elements, 'Expected `ElementRegistry` to be present in animations subsystem');
21583
- const ngZone = lView[INJECTOR].get(NgZone);
21584
- // This function gets stashed in the registry to be used once the element removal process
21585
- // begins. We pass in the values and resolvers so as to evaluate the resolved classes
21586
- // at the latest possible time, meaning we evaluate them right before the animation
21587
- // begins.
21588
- const animate = (el, value, resolvers) => {
21589
- return (removalFn) => {
21590
- animateLeaveClassRunner(el, tNode, getClassList(value, resolvers), removalFn, renderer, animationsDisabled, ngZone);
21591
- };
21592
- };
21593
- // Ensure cleanup if the LView is destroyed before the animation runs.
21594
- setupElementRegistryCleanup(elementRegistry, lView, tView, nativeElement);
21595
- elementRegistry.elements.add(nativeElement, value, animate);
21657
+ getLViewLeaveAnimations(lView).push(() => runLeaveAnimations(lView, tNode, value, animationsDisabled));
21596
21658
  return ɵɵanimateLeave; // For chaining
21597
21659
  }
21598
- /**
21599
- * Instruction to handle the `(animate.leave)` behavior for event bindings, aka when
21600
- * a user wants to use a custom animation function rather than a class. It registers
21601
- * an animation with the ElementRegistry to be run when the element is scheduled for
21602
- * removal from the DOM.
21603
- *
21604
- * @param value The value bound to `(animate.leave)`, an AnimationFunction.
21605
- * @returns This function returns itself so that it may be chained.
21606
- *
21607
- * @codeGenApi
21608
- */
21609
- function ɵɵanimateLeaveListener(value) {
21610
- performanceMarkFeature('NgAnimateLeave');
21611
- if ((typeof ngServerMode !== 'undefined' && ngServerMode) || !areAnimationSupported) {
21612
- return ɵɵanimateLeaveListener;
21613
- }
21614
- ngDevMode && assertAnimationTypes(value, 'animate.leave');
21615
- // Even when animations are disabled, we still need to register the element for removal
21616
- // to ensure proper cleanup and allow developers to handle element removal in tests
21617
- // So we don't have an early return here.
21618
- const lView = getLView();
21619
- const tNode = getCurrentTNode();
21620
- const tView = getTView();
21660
+ function runLeaveAnimations(lView, tNode, value, animationsDisabled) {
21661
+ const { promise, resolve } = promiseWithResolvers();
21621
21662
  const nativeElement = getNativeByTNode(tNode, lView);
21622
21663
  ngDevMode && assertElementNodes(nativeElement, 'animate.leave');
21623
- const elementRegistry = getAnimationElementRemovalRegistry();
21624
- ngDevMode &&
21625
- assertDefined(elementRegistry.elements, 'Expected `ElementRegistry` to be present in animations subsystem');
21626
21664
  const renderer = lView[RENDERER];
21627
- const animationsDisabled = areAnimationsDisabled(lView);
21628
21665
  const ngZone = lView[INJECTOR].get(NgZone);
21629
- const animate = (_el, value) => {
21630
- return (removeFn) => {
21631
- if (animationsDisabled) {
21632
- removeFn();
21633
- }
21634
- else {
21635
- const event = {
21636
- target: nativeElement,
21637
- animationComplete: () => {
21638
- clearLeavingNodes(tNode, _el);
21639
- removeFn();
21640
- },
21641
- };
21642
- trackLeavingNodes(tNode, _el);
21643
- ngZone.runOutsideAngular(() => {
21644
- renderer.listen(_el, 'animationend', () => removeFn(), { once: true });
21645
- });
21646
- value.call(lView[CONTEXT], event);
21647
- }
21648
- };
21649
- };
21650
- // Ensure cleanup if the LView is destroyed before the animation runs.
21651
- setupElementRegistryCleanup(elementRegistry, lView, tView, nativeElement);
21652
- elementRegistry.elements.addCallback(nativeElement, value, animate);
21653
- return ɵɵanimateLeaveListener; // For chaining
21654
- }
21655
- /**
21656
- * Builds the list of classes to apply to an element based on either the passed in list of strings
21657
- * or the set of resolver functions that are coming from bindings. Those resolver functions should
21658
- * resolve into either a string or a string array. There may be multiple to support composition.
21659
- */
21660
- function getClassList(value, resolvers) {
21661
- const classList = new Set(value);
21662
- if (resolvers && resolvers.length) {
21663
- for (const resolverFn of resolvers) {
21664
- const resolvedValue = getClassListFromValue(resolverFn);
21665
- if (resolvedValue) {
21666
- for (const rv of resolvedValue) {
21667
- classList.add(rv);
21668
- }
21669
- }
21670
- }
21671
- }
21672
- return classList;
21673
- }
21674
- function cancelAnimationsIfRunning(element, renderer) {
21675
- if (!areAnimationSupported)
21676
- return;
21677
- const elementData = enterClassMap.get(element);
21678
- if (elementData &&
21679
- elementData.classList.length > 0 &&
21680
- elementHasClassList(element, elementData.classList)) {
21681
- for (const klass of elementData.classList) {
21682
- renderer.removeClass(element, klass);
21683
- }
21684
- }
21685
- // We need to prevent any enter animation listeners from firing if they exist.
21686
- cleanupEnterClassData(element);
21687
- }
21688
- function elementHasClassList(element, classList) {
21689
- for (const className of classList) {
21690
- if (element.classList.contains(className))
21691
- return true;
21692
- }
21693
- return false;
21694
- }
21695
- function isLongestAnimation(event, nativeElement) {
21696
- const longestAnimation = longestAnimations.get(nativeElement);
21697
- return (nativeElement === event.target &&
21698
- longestAnimation !== undefined &&
21699
- ((longestAnimation.animationName !== undefined &&
21700
- event.animationName === longestAnimation.animationName) ||
21701
- (longestAnimation.propertyName !== undefined &&
21702
- event.propertyName === longestAnimation.propertyName)));
21703
- }
21704
- function animationEnd(event, nativeElement, renderer) {
21705
- const elementData = enterClassMap.get(nativeElement);
21706
- if (!elementData)
21707
- return;
21708
- if (isLongestAnimation(event, nativeElement)) {
21709
- // Now that we've found the longest animation, there's no need
21710
- // to keep bubbling up this event as it's not going to apply to
21711
- // other elements further up. We don't want it to inadvertently
21712
- // affect any other animations on the page.
21713
- event.stopImmediatePropagation();
21714
- for (const klass of elementData.classList) {
21715
- renderer.removeClass(nativeElement, klass);
21716
- }
21717
- cleanupEnterClassData(nativeElement);
21718
- }
21719
- }
21720
- function assertAnimationTypes(value, instruction) {
21721
- if (value == null || (typeof value !== 'string' && typeof value !== 'function')) {
21722
- throw new RuntimeError(650 /* RuntimeErrorCode.ANIMATE_INVALID_VALUE */, `'${instruction}' value must be a string of CSS classes or an animation function, got ${stringify(value)}`);
21666
+ allLeavingAnimations.add(lView);
21667
+ const activeClasses = getClassListFromValue(value);
21668
+ if (activeClasses && activeClasses.length > 0) {
21669
+ animateLeaveClassRunner(nativeElement, tNode, activeClasses, renderer, animationsDisabled, ngZone, resolve);
21723
21670
  }
21724
- }
21725
- function assertElementNodes(nativeElement, instruction) {
21726
- if (nativeElement.nodeType !== Node.ELEMENT_NODE) {
21727
- throw new RuntimeError(650 /* RuntimeErrorCode.ANIMATE_INVALID_VALUE */, `'${instruction}' can only be used on an element node, got ${stringify(nativeElement.nodeType)}`);
21671
+ else {
21672
+ resolve();
21728
21673
  }
21674
+ return promise;
21729
21675
  }
21730
21676
  /**
21731
21677
  * This function actually adds the classes that animate element that's leaving the DOM.
21732
21678
  * Once it finishes, it calls the remove function that was provided by the DOM renderer.
21733
21679
  */
21734
- function animateLeaveClassRunner(el, tNode, classList, finalRemoveFn, renderer, animationsDisabled, ngZone) {
21680
+ function animateLeaveClassRunner(el, tNode, classList, renderer, animationsDisabled, ngZone, resolver) {
21735
21681
  if (animationsDisabled) {
21736
21682
  longestAnimations.delete(el);
21737
- finalRemoveFn();
21683
+ resolver();
21738
21684
  return;
21739
21685
  }
21740
21686
  cancelAnimationsIfRunning(el, renderer);
@@ -21747,8 +21693,16 @@ function animateLeaveClassRunner(el, tNode, classList, finalRemoveFn, renderer,
21747
21693
  event.stopImmediatePropagation();
21748
21694
  longestAnimations.delete(el);
21749
21695
  clearLeavingNodes(tNode, el);
21750
- finalRemoveFn();
21696
+ if (Array.isArray(tNode.projection)) {
21697
+ // in the content projection case, the element is not destroyed.
21698
+ // So we need to remove the class at the end so that it isn't left
21699
+ // behind for whenever the item shows up again.
21700
+ for (const item of classList) {
21701
+ renderer.removeClass(el, item);
21702
+ }
21703
+ }
21751
21704
  }
21705
+ resolver();
21752
21706
  };
21753
21707
  ngZone.runOutsideAngular(() => {
21754
21708
  renderer.listen(el, 'animationend', handleOutAnimationEnd);
@@ -21766,11 +21720,75 @@ function animateLeaveClassRunner(el, tNode, classList, finalRemoveFn, renderer,
21766
21720
  determineLongestAnimation(el, longestAnimations, areAnimationSupported);
21767
21721
  if (!longestAnimations.has(el)) {
21768
21722
  clearLeavingNodes(tNode, el);
21769
- finalRemoveFn();
21723
+ resolver();
21770
21724
  }
21771
21725
  });
21772
21726
  });
21773
21727
  }
21728
+ /**
21729
+ * Instruction to handle the `(animate.leave)` behavior for event bindings, aka when
21730
+ * a user wants to use a custom animation function rather than a class. It registers
21731
+ * a leave animation function in the LView to be run at right before removal from the
21732
+ * DOM.
21733
+ *
21734
+ * @param value The value bound to `(animate.leave)`, an AnimationFunction.
21735
+ * @returns This function returns itself so that it may be chained.
21736
+ *
21737
+ * @codeGenApi
21738
+ */
21739
+ function ɵɵanimateLeaveListener(value) {
21740
+ performanceMarkFeature('NgAnimateLeave');
21741
+ if ((typeof ngServerMode !== 'undefined' && ngServerMode) || !areAnimationSupported) {
21742
+ return ɵɵanimateLeaveListener;
21743
+ }
21744
+ ngDevMode && assertAnimationTypes(value, 'animate.leave');
21745
+ // Even when animations are disabled, we still need to register the element for removal
21746
+ // to ensure proper cleanup and allow developers to handle element removal in tests
21747
+ // So we don't have an early return here.
21748
+ const lView = getLView();
21749
+ const tNode = getCurrentTNode();
21750
+ allLeavingAnimations.add(lView);
21751
+ getLViewLeaveAnimations(lView).push(() => runLeaveAnimationFunction(lView, tNode, value));
21752
+ return ɵɵanimateLeaveListener; // For chaining
21753
+ }
21754
+ /**
21755
+ * runs leave animations when a custom function is provided
21756
+ */
21757
+ function runLeaveAnimationFunction(lView, tNode, value) {
21758
+ const { promise, resolve } = promiseWithResolvers();
21759
+ const nativeElement = getNativeByTNode(tNode, lView);
21760
+ ngDevMode && assertElementNodes(nativeElement, 'animate.leave');
21761
+ const renderer = lView[RENDERER];
21762
+ const animationsDisabled = areAnimationsDisabled(lView);
21763
+ const ngZone = lView[INJECTOR].get(NgZone);
21764
+ const maxAnimationTimeout = lView[INJECTOR].get(MAX_ANIMATION_TIMEOUT);
21765
+ if (animationsDisabled) {
21766
+ resolve();
21767
+ }
21768
+ else {
21769
+ const timeoutId = setTimeout(() => {
21770
+ clearLeavingNodes(tNode, nativeElement);
21771
+ resolve();
21772
+ }, maxAnimationTimeout);
21773
+ const event = {
21774
+ target: nativeElement,
21775
+ animationComplete: () => {
21776
+ clearLeavingNodes(tNode, nativeElement);
21777
+ clearTimeout(timeoutId);
21778
+ resolve();
21779
+ },
21780
+ };
21781
+ trackLeavingNodes(tNode, nativeElement);
21782
+ ngZone.runOutsideAngular(() => {
21783
+ renderer.listen(nativeElement, 'animationend', () => {
21784
+ resolve();
21785
+ }, { once: true });
21786
+ });
21787
+ value.call(lView[CONTEXT], event);
21788
+ }
21789
+ // Ensure cleanup if the LView is destroyed before the animation runs.
21790
+ return promise;
21791
+ }
21774
21792
 
21775
21793
  /*!
21776
21794
  * @license
@@ -21821,7 +21839,11 @@ class LiveCollection {
21821
21839
  }
21822
21840
  }
21823
21841
  move(prevIndex, newIdx) {
21824
- this.attach(newIdx, this.detach(prevIndex));
21842
+ // For move operations, the detach code path is the same one used for removing
21843
+ // DOM nodes, which would trigger `animate.leave` bindings. We need to skip
21844
+ // those animations in the case of a move operation so the moving elements don't
21845
+ // unexpectedly disappear.
21846
+ this.attach(newIdx, this.detach(prevIndex, true /* skipLeaveAnimations */));
21825
21847
  }
21826
21848
  }
21827
21849
  function valuesMatching(liveIdx, liveValue, newIdx, newValue, trackBy) {
@@ -22393,8 +22415,10 @@ class LiveCollectionLContainerImpl extends LiveCollection {
22393
22415
  this.needsIndexUpdate ||= index !== this.length;
22394
22416
  addLViewToLContainer(this.lContainer, lView, index, shouldAddViewToDom(this.templateTNode, dehydratedView));
22395
22417
  }
22396
- detach(index) {
22418
+ detach(index, skipLeaveAnimations) {
22397
22419
  this.needsIndexUpdate ||= index !== this.length - 1;
22420
+ if (skipLeaveAnimations)
22421
+ setSkipLeaveAnimations(this.lContainer, index);
22398
22422
  return detachExistingView(this.lContainer, index);
22399
22423
  }
22400
22424
  create(index, value) {
@@ -22500,6 +22524,15 @@ function getLContainer(lView, index) {
22500
22524
  ngDevMode && assertLContainer(lContainer);
22501
22525
  return lContainer;
22502
22526
  }
22527
+ function setSkipLeaveAnimations(lContainer, index) {
22528
+ if (lContainer.length <= CONTAINER_HEADER_OFFSET)
22529
+ return;
22530
+ const indexInContainer = CONTAINER_HEADER_OFFSET + index;
22531
+ const viewToDetach = lContainer[indexInContainer];
22532
+ if (viewToDetach && viewToDetach[ANIMATIONS]) {
22533
+ viewToDetach[ANIMATIONS].skipLeaveAnimations = true;
22534
+ }
22535
+ }
22503
22536
  function detachExistingView(lContainer, index) {
22504
22537
  const existingLView = detachView(lContainer, index);
22505
22538
  ngDevMode && assertLView(existingLView);
@@ -22987,7 +23020,7 @@ function plural(val) {
22987
23020
  return 1;
22988
23021
  return 5;
22989
23022
  }
22990
- var localeEn = ["en", [["a", "p"], ["AM", "PM"], u], [["AM", "PM"], u, u], [["S", "M", "T", "W", "T", "F", "S"], ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]], u, [["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"], ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]], u, [["B", "A"], ["BC", "AD"], ["Before Christ", "Anno Domini"]], 0, [6, 0], ["M/d/yy", "MMM d, y", "MMMM d, y", "EEEE, MMMM d, y"], ["h:mm a", "h:mm:ss a", "h:mm:ss a z", "h:mm:ss a zzzz"], ["{1}, {0}", u, "{1} 'at' {0}", u], [".", ",", ";", "%", "+", "-", "E", "×", "‰", "∞", "NaN", ":"], ["#,##0.###", "#,##0%", "¤#,##0.00", "#E0"], "USD", "$", "US Dollar", {}, "ltr", plural];
23023
+ var localeEn = ["en", [["a", "p"], ["AM", "PM"]], [["AM", "PM"]], [["S", "M", "T", "W", "T", "F", "S"], ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]], u, [["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"], ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]], u, [["B", "A"], ["BC", "AD"], ["Before Christ", "Anno Domini"]], 0, [6, 0], ["M/d/yy", "MMM d, y", "MMMM d, y", "EEEE, MMMM d, y"], ["h:mm a", "h:mm:ss a", "h:mm:ss a z", "h:mm:ss a zzzz"], ["{1}, {0}", u, "{1} 'at' {0}", u], [".", ",", ";", "%", "+", "-", "E", "×", "‰", "∞", "NaN", ":"], ["#,##0.###", "#,##0%", "¤#,##0.00", "#E0"], "USD", "$", "US Dollar", {}, "ltr", plural];
22991
23024
 
22992
23025
  /**
22993
23026
  * This const is used to store the locale data registered with `registerLocaleData`
@@ -23155,6 +23188,7 @@ const ICU_MARKER = {
23155
23188
  */
23156
23189
  var I18nCreateOpCode;
23157
23190
  (function (I18nCreateOpCode) {
23191
+ /* tslint:disable:no-duplicate-enum-values */
23158
23192
  /**
23159
23193
  * Number of bits to shift index so that it can be combined with the `APPEND_EAGERLY` and
23160
23194
  * `COMMENT`.
@@ -23168,6 +23202,7 @@ var I18nCreateOpCode;
23168
23202
  * If set the node should be comment (rather than a text) node.
23169
23203
  */
23170
23204
  I18nCreateOpCode[I18nCreateOpCode["COMMENT"] = 2] = "COMMENT";
23205
+ /* tslint:enable:no-duplicate-enum-values */
23171
23206
  })(I18nCreateOpCode || (I18nCreateOpCode = {}));
23172
23207
 
23173
23208
  /**
@@ -27693,18 +27728,6 @@ function ɵɵExternalStylesFeature(styleUrls) {
27693
27728
  };
27694
27729
  }
27695
27730
 
27696
- /**
27697
- * This feature adds the element registry for delayed element removal when animate.leave
27698
- * is utilized.
27699
- *
27700
- * @codeGenApi
27701
- */
27702
- function ɵɵAnimationsFeature() {
27703
- return () => {
27704
- setAnimationElementRemovalRegistry(new ElementRegistry());
27705
- };
27706
- }
27707
-
27708
27731
  /**
27709
27732
  * Generated next to NgModules to monkey-patch directive and pipe references onto a component's
27710
27733
  * definition, when generating a direct reference in the component file would otherwise create an
@@ -28664,7 +28687,6 @@ const angularCoreEnv = (() => ({
28664
28687
  'ɵɵCopyDefinitionFeature': ɵɵCopyDefinitionFeature,
28665
28688
  'ɵɵInheritDefinitionFeature': ɵɵInheritDefinitionFeature,
28666
28689
  'ɵɵExternalStylesFeature': ɵɵExternalStylesFeature,
28667
- 'ɵɵAnimationsFeature': ɵɵAnimationsFeature,
28668
28690
  'ɵɵnextContext': ɵɵnextContext,
28669
28691
  'ɵɵnamespaceHTML': __namespaceHTML,
28670
28692
  'ɵɵnamespaceMathML': __namespaceMathML,
@@ -29395,7 +29417,6 @@ function compileComponent(type, metadata) {
29395
29417
  declarations: [],
29396
29418
  changeDetection: metadata.changeDetection,
29397
29419
  encapsulation,
29398
- interpolation: metadata.interpolation,
29399
29420
  viewProviders: metadata.viewProviders || null,
29400
29421
  // We can't inspect whether any of the dependencies are actually directives, because they
29401
29422
  // get patched on after compilation. That's why in JIT mode we consider that any
@@ -29917,180 +29938,6 @@ const COMPILER_OPTIONS = new InjectionToken(ngDevMode ? 'compilerOptions' : '');
29917
29938
  class CompilerFactory {
29918
29939
  }
29919
29940
 
29920
- class NgZoneChangeDetectionScheduler {
29921
- zone = inject(NgZone);
29922
- changeDetectionScheduler = inject(ChangeDetectionScheduler);
29923
- applicationRef = inject(ApplicationRef);
29924
- applicationErrorHandler = inject(INTERNAL_APPLICATION_ERROR_HANDLER);
29925
- _onMicrotaskEmptySubscription;
29926
- initialize() {
29927
- if (this._onMicrotaskEmptySubscription) {
29928
- return;
29929
- }
29930
- this._onMicrotaskEmptySubscription = this.zone.onMicrotaskEmpty.subscribe({
29931
- next: () => {
29932
- // `onMicroTaskEmpty` can happen _during_ the zoneless scheduler change detection because
29933
- // zone.run(() => {}) will result in `checkStable` at the end of the `zone.run` closure
29934
- // and emit `onMicrotaskEmpty` synchronously if run coalsecing is false.
29935
- if (this.changeDetectionScheduler.runningTick) {
29936
- return;
29937
- }
29938
- this.zone.run(() => {
29939
- try {
29940
- this.applicationRef.dirtyFlags |= 1 /* ApplicationRefDirtyFlags.ViewTreeGlobal */;
29941
- this.applicationRef._tick();
29942
- }
29943
- catch (e) {
29944
- this.applicationErrorHandler(e);
29945
- }
29946
- });
29947
- },
29948
- });
29949
- }
29950
- ngOnDestroy() {
29951
- this._onMicrotaskEmptySubscription?.unsubscribe();
29952
- }
29953
- static ɵfac = function NgZoneChangeDetectionScheduler_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || NgZoneChangeDetectionScheduler)(); };
29954
- static ɵprov = /*@__PURE__*/ __defineInjectable({ token: NgZoneChangeDetectionScheduler, factory: NgZoneChangeDetectionScheduler.ɵfac, providedIn: 'root' });
29955
- }
29956
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgZoneChangeDetectionScheduler, [{
29957
- type: Injectable,
29958
- args: [{ providedIn: 'root' }]
29959
- }], null, null); })();
29960
- /**
29961
- * Internal token used to verify that `provideZoneChangeDetection` is not used
29962
- * with the bootstrapModule API.
29963
- */
29964
- const PROVIDED_NG_ZONE = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'provideZoneChangeDetection token' : '', { factory: () => false });
29965
- function internalProvideZoneChangeDetection({ ngZoneFactory, scheduleInRootZone, }) {
29966
- ngZoneFactory ??= () => new NgZone({ ...getNgZoneOptions(), scheduleInRootZone });
29967
- return [
29968
- { provide: NgZone, useFactory: ngZoneFactory },
29969
- {
29970
- provide: ENVIRONMENT_INITIALIZER,
29971
- multi: true,
29972
- useFactory: () => {
29973
- const ngZoneChangeDetectionScheduler = inject(NgZoneChangeDetectionScheduler, {
29974
- optional: true,
29975
- });
29976
- if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
29977
- ngZoneChangeDetectionScheduler === null) {
29978
- throw new RuntimeError(402 /* RuntimeErrorCode.MISSING_REQUIRED_INJECTABLE_IN_BOOTSTRAP */, `A required Injectable was not found in the dependency injection tree. ` +
29979
- 'If you are bootstrapping an NgModule, make sure that the `BrowserModule` is imported.');
29980
- }
29981
- return () => ngZoneChangeDetectionScheduler.initialize();
29982
- },
29983
- },
29984
- {
29985
- provide: ENVIRONMENT_INITIALIZER,
29986
- multi: true,
29987
- useFactory: () => {
29988
- const service = inject(ZoneStablePendingTask);
29989
- return () => {
29990
- service.initialize();
29991
- };
29992
- },
29993
- },
29994
- {
29995
- provide: SCHEDULE_IN_ROOT_ZONE,
29996
- useValue: scheduleInRootZone ?? SCHEDULE_IN_ROOT_ZONE_DEFAULT,
29997
- },
29998
- ];
29999
- }
30000
- /**
30001
- * Provides `NgZone`-based change detection for the application bootstrapped using
30002
- * `bootstrapApplication`.
30003
- *
30004
- * `NgZone` is already provided in applications by default. This provider allows you to configure
30005
- * options like `eventCoalescing` in the `NgZone`.
30006
- * This provider is not available for `platformBrowser().bootstrapModule`, which uses
30007
- * `BootstrapOptions` instead.
30008
- *
30009
- * @usageNotes
30010
- * ```ts
30011
- * bootstrapApplication(MyApp, {providers: [
30012
- * provideZoneChangeDetection({eventCoalescing: true}),
30013
- * ]});
30014
- * ```
30015
- *
30016
- * @publicApi
30017
- * @see {@link /api/platform-browser/bootstrapApplication bootstrapApplication}
30018
- * @see {@link NgZoneOptions}
30019
- */
30020
- function provideZoneChangeDetection(options) {
30021
- const scheduleInRootZone = options?.scheduleInRootZone;
30022
- const zoneProviders = internalProvideZoneChangeDetection({
30023
- ngZoneFactory: () => {
30024
- const ngZoneOptions = getNgZoneOptions(options);
30025
- ngZoneOptions.scheduleInRootZone = scheduleInRootZone;
30026
- if (ngZoneOptions.shouldCoalesceEventChangeDetection) {
30027
- performanceMarkFeature('NgZone_CoalesceEvent');
30028
- }
30029
- return new NgZone(ngZoneOptions);
30030
- },
30031
- scheduleInRootZone,
30032
- });
30033
- return makeEnvironmentProviders([
30034
- { provide: PROVIDED_NG_ZONE, useValue: true },
30035
- { provide: ZONELESS_ENABLED, useValue: false },
30036
- zoneProviders,
30037
- ]);
30038
- }
30039
- // Transforms a set of `BootstrapOptions` (supported by the NgModule-based bootstrap APIs) ->
30040
- // `NgZoneOptions` that are recognized by the NgZone constructor. Passing no options will result in
30041
- // a set of default options returned.
30042
- function getNgZoneOptions(options) {
30043
- return {
30044
- enableLongStackTrace: typeof ngDevMode === 'undefined' ? false : !!ngDevMode,
30045
- shouldCoalesceEventChangeDetection: options?.eventCoalescing ?? false,
30046
- shouldCoalesceRunChangeDetection: options?.runCoalescing ?? false,
30047
- };
30048
- }
30049
- class ZoneStablePendingTask {
30050
- subscription = new Subscription();
30051
- initialized = false;
30052
- zone = inject(NgZone);
30053
- pendingTasks = inject(PendingTasksInternal);
30054
- initialize() {
30055
- if (this.initialized) {
30056
- return;
30057
- }
30058
- this.initialized = true;
30059
- let task = null;
30060
- if (!this.zone.isStable && !this.zone.hasPendingMacrotasks && !this.zone.hasPendingMicrotasks) {
30061
- task = this.pendingTasks.add();
30062
- }
30063
- this.zone.runOutsideAngular(() => {
30064
- this.subscription.add(this.zone.onStable.subscribe(() => {
30065
- NgZone.assertNotInAngularZone();
30066
- // Check whether there are no pending macro/micro tasks in the next tick
30067
- // to allow for NgZone to update the state.
30068
- queueMicrotask(() => {
30069
- if (task !== null &&
30070
- !this.zone.hasPendingMacrotasks &&
30071
- !this.zone.hasPendingMicrotasks) {
30072
- this.pendingTasks.remove(task);
30073
- task = null;
30074
- }
30075
- });
30076
- }));
30077
- });
30078
- this.subscription.add(this.zone.onUnstable.subscribe(() => {
30079
- NgZone.assertInAngularZone();
30080
- task ??= this.pendingTasks.add();
30081
- }));
30082
- }
30083
- ngOnDestroy() {
30084
- this.subscription.unsubscribe();
30085
- }
30086
- static ɵfac = function ZoneStablePendingTask_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ZoneStablePendingTask)(); };
30087
- static ɵprov = /*@__PURE__*/ __defineInjectable({ token: ZoneStablePendingTask, factory: ZoneStablePendingTask.ɵfac, providedIn: 'root' });
30088
- }
30089
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ZoneStablePendingTask, [{
30090
- type: Injectable,
30091
- args: [{ providedIn: 'root' }]
30092
- }], null, null); })();
30093
-
30094
29941
  const CONSECUTIVE_MICROTASK_NOTIFICATION_LIMIT = 100;
30095
29942
  let consecutiveMicrotaskNotifications = 0;
30096
29943
  let stackFromLastFewNotifications = [];
@@ -30115,7 +29962,6 @@ class ChangeDetectionSchedulerImpl {
30115
29962
  ngZone = inject(NgZone);
30116
29963
  zonelessEnabled = inject(ZONELESS_ENABLED);
30117
29964
  tracing = inject(TracingService, { optional: true });
30118
- disableScheduling = inject(ZONELESS_SCHEDULER_DISABLED, { optional: true }) ?? false;
30119
29965
  zoneIsDefined = typeof Zone !== 'undefined' && !!Zone.root.run;
30120
29966
  schedulerTickApplyArgs = [{ data: { '__scheduler_tick__': true } }];
30121
29967
  subscriptions = new Subscription();
@@ -30146,14 +29992,6 @@ class ChangeDetectionSchedulerImpl {
30146
29992
  this.cleanup();
30147
29993
  }
30148
29994
  }));
30149
- // TODO(atscott): These conditions will need to change when zoneless is the default
30150
- // Instead, they should flip to checking if ZoneJS scheduling is provided
30151
- this.disableScheduling ||=
30152
- !this.zonelessEnabled &&
30153
- // NoopNgZone without enabling zoneless means no scheduling whatsoever
30154
- (this.ngZone instanceof NoopNgZone ||
30155
- // The same goes for the lack of Zone without enabling zoneless scheduling
30156
- !this.zoneIsDefined);
30157
29995
  }
30158
29996
  notify(source) {
30159
29997
  if (!this.zonelessEnabled && source === 5 /* NotificationSource.Listener */) {
@@ -30167,7 +30005,6 @@ class ChangeDetectionSchedulerImpl {
30167
30005
  // to make listener callbacks work correctly with `OnPush` components.
30168
30006
  return;
30169
30007
  }
30170
- let force = false;
30171
30008
  switch (source) {
30172
30009
  case 0 /* NotificationSource.MarkAncestorsForTraversal */: {
30173
30010
  this.appRef.dirtyFlags |= 2 /* ApplicationRefDirtyFlags.ViewTreeTraversal */;
@@ -30186,34 +30023,19 @@ class ChangeDetectionSchedulerImpl {
30186
30023
  // during CD. In practice this is a no-op since the elements code also calls via a
30187
30024
  // `markForRefresh()` API which sends `NotificationSource.MarkAncestorsForTraversal` anyway.
30188
30025
  this.appRef.dirtyFlags |= 2 /* ApplicationRefDirtyFlags.ViewTreeTraversal */;
30189
- force = true;
30190
30026
  break;
30191
30027
  }
30192
30028
  case 12 /* NotificationSource.RootEffect */: {
30193
30029
  this.appRef.dirtyFlags |= 16 /* ApplicationRefDirtyFlags.RootEffects */;
30194
- // Root effects still force a CD, even if the scheduler is disabled. This ensures that
30195
- // effects always run, even when triggered from outside the zone when the scheduler is
30196
- // otherwise disabled.
30197
- force = true;
30198
30030
  break;
30199
30031
  }
30200
30032
  case 13 /* NotificationSource.ViewEffect */: {
30201
30033
  // This is technically a no-op, since view effects will also send a
30202
30034
  // `MarkAncestorsForTraversal` notification. Still, we set this for logical consistency.
30203
30035
  this.appRef.dirtyFlags |= 2 /* ApplicationRefDirtyFlags.ViewTreeTraversal */;
30204
- // View effects still force a CD, even if the scheduler is disabled. This ensures that
30205
- // effects always run, even when triggered from outside the zone when the scheduler is
30206
- // otherwise disabled.
30207
- force = true;
30208
30036
  break;
30209
30037
  }
30210
30038
  case 11 /* NotificationSource.PendingTaskRemoved */: {
30211
- // Removing a pending task via the public API forces a scheduled tick, ensuring that
30212
- // stability is async and delayed until there was at least an opportunity to run
30213
- // application synchronization. This prevents some footguns when working with the
30214
- // public API for pending tasks where developers attempt to update application state
30215
- // immediately after removing the last task.
30216
- force = true;
30217
30039
  break;
30218
30040
  }
30219
30041
  case 9 /* NotificationSource.ViewDetachedFromDOM */:
@@ -30231,7 +30053,7 @@ class ChangeDetectionSchedulerImpl {
30231
30053
  // notification so that the resulting CD run can be attributed to the
30232
30054
  // context which produced the notification.
30233
30055
  this.appRef.tracingSnapshot = this.tracing?.snapshot(this.appRef.tracingSnapshot) ?? null;
30234
- if (!this.shouldScheduleTick(force)) {
30056
+ if (!this.shouldScheduleTick()) {
30235
30057
  return;
30236
30058
  }
30237
30059
  if (typeof ngDevMode === 'undefined' || ngDevMode) {
@@ -30254,8 +30076,8 @@ class ChangeDetectionSchedulerImpl {
30254
30076
  this.cancelScheduledCallback = this.ngZone.runOutsideAngular(() => scheduleCallback(() => this.tick()));
30255
30077
  }
30256
30078
  }
30257
- shouldScheduleTick(force) {
30258
- if ((this.disableScheduling && !force) || this.appRef.destroyed) {
30079
+ shouldScheduleTick() {
30080
+ if (this.appRef.destroyed) {
30259
30081
  return false;
30260
30082
  }
30261
30083
  // already scheduled or running
@@ -30406,15 +30228,19 @@ function provideZonelessChangeDetection() {
30406
30228
  console.warn(message);
30407
30229
  }
30408
30230
  return makeEnvironmentProviders([
30409
- { provide: ChangeDetectionScheduler, useExisting: ChangeDetectionSchedulerImpl },
30410
- { provide: NgZone, useClass: NoopNgZone },
30411
- { provide: ZONELESS_ENABLED, useValue: true },
30412
- { provide: SCHEDULE_IN_ROOT_ZONE, useValue: false },
30231
+ ...provideZonelessChangeDetectionInternal(),
30413
30232
  typeof ngDevMode === 'undefined' || ngDevMode
30414
30233
  ? [{ provide: PROVIDED_ZONELESS, useValue: true }]
30415
30234
  : [],
30416
30235
  ]);
30417
30236
  }
30237
+ function provideZonelessChangeDetectionInternal() {
30238
+ return [
30239
+ { provide: ChangeDetectionScheduler, useExisting: ChangeDetectionSchedulerImpl },
30240
+ { provide: NgZone, useClass: NoopNgZone },
30241
+ { provide: ZONELESS_ENABLED, useValue: true },
30242
+ ];
30243
+ }
30418
30244
 
30419
30245
  /// <reference path="../../../goog.d.ts" />
30420
30246
  /**
@@ -31185,5 +31011,5 @@ function getDebugNode(nativeNode) {
31185
31011
  return null;
31186
31012
  }
31187
31013
 
31188
- export { AFTER_RENDER_PHASES, ANIMATIONS_DISABLED, ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, AcxChangeDetectionStrategy, AcxViewEncapsulation, AfterRenderImpl, AfterRenderManager, AfterRenderSequence, ApplicationInitStatus, ApplicationRef, Attribute, COMPILER_OPTIONS, CONTAINERS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionSchedulerImpl, ChangeDetectionStrategy, Compiler, CompilerFactory, Component, ComponentFactory, ComponentFactory$1, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ComponentRef as ComponentRef$1, Console, DEFAULT_CURRENCY_CODE, DEFAULT_LOCALE_ID, DEFER_BLOCK_CONFIG, DEFER_BLOCK_DEPENDENCY_INTERCEPTOR, DEFER_BLOCK_ID, DEFER_BLOCK_SSR_ID_ATTRIBUTE, DEFER_BLOCK_STATE$1 as DEFER_BLOCK_STATE, DEFER_BLOCK_STATE as DEFER_BLOCK_STATE$1, DEFER_HYDRATE_TRIGGERS, DEFER_PARENT_BLOCK_ID, DEHYDRATED_BLOCK_REGISTRY, DISCONNECTED_NODES, DebugElement, DebugEventListener, DebugNode, DeferBlockBehavior, DeferBlockState, DehydratedBlockRegistry, Directive, ELEMENT_CONTAINERS, EVENT_REPLAY_ENABLED_DEFAULT, ElementRef, ElementRegistry, EnvironmentNgModuleRefAdapter, Framework, Host, HostBinding, HostListener, HydrationStatus, I18N_DATA, IMAGE_CONFIG, IMAGE_CONFIG_DEFAULTS, IS_ENABLED_BLOCKING_INITIAL_NAVIGATION, IS_EVENT_REPLAY_ENABLED, IS_HYDRATION_DOM_REUSE_ENABLED, IS_I18N_HYDRATION_ENABLED, IS_INCREMENTAL_HYDRATION_ENABLED, Inject, Injectable, Input, JSACTION_BLOCK_ELEMENT_MAP, JSACTION_EVENT_CONTRACT, LContext, LOCALE_ID, LocaleDataIndex, MAX_ANIMATION_TIMEOUT, MULTIPLIER, MissingTranslationStrategy, ModuleWithComponentFactories, NGH_ATTR_NAME, NGH_DATA_KEY, NGH_DEFER_BLOCKS_KEY, NODES, NOOP_AFTER_RENDER_REF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE, NO_ERRORS_SCHEMA, NUM_ROOT_NODES, NgModule, NgModuleFactory, NgModuleFactory$1, NgModuleRef, NgModuleRef$1, Optional, Output, PLATFORM_ID, PLATFORM_INITIALIZER, PRESERVE_HOST_CONTENT, PROVIDED_NG_ZONE, Pipe, QueryList, ReflectionCapabilities, Renderer2, RendererFactory2, RendererStyleFlags2, SKIP_HYDRATION_ATTR_NAME, SSR_CONTENT_INTEGRITY_MARKER, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TEMPLATES, TEMPLATE_ID, TESTABILITY, TESTABILITY_GETTER, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TimerScheduler, TracingAction, TracingService, TransferState, Type, UseExhaustiveCheckNoChanges, ViewContainerRef, ViewEncapsulation, ViewRef, _sanitizeHtml, _sanitizeUrl, afterEveryRender, afterNextRender, allowSanitizationBypassAndThrow, angularCoreEnv, appendDeferBlocksToJSActionMap, asNativeElements, assertComponentDef, assertStandaloneComponentType, bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl, calcPathForNode, checkNoChangesInternal, cleanupDehydratedViews, clearResolutionOfComponentResourcesQueue, collectNativeNodes, collectNativeNodesInLContainer, compileComponent, compileDirective, compileNgModule, compileNgModuleDefs, compilePipe, convertHydrateTriggersToJsAction, countBlocksSkippedByHydration, createEnvironmentInjector, createMultiResultQuerySignalFn, createNgModule, createNgModuleRef, createNgModuleRefWithProviders, createSingleResultOptionalQuerySignalFn, createSingleResultRequiredQuerySignalFn, depsTracker, devModeEqual, enableApplyRootElementTransformImpl, enableClaimDehydratedIcuCaseImpl, enableFindMatchingDehydratedViewImpl, enableLocateOrCreateContainerAnchorImpl, enableLocateOrCreateContainerRefImpl, enableLocateOrCreateElementContainerNodeImpl, enableLocateOrCreateElementNodeImpl, enableLocateOrCreateI18nNodeImpl, enableLocateOrCreateTextNodeImpl, enablePrepareI18nBlockForHydrationImpl, enableProfiling, enableRetrieveDeferBlockDataImpl, enableRetrieveHydrationInfoImpl, enableStashEventListenerImpl, findLocaleData, flushModuleScopingQueueAsMuchAsPossible, gatherDeferBlocksCommentNodes, generateStandaloneInDeclarationsError, getAsyncClassMetadataFn, getCompilerFacade, getDebugNode, getDeferBlocks$1 as getDeferBlocks, getDirectives, getDocument, getHostElement, getLContext, getLDeferBlockDetails, getLNodeForHydration, getLocaleCurrencyCode, getLocalePluralCase, getNgZoneOptions, getOrComputeI18nChildren, getRegisteredNgModuleType, getSanitizationBypassType, getTDeferBlockDetails, getTransferState, inferTagNameFromDefinition, inputBinding, internalProvideZoneChangeDetection, invokeListeners, isBoundToModule, isComponentDefPendingResolution, isComponentResourceResolutionQueueEmpty, isDeferBlock, isDetachedByI18n, isDisconnectedNode, isI18nHydrationEnabled, isI18nHydrationSupportEnabled, isInSkipHydrationBlock, isIncrementalHydrationEnabled, isJsObject, isLetDeclaration, isListLikeIterable, isNgModule, isPromise, isSubscribable, isTNodeShape, isViewDirty, iterateListLike, makePropDecorator, makeStateKey, markForRefresh, noSideEffects, optionsReducer, outputBinding, patchComponentDefWithScope, performanceMarkFeature, processAndInitTriggers, processBlockData, processTextNodeBeforeSerialization, profiler, provideAppInitializer, provideNgReflectAttributes, provideZoneChangeDetection, provideZonelessChangeDetection, publishDefaultGlobalUtils, publishExternalGlobalUtil, publishSignalConfiguration, readHydrationInfo, readPatchedLView, registerLocaleData, registerNgModuleType, remove, removeListeners, renderDeferBlockState, resetCompiledComponents, resetJitOptions, resolveComponentResources, restoreComponentResolutionQueue, setAllowDuplicateNgModuleIdsForTest, setClassMetadata, setClassMetadataAsync, setDocument, setIsI18nHydrationSupportEnabled, setJSActionAttributes, setJitOptions, setLocaleId, setStashFn, setTestabilityGetter, sharedMapFunction, sharedStashFunction, transitiveScopesFor, triggerHydrationFromBlockName, triggerResourceLoading, trySerializeI18nBlock, twoWayBinding, unregisterAllLocaleData, unsupportedProjectionOfDomNodes, unwrapSafeValue, validateMatchingNode, validateNodeExists, verifySsrContentsIntegrity, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, ɵsetClassDebugInfo, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, ɵɵAnimationsFeature, ɵɵCopyDefinitionFeature, ɵɵExternalStylesFeature, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵadvance, ɵɵanimateEnter, ɵɵanimateEnterListener, ɵɵanimateLeave, ɵɵanimateLeaveListener, ɵɵariaProperty, ɵɵattachSourceLocations, ɵɵattribute, ɵɵclassMap, ɵɵclassProp, ɵɵcomponentInstance, ɵɵconditional, ɵɵconditionalBranchCreate, ɵɵconditionalCreate, ɵɵcontentQuery, ɵɵcontentQuerySignal, ɵɵdeclareLet, ɵɵdefer, ɵɵdeferEnableTimerScheduling, ɵɵdeferHydrateNever, ɵɵdeferHydrateOnHover, ɵɵdeferHydrateOnIdle, ɵɵdeferHydrateOnImmediate, ɵɵdeferHydrateOnInteraction, ɵɵdeferHydrateOnTimer, ɵɵdeferHydrateOnViewport, ɵɵdeferHydrateWhen, ɵɵdeferOnHover, ɵɵdeferOnIdle, ɵɵdeferOnImmediate, ɵɵdeferOnInteraction, ɵɵdeferOnTimer, ɵɵdeferOnViewport, ɵɵdeferPrefetchOnHover, ɵɵdeferPrefetchOnIdle, ɵɵdeferPrefetchOnImmediate, ɵɵdeferPrefetchOnInteraction, ɵɵdeferPrefetchOnTimer, ɵɵdeferPrefetchOnViewport, ɵɵdeferPrefetchWhen, ɵɵdeferWhen, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdomElement, ɵɵdomElementContainer, ɵɵdomElementContainerEnd, ɵɵdomElementContainerStart, ɵɵdomElementEnd, ɵɵdomElementStart, ɵɵdomListener, ɵɵdomProperty, ɵɵdomTemplate, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵgetComponentDepsFactory, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵgetReplaceMetadataURL, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinjectAttribute, ɵɵinterpolate, ɵɵinterpolate1, ɵɵinterpolate2, ɵɵinterpolate3, ɵɵinterpolate4, ɵɵinterpolate5, ɵɵinterpolate6, ɵɵinterpolate7, ɵɵinterpolate8, ɵɵinterpolateV, ɵɵinvalidFactory, ɵɵlistener, ɵɵloadQuery, ɵɵnextContext, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryAdvance, ɵɵqueryRefresh, ɵɵreadContextLet, ɵɵreference, ɵɵrepeater, ɵɵrepeaterCreate, ɵɵrepeaterTrackByIdentity, ɵɵrepeaterTrackByIndex, ɵɵreplaceMetadata, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstoreLet, ɵɵstyleMap, ɵɵstyleProp, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵtwoWayBindingSet, ɵɵtwoWayListener, ɵɵtwoWayProperty, ɵɵvalidateIframeAttribute, ɵɵviewQuery, ɵɵviewQuerySignal };
31014
+ export { AFTER_RENDER_PHASES, ANIMATIONS_DISABLED, ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, AcxChangeDetectionStrategy, AcxViewEncapsulation, AfterRenderImpl, AfterRenderManager, AfterRenderSequence, ApplicationInitStatus, ApplicationRef, Attribute, COMPILER_OPTIONS, CONTAINERS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionSchedulerImpl, ChangeDetectionStrategy, Compiler, CompilerFactory, Component, ComponentFactory, ComponentFactory$1, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ComponentRef as ComponentRef$1, Console, DEFAULT_CURRENCY_CODE, DEFAULT_LOCALE_ID, DEFER_BLOCK_CONFIG, DEFER_BLOCK_DEPENDENCY_INTERCEPTOR, DEFER_BLOCK_ID, DEFER_BLOCK_SSR_ID_ATTRIBUTE, DEFER_BLOCK_STATE$1 as DEFER_BLOCK_STATE, DEFER_BLOCK_STATE as DEFER_BLOCK_STATE$1, DEFER_HYDRATE_TRIGGERS, DEFER_PARENT_BLOCK_ID, DEHYDRATED_BLOCK_REGISTRY, DISCONNECTED_NODES, DebugElement, DebugEventListener, DebugNode, DeferBlockBehavior, DeferBlockState, DehydratedBlockRegistry, Directive, ELEMENT_CONTAINERS, EVENT_REPLAY_ENABLED_DEFAULT, ElementRef, EnvironmentNgModuleRefAdapter, Framework, Host, HostBinding, HostListener, HydrationStatus, I18N_DATA, IMAGE_CONFIG, IMAGE_CONFIG_DEFAULTS, IS_ENABLED_BLOCKING_INITIAL_NAVIGATION, IS_EVENT_REPLAY_ENABLED, IS_HYDRATION_DOM_REUSE_ENABLED, IS_I18N_HYDRATION_ENABLED, IS_INCREMENTAL_HYDRATION_ENABLED, Inject, Injectable, Input, JSACTION_BLOCK_ELEMENT_MAP, JSACTION_EVENT_CONTRACT, LContext, LOCALE_ID, LocaleDataIndex, MAX_ANIMATION_TIMEOUT, MULTIPLIER, MissingTranslationStrategy, ModuleWithComponentFactories, NGH_ATTR_NAME, NGH_DATA_KEY, NGH_DEFER_BLOCKS_KEY, NODES, NOOP_AFTER_RENDER_REF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE, NO_ERRORS_SCHEMA, NUM_ROOT_NODES, NgModule, NgModuleFactory, NgModuleFactory$1, NgModuleRef, NgModuleRef$1, Optional, Output, PLATFORM_ID, PLATFORM_INITIALIZER, PRESERVE_HOST_CONTENT, Pipe, QueryList, ReflectionCapabilities, Renderer2, RendererFactory2, RendererStyleFlags2, SKIP_HYDRATION_ATTR_NAME, SSR_CONTENT_INTEGRITY_MARKER, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TEMPLATES, TEMPLATE_ID, TESTABILITY, TESTABILITY_GETTER, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TimerScheduler, TracingAction, TracingService, TransferState, Type, UseExhaustiveCheckNoChanges, ViewContainerRef, ViewEncapsulation, ViewRef, _sanitizeHtml, _sanitizeUrl, afterEveryRender, afterNextRender, allLeavingAnimations, allowSanitizationBypassAndThrow, angularCoreEnv, appendDeferBlocksToJSActionMap, asNativeElements, assertComponentDef, assertStandaloneComponentType, bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl, calcPathForNode, checkNoChangesInternal, cleanupDehydratedViews, clearResolutionOfComponentResourcesQueue, collectNativeNodes, collectNativeNodesInLContainer, compileComponent, compileDirective, compileNgModule, compileNgModuleDefs, compilePipe, convertHydrateTriggersToJsAction, countBlocksSkippedByHydration, createEnvironmentInjector, createMultiResultQuerySignalFn, createNgModule, createNgModuleRef, createNgModuleRefWithProviders, createSingleResultOptionalQuerySignalFn, createSingleResultRequiredQuerySignalFn, depsTracker, devModeEqual, enableApplyRootElementTransformImpl, enableClaimDehydratedIcuCaseImpl, enableFindMatchingDehydratedViewImpl, enableLocateOrCreateContainerAnchorImpl, enableLocateOrCreateContainerRefImpl, enableLocateOrCreateElementContainerNodeImpl, enableLocateOrCreateElementNodeImpl, enableLocateOrCreateI18nNodeImpl, enableLocateOrCreateTextNodeImpl, enablePrepareI18nBlockForHydrationImpl, enableProfiling, enableRetrieveDeferBlockDataImpl, enableRetrieveHydrationInfoImpl, enableStashEventListenerImpl, findLocaleData, flushModuleScopingQueueAsMuchAsPossible, gatherDeferBlocksCommentNodes, generateStandaloneInDeclarationsError, getAsyncClassMetadataFn, getCompilerFacade, getDebugNode, getDeferBlocks$1 as getDeferBlocks, getDirectives, getDocument, getHostElement, getLContext, getLDeferBlockDetails, getLNodeForHydration, getLocaleCurrencyCode, getLocalePluralCase, getOrComputeI18nChildren, getRegisteredNgModuleType, getSanitizationBypassType, getTDeferBlockDetails, getTransferState, inferTagNameFromDefinition, inputBinding, invokeListeners, isBoundToModule, isComponentDefPendingResolution, isComponentResourceResolutionQueueEmpty, isDeferBlock, isDetachedByI18n, isDisconnectedNode, isI18nHydrationEnabled, isI18nHydrationSupportEnabled, isInSkipHydrationBlock, isIncrementalHydrationEnabled, isJsObject, isLetDeclaration, isListLikeIterable, isNgModule, isPromise, isSubscribable, isTNodeShape, isViewDirty, iterateListLike, makePropDecorator, makeStateKey, markForRefresh, noSideEffects, optionsReducer, outputBinding, patchComponentDefWithScope, performanceMarkFeature, processAndInitTriggers, processBlockData, processTextNodeBeforeSerialization, profiler, provideAppInitializer, provideNgReflectAttributes, provideZonelessChangeDetection, provideZonelessChangeDetectionInternal, publishDefaultGlobalUtils, publishExternalGlobalUtil, publishSignalConfiguration, readHydrationInfo, readPatchedLView, registerLocaleData, registerNgModuleType, remove, removeListeners, renderDeferBlockState, resetCompiledComponents, resetJitOptions, resolveComponentResources, restoreComponentResolutionQueue, setAllowDuplicateNgModuleIdsForTest, setClassMetadata, setClassMetadataAsync, setDocument, setIsI18nHydrationSupportEnabled, setJSActionAttributes, setJitOptions, setLocaleId, setStashFn, setTestabilityGetter, sharedMapFunction, sharedStashFunction, transitiveScopesFor, triggerHydrationFromBlockName, triggerResourceLoading, trySerializeI18nBlock, twoWayBinding, unregisterAllLocaleData, unsupportedProjectionOfDomNodes, unwrapSafeValue, validateMatchingNode, validateNodeExists, verifySsrContentsIntegrity, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, ɵsetClassDebugInfo, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, ɵɵCopyDefinitionFeature, ɵɵExternalStylesFeature, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵadvance, ɵɵanimateEnter, ɵɵanimateEnterListener, ɵɵanimateLeave, ɵɵanimateLeaveListener, ɵɵariaProperty, ɵɵattachSourceLocations, ɵɵattribute, ɵɵclassMap, ɵɵclassProp, ɵɵcomponentInstance, ɵɵconditional, ɵɵconditionalBranchCreate, ɵɵconditionalCreate, ɵɵcontentQuery, ɵɵcontentQuerySignal, ɵɵdeclareLet, ɵɵdefer, ɵɵdeferEnableTimerScheduling, ɵɵdeferHydrateNever, ɵɵdeferHydrateOnHover, ɵɵdeferHydrateOnIdle, ɵɵdeferHydrateOnImmediate, ɵɵdeferHydrateOnInteraction, ɵɵdeferHydrateOnTimer, ɵɵdeferHydrateOnViewport, ɵɵdeferHydrateWhen, ɵɵdeferOnHover, ɵɵdeferOnIdle, ɵɵdeferOnImmediate, ɵɵdeferOnInteraction, ɵɵdeferOnTimer, ɵɵdeferOnViewport, ɵɵdeferPrefetchOnHover, ɵɵdeferPrefetchOnIdle, ɵɵdeferPrefetchOnImmediate, ɵɵdeferPrefetchOnInteraction, ɵɵdeferPrefetchOnTimer, ɵɵdeferPrefetchOnViewport, ɵɵdeferPrefetchWhen, ɵɵdeferWhen, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdomElement, ɵɵdomElementContainer, ɵɵdomElementContainerEnd, ɵɵdomElementContainerStart, ɵɵdomElementEnd, ɵɵdomElementStart, ɵɵdomListener, ɵɵdomProperty, ɵɵdomTemplate, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵgetComponentDepsFactory, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵgetReplaceMetadataURL, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinjectAttribute, ɵɵinterpolate, ɵɵinterpolate1, ɵɵinterpolate2, ɵɵinterpolate3, ɵɵinterpolate4, ɵɵinterpolate5, ɵɵinterpolate6, ɵɵinterpolate7, ɵɵinterpolate8, ɵɵinterpolateV, ɵɵinvalidFactory, ɵɵlistener, ɵɵloadQuery, ɵɵnextContext, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryAdvance, ɵɵqueryRefresh, ɵɵreadContextLet, ɵɵreference, ɵɵrepeater, ɵɵrepeaterCreate, ɵɵrepeaterTrackByIdentity, ɵɵrepeaterTrackByIndex, ɵɵreplaceMetadata, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstoreLet, ɵɵstyleMap, ɵɵstyleProp, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵtwoWayBindingSet, ɵɵtwoWayListener, ɵɵtwoWayProperty, ɵɵvalidateIframeAttribute, ɵɵviewQuery, ɵɵviewQuerySignal };
31189
31015
  //# sourceMappingURL=debug_node.mjs.map