@angular/core 16.0.0-next.3 → 16.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 (59) hide show
  1. package/esm2020/src/application_tokens.mjs +33 -1
  2. package/esm2020/src/change_detection/change_detector_ref.mjs +4 -4
  3. package/esm2020/src/compiler/compiler_facade_interface.mjs +1 -1
  4. package/esm2020/src/core.mjs +2 -2
  5. package/esm2020/src/core_private_export.mjs +2 -1
  6. package/esm2020/src/core_reactivity_export_internal.mjs +1 -1
  7. package/esm2020/src/core_render3_private_export.mjs +1 -2
  8. package/esm2020/src/di/r3_injector.mjs +8 -1
  9. package/esm2020/src/errors.mjs +1 -1
  10. package/esm2020/src/hydration/annotate.mjs +118 -5
  11. package/esm2020/src/hydration/api.mjs +14 -1
  12. package/esm2020/src/hydration/cleanup.mjs +54 -3
  13. package/esm2020/src/hydration/compression.mjs +69 -0
  14. package/esm2020/src/hydration/error_handling.mjs +357 -15
  15. package/esm2020/src/hydration/interfaces.mjs +17 -1
  16. package/esm2020/src/hydration/node_lookup_utils.mjs +199 -7
  17. package/esm2020/src/hydration/utils.mjs +16 -3
  18. package/esm2020/src/hydration/views.mjs +19 -15
  19. package/esm2020/src/linker/destroy_ref.mjs +5 -2
  20. package/esm2020/src/linker/view_container_ref.mjs +8 -7
  21. package/esm2020/src/metadata/directives.mjs +8 -3
  22. package/esm2020/src/render3/instructions/element.mjs +16 -9
  23. package/esm2020/src/render3/instructions/element_container.mjs +2 -5
  24. package/esm2020/src/render3/instructions/element_validation.mjs +2 -2
  25. package/esm2020/src/render3/instructions/projection.mjs +7 -4
  26. package/esm2020/src/render3/instructions/template.mjs +4 -7
  27. package/esm2020/src/render3/instructions/text.mjs +6 -6
  28. package/esm2020/src/render3/interfaces/public_definitions.mjs +1 -1
  29. package/esm2020/src/render3/interfaces/type_checks.mjs +4 -1
  30. package/esm2020/src/render3/node_manipulation.mjs +2 -2
  31. package/esm2020/src/render3/node_selector_matcher.mjs +17 -5
  32. package/esm2020/src/render3/util/view_utils.mjs +12 -1
  33. package/esm2020/src/render3/view_ref.mjs +1 -1
  34. package/esm2020/src/signals/index.mjs +2 -1
  35. package/esm2020/src/signals/src/computed.mjs +3 -3
  36. package/esm2020/src/signals/src/effect.mjs +1 -3
  37. package/esm2020/src/signals/src/signal.mjs +3 -3
  38. package/esm2020/src/signals/src/watch.mjs +3 -3
  39. package/esm2020/src/signals/src/weak_ref.mjs +18 -2
  40. package/esm2020/src/util/ng_dev_mode.mjs +2 -1
  41. package/esm2020/src/version.mjs +1 -1
  42. package/esm2020/testing/src/logger.mjs +3 -3
  43. package/esm2020/testing/src/ng_zone_mock.mjs +3 -3
  44. package/esm2020/testing/src/test_bed_compiler.mjs +12 -7
  45. package/fesm2015/core.mjs +1066 -178
  46. package/fesm2015/core.mjs.map +1 -1
  47. package/fesm2015/testing.mjs +816 -68
  48. package/fesm2015/testing.mjs.map +1 -1
  49. package/fesm2020/core.mjs +1051 -170
  50. package/fesm2020/core.mjs.map +1 -1
  51. package/fesm2020/testing.mjs +810 -67
  52. package/fesm2020/testing.mjs.map +1 -1
  53. package/index.d.ts +128 -216
  54. package/package.json +1 -1
  55. package/schematics/migrations/relative-link-resolution/bundle.js +7 -7
  56. package/schematics/migrations/router-link-with-href/bundle.js +10 -10
  57. package/schematics/ng-generate/standalone-migration/bundle.js +473 -376
  58. package/schematics/ng-generate/standalone-migration/bundle.js.map +2 -2
  59. package/testing/index.d.ts +1 -1
package/fesm2015/core.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * @license Angular v16.0.0-next.3
2
+ * @license Angular v16.0.0-next.4
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
6
6
 
7
7
  import { Subject, Subscription, Observable, merge as merge$1 } from 'rxjs';
8
- import { share } from 'rxjs/operators';
8
+ import { first, share } from 'rxjs/operators';
9
9
 
10
10
  function getClosureSafeProperty(objWithPropertyToExtract) {
11
11
  for (let key in objWithPropertyToExtract) {
@@ -558,6 +558,7 @@ function ngDevModeResetPerfCounters() {
558
558
  hydratedNodes: 0,
559
559
  hydratedComponents: 0,
560
560
  dehydratedViewsRemoved: 0,
561
+ dehydratedViewsCleanupRuns: 0,
561
562
  };
562
563
  // Make sure to refer to ngDevMode as ['ngDevMode'] for closure.
563
564
  const allowNgDevModeTrue = locationString.indexOf('ngDevMode=false') === -1;
@@ -1187,12 +1188,19 @@ function isCssClassMatching(attrs, cssClassToMatch, isProjectionMode) {
1187
1188
  ngDevMode &&
1188
1189
  assertEqual(cssClassToMatch, cssClassToMatch.toLowerCase(), 'Class name expected to be lowercase.');
1189
1190
  let i = 0;
1191
+ // Indicates whether we are processing value from the implicit
1192
+ // attribute section (i.e. before the first marker in the array).
1193
+ let isImplicitAttrsSection = true;
1190
1194
  while (i < attrs.length) {
1191
1195
  let item = attrs[i++];
1192
- if (isProjectionMode && item === 'class') {
1193
- item = attrs[i];
1194
- if (classIndexOf(item.toLowerCase(), cssClassToMatch, 0) !== -1) {
1195
- return true;
1196
+ if (typeof item === 'string' && isImplicitAttrsSection) {
1197
+ const value = attrs[i++];
1198
+ if (isProjectionMode && item === 'class') {
1199
+ // We found a `class` attribute in the implicit attribute section,
1200
+ // check if it matches the value of the `cssClassToMatch` argument.
1201
+ if (classIndexOf(value.toLowerCase(), cssClassToMatch, 0) !== -1) {
1202
+ return true;
1203
+ }
1196
1204
  }
1197
1205
  }
1198
1206
  else if (item === 1 /* AttributeMarker.Classes */) {
@@ -1204,6 +1212,11 @@ function isCssClassMatching(attrs, cssClassToMatch, isProjectionMode) {
1204
1212
  }
1205
1213
  return false;
1206
1214
  }
1215
+ else if (typeof item === 'number') {
1216
+ // We've came across a first marker, which indicates
1217
+ // that the implicit attribute section is over.
1218
+ isImplicitAttrsSection = false;
1219
+ }
1207
1220
  }
1208
1221
  return false;
1209
1222
  }
@@ -2020,6 +2033,9 @@ function isComponentDef(def) {
2020
2033
  function isRootView(target) {
2021
2034
  return (target[FLAGS] & 256 /* LViewFlags.IsRoot */) !== 0;
2022
2035
  }
2036
+ function isProjectionTNode(tNode) {
2037
+ return (tNode.type & 16 /* TNodeType.Projection */) === 16 /* TNodeType.Projection */;
2038
+ }
2023
2039
 
2024
2040
  // [Assert functions do not constraint type when they are guarded by a truthy
2025
2041
  // expression.](https://github.com/microsoft/TypeScript/issues/37295)
@@ -2433,6 +2449,17 @@ function storeLViewOnDestroy(lView, onDestroyCallback) {
2433
2449
  }
2434
2450
  lView[ON_DESTROY_HOOKS].push(onDestroyCallback);
2435
2451
  }
2452
+ /**
2453
+ * Removes previously registered LView-specific destroy callback.
2454
+ */
2455
+ function removeLViewOnDestroy(lView, onDestroyCallback) {
2456
+ if (lView[ON_DESTROY_HOOKS] === null)
2457
+ return;
2458
+ const destroyCBIdx = lView[ON_DESTROY_HOOKS].indexOf(onDestroyCallback);
2459
+ if (destroyCBIdx !== -1) {
2460
+ lView[ON_DESTROY_HOOKS].splice(destroyCBIdx, 1);
2461
+ }
2462
+ }
2436
2463
 
2437
2464
  const instructionState = {
2438
2465
  lFrame: createLFrame(null),
@@ -8422,6 +8449,7 @@ class R3Injector extends EnvironmentInjector {
8422
8449
  }
8423
8450
  onDestroy(callback) {
8424
8451
  this._onDestroyHooks.push(callback);
8452
+ return () => this.removeOnDestroy(callback);
8425
8453
  }
8426
8454
  runInContext(fn) {
8427
8455
  this.assertNotDestroyed();
@@ -8596,6 +8624,12 @@ class R3Injector extends EnvironmentInjector {
8596
8624
  return this.injectorDefTypes.has(providedIn);
8597
8625
  }
8598
8626
  }
8627
+ removeOnDestroy(callback) {
8628
+ const destroyCBIdx = this._onDestroyHooks.indexOf(callback);
8629
+ if (destroyCBIdx !== -1) {
8630
+ this._onDestroyHooks.splice(destroyCBIdx, 1);
8631
+ }
8632
+ }
8599
8633
  }
8600
8634
  function injectableDefOrInjectorDefFactory(token) {
8601
8635
  // Most tokens will have an injectable def directly on them, which specifies a factory directly.
@@ -8781,6 +8815,38 @@ const PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');
8781
8815
  * @publicApi
8782
8816
  */
8783
8817
  const ANIMATION_MODULE_TYPE = new InjectionToken('AnimationModuleType');
8818
+ // TODO(crisbeto): link to CSP guide here.
8819
+ /**
8820
+ * Token used to configure the [Content Security Policy](https://web.dev/strict-csp/) nonce that
8821
+ * Angular will apply when inserting inline styles. If not provided, Angular will look up its value
8822
+ * from the `ngCspNonce` attribute of the application root node.
8823
+ *
8824
+ * @publicApi
8825
+ */
8826
+ const CSP_NONCE = new InjectionToken('CSP nonce', {
8827
+ providedIn: 'root',
8828
+ factory: () => {
8829
+ var _a;
8830
+ // Ideally we wouldn't have to use `querySelector` here since we know that the nonce will be on
8831
+ // the root node, but because the token value is used in renderers, it has to be available
8832
+ // *very* early in the bootstrapping process. This should be a fairly shallow search, because
8833
+ // the app won't have been added to the DOM yet. Some approaches that were considered:
8834
+ // 1. Find the root node through `ApplicationRef.components[i].location` - normally this would
8835
+ // be enough for our purposes, but the token is injected very early so the `components` array
8836
+ // isn't populated yet.
8837
+ // 2. Find the root `LView` through the current `LView` - renderers are a prerequisite to
8838
+ // creating the `LView`. This means that no `LView` will have been entered when this factory is
8839
+ // invoked for the root component.
8840
+ // 3. Have the token factory return `() => string` which is invoked when a nonce is requested -
8841
+ // the slightly later execution does allow us to get an `LView` reference, but the fact that
8842
+ // it is a function means that it could be executed at *any* time (including immediately) which
8843
+ // may lead to weird bugs.
8844
+ // 4. Have the `ComponentFactory` read the attribute and provide it to the injector under the
8845
+ // hood - has the same problem as #1 and #2 in that the renderer is used to query for the root
8846
+ // node and the nonce value needs to be available when the renderer is created.
8847
+ return ((_a = getDocument().body.querySelector('[ngCspNonce]')) === null || _a === void 0 ? void 0 : _a.getAttribute('ngCspNonce')) || null;
8848
+ },
8849
+ });
8784
8850
 
8785
8851
  function escapeTransferStateContent(text) {
8786
8852
  const escapedText = {
@@ -8923,6 +8989,19 @@ function retrieveTransferredState(doc, appId) {
8923
8989
  return initialState;
8924
8990
  }
8925
8991
 
8992
+ /** Encodes that the node lookup should start from the host node of this component. */
8993
+ const REFERENCE_NODE_HOST = 'h';
8994
+ /** Encodes that the node lookup should start from the document body node. */
8995
+ const REFERENCE_NODE_BODY = 'b';
8996
+ /**
8997
+ * Describes navigation steps that the runtime logic need to perform,
8998
+ * starting from a given (known) element.
8999
+ */
9000
+ var NodeNavigationStep;
9001
+ (function (NodeNavigationStep) {
9002
+ NodeNavigationStep["FirstChild"] = "f";
9003
+ NodeNavigationStep["NextSibling"] = "n";
9004
+ })(NodeNavigationStep || (NodeNavigationStep = {}));
8926
9005
  /**
8927
9006
  * Keys within serialized view data structure to represent various
8928
9007
  * parts. See the `SerializedView` interface below for additional information.
@@ -8930,8 +9009,11 @@ function retrieveTransferredState(doc, appId) {
8930
9009
  const ELEMENT_CONTAINERS = 'e';
8931
9010
  const TEMPLATES = 't';
8932
9011
  const CONTAINERS = 'c';
9012
+ const MULTIPLIER = 'x';
8933
9013
  const NUM_ROOT_NODES = 'r';
8934
9014
  const TEMPLATE_ID = 'i'; // as it's also an "id"
9015
+ const NODES = 'n';
9016
+ const DISCONNECTED_NODES = 'd';
8935
9017
 
8936
9018
  /**
8937
9019
  * The name of the key used in the TransferState collection,
@@ -9124,14 +9206,28 @@ function getSerializedContainerViews(hydrationInfo, index) {
9124
9206
  * by calculating the sum of root nodes in all dehydrated views in this container.
9125
9207
  */
9126
9208
  function calcSerializedContainerSize(hydrationInfo, index) {
9127
- var _a;
9209
+ var _a, _b;
9128
9210
  const views = (_a = getSerializedContainerViews(hydrationInfo, index)) !== null && _a !== void 0 ? _a : [];
9129
9211
  let numNodes = 0;
9130
9212
  for (let view of views) {
9131
- numNodes += view[NUM_ROOT_NODES];
9213
+ numNodes += view[NUM_ROOT_NODES] * ((_b = view[MULTIPLIER]) !== null && _b !== void 0 ? _b : 1);
9132
9214
  }
9133
9215
  return numNodes;
9134
9216
  }
9217
+ /**
9218
+ * Checks whether a node is annotated as "disconnected", i.e. not present
9219
+ * in the DOM at serialization time. We should not attempt hydration for
9220
+ * such nodes and instead, use a regular "creation mode".
9221
+ */
9222
+ function isDisconnectedNode(hydrationInfo, index) {
9223
+ var _a;
9224
+ // Check if we are processing disconnected info for the first time.
9225
+ if (typeof hydrationInfo.disconnectedNodes === 'undefined') {
9226
+ const nodeIds = hydrationInfo.data[DISCONNECTED_NODES];
9227
+ hydrationInfo.disconnectedNodes = nodeIds ? (new Set(nodeIds)) : null;
9228
+ }
9229
+ return !!((_a = hydrationInfo.disconnectedNodes) === null || _a === void 0 ? void 0 : _a.has(index));
9230
+ }
9135
9231
 
9136
9232
  /**
9137
9233
  * Represents a component created by a `ComponentFactory`.
@@ -9312,7 +9408,7 @@ class Version {
9312
9408
  /**
9313
9409
  * @publicApi
9314
9410
  */
9315
- const VERSION = new Version('16.0.0-next.3');
9411
+ const VERSION = new Version('16.0.0-next.4');
9316
9412
 
9317
9413
  // This default value is when checking the hierarchy for a token.
9318
9414
  //
@@ -14054,41 +14150,446 @@ function detectChanges(component) {
14054
14150
  detectChangesInternal(view[TVIEW], view, component);
14055
14151
  }
14056
14152
 
14153
+ const AT_THIS_LOCATION = '<-- AT THIS LOCATION';
14057
14154
  /**
14058
- * Verifies whether a given node matches an expected criteria,
14059
- * based on internal data structure state.
14155
+ * Retrieves a user friendly string for a given TNodeType for use in
14156
+ * friendly error messages
14157
+ *
14158
+ * @param tNodeType
14159
+ * @returns
14060
14160
  */
14061
- function validateMatchingNode(node, nodeType, tagName, lView, tNode) {
14062
- validateNodeExists(node);
14063
- if (node.nodeType !== nodeType ||
14064
- node.nodeType === Node.ELEMENT_NODE &&
14065
- node.tagName.toLowerCase() !== (tagName === null || tagName === void 0 ? void 0 : tagName.toLowerCase())) {
14066
- // TODO: improve error message and use RuntimeError instead.
14067
- throw new Error(`Unexpected node found during hydration.`);
14161
+ function getFriendlyStringFromTNodeType(tNodeType) {
14162
+ switch (tNodeType) {
14163
+ case 4 /* TNodeType.Container */:
14164
+ return 'view container';
14165
+ case 2 /* TNodeType.Element */:
14166
+ return 'element';
14167
+ case 8 /* TNodeType.ElementContainer */:
14168
+ return 'ng-container';
14169
+ case 32 /* TNodeType.Icu */:
14170
+ return 'icu';
14171
+ case 64 /* TNodeType.Placeholder */:
14172
+ return 'i18n';
14173
+ case 16 /* TNodeType.Projection */:
14174
+ return 'projection';
14175
+ case 1 /* TNodeType.Text */:
14176
+ return 'text';
14177
+ default:
14178
+ // This should not happen as we cover all possible TNode types above.
14179
+ return '<unknown>';
14180
+ }
14181
+ }
14182
+ /**
14183
+ * Validates that provided nodes match during the hydration process.
14184
+ */
14185
+ function validateMatchingNode(node, nodeType, tagName, lView, tNode, isViewContainerAnchor = false) {
14186
+ var _a, _b, _c;
14187
+ if (!node ||
14188
+ (node.nodeType !== nodeType ||
14189
+ (node.nodeType === Node.ELEMENT_NODE &&
14190
+ node.tagName.toLowerCase() !== (tagName === null || tagName === void 0 ? void 0 : tagName.toLowerCase())))) {
14191
+ const expectedNode = shortRNodeDescription(nodeType, tagName, null);
14192
+ let header = `During hydration Angular expected ${expectedNode} but `;
14193
+ const hostComponentDef = getDeclarationComponentDef(lView);
14194
+ const componentClassName = (_a = hostComponentDef === null || hostComponentDef === void 0 ? void 0 : hostComponentDef.type) === null || _a === void 0 ? void 0 : _a.name;
14195
+ const expected = `Angular expected this DOM:\n\n${describeExpectedDom(lView, tNode, isViewContainerAnchor)}\n\n`;
14196
+ let actual = '';
14197
+ if (!node) {
14198
+ // No node found during hydration.
14199
+ header += `the node was not found.\n\n`;
14200
+ }
14201
+ else {
14202
+ const actualNode = shortRNodeDescription(node.nodeType, (_b = node.tagName) !== null && _b !== void 0 ? _b : null, (_c = node.textContent) !== null && _c !== void 0 ? _c : null);
14203
+ header += `found ${actualNode}.\n\n`;
14204
+ actual = `Actual DOM is:\n\n${describeDomFromNode(node)}\n\n`;
14205
+ }
14206
+ const footer = getHydrationErrorFooter(componentClassName);
14207
+ const message = header + expected + actual + getHydrationAttributeNote() + footer;
14208
+ throw new RuntimeError(500 /* RuntimeErrorCode.HYDRATION_NODE_MISMATCH */, message);
14068
14209
  }
14069
14210
  }
14070
14211
  /**
14071
- * Verifies whether next sibling node exists.
14212
+ * Validates that a given node has sibling nodes
14072
14213
  */
14073
14214
  function validateSiblingNodeExists(node) {
14074
14215
  validateNodeExists(node);
14075
14216
  if (!node.nextSibling) {
14076
- // TODO: improve error message and use RuntimeError instead.
14077
- throw new Error(`Unexpected state: insufficient number of sibling nodes.`);
14217
+ const header = 'During hydration Angular expected more sibling nodes to be present.\n\n';
14218
+ const actual = `Actual DOM is:\n\n${describeDomFromNode(node)}\n\n`;
14219
+ const footer = getHydrationErrorFooter();
14220
+ const message = header + actual + footer;
14221
+ throw new RuntimeError(501 /* RuntimeErrorCode.HYDRATION_MISSING_SIBLINGS */, message);
14078
14222
  }
14079
14223
  }
14224
+ /**
14225
+ * Validates that a node exists or throws
14226
+ */
14080
14227
  function validateNodeExists(node) {
14081
14228
  if (!node) {
14082
- // TODO: improve error message and use RuntimeError instead.
14083
- throw new Error(`Hydration expected an element to be present at this location.`);
14229
+ throw new RuntimeError(502 /* RuntimeErrorCode.HYDRATION_MISSING_NODE */, `Hydration expected an element to be present at this location.`);
14230
+ }
14231
+ }
14232
+ /**
14233
+ * Builds the hydration error message when a node is not found
14234
+ *
14235
+ * @param lView the LView where the node exists
14236
+ * @param tNode the TNode
14237
+ */
14238
+ function nodeNotFoundError(lView, tNode) {
14239
+ const header = 'During serialization, Angular was unable to find an element in the DOM:\n\n';
14240
+ const expected = `${describeExpectedDom(lView, tNode, false)}\n\n`;
14241
+ const footer = getHydrationErrorFooter();
14242
+ throw new RuntimeError(502 /* RuntimeErrorCode.HYDRATION_MISSING_NODE */, header + expected + footer);
14243
+ }
14244
+ /**
14245
+ * Builds a hydration error message when a node is not found at a path location
14246
+ *
14247
+ * @param host the Host Node
14248
+ * @param path the path to the node
14249
+ */
14250
+ function nodeNotFoundAtPathError(host, path) {
14251
+ const header = `During hydration Angular was unable to locate a node ` +
14252
+ `using the "${path}" path, starting from the ${describeRNode(host)} node.\n\n`;
14253
+ const footer = getHydrationErrorFooter();
14254
+ throw new RuntimeError(502 /* RuntimeErrorCode.HYDRATION_MISSING_NODE */, header + footer);
14255
+ }
14256
+ /**
14257
+ * Builds the hydration error message in the case that dom nodes are created outside of
14258
+ * the Angular context and are being used as projected nodes
14259
+ *
14260
+ * @param lView the LView
14261
+ * @param tNode the TNode
14262
+ * @returns an error
14263
+ */
14264
+ function unsupportedProjectionOfDomNodes(rNode) {
14265
+ const header = 'During serialization, Angular detected DOM nodes ' +
14266
+ 'that were created outside of Angular context and provided as projectable nodes ' +
14267
+ '(likely via `ViewContainerRef.createComponent` or `createComponent` APIs). ' +
14268
+ 'Hydration is not supported for such cases, consider refactoring the code to avoid ' +
14269
+ 'this pattern or using `ngSkipHydration` on the host element of the component.\n\n';
14270
+ const actual = `${describeDomFromNode(rNode)}\n\n`;
14271
+ const message = header + actual + getHydrationAttributeNote();
14272
+ return new RuntimeError(503 /* RuntimeErrorCode.UNSUPPORTED_PROJECTION_DOM_NODES */, message);
14273
+ }
14274
+ /**
14275
+ * Builds the hydration error message in the case that ngSkipHydration was used on a
14276
+ * node that is not a component host element or host binding
14277
+ *
14278
+ * @param rNode the HTML Element
14279
+ * @returns an error
14280
+ */
14281
+ function invalidSkipHydrationHost(rNode) {
14282
+ const header = 'The `ngSkipHydration` flag is applied on a node ' +
14283
+ 'that doesn\'t act as a component host. Hydration can be ' +
14284
+ 'skipped only on per-component basis.\n\n';
14285
+ const actual = `${describeDomFromNode(rNode)}\n\n`;
14286
+ const footer = 'Please move the `ngSkipHydration` attribute to the component host element.';
14287
+ const message = header + actual + footer;
14288
+ return new RuntimeError(504 /* RuntimeErrorCode.INVALID_SKIP_HYDRATION_HOST */, message);
14289
+ }
14290
+ /**
14291
+ * Builds the hydration error message in the case that a user is attempting to enable
14292
+ * hydration on internationalized nodes, which is not yet supported.
14293
+ *
14294
+ * @param rNode the HTML Element
14295
+ * @returns an error
14296
+ */
14297
+ function notYetSupportedI18nBlockError(rNode) {
14298
+ const header = 'Hydration for nodes marked with `i18n` is not yet supported. ' +
14299
+ 'You can opt-out a component that uses `i18n` in a template using ' +
14300
+ 'the `ngSkipHydration` attribute or fall back to the previous ' +
14301
+ 'hydration logic (which re-creates the application structure).\n\n';
14302
+ const actual = `${describeDomFromNode(rNode)}\n\n`;
14303
+ const message = header + actual;
14304
+ return new RuntimeError(518 /* RuntimeErrorCode.HYDRATION_I18N_NOT_YET_SUPPORTED */, message);
14305
+ }
14306
+ // Stringification methods
14307
+ /**
14308
+ * Stringifies a given TNode's attributes
14309
+ *
14310
+ * @param tNode a provided TNode
14311
+ * @returns string
14312
+ */
14313
+ function stringifyTNodeAttrs(tNode) {
14314
+ const results = [];
14315
+ if (tNode.attrs) {
14316
+ for (let i = 0; i < tNode.attrs.length;) {
14317
+ const attrName = tNode.attrs[i++];
14318
+ // Once we reach the first flag, we know that the list of
14319
+ // attributes is over.
14320
+ if (typeof attrName == 'number') {
14321
+ break;
14322
+ }
14323
+ const attrValue = tNode.attrs[i++];
14324
+ results.push(`${attrName}="${shorten(attrValue)}"`);
14325
+ }
14326
+ }
14327
+ return results.join(' ');
14328
+ }
14329
+ /**
14330
+ * The list of internal attributes that should be filtered out while
14331
+ * producing an error message.
14332
+ */
14333
+ const internalAttrs = new Set(['ngh', 'ng-version', 'ng-server-context']);
14334
+ /**
14335
+ * Stringifies an HTML Element's attributes
14336
+ *
14337
+ * @param rNode an HTML Element
14338
+ * @returns string
14339
+ */
14340
+ function stringifyRNodeAttrs(rNode) {
14341
+ const results = [];
14342
+ for (let i = 0; i < rNode.attributes.length; i++) {
14343
+ const attr = rNode.attributes[i];
14344
+ if (internalAttrs.has(attr.name))
14345
+ continue;
14346
+ results.push(`${attr.name}="${shorten(attr.value)}"`);
14347
+ }
14348
+ return results.join(' ');
14349
+ }
14350
+ // Methods for Describing the DOM
14351
+ /**
14352
+ * Converts a tNode to a helpful readable string value for use in error messages
14353
+ *
14354
+ * @param tNode a given TNode
14355
+ * @param innerContent the content of the node
14356
+ * @returns string
14357
+ */
14358
+ function describeTNode(tNode, innerContent = '…') {
14359
+ switch (tNode.type) {
14360
+ case 1 /* TNodeType.Text */:
14361
+ const content = tNode.value ? `(${tNode.value})` : '';
14362
+ return `#text${content}`;
14363
+ case 2 /* TNodeType.Element */:
14364
+ const attrs = stringifyTNodeAttrs(tNode);
14365
+ const tag = tNode.value.toLowerCase();
14366
+ return `<${tag}${attrs ? ' ' + attrs : ''}>${innerContent}</${tag}>`;
14367
+ case 8 /* TNodeType.ElementContainer */:
14368
+ return '<!-- ng-container -->';
14369
+ case 4 /* TNodeType.Container */:
14370
+ return '<!-- container -->';
14371
+ default:
14372
+ const typeAsString = getFriendlyStringFromTNodeType(tNode.type);
14373
+ return `#node(${typeAsString})`;
14084
14374
  }
14085
14375
  }
14376
+ /**
14377
+ * Converts an RNode to a helpful readable string value for use in error messages
14378
+ *
14379
+ * @param rNode a given RNode
14380
+ * @param innerContent the content of the node
14381
+ * @returns string
14382
+ */
14383
+ function describeRNode(rNode, innerContent = '…') {
14384
+ var _a;
14385
+ const node = rNode;
14386
+ switch (node.nodeType) {
14387
+ case Node.ELEMENT_NODE:
14388
+ const tag = node.tagName.toLowerCase();
14389
+ const attrs = stringifyRNodeAttrs(node);
14390
+ return `<${tag}${attrs ? ' ' + attrs : ''}>${innerContent}</${tag}>`;
14391
+ case Node.TEXT_NODE:
14392
+ const content = node.textContent ? shorten(node.textContent) : '';
14393
+ return `#text${content ? `(${content})` : ''}`;
14394
+ case Node.COMMENT_NODE:
14395
+ return `<!-- ${shorten((_a = node.textContent) !== null && _a !== void 0 ? _a : '')} -->`;
14396
+ default:
14397
+ return `#node(${node.nodeType})`;
14398
+ }
14399
+ }
14400
+ /**
14401
+ * Builds the string containing the expected DOM present given the LView and TNode
14402
+ * values for a readable error message
14403
+ *
14404
+ * @param lView the lView containing the DOM
14405
+ * @param tNode the tNode
14406
+ * @param isViewContainerAnchor boolean
14407
+ * @returns string
14408
+ */
14409
+ function describeExpectedDom(lView, tNode, isViewContainerAnchor) {
14410
+ const spacer = ' ';
14411
+ let content = '';
14412
+ if (tNode.prev) {
14413
+ content += spacer + '…\n';
14414
+ content += spacer + describeTNode(tNode.prev) + '\n';
14415
+ }
14416
+ else if (tNode.type && tNode.type & 12 /* TNodeType.AnyContainer */) {
14417
+ content += spacer + '…\n';
14418
+ }
14419
+ if (isViewContainerAnchor) {
14420
+ content += spacer + describeTNode(tNode) + '\n';
14421
+ content += spacer + `<!-- container --> ${AT_THIS_LOCATION}\n`;
14422
+ }
14423
+ else {
14424
+ content += spacer + describeTNode(tNode) + ` ${AT_THIS_LOCATION}\n`;
14425
+ }
14426
+ content += spacer + '…\n';
14427
+ const parentRNode = tNode.type ? getParentRElement(lView[TVIEW], tNode, lView) : null;
14428
+ if (parentRNode) {
14429
+ content = describeRNode(parentRNode, '\n' + content);
14430
+ }
14431
+ return content;
14432
+ }
14433
+ /**
14434
+ * Builds the string containing the DOM present around a given RNode for a
14435
+ * readable error message
14436
+ *
14437
+ * @param node the RNode
14438
+ * @returns string
14439
+ */
14440
+ function describeDomFromNode(node) {
14441
+ const spacer = ' ';
14442
+ let content = '';
14443
+ const currentNode = node;
14444
+ if (currentNode.previousSibling) {
14445
+ content += spacer + '…\n';
14446
+ content += spacer + describeRNode(currentNode.previousSibling) + '\n';
14447
+ }
14448
+ content += spacer + describeRNode(currentNode) + ` ${AT_THIS_LOCATION}\n`;
14449
+ if (node.nextSibling) {
14450
+ content += spacer + '…\n';
14451
+ }
14452
+ if (node.parentNode) {
14453
+ content = describeRNode(currentNode.parentNode, '\n' + content);
14454
+ }
14455
+ return content;
14456
+ }
14457
+ /**
14458
+ * Shortens the description of a given RNode by its type for readability
14459
+ *
14460
+ * @param nodeType the type of node
14461
+ * @param tagName the node tag name
14462
+ * @param textContent the text content in the node
14463
+ * @returns string
14464
+ */
14465
+ function shortRNodeDescription(nodeType, tagName, textContent) {
14466
+ switch (nodeType) {
14467
+ case Node.ELEMENT_NODE:
14468
+ return `<${tagName.toLowerCase()}>`;
14469
+ case Node.TEXT_NODE:
14470
+ const content = textContent ? ` (with the "${shorten(textContent)}" content)` : '';
14471
+ return `a text node${content}`;
14472
+ case Node.COMMENT_NODE:
14473
+ return 'a comment node';
14474
+ default:
14475
+ return `#node(nodeType=${nodeType})`;
14476
+ }
14477
+ }
14478
+ /**
14479
+ * Builds the footer hydration error message
14480
+ *
14481
+ * @param componentClassName the name of the component class
14482
+ * @returns string
14483
+ */
14484
+ function getHydrationErrorFooter(componentClassName) {
14485
+ const componentInfo = componentClassName ? `the "${componentClassName}"` : 'corresponding';
14486
+ return `To fix this problem:\n` +
14487
+ ` * check ${componentInfo} component for hydration-related issues\n` +
14488
+ ` * or skip hydration by adding the \`ngSkipHydration\` attribute ` +
14489
+ `to its host node in a template`;
14490
+ }
14491
+ /**
14492
+ * An attribute related note for hydration errors
14493
+ */
14494
+ function getHydrationAttributeNote() {
14495
+ return 'Note: attributes are only displayed to better represent the DOM' +
14496
+ ' but have no effect on hydration mismatches.\n\n';
14497
+ }
14498
+ // Node string utility functions
14499
+ /**
14500
+ * Strips all newlines out of a given string
14501
+ *
14502
+ * @param input a string to be cleared of new line characters
14503
+ * @returns
14504
+ */
14505
+ function stripNewlines(input) {
14506
+ return input.replace(/\s+/gm, '');
14507
+ }
14508
+ /**
14509
+ * Reduces a string down to a maximum length of characters with ellipsis for readability
14510
+ *
14511
+ * @param input a string input
14512
+ * @param maxLength a maximum length in characters
14513
+ * @returns string
14514
+ */
14515
+ function shorten(input, maxLength = 50) {
14516
+ if (!input) {
14517
+ return '';
14518
+ }
14519
+ input = stripNewlines(input);
14520
+ return input.length > maxLength ? `${input.substring(0, maxLength - 1)}…` : input;
14521
+ }
14522
+
14523
+ /**
14524
+ * Regexp that extracts a reference node information from the compressed node location.
14525
+ * The reference node is represented as either:
14526
+ * - a number which points to an LView slot
14527
+ * - the `b` char which indicates that the lookup should start from the `document.body`
14528
+ * - the `h` char to start lookup from the component host node (`lView[HOST]`)
14529
+ */
14530
+ const REF_EXTRACTOR_REGEXP = new RegExp(`^(\\d+)*(${REFERENCE_NODE_BODY}|${REFERENCE_NODE_HOST})*(.*)`);
14531
+ /**
14532
+ * Helper function that takes a reference node location and a set of navigation steps
14533
+ * (from the reference node) to a target node and outputs a string that represents
14534
+ * a location.
14535
+ *
14536
+ * For example, given: referenceNode = 'b' (body) and path = ['firstChild', 'firstChild',
14537
+ * 'nextSibling'], the function returns: `bf2n`.
14538
+ */
14539
+ function compressNodeLocation(referenceNode, path) {
14540
+ const result = [referenceNode];
14541
+ for (const segment of path) {
14542
+ const lastIdx = result.length - 1;
14543
+ if (lastIdx > 0 && result[lastIdx - 1] === segment) {
14544
+ // An empty string in a count slot represents 1 occurrence of an instruction.
14545
+ const value = (result[lastIdx] || 1);
14546
+ result[lastIdx] = value + 1;
14547
+ }
14548
+ else {
14549
+ // Adding a new segment to the path.
14550
+ // Using an empty string in a counter field to avoid encoding `1`s
14551
+ // into the path, since they are implicit (e.g. `f1n1` vs `fn`), so
14552
+ // it's enough to have a single char in this case.
14553
+ result.push(segment, '');
14554
+ }
14555
+ }
14556
+ return result.join('');
14557
+ }
14558
+ /**
14559
+ * Helper function that reverts the `compressNodeLocation` and transforms a given
14560
+ * string into an array where at 0th position there is a reference node info and
14561
+ * after that it contains information (in pairs) about a navigation step and the
14562
+ * number of repetitions.
14563
+ *
14564
+ * For example, the path like 'bf2n' will be transformed to:
14565
+ * ['b', 'firstChild', 2, 'nextSibling', 1].
14566
+ *
14567
+ * This information is later consumed by the code that navigates the DOM to find
14568
+ * a given node by its location.
14569
+ */
14570
+ function decompressNodeLocation(path) {
14571
+ const matches = path.match(REF_EXTRACTOR_REGEXP);
14572
+ const [_, refNodeId, refNodeName, rest] = matches;
14573
+ // If a reference node is represented by an index, transform it to a number.
14574
+ const ref = refNodeId ? parseInt(refNodeId, 10) : refNodeName;
14575
+ const steps = [];
14576
+ // Match all segments in a path.
14577
+ for (const [_, step, count] of rest.matchAll(/(f|n)(\d*)/g)) {
14578
+ const repeat = parseInt(count, 10) || 1;
14579
+ steps.push(step, repeat);
14580
+ }
14581
+ return [ref, ...steps];
14582
+ }
14086
14583
 
14087
14584
  /** Whether current TNode is a first node in an <ng-container>. */
14088
14585
  function isFirstElementInNgContainer(tNode) {
14089
14586
  var _a;
14090
14587
  return !tNode.prev && ((_a = tNode.parent) === null || _a === void 0 ? void 0 : _a.type) === 8 /* TNodeType.ElementContainer */;
14091
14588
  }
14589
+ /** Returns an instruction index (subtracting HEADER_OFFSET). */
14590
+ function getNoOffsetIndex(tNode) {
14591
+ return tNode.index - HEADER_OFFSET;
14592
+ }
14092
14593
  /**
14093
14594
  * Locate a node in DOM tree that corresponds to a given TNode.
14094
14595
  *
@@ -14101,7 +14602,13 @@ function isFirstElementInNgContainer(tNode) {
14101
14602
  function locateNextRNode(hydrationInfo, tView, lView, tNode) {
14102
14603
  var _a;
14103
14604
  let native = null;
14104
- if (tView.firstChild === tNode) {
14605
+ const noOffsetIndex = getNoOffsetIndex(tNode);
14606
+ const nodes = hydrationInfo.data[NODES];
14607
+ if (nodes === null || nodes === void 0 ? void 0 : nodes[noOffsetIndex]) {
14608
+ // We know the exact location of the node.
14609
+ native = locateRNodeByPath(nodes[noOffsetIndex], lView);
14610
+ }
14611
+ else if (tView.firstChild === tNode) {
14105
14612
  // We create a first node in this view, so we use a reference
14106
14613
  // to the first child in this DOM segment.
14107
14614
  native = hydrationInfo.firstChild;
@@ -14114,7 +14621,7 @@ function locateNextRNode(hydrationInfo, tView, lView, tNode) {
14114
14621
  assertDefined(previousTNode, 'Unexpected state: current TNode does not have a connection ' +
14115
14622
  'to the previous node or a parent node.');
14116
14623
  if (isFirstElementInNgContainer(tNode)) {
14117
- const noOffsetParentIndex = tNode.parent.index - HEADER_OFFSET;
14624
+ const noOffsetParentIndex = getNoOffsetIndex(tNode.parent);
14118
14625
  native = getSegmentHead(hydrationInfo, noOffsetParentIndex);
14119
14626
  }
14120
14627
  else {
@@ -14128,7 +14635,7 @@ function locateNextRNode(hydrationInfo, tView, lView, tNode) {
14128
14635
  // represented in the DOM as `<div></div>...<!--container-->`.
14129
14636
  // In this case, there are nodes *after* this element and we need to skip
14130
14637
  // all of them to reach an element that we are looking for.
14131
- const noOffsetPrevSiblingIndex = previousTNode.index - HEADER_OFFSET;
14638
+ const noOffsetPrevSiblingIndex = getNoOffsetIndex(previousTNode);
14132
14639
  const segmentHead = getSegmentHead(hydrationInfo, noOffsetPrevSiblingIndex);
14133
14640
  if (previousTNode.type === 2 /* TNodeType.Element */ && segmentHead) {
14134
14641
  const numRootNodesToSkip = calcSerializedContainerSize(hydrationInfo, noOffsetPrevSiblingIndex);
@@ -14156,6 +14663,183 @@ function siblingAfter(skip, from) {
14156
14663
  }
14157
14664
  return currentNode;
14158
14665
  }
14666
+ /**
14667
+ * Helper function to produce a string representation of the navigation steps
14668
+ * (in terms of `nextSibling` and `firstChild` navigations). Used in error
14669
+ * messages in dev mode.
14670
+ */
14671
+ function stringifyNavigationInstructions(instructions) {
14672
+ const container = [];
14673
+ let i = 0;
14674
+ while (i < instructions.length) {
14675
+ const step = instructions[i++];
14676
+ const repeat = instructions[i++];
14677
+ for (let r = 0; r < repeat; r++) {
14678
+ container.push(step === NodeNavigationStep.FirstChild ? 'firstChild' : 'nextSibling');
14679
+ }
14680
+ }
14681
+ return container.join('.');
14682
+ }
14683
+ /**
14684
+ * Helper function that navigates from a starting point node (the `from` node)
14685
+ * using provided set of navigation instructions (within `path` argument).
14686
+ */
14687
+ function navigateToNode(from, instructions) {
14688
+ let node = from;
14689
+ let i = 0;
14690
+ while (i < instructions.length) {
14691
+ const step = instructions[i++];
14692
+ const repeat = instructions[i++];
14693
+ for (let r = 0; r < repeat; r++) {
14694
+ if (ngDevMode && !node) {
14695
+ throw nodeNotFoundAtPathError(from, stringifyNavigationInstructions(instructions));
14696
+ }
14697
+ switch (step) {
14698
+ case NodeNavigationStep.FirstChild:
14699
+ node = node.firstChild;
14700
+ break;
14701
+ case NodeNavigationStep.NextSibling:
14702
+ node = node.nextSibling;
14703
+ break;
14704
+ }
14705
+ }
14706
+ }
14707
+ if (ngDevMode && !node) {
14708
+ throw nodeNotFoundAtPathError(from, stringifyNavigationInstructions(instructions));
14709
+ }
14710
+ return node;
14711
+ }
14712
+ /**
14713
+ * Locates an RNode given a set of navigation instructions (which also contains
14714
+ * a starting point node info).
14715
+ */
14716
+ function locateRNodeByPath(path, lView) {
14717
+ const [referenceNode, ...navigationInstructions] = decompressNodeLocation(path);
14718
+ let ref;
14719
+ if (referenceNode === REFERENCE_NODE_HOST) {
14720
+ ref = lView[0];
14721
+ }
14722
+ else if (referenceNode === REFERENCE_NODE_BODY) {
14723
+ ref = ɵɵresolveBody(lView[0]);
14724
+ }
14725
+ else {
14726
+ const parentElementId = Number(referenceNode);
14727
+ ref = unwrapRNode(lView[parentElementId + HEADER_OFFSET]);
14728
+ }
14729
+ return navigateToNode(ref, navigationInstructions);
14730
+ }
14731
+ /**
14732
+ * Generate a list of DOM navigation operations to get from node `start` to node `finish`.
14733
+ *
14734
+ * Note: assumes that node `start` occurs before node `finish` in an in-order traversal of the DOM
14735
+ * tree. That is, we should be able to get from `start` to `finish` purely by using `.firstChild`
14736
+ * and `.nextSibling` operations.
14737
+ */
14738
+ function navigateBetween(start, finish) {
14739
+ if (start === finish) {
14740
+ return [];
14741
+ }
14742
+ else if (start.parentElement == null || finish.parentElement == null) {
14743
+ return null;
14744
+ }
14745
+ else if (start.parentElement === finish.parentElement) {
14746
+ return navigateBetweenSiblings(start, finish);
14747
+ }
14748
+ else {
14749
+ // `finish` is a child of its parent, so the parent will always have a child.
14750
+ const parent = finish.parentElement;
14751
+ const parentPath = navigateBetween(start, parent);
14752
+ const childPath = navigateBetween(parent.firstChild, finish);
14753
+ if (!parentPath || !childPath)
14754
+ return null;
14755
+ return [
14756
+ // First navigate to `finish`'s parent
14757
+ ...parentPath,
14758
+ // Then to its first child.
14759
+ NodeNavigationStep.FirstChild,
14760
+ // And finally from that node to `finish` (maybe a no-op if we're already there).
14761
+ ...childPath,
14762
+ ];
14763
+ }
14764
+ }
14765
+ /**
14766
+ * Calculates a path between 2 sibling nodes (generates a number of `NextSibling` navigations).
14767
+ */
14768
+ function navigateBetweenSiblings(start, finish) {
14769
+ const nav = [];
14770
+ let node = null;
14771
+ for (node = start; node != null && node !== finish; node = node.nextSibling) {
14772
+ nav.push(NodeNavigationStep.NextSibling);
14773
+ }
14774
+ return node === null ? [] : nav;
14775
+ }
14776
+ /**
14777
+ * Calculates a path between 2 nodes in terms of `nextSibling` and `firstChild`
14778
+ * navigations:
14779
+ * - the `from` node is a known node, used as an starting point for the lookup
14780
+ * (the `fromNodeName` argument is a string representation of the node).
14781
+ * - the `to` node is a node that the runtime logic would be looking up,
14782
+ * using the path generated by this function.
14783
+ */
14784
+ function calcPathBetween(from, to, fromNodeName) {
14785
+ const path = navigateBetween(from, to);
14786
+ return path === null ? null : compressNodeLocation(fromNodeName, path);
14787
+ }
14788
+ /**
14789
+ * Invoked at serialization time (on the server) when a set of navigation
14790
+ * instructions needs to be generated for a TNode.
14791
+ */
14792
+ function calcPathForNode(tNode, lView) {
14793
+ const parentTNode = tNode.parent;
14794
+ let parentIndex;
14795
+ let parentRNode;
14796
+ let referenceNodeName;
14797
+ if (parentTNode === null) {
14798
+ // No parent TNode - use host element as a reference node.
14799
+ parentIndex = referenceNodeName = REFERENCE_NODE_HOST;
14800
+ parentRNode = lView[HOST];
14801
+ }
14802
+ else {
14803
+ // Use parent TNode as a reference node.
14804
+ parentIndex = parentTNode.index;
14805
+ parentRNode = unwrapRNode(lView[parentIndex]);
14806
+ referenceNodeName = renderStringify(parentIndex - HEADER_OFFSET);
14807
+ }
14808
+ let rNode = unwrapRNode(lView[tNode.index]);
14809
+ if (tNode.type & 12 /* TNodeType.AnyContainer */) {
14810
+ // For <ng-container> nodes, instead of serializing a reference
14811
+ // to the anchor comment node, serialize a location of the first
14812
+ // DOM element. Paired with the container size (serialized as a part
14813
+ // of `ngh.containers`), it should give enough information for runtime
14814
+ // to hydrate nodes in this container.
14815
+ const firstRNode = getFirstNativeNode(lView, tNode);
14816
+ // If container is not empty, use a reference to the first element,
14817
+ // otherwise, rNode would point to an anchor comment node.
14818
+ if (firstRNode) {
14819
+ rNode = firstRNode;
14820
+ }
14821
+ }
14822
+ let path = calcPathBetween(parentRNode, rNode, referenceNodeName);
14823
+ if (path === null && parentRNode !== rNode) {
14824
+ // Searching for a path between elements within a host node failed.
14825
+ // Trying to find a path to an element starting from the `document.body` instead.
14826
+ //
14827
+ // Important note: this type of reference is relatively unstable, since Angular
14828
+ // may not be able to control parts of the page that the runtime logic navigates
14829
+ // through. This is mostly needed to cover "portals" use-case (like menus, dialog boxes,
14830
+ // etc), where nodes are content-projected (including direct DOM manipulations) outside
14831
+ // of the host node. The better solution is to provide APIs to work with "portals",
14832
+ // at which point this code path would not be needed.
14833
+ const body = parentRNode.ownerDocument.body;
14834
+ path = calcPathBetween(body, rNode, REFERENCE_NODE_BODY);
14835
+ if (path === null) {
14836
+ // If the path is still empty, it's likely that this node is detached and
14837
+ // won't be found during hydration.
14838
+ throw nodeNotFoundError(lView, tNode);
14839
+ }
14840
+ }
14841
+ return path;
14842
+ }
14159
14843
 
14160
14844
  function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex) {
14161
14845
  var _a, _b;
@@ -14233,7 +14917,7 @@ function createContainerAnchorImpl(tView, lView, tNode, index) {
14233
14917
  */
14234
14918
  function locateOrCreateContainerAnchorImpl(tView, lView, tNode, index) {
14235
14919
  const hydrationInfo = lView[HYDRATION];
14236
- const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1();
14920
+ const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() || isDisconnectedNode(hydrationInfo, index);
14237
14921
  lastNodeWasCreated(isNodeCreationMode);
14238
14922
  // Regular creation mode.
14239
14923
  if (isNodeCreationMode) {
@@ -14242,11 +14926,8 @@ function locateOrCreateContainerAnchorImpl(tView, lView, tNode, index) {
14242
14926
  // Hydration mode, looking up existing elements in DOM.
14243
14927
  const currentRNode = locateNextRNode(hydrationInfo, tView, lView, tNode);
14244
14928
  ngDevMode && validateNodeExists(currentRNode);
14929
+ setSegmentHead(hydrationInfo, index, currentRNode);
14245
14930
  const viewContainerSize = calcSerializedContainerSize(hydrationInfo, index);
14246
- // If this container is non-empty, store the first node as a segment head,
14247
- // otherwise, this node is an anchor and segment head doesn't exist (thus `null`).
14248
- const segmentHead = viewContainerSize > 0 ? currentRNode : null;
14249
- setSegmentHead(hydrationInfo, index, segmentHead);
14250
14931
  const comment = siblingAfter(viewContainerSize, currentRNode);
14251
14932
  if (ngDevMode) {
14252
14933
  validateMatchingNode(comment, Node.COMMENT_NODE, null, lView, tNode);
@@ -14502,7 +15183,7 @@ let _locateOrCreateElementNode = (tView, lView, tNode, renderer, name, index) =>
14502
15183
  */
14503
15184
  function locateOrCreateElementNodeImpl(tView, lView, tNode, renderer, name, index) {
14504
15185
  const hydrationInfo = lView[HYDRATION];
14505
- const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1();
15186
+ const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() || isDisconnectedNode(hydrationInfo, index);
14506
15187
  lastNodeWasCreated(isNodeCreationMode);
14507
15188
  // Regular creation mode.
14508
15189
  if (isNodeCreationMode) {
@@ -14526,10 +15207,17 @@ function locateOrCreateElementNodeImpl(tView, lView, tNode, renderer, name, inde
14526
15207
  // Checks if the skip hydration attribute is present during hydration so we know to
14527
15208
  // skip attempting to hydrate this block.
14528
15209
  if (hydrationInfo && hasNgSkipHydrationAttr(tNode)) {
14529
- enterSkipHydrationBlock(tNode);
14530
- // Since this isn't hydratable, we need to empty the node
14531
- // so there's no duplicate content after render
14532
- clearElementContents(renderer, native);
15210
+ if (isComponentHost(tNode)) {
15211
+ enterSkipHydrationBlock(tNode);
15212
+ // Since this isn't hydratable, we need to empty the node
15213
+ // so there's no duplicate content after render
15214
+ clearElementContents(renderer, native);
15215
+ }
15216
+ else if (ngDevMode) {
15217
+ // If this is not a component host, throw an error.
15218
+ // Hydration can be skipped on per-component basis only.
15219
+ throw invalidSkipHydrationHost(native);
15220
+ }
14533
15221
  }
14534
15222
  return native;
14535
15223
  }
@@ -14663,10 +15351,7 @@ function locateOrCreateElementContainerNode(tView, lView, tNode, index) {
14663
15351
  ngDevMode &&
14664
15352
  assertNumber(ngContainerSize, 'Unexpected state: hydrating an <ng-container>, ' +
14665
15353
  'but no hydration info is available.');
14666
- // If this container is non-empty, store the first node as a segment head,
14667
- // otherwise, this node is an anchor and segment head doesn't exist (thus `null`).
14668
- const segmentHead = ngContainerSize > 0 ? currentRNode : null;
14669
- setSegmentHead(hydrationInfo, index, segmentHead);
15354
+ setSegmentHead(hydrationInfo, index, currentRNode);
14670
15355
  comment = siblingAfter(ngContainerSize, currentRNode);
14671
15356
  if (ngDevMode) {
14672
15357
  validateMatchingNode(comment, Node.COMMENT_NODE, null, lView, tNode);
@@ -15048,7 +15733,10 @@ function ɵɵprojection(nodeIndex, selectorIndex = 0, attrs) {
15048
15733
  tProjectionNode.projection = selectorIndex;
15049
15734
  // `<ng-content>` has no content
15050
15735
  setCurrentTNodeAsNotParent();
15051
- if ((tProjectionNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
15736
+ const hydrationInfo = lView[HYDRATION];
15737
+ const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1();
15738
+ if (isNodeCreationMode &&
15739
+ (tProjectionNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
15052
15740
  // re-distribution of projectable nodes is stored on a component's view level
15053
15741
  applyProjection(tView, lView, tProjectionNode);
15054
15742
  }
@@ -17011,7 +17699,7 @@ function ɵɵtext(index, value = '') {
17011
17699
  const tNode = tView.firstCreatePass ?
17012
17700
  getOrCreateTNode(tView, adjustedIndex, 1 /* TNodeType.Text */, value, null) :
17013
17701
  tView.data[adjustedIndex];
17014
- const textNative = _locateOrCreateTextNode(tView, lView, tNode, value);
17702
+ const textNative = _locateOrCreateTextNode(tView, lView, tNode, value, index);
17015
17703
  lView[adjustedIndex] = textNative;
17016
17704
  if (wasLastNodeCreated()) {
17017
17705
  appendChild(tView, lView, textNative, tNode);
@@ -17019,7 +17707,7 @@ function ɵɵtext(index, value = '') {
17019
17707
  // Text nodes are self closing.
17020
17708
  setCurrentTNode(tNode, false);
17021
17709
  }
17022
- let _locateOrCreateTextNode = (tView, lView, tNode, value) => {
17710
+ let _locateOrCreateTextNode = (tView, lView, tNode, value, index) => {
17023
17711
  lastNodeWasCreated(true);
17024
17712
  return createTextNode(lView[RENDERER], value);
17025
17713
  };
@@ -17027,9 +17715,9 @@ let _locateOrCreateTextNode = (tView, lView, tNode, value) => {
17027
17715
  * Enables hydration code path (to lookup existing elements in DOM)
17028
17716
  * in addition to the regular creation mode of text nodes.
17029
17717
  */
17030
- function locateOrCreateTextNodeImpl(tView, lView, tNode, value) {
17718
+ function locateOrCreateTextNodeImpl(tView, lView, tNode, value, index) {
17031
17719
  const hydrationInfo = lView[HYDRATION];
17032
- const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1();
17720
+ const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() || isDisconnectedNode(hydrationInfo, index);
17033
17721
  lastNodeWasCreated(isNodeCreationMode);
17034
17722
  // Regular creation mode.
17035
17723
  if (isNodeCreationMode) {
@@ -22140,6 +22828,54 @@ function removeDehydratedView(dehydratedView, renderer) {
22140
22828
  }
22141
22829
  }
22142
22830
  }
22831
+ /**
22832
+ * Walks over all views within this LContainer invokes dehydrated views
22833
+ * cleanup function for each one.
22834
+ */
22835
+ function cleanupLContainer(lContainer) {
22836
+ removeDehydratedViews(lContainer);
22837
+ for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
22838
+ cleanupLView(lContainer[i]);
22839
+ }
22840
+ }
22841
+ /**
22842
+ * Walks over `LContainer`s and components registered within
22843
+ * this LView and invokes dehydrated views cleanup function for each one.
22844
+ */
22845
+ function cleanupLView(lView) {
22846
+ const tView = lView[TVIEW];
22847
+ for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
22848
+ if (isLContainer(lView[i])) {
22849
+ const lContainer = lView[i];
22850
+ cleanupLContainer(lContainer);
22851
+ }
22852
+ else if (Array.isArray(lView[i])) {
22853
+ // This is a component, enter the `cleanupLView` recursively.
22854
+ cleanupLView(lView[i]);
22855
+ }
22856
+ }
22857
+ }
22858
+ /**
22859
+ * Walks over all views registered within the ApplicationRef and removes
22860
+ * all dehydrated views from all `LContainer`s along the way.
22861
+ */
22862
+ function cleanupDehydratedViews(appRef) {
22863
+ // Wait once an app becomes stable and cleanup all views that
22864
+ // were not claimed during the application bootstrap process.
22865
+ // The timing is similar to when we kick off serialization on the server.
22866
+ return appRef.isStable.pipe(first((isStable) => isStable)).toPromise().then(() => {
22867
+ const viewRefs = appRef._views;
22868
+ for (const viewRef of viewRefs) {
22869
+ const lView = getComponentLViewForHydration(viewRef);
22870
+ // An `lView` might be `null` if a `ViewRef` represents
22871
+ // an embedded view (not a component view).
22872
+ if (lView !== null && lView[HOST] !== null) {
22873
+ cleanupLView(lView);
22874
+ ngDevMode && ngDevMode.dehydratedViewsCleanupRuns++;
22875
+ }
22876
+ }
22877
+ });
22878
+ }
22143
22879
 
22144
22880
  /**
22145
22881
  * Given a current DOM node and a serialized information about the views
@@ -22147,22 +22883,27 @@ function removeDehydratedView(dehydratedView, renderer) {
22147
22883
  * dehydrated views.
22148
22884
  */
22149
22885
  function locateDehydratedViewsInContainer(currentRNode, serializedViews) {
22886
+ var _a;
22150
22887
  const dehydratedViews = [];
22151
22888
  for (const serializedView of serializedViews) {
22152
- const view = {
22153
- data: serializedView,
22154
- firstChild: null,
22155
- };
22156
- if (serializedView[NUM_ROOT_NODES] > 0) {
22157
- // Keep reference to the first node in this view,
22158
- // so it can be accessed while invoking template instructions.
22159
- view.firstChild = currentRNode;
22160
- // Move over to the next node after this view, which can
22161
- // either be a first node of the next view or an anchor comment
22162
- // node after the last view in a container.
22163
- currentRNode = siblingAfter(serializedView[NUM_ROOT_NODES], currentRNode);
22889
+ // Repeats a view multiple times as needed, based on the serialized information
22890
+ // (for example, for *ngFor-produced views).
22891
+ for (let i = 0; i < ((_a = serializedView[MULTIPLIER]) !== null && _a !== void 0 ? _a : 1); i++) {
22892
+ const view = {
22893
+ data: serializedView,
22894
+ firstChild: null,
22895
+ };
22896
+ if (serializedView[NUM_ROOT_NODES] > 0) {
22897
+ // Keep reference to the first node in this view,
22898
+ // so it can be accessed while invoking template instructions.
22899
+ view.firstChild = currentRNode;
22900
+ // Move over to the next node after this view, which can
22901
+ // either be a first node of the next view or an anchor comment
22902
+ // node after the last view in a container.
22903
+ currentRNode = siblingAfter(serializedView[NUM_ROOT_NODES], currentRNode);
22904
+ }
22905
+ dehydratedViews.push(view);
22164
22906
  }
22165
- dehydratedViews.push(view);
22166
22907
  }
22167
22908
  return [currentRNode, dehydratedViews];
22168
22909
  }
@@ -22546,21 +23287,22 @@ function locateOrCreateAnchorNode(lContainer, hostLView, hostTNode, slotValue) {
22546
23287
  if (lContainer[NATIVE] && lContainer[DEHYDRATED_VIEWS])
22547
23288
  return;
22548
23289
  const hydrationInfo = hostLView[HYDRATION];
22549
- const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock(hostTNode);
23290
+ const noOffsetIndex = hostTNode.index - HEADER_OFFSET;
23291
+ const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock(hostTNode) ||
23292
+ isDisconnectedNode(hydrationInfo, noOffsetIndex);
22550
23293
  // Regular creation mode.
22551
23294
  if (isNodeCreationMode) {
22552
23295
  return createAnchorNode(lContainer, hostLView, hostTNode, slotValue);
22553
23296
  }
22554
23297
  // Hydration mode, looking up an anchor node and dehydrated views in DOM.
22555
- const index = hostTNode.index - HEADER_OFFSET;
22556
- const currentRNode = getSegmentHead(hydrationInfo, index);
22557
- const serializedViews = (_a = hydrationInfo.data[CONTAINERS]) === null || _a === void 0 ? void 0 : _a[index];
23298
+ const currentRNode = getSegmentHead(hydrationInfo, noOffsetIndex);
23299
+ const serializedViews = (_a = hydrationInfo.data[CONTAINERS]) === null || _a === void 0 ? void 0 : _a[noOffsetIndex];
22558
23300
  ngDevMode &&
22559
23301
  assertDefined(serializedViews, 'Unexpected state: no hydration info available for a given TNode, ' +
22560
23302
  'which represents a view container.');
22561
23303
  const [commentNode, dehydratedViews] = locateDehydratedViewsInContainer(currentRNode, serializedViews);
22562
23304
  if (ngDevMode) {
22563
- validateMatchingNode(commentNode, Node.COMMENT_NODE, null, hostLView, hostTNode);
23305
+ validateMatchingNode(commentNode, Node.COMMENT_NODE, null, hostLView, hostTNode, true);
22564
23306
  // Do not throw in case this node is already claimed (thus `false` as a second
22565
23307
  // argument). If this container is created based on an `<ng-template>`, the comment
22566
23308
  // node would be already claimed from the `template` instruction. If an element acts
@@ -24259,12 +25001,17 @@ const Pipe = makeDecorator('Pipe', (p) => (Object.assign({ pure: true }, p)), un
24259
25001
  * @Annotation
24260
25002
  * @publicApi
24261
25003
  */
24262
- const Input = makePropDecorator('Input', (bindingPropertyName) => ({ bindingPropertyName }));
25004
+ const Input = makePropDecorator('Input', (arg) => {
25005
+ if (!arg) {
25006
+ return {};
25007
+ }
25008
+ return typeof arg === 'string' ? { alias: arg } : arg;
25009
+ });
24263
25010
  /**
24264
25011
  * @Annotation
24265
25012
  * @publicApi
24266
25013
  */
24267
- const Output = makePropDecorator('Output', (bindingPropertyName) => ({ bindingPropertyName }));
25014
+ const Output = makePropDecorator('Output', (alias) => ({ alias }));
24268
25015
  /**
24269
25016
  * @Annotation
24270
25017
  * @publicApi
@@ -26612,6 +27359,8 @@ function enableProdMode() {
26612
27359
  * The scope of this destruction depends on where `DestroyRef` is injected. If `DestroyRef`
26613
27360
  * is injected in a component or directive, the callbacks run when that component or
26614
27361
  * directive is destroyed. Otherwise the callbacks run when a corresponding injector is destroyed.
27362
+ *
27363
+ * @publicApi
26615
27364
  */
26616
27365
  class DestroyRef {
26617
27366
  }
@@ -26632,6 +27381,7 @@ class NodeInjectorDestroyRef extends DestroyRef {
26632
27381
  }
26633
27382
  onDestroy(callback) {
26634
27383
  storeLViewOnDestroy(this._lView, callback);
27384
+ return () => removeLViewOnDestroy(this._lView, callback);
26635
27385
  }
26636
27386
  }
26637
27387
  function injectDestroyRef() {
@@ -28558,7 +29308,9 @@ function annotateForHydration(appRef, doc) {
28558
29308
  * @returns an array of the `SerializedView` objects
28559
29309
  */
28560
29310
  function serializeLContainer(lContainer, context) {
29311
+ var _a;
28561
29312
  const views = [];
29313
+ let lastViewAsString = '';
28562
29314
  for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
28563
29315
  let childLView = lContainer[i];
28564
29316
  // If this is a root view, get an LView for the underlying component,
@@ -28580,10 +29332,43 @@ function serializeLContainer(lContainer, context) {
28580
29332
  numRootNodes = calcNumRootNodes(childTView, childLView, childTView.firstChild);
28581
29333
  }
28582
29334
  const view = Object.assign({ [TEMPLATE_ID]: template, [NUM_ROOT_NODES]: numRootNodes }, serializeLView(lContainer[i], context));
28583
- views.push(view);
29335
+ // Check if the previous view has the same shape (for example, it was
29336
+ // produced by the *ngFor), in which case bump the counter on the previous
29337
+ // view instead of including the same information again.
29338
+ const currentViewAsString = JSON.stringify(view);
29339
+ if (views.length > 0 && currentViewAsString === lastViewAsString) {
29340
+ const previousView = views[views.length - 1];
29341
+ (_a = previousView[MULTIPLIER]) !== null && _a !== void 0 ? _a : (previousView[MULTIPLIER] = 1);
29342
+ previousView[MULTIPLIER]++;
29343
+ }
29344
+ else {
29345
+ // Record this view as most recently added.
29346
+ lastViewAsString = currentViewAsString;
29347
+ views.push(view);
29348
+ }
28584
29349
  }
28585
29350
  return views;
28586
29351
  }
29352
+ /**
29353
+ * Helper function to produce a node path (which navigation steps runtime logic
29354
+ * needs to take to locate a node) and stores it in the `NODES` section of the
29355
+ * current serialized view.
29356
+ */
29357
+ function appendSerializedNodePath(ngh, tNode, lView) {
29358
+ var _a;
29359
+ const noOffsetIndex = tNode.index - HEADER_OFFSET;
29360
+ (_a = ngh[NODES]) !== null && _a !== void 0 ? _a : (ngh[NODES] = {});
29361
+ ngh[NODES][noOffsetIndex] = calcPathForNode(tNode, lView);
29362
+ }
29363
+ /**
29364
+ * There is no special TNode type for an i18n block, so we verify
29365
+ * whether the structure that we store at the `TView.data[idx]` position
29366
+ * has the `TI18n` shape.
29367
+ */
29368
+ function isTI18nNode(obj) {
29369
+ const tI18n = obj;
29370
+ return tI18n.hasOwnProperty('create') && tI18n.hasOwnProperty('update');
29371
+ }
28587
29372
  /**
28588
29373
  * Serializes the lView data into a SerializedView object that will later be added
28589
29374
  * to the TransferState storage and referenced using the `ngh` attribute on a host
@@ -28594,7 +29379,7 @@ function serializeLContainer(lContainer, context) {
28594
29379
  * @returns the `SerializedView` object containing the data to be added to the host node
28595
29380
  */
28596
29381
  function serializeLView(lView, context) {
28597
- var _a, _b, _c, _d, _e;
29382
+ var _a, _b, _c, _d, _e, _f;
28598
29383
  const ngh = {};
28599
29384
  const tView = lView[TVIEW];
28600
29385
  // Iterate over DOM element references in an LView.
@@ -28608,11 +29393,56 @@ function serializeLView(lView, context) {
28608
29393
  if (!tNode) {
28609
29394
  continue;
28610
29395
  }
29396
+ // Check if a native node that represents a given TNode is disconnected from the DOM tree.
29397
+ // Such nodes must be excluded from the hydration (since the hydration won't be able to
29398
+ // find them), so the TNode ids are collected and used at runtime to skip the hydration.
29399
+ //
29400
+ // This situation may happen during the content projection, when some nodes don't make it
29401
+ // into one of the content projection slots (for example, when there is no default
29402
+ // <ng-content /> slot in projector component's template).
29403
+ //
29404
+ // Note: we leverage the fact that we have this information available in the DOM emulation
29405
+ // layer (in Domino) for now. Longer-term solution should not rely on the DOM emulation and
29406
+ // only use internal data structures and state to compute this information.
29407
+ if (!(tNode.type & 16 /* TNodeType.Projection */) && !!lView[i] &&
29408
+ !unwrapRNode(lView[i]).isConnected) {
29409
+ (_a = ngh[DISCONNECTED_NODES]) !== null && _a !== void 0 ? _a : (ngh[DISCONNECTED_NODES] = []);
29410
+ ngh[DISCONNECTED_NODES].push(noOffsetIndex);
29411
+ continue;
29412
+ }
29413
+ if (Array.isArray(tNode.projection)) {
29414
+ for (const projectionHeadTNode of tNode.projection) {
29415
+ // We may have `null`s in slots with no projected content.
29416
+ if (!projectionHeadTNode)
29417
+ continue;
29418
+ if (!Array.isArray(projectionHeadTNode)) {
29419
+ // If we process re-projected content (i.e. `<ng-content>`
29420
+ // appears at projection location), skip annotations for this content
29421
+ // since all DOM nodes in this projection were handled while processing
29422
+ // a parent lView, which contains those nodes.
29423
+ if (!isProjectionTNode(projectionHeadTNode) &&
29424
+ !isInSkipHydrationBlock(projectionHeadTNode)) {
29425
+ appendSerializedNodePath(ngh, projectionHeadTNode, lView);
29426
+ }
29427
+ }
29428
+ else {
29429
+ // If a value is an array, it means that we are processing a projection
29430
+ // where projectable nodes were passed in as DOM nodes (for example, when
29431
+ // calling `ViewContainerRef.createComponent(CmpA, {projectableNodes: [...]})`).
29432
+ //
29433
+ // In this scenario, nodes can come from anywhere (either created manually,
29434
+ // accessed via `document.querySelector`, etc) and may be in any state
29435
+ // (attached or detached from the DOM tree). As a result, we can not reliably
29436
+ // restore the state for such cases during hydration.
29437
+ throw unsupportedProjectionOfDomNodes(unwrapRNode(lView[i]));
29438
+ }
29439
+ }
29440
+ }
28611
29441
  if (isLContainer(lView[i])) {
28612
29442
  // Serialize information about a template.
28613
29443
  const embeddedTView = tNode.tView;
28614
29444
  if (embeddedTView !== null) {
28615
- (_a = ngh[TEMPLATES]) !== null && _a !== void 0 ? _a : (ngh[TEMPLATES] = {});
29445
+ (_b = ngh[TEMPLATES]) !== null && _b !== void 0 ? _b : (ngh[TEMPLATES] = {});
28616
29446
  ngh[TEMPLATES][noOffsetIndex] = getSsrId(embeddedTView);
28617
29447
  }
28618
29448
  // Serialize views within this LContainer.
@@ -28627,7 +29457,7 @@ function serializeLView(lView, context) {
28627
29457
  annotateHostElementForHydration(targetNode, hostNode, context);
28628
29458
  }
28629
29459
  }
28630
- (_b = ngh[CONTAINERS]) !== null && _b !== void 0 ? _b : (ngh[CONTAINERS] = {});
29460
+ (_c = ngh[CONTAINERS]) !== null && _c !== void 0 ? _c : (ngh[CONTAINERS] = {});
28631
29461
  ngh[CONTAINERS][noOffsetIndex] = serializeLContainer(lView[i], context);
28632
29462
  }
28633
29463
  else if (Array.isArray(lView[i])) {
@@ -28637,15 +29467,41 @@ function serializeLView(lView, context) {
28637
29467
  annotateHostElementForHydration(targetNode, lView[i], context);
28638
29468
  }
28639
29469
  }
29470
+ else if (isTI18nNode(tNode)) {
29471
+ // Hydration for i18n nodes is not *yet* supported.
29472
+ // Produce an error message which would also describe possible
29473
+ // solutions (switching back to the "destructive" hydration or
29474
+ // excluding a component from hydration via `ngSkipHydration`).
29475
+ //
29476
+ // TODO(akushnir): we should find a better way to get a hold of the node that has the `i18n`
29477
+ // attribute on it. For now, we either refer to the host element of the component or to the
29478
+ // previous element in the LView.
29479
+ const targetNode = (i === HEADER_OFFSET) ? lView[HOST] : unwrapRNode(lView[i - 1]);
29480
+ throw notYetSupportedI18nBlockError(targetNode);
29481
+ }
28640
29482
  else {
28641
29483
  // <ng-container> case
28642
29484
  if (tNode.type & 8 /* TNodeType.ElementContainer */) {
28643
29485
  // An <ng-container> is represented by the number of
28644
29486
  // top-level nodes. This information is needed to skip over
28645
29487
  // those nodes to reach a corresponding anchor node (comment node).
28646
- (_c = ngh[ELEMENT_CONTAINERS]) !== null && _c !== void 0 ? _c : (ngh[ELEMENT_CONTAINERS] = {});
29488
+ (_d = ngh[ELEMENT_CONTAINERS]) !== null && _d !== void 0 ? _d : (ngh[ELEMENT_CONTAINERS] = {});
28647
29489
  ngh[ELEMENT_CONTAINERS][noOffsetIndex] = calcNumRootNodes(tView, lView, tNode.child);
28648
29490
  }
29491
+ else if (tNode.type & 16 /* TNodeType.Projection */) {
29492
+ // Current TNode represents an `<ng-content>` slot, thus it has no
29493
+ // DOM elements associated with it, so the **next sibling** node would
29494
+ // not be able to find an anchor. In this case, use full path instead.
29495
+ let nextTNode = tNode.next;
29496
+ // Skip over all `<ng-content>` slots in a row.
29497
+ while (nextTNode !== null && (nextTNode.type & 16 /* TNodeType.Projection */)) {
29498
+ nextTNode = nextTNode.next;
29499
+ }
29500
+ if (nextTNode && !isInSkipHydrationBlock(nextTNode)) {
29501
+ // Handle a tNode after the `<ng-content>` slot.
29502
+ appendSerializedNodePath(ngh, nextTNode, lView);
29503
+ }
29504
+ }
28649
29505
  else {
28650
29506
  // Handle cases where text nodes can be lost after DOM serialization:
28651
29507
  // 1. When there is an *empty text node* in DOM: in this case, this
@@ -28675,13 +29531,20 @@ function serializeLView(lView, context) {
28675
29531
  // live DOM has exactly the same state as it was before serialization.
28676
29532
  if (tNode.type & 1 /* TNodeType.Text */) {
28677
29533
  const rNode = unwrapRNode(lView[i]);
28678
- if (((_d = rNode.textContent) === null || _d === void 0 ? void 0 : _d.replace(/\s/gm, '')) === '') {
29534
+ if (((_e = rNode.textContent) === null || _e === void 0 ? void 0 : _e.replace(/\s/gm, '')) === '') {
28679
29535
  context.corruptedTextNodes.set(rNode, "ngetn" /* TextNodeMarker.EmptyNode */);
28680
29536
  }
28681
- else if (((_e = rNode.nextSibling) === null || _e === void 0 ? void 0 : _e.nodeType) === Node.TEXT_NODE) {
29537
+ else if (((_f = rNode.nextSibling) === null || _f === void 0 ? void 0 : _f.nodeType) === Node.TEXT_NODE) {
28682
29538
  context.corruptedTextNodes.set(rNode, "ngtns" /* TextNodeMarker.Separator */);
28683
29539
  }
28684
29540
  }
29541
+ if (tNode.projectionNext && tNode.projectionNext !== tNode.next &&
29542
+ !isInSkipHydrationBlock(tNode.projectionNext)) {
29543
+ // Check if projection next is not the same as next, in which case
29544
+ // the node would not be found at creation time at runtime and we
29545
+ // need to provide a location for that node.
29546
+ appendSerializedNodePath(ngh, tNode.projectionNext, lView);
29547
+ }
28685
29548
  }
28686
29549
  }
28687
29550
  }
@@ -28820,109 +29683,21 @@ function provideHydrationSupport() {
28820
29683
  // environment. On a server, an application is rendered
28821
29684
  // from scratch, so the host content needs to be empty.
28822
29685
  useFactory: () => isBrowser(),
29686
+ },
29687
+ {
29688
+ provide: APP_BOOTSTRAP_LISTENER,
29689
+ useFactory: () => {
29690
+ if (isBrowser()) {
29691
+ const appRef = inject(ApplicationRef);
29692
+ return () => cleanupDehydratedViews(appRef);
29693
+ }
29694
+ return () => { }; // noop
29695
+ },
29696
+ multi: true,
28823
29697
  }
28824
29698
  ]);
28825
29699
  }
28826
29700
 
28827
- /** Coerces a value (typically a string) to a boolean. */
28828
- function coerceToBoolean(value) {
28829
- return typeof value === 'boolean' ? value : (value != null && value !== 'false');
28830
- }
28831
-
28832
- /**
28833
- * Compiles a partial directive declaration object into a full directive definition object.
28834
- *
28835
- * @codeGenApi
28836
- */
28837
- function ɵɵngDeclareDirective(decl) {
28838
- const compiler = getCompilerFacade({ usage: 1 /* JitCompilerUsage.PartialDeclaration */, kind: 'directive', type: decl.type });
28839
- return compiler.compileDirectiveDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵfac.js`, decl);
28840
- }
28841
- /**
28842
- * Evaluates the class metadata declaration.
28843
- *
28844
- * @codeGenApi
28845
- */
28846
- function ɵɵngDeclareClassMetadata(decl) {
28847
- var _a, _b;
28848
- setClassMetadata(decl.type, decl.decorators, (_a = decl.ctorParameters) !== null && _a !== void 0 ? _a : null, (_b = decl.propDecorators) !== null && _b !== void 0 ? _b : null);
28849
- }
28850
- /**
28851
- * Compiles a partial component declaration object into a full component definition object.
28852
- *
28853
- * @codeGenApi
28854
- */
28855
- function ɵɵngDeclareComponent(decl) {
28856
- const compiler = getCompilerFacade({ usage: 1 /* JitCompilerUsage.PartialDeclaration */, kind: 'component', type: decl.type });
28857
- return compiler.compileComponentDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵcmp.js`, decl);
28858
- }
28859
- /**
28860
- * Compiles a partial pipe declaration object into a full pipe definition object.
28861
- *
28862
- * @codeGenApi
28863
- */
28864
- function ɵɵngDeclareFactory(decl) {
28865
- const compiler = getCompilerFacade({
28866
- usage: 1 /* JitCompilerUsage.PartialDeclaration */,
28867
- kind: getFactoryKind(decl.target),
28868
- type: decl.type
28869
- });
28870
- return compiler.compileFactoryDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵfac.js`, decl);
28871
- }
28872
- function getFactoryKind(target) {
28873
- switch (target) {
28874
- case FactoryTarget.Directive:
28875
- return 'directive';
28876
- case FactoryTarget.Component:
28877
- return 'component';
28878
- case FactoryTarget.Injectable:
28879
- return 'injectable';
28880
- case FactoryTarget.Pipe:
28881
- return 'pipe';
28882
- case FactoryTarget.NgModule:
28883
- return 'NgModule';
28884
- }
28885
- }
28886
- /**
28887
- * Compiles a partial injectable declaration object into a full injectable definition object.
28888
- *
28889
- * @codeGenApi
28890
- */
28891
- function ɵɵngDeclareInjectable(decl) {
28892
- const compiler = getCompilerFacade({ usage: 1 /* JitCompilerUsage.PartialDeclaration */, kind: 'injectable', type: decl.type });
28893
- return compiler.compileInjectableDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵprov.js`, decl);
28894
- }
28895
- /**
28896
- * Compiles a partial injector declaration object into a full injector definition object.
28897
- *
28898
- * @codeGenApi
28899
- */
28900
- function ɵɵngDeclareInjector(decl) {
28901
- const compiler = getCompilerFacade({ usage: 1 /* JitCompilerUsage.PartialDeclaration */, kind: 'NgModule', type: decl.type });
28902
- return compiler.compileInjectorDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵinj.js`, decl);
28903
- }
28904
- /**
28905
- * Compiles a partial NgModule declaration object into a full NgModule definition object.
28906
- *
28907
- * @codeGenApi
28908
- */
28909
- function ɵɵngDeclareNgModule(decl) {
28910
- const compiler = getCompilerFacade({ usage: 1 /* JitCompilerUsage.PartialDeclaration */, kind: 'NgModule', type: decl.type });
28911
- return compiler.compileNgModuleDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵmod.js`, decl);
28912
- }
28913
- /**
28914
- * Compiles a partial pipe declaration object into a full pipe definition object.
28915
- *
28916
- * @codeGenApi
28917
- */
28918
- function ɵɵngDeclarePipe(decl) {
28919
- const compiler = getCompilerFacade({ usage: 1 /* JitCompilerUsage.PartialDeclaration */, kind: 'pipe', type: decl.type });
28920
- return compiler.compilePipeDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵpipe.js`, decl);
28921
- }
28922
-
28923
- // clang-format off
28924
- // clang-format on
28925
-
28926
29701
  /**
28927
29702
  * Symbol used to tell `Signal`s apart from other functions.
28928
29703
  *
@@ -29070,8 +29845,24 @@ function consumerPollValueStatus(consumer) {
29070
29845
  return false;
29071
29846
  }
29072
29847
 
29848
+ // `WeakRef` is not always defined in every TS environment where Angular is compiled. Instead,
29849
+ // read it off of the global context if available.
29073
29850
  // tslint:disable-next-line: no-toplevel-property-access
29074
- const WeakRef = _global['WeakRef'];
29851
+ let WeakRefImpl = _global['WeakRef'];
29852
+ function newWeakRef(value) {
29853
+ if (typeof ngDevMode !== 'undefined' && ngDevMode && WeakRefImpl === undefined) {
29854
+ throw new Error(`Angular requires a browser which supports the 'WeakRef' API`);
29855
+ }
29856
+ return new WeakRefImpl(value);
29857
+ }
29858
+ /**
29859
+ * Use an alternate implementation of `WeakRef` if a platform implementation isn't available.
29860
+ */
29861
+ function setAlternateWeakRefImpl(impl) {
29862
+ if (!WeakRefImpl) {
29863
+ WeakRefImpl = impl;
29864
+ }
29865
+ }
29075
29866
 
29076
29867
  /**
29077
29868
  * Create a computed `Signal` which derives a reactive value from an expression.
@@ -29128,7 +29919,7 @@ class ComputedImpl {
29128
29919
  */
29129
29920
  this.stale = true;
29130
29921
  this.id = nextReactiveId();
29131
- this.ref = new WeakRef(this);
29922
+ this.ref = newWeakRef(this);
29132
29923
  this.producers = new Map();
29133
29924
  this.consumers = new Map();
29134
29925
  this.trackingVersion = 0;
@@ -29217,7 +30008,7 @@ class Watch {
29217
30008
  this.watch = watch;
29218
30009
  this.schedule = schedule;
29219
30010
  this.id = nextReactiveId();
29220
- this.ref = new WeakRef(this);
30011
+ this.ref = newWeakRef(this);
29221
30012
  this.producers = new Map();
29222
30013
  this.trackingVersion = 0;
29223
30014
  this.dirty = false;
@@ -29261,8 +30052,6 @@ function effect(effectFn) {
29261
30052
  // Effects start dirty.
29262
30053
  watch.notify();
29263
30054
  return {
29264
- consumer: watch,
29265
- schedule: watch.notify.bind(watch),
29266
30055
  destroy: () => {
29267
30056
  queuedWatches.delete(watch);
29268
30057
  globalWatches.delete(watch);
@@ -29320,7 +30109,7 @@ class SettableSignalImpl {
29320
30109
  this.value = value;
29321
30110
  this.equal = equal;
29322
30111
  this.id = nextReactiveId();
29323
- this.ref = new WeakRef(this);
30112
+ this.ref = newWeakRef(this);
29324
30113
  this.consumers = new Map();
29325
30114
  this.valueVersion = 0;
29326
30115
  }
@@ -29398,6 +30187,105 @@ function untracked(nonReactiveReadsFn) {
29398
30187
  }
29399
30188
  }
29400
30189
 
30190
+ /** Coerces a value (typically a string) to a boolean. */
30191
+ function coerceToBoolean(value) {
30192
+ return typeof value === 'boolean' ? value : (value != null && value !== 'false');
30193
+ }
30194
+
30195
+ /**
30196
+ * Compiles a partial directive declaration object into a full directive definition object.
30197
+ *
30198
+ * @codeGenApi
30199
+ */
30200
+ function ɵɵngDeclareDirective(decl) {
30201
+ const compiler = getCompilerFacade({ usage: 1 /* JitCompilerUsage.PartialDeclaration */, kind: 'directive', type: decl.type });
30202
+ return compiler.compileDirectiveDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵfac.js`, decl);
30203
+ }
30204
+ /**
30205
+ * Evaluates the class metadata declaration.
30206
+ *
30207
+ * @codeGenApi
30208
+ */
30209
+ function ɵɵngDeclareClassMetadata(decl) {
30210
+ var _a, _b;
30211
+ setClassMetadata(decl.type, decl.decorators, (_a = decl.ctorParameters) !== null && _a !== void 0 ? _a : null, (_b = decl.propDecorators) !== null && _b !== void 0 ? _b : null);
30212
+ }
30213
+ /**
30214
+ * Compiles a partial component declaration object into a full component definition object.
30215
+ *
30216
+ * @codeGenApi
30217
+ */
30218
+ function ɵɵngDeclareComponent(decl) {
30219
+ const compiler = getCompilerFacade({ usage: 1 /* JitCompilerUsage.PartialDeclaration */, kind: 'component', type: decl.type });
30220
+ return compiler.compileComponentDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵcmp.js`, decl);
30221
+ }
30222
+ /**
30223
+ * Compiles a partial pipe declaration object into a full pipe definition object.
30224
+ *
30225
+ * @codeGenApi
30226
+ */
30227
+ function ɵɵngDeclareFactory(decl) {
30228
+ const compiler = getCompilerFacade({
30229
+ usage: 1 /* JitCompilerUsage.PartialDeclaration */,
30230
+ kind: getFactoryKind(decl.target),
30231
+ type: decl.type
30232
+ });
30233
+ return compiler.compileFactoryDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵfac.js`, decl);
30234
+ }
30235
+ function getFactoryKind(target) {
30236
+ switch (target) {
30237
+ case FactoryTarget.Directive:
30238
+ return 'directive';
30239
+ case FactoryTarget.Component:
30240
+ return 'component';
30241
+ case FactoryTarget.Injectable:
30242
+ return 'injectable';
30243
+ case FactoryTarget.Pipe:
30244
+ return 'pipe';
30245
+ case FactoryTarget.NgModule:
30246
+ return 'NgModule';
30247
+ }
30248
+ }
30249
+ /**
30250
+ * Compiles a partial injectable declaration object into a full injectable definition object.
30251
+ *
30252
+ * @codeGenApi
30253
+ */
30254
+ function ɵɵngDeclareInjectable(decl) {
30255
+ const compiler = getCompilerFacade({ usage: 1 /* JitCompilerUsage.PartialDeclaration */, kind: 'injectable', type: decl.type });
30256
+ return compiler.compileInjectableDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵprov.js`, decl);
30257
+ }
30258
+ /**
30259
+ * Compiles a partial injector declaration object into a full injector definition object.
30260
+ *
30261
+ * @codeGenApi
30262
+ */
30263
+ function ɵɵngDeclareInjector(decl) {
30264
+ const compiler = getCompilerFacade({ usage: 1 /* JitCompilerUsage.PartialDeclaration */, kind: 'NgModule', type: decl.type });
30265
+ return compiler.compileInjectorDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵinj.js`, decl);
30266
+ }
30267
+ /**
30268
+ * Compiles a partial NgModule declaration object into a full NgModule definition object.
30269
+ *
30270
+ * @codeGenApi
30271
+ */
30272
+ function ɵɵngDeclareNgModule(decl) {
30273
+ const compiler = getCompilerFacade({ usage: 1 /* JitCompilerUsage.PartialDeclaration */, kind: 'NgModule', type: decl.type });
30274
+ return compiler.compileNgModuleDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵmod.js`, decl);
30275
+ }
30276
+ /**
30277
+ * Compiles a partial pipe declaration object into a full pipe definition object.
30278
+ *
30279
+ * @codeGenApi
30280
+ */
30281
+ function ɵɵngDeclarePipe(decl) {
30282
+ const compiler = getCompilerFacade({ usage: 1 /* JitCompilerUsage.PartialDeclaration */, kind: 'pipe', type: decl.type });
30283
+ return compiler.compilePipeDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵpipe.js`, decl);
30284
+ }
30285
+
30286
+ // clang-format off
30287
+ // clang-format on
30288
+
29401
30289
  // This file exists to allow the set of reactivity exports to be modified in g3, as these APIs are
29402
30290
 
29403
30291
  /**
@@ -29581,5 +30469,5 @@ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
29581
30469
  * Generated bundle index. Do not edit.
29582
30470
  */
29583
30471
 
29584
- export { ANALYZE_FOR_ENTRY_COMPONENTS, ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Compiler, CompilerFactory, Component, ComponentFactory$1 as ComponentFactory, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ContentChild, ContentChildren, DEFAULT_CURRENCY_CODE, DebugElement, DebugEventListener, DebugNode, DefaultIterableDiffer, DestroyRef, Directive, ENVIRONMENT_INITIALIZER, ElementRef, EmbeddedViewRef, EnvironmentInjector, ErrorHandler, EventEmitter, Host, HostBinding, HostListener, INJECTOR, Inject, InjectFlags, Injectable, InjectionToken, Injector, Input, IterableDiffers, KeyValueDiffers, LOCALE_ID, MissingTranslationStrategy, ModuleWithComponentFactories, NO_ERRORS_SCHEMA, NgModule, NgModuleFactory$1 as NgModuleFactory, NgModuleRef$1 as NgModuleRef, NgProbeToken, NgZone, Optional, Output, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, Pipe, PlatformRef, Query, QueryList, ReflectiveInjector, ReflectiveKey, Renderer2, RendererFactory2, RendererStyleFlags2, ResolvedReflectiveFactory, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, asNativeElements, assertPlatform, computed, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, effect, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, isDevMode, isSignal, isStandalone, makeEnvironmentProviders, mergeApplicationConfig, platformCore, reflectComponentType, resolveForwardRef, runInInjectionContext, setTestabilityGetter, signal, untracked, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, ComponentFactory$1 as ɵComponentFactory, Console as ɵConsole, DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, INJECTOR_SCOPE as ɵINJECTOR_SCOPE, IS_HYDRATION_FEATURE_ENABLED as ɵIS_HYDRATION_FEATURE_ENABLED, LContext as ɵLContext, LifecycleHooksFeature as ɵLifecycleHooksFeature, LocaleDataIndex as ɵLocaleDataIndex, NG_COMP_DEF as ɵNG_COMP_DEF, NG_DIR_DEF as ɵNG_DIR_DEF, NG_ELEMENT_ID as ɵNG_ELEMENT_ID, NG_INJ_DEF as ɵNG_INJ_DEF, NG_MOD_DEF as ɵNG_MOD_DEF, NG_PIPE_DEF as ɵNG_PIPE_DEF, NG_PROV_DEF as ɵNG_PROV_DEF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE as ɵNO_CHANGE, NgModuleFactory as ɵNgModuleFactory, NoopNgZone as ɵNoopNgZone, ReflectionCapabilities as ɵReflectionCapabilities, ComponentFactory as ɵRender3ComponentFactory, ComponentRef as ɵRender3ComponentRef, NgModuleRef as ɵRender3NgModuleRef, RuntimeError as ɵRuntimeError, TESTABILITY as ɵTESTABILITY, TESTABILITY_GETTER as ɵTESTABILITY_GETTER, TransferState as ɵTransferState, ViewRef$1 as ɵViewRef, XSS_SECURITY_URL as ɵXSS_SECURITY_URL, _sanitizeHtml as ɵ_sanitizeHtml, _sanitizeUrl as ɵ_sanitizeUrl, allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, annotateForHydration as ɵannotateForHydration, bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, coerceToBoolean as ɵcoerceToBoolean, compileComponent as ɵcompileComponent, compileDirective as ɵcompileDirective, compileNgModule as ɵcompileNgModule, compileNgModuleDefs as ɵcompileNgModuleDefs, compileNgModuleFactory as ɵcompileNgModuleFactory, compilePipe as ɵcompilePipe, convertToBitFlags as ɵconvertToBitFlags, createInjector as ɵcreateInjector, defaultIterableDiffers as ɵdefaultIterableDiffers, defaultKeyValueDiffers as ɵdefaultKeyValueDiffers, detectChanges as ɵdetectChanges, devModeEqual as ɵdevModeEqual, escapeTransferStateContent as ɵescapeTransferStateContent, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, formatRuntimeError as ɵformatRuntimeError, getComponentDef as ɵgetComponentDef, getDebugNode as ɵgetDebugNode, getDirectives as ɵgetDirectives, getHostElement as ɵgetHostElement, getInjectableDef as ɵgetInjectableDef, getLContext as ɵgetLContext, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, getSanitizationBypassType as ɵgetSanitizationBypassType, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, _global as ɵglobal, injectChangeDetectorRef as ɵinjectChangeDetectorRef, internalCreateApplication as ɵinternalCreateApplication, isBoundToModule as ɵisBoundToModule, isEnvironmentProviders as ɵisEnvironmentProviders, isInjectable as ɵisInjectable, isNgModule as ɵisNgModule, isPromise as ɵisPromise, isSubscribable as ɵisSubscribable, makeDecorator as ɵmakeDecorator, makeStateKey as ɵmakeStateKey, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, provideHydrationSupport as ɵprovideHydrationSupport, provideNgZoneChangeDetection as ɵprovideNgZoneChangeDetection, publishDefaultGlobalUtils$1 as ɵpublishDefaultGlobalUtils, publishGlobalUtil as ɵpublishGlobalUtil, registerLocaleData as ɵregisterLocaleData, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, resolveComponentResources as ɵresolveComponentResources, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, setClassMetadata as ɵsetClassMetadata, setCurrentInjector as ɵsetCurrentInjector, setDocument as ɵsetDocument, setLocaleId as ɵsetLocaleId, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, store as ɵstore, stringify as ɵstringify, transitiveScopesFor as ɵtransitiveScopesFor, unescapeTransferStateContent as ɵunescapeTransferStateContent, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, ɵɵCopyDefinitionFeature, FactoryTarget as ɵɵFactoryTarget, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵStandaloneFeature, ɵɵadvance, ɵɵattribute, ɵɵattributeInterpolate1, ɵɵattributeInterpolate2, ɵɵattributeInterpolate3, ɵɵattributeInterpolate4, ɵɵattributeInterpolate5, ɵɵattributeInterpolate6, ɵɵattributeInterpolate7, ɵɵattributeInterpolate8, ɵɵattributeInterpolateV, ɵɵclassMap, ɵɵclassMapInterpolate1, ɵɵclassMapInterpolate2, ɵɵclassMapInterpolate3, ɵɵclassMapInterpolate4, ɵɵclassMapInterpolate5, ɵɵclassMapInterpolate6, ɵɵclassMapInterpolate7, ɵɵclassMapInterpolate8, ɵɵclassMapInterpolateV, ɵɵclassProp, ɵɵcontentQuery, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdisableBindings, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵenableBindings, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵhostProperty, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinject, ɵɵinjectAttribute, ɵɵinvalidFactory, ɵɵinvalidFactoryDep, ɵɵlistener, ɵɵloadQuery, ɵɵnamespaceHTML, ɵɵnamespaceMathML, ɵɵnamespaceSVG, ɵɵnextContext, ɵɵngDeclareClassMetadata, ɵɵngDeclareComponent, ɵɵngDeclareDirective, ɵɵngDeclareFactory, ɵɵngDeclareInjectable, ɵɵngDeclareInjector, ɵɵngDeclareNgModule, ɵɵngDeclarePipe, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpropertyInterpolate, ɵɵpropertyInterpolate1, ɵɵpropertyInterpolate2, ɵɵpropertyInterpolate3, ɵɵpropertyInterpolate4, ɵɵpropertyInterpolate5, ɵɵpropertyInterpolate6, ɵɵpropertyInterpolate7, ɵɵpropertyInterpolate8, ɵɵpropertyInterpolateV, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryRefresh, ɵɵreference, registerNgModuleType as ɵɵregisterNgModuleType, ɵɵresetView, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵrestoreView, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstyleMap, ɵɵstyleMapInterpolate1, ɵɵstyleMapInterpolate2, ɵɵstyleMapInterpolate3, ɵɵstyleMapInterpolate4, ɵɵstyleMapInterpolate5, ɵɵstyleMapInterpolate6, ɵɵstyleMapInterpolate7, ɵɵstyleMapInterpolate8, ɵɵstyleMapInterpolateV, ɵɵstyleProp, ɵɵstylePropInterpolate1, ɵɵstylePropInterpolate2, ɵɵstylePropInterpolate3, ɵɵstylePropInterpolate4, ɵɵstylePropInterpolate5, ɵɵstylePropInterpolate6, ɵɵstylePropInterpolate7, ɵɵstylePropInterpolate8, ɵɵstylePropInterpolateV, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵvalidateIframeAttribute, ɵɵviewQuery };
30472
+ export { ANALYZE_FOR_ENTRY_COMPONENTS, ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, ApplicationInitStatus, ApplicationModule, ApplicationRef, Attribute, COMPILER_OPTIONS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Compiler, CompilerFactory, Component, ComponentFactory$1 as ComponentFactory, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ContentChild, ContentChildren, DEFAULT_CURRENCY_CODE, DebugElement, DebugEventListener, DebugNode, DefaultIterableDiffer, DestroyRef, Directive, ENVIRONMENT_INITIALIZER, ElementRef, EmbeddedViewRef, EnvironmentInjector, ErrorHandler, EventEmitter, Host, HostBinding, HostListener, INJECTOR, Inject, InjectFlags, Injectable, InjectionToken, Injector, Input, IterableDiffers, KeyValueDiffers, LOCALE_ID, MissingTranslationStrategy, ModuleWithComponentFactories, NO_ERRORS_SCHEMA, NgModule, NgModuleFactory$1 as NgModuleFactory, NgModuleRef$1 as NgModuleRef, NgProbeToken, NgZone, Optional, Output, PACKAGE_ROOT_URL, PLATFORM_ID, PLATFORM_INITIALIZER, Pipe, PlatformRef, Query, QueryList, ReflectiveInjector, ReflectiveKey, Renderer2, RendererFactory2, RendererStyleFlags2, ResolvedReflectiveFactory, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, Type, VERSION, Version, ViewChild, ViewChildren, ViewContainerRef, ViewEncapsulation$1 as ViewEncapsulation, ViewRef, asNativeElements, assertPlatform, computed, createComponent, createEnvironmentInjector, createNgModule, createNgModuleRef, createPlatform, createPlatformFactory, defineInjectable, destroyPlatform, effect, enableProdMode, forwardRef, getDebugNode, getModuleFactory, getNgModuleById, getPlatform, importProvidersFrom, inject, isDevMode, isSignal, isStandalone, makeEnvironmentProviders, mergeApplicationConfig, platformCore, reflectComponentType, resolveForwardRef, runInInjectionContext, setTestabilityGetter, signal, untracked, ALLOW_MULTIPLE_PLATFORMS as ɵALLOW_MULTIPLE_PLATFORMS, ComponentFactory$1 as ɵComponentFactory, Console as ɵConsole, DEFAULT_LOCALE_ID as ɵDEFAULT_LOCALE_ID, INJECTOR_SCOPE as ɵINJECTOR_SCOPE, IS_HYDRATION_FEATURE_ENABLED as ɵIS_HYDRATION_FEATURE_ENABLED, LContext as ɵLContext, LifecycleHooksFeature as ɵLifecycleHooksFeature, LocaleDataIndex as ɵLocaleDataIndex, NG_COMP_DEF as ɵNG_COMP_DEF, NG_DIR_DEF as ɵNG_DIR_DEF, NG_ELEMENT_ID as ɵNG_ELEMENT_ID, NG_INJ_DEF as ɵNG_INJ_DEF, NG_MOD_DEF as ɵNG_MOD_DEF, NG_PIPE_DEF as ɵNG_PIPE_DEF, NG_PROV_DEF as ɵNG_PROV_DEF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE as ɵNO_CHANGE, NgModuleFactory as ɵNgModuleFactory, NoopNgZone as ɵNoopNgZone, ReflectionCapabilities as ɵReflectionCapabilities, ComponentFactory as ɵRender3ComponentFactory, ComponentRef as ɵRender3ComponentRef, NgModuleRef as ɵRender3NgModuleRef, RuntimeError as ɵRuntimeError, TESTABILITY as ɵTESTABILITY, TESTABILITY_GETTER as ɵTESTABILITY_GETTER, TransferState as ɵTransferState, ViewRef$1 as ɵViewRef, XSS_SECURITY_URL as ɵXSS_SECURITY_URL, _sanitizeHtml as ɵ_sanitizeHtml, _sanitizeUrl as ɵ_sanitizeUrl, allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, annotateForHydration as ɵannotateForHydration, bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, coerceToBoolean as ɵcoerceToBoolean, compileComponent as ɵcompileComponent, compileDirective as ɵcompileDirective, compileNgModule as ɵcompileNgModule, compileNgModuleDefs as ɵcompileNgModuleDefs, compileNgModuleFactory as ɵcompileNgModuleFactory, compilePipe as ɵcompilePipe, convertToBitFlags as ɵconvertToBitFlags, createInjector as ɵcreateInjector, defaultIterableDiffers as ɵdefaultIterableDiffers, defaultKeyValueDiffers as ɵdefaultKeyValueDiffers, detectChanges as ɵdetectChanges, devModeEqual as ɵdevModeEqual, escapeTransferStateContent as ɵescapeTransferStateContent, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, formatRuntimeError as ɵformatRuntimeError, getDebugNode as ɵgetDebugNode, getDirectives as ɵgetDirectives, getHostElement as ɵgetHostElement, getInjectableDef as ɵgetInjectableDef, getLContext as ɵgetLContext, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, getSanitizationBypassType as ɵgetSanitizationBypassType, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, _global as ɵglobal, injectChangeDetectorRef as ɵinjectChangeDetectorRef, internalCreateApplication as ɵinternalCreateApplication, isBoundToModule as ɵisBoundToModule, isEnvironmentProviders as ɵisEnvironmentProviders, isInjectable as ɵisInjectable, isNgModule as ɵisNgModule, isPromise as ɵisPromise, isSubscribable as ɵisSubscribable, makeDecorator as ɵmakeDecorator, makeStateKey as ɵmakeStateKey, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, provideHydrationSupport as ɵprovideHydrationSupport, provideNgZoneChangeDetection as ɵprovideNgZoneChangeDetection, publishDefaultGlobalUtils$1 as ɵpublishDefaultGlobalUtils, publishGlobalUtil as ɵpublishGlobalUtil, registerLocaleData as ɵregisterLocaleData, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, resolveComponentResources as ɵresolveComponentResources, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, setAlternateWeakRefImpl as ɵsetAlternateWeakRefImpl, setClassMetadata as ɵsetClassMetadata, setCurrentInjector as ɵsetCurrentInjector, setDocument as ɵsetDocument, setLocaleId as ɵsetLocaleId, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, store as ɵstore, stringify as ɵstringify, transitiveScopesFor as ɵtransitiveScopesFor, unescapeTransferStateContent as ɵunescapeTransferStateContent, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, ɵɵCopyDefinitionFeature, FactoryTarget as ɵɵFactoryTarget, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵStandaloneFeature, ɵɵadvance, ɵɵattribute, ɵɵattributeInterpolate1, ɵɵattributeInterpolate2, ɵɵattributeInterpolate3, ɵɵattributeInterpolate4, ɵɵattributeInterpolate5, ɵɵattributeInterpolate6, ɵɵattributeInterpolate7, ɵɵattributeInterpolate8, ɵɵattributeInterpolateV, ɵɵclassMap, ɵɵclassMapInterpolate1, ɵɵclassMapInterpolate2, ɵɵclassMapInterpolate3, ɵɵclassMapInterpolate4, ɵɵclassMapInterpolate5, ɵɵclassMapInterpolate6, ɵɵclassMapInterpolate7, ɵɵclassMapInterpolate8, ɵɵclassMapInterpolateV, ɵɵclassProp, ɵɵcontentQuery, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdisableBindings, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵenableBindings, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵhostProperty, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinject, ɵɵinjectAttribute, ɵɵinvalidFactory, ɵɵinvalidFactoryDep, ɵɵlistener, ɵɵloadQuery, ɵɵnamespaceHTML, ɵɵnamespaceMathML, ɵɵnamespaceSVG, ɵɵnextContext, ɵɵngDeclareClassMetadata, ɵɵngDeclareComponent, ɵɵngDeclareDirective, ɵɵngDeclareFactory, ɵɵngDeclareInjectable, ɵɵngDeclareInjector, ɵɵngDeclareNgModule, ɵɵngDeclarePipe, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpropertyInterpolate, ɵɵpropertyInterpolate1, ɵɵpropertyInterpolate2, ɵɵpropertyInterpolate3, ɵɵpropertyInterpolate4, ɵɵpropertyInterpolate5, ɵɵpropertyInterpolate6, ɵɵpropertyInterpolate7, ɵɵpropertyInterpolate8, ɵɵpropertyInterpolateV, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryRefresh, ɵɵreference, registerNgModuleType as ɵɵregisterNgModuleType, ɵɵresetView, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵrestoreView, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstyleMap, ɵɵstyleMapInterpolate1, ɵɵstyleMapInterpolate2, ɵɵstyleMapInterpolate3, ɵɵstyleMapInterpolate4, ɵɵstyleMapInterpolate5, ɵɵstyleMapInterpolate6, ɵɵstyleMapInterpolate7, ɵɵstyleMapInterpolate8, ɵɵstyleMapInterpolateV, ɵɵstyleProp, ɵɵstylePropInterpolate1, ɵɵstylePropInterpolate2, ɵɵstylePropInterpolate3, ɵɵstylePropInterpolate4, ɵɵstylePropInterpolate5, ɵɵstylePropInterpolate6, ɵɵstylePropInterpolate7, ɵɵstylePropInterpolate8, ɵɵstylePropInterpolateV, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵvalidateIframeAttribute, ɵɵviewQuery };
29585
30473
  //# sourceMappingURL=core.mjs.map