{"version":3,"file":"ngx-vest-forms.mjs","sources":["../../../projects/ngx-vest-forms/src/lib/directives/error-display-mode.token.ts","../../../projects/ngx-vest-forms/src/lib/errors/error-catalog.ts","../../../projects/ngx-vest-forms/src/lib/tokens/debounce.token.ts","../../../projects/ngx-vest-forms/src/lib/utils/equality.ts","../../../projects/ngx-vest-forms/src/lib/tokens/equality.token.ts","../../../projects/ngx-vest-forms/src/lib/utils/destroy-scheduler.ts","../../../projects/ngx-vest-forms/src/lib/utils/field-path.utils.ts","../../../projects/ngx-vest-forms/src/lib/utils/first-invalid.utils.ts","../../../projects/ngx-vest-forms/src/lib/constants.ts","../../../projects/ngx-vest-forms/src/lib/utils/form-utils.ts","../../../projects/ngx-vest-forms/src/lib/utils/shape-validation.ts","../../../projects/ngx-vest-forms/src/lib/directives/form-submitted-state.ts","../../../projects/ngx-vest-forms/src/lib/directives/form.directive.ts","../../../projects/ngx-vest-forms/src/lib/directives/form-control-state.directive.ts","../../../projects/ngx-vest-forms/src/lib/directives/form-error-display.directive.ts","../../../projects/ngx-vest-forms/src/lib/utils/aria-association.utils.ts","../../../projects/ngx-vest-forms/src/lib/utils/pending-state.utils.ts","../../../projects/ngx-vest-forms/src/lib/components/control-wrapper/control-wrapper.component.ts","../../../projects/ngx-vest-forms/src/lib/components/control-wrapper/control-wrapper.component.html","../../../projects/ngx-vest-forms/src/lib/components/form-group-wrapper/form-group-wrapper.component.ts","../../../projects/ngx-vest-forms/src/lib/components/form-group-wrapper/form-group-wrapper.component.html","../../../projects/ngx-vest-forms/src/lib/directives/form-error-control.directive.ts","../../../projects/ngx-vest-forms/src/lib/directives/async-validator-bridge.ts","../../../projects/ngx-vest-forms/src/lib/directives/form-model-group.directive.ts","../../../projects/ngx-vest-forms/src/lib/directives/form-model.directive.ts","../../../projects/ngx-vest-forms/src/lib/directives/validate-root-form.directive.ts","../../../projects/ngx-vest-forms/src/lib/exports.ts","../../../projects/ngx-vest-forms/src/lib/utils/field-path-types.ts","../../../projects/ngx-vest-forms/src/lib/utils/form-state.utils.ts","../../../projects/ngx-vest-forms/src/lib/utils/validation-config-builder.ts","../../../projects/ngx-vest-forms/src/lib/utils/array-to-object.ts","../../../projects/ngx-vest-forms/src/lib/utils/field-clearing.ts","../../../projects/ngx-vest-forms/src/public-api.ts","../../../projects/ngx-vest-forms/src/ngx-vest-forms.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport {\n  NgxWarningDisplayMode,\n  ScErrorDisplayMode,\n} from './form-error-display.directive';\n\n/**\n * @deprecated Use NGX_ERROR_DISPLAY_MODE_TOKEN instead\n */\nexport const SC_ERROR_DISPLAY_MODE_TOKEN =\n  new InjectionToken<ScErrorDisplayMode>('SC_ERROR_DISPLAY_MODE_TOKEN', {\n    providedIn: 'root',\n    factory: () => 'on-blur-or-submit',\n  });\n\n/**\n * Injection token for configuring the default error display mode.\n * Values:\n * - 'on-blur': Show errors after field is touched/blurred\n * - 'on-submit': Show errors after form submission\n * - 'on-blur-or-submit': Show errors after blur or form submission (default)\n * - 'on-dirty': Show errors as soon as the field value changes\n * - 'always': Show errors immediately, even on pristine fields\n */\nexport const NGX_ERROR_DISPLAY_MODE_TOKEN =\n  new InjectionToken<ScErrorDisplayMode>('NGX_ERROR_DISPLAY_MODE_TOKEN', {\n    providedIn: 'root',\n    factory: () => 'on-blur-or-submit',\n  });\n\n/**\n * Injection token for configuring the default warning display mode.\n * Values:\n * - 'on-touch': Show warnings after field is touched/blurred\n * - 'on-validated-or-touch': Show warnings after validation runs or field is touched (default)\n * - 'on-dirty': Show warnings as soon as the field value changes\n * - 'always': Show warnings immediately, even on pristine fields\n */\nexport const NGX_WARNING_DISPLAY_MODE_TOKEN =\n  new InjectionToken<NgxWarningDisplayMode>('NGX_WARNING_DISPLAY_MODE_TOKEN', {\n    providedIn: 'root',\n    factory: () => 'on-validated-or-touch',\n  });\n","export const NGX_VEST_FORMS_ERRORS = {\n  EXTRA_PROPERTY: {\n    code: 'NGX-001',\n    message: (path: string) =>\n      `Shape mismatch: Property '${path}' is present in the form value but not defined in the form shape.`,\n  },\n  TYPE_MISMATCH: {\n    code: 'NGX-002',\n    message: (path: string, expected: string, actual: string) =>\n      `Type mismatch at '${path}': Expected '${expected}' but got '${actual}'.`,\n  },\n  CONTROL_NOT_FOUND: {\n    code: 'NGX-003',\n    message: (path: string) =>\n      `Control not found: Could not find form control at path '${path}'. Check your [ngModel] name attributes.`,\n  },\n} as const;\n\nexport function logWarning<T extends unknown[]>(\n  error: { code: string; message: (...args: T) => string },\n  ...args: T\n): void {\n  console.warn(\n    `[${error.code}] ${error.message(...args)}\\nCheck your [formShape] input and the initial [formValue].`\n  );\n}\n","import { InjectionToken } from '@angular/core';\n\n/**\n * Injection token for configurable validation config debounce timing.\n *\n * This token allows you to configure the debounce time for validation config\n * dependencies at the application, route, or component level.\n *\n * @example\n * ```typescript\n * /// Global configuration\n * export const appConfig: ApplicationConfig = {\n *   providers: [\n *     {\n *       provide: NGX_VALIDATION_CONFIG_DEBOUNCE_TOKEN,\n *       useValue: 200\n *     }\n *   ]\n * };\n *\n * /// Per-route configuration\n * {\n *   path: 'checkout',\n *   component: CheckoutComponent,\n *   providers: [\n *     {\n *       provide: NGX_VALIDATION_CONFIG_DEBOUNCE_TOKEN,\n *       useValue: 50\n *     }\n *   ]\n * }\n *\n * /// Per-component override\n * @Component({\n *   providers: [\n *     {\n *       provide: NGX_VALIDATION_CONFIG_DEBOUNCE_TOKEN,\n *       useValue: 0 // for testing\n *     }\n *   ]\n * })\n * export class TestFormComponent {}\n * ```\n *\n * @default 100ms - Maintains backward compatibility with existing behavior\n */\nexport const NGX_VALIDATION_CONFIG_DEBOUNCE_TOKEN = new InjectionToken<number>(\n  'NgxValidationConfigDebounceTime',\n  {\n    providedIn: 'root',\n    factory: () => 100,\n  }\n);\n","/**\n * Type guard to check if a value is a primitive type.\n *\n * @param value - The value to check\n * @returns true if the value is a primitive (string, number, boolean, null, undefined, symbol, bigint)\n */\nexport function isPrimitive(\n  value: unknown\n): value is string | number | boolean | null | undefined | symbol | bigint {\n  return (\n    value === null || (typeof value !== 'object' && typeof value !== 'function')\n  );\n}\n\ntype VisitedPairs = WeakMap<object, WeakSet<object>>;\n\n/**\n * Records that we've started comparing the pair (a, b). Re-entering the same\n * pair during recursion (cycle, or repeated DAG path) short-circuits to `true`\n * — correct because if the prior descent had returned `false`, the outer call\n * would already have short-circuited before we reach the second visit.\n */\nfunction rememberPair(seen: VisitedPairs, a: object, b: object): void {\n  let targets = seen.get(a);\n  if (!targets) {\n    targets = new WeakSet<object>();\n    seen.set(a, targets);\n  }\n  targets.add(b);\n}\n\n/**\n * @internal\n * Internal utility for shallow equality checks.\n *\n * **Not intended for external use.** This function is used internally by the library\n * for performance-critical operations. Consider using your own comparison logic or\n * a library like lodash if you need shallow equality checks in your application.\n *\n * Optimized shallow equality check for objects.\n *\n * **Why this custom implementation is preferred:**\n * - **Performance**: Direct property comparison is significantly faster than JSON.stringify\n * - **Type Safety**: Handles null/undefined values correctly without serialization issues\n * - **Accuracy**: Doesn't suffer from JSON.stringify limitations (undefined values, functions, symbols)\n * - **Memory Efficient**: No temporary string creation or object serialization overhead\n *\n * **Use Cases:**\n * - Form value change detection where only top-level properties matter\n * - Quick object comparison in performance-critical code paths\n * - Validation triggers where deep comparison is unnecessary\n *\n * **Performance Comparison:**\n * ```typescript\n * /// ❌ Slow: JSON.stringify approach\n * JSON.stringify(obj1) === JSON.stringify(obj2)\n *\n * /// ✅ Fast: Direct property comparison\n * shallowEqual(obj1, obj2)\n * ```\n *\n * @param obj1 - First object to compare\n * @param obj2 - Second object to compare\n * @returns true if objects are shallowly equal (same keys and same values by reference)\n */\nexport function shallowEqual(obj1: unknown, obj2: unknown): boolean {\n  if (obj1 === obj2) {\n    return true;\n  }\n\n  if (obj1 == null || obj2 == null) {\n    return obj1 === obj2;\n  }\n\n  if (typeof obj1 !== 'object' || typeof obj2 !== 'object') {\n    return obj1 === obj2;\n  }\n\n  const keys1 = Object.keys(obj1);\n  const keys2 = Object.keys(obj2);\n\n  if (keys1.length !== keys2.length) {\n    return false;\n  }\n\n  for (const key of keys1) {\n    if (\n      !Object.hasOwn(obj2 as object, key) ||\n      (obj1 as Record<string, unknown>)[key] !==\n        (obj2 as Record<string, unknown>)[key]\n    ) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n/**\n * @internal\n * Internal utility for deep equality checks.\n *\n * **Not intended for external use.** This function is used internally by the library\n * for form value comparison and change detection. Consider using your own comparison\n * logic or a library like lodash if you need deep equality checks in your application.\n *\n * Fast deep equality check optimized for form values and Angular applications.\n *\n * **Why this custom implementation is preferred over alternatives:**\n *\n * **vs JSON.stringify():**\n * - **10-100x faster**: Direct comparison without string serialization overhead\n * - **Accurate**: Handles Date objects, RegExp, undefined values, and functions correctly\n * - **Memory efficient**: No temporary string creation or garbage collection pressure\n * - **Preserves semantics**: Maintains type information during comparison\n *\n * **vs structuredClone():**\n * - **Wrong purpose**: structuredClone creates copies, not comparisons\n * - **Performance**: Would require cloning both objects just to compare them\n * - **Memory waste**: Creates unnecessary deep copies, doubling memory usage\n * - **Still incomplete**: Even after cloning, you'd still need a comparison function\n *\n * **vs External libraries (lodash.isEqual, etc.):**\n * - **Bundle size**: Zero dependencies, smaller application bundles\n * - **Form-specific**: Optimized for common Angular form data patterns\n * - **Type safety**: Full TypeScript integration with strict typing\n * - **Performance**: Tailored algorithms for form value comparison use cases\n *\n * **Supported Data Types:**\n * - Primitives (string, number, boolean, null, undefined, symbol, bigint)\n * - Arrays (with recursive deep comparison)\n * - Plain objects (with recursive deep comparison)\n * - Date objects (by timestamp comparison)\n * - RegExp objects (by source and flags comparison)\n * - Set objects (reference equality only)\n * - Map objects (reference equality only)\n * - Functions (reference equality only — distinct function instances are never equal,\n *   even if their source code is identical)\n *\n * **Safety Features:**\n * - **Circular reference handling**: Tracks visited object pairs with `WeakMap<object, WeakSet<object>>`\n * - **Type coercion prevention**: Strict type checking before comparison\n * - **Null safety**: Proper handling of null and undefined values\n *\n * **Performance Characteristics:**\n * ```typescript\n * /// Performance comparison on typical form objects:\n * /// JSON.stringify:    ~100ms for complex nested forms\n * /// fastDeepEqual:     ~1-5ms for the same objects\n * ///\n * /// Memory usage:\n * /// JSON.stringify:    Creates temporary strings (high GC pressure)\n * /// fastDeepEqual:     One small WeakMap of visited object pairs is allocated lazily on\n * ///                    first nested-container descent; primitive-only comparisons allocate nothing.\n * ```\n *\n * **Typical Usage in Forms:**\n * ```typescript\n * /// Detect when form values actually change\n * distinctUntilChanged(fastDeepEqual)\n *\n * /// Prevent unnecessary re-renders\n * if (!fastDeepEqual(oldFormValue, newFormValue)) {\n *   updateUI();\n * }\n * ```\n *\n * @param obj1 - First object to compare\n * @param obj2 - Second object to compare\n *\n * Cyclic arrays and plain objects are compared structurally by tracking visited object\n * pairs. Distinct cyclic graphs with the same structure compare equal. `Date` and\n * `RegExp` values compare structurally. `Map` and `Set` values compare by reference\n * only, so distinct instances are considered different even if their contents match.\n *\n * @returns true if objects are deeply equal by value\n */\nexport function fastDeepEqual(obj1: unknown, obj2: unknown): boolean {\n  return fastDeepEqualInternal(obj1, obj2, undefined);\n}\n\nfunction fastDeepEqualInternal(\n  obj1: unknown,\n  obj2: unknown,\n  seen: VisitedPairs | undefined\n): boolean {\n  // Object.is gives correct semantics for NaN and ±0 — important for numeric\n  // form values where `fastDeepEqual(NaN, NaN)` should be true.\n  if (Object.is(obj1, obj2)) {\n    return true;\n  }\n\n  if (obj1 == null || obj2 == null) {\n    return false;\n  }\n\n  if (typeof obj1 !== typeof obj2) {\n    return false;\n  }\n\n  // Functions use reference-only equality. Object.is at the top already returned\n  // true for identical references, so reaching here means the references differ.\n  if (typeof obj1 === 'function') {\n    return false;\n  }\n\n  if (isPrimitive(obj1) || isPrimitive(obj2)) {\n    return false;\n  }\n\n  // Handle Date / RegExp first — they have value semantics and can't contain cycles,\n  // so they don't need pair tracking.\n  if (obj1 instanceof Date || obj2 instanceof Date) {\n    return (\n      obj1 instanceof Date &&\n      obj2 instanceof Date &&\n      obj1.getTime() === obj2.getTime()\n    );\n  }\n\n  if (obj1 instanceof RegExp || obj2 instanceof RegExp) {\n    return (\n      obj1 instanceof RegExp &&\n      obj2 instanceof RegExp &&\n      obj1.source === obj2.source &&\n      obj1.flags === obj2.flags\n    );\n  }\n\n  // Intentional contract: distinct Set / Map instances compare by reference only.\n  if (obj1 instanceof Set || obj2 instanceof Set) {\n    return false;\n  }\n  if (obj1 instanceof Map || obj2 instanceof Map) {\n    return false;\n  }\n\n  if (Array.isArray(obj1) !== Array.isArray(obj2)) {\n    return false;\n  }\n\n  // Cycle / repeated-pair guard for traversable containers.\n  // Allocates lazily on first nested-object descent.\n  const a = obj1 as object;\n  const b = obj2 as object;\n  if (seen?.get(a)?.has(b)) {\n    return true;\n  }\n  seen ??= new WeakMap<object, WeakSet<object>>();\n  rememberPair(seen, a, b);\n\n  if (Array.isArray(obj1)) {\n    const arr2 = obj2 as unknown[];\n    if (obj1.length !== arr2.length) {\n      return false;\n    }\n    for (let i = 0; i < obj1.length; i++) {\n      if (!fastDeepEqualInternal(obj1[i], arr2[i], seen)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  // Plain objects\n  const keys1 = Object.keys(a);\n  const o2 = b as Record<string, unknown>;\n  if (keys1.length !== Object.keys(o2).length) {\n    return false;\n  }\n  for (const key of keys1) {\n    if (!Object.hasOwn(o2, key)) {\n      return false;\n    }\n    if (\n      !fastDeepEqualInternal(\n        (a as Record<string, unknown>)[key],\n        o2[key],\n        seen\n      )\n    ) {\n      return false;\n    }\n  }\n  return true;\n}\n","import { InjectionToken } from '@angular/core';\nimport { fastDeepEqual } from '../utils/equality';\n\n/**\n * Signature of a deep-equality comparator. Must return `true` iff `a` and `b`\n * are considered equal for the purpose of change detection.\n */\nexport type NgxEqualityFn = (a: unknown, b: unknown) => boolean;\n\n/**\n * Injection token for the deep-equality function used internally by\n * {@link FormDirective} for change detection — `formValueChange`\n * `distinctUntilChanged`, the form↔model two-way sync effect, and the\n * `formState` signal's structural comparator.\n *\n * The default factory returns {@link fastDeepEqual}. Override this token to\n * plug in a smaller or differently-tuned comparator (e.g. `dequal/lite`,\n * `lodash.isEqual`) without forking the directive.\n *\n * @example Bring-your-own equality at the application level\n * ```ts\n * import { dequal } from 'dequal/lite';\n * import { NGX_EQUALITY_FN } from 'ngx-vest-forms';\n *\n * export const appConfig: ApplicationConfig = {\n *   providers: [\n *     { provide: NGX_EQUALITY_FN, useValue: dequal },\n *   ],\n * };\n * ```\n *\n * @example Per-component override (e.g. for tests)\n * ```ts\n * @Component({\n *   providers: [\n *     { provide: NGX_EQUALITY_FN, useValue: (a, b) => a === b },\n *   ],\n * })\n * export class TestFormComponent {}\n * ```\n *\n * @default {@link fastDeepEqual}\n */\nexport const NGX_EQUALITY_FN = new InjectionToken<NgxEqualityFn>(\n  'NgxEqualityFn',\n  {\n    providedIn: 'root',\n    factory: () => fastDeepEqual,\n  }\n);\n","import { DestroyRef } from '@angular/core';\n\n/**\n * Schedules a callback to run after a delay, automatically cancelling it if the\n * provided `DestroyRef` fires before the timer expires.\n *\n * @param callback - Function to invoke after the delay.\n * @param delayMs - Delay in milliseconds (passed to `setTimeout`).\n * @param destroyRef - Angular `DestroyRef` to register auto-cancellation against.\n * @returns A cancel function; calling it before the timer fires prevents the\n *          callback from running and unregisters the destroy listener.\n */\nexport function scheduleTimeout(\n  callback: () => void,\n  delayMs: number,\n  destroyRef: DestroyRef\n): () => void {\n  let cancelled = false;\n  let unregisterCalled = false;\n  // eslint-disable-next-line prefer-const -- assigned after onDestroy returns\n  let unregisterDestroy: (() => void) | undefined;\n\n  // Idempotent unregister wrapper so all paths (timer-fires, explicit-cancel,\n  // and onDestroy) can call it safely without double-removal.\n  const safeUnregister = () => {\n    if (unregisterCalled) return;\n    unregisterCalled = true;\n    unregisterDestroy?.();\n  };\n\n  const handle = setTimeout(() => {\n    safeUnregister();\n    if (!cancelled) {\n      callback();\n    }\n  }, delayMs);\n\n  unregisterDestroy = destroyRef.onDestroy(() => {\n    cancelled = true;\n    clearTimeout(handle);\n    safeUnregister();\n  });\n\n  return () => {\n    if (!cancelled) {\n      cancelled = true;\n      clearTimeout(handle);\n      safeUnregister();\n    }\n  };\n}\n\n/**\n * Schedules a microtask callback, automatically suppressing it if the provided\n * `DestroyRef` fires before the microtask runs.\n *\n * Since `queueMicrotask` has no native cancellation API, this relies on a\n * destroyed flag that is set inside the registered `onDestroy` hook.\n *\n * @param callback - Function to invoke in the next microtask checkpoint.\n * @param destroyRef - Angular `DestroyRef` to register auto-cancellation against.\n * @returns A cancel function; calling it before the microtask runs prevents the\n *          callback from executing and unregisters the destroy listener.\n */\nexport function scheduleMicrotask(\n  callback: () => void,\n  destroyRef: DestroyRef\n): () => void {\n  let cancelled = false;\n  let unregisterCalled = false;\n\n  // Register the onDestroy listener before queuing the microtask so that\n  // `unregisterDestroy` is always defined when the microtask fires.\n  const unregisterDestroy = destroyRef.onDestroy(() => {\n    cancelled = true;\n    safeUnregister();\n  });\n\n  // Idempotent unregister wrapper so all paths (microtask-fires, explicit-cancel,\n  // and onDestroy) can call it safely without double-removal.\n  function safeUnregister() {\n    if (unregisterCalled) return;\n    unregisterCalled = true;\n    unregisterDestroy();\n  }\n\n  queueMicrotask(() => {\n    // Always clean up the destroy listener when the microtask fires,\n    // regardless of whether the callback is suppressed.\n    safeUnregister();\n    if (!cancelled) {\n      callback();\n    }\n  });\n\n  return () => {\n    if (!cancelled) {\n      cancelled = true;\n      safeUnregister();\n    }\n  };\n}\n","/**\n * Utilities for working with field paths in dot/bracket notation and Standard Schema path arrays.\n *\n * These utilities help convert between:\n * - **Dot/bracket notation**: `'addresses[0].street'` (used in Angular forms and Vest)\n * - **Standard Schema paths**: `['addresses', 0, 'street']` (used in schema validation)\n *\n * @example\n * ```typescript\n * // Parse string path to array\n * parseFieldPath('user.addresses[0].street')\n * // Returns: ['user', 'addresses', 0, 'street']\n *\n * // Stringify array path to string\n * stringifyFieldPath(['user', 'addresses', 0, 'street'])\n * // Returns: 'user.addresses[0].street'\n * ```\n */\n\nconst UNSAFE_PATH_SEGMENTS = new Set(['__proto__', 'prototype', 'constructor']);\nconst LOG_PREFIX = '[ngx-vest-forms] field-path.utils';\n\n/**\n * @internal\n * Returns whether a path segment is unsafe for object writes/merges.\n *\n * Unsafe segments are blocked to prevent prototype pollution vectors.\n */\nexport function isUnsafePathSegment(segment: string | number): boolean {\n  return typeof segment === 'string' && UNSAFE_PATH_SEGMENTS.has(segment);\n}\n\n/**\n * @internal\n * Internal utility for parsing field path strings.\n *\n * **Not intended for external use.** While this function can parse field paths,\n * it's primarily used internally. Most users won't need to parse field paths manually.\n * If you do need this functionality, consider using your own implementation tailored\n * to your specific needs.\n *\n * Converts a dot/bracket notation path (e.g. `'addresses[0].street'`)\n * to a Standard Schema path array (e.g. `['addresses', 0, 'street']`).\n *\n * **Use cases:**\n * - Converting Angular form paths to schema-compatible arrays\n * - Parsing Vest field names for array access\n * - Processing validation error paths from different sources\n *\n * **Supported formats:**\n * - Dot notation: `'user.name'` → `['user', 'name']`\n * - Bracket notation: `'addresses[0]'` → `['addresses', 0]`\n * - Mixed: `'user.addresses[0].street'` → `['user', 'addresses', 0, 'street']`\n *\n * @param path - The dot/bracket notation path string\n * @returns Array of path segments (strings for properties, numbers for array indices)\n *\n * @example\n * ```typescript\n * parseFieldPath('email')              // ['email']\n * parseFieldPath('user.profile.name')  // ['user', 'profile', 'name']\n * parseFieldPath('items[0]')           // ['items', 0]\n * parseFieldPath('users[0].addresses[1].street')\n * // ['users', 0, 'addresses', 1, 'street']\n * ```\n */\nexport function parseFieldPath(path: string): Array<string | number> {\n  if (!path) return [];\n\n  // Normalize bracket notation to dot notation first so malformed inputs like\n  // 'a.[0]' (which becomes 'a..0') are caught alongside 'a..b', '.a', 'a.', '.'.\n  const startsWithBracket = path.startsWith('[');\n  const segments = path\n    .replaceAll(/\\[(\\d+)\\]/g, '.$1')\n    .split('.');\n\n  // Empty segments after normalization signal a malformed path. The single\n  // legitimate case is a leading empty produced by a path that originally\n  // started with '[' (e.g. '[0].x' → '.0.x' → ['', '0', 'x']).\n  for (let i = 0; i < segments.length; i++) {\n    if (segments[i] === '' && !(i === 0 && startsWithBracket)) {\n      if (typeof ngDevMode !== 'undefined' && ngDevMode) {\n        console.warn(\n          `${LOG_PREFIX}: Invalid field path '${path}'. Leading dots, trailing dots, consecutive dots, and '.[' separators are not allowed.`\n        );\n      }\n      return [];\n    }\n  }\n\n  return segments\n    .filter((part) => part !== '')\n    .map((part) => (/^\\d+$/.test(part) ? Number(part) : part));\n}\n\n/**\n * Converts a Standard Schema path array (e.g. `['addresses', 0, 'street']`)\n * to a dot/bracket notation string (e.g. `'addresses[0].street'`).\n *\n * **Use cases:**\n * - Converting schema validation paths to Angular form field names\n * - Generating Vest field names from path arrays\n * - Creating human-readable field identifiers\n *\n * **Format rules:**\n * - String segments joined with dots: `['user', 'name']` → `'user.name'`\n * - Number segments use brackets: `['items', 0]` → `'items[0]'`\n * - Mixed paths combine both: `['users', 0, 'email']` → `'users[0].email'`\n *\n * @param path - Array of path segments (strings for properties, numbers for indices)\n * @returns Dot/bracket notation path string\n *\n * @example\n * ```typescript\n * stringifyFieldPath(['email'])                     // 'email'\n * stringifyFieldPath(['user', 'profile', 'name'])   // 'user.profile.name'\n * stringifyFieldPath(['items', 0])                  // 'items[0]'\n * stringifyFieldPath(['users', 0, 'addresses', 1, 'street'])\n * // 'users[0].addresses[1].street'\n * ```\n */\nexport function stringifyFieldPath(path: Array<string | number>): string {\n  if (!path || path.length === 0) return '';\n\n  let result = '';\n\n  for (let i = 0; i < path.length; i++) {\n    const segment = path[i];\n\n    if (typeof segment === 'number') {\n      // Array index - add as bracket notation\n      result += `[${segment}]`;\n    } else {\n      // Property name - add with dot prefix if not first segment\n      if (i > 0) result += '.';\n      result += segment;\n    }\n  }\n\n  return result;\n}\n","export type NgxFirstInvalidOptions = {\n  /** Scroll animation behavior (default: `'smooth'`, or `'auto'` when reduced motion is preferred). */\n  behavior?: ScrollBehavior;\n  /** Vertical alignment when scrolling (default: `'center'`). */\n  block?: ScrollLogicalPosition;\n  /** Horizontal alignment when scrolling (default: `'nearest'`). */\n  inline?: ScrollLogicalPosition;\n  /** Whether to focus after scrolling (default: `true`). */\n  focus?: boolean;\n  /** Passed to `focus()` when focusing (default: `true`). */\n  preventScrollOnFocus?: boolean;\n  /** Opens ancestor `<details>` elements before scroll/focus (default: `true`). */\n  openCollapsedParents?: boolean;\n  /** Selector used to locate the first invalid element. */\n  invalidSelector?: string;\n  /** Selector used to resolve the best focus target within the invalid element. */\n  focusSelector?: string;\n};\n\nexport const DEFAULT_INVALID_SELECTOR = [\n  '.ngx-control-wrapper--invalid',\n  '.ngx-form-group-wrapper--invalid',\n  'input[aria-invalid=\"true\"]',\n  'textarea[aria-invalid=\"true\"]',\n  'select[aria-invalid=\"true\"]',\n].join(', ');\n\nexport const DEFAULT_FOCUS_SELECTOR = [\n  'input:not([type=\"hidden\"]):not([disabled])',\n  'textarea:not([disabled])',\n  'select:not([disabled])',\n  'button:not([disabled])',\n  'a[href]',\n  '[tabindex]:not([tabindex=\"-1\"]):not([disabled])',\n].join(', ');\n\n/**\n * Focus candidates that are already invalid.\n * This ensures invalid group wrappers focus a failing control before any valid sibling.\n */\nconst INVALID_FOCUS_PREFERRED_SELECTOR = [\n  'input[aria-invalid=\"true\"]:not([type=\"hidden\"]):not([disabled])',\n  'textarea[aria-invalid=\"true\"]:not([disabled])',\n  'select[aria-invalid=\"true\"]:not([disabled])',\n  '[aria-invalid=\"true\"][tabindex]:not([tabindex=\"-1\"]):not([disabled])',\n].join(', ');\n\nconst REDUCED_MOTION_MEDIA_QUERY = '(prefers-reduced-motion: reduce)';\n\nfunction prefersReducedMotion(): boolean {\n  return (\n    typeof globalThis.matchMedia === 'function' &&\n    globalThis.matchMedia(REDUCED_MOTION_MEDIA_QUERY).matches\n  );\n}\n\nexport function resolveFirstInvalidScrollBehavior(\n  behavior?: ScrollBehavior\n): ScrollBehavior {\n  if (behavior !== undefined) {\n    return behavior;\n  }\n  return prefersReducedMotion() ? 'auto' : 'smooth';\n}\n\nexport function resolveFirstInvalidElement(\n  root: HTMLFormElement,\n  invalidSelector: string\n): HTMLElement | null {\n  try {\n    const firstInvalid = root.querySelector(invalidSelector);\n    return firstInvalid instanceof HTMLElement ? firstInvalid : null;\n  } catch {\n    return null;\n  }\n}\n\nexport function openCollapsedDetailsAncestors(\n  root: HTMLFormElement,\n  element: HTMLElement\n): void {\n  let current: HTMLElement = element;\n  while (current !== root) {\n    const parentElement = current.parentElement;\n    if (!parentElement) {\n      break;\n    }\n\n    if (parentElement instanceof HTMLDetailsElement) {\n      parentElement.open = true;\n    }\n\n    current = parentElement;\n  }\n}\n\nexport function resolveFirstInvalidFocusTarget(\n  firstInvalid: HTMLElement,\n  focusSelector: string\n): HTMLElement | null {\n  const preferredInvalidTarget = firstInvalid.querySelector(\n    INVALID_FOCUS_PREFERRED_SELECTOR\n  );\n  if (preferredInvalidTarget instanceof HTMLElement) {\n    return preferredInvalidTarget;\n  }\n\n  try {\n    if (firstInvalid.matches(focusSelector)) {\n      return firstInvalid;\n    }\n\n    const fallbackTarget = firstInvalid.querySelector(focusSelector);\n    return fallbackTarget instanceof HTMLElement ? fallbackTarget : null;\n  } catch {\n    return null;\n  }\n}\n","export const ROOT_FORM = 'rootForm';\n","import {\n  AbstractControl,\n  FormArray,\n  FormGroup,\n  isFormArray,\n  isFormGroup,\n  ValidationErrors,\n} from '@angular/forms';\nimport { ROOT_FORM } from '../constants';\nimport {\n  isUnsafePathSegment,\n  parseFieldPath,\n  stringifyFieldPath,\n} from './field-path.utils';\n\ntype UnknownRecord = Record<string, unknown>;\n\ntype ControlWithOptionalName = AbstractControl & {\n  name?: unknown;\n};\n\ntype FormContainer = FormGroup | FormArray;\ntype ErrorList = string[] & { warnings?: string[] };\n\nconst ERROR_MESSAGES_KEY = 'errors';\nconst WARNING_MESSAGES_KEY = 'warnings';\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n  return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Recursively calculates the path of a form control\n * @param formGroup\n * @param control\n */\nfunction getChildEntries(\n  container: FormContainer\n): Array<[string, AbstractControl]> {\n  if (isFormArray(container)) {\n    return container.controls.map((child, index) => [String(index), child]);\n  }\n\n  return Object.entries(container.controls);\n}\n\nfunction getControlPath(\n  formGroup: FormGroup,\n  control: AbstractControl\n): string {\n  // First attempt: depth-first traversal from provided root\n  for (const [key, child] of getChildEntries(formGroup)) {\n    if (child === control) {\n      return key;\n    }\n    if (isFormGroup(child) || isFormArray(child)) {\n      const subPath = getControlPath(child as FormGroup, control);\n      if (subPath) {\n        return `${key}.${subPath}`;\n      }\n    }\n  }\n\n  // Fallback: walk up the parent chain from control to root\n  let current: AbstractControl | null | undefined = control;\n  const segments: string[] = [];\n  while (current?.parent) {\n    const parent: FormContainer = current.parent;\n    for (const [key, controlInParent] of getChildEntries(parent)) {\n      if (controlInParent === current) {\n        segments.unshift(key);\n        break;\n      }\n    }\n    current = parent;\n    if (current === formGroup) {\n      return segments.join('.');\n    }\n  }\n\n  // Last resort: try control.name if available\n  const name = (control as ControlWithOptionalName).name;\n  if (typeof name === 'string') {\n    return name;\n  }\n  return '';\n}\n\n/**\n * Recursively calculates the path of a form group\n * @param formGroup\n * @param control\n */\nfunction getGroupPath(formGroup: FormGroup, control: AbstractControl): string {\n  for (const [key, ctrl] of getChildEntries(formGroup)) {\n    if (ctrl === control) {\n      return key;\n    }\n    if (isFormGroup(ctrl)) {\n      const path = getGroupPath(ctrl, control);\n      if (path) {\n        return `${key}.${path}`;\n      }\n    }\n  }\n  return '';\n}\n\n/**\n * @internal\n * Internal utility for calculating form control field paths.\n *\n * **Not intended for external use.** This function is used internally by the library\n * to determine field names for validation. Use the `name` attribute on your form controls\n * instead of relying on this function.\n *\n * Calculates the field name of a form control: Eg: addresses.shippingAddress.street\n * @param rootForm\n * @param control\n */\nexport function getFormControlField(\n  rootForm: FormGroup,\n  control: AbstractControl\n): string {\n  return getControlPath(rootForm, control);\n}\n\n/**\n * @internal\n * Internal utility for calculating form group field paths.\n *\n * **Not intended for external use.** This function is used internally by the library\n * to determine field names for nested form groups.\n *\n * Calcuates the field name of a form group Eg: addresses.shippingAddress\n * @param rootForm\n * @param control\n */\nexport function getFormGroupField(\n  rootForm: FormGroup,\n  control: AbstractControl\n): string {\n  return getGroupPath(rootForm, control);\n}\n\n/**\n * @internal\n * Internal utility for merging form values with disabled field values.\n *\n * **Not intended for external use.** This function is used internally by the library\n * to include disabled field values in form submissions. Use Angular's `getRawValue()`\n * method on your form if you need to access disabled field values.\n *\n * This utility merges the value of the form with the raw value.\n * By doing this we can assure that we don't lose values of disabled form fields\n *\n * Security: Unsafe prototype-related keys (`__proto__`, `prototype`, `constructor`)\n * are skipped during recursive merge.\n * @param form\n */\nexport function mergeValuesAndRawValues<T>(form: FormGroup): T {\n  // Deep clone both values to prevent reference sharing.\n  // This is necessary because:\n  // 1. form.value may contain object references that could be mutated elsewhere\n  // 2. form.getRawValue() also returns references to form control values\n  // 3. Without cloning, mutations to the returned object would affect the original form state\n  // 4. The merge operation itself requires a mutable copy to work with\n  // Performance note: For large forms, this may have performance implications. However,\n  // reference isolation is critical for maintaining form state integrity.\n  const value = structuredClone(form.value);\n  const rawValue = structuredClone(form.getRawValue());\n\n  // Recursive function to merge rawValue into value\n  function mergeRecursive(target: UnknownRecord, source: UnknownRecord): void {\n    for (const key of Object.keys(source)) {\n      if (isUnsafePathSegment(key)) {\n        continue;\n      }\n\n      const sourceValue = source[key];\n      const targetValue = target[key];\n\n      if (targetValue === undefined || targetValue === null) {\n        // Key missing from target (e.g. disabled field) or set to null —\n        // copy source so raw values from disabled controls aren't dropped.\n        target[key] = sourceValue;\n      } else if (isRecord(sourceValue) && isRecord(targetValue)) {\n        // If the value is an object, merge it recursively\n        mergeRecursive(targetValue, sourceValue);\n      }\n      // If the target already has the key with a primitive value, it's left as is to maintain references\n    }\n  }\n\n  mergeRecursive(value as UnknownRecord, rawValue as UnknownRecord);\n  return value;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\ntype Primitive = undefined | null | boolean | string | number | Function;\n\nfunction isPrimitive(value: unknown): value is Primitive {\n  return (\n    value === null || (typeof value !== 'object' && typeof value !== 'function')\n  );\n}\n\nfunction getStringArrayError(\n  errors: ValidationErrors | null,\n  key: string\n): string[] | undefined {\n  const value = errors?.[key];\n  return Array.isArray(value)\n    ? value.filter((v): v is string => typeof v === 'string')\n    : undefined;\n}\n\n/**\n * Performs a deep-clone of an object.\n *\n * @deprecated Use the standard {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/structuredClone structuredClone} instead.\n *\n * `structuredClone` correctly handles `Map`, `Set`, `RegExp`, typed arrays, and\n * cyclic references; this implementation silently drops `Map` / `Set` / `RegExp`\n * data and produces incorrect results on cycles. Scheduled for removal in a\n * future major; see `docs/prd/PRD-bug-sweep.md` (Bundle D) for tracking.\n *\n * Browser Support: `structuredClone` is available in all modern browsers\n * (Chrome 98+, Firefox 94+, Safari 15.4+, Edge 98+) and Node.js 17+.\n */\nlet cloneDeepDeprecationWarned = false;\n\nexport function cloneDeep<T>(object: T): T {\n  // NOTE: `typeof ngDevMode !== 'undefined' && ngDevMode` is kept inline\n  // (not extracted to a helper) because Angular's build optimizer relies on\n  // this exact pattern for tree-shaking dev-only code from production bundles.\n  if (\n    !cloneDeepDeprecationWarned &&\n    typeof ngDevMode !== 'undefined' &&\n    ngDevMode\n  ) {\n    cloneDeepDeprecationWarned = true;\n    console.warn(\n      '[ngx-vest-forms] cloneDeep is deprecated and silently drops Map/Set/RegExp values. ' +\n        'Use the standard structuredClone() instead.'\n    );\n  }\n\n  // Handle primitives (null, undefined, boolean, string, number, function)\n  if (isPrimitive(object)) {\n    return object;\n  }\n\n  // Handle Date\n  if (object instanceof Date) {\n    return new Date(object) as T;\n  }\n\n  // Handle Array\n  if (Array.isArray(object)) {\n    return object.map((item) => cloneDeep(item)) as T;\n  }\n\n  // Handle Object\n  if (object instanceof Object) {\n    const clonedObject: UnknownRecord = {};\n    for (const key in object) {\n      if (Object.prototype.hasOwnProperty.call(object, key)) {\n        clonedObject[key] = cloneDeep(\n          (object as UnknownRecord)[key] as unknown\n        );\n      }\n    }\n    return clonedObject as T;\n  }\n\n  throw new Error(\"Unable to copy object! Its type isn't supported.\");\n}\n\n/**\n * Sets a value in an object at the provided field path.\n *\n * Supports dot and bracket notation via `parseFieldPath()`.\n * Examples: `user.profile.name`, `addresses[0].street`.\n *\n * Security: If any path segment matches an unsafe prototype-related key\n * (`__proto__`, `prototype`, `constructor`), the write is ignored.\n *\n * @param obj - Target object to mutate.\n * @param path - Dot/bracket field path.\n * @param value - Value to assign at the resolved path.\n */\nexport function setValueAtPath(\n  obj: object,\n  path: string,\n  value: unknown\n): void {\n  const keys = parseFieldPath(path);\n  if (keys.length === 0) {\n    return;\n  }\n\n  let current: UnknownRecord = obj as UnknownRecord;\n\n  for (let i = 0; i < keys.length - 1; i++) {\n    const segment = keys[i];\n    const nextSegment = keys[i + 1];\n    if (segment === undefined) {\n      continue;\n    }\n    if (isUnsafePathSegment(segment)) {\n      return;\n    }\n\n    const key = String(segment);\n\n    const next = current[key];\n    if (!Array.isArray(next) && !isRecord(next)) {\n      const shouldCreateArray =\n        typeof nextSegment === 'number' ||\n        (typeof nextSegment === 'string' && /^\\d+$/.test(nextSegment));\n      current[key] = shouldCreateArray ? [] : {};\n    }\n    current = current[key] as UnknownRecord;\n  }\n\n  const lastSegment = keys[keys.length - 1];\n  if (lastSegment === undefined || isUnsafePathSegment(lastSegment)) {\n    return;\n  }\n\n  current[String(lastSegment)] = value;\n}\n\n/**\n * @deprecated Use {@link setValueAtPath} instead\n */\nexport function set(obj: object, path: string, value: unknown): void {\n  return setValueAtPath(obj, path, value);\n}\n\n/**\n * @internal\n * Internal utility for collecting all form errors by field path.\n *\n * **Not intended for external use.** This function is used internally by the library\n * to generate the form state. Use the `formState()` signal from the `scVestForm` directive\n * to access form errors in your components.\n *\n * Traverses the form and returns the errors by path\n * @param form\n */\nexport function getAllFormErrors(\n  form?: AbstractControl\n): Record<string, string[]> {\n  const errors: Record<string, ErrorList> = {};\n  if (!form) {\n    return errors;\n  }\n\n  // Collect root form errors (from ValidateRootFormDirective) before processing children\n  if (form.enabled) {\n    const rootErrors = getStringArrayError(form.errors, ERROR_MESSAGES_KEY);\n    if (rootErrors) {\n      errors[ROOT_FORM] = rootErrors;\n    }\n  }\n\n  function collect(\n    control: AbstractControl,\n    pathParts: Array<string | number>\n  ): void {\n    const pathString = stringifyFieldPath(pathParts);\n\n    // Skip processing the root form control directly in NgxFormDirective\n    if (pathParts.length === 0 && control === form) {\n      // Instead, iterate its children if it's a group/array\n      if (isFormGroup(control) || isFormArray(control)) {\n        for (const [key, childControl] of getChildEntries(control)) {\n          const numericKey = Number(key);\n          const nextPath = [\n            // ...pathParts, // pathParts is empty here\n            Number.isNaN(numericKey) ? key : numericKey,\n          ];\n          collect(childControl, nextPath);\n        }\n      }\n      return; // Stop processing for the root form itself at this level\n    }\n\n    if (isFormGroup(control) || isFormArray(control)) {\n      for (const [key, childControl] of getChildEntries(control)) {\n        const numericKey = Number(key);\n        const nextPath = [\n          ...pathParts,\n          Number.isNaN(numericKey) ? key : numericKey,\n        ];\n        collect(childControl, nextPath);\n      }\n    }\n\n    // Attach control errors (both errors and warnings)\n    if (control.enabled) {\n      const fieldErrors = getStringArrayError(\n        control.errors,\n        ERROR_MESSAGES_KEY\n      );\n      if (fieldErrors) {\n        errors[pathString] = fieldErrors;\n      }\n      // Optionally, add warnings if present\n      const fieldWarnings = getStringArrayError(\n        control.errors,\n        WARNING_MESSAGES_KEY\n      );\n      if (fieldWarnings) {\n        // Attach warnings as a property on the error array (non-enumerable)\n        // This is still done here for field-specific warnings, but not for root warnings.\n        if (!errors[pathString]) {\n          errors[pathString] = []; // Ensure array exists if only warnings are present\n        }\n        Object.defineProperty(errors[pathString], 'warnings', {\n          value: fieldWarnings,\n          enumerable: false, // Keep it non-enumerable as per previous behavior for field warnings\n          configurable: true,\n          writable: true,\n        });\n      }\n    }\n  }\n\n  collect(form, []);\n\n  // Root form errors (form.errors) are no longer processed here.\n  // They are handled directly in NgxFormDirective to populate formState.root.\n\n  return errors;\n}\n","import { isDevMode } from '@angular/core';\nimport { NGX_VEST_FORMS_ERRORS, logWarning } from '../errors/error-catalog';\n\nconst NUMERIC_PATH_SEGMENT = /^\\d+$/;\ntype TraversableShapeValue = Record<string, unknown> | unknown[];\n\nfunction isOpaqueLeafValue(value: unknown): boolean {\n  return (\n    value instanceof Date ||\n    value instanceof Map ||\n    value instanceof Set ||\n    value instanceof RegExp ||\n    (typeof File !== 'undefined' && value instanceof File) ||\n    (typeof Blob !== 'undefined' && value instanceof Blob)\n  );\n}\n\nfunction isTraversableValue(value: unknown): value is TraversableShapeValue {\n  return typeof value === 'object' && value !== null && !isOpaqueLeafValue(value);\n}\n\n/**\n * Validates a form value against a shape to catch typos in `name` or `ngModelGroup` attributes.\n *\n * **What it checks:**\n * - Extra properties: Keys in formValue that don't exist in shape (likely typos)\n * - Type mismatches: When formValue has an object but shape expects a primitive\n *\n * **What it does NOT check:**\n * - Missing properties: Keys in shape that don't exist in formValue\n *   (forms build incrementally with `NgxDeepPartial`, and `@if` conditionally renders fields)\n *\n * Only runs in development mode.\n *\n * @param formVal - The current form value\n * @param shape - The expected shape (created with `NgxDeepRequired<T>`)\n */\nexport function validateShape<\n  T extends Record<string, unknown>,\n  U extends Record<string, unknown>,\n>(formVal: T, shape: U): void {\n  if (isDevMode()) {\n    validateFormValueAgainstShape(formVal, shape);\n  }\n}\n\n/**\n * Recursively validates form value keys against the shape.\n * Reports warnings for extra properties and type mismatches.\n */\nfunction validateFormValueAgainstShape(\n  formValue: Record<string, unknown>,\n  shape: Record<string, unknown>,\n  path = ''\n): void {\n  for (const key of Object.keys(formValue)) {\n    const value = formValue[key];\n    const fieldPath = path ? `${path}.${key}` : key;\n\n    // Skip null/undefined values (valid during form initialization)\n    if (value == null) {\n      continue;\n    }\n\n    // For array items (numeric keys > 0), compare against the first item in shape\n    // since we only define one example item in the shape for arrays\n    const isNumericKey = NUMERIC_PATH_SEGMENT.test(key);\n    // Array shapes provide one example item at index 0, so every numeric key maps to '0'.\n    const shapeKey = isNumericKey && key !== '0' ? '0' : key;\n    const shapeValue = shape?.[shapeKey];\n    const hasShapeKey = shape != null && shapeKey in shape;\n\n    // Skip Date fields receiving empty strings (common in date picker libraries)\n    if (shapeValue instanceof Date && value === '') {\n      continue;\n    }\n\n    // Handle object values (recurse into nested objects)\n    if (typeof value === 'object') {\n      if (!isTraversableValue(value)) {\n        if (!isNumericKey && !hasShapeKey) {\n          logWarning(NGX_VEST_FORMS_ERRORS.EXTRA_PROPERTY, fieldPath);\n        } else if (\n          !isNumericKey &&\n          hasShapeKey &&\n          (shapeValue === null || typeof shapeValue !== 'object')\n        ) {\n          // Type mismatch: formValue holds an opaque object (Date, Map, etc.)\n          // but shape declares a primitive. Recursion is intentionally skipped\n          // for opaque leaves, but the user still benefits from a warning.\n          logWarning(\n            NGX_VEST_FORMS_ERRORS.TYPE_MISMATCH,\n            fieldPath,\n            'primitive',\n            'object'\n          );\n        }\n        continue;\n      }\n\n      // Type mismatch: formValue has object, but shape expects primitive\n      if (!isNumericKey && !isTraversableValue(shapeValue)) {\n        logWarning(\n          NGX_VEST_FORMS_ERRORS.TYPE_MISMATCH,\n          fieldPath,\n          'primitive',\n          'object'\n        );\n      }\n\n      // Recurse into nested object\n      validateFormValueAgainstShape(\n        value as Record<string, unknown>,\n        isTraversableValue(shapeValue) ? (shapeValue as Record<string, unknown>) : {},\n        fieldPath\n      );\n      continue;\n    }\n\n    // Extra property: key exists in formValue but not in shape (likely a typo)\n    if (!isNumericKey && !hasShapeKey) {\n      logWarning(NGX_VEST_FORMS_ERRORS.EXTRA_PROPERTY, fieldPath);\n    }\n  }\n}\n","import { signal, WritableSignal } from '@angular/core';\nimport { NgForm } from '@angular/forms';\n\nconst formSubmittedSignals = new WeakMap<NgForm, WritableSignal<boolean>>();\n\ntype AngularSubmittedSignalHost = {\n  submittedReactive?: WritableSignal<boolean>;\n  _submittedReactive?: WritableSignal<boolean>;\n};\n\nexport function getFormSubmittedSignal(\n  ngForm: NgForm\n): WritableSignal<boolean> {\n  let submitted = formSubmittedSignals.get(ngForm);\n  if (!submitted) {\n    submitted = signal(ngForm.submitted);\n    formSubmittedSignals.set(ngForm, submitted);\n  }\n  return submitted;\n}\n\nexport function setAngularFormSubmittedState(\n  ngForm: NgForm,\n  submitted: boolean\n): void {\n  // Angular 21.x's concrete NgForm stores submitted state on\n  // `submittedReactive`, while AbstractFormDirective-backed implementations\n  // expose `_submittedReactive` and may also provide a public setter on\n  // `submitted`. This helper is verified against Angular 21.x in this\n  // repository and falls back to the first writable `submitted` setter it can\n  // find if a future Angular version changes the concrete field names.\n  //\n  // We try the concrete/internal signal first because NgForm overrides the\n  // getter-only `submitted` property at runtime in this workspace. If neither\n  // signal exists, fall back to the first writable `submitted` setter we can\n  // find on the prototype chain. If no setter exists either, callers should\n  // still update ngx-vest-forms' shared signal so error display state remains\n  // reactive even though Angular's native submitted flag cannot be changed.\n  const signalHost = ngForm as unknown as AngularSubmittedSignalHost;\n  const angularSignal =\n    signalHost.submittedReactive ?? signalHost._submittedReactive;\n\n  if (angularSignal) {\n    angularSignal.set(submitted);\n    return;\n  }\n\n  let prototype: object | null = Object.getPrototypeOf(ngForm);\n  while (prototype) {\n    const submittedDescriptor = Object.getOwnPropertyDescriptor(\n      prototype,\n      'submitted'\n    );\n    if (submittedDescriptor?.set) {\n      submittedDescriptor.set.call(ngForm, submitted);\n      return;\n    }\n    prototype = Object.getPrototypeOf(prototype);\n  }\n}\n","import {\n  ChangeDetectorRef,\n  computed,\n  DestroyRef,\n  Directive,\n  effect,\n  ElementRef,\n  inject,\n  input,\n  InputSignal,\n  isDevMode,\n  linkedSignal,\n  output,\n  signal,\n  untracked,\n} from '@angular/core';\nimport {\n  outputFromObservable,\n  takeUntilDestroyed,\n  toObservable,\n  toSignal,\n} from '@angular/core/rxjs-interop';\nimport {\n  AbstractControl,\n  AsyncValidatorFn,\n  ControlValueAccessor,\n  FormArray,\n  FormGroup,\n  NgForm,\n  NgModel,\n  PristineChangeEvent,\n  StatusChangeEvent,\n  ValidationErrors,\n  ValueChangeEvent,\n} from '@angular/forms';\nimport {\n  catchError,\n  debounceTime,\n  distinctUntilChanged,\n  EMPTY,\n  filter,\n  map,\n  Observable,\n  of,\n  race,\n  merge as rxMerge,\n  scan,\n  startWith,\n  switchMap,\n  take,\n  tap,\n  timer,\n} from 'rxjs';\nimport { logWarning, NGX_VEST_FORMS_ERRORS } from '../errors/error-catalog';\nimport { NGX_VALIDATION_CONFIG_DEBOUNCE_TOKEN } from '../tokens/debounce.token';\nimport { DeepRequired } from '../utils/deep-required';\nimport { NGX_EQUALITY_FN } from '../tokens/equality.token';\nimport {\n  scheduleMicrotask,\n  scheduleTimeout,\n} from '../utils/destroy-scheduler';\nimport type { ValidationConfigMap } from '../utils/field-path-types';\nimport { stringifyFieldPath } from '../utils/field-path.utils';\nimport {\n  DEFAULT_FOCUS_SELECTOR,\n  DEFAULT_INVALID_SELECTOR,\n  type NgxFirstInvalidOptions,\n  openCollapsedDetailsAncestors,\n  resolveFirstInvalidElement,\n  resolveFirstInvalidFocusTarget,\n  resolveFirstInvalidScrollBehavior,\n} from '../utils/first-invalid.utils';\nimport { NgxFormState } from '../utils/form-state.utils';\nimport {\n  getAllFormErrors,\n  mergeValuesAndRawValues,\n  setValueAtPath,\n} from '../utils/form-utils';\nimport { validateShape } from '../utils/shape-validation';\nimport { NgxTypedVestSuite, NgxVestSuite } from '../utils/validation-suite';\nimport {\n  getFormSubmittedSignal,\n  setAngularFormSubmittedState,\n} from './form-submitted-state';\nimport { ValidationOptions } from './validation-options';\n\n/**\n * Duration (in milliseconds) to keep fields marked as \"in-progress\" after validation.\n * This prevents immediate re-triggering of bidirectional validations.\n * Increased from 100ms to 500ms to give validators enough time to complete and propagate.\n */\nconst VALIDATION_IN_PROGRESS_TIMEOUT_MS = 500;\n\n/**\n * Type for validation configuration that accepts both the typed and untyped versions.\n * This ensures backward compatibility while supporting the new typed API.\n */\nexport type NgxValidationConfig<T = unknown> =\n  | Record<string, string[]>\n  | ValidationConfigMap<T>\n  | null;\n\n/**\n * Payload emitted when a named control inside the form loses focus.\n *\n * This is intentionally low-level so app code can build workflows such as\n * draft auto-save, analytics, or blur-driven side effects without the form\n * library taking ownership of persistence behavior.\n *\n * It is not intended as a blur-time workaround for dependent field validation;\n * for that pattern, prefer `validationConfig` plus each target field's own\n * `errorDisplayMode`.\n *\n * The emitted `field` is the full dotted control path (e.g.\n * `passwords.confirm`, `businessHours.values.0.from`) regardless of whether\n * the surrounding groups use static `ngModelGroup=\"key\"` or dynamic\n * `[ngModelGroup]=\"expr\"` bindings, because the path is read from the live\n * `NgModel` directive registered with the form.\n *\n * @publicApi\n */\nexport type NgxFieldBlurEvent<T = unknown> = {\n  field: string;\n  value: unknown;\n  formValue: T | null;\n  dirty: boolean;\n  touched: boolean;\n  valid: boolean;\n  pending: boolean;\n};\n\n/**\n * Main form directive for ngx-vest-forms that bridges Angular template-driven forms with Vest.js validation.\n *\n * This directive provides:\n * - **Unidirectional data flow**: Use `[ngModel]` (not `[(ngModel)]`) with `(formValueChange)` for predictable state updates\n * - **Vest.js integration**: Automatic async validators from Vest suites with field-level optimization\n * - **Validation dependencies**: Configure cross-field validation triggers via `validationConfig`\n * - **Form state**: Access validity, errors, and values through the `formState` signal\n *\n * @usageNotes\n *\n * ### Basic Usage\n * ```html\n * <form ngxVestForm [suite]=\"validationSuite\" (formValueChange)=\"formValue.set($event)\">\n *   <input name=\"email\" [ngModel]=\"formValue().email\" />\n * </form>\n * ```\n *\n * ### With Validation Dependencies\n * ```html\n * <form ngxVestForm [suite]=\"suite\" [validationConfig]=\"validationConfig\">\n *   <input name=\"password\" [ngModel]=\"formValue().password\" />\n *   <input name=\"confirmPassword\" [ngModel]=\"formValue().confirmPassword\" />\n * </form>\n * ```\n * ```typescript\n * validationConfig = { 'password': ['confirmPassword'] };\n * ```\n *\n * ### Accessing Form State\n * ```typescript\n * vestForm = viewChild.required('vestForm', { read: FormDirective });\n * isValid = computed(() => this.vestForm().formState().valid);\n * ```\n *\n * @see {@link https://github.com/ngx-vest-forms/ngx-vest-forms} for full documentation\n * @publicApi\n */\n@Directive({\n  selector: 'form[scVestForm], form[ngxVestForm]',\n  exportAs: 'scVestForm, ngxVestForm',\n  host: {\n    '(focusout)': 'onFormFocusOut($event)',\n  },\n})\nexport class FormDirective<T extends Record<string, unknown>> {\n  readonly ngForm = inject(NgForm, { self: true });\n  private readonly elementRef = inject(ElementRef<HTMLFormElement>);\n  private readonly destroyRef = inject(DestroyRef);\n  private readonly cdr = inject(ChangeDetectorRef);\n  private readonly configDebounceTime = inject(\n    NGX_VALIDATION_CONFIG_DEBOUNCE_TOKEN\n  );\n  /**\n   * Deep-equality comparator. Defaults to `fastDeepEqual`; can be overridden\n   * application-wide or per-component via {@link NGX_EQUALITY_FN}.\n   */\n  readonly #equal = inject(NGX_EQUALITY_FN);\n\n  /**\n   * Public signal storing field warnings keyed by field path.\n   * This allows warnings to be stored and displayed without affecting field validity.\n   * Angular's control.errors !== null marks a field as invalid, so we store warnings\n   * separately when they exist without errors.\n   */\n  readonly fieldWarnings = signal<Map<string, readonly string[]>>(new Map());\n\n  /**\n   * Set to true by the onDestroy hook. Used to guard async callbacks\n   * (e.g. Vest `done()`) that cannot be cancelled via RxJS operators.\n   */\n  #destroyed = false;\n\n  #lastSyncedFormValue: T | null = null;\n  #lastSyncedModelValue: T | null = null;\n\n  // Internal signal tracking changes that can affect the merged form snapshot.\n  // ValueChangeEvent keeps the cache fresh for blur-driven consumers like\n  // draft auto-save, even when a value update doesn't change form validity.\n  readonly #formSnapshotTick = toSignal(\n    this.ngForm.form.events.pipe(\n      filter(\n        (event) =>\n          event instanceof ValueChangeEvent || event instanceof StatusChangeEvent\n      ),\n      scan((count) => count + 1, 0),\n      startWith(0)\n    ),\n    { initialValue: 0 }\n  );\n\n  /**\n   * LinkedSignal that computes form values from Angular form state.\n   * This eliminates timing issues with the previous dual-effect pattern.\n   */\n  readonly #formValueSignal = linkedSignal(() => {\n    // Track changes that affect the merged form snapshot.\n    this.#formSnapshotTick();\n    if (Object.keys(this.ngForm.form.controls).length === 0) {\n      // No controls remain (e.g. dynamic group removal): expose `null` so\n      // consumers don't see ghost data from a previous form shape.\n      return null;\n    }\n    return mergeValuesAndRawValues<T>(this.ngForm.form);\n  });\n\n  /**\n   * Track the Angular form status as a signal for advanced status flags\n   */\n  readonly #statusSignal = toSignal(\n    this.ngForm.form.statusChanges.pipe(startWith(this.ngForm.form.status)),\n    { initialValue: this.ngForm.form.status }\n  );\n\n  /**\n   * Reactive counter incremented on any focusout within the form.\n   * This guarantees recomputation for every blur/tab interaction,\n   * even when the form's aggregate touched flag is already true.\n   */\n  readonly #blurTick = signal(0);\n\n  /**\n   * Computed signal that returns field paths for all touched (or submitted) leaf controls.\n   * Updates reactively when controls are touched (blur) or when form status changes.\n   *\n   * This enables consumers to determine which fields the user has interacted with,\n   * useful for filtering errors/warnings to match the form's visible validation state.\n   *\n   * @publicApi\n   */\n  readonly touchedFieldPaths = computed(() => {\n    this.#blurTick();\n    this.#statusSignal();\n    return this.#collectTouchedPaths(this.ngForm.form, this.ngForm.submitted);\n  });\n\n  /**\n   * Computed signal for form state with validity and errors.\n   * Used by templates and tests as vestForm.formState().valid/errors\n   *\n   * Uses custom equality function to prevent unnecessary recalculations\n   * when form status changes but actual values/errors remain the same.\n   */\n  readonly formState = computed<NgxFormState<T>>(\n    () => {\n      // Tie to validation feedback instead of aggregate status so errors update\n      // even when the root form remains INVALID -> INVALID.\n      this.#validationFeedbackTick();\n      return {\n        valid: this.ngForm.form.valid,\n        errors: getAllFormErrors(this.ngForm.form),\n        value: this.#formValueSignal(),\n      };\n    },\n    {\n      equal: (a, b) => {\n        // Fast path: reference equality\n        if (a === b) return true;\n        // Null/undefined check\n        if (!a || !b) return false;\n        // Deep equality check for form state properties\n        return (\n          a.valid === b.valid &&\n          this.#equal(a.errors, b.errors) &&\n          this.#equal(a.value, b.value)\n        );\n      },\n    }\n  );\n\n  /**\n   * The value of the form, this is needed for the validation part.\n   * Using input() here because two-way binding is provided via formValueChange output.\n   * In the minimal core directive (form-core.directive.ts), this would be model() instead.\n   */\n  readonly formValue = input<T | null>(null);\n\n  /**\n   * Static vest suite that will be used to feed our angular validators.\n   * Accepts both NgxVestSuite and NgxTypedVestSuite through compatible type signatures.\n   * NgxTypedVestSuite<T> is assignable to NgxVestSuite<T> due to bivariance and\n   * FormFieldName<T> (string literal union) being assignable to string.\n   */\n  readonly suite = input<NgxVestSuite<T> | NgxTypedVestSuite<T> | null>(null);\n\n  /**\n   * The shape of our form model. This is a deep required version of the form model\n   * The goal is to add default values to the shape so when the template-driven form\n   * contains values that shouldn't be there (typo's) that the developer gets run-time\n   * errors in dev mode\n   */\n  readonly formShape = input<DeepRequired<T> | null>(null);\n\n  /**\n   * Updates the validation config which is a dynamic object that will be used to\n   * trigger validations on the dependant fields\n   * Eg: ```typescript\n   * validationConfig = {\n   *     'passwords.password': ['passwords.confirmPassword']\n   * }\n   * ```\n   *\n   * This will trigger the updateValueAndValidity on passwords.confirmPassword every time the passwords.password gets a new value\n   *\n   * @param v\n   */\n  readonly validationConfig: InputSignal<NgxValidationConfig<T>> =\n    input<NgxValidationConfig<T>>(null);\n\n  /**\n   * Emits whenever validation feedback may have changed, even if the aggregate\n   * root form status string stays the same.\n   */\n  private readonly validationFeedback$ = rxMerge(\n    this.ngForm.form.events.pipe(\n      filter((v) => v instanceof StatusChangeEvent),\n      map((v) => (v as StatusChangeEvent).status),\n      filter((v) => v !== 'PENDING')\n    ),\n    this.ngForm.ngSubmit.pipe(\n      switchMap(() => {\n        if (this.ngForm.form.status === 'PENDING') {\n          return this.ngForm.form.statusChanges.pipe(\n            filter((status) => status !== 'PENDING'),\n            take(1)\n          );\n        }\n\n        return of(this.ngForm.form.status);\n      })\n    )\n  );\n\n  /**\n   * Counter signal tied to validation feedback updates so `formState()` can\n   * recompute whenever the underlying error set changes.\n   */\n  readonly #validationFeedbackTick = toSignal(\n    this.validationFeedback$.pipe(\n      scan((count) => count + 1, 0),\n      startWith(0)\n    ),\n    { initialValue: 0 }\n  );\n\n  private readonly pending$ = this.ngForm.form.events.pipe(\n    filter((v) => v instanceof StatusChangeEvent),\n    map((v) => (v as StatusChangeEvent).status),\n    filter((v) => v === 'PENDING'),\n    distinctUntilChanged()\n  );\n\n  /**\n   * Emits every time the form status changes in a state\n   * that is not PENDING\n   * We need this to assure that the form is in 'idle' state\n   */\n  readonly idle$ = this.ngForm.form.events.pipe(\n    filter((v) => v instanceof StatusChangeEvent),\n    map((v) => (v as StatusChangeEvent).status),\n    filter((v) => v !== 'PENDING'),\n    distinctUntilChanged()\n  );\n\n  /**\n   * Triggered as soon as the form value changes\n   * It also contains the disabled values (raw values)\n   *\n   * Cleanup is handled automatically by the directive when it's destroyed.\n   */\n  readonly formValueChange = outputFromObservable(\n    this.ngForm.form.events.pipe(\n      filter((v) => v instanceof ValueChangeEvent),\n      map((v) => (v as ValueChangeEvent<unknown>).value),\n      distinctUntilChanged((prev, curr) => {\n        // Use efficient deep equality instead of JSON.stringify for better performance\n        return this.#equal(prev, curr);\n      }),\n      map(() => mergeValuesAndRawValues<T>(this.ngForm.form)),\n      takeUntilDestroyed(this.destroyRef)\n    )\n  );\n\n  /**\n   * Emits an object with all the errors of the form\n   * every time a form control or form groups changes its status to valid or invalid\n   *\n   * For submit events, waits for async validation (including ROOT_FORM) to complete\n   * before emitting errors. This ensures ROOT_FORM errors are included in the output.\n   *\n   * Cleanup is handled automatically by the directive when it's destroyed.\n   */\n  readonly errorsChange = outputFromObservable(\n    this.validationFeedback$.pipe(\n      map(() => getAllFormErrors(this.ngForm.form)),\n      takeUntilDestroyed(this.destroyRef)\n    )\n  );\n\n  /**\n   * Triggered as soon as the form becomes dirty\n   *\n   * Cleanup is handled automatically by the directive when it's destroyed.\n   */\n  readonly dirtyChange = outputFromObservable(\n    this.ngForm.form.events.pipe(\n      filter((v) => v instanceof PristineChangeEvent),\n      map((v) => !(v as PristineChangeEvent).pristine),\n      startWith(this.ngForm.form.dirty),\n      distinctUntilChanged(),\n      takeUntilDestroyed(this.destroyRef)\n    )\n  );\n\n  /**\n   * Fired when the status of the root form changes.\n   */\n  private readonly statusChanges$ = this.ngForm.form.statusChanges.pipe(\n    startWith(this.ngForm.form.status),\n    distinctUntilChanged()\n  );\n\n  /**\n   * Triggered When the form becomes valid but waits until the form is idle\n   *\n   * Cleanup is handled automatically by the directive when it's destroyed.\n   */\n  readonly validChange = outputFromObservable(\n    this.statusChanges$.pipe(\n      filter((e) => e === 'VALID' || e === 'INVALID'),\n      map((v) => v === 'VALID'),\n      distinctUntilChanged(),\n      takeUntilDestroyed(this.destroyRef)\n    )\n  );\n\n  /**\n   * Emits when a named control inside the form loses focus.\n   *\n   * Useful for application-level workflows such as draft auto-save on blur.\n   */\n  readonly fieldBlur = output<NgxFieldBlurEvent<T>>();\n\n  /**\n   * Track validation in progress to prevent circular triggering (Issue #19)\n   */\n  private readonly validationInProgress = new Set<string>();\n\n  constructor() {\n    this.destroyRef.onDestroy(() => {\n      this.#destroyed = true;\n      this.fieldWarnings.set(new Map());\n    });\n\n    /**\n     * Trigger shape validations if the form gets updated\n     * This is how we can throw run-time errors\n     */\n    if (isDevMode()) {\n      effect(() => {\n        const v = this.formValue();\n        if (v && this.formShape()) {\n          validateShape(v, this.formShape() as DeepRequired<T>);\n        }\n      });\n    }\n\n    /**\n     * Mark all the fields as touched when the form is submitted\n     */\n    this.ngForm.ngSubmit\n      .pipe(takeUntilDestroyed(this.destroyRef))\n      .subscribe(() => {\n        this.ngForm.form.markAllAsTouched();\n        this.#blurTick.update((v) => v + 1);\n      });\n\n    /**\n     * Single bidirectional synchronization effect using linkedSignal.\n     * Uses proper deep comparison and change tracking for correct sync direction.\n     * Note: formValue is read-only input(), so we emit changes via formValueChange output.\n     */\n    effect(() => {\n      const formValue = this.#formValueSignal();\n      const modelValue = this.formValue();\n\n      // Skip if either is null\n      if (!formValue && !modelValue) return;\n\n      // Compute change flags first\n      const formChanged = !this.#equal(formValue, this.#lastSyncedFormValue);\n      const modelChanged = !this.#equal(\n        modelValue,\n        this.#lastSyncedModelValue\n      );\n\n      // Early return if nothing changed\n      if (!formChanged && !modelChanged) {\n        return;\n      }\n\n      if (formChanged && !modelChanged) {\n        // Form was modified by user -> form wins\n        // Note: We can't call this.formValue.set() since it's an input()\n        // The formValueChange output will emit the new value\n        // Use untracked() to avoid infinite loops - we're updating tracking state here\n        untracked(() => {\n          this.#lastSyncedFormValue = formValue;\n          this.#lastSyncedModelValue = formValue;\n        });\n      } else if (modelChanged && !formChanged) {\n        // Model was modified programmatically -> model wins\n        // Use untracked() to avoid infinite loops - we're updating tracking state here\n        untracked(() => {\n          // Update form controls with new model values\n          if (modelValue) {\n            // IMPORTANT: Use root patchValue instead of per-key setValue.\n            // - Supports nested objects (ngModelGroup) without throwing when partial objects are provided.\n            // - patchValue ignores missing controls/keys, which is compatible with DeepPartial form models.\n            // - emitEvent:false prevents feedback loops; validation still updates internally.\n            this.ngForm.form.patchValue(modelValue, { emitEvent: false });\n          }\n          this.#lastSyncedFormValue = modelValue;\n          this.#lastSyncedModelValue = modelValue;\n        });\n      } else if (formChanged && modelChanged) {\n        // Both form and model changed simultaneously\n        // Check if they changed to the same value (synchronized change) or different values (conflict)\n        const valuesEqual = this.#equal(formValue, modelValue);\n\n        if (valuesEqual) {\n          // Both changed to the same value - this is a synchronized change, not a conflict\n          // Just update tracking to acknowledge the change\n          untracked(() => {\n            this.#lastSyncedFormValue = formValue;\n            this.#lastSyncedModelValue = formValue;\n          });\n        } else {\n          // Both changed to different values - this is a true conflict\n          // This is an edge case that should rarely happen in practice.\n          // We intentionally do nothing here to avoid breaking the Angular event flow.\n          // The form will continue with its current values, and validation will run normally.\n          // The next change (either form or model) will trigger proper synchronization.\n        }\n      }\n    });\n\n    // Set up validation config reactively\n    this.#setupValidationConfig();\n  }\n\n  /**\n   * Manually trigger form validation update.\n   *\n   * This is useful when form structure changes but no control values change,\n   * which means validation state might be stale. This method forces a re-evaluation\n   * of all form validators and updates the form validity state.\n   *\n   * **IMPORTANT: This method validates ALL form fields by design.**\n   * This is intentional for structure changes as conditional validators may now\n   * apply to different fields, requiring a complete validation refresh.\n   *\n   * **CRITICAL: This method does NOT mark fields as touched or show errors.**\n   * It only re-runs validation logic. To show all errors (e.g., on submit),\n   * use `markAllAsTouched()` instead or in combination.\n   *\n   * **When to use each:**\n   * - `triggerFormValidation()` - Re-run validation when structure changes\n   * - `markAllAsTouched()` - Show all errors to user (e.g., on submit)\n   * - Both together - Rare, only if structure changed AND you want to show errors\n   *\n   * **Note on form submission:**\n   * When using the default error display mode (`on-blur-or-submit`), you typically\n   * don't need to call this method on submit. The form directive automatically marks\n   * all fields as touched on `ngSubmit`, and errors will display automatically.\n   * Only use this method when form structure changes without value changes.\n   *\n   * **Use Cases:**\n   * - Conditionally showing/hiding form controls based on other field values\n   * - Adding or removing form controls dynamically\n   * - Switching between different form layouts where validation requirements change\n   * - Any scenario where form structure changes but no ValueChangeEvent is triggered\n   *\n   * **Example:**\n   * When switching from a form with required input fields to one with only informational content,\n   * the form should become valid, but this won't happen automatically\n   * when no value changes occur (e.g., switching from input fields to informational content).\n   *\n   * **Performance Note:**\n   * This method calls `updateValueAndValidity({ emitEvent: true })` on the root form,\n   * which validates all form controls. For large forms, consider if more granular\n   * validation updates are possible.\n   *\n   * @example\n   * ```typescript\n   * /// After changing form structure\n   * onProcedureTypeChange(newType: string) {\n   *   this.procedureType.set(newType);\n   *   /// Structure changed but no control values changed\n   *   this.formDirective.triggerFormValidation();\n   * }\n   *\n   * /// For submit with multiple forms (show all errors)\n   * submitAll() {\n   *   // Mark all as touched to show errors\n   *   this.form1Ref().markAllAsTouched();\n   *   this.form2Ref().markAllAsTouched();\n   *   // Only needed if structure changed without value changes\n   *   // this.form1Ref().triggerFormValidation();\n   *   // this.form2Ref().triggerFormValidation();\n   * }\n   * ```\n   */\n  triggerFormValidation(path?: string): void {\n    if (path) {\n      const control = this.ngForm.form.get(path);\n      if (control) {\n        control.updateValueAndValidity({ emitEvent: true });\n      } else if (isDevMode()) {\n        logWarning(NGX_VEST_FORMS_ERRORS.CONTROL_NOT_FOUND, path);\n      }\n    } else {\n      // Update all form controls validity which will trigger all form events\n      this.ngForm.form.updateValueAndValidity({ emitEvent: true });\n    }\n  }\n\n  /**\n   * Convenience method to mark all form controls as touched.\n   *\n   * This is useful for showing all validation errors at once, typically when\n   * the user clicks a submit button. When a field is marked as touched,\n   * the error display logic (based on `errorDisplayMode`) will show its errors.\n   *\n   * **Note on automatic behavior:**\n   * When using the default error display mode (`on-blur-or-submit`), you typically\n   * don't need to call this method manually for regular form submissions. The form\n   * directive automatically marks all fields as touched on `ngSubmit`, so errors\n   * will display automatically when the user submits the form.\n   *\n   * **When to use this method:**\n   * - Multiple forms with a single submit button (forms without their own submit)\n   * - Programmatic form submission without triggering `ngSubmit`\n   * - Custom validation flows outside the normal submit process\n   *\n   * **Note:** This method only marks fields as touched—it does NOT re-run validation.\n   * If you also need to re-run validation (e.g., after structure changes), call\n   * `triggerFormValidation()` as well.\n   *\n   * @example\n   * ```typescript\n   * /// Standard form submission - NO need to call markAllAsTouched()\n   * /// The directive handles this automatically on ngSubmit\n   * <form ngxVestForm (ngSubmit)=\"save()\">\n   *   <button type=\"submit\">Submit</button>\n   * </form>\n   *\n   * /// Multiple forms with one submit button\n   * submitAll() {\n   *   this.form1().markAllAsTouched();\n   *   this.form2().markAllAsTouched();\n   *   if (this.form1().formState().valid && this.form2().formState().valid) {\n   *     /// Submit all forms\n   *   }\n   * }\n   * ```\n   */\n  markAllAsTouched(): void {\n    this.ngForm.form.markAllAsTouched();\n    this.#blurTick.update((v) => v + 1);\n  }\n\n  /**\n   * Clears the current submit cycle without resetting control values or metadata.\n   *\n   * Unlike {@link resetForm}, this only flips the submitted gate back to `false`.\n   * Touched/dirty/pristine state is preserved so consumers can end `'on-submit'`\n   * error visibility without a full form reset.\n   *\n   * **When to use:**\n   * - You use submit-gated error visibility such as `'on-submit'`\n   * - A submit attempt already happened\n   * - The user resolved the current submit-time errors\n   * - You want future untouched fields to wait for the next submit before showing errors\n   *\n   * **Why this exists:**\n   * `resetForm()` would also clear touched/dirty/pristine metadata, which is often\n   * too disruptive for long-form, multi-form, or mixed error-display flows.\n   *\n   * **What it does NOT do:**\n   * - Does not change field values\n   * - Does not mark controls pristine or untouched\n   * - Does not re-run validation\n   *\n   * @example\n   * ```typescript\n   * submitAll(): void {\n   *   for (const form of this.submitForms()) {\n   *     form.ngForm.onSubmit(new Event('submit'));\n   *   }\n   *\n   *   if (this.submitForms().every((form) => form.formState().valid)) {\n   *     for (const form of this.submitForms()) {\n   *       form.clearSubmittedState();\n   *     }\n   *   }\n   * }\n   * ```\n   *\n   * @see {@link resetForm} to fully reset values and control metadata\n   * @see {@link markAllAsTouched} to manually show all errors\n   * @see {@link triggerFormValidation} to re-run validation after structure changes\n   */\n  clearSubmittedState(): void {\n    setAngularFormSubmittedState(this.ngForm, false);\n    getFormSubmittedSignal(this.ngForm).set(false);\n    this.#blurTick.update((v) => v + 1);\n  }\n\n  /**\n   * Finds the first invalid element in this form, scrolls it into view, and focuses it.\n   *\n   * Useful in custom submit flows where `markAllAsTouched()` is triggered externally\n   * and the app then wants to guide keyboard and assistive-technology users to the\n   * first failing field.\n   *\n   * @returns The focused element when a focusable target exists, otherwise the first\n   *          matched invalid element. Returns `null` when no invalid element is found.\n   */\n  focusFirstInvalidControl(\n    options: NgxFirstInvalidOptions = {}\n  ): HTMLElement | null {\n    const {\n      block = 'center',\n      inline = 'nearest',\n      focus = true,\n      preventScrollOnFocus = true,\n      openCollapsedParents = true,\n      invalidSelector = DEFAULT_INVALID_SELECTOR,\n      focusSelector = DEFAULT_FOCUS_SELECTOR,\n    } = options;\n    const behavior = resolveFirstInvalidScrollBehavior(options.behavior);\n\n    const root: HTMLFormElement = this.elementRef.nativeElement;\n    const firstInvalid = resolveFirstInvalidElement(root, invalidSelector);\n    if (!firstInvalid) {\n      return null;\n    }\n\n    if (openCollapsedParents) {\n      openCollapsedDetailsAncestors(root, firstInvalid);\n    }\n\n    const focusTarget = resolveFirstInvalidFocusTarget(\n      firstInvalid,\n      focusSelector\n    );\n\n    const scrollTarget = focusTarget ?? firstInvalid;\n    scrollTarget.scrollIntoView({ behavior, block, inline });\n\n    if (focus && focusTarget) {\n      focusTarget.focus({ preventScroll: preventScrollOnFocus });\n    }\n\n    return focusTarget ?? firstInvalid;\n  }\n\n  /**\n   * Finds and scrolls the first invalid element into view without moving focus.\n   *\n   * @returns The resolved element, or `null` when no invalid element is found.\n   */\n  scrollToFirstInvalidControl(\n    options: NgxFirstInvalidOptions = {}\n  ): HTMLElement | null {\n    return this.focusFirstInvalidControl({\n      ...options,\n      focus: false,\n    });\n  }\n\n  /**\n   * Host handler: called whenever any descendant field loses focus.\n   * Used to make touched-path tracking react immediately on blur/tab.\n   */\n  onFormFocusOut(event: FocusEvent): void {\n    // Run on the next microtask to ensure Angular has already applied\n    // control.touched changes for the field that just blurred.\n    scheduleMicrotask(() => {\n      this.#blurTick.update((v) => v + 1);\n      this.#emitFieldBlurEvent(event);\n    }, this.destroyRef);\n  }\n\n  #emitFieldBlurEvent(event: FocusEvent): void {\n    const resolved = this.#resolveFieldFromFocusEvent(event);\n    if (!resolved) {\n      return;\n    }\n    const { field, control, element } = resolved;\n\n    // Read the latest value directly from the DOM element when it can be\n    // trusted. For radio groups Angular keeps the bound `control.value` in\n    // sync with the *selected* option, while a focused-but-unchecked radio\n    // would expose its own option value via the DOM — so radios must always\n    // fall back to `control.value`. For text/textarea/select we prefer the\n    // element value to avoid `ngModelOptions.updateOn: 'submit'` staleness.\n    const domValue = readElementValueForBlur(element);\n    const value = domValue !== undefined ? domValue : control.value;\n\n    // Prefer the cached linked-signal snapshot when it exists. Both code\n    // paths produce a deep-cloned snapshot, but reusing the cached value\n    // saves one of the two `structuredClone` passes performed by\n    // `mergeValuesAndRawValues()` on every blur.\n    const cachedSnapshot = this.#formValueSignal();\n    const formValue =\n      cachedSnapshot !== null\n        ? (structuredClone(cachedSnapshot) as T)\n        : mergeValuesAndRawValues<T>(this.ngForm.form);\n    setValueAtPath(formValue as object, field, value);\n\n    this.fieldBlur.emit({\n      field,\n      value,\n      formValue,\n      dirty: control.dirty,\n      touched: control.touched,\n      valid: control.valid,\n      pending: control.pending,\n    });\n  }\n\n  #resolveFieldFromFocusEvent(event: FocusEvent): {\n    field: string;\n    control: AbstractControl;\n    element: HTMLElement;\n  } | null {\n    const target = event.target;\n    if (!(target instanceof Element)) {\n      return null;\n    }\n\n    const fieldElement = target.closest('[name]');\n    if (!(fieldElement instanceof HTMLElement)) {\n      return null;\n    }\n\n    const name = fieldElement.getAttribute('name')?.trim();\n    if (!name) {\n      return null;\n    }\n\n    const formEl = this.elementRef.nativeElement;\n\n    // Authoritative path: ask the registered NgModel directive whose value\n    // accessor is bound to this exact element. This handles all forms of\n    // grouping uniformly — static `ngModelGroup=\"key\"`, dynamic\n    // `[ngModelGroup]=\"expr\"`, repeated leaf names across siblings — because\n    // the directive's `path` is computed from the live ControlContainer tree.\n    const directiveMatch = resolveControlPathByNgModelDirective(\n      this.ngForm,\n      fieldElement\n    );\n    if (directiveMatch) {\n      return {\n        field: directiveMatch.path,\n        control: directiveMatch.control,\n        element: fieldElement,\n      };\n    }\n\n    // Fallback: walk DOM ancestors collecting any `ngModelGroup` attribute\n    // values, producing the canonical dotted path for the static attribute\n    // form (e.g. `<div ngModelGroup=\"passwords\"><input name=\"password\">` →\n    // `passwords.password`). Used when the directive lookup misses (e.g. the\n    // value accessor doesn't expose its element ref in some custom CVAs).\n    const staticGroups = collectNgModelGroupAttributes(fieldElement, formEl);\n    const staticPath = [...staticGroups, name].join('.');\n    const staticControl = this.ngForm.form.get(staticPath);\n    if (staticControl) {\n      return { field: staticPath, control: staticControl, element: fieldElement };\n    }\n\n    // Last-resort fallback for ambiguous DOM structures: probe each ancestor\n    // element as a potential group boundary, querying the form tree until we\n    // find a child that owns this DOM element.\n    const dynamicMatch = resolveControlPathByDomAncestors(\n      this.ngForm.form,\n      fieldElement,\n      formEl,\n      name\n    );\n    if (dynamicMatch) {\n      return {\n        field: dynamicMatch.path,\n        control: dynamicMatch.control,\n        element: fieldElement,\n      };\n    }\n\n    return null;\n  }\n\n  /**\n   * Resets the form to a pristine, untouched state with optional new values.\n   *\n   * This method properly resets the form by:\n   * 1. Resetting Angular's underlying NgForm with the provided value\n   * 2. Clearing the bidirectional sync tracking state\n   * 3. Forcing a form validity update to clear any stale validation errors\n   *\n   * **Why this method exists:**\n   * When using the pattern `formValue.set({})` to reset a form, there can be a timing\n   * issue where the form controls in the DOM still hold their old values while the\n   * signal has already been updated. This creates a conflict in the bidirectional\n   * sync logic, requiring workarounds like calling `formValue.set({})` twice with\n   * a setTimeout. This method provides a proper solution by:\n   * - Calling Angular's `NgForm.resetForm()` which properly clears all controls\n   * - Clearing the internal sync tracking state to avoid stale comparisons\n   * - Triggering a form validity update to ensure validation state is current\n   *\n   * **Usage:**\n   * Instead of the double-set workaround:\n   * ```typescript\n   * // ❌ Old workaround (avoid)\n   * reset(): void {\n   *   this.formValue.set({});\n   *   setTimeout(() => this.formValue.set({}), 0);\n   * }\n   *\n   * // ✅ Preferred approach\n   * vestForm = viewChild.required('vestForm', { read: FormDirective });\n   * reset(): void {\n   *   this.formValue.set({});\n   *   this.vestForm().resetForm();\n   * }\n   * ```\n   *\n   * **With new values:**\n   * ```typescript\n   * // Reset and set new initial values\n   * resetWithDefaults(): void {\n   *   const defaults = { firstName: '', lastName: '', age: 18 };\n   *   this.formValue.set(defaults);\n   *   this.vestForm().resetForm(defaults);\n   * }\n   * ```\n   *\n   * @param value - Optional new value to reset the form to. If not provided,\n   *                resets to empty/default values.\n   *\n   * @see {@link markAllAsTouched} for showing validation errors\n   * @see {@link triggerFormValidation} for re-running validation without reset\n   */\n  resetForm(value?: T | null): void {\n    // Reset Angular's form to clear all controls and mark as pristine/untouched\n    this.ngForm.resetForm(value ?? undefined);\n\n    // Clear any stored warnings to avoid stale messages after reset\n    this.fieldWarnings.set(new Map());\n\n    // Clear the bidirectional sync tracking state so the next formValue change\n    // is treated as a model change (not a conflict with stale form values)\n    this.#lastSyncedFormValue = null;\n    this.#lastSyncedModelValue = null;\n\n    // Force change detection to ensure DOM updates are reflected\n    // Note: This is still needed even with signals because we're modifying NgForm\n    // (reactive forms), not signals. The formValue signal updates happen in the\n    // consumer component. detectChanges() ensures NgForm's reset is reflected in\n    // the DOM before we update validity.\n    this.cdr.detectChanges();\n\n    // Trigger validation update to clear any stale errors\n    // Now synchronous since detectChanges() has flushed DOM updates\n    this.ngForm.form.updateValueAndValidity({ emitEvent: true });\n    this.#blurTick.update((v) => v + 1);\n  }\n\n  /**\n   * Creates a one-shot async validator function for a specific field path.\n   *\n   * The returned validator:\n   * - snapshots the current form model,\n   * - injects the candidate control value at `field`,\n   * - runs the Vest suite with debouncing,\n   * - maps Vest errors/warnings into Angular `ValidationErrors | null`.\n   *\n   * Warnings are stored in `fieldWarnings` to keep warnings non-blocking when no errors exist.\n   */\n  createAsyncValidator(\n    field: string,\n    validationOptions: ValidationOptions\n  ): AsyncValidatorFn {\n    const suite = this.suite();\n    if (!suite) return () => of(null);\n\n    return (control: AbstractControl) => {\n      const model = mergeValuesAndRawValues<T>(this.ngForm.form);\n\n      // Targeted snapshot with candidate value injected at path\n      // mergeValuesAndRawValues already returns a deep clone (via structuredClone),\n      // so we can modify it directly without affecting the form state.\n      const snapshot = model;\n      setValueAtPath(snapshot as object, field, control.value);\n\n      // Use timer() instead of ReplaySubject for proper debouncing\n      return timer(validationOptions.debounceTime ?? 0).pipe(\n        map(() => snapshot),\n        switchMap(\n          (snap) =>\n            new Observable<ValidationErrors | null>((observer) => {\n              try {\n                // Cast to NgxVestSuite to accept string field parameter\n                // Both NgxVestSuite and NgxTypedVestSuite work with string at runtime\n                // eslint-disable-next-line @typescript-eslint/no-explicit-any\n                (suite as NgxVestSuite<T>)(snap, field).done((result: any) => {\n                  // Guard: bail out if the directive was destroyed while\n                  // validation was in flight to avoid writing to disposed\n                  // signals or a torn-down view.\n                  if (this.#destroyed) {\n                    // Emit a neutral `null` before completing so async\n                    // validators always emit exactly once. Completing without\n                    // emission can leave consumers (e.g. a control's status)\n                    // in an unexpected `PENDING` state.\n                    observer.next(null);\n                    observer.complete();\n                    return;\n                  }\n\n                  const errors = result.getErrors()[field];\n                  const warnings = result.getWarnings()[field];\n\n                  // Store warnings in the fieldWarnings signal for access by control wrappers.\n                  // This is necessary because Angular marks a field as invalid when control.errors !== null.\n                  // By storing warnings separately, fields can remain valid while still displaying warnings.\n                  this.fieldWarnings.update((map) => {\n                    const newMap = new Map(map);\n                    if (warnings?.length) {\n                      newMap.set(field, warnings);\n                    } else {\n                      newMap.delete(field);\n                    }\n                    return newMap;\n                  });\n\n                  // Build the validation result:\n                  // - Errors exist → return { errors, warnings? } (field invalid, Angular shows ng-invalid)\n                  // - Only warnings → return null (field valid, warnings accessed via fieldWarnings signal)\n                  // - Neither → return null (field valid)\n                  //\n                  // When errors exist, we also include warnings in control.errors for backwards compatibility\n                  // with code that reads warnings from control.errors.warnings.\n                  const out = errors?.length\n                    ? {\n                        errors,\n                        ...(warnings?.length && { warnings }),\n                      }\n                    : null;\n\n                  // CRITICAL: Ensure DOM validity classes update for OnPush components.\n                  //\n                  // Angular's template-driven forms update `ng-valid`/`ng-invalid` host classes\n                  // during change detection. When async validation completes, there may be no\n                  // follow-up change detection pass for OnPush hosts, leaving the DOM in a stale\n                  // visual state (even though the control status has updated).\n                  //\n                  // We schedule a detectChanges() on the next microtask to avoid calling it\n                  // synchronously inside Angular's own validation pipeline. The scheduleMicrotask\n                  // primitive auto-cancels if the directive is destroyed before it fires.\n                  scheduleMicrotask(() => {\n                    try {\n                      this.cdr.detectChanges();\n                    } catch {\n                      // Fallback: mark for check when immediate detectChanges isn't safe.\n                      // This keeps behavior resilient in edge cases.\n                      this.cdr.markForCheck();\n                    }\n                  }, this.destroyRef);\n\n                  observer.next(out);\n                  observer.complete();\n                });\n              } catch {\n                observer.next({ vestInternalError: 'Validation failed' });\n                observer.complete();\n              }\n            })\n        ),\n        catchError(() => of({ vestInternalError: 'Validation failed' })),\n        take(1)\n      );\n    };\n  }\n\n  /**\n   * Set up validation config reactively using v2 pattern with toObservable + switchMap.\n   * This provides automatic cleanup when config changes.\n   */\n  #setupValidationConfig(): void {\n    const form = this.ngForm.form;\n    toObservable(this.validationConfig)\n      .pipe(\n        distinctUntilChanged(),\n        switchMap((config) => {\n          // Cast to the expected type for the helper method\n          const typedConfig = config as\n            | ValidationConfigMap<T>\n            | null\n            | undefined;\n          return this.#createValidationStreams(form, typedConfig);\n        }),\n        takeUntilDestroyed(this.destroyRef)\n      )\n      .subscribe();\n  }\n\n  /**\n   * Creates validation streams for the provided configuration.\n   * Returns EMPTY if config is null/undefined, otherwise merges all trigger field streams.\n   *\n   * @param form - The NgForm instance\n   * @param config - The validation configuration mapping trigger fields to dependent fields\n   * @returns Observable that emits when any trigger field changes and dependent fields need validation\n   */\n  #createValidationStreams(\n    form: FormGroup,\n    config: ValidationConfigMap<T> | null | undefined\n  ): Observable<unknown> {\n    if (!config) {\n      this.validationInProgress.clear();\n      return EMPTY;\n    }\n\n    const streams = Object.entries(config as Record<string, string[]>).map(\n      ([triggerField, dependents]) =>\n        this.#createTriggerStream(form, triggerField, dependents || [])\n    );\n\n    return streams.length > 0 ? rxMerge(...streams) : EMPTY;\n  }\n\n  /**\n   * Creates a stream for a single trigger field that revalidates its dependent fields.\n   *\n   * This method handles:\n   * 1. Waiting for the trigger control to exist in the form (for @if scenarios)\n   * 2. Listening to value changes with debouncing\n   * 3. Waiting for form to be idle before triggering dependents\n   * 4. Waiting for all dependent controls to exist\n   * 5. Updating dependent field validity with loop prevention\n   *\n   * @param form - The NgForm instance\n   * @param triggerField - Field path that triggers validation (e.g., 'password')\n   * @param dependents - Array of dependent field paths to revalidate (e.g., ['confirmPassword'])\n   * @returns Observable that completes after dependent fields are validated\n   */\n  #createTriggerStream(\n    form: FormGroup,\n    triggerField: string,\n    dependents: string[]\n  ): Observable<unknown> {\n    // Wait for trigger control to exist, then stop listening (take(1) prevents feedback loops)\n    const triggerControl$ = form.statusChanges.pipe(\n      startWith(form.status),\n      map(() => form.get(triggerField)),\n      filter((c): c is AbstractControl => !!c),\n      // CRITICAL: take(1) to stop listening after control is found\n      // Without this, the pipeline continues to listen to statusChanges,\n      // creating a feedback loop where validation triggers re-trigger the pipeline\n      take(1)\n    );\n\n    return triggerControl$.pipe(\n      switchMap((control) => {\n        return control.valueChanges.pipe(\n          // CRITICAL: Filter out changes when this field is being validated by another field's config\n          // This prevents circular triggers in bidirectional validationConfig\n          filter(() => !this.validationInProgress.has(triggerField)),\n          debounceTime(this.configDebounceTime),\n          switchMap(() => {\n            return this.#waitForFormIdle(form, control);\n          }),\n          switchMap(() =>\n            this.#waitForDependentControls(form, dependents, control)\n          ),\n          tap(() =>\n            this.#updateDependentFields(form, control, triggerField, dependents)\n          )\n        );\n      })\n    );\n  }\n\n  /**\n   * Waits for the form to reach a non-PENDING state before proceeding.\n   * This prevents validation race conditions where dependent field validation\n   * triggers while the trigger field's validation is still running.\n   *\n   * If the form stays PENDING for longer than 2 seconds (e.g., slow async validators),\n   * proceeds anyway to prevent blocking the validation pipeline.\n   *\n   * @param form - The NgForm instance\n   * @param control - The trigger control to pass through\n   * @returns Observable that emits the control once form is idle or timeout\n   */\n  #waitForFormIdle(\n    form: FormGroup,\n    control: AbstractControl\n  ): Observable<AbstractControl> {\n    // If form is already non-PENDING, return immediately\n    if (form.status !== 'PENDING') {\n      return of(control);\n    }\n\n    // Form is PENDING, wait for it to become idle\n\n    const idle$ = form.statusChanges.pipe(\n      filter((s) => s !== 'PENDING'),\n      take(1)\n    );\n\n    const timeout$ = timer(2000).pipe(\n      tap(() => {\n        if (isDevMode()) {\n          console.warn(\n            '[ngx-vest-forms] validationConfig: timed out waiting for form to leave PENDING state (2s). Continuing dependent validation to avoid stalling.'\n          );\n        }\n      })\n    );\n\n    return race(idle$, timeout$).pipe(map(() => control));\n  }\n\n  /**\n   * Waits for all dependent controls to exist in the form.\n   * This handles @if scenarios where controls are conditionally rendered.\n   *\n   * @param form - The NgForm instance\n   * @param dependents - Array of dependent field paths\n   * @param control - The trigger control to pass through\n   * @returns Observable that emits the control once all dependents exist\n   */\n  #waitForDependentControls(\n    form: FormGroup,\n    dependents: string[],\n    control: AbstractControl\n  ): Observable<AbstractControl> {\n    const allDependentsExist = dependents.every(\n      (depField) => !!form.get(depField)\n    );\n\n    if (allDependentsExist) {\n      return of(control);\n    }\n\n    // Wait for dependent controls to be added to the form, but bound the wait to avoid silent stalls.\n    const dependentControlsReady$ = form.statusChanges.pipe(\n      startWith(form.status),\n      filter(() => dependents.every((depField) => !!form.get(depField))),\n      take(1),\n      map(() => control)\n    );\n\n    const timeout$ = timer(2000).pipe(\n      tap(() => {\n        if (isDevMode()) {\n          const unresolved = dependents.filter(\n            (depField) => !form.get(depField)\n          );\n          console.warn(\n            `[ngx-vest-forms] validationConfig: timed out waiting for dependent controls (2s): ${unresolved.join(', ')}. Continuing without waiting further.`\n          );\n        }\n      }),\n      map(() => control)\n    );\n\n    return race(dependentControlsReady$, timeout$).pipe(take(1));\n  }\n\n  /**\n   * Updates validation for all dependent fields.\n   *\n   * Handles:\n   * - Loop prevention via validationInProgress set\n   * - Silent validation updates that avoid feedback loops\n   *\n   * Note: Touch state is NOT propagated to prevent premature error display\n   * on conditionally revealed fields.\n   *\n   * Note: This method does NOT propagate touch state from trigger to dependent fields.\n   * Dependent fields only show errors after the user directly interacts with them.\n   *\n   * @param form - The NgForm instance\n   * @param control - The trigger control\n   * @param triggerField - Field path of the trigger\n   * @param dependents - Array of dependent field paths to update\n   */\n  #updateDependentFields(\n    form: FormGroup,\n    control: AbstractControl,\n    triggerField: string,\n    dependents: string[]\n  ): void {\n    // Mark trigger field as in-progress to prevent it from being re-triggered\n    this.validationInProgress.add(triggerField);\n\n    for (const depField of dependents) {\n      const dependentControl = form.get(depField);\n      if (!dependentControl) {\n        continue;\n      }\n\n      // Only validate if not already in progress (prevents bidirectional loops)\n      if (!this.validationInProgress.has(depField)) {\n        // CRITICAL: Mark the dependent field as in-progress BEFORE calling updateValueAndValidity\n        // This prevents the dependent field's valueChanges from triggering its own validationConfig\n        this.validationInProgress.add(depField);\n\n        // emitEvent: true is REQUIRED for async validators to actually run\n        // The validationInProgress Set prevents infinite loops:\n        // 1. Field A changes → triggers validation on dependent field B\n        // 2. B is added to validationInProgress Set\n        // 3. B's statusChanges emits → #handleValueChange checks validationInProgress\n        // 4. Since B is in validationInProgress, its validationConfig is not triggered\n        // 5. After 500ms timeout, B is removed from validationInProgress\n        // This way:\n        // - Async validators CAN run (emitEvent: true)\n        // - BUT circular triggers are prevented (validationInProgress check)\n        dependentControl.updateValueAndValidity({\n          onlySelf: true,\n          emitEvent: true, // Changed from false - REQUIRED for validators to run!\n        });\n\n        // CRITICAL: Force immediate change detection for OnPush components\n        // updateValueAndValidity updates the control's status, but doesn't automatically\n        // trigger change detection. Components using OnPush won't see the ng-invalid class\n        // update in the DOM without this. Using detectChanges() instead of markForCheck()\n        // to force immediate synchronous update rather than waiting for next CD cycle.\n        this.cdr.detectChanges();\n      }\n    }\n\n    // Keep fields marked as in-progress for a short time to prevent immediate re-triggering\n    // Use scheduleTimeout to ensure async validators have time to complete before allowing\n    // new triggers. The timer auto-cancels on directive destroy so no timers leak.\n    scheduleTimeout(() => {\n      this.validationInProgress.delete(triggerField);\n      for (const depField of dependents) {\n        this.validationInProgress.delete(depField);\n      }\n    }, VALIDATION_IN_PROGRESS_TIMEOUT_MS, this.destroyRef);\n  }\n\n  /**\n   * Collects field paths of all touched (or submitted) leaf controls\n   * by walking the form control tree.\n   */\n  #collectTouchedPaths(control: AbstractControl, submitted: boolean): string[] {\n    const fields: string[] = [];\n\n    const collect = (\n      current: AbstractControl,\n      path: Array<string | number>\n    ): void => {\n      if (current instanceof FormGroup) {\n        for (const [name, child] of Object.entries(current.controls)) {\n          collect(child, [...path, name]);\n        }\n        return;\n      }\n\n      if (current instanceof FormArray) {\n        current.controls.forEach((child, index) => {\n          collect(child, [...path, index]);\n        });\n        return;\n      }\n\n      if ((submitted || current.touched) && path.length > 0) {\n        fields.push(stringifyFieldPath(path));\n      }\n    };\n\n    collect(control, []);\n    return fields;\n  }\n}\n\n/**\n * Reads the user-entered value from a blurred form element. Returns\n * `undefined` for radio inputs (caller must fall back to the bound\n * `control.value`, since the focused radio is not necessarily the\n * group's selected option) and for elements we don't handle.\n */\nfunction readElementValueForBlur(element: HTMLElement): unknown {\n  if (element instanceof HTMLInputElement) {\n    if (element.type === 'radio') return undefined;\n    if (element.type === 'checkbox') return element.checked;\n    if (element.type === 'number') {\n      return element.value === '' ? null : element.valueAsNumber;\n    }\n    return element.value;\n  }\n  if (\n    element instanceof HTMLTextAreaElement ||\n    element instanceof HTMLSelectElement\n  ) {\n    return element.value;\n  }\n  return undefined;\n}\n\n/**\n * Walks DOM ancestors between `start` (exclusive) and `formEl` (exclusive),\n * collecting any preserved `ngModelGroup` attribute values into a path\n * suitable for `FormGroup.get()`. Only the static attribute form is\n * preserved on the DOM; dynamically-bound `[ngModelGroup]` is handled by\n * `resolveControlPathByDomAncestors`.\n */\nfunction collectNgModelGroupAttributes(\n  start: HTMLElement,\n  formEl: HTMLElement\n): string[] {\n  const groups: string[] = [];\n  let current: Element | null = start.parentElement;\n  while (current && current !== formEl && formEl.contains(current)) {\n    const groupName = current.getAttribute('ngModelGroup')?.trim();\n    if (groupName) {\n      groups.unshift(groupName);\n    }\n    current = current.parentElement;\n  }\n  return groups;\n}\n\n/**\n * Resolves the dotted control path for a blurred element when the static\n * `ngModelGroup` attribute walk failed (typically because the host used\n * `[ngModelGroup]=\"expr\"`, which Angular does not always preserve as a\n * DOM attribute). Walks the control tree top-down and at each FormGroup\n * boundary tries to descend into a child whose subtree contains an element\n * with the matching `name` — disambiguating repeated leaf names by DOM\n * containment instead of giving up.\n */\nfunction resolveControlPathByDomAncestors(\n  root: FormGroup,\n  fieldElement: HTMLElement,\n  formEl: HTMLElement,\n  leafName: string\n): { path: string; control: AbstractControl } | null {\n  type Frame = { control: AbstractControl; path: Array<string | number> };\n\n  const descend = (frame: Frame): Frame | null => {\n    if (frame.control instanceof FormGroup) {\n      for (const [key, child] of Object.entries(frame.control.controls)) {\n        if (key === leafName && !(child instanceof FormGroup)) {\n          return { control: child, path: [...frame.path, key] };\n        }\n      }\n      const candidates: Frame[] = [];\n      for (const [key, child] of Object.entries(frame.control.controls)) {\n        if (child instanceof FormGroup || child instanceof FormArray) {\n          if (subtreeContainsElement(child, fieldElement, formEl, key)) {\n            candidates.push({ control: child, path: [...frame.path, key] });\n          }\n        }\n      }\n      if (candidates.length === 1 && candidates[0])\n        return descend(candidates[0]);\n      return null;\n    }\n    if (frame.control instanceof FormArray) {\n      const candidates: Frame[] = [];\n      frame.control.controls.forEach((child, index) => {\n        if (child instanceof FormGroup || child instanceof FormArray) {\n          if (subtreeContainsElement(child, fieldElement, formEl, index)) {\n            candidates.push({ control: child, path: [...frame.path, index] });\n          }\n        }\n      });\n      if (candidates.length === 1 && candidates[0])\n        return descend(candidates[0]);\n    }\n    return null;\n  };\n\n  const result = descend({ control: root, path: [] });\n  if (!result) return null;\n  return { path: stringifyFieldPath(result.path), control: result.control };\n}\n\n/**\n * Best-effort check: does the DOM subtree rooted at any element annotated\n * with `ngModelGroup=\"<key>\"` contain `fieldElement`? Used by\n * `resolveControlPathByDomAncestors` to disambiguate repeated leaf names.\n * For dynamic `[ngModelGroup]` with no preserved attribute we cannot\n * disambiguate from DOM alone — those cases return `false`, matching the\n * documented limitation.\n */\nfunction subtreeContainsElement(\n  _child: AbstractControl,\n  fieldElement: HTMLElement,\n  formEl: HTMLElement,\n  key: string | number\n): boolean {\n  if (typeof key !== 'string') return false;\n  const selector = `[ngModelGroup=\"${CSS.escape(key)}\"]`;\n  const candidates = formEl.querySelectorAll(selector);\n  for (const candidate of candidates) {\n    if (candidate.contains(fieldElement)) return true;\n  }\n  return false;\n}\n\n/**\n * Resolves the control + dotted path for a blurred element by consulting the\n * `NgModel` directives Angular registered with this `NgForm`. Each registered\n * directive carries a live `path` (the full ControlContainer chain) and a\n * value accessor whose element ref is the input the directive is hosted on.\n *\n * This handles all grouping shapes uniformly — static `ngModelGroup=\"key\"`,\n * dynamic `[ngModelGroup]=\"expr\"`, and repeated leaf names across siblings —\n * because the path comes from the live form tree rather than DOM heuristics.\n * Returns `null` when the directive can't be matched (e.g. a custom CVA that\n * doesn't store an element ref), so the caller can fall back to DOM probes.\n */\nfunction resolveControlPathByNgModelDirective(\n  ngForm: NgForm,\n  fieldElement: HTMLElement\n): { path: string; control: AbstractControl } | null {\n  const directives = readNgFormDirectives(ngForm);\n  if (!directives) return null;\n\n  for (const directive of directives) {\n    const accessorEl = readValueAccessorElement(directive.valueAccessor);\n    if (accessorEl !== fieldElement) continue;\n    const control = directive.control ?? ngForm.form.get(directive.path);\n    if (!control) return null;\n    return { path: directive.path.join('.'), control };\n  }\n  return null;\n}\n\n/**\n * Reads the registered `NgModel` directives from `NgForm`. Angular forms keeps\n * them in a private `_directives: Set<NgModel>`. The field name is stable\n * across all Angular versions that ship `ngModel`, but is not part of the\n * public type — callers must tolerate `null`.\n */\nfunction readNgFormDirectives(ngForm: NgForm): Iterable<NgModel> | null {\n  const set = (ngForm as unknown as { _directives?: Set<NgModel> })._directives;\n  return set ?? null;\n}\n\n/**\n * Reads the host element of a `ControlValueAccessor`. The standard accessors\n * shipped by Angular forms (default, number, select, radio, checkbox, range)\n * all store an `ElementRef` injected at construction as `_elementRef`. This\n * is private but stable; custom accessors that don't follow the convention\n * will simply miss the fast path.\n */\nfunction readValueAccessorElement(\n  accessor: ControlValueAccessor | null | undefined\n): HTMLElement | null {\n  if (!accessor) return null;\n  const elementRef = (accessor as { _elementRef?: { nativeElement?: unknown } })\n    ._elementRef;\n  const native = elementRef?.nativeElement;\n  return native instanceof HTMLElement ? native : null;\n}\n","import {\n  Directive,\n  Injector,\n  afterEveryRender,\n  afterNextRender,\n  computed,\n  contentChild,\n  effect,\n  inject,\n  signal,\n} from '@angular/core';\nimport {\n  AbstractControlDirective,\n  NgModel,\n  NgModelGroup,\n  ValidationErrors,\n} from '@angular/forms';\nimport { FormDirective } from './form.directive';\n\n/**\n * Angular's ValidationErrors is `{ [key: string]: any }`.\n * We extend it with Vest-specific structure for better type safety.\n */\nexport type VestValidationErrors = {\n  /** Vest error messages array */\n  errors?: readonly string[];\n  /** Vest warning messages array */\n  warnings?: readonly string[];\n} & ValidationErrors;\n\n/**\n * Form control status values as defined by Angular.\n * @see AbstractControl.status\n */\nexport type FormControlStatus = 'VALID' | 'INVALID' | 'PENDING' | 'DISABLED';\n\n/**\n * Represents the core state of an Angular form control.\n * Uses narrower types than Angular's defaults where possible.\n */\nexport type FormControlState = {\n  readonly status: FormControlStatus | null;\n  readonly isValid: boolean;\n  readonly isInvalid: boolean;\n  readonly isPending: boolean;\n  readonly isDisabled: boolean;\n  readonly isTouched: boolean;\n  readonly isDirty: boolean;\n  readonly isPristine: boolean;\n  /** Errors from Angular validators or Vest validation */\n  readonly errors: VestValidationErrors | null;\n};\n\nconst INITIAL_FORM_CONTROL_STATE = {\n  status: 'INVALID',\n  isValid: false,\n  isInvalid: true,\n  isPending: false,\n  isDisabled: false,\n  isTouched: false,\n  isDirty: false,\n  isPristine: true,\n  errors: null,\n} as const satisfies FormControlState;\n\n@Directive({\n  selector: '[formControlState], [ngxControlState]',\n  exportAs: 'formControlState, ngxControlState',\n})\nexport class FormControlStateDirective {\n  protected readonly contentNgModel = contentChild(NgModel);\n  protected readonly contentNgModelGroup = contentChild(NgModelGroup);\n\n  readonly #hostNgModel = inject(NgModel, { self: true, optional: true });\n  readonly #hostNgModelGroup = inject(NgModelGroup, {\n    self: true,\n    optional: true,\n  });\n  readonly #injector = inject(Injector);\n\n  /**\n   * Reference to the parent FormDirective for accessing field warnings.\n   * Optional to support usage outside of ngxVestForm context.\n   */\n  readonly #formDirective = inject(FormDirective, { optional: true });\n\n  /**\n   * Computed signal for the active control (NgModel or NgModelGroup)\n   */\n  readonly #activeControl = computed(\n    (): AbstractControlDirective | null =>\n      this.#hostNgModel ||\n      this.#hostNgModelGroup ||\n      this.contentNgModel() ||\n      this.contentNgModelGroup() ||\n      null\n  );\n\n  /**\n   * Consolidated internal signal for interaction state tracking.\n   * Combines touched, dirty, and hasBeenValidated into a single signal\n   * to reduce signal overhead and simplify state updates.\n   */\n  readonly #interactionState = signal({\n    isTouched: false,\n    isDirty: false,\n    hasBeenValidated: false,\n  });\n\n  /**\n   * Track the previous status to detect actual status changes (not just status emissions).\n   * This helps distinguish between initial control creation and actual re-validation.\n   */\n  #previousStatus: FormControlStatus | null = null;\n\n  /**\n   * Internal signal for control state (updated reactively)\n   */\n  readonly #controlStateSignal = signal<FormControlState>(\n    INITIAL_FORM_CONTROL_STATE\n  );\n\n  /**\n   * Tick bumped once via `afterNextRender` if `control.control` is undefined\n   * at the first effect run (NgModel registers asynchronously). Reading this\n   * signal inside the effect causes a re-evaluation after the next render so\n   * we pick up the late-attached `FormControl`. Bookkeeping below ensures we\n   * only schedule a single retry — no permanent polling.\n   */\n  readonly #controlAttachTick = signal(0);\n  // Latch is scoped to the *current* `#activeControl` instance. When the\n  // active control changes (e.g. host swaps an `@if` block, NgModel\n  // recreates), the latch resets so a fresh late-attach gets one retry.\n  #controlAttachRetryScheduled = false;\n  #lastSeenActiveControl: AbstractControlDirective | null = null;\n\n  constructor() {\n    // Update control state reactively with proper cleanup\n    effect((onCleanup) => {\n      const control = this.#activeControl();\n      const interaction = this.#interactionState();\n      // Track the retry tick so a late-attached `control.control` re-runs this\n      // effect after the next render.\n      this.#controlAttachTick();\n\n      // Re-arm the late-attach latch whenever the active control identity\n      // changes — including transitions to/from null — so a newly mounted\n      // directive whose `FormControl` registers asynchronously gets its own\n      // single retry.\n      if (control !== this.#lastSeenActiveControl) {\n        this.#lastSeenActiveControl = control;\n        this.#controlAttachRetryScheduled = false;\n      }\n\n      if (!control) {\n        this.#controlStateSignal.set(INITIAL_FORM_CONTROL_STATE);\n        return;\n      }\n\n      // NgModel attaches its `FormControl` during its own ngOnInit, which can\n      // run after this effect's first execution in some host orderings. If\n      // `control.control` isn't there yet, schedule a single `afterNextRender`\n      // retry so we re-evaluate once Angular finishes wiring directives.\n      if (!control.control && !this.#controlAttachRetryScheduled) {\n        this.#controlAttachRetryScheduled = true;\n        afterNextRender(\n          () => {\n            this.#controlAttachTick.update((v) => v + 1);\n          },\n          { injector: this.#injector }\n        );\n        return;\n      }\n\n      // Listen to control changes\n      const sub = control.control?.statusChanges?.subscribe(() => {\n        const {\n          status,\n          valid,\n          invalid,\n          pending,\n          disabled,\n          pristine,\n          errors,\n          touched,\n        } = control;\n\n        const currentStatus = status as FormControlStatus | null;\n\n        // Mark as validated when any of the following conditions are met:\n        // 1. The control has been touched (user blurred the field).\n        // 2. The control's status has actually changed (not the first status emission),\n        //    AND the new status is not 'PENDING' (validation completed).\n        //\n        // This ensures hasBeenValidated is true for:\n        //   - User blur events (touched becomes true)\n        //   - Any validation that changes status (e.g., typing then validation completes)\n        //   - ValidationConfig-triggered validations (status changed without touch/dirty)\n        // But NOT for initial page load validations (previousStatus === null).\n        //\n        // Note: The dirty check was removed to support validationConfig-triggered validations.\n        // This allows warnings to show even when the field hasn't been touched/dirtied by the user.\n        //\n        // Accessibility: The logic is structured for clarity and maintainability.\n        // IMPORTANT: Read touched/dirty directly from control, not from signal,\n        // to avoid race conditions with afterEveryRender sync.\n        if (\n          touched || // Control was blurred (most common case)\n          (this.#previousStatus !== null && // Not the first status emission\n            this.#previousStatus !== currentStatus && // Status actually changed\n            currentStatus !== null &&\n            currentStatus !== 'PENDING') // Validation completed (not pending)\n        ) {\n          this.#interactionState.update((state) => ({\n            ...state,\n            hasBeenValidated: true,\n          }));\n        }\n\n        // Track current status for next iteration\n        this.#previousStatus = currentStatus;\n\n        this.#controlStateSignal.set({\n          status: currentStatus,\n          isValid: valid ?? false,\n          isInvalid: invalid ?? false,\n          isPending: pending ?? false,\n          isDisabled: disabled ?? false,\n          isTouched: interaction.isTouched,\n          isDirty: interaction.isDirty,\n          isPristine: pristine ?? true,\n          errors: errors as VestValidationErrors | null,\n        });\n      });\n\n      // Initial update\n      const { status, valid, invalid, pending, disabled, pristine, errors } =\n        control;\n\n      const initialStatus = status as FormControlStatus | null;\n      this.#previousStatus = initialStatus;\n\n      this.#controlStateSignal.set({\n        status: initialStatus,\n        isValid: valid ?? false,\n        isInvalid: invalid ?? false,\n        isPending: pending ?? false,\n        isDisabled: disabled ?? false,\n        isTouched: interaction.isTouched,\n        isDirty: interaction.isDirty,\n        isPristine: pristine ?? true,\n        errors: errors as VestValidationErrors | null,\n      });\n\n      // Proper cleanup using onCleanup callback (Angular 21 best practice)\n      onCleanup(() => sub?.unsubscribe());\n    });\n\n    // Robustly sync touched/dirty/pending after every render (Angular 18+ best practice)\n    // This handles cases where statusChanges events are missed or delayed\n    afterEveryRender(\n      () => {\n        const control = this.#activeControl();\n        if (control) {\n          const currentInteraction = this.#interactionState();\n          const currentState = this.#controlStateSignal();\n          const newTouched = control.touched ?? false;\n          const newDirty = control.dirty ?? false;\n\n          // Sync interaction state (touched/dirty)\n          if (\n            newTouched !== currentInteraction.isTouched ||\n            newDirty !== currentInteraction.isDirty\n          ) {\n            // Mark as validated when control becomes touched (e.g., user blurred the field)\n            // This handles the case where blur doesn't trigger statusChanges (field already invalid)\n            const shouldMarkValidated =\n              newTouched && !currentInteraction.isTouched;\n\n            // Reset hasBeenValidated when a control transitions back to pristine interaction state\n            // (e.g., after form.resetForm()).\n            //\n            // This prevents stale warning display on untouched fields after reset while preserving\n            // validationConfig-triggered behavior during normal interaction.\n            const wasResetToPristineInteraction =\n              !newTouched &&\n              !newDirty &&\n              (currentInteraction.isTouched || currentInteraction.isDirty);\n\n            this.#interactionState.update((state) => ({\n              ...state,\n              isTouched: newTouched,\n              isDirty: newDirty,\n              hasBeenValidated: wasResetToPristineInteraction\n                ? false\n                : shouldMarkValidated\n                  ? true\n                  : state.hasBeenValidated,\n            }));\n\n            // Keep the derived control-state signal in sync even when blur/dirty\n            // changes do not produce a statusChanges emission.\n            //\n            // This happens when a control is already INVALID due to dependent-field\n            // validation and the user then blurs it. Error display modes that depend\n            // on `isTouched()` must still update immediately in that case.\n            this.#controlStateSignal.set({\n              status: control.status as FormControlStatus | null,\n              isValid: control.valid ?? false,\n              isInvalid: control.invalid ?? false,\n              isPending: control.pending ?? false,\n              isDisabled: control.disabled ?? false,\n              isTouched: newTouched,\n              isDirty: newDirty,\n              isPristine: control.pristine ?? true,\n              errors: control.errors as VestValidationErrors | null,\n            });\n          }\n\n          // Sync pending state only when it transitions from true to false\n          // This fixes \"Validating...\" being stuck when statusChanges misses the transition\n          // We only sync when pending goes false to avoid interfering with async validation in progress\n          const controlPending = control.pending ?? false;\n          if (currentState.isPending && !controlPending) {\n            // Pending changed from true to false - update the full state\n            const newStatus = control.status as FormControlStatus | null;\n            this.#controlStateSignal.set({\n              status: newStatus,\n              isPending: false,\n              isValid: control.valid ?? false,\n              isInvalid: control.invalid ?? false,\n              isPristine: control.pristine ?? true,\n              isDisabled: control.disabled ?? false,\n              isTouched: newTouched,\n              isDirty: newDirty,\n              errors: control.errors as VestValidationErrors | null,\n            });\n          }\n        }\n      },\n      { injector: this.#injector }\n    );\n  }\n\n  /**\n   * Main control state computed signal (merges robust touched/dirty)\n   */\n  readonly controlState = computed(() => this.#controlStateSignal());\n\n  /**\n   * Recursively flattens Angular error objects into an array of error messages.\n   * Handles string values, objects with a message property, and nested structures.\n   */\n  #flattenAngularErrors(errors: Record<string, unknown>): string[] {\n    const result: string[] = [];\n\n    for (const key of Object.keys(errors)) {\n      const value: unknown = errors[key];\n\n      if (typeof value === 'string') {\n        // String values: push the value itself, not the key\n        result.push(value);\n      } else if (isErrorWithMessage(value)) {\n        // Objects with a 'message' property: extract the message\n        result.push(value.message);\n      } else if (typeof value === 'object' && value !== null) {\n        // Nested objects/arrays: recursively flatten\n        result.push(\n          ...this.#flattenAngularErrors(value as Record<string, unknown>)\n        );\n      } else {\n        // Fallback: push the key for primitive types (backward compatibility)\n        result.push(key);\n      }\n    }\n\n    return result;\n  }\n\n  /**\n   * Extracts error messages from Angular/Vest errors (recursively flattens)\n   */\n  readonly errorMessages = computed((): string[] => {\n    const { errors } = this.controlState();\n    if (!errors) return [];\n\n    // Vest errors are stored in the 'errors' property as an array\n    const vestErrors = errors.errors;\n    if (vestErrors) {\n      return (vestErrors as readonly unknown[])\n        .map((error) => normalizeErrorMessage(error))\n        .filter((error): error is string => Boolean(error));\n    }\n\n    // Fallback to flattened Angular error keys, excluding 'warnings' key\n    // to prevent warnings from appearing in the error list\n    const errorsWithoutWarnings = { ...errors };\n    delete errorsWithoutWarnings['warnings'];\n    return this.#flattenAngularErrors(errorsWithoutWarnings);\n  });\n\n  /**\n   * ADVANCED: updateOn strategy (change/blur/submit) if available\n   */\n  readonly updateOn = computed((): 'change' | 'blur' | 'submit' => {\n    const ngModel = this.contentNgModel() || this.#hostNgModel;\n    return ngModel?.options?.updateOn ?? 'change';\n  });\n\n  /**\n   * ADVANCED: Composite/derived signals for advanced error display logic\n   */\n  readonly isValidTouched = computed(() => this.isValid() && this.isTouched());\n\n  readonly isInvalidTouched = computed(\n    () => this.isInvalid() && this.isTouched()\n  );\n\n  readonly shouldShowErrors = computed(\n    () => this.isInvalid() && this.isTouched() && !this.isPending()\n  );\n\n  /**\n   * Extracts warning messages from Vest validation results.\n   * Checks two sources:\n   * 1. control.errors.warnings (when errors exist alongside warnings)\n   * 2. FormDirective.fieldWarnings (for warnings-only scenarios)\n   * This dual-source approach allows warnings to be displayed without affecting field validity.\n   */\n  readonly warningMessages = computed((): string[] => {\n    // Source 1: warnings from control.errors (when field has errors)\n    const { errors } = this.controlState();\n\n    // Always read fieldWarnings signal to ensure reactive tracking\n    // This must be read unconditionally for proper signal dependency tracking\n    const fieldWarnings = this.#formDirective?.fieldWarnings();\n    const activeControl = this.#activeControl();\n\n    // If we have warnings in control.errors, use those (errors+warnings case)\n    if (errors?.warnings) {\n      return [...errors.warnings];\n    }\n\n    // Source 2: warnings from FormDirective (for warnings-only scenarios)\n    // When a field only has warnings (no errors), they're stored in fieldWarnings\n    // to keep the field valid while still allowing warnings to be displayed.\n    if (fieldWarnings && activeControl) {\n      // Get the field path from the control's path property\n      // NgModel.path returns an array like ['passwords', 'password'] which needs to be joined\n      const path = (activeControl as { path?: string[] }).path;\n      if (path?.length) {\n        const fieldPath = path.join('.');\n        const warnings = fieldWarnings.get(fieldPath);\n        if (warnings) {\n          return [...warnings];\n        }\n      }\n    }\n\n    return [];\n  });\n\n  /**\n   * Whether async validation is in progress\n   */\n  readonly hasPendingValidation = computed(() => this.controlState().isPending);\n\n  /**\n   * Convenience signals for common state checks\n   */\n  readonly isValid = computed(() => this.controlState().isValid);\n  readonly isInvalid = computed(() => this.controlState().isInvalid);\n  readonly isPending = computed(() => this.controlState().isPending);\n  readonly isTouched = computed(() => this.controlState().isTouched);\n  readonly isDirty = computed(() => this.controlState().isDirty);\n  readonly isPristine = computed(() => this.controlState().isPristine);\n  readonly isDisabled = computed(() => this.controlState().isDisabled);\n  readonly hasErrors = computed(() => this.errorMessages().length > 0);\n\n  /**\n   * Whether this control has been validated at least once.\n   * True after the first validation completes, even if the user hasn't touched the field.\n   * This is primarily used for warning display and other derived state that should react\n   * to validationConfig-triggered validation even before the user touches the field.\n   */\n  readonly hasBeenValidated = computed(\n    () => this.#interactionState().hasBeenValidated\n  );\n}\n\n/**\n * Type guard for objects with a message property\n */\nfunction isErrorWithMessage(value: unknown): value is { message: string } {\n  return (\n    typeof value === 'object' &&\n    value !== null &&\n    'message' in value &&\n    typeof (value as { message: unknown }).message === 'string'\n  );\n}\n\nfunction normalizeErrorMessage(value: unknown): string | null {\n  if (typeof value === 'string') {\n    return value;\n  }\n\n  if (isErrorWithMessage(value)) {\n    return value.message;\n  }\n\n  if (value === null || value === undefined) {\n    return null;\n  }\n\n  if (typeof value === 'object') {\n    try {\n      return JSON.stringify(value);\n    } catch {\n      return String(value);\n    }\n  }\n\n  return String(value);\n}\n","import {\n  computed,\n  Directive,\n  effect,\n  inject,\n  input,\n  signal,\n  Signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormResetEvent, FormSubmittedEvent, NgForm } from '@angular/forms';\nimport { filter, map, startWith } from 'rxjs';\nimport {\n  NGX_ERROR_DISPLAY_MODE_TOKEN,\n  NGX_WARNING_DISPLAY_MODE_TOKEN,\n  SC_ERROR_DISPLAY_MODE_TOKEN,\n} from './error-display-mode.token';\nimport { FormControlStateDirective } from './form-control-state.directive';\nimport { getFormSubmittedSignal } from './form-submitted-state';\n\n/**\n * Error display modes for form controls.\n * - 'on-blur': Show errors after field is touched/blurred\n * - 'on-submit': Show errors after form submission\n * - 'on-blur-or-submit': Show errors after blur or form submission (default)\n * - 'on-dirty': Show errors as soon as the field value changes\n * - 'always': Show errors immediately, even on pristine fields\n */\nexport type ScErrorDisplayMode =\n  | 'on-blur'\n  | 'on-submit'\n  | 'on-blur-or-submit'\n  | 'on-dirty'\n  | 'always';\n\n/**\n * Warning display modes for form controls.\n * - 'on-touch': Show warnings after field is touched/blurred\n * - 'on-validated-or-touch': Show warnings after validation runs or field is touched (default)\n * - 'on-dirty': Show warnings as soon as the field value changes\n * - 'always': Show warnings immediately, even on pristine fields\n */\nexport type NgxWarningDisplayMode =\n  | 'on-touch'\n  | 'on-validated-or-touch'\n  | 'on-dirty'\n  | 'always';\n\nexport const SC_ERROR_DISPLAY_MODE_DEFAULT: ScErrorDisplayMode =\n  'on-blur-or-submit';\nexport const SC_WARNING_DISPLAY_MODE_DEFAULT: NgxWarningDisplayMode =\n  'on-validated-or-touch';\n\n@Directive({\n  selector: '[formErrorDisplay], [ngxErrorDisplay]',\n  exportAs: 'formErrorDisplay, ngxErrorDisplay',\n  hostDirectives: [FormControlStateDirective],\n})\nexport class FormErrorDisplayDirective {\n  readonly #formControlState = inject(FormControlStateDirective);\n  // Optionally inject NgForm for form submission tracking\n  readonly #ngForm = inject(NgForm, { optional: true });\n  readonly #formSubmittedState = this.#ngForm\n    ? getFormSubmittedSignal(this.#ngForm)\n    : signal(false);\n\n  /**\n   * Input signal for error display mode.\n   * Works seamlessly with hostDirectives in Angular 19+.\n   */\n  readonly errorDisplayMode = input<ScErrorDisplayMode>(\n    inject(NGX_ERROR_DISPLAY_MODE_TOKEN, { optional: true }) ??\n      inject(SC_ERROR_DISPLAY_MODE_TOKEN, { optional: true }) ??\n      SC_ERROR_DISPLAY_MODE_DEFAULT\n  );\n\n  /**\n   * Input signal for warning display mode.\n   * Controls whether warnings are shown only after touch or also after validation.\n   */\n  readonly warningDisplayMode = input<NgxWarningDisplayMode>(\n    inject(NGX_WARNING_DISPLAY_MODE_TOKEN, { optional: true }) ??\n      SC_WARNING_DISPLAY_MODE_DEFAULT\n  );\n\n  // Expose state signals from FormControlStateDirective\n  readonly controlState = this.#formControlState.controlState;\n  readonly errorMessages = this.#formControlState.errorMessages;\n  readonly warningMessages = this.#formControlState.warningMessages;\n  readonly hasPendingValidation = this.#formControlState.hasPendingValidation;\n  readonly isTouched = this.#formControlState.isTouched;\n  readonly isDirty = this.#formControlState.isDirty;\n  readonly isValid = this.#formControlState.isValid;\n  readonly isInvalid = this.#formControlState.isInvalid;\n  readonly hasBeenValidated = this.#formControlState.hasBeenValidated;\n  /**\n   * Expose updateOn and formSubmitted as public signals for advanced consumers.\n   * updateOn: The ngModelOptions.updateOn value for the control (change/blur/submit)\n   * formSubmitted: true after the form is submitted (if NgForm is present)\n   */\n  readonly updateOn = this.#formControlState.updateOn;\n\n  /**\n   * Signal that tracks NgForm.submitted state reactively.\n   *\n   * Map form-level submit/reset events directly to boolean state.\n   *\n   * This keeps programmatic `NgForm.onSubmit()` reactive in zoneless mode and\n   * avoids depending on `NgForm.submitted`, whose getter intentionally reads an\n   * internal signal with `untracked()`.\n   *\n   * Note: when this directive is used outside an `NgForm` (no parent form), no\n   * subscription is wired up and this signal stays `false` for the lifetime of\n   * the directive. Consumers relying on submitted state must host the field\n   * inside an `NgForm` (or `ngxVestForm`).\n   */\n  readonly formSubmitted: Signal<boolean> = this.#formSubmittedState;\n\n  constructor() {\n    const ngForm = this.#ngForm;\n    if (ngForm) {\n      ngForm.form.events\n        .pipe(\n          filter(\n            (event) =>\n              event.source === ngForm.form &&\n              (event instanceof FormSubmittedEvent ||\n                event instanceof FormResetEvent)\n          ),\n          map((event) => event instanceof FormSubmittedEvent),\n          startWith(ngForm.submitted),\n          takeUntilDestroyed()\n        )\n        .subscribe((submitted) => {\n          this.#formSubmittedState.set(submitted);\n        });\n    }\n\n    // Warn about problematic combinations of updateOn and errorDisplayMode\n    effect(() => {\n      const mode = this.errorDisplayMode();\n      const updateOn = this.updateOn();\n      if (updateOn === 'submit' && mode === 'on-blur') {\n        console.warn(\n          '[ngx-vest-forms] Potential UX issue: errorDisplayMode is \"on-blur\" but updateOn is \"submit\". Errors will only show after form submission, not after blur.'\n        );\n      }\n    });\n  }\n\n  /**\n   * Determines if errors should be shown based on the specified display mode\n   * and the control's state (touched/submitted/dirty).\n   *\n   * Note: We check both hasErrors (extracted error messages) AND isInvalid (Angular's validation state)\n   * because in some cases (like conditional validations via validationConfig), the control is marked\n   * as invalid by Angular before error messages are extracted from Vest. This ensures aria-invalid\n   * is set correctly even during the validation propagation delay.\n   *\n   * For validationConfig-triggered validations, a field may become invalid before it has been\n   * touched. Error visibility still respects the field's own `errorDisplayMode`, so untouched\n   * dependent fields can remain visually quiet until blur or submit.\n   */\n  readonly shouldShowErrors: Signal<boolean> = computed(() => {\n    const mode = this.errorDisplayMode();\n    const isTouched = this.isTouched();\n    const isDirty = this.isDirty();\n    const isInvalid = this.isInvalid();\n    const hasErrors = this.errorMessages().length > 0;\n    const updateOn = this.updateOn();\n    const formSubmitted = this.formSubmitted();\n\n    // Consider errors present if either we have error messages OR the control is invalid\n    // This handles the race condition where Angular marks control invalid before Vest errors propagate\n    const hasErrorState = hasErrors || isInvalid;\n\n    // Always only show errors after submit if updateOn is 'submit'\n    if (updateOn === 'submit') {\n      return !!(formSubmitted && hasErrorState);\n    }\n\n    // Handle the new display modes\n    switch (mode) {\n      case 'always':\n        // Always show errors immediately, even on pristine fields\n        return hasErrorState;\n\n      case 'on-dirty':\n        // Show when value has changed, OR when touched/submitted (for backwards compat)\n        return !!(isDirty || isTouched || formSubmitted) && hasErrorState;\n\n      case 'on-blur':\n        // Show after touch (blur) or form submission (traditional behavior, not dirty-based)\n        return !!(isTouched || formSubmitted) && hasErrorState;\n\n      case 'on-submit':\n        // Show only after form submission\n        return !!(formSubmitted && hasErrorState);\n\n      case 'on-blur-or-submit':\n      default:\n        // Show after blur (touch) OR submit (default behavior)\n        return !!((isTouched || formSubmitted) && hasErrorState);\n    }\n  });\n\n  /**\n   * Errors to display (filtered for pending state)\n   */\n  readonly errors: Signal<string[]> = computed(() => {\n    if (this.hasPendingValidation()) return [];\n    return this.errorMessages();\n  });\n\n  /**\n   * Warnings to display (filtered for pending state)\n   */\n  readonly warnings: Signal<string[]> = computed(() => {\n    if (this.hasPendingValidation()) return [];\n    return this.warningMessages();\n  });\n\n  /**\n   * Whether the control is currently being validated (pending)\n   * Excludes pristine+untouched controls to prevent \"Validating...\" on initial load\n   */\n  readonly isPending: Signal<boolean> = computed(() => {\n    // Don't show pending state for pristine untouched controls\n    // This prevents \"Validating...\" message appearing on initial page load\n    const state = this.#formControlState.controlState();\n    if (state.isPristine && !state.isTouched) {\n      return false;\n    }\n    return this.hasPendingValidation();\n  });\n\n  /**\n   * Determines if warnings should be shown based on the specified display mode\n   * and the control's state (touched/validated/dirty).\n   *\n   * NOTE: Unlike errors, warnings can exist on VALID fields (warnings-only scenario).\n   * We don't require isInvalid() because Vest warn() tests don't affect field validity.\n   *\n   * UX Note: We include `hasBeenValidated` for `on-validated-or-touch` mode to support\n   * cross-field validation. If Field A triggers validation on Field B (via validationConfig),\n   * Field B should show warnings if it has them, even if the user hasn't touched Field B yet.\n   * Unlike errors (which block submission), warnings are informational and safe to show.\n   */\n  readonly shouldShowWarnings: Signal<boolean> = computed(() => {\n    const mode = this.warningDisplayMode();\n    const isTouched = this.isTouched();\n    const isDirty = this.isDirty();\n    const hasBeenValidated = this.hasBeenValidated();\n    const hasWarnings = this.warningMessages().length > 0;\n    const isPending = this.hasPendingValidation();\n    const formSubmitted = this.formSubmitted();\n\n    // No warnings to show or still pending\n    if (!hasWarnings || isPending) {\n      return false;\n    }\n\n    // Handle the warning display modes\n    switch (mode) {\n      case 'always':\n        // Always show warnings immediately, even on pristine fields\n        return true;\n\n      case 'on-dirty':\n        // Show when value has changed, OR when touched/submitted (for backwards compat)\n        return isDirty || isTouched || formSubmitted;\n\n      case 'on-touch':\n        // Show after touch (blur) or form submission (traditional behavior, not dirty-based)\n        return isTouched || formSubmitted;\n\n      case 'on-validated-or-touch':\n      default:\n        // Show after validation runs or after touch/submit (default behavior)\n        return hasBeenValidated || isTouched || formSubmitted;\n    }\n  });\n}\n","export type AriaAssociationMode = 'all-controls' | 'single-control' | 'none';\n\n/**\n * Splits an `aria-describedby` attribute value into normalized token IDs.\n */\nexport function parseAriaIdTokens(value: string | null): string[] {\n  return (value ?? '')\n    .split(/\\s+/)\n    .map((token) => token.trim())\n    .filter(Boolean);\n}\n\n/**\n * Merges currently-active wrapper IDs into an existing `aria-describedby` value.\n *\n * Existing tokens owned by the wrapper are removed first, then current active IDs\n * are appended while preserving non-owned tokens and token uniqueness.\n */\nexport function mergeAriaDescribedBy(\n  existing: string | null,\n  activeIds: readonly string[],\n  ownedIds: readonly string[]\n): string | null {\n  const ownedIdSet = new Set(ownedIds);\n  const existingTokens = parseAriaIdTokens(existing);\n  const existingWithoutOwned = existingTokens.filter(\n    (token) => !ownedIdSet.has(token)\n  );\n\n  const merged: string[] = [...existingWithoutOwned];\n  const mergedIdSet = new Set(merged);\n  for (const id of activeIds) {\n    if (!mergedIdSet.has(id)) {\n      merged.push(id);\n      mergedIdSet.add(id);\n    }\n  }\n\n  return merged.length > 0 ? merged.join(' ') : null;\n}\n\n/**\n * Resolves control targets based on ARIA association mode.\n */\nexport function resolveAssociationTargets(\n  controls: readonly HTMLElement[],\n  mode: AriaAssociationMode\n): HTMLElement[] {\n  if (mode === 'none') {\n    return [];\n  }\n\n  if (mode === 'single-control') {\n    return controls.length === 1 ? [...controls] : [];\n  }\n\n  return [...controls];\n}\n","import { effect, isSignal, Signal, signal } from '@angular/core';\n\n/**\n * Options for configuring debounced pending state behavior.\n */\nexport type DebouncedPendingStateOptions = {\n  /**\n   * Delay in milliseconds before showing the pending message.\n   * Prevents flashing for quick async validations.\n   * @default 200\n   */\n  showAfter?: number;\n\n  /**\n   * Minimum display time in milliseconds once the pending message is shown.\n   * Prevents flickering when validation completes shortly after being shown.\n   * @default 500\n   */\n  minimumDisplay?: number;\n};\n\n/**\n * Accepts either a static options object or a reactive `Signal` (e.g. an\n * `input()` accessor) so consumers can update debounce timings at runtime\n * without recreating the pending-state machine.\n */\nexport type DebouncedPendingStateOptionsInput =\n  | DebouncedPendingStateOptions\n  | Signal<DebouncedPendingStateOptions>;\n\n/**\n * Result of createDebouncedPendingState containing the debounced signal\n * and cleanup function.\n */\nexport type DebouncedPendingStateResult = {\n  /**\n   * Signal that is true when the pending message should be shown.\n   * This is debounced according to the provided options.\n   */\n  showPendingMessage: Signal<boolean>;\n\n  /**\n   * Optional cleanup function to cancel any pending timeouts.\n   * Call this in ngOnDestroy if needed (though the effect cleanup handles most cases).\n   */\n  cleanup: () => void;\n};\n\n/**\n * Creates a debounced pending state signal that prevents flashing validation messages.\n *\n * This utility helps implement a better UX for async validations by:\n * 1. Delaying the display of \"Validating...\" messages until validation takes longer than `showAfter`ms (default: 200ms)\n * 2. Keeping the message visible for at least `minimumDisplay`ms (default: 500ms) once shown to prevent flickering\n *\n * @example\n * ```typescript\n * @Component({\n *   template: `\n *     @if (showPendingMessage()) {\n *       <div role=\"status\" aria-live=\"polite\">Validating…</div>\n *     }\n *   `\n * })\n * export class CustomControlWrapperComponent {\n *   protected readonly errorDisplay = inject(FormErrorDisplayDirective, { self: true });\n *\n *   // Create debounced pending state\n *   private readonly pendingState = createDebouncedPendingState(\n *     this.errorDisplay.isPending,\n *     { showAfter: 200, minimumDisplay: 500 }\n *   );\n *\n *   protected readonly showPendingMessage = this.pendingState.showPendingMessage;\n * }\n * ```\n *\n * @param isPending - Signal indicating whether async validation is currently pending\n * @param options - Configuration options for debouncing behavior\n * @returns Object containing the debounced showPendingMessage signal and cleanup function\n */\nexport function createDebouncedPendingState(\n  isPending: Signal<boolean>,\n  options: DebouncedPendingStateOptionsInput = {}\n): DebouncedPendingStateResult {\n  // Reading the options inside the effect makes the timings reactive: when\n  // a consumer passes an `input()` accessor (a Signal), changes propagate at\n  // runtime rather than getting captured once at construction.\n  const optionsSignal: Signal<DebouncedPendingStateOptions> | null = isSignal(\n    options\n  )\n    ? (options as Signal<DebouncedPendingStateOptions>)\n    : null;\n  const staticOptions: DebouncedPendingStateOptions = optionsSignal\n    ? {}\n    : (options as DebouncedPendingStateOptions);\n\n  // Create writable signal for debounced state\n  const showPendingMessageSignal = signal(false);\n\n  // Track timeouts\n  let pendingTimeout: ReturnType<typeof setTimeout> | null = null;\n  let minimumDisplayTimeout: ReturnType<typeof setTimeout> | null = null;\n\n  // Cleanup function\n  const cleanup = () => {\n    if (pendingTimeout) {\n      clearTimeout(pendingTimeout);\n      pendingTimeout = null;\n    }\n    if (minimumDisplayTimeout) {\n      clearTimeout(minimumDisplayTimeout);\n      minimumDisplayTimeout = null;\n    }\n  };\n\n  // Effect to manage debounced pending message display\n  effect((onCleanup) => {\n    const pending = isPending();\n    const current = optionsSignal ? optionsSignal() : staticOptions;\n    const showAfter = current.showAfter ?? 200;\n    const minimumDisplay = current.minimumDisplay ?? 500;\n\n    if (pending) {\n      // Clear any existing minimum display timeout\n      if (minimumDisplayTimeout) {\n        clearTimeout(minimumDisplayTimeout);\n        minimumDisplayTimeout = null;\n      }\n\n      // Start delay timer before showing pending message\n      pendingTimeout = setTimeout(() => {\n        showPendingMessageSignal.set(true);\n        pendingTimeout = null;\n      }, showAfter);\n\n      onCleanup(() => {\n        if (pendingTimeout) {\n          clearTimeout(pendingTimeout);\n          pendingTimeout = null;\n        }\n      });\n    } else {\n      // Validation completed\n      if (pendingTimeout) {\n        // Validation completed before delay - don't show message\n        clearTimeout(pendingTimeout);\n        pendingTimeout = null;\n      } else if (showPendingMessageSignal()) {\n        // Message was shown - keep it visible for minimum duration\n        minimumDisplayTimeout = setTimeout(() => {\n          showPendingMessageSignal.set(false);\n          minimumDisplayTimeout = null;\n        }, minimumDisplay);\n\n        onCleanup(() => {\n          if (minimumDisplayTimeout) {\n            clearTimeout(minimumDisplayTimeout);\n            minimumDisplayTimeout = null;\n          }\n        });\n      }\n    }\n  });\n\n  return {\n    showPendingMessage: showPendingMessageSignal.asReadonly(),\n    cleanup,\n  };\n}\n","import {\n  AfterContentInit,\n  ChangeDetectionStrategy,\n  Component,\n  computed,\n  DestroyRef,\n  effect,\n  ElementRef,\n  inject,\n  input,\n  OnDestroy,\n  signal,\n} from '@angular/core';\nimport { FormErrorDisplayDirective } from '../../directives/form-error-display.directive';\nimport {\n  AriaAssociationMode,\n  mergeAriaDescribedBy,\n  parseAriaIdTokens,\n  resolveAssociationTargets,\n} from '../../utils/aria-association.utils';\nimport { createDebouncedPendingState } from '../../utils/pending-state.utils';\n\n// Counter for unique IDs\nlet nextUniqueId = 0;\n\n/**\n * Accessible form control wrapper built with WCAG 2.2 AA considerations.\n *\n * Wrap form fields to automatically display validation errors, warnings, and pending states\n * with proper accessibility attributes.\n *\n * @usageNotes\n *\n * ### Basic Usage\n * ```html\n * <ngx-control-wrapper>\n *   <label for=\"email\">Email</label>\n *   <input id=\"email\" name=\"email\" [ngModel]=\"formValue().email\" />\n * </ngx-control-wrapper>\n * ```\n *\n * ### Error Display Modes\n * Control when errors appear using the `errorDisplayMode` input:\n * - `'on-blur-or-submit'` (default): Show errors after blur OR form submit\n * - `'on-blur'`: Show errors only after blur\n * - `'on-submit'`: Show errors only after form submit\n * - `'on-dirty'`: Show errors as soon as the field value changes\n * - `'always'`: Show errors immediately, even on pristine fields\n *\n * ```html\n * <ngx-control-wrapper [errorDisplayMode]=\"'on-submit'\">\n *   <input name=\"email\" [ngModel]=\"formValue().email\" />\n * </ngx-control-wrapper>\n * ```\n *\n * ### Warning Display Modes\n * Control when warnings appear using the `warningDisplayMode` input:\n * - `'on-validated-or-touch'` (default): Show warnings after validation runs or touch\n * - `'on-touch'`: Show warnings only after touch/blur\n * - `'on-dirty'`: Show warnings as soon as the field value changes\n * - `'always'`: Show warnings immediately, even on pristine fields\n *\n * ```html\n * <ngx-control-wrapper [warningDisplayMode]=\"'on-dirty'\">\n *   <input name=\"email\" [ngModel]=\"formValue().email\" />\n * </ngx-control-wrapper>\n * ```\n *\n * ### Accessibility Features (Automatic)\n * - Unique IDs for error/warning/pending regions\n * - `aria-describedby` linking errors to form controls\n * - `aria-invalid=\"true\"` when errors are shown\n * - Uses `role=\"status\"` with `aria-live=\"polite\"` for non-disruptive announcements\n * - Debounced pending state to prevent flashing for quick validations\n *\n * ### WCAG 2.2 AA - Error Severity Levels\n * This component uses `role=\"status\"` for **field-level** validation messages:\n * - **Errors**: Non-disruptive announcement (user can continue filling other fields)\n * - **Warnings**: Informational only, doesn't block submission\n * - **Pending**: Status update while async validation runs\n *\n * For **form-level blocking errors** (e.g., submission failed), implement a separate\n * error summary component with `role=\"alert\"` and `aria-live=\"assertive\"`.\n *\n * @see {@link FormErrorDisplayDirective} for custom wrapper implementation\n *\n *   Form-Level Blocking Errors:\n *   - For post-submit validation errors that block submission, implement a separate\n *     form-level error summary with role=\"alert\" and aria-live=\"assertive\"\n *   - This component uses role=\"status\" for field-level errors (non-disruptive)\n *   - Example for form-level errors:\n *     ```html\n *     <!-- Keep in DOM; update text content on submit -->\n *     <div id=\"form-errors\" role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\"></div>\n *     ```\n *   - This separation provides immediate announcements for blocking form errors while\n *     keeping inline field errors non-disruptive. Follows WCAG ARIA21/ARIA22 guidance.\n *\n * Error & Warning Display Behavior:\n *   - The error display mode can be configured globally using the NGX_ERROR_DISPLAY_MODE_TOKEN injection token, or per instance using the `errorDisplayMode` input on FormErrorDisplayDirective (which this component uses as a hostDirective).\n *   - Possible error display values: 'on-blur' | 'on-submit' | 'on-blur-or-submit' | 'on-dirty' | 'always' (default: 'on-blur-or-submit')\n *   - The warning display mode can be configured globally using NGX_WARNING_DISPLAY_MODE_TOKEN, or per instance using the `warningDisplayMode` input on FormErrorDisplayDirective.\n *   - Possible warning display values: 'on-touch' | 'on-validated-or-touch' | 'on-dirty' | 'always' (default: 'on-validated-or-touch')\n *\n * Example (per instance):\n *   <div ngxControlWrapper>\n *     <label>\n *       <span>First name</span>\n *       <input type=\"text\" name=\"firstName\" [ngModel]=\"formValue().firstName\" />\n *     </label>\n *   </div>\n *   /// To customize errorDisplayMode for this instance, use the errorDisplayMode input.\n *\n * Example (with warnings and pending):\n *   <ngx-control-wrapper>\n *     <input name=\"username\" ngModel />\n *   </ngx-control-wrapper>\n *   /// If async validation is running for >500ms, a spinner and 'Validating…' will be shown.\n *   /// Once shown, the validation message stays visible for minimum 500ms to prevent flashing.\n *   /// If Vest warnings are present, they will be shown below errors.\n *\n * Example (global config):\n *   import { provide } from '@angular/core';\n *   import { NGX_ERROR_DISPLAY_MODE_TOKEN } from 'ngx-vest-forms';\n *   @Component({\n *     providers: [\n *       provide(NGX_ERROR_DISPLAY_MODE_TOKEN, { useValue: 'on-submit' })\n *     ]\n *   })\n *   export class MyComponent {}\n *\n * Best Practices:\n *   - Use for single-control wrappers.\n *   - For multi-control/group containers, prefer `ngx-form-group-wrapper`.\n *   - Do not manually display errors for individual fields; rely on this wrapper.\n *   - Validate with tools like Accessibility Insights and real screen reader testing.\n *\n * @see https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA19 - ARIA19: Using ARIA role=alert\n * @see https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA22 - ARIA22: Using role=status\n */\n@Component({\n  selector:\n    'ngx-control-wrapper, sc-control-wrapper, [scControlWrapper], [ngxControlWrapper], [ngx-control-wrapper], [sc-control-wrapper]',\n  templateUrl: './control-wrapper.component.html',\n  styles: `\n    :host {\n      display: block;\n      position: relative;\n    }\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n\n  host: {\n    class: 'ngx-control-wrapper sc-control-wrapper',\n    '[class.ngx-control-wrapper--invalid]': 'errorDisplay.shouldShowErrors()',\n    '[attr.aria-busy]': \"errorDisplay.isPending() ? 'true' : null\",\n  },\n  hostDirectives: [\n    {\n      directive: FormErrorDisplayDirective,\n      inputs: ['errorDisplayMode', 'warningDisplayMode'],\n    },\n  ],\n})\nexport class ControlWrapperComponent implements AfterContentInit, OnDestroy {\n  protected readonly errorDisplay = inject(FormErrorDisplayDirective, {\n    self: true,\n  });\n  private readonly elementRef = inject(ElementRef);\n  private readonly destroyRef = inject(DestroyRef);\n\n  /**\n   * Controls how this wrapper applies ARIA attributes to descendant controls.\n   *\n   * - `all-controls` (default, backwards compatible): apply `aria-describedby` / `aria-invalid`\n   *   to all `input/select/textarea` elements inside the wrapper.\n   * - `single-control`: apply ARIA attributes only when exactly one control is found.\n   *   (Useful for wrappers that sometimes contain helper buttons/controls.)\n   * - `none`: do not mutate descendant controls at all (group-safe mode).\n   *\n   * Notes:\n   * - Use `none` when wrapping a container (e.g. `NgModelGroup`) to avoid stamping ARIA\n   *   across multiple child controls.\n   * - This does not affect whether messages render; it only affects ARIA wiring.\n   */\n  readonly ariaAssociationMode = input<AriaAssociationMode>('all-controls');\n\n  // Generate unique IDs for ARIA associations\n  protected readonly uniqueId = `ngx-control-wrapper-${nextUniqueId++}`;\n  protected readonly errorId = `${this.uniqueId}-error`;\n  protected readonly warningId = `${this.uniqueId}-warning`;\n  protected readonly pendingId = `${this.uniqueId}-pending`;\n\n  // Track form controls found in the wrapper\n  private readonly formControls = signal<HTMLElement[]>([]);\n\n  // Signals when content is initialized so effects can safely touch the DOM.\n  private readonly contentInitialized = signal(false);\n\n  // MutationObserver to detect dynamically added/removed controls\n  private mutationObserver: MutationObserver | null = null;\n\n  /**\n   * Debounced pending state to prevent flashing for quick async validations.\n   * Uses createDebouncedPendingState utility with 500ms delay and 500ms minimum display.\n   */\n  private readonly pendingState = createDebouncedPendingState(\n    this.errorDisplay.isPending,\n    { showAfter: 500, minimumDisplay: 500 }\n  );\n  protected readonly showPendingMessage = this.pendingState.showPendingMessage;\n\n  /**\n   * Whether to display warnings.\n   * Delegates to FormErrorDisplayDirective's centralized shouldShowWarnings signal.\n   *\n   * This ensures consistent warning display behavior across all form components\n   * and supports the new 'on-dirty' and 'always' display modes.\n   */\n  protected readonly shouldShowWarnings = this.errorDisplay.shouldShowWarnings;\n\n  /**\n   * Computed signal that builds aria-describedby string based on visible regions\n   */\n  protected readonly ariaDescribedBy = computed(() => {\n    const ids: string[] = [];\n    if (this.errorDisplay.shouldShowErrors()) {\n      ids.push(this.errorId);\n    }\n    if (this.shouldShowWarnings()) {\n      ids.push(this.warningId);\n    }\n    if (this.showPendingMessage()) {\n      ids.push(this.pendingId);\n    }\n    return ids.length > 0 ? ids.join(' ') : null;\n  });\n\n  /**\n   * IDs managed by this wrapper when composing aria-describedby.\n   *\n   * We remove only these from the consumer-provided aria-describedby tokens and then\n   * append the currently-relevant wrapper IDs. This prevents clobbering app-provided\n   * hint/help text associations.\n   */\n  private readonly wrapperOwnedDescribedByIds = [\n    this.errorId,\n    this.warningId,\n    this.pendingId,\n  ];\n\n  constructor() {\n    // Effect to update aria-describedby and aria-invalid on form controls\n    effect(() => {\n      if (!this.contentInitialized()) return;\n\n      const mode = this.ariaAssociationMode();\n      if (mode === 'none') {\n        return;\n      }\n\n      const describedBy = this.ariaDescribedBy();\n      const wrapperActiveIds = parseAriaIdTokens(describedBy);\n      const shouldShowErrors = this.errorDisplay.shouldShowErrors();\n\n      const targets = resolveAssociationTargets(this.formControls(), mode);\n\n      targets.forEach((control) => {\n        // Update aria-describedby (merge, don't overwrite)\n        const nextDescribedBy = mergeAriaDescribedBy(\n          control.getAttribute('aria-describedby'),\n          wrapperActiveIds,\n          this.wrapperOwnedDescribedByIds\n        );\n        if (nextDescribedBy) {\n          control.setAttribute('aria-describedby', nextDescribedBy);\n        } else {\n          control.removeAttribute('aria-describedby');\n        }\n\n        // Update aria-invalid\n        if (shouldShowErrors) {\n          control.setAttribute('aria-invalid', 'true');\n        } else {\n          control.removeAttribute('aria-invalid');\n        }\n      });\n    });\n\n    // Clean up MutationObserver when component is destroyed\n    this.destroyRef.onDestroy(() => {\n      this.mutationObserver?.disconnect();\n      this.mutationObserver = null;\n    });\n\n    // Effect to enable/disable DOM observation based on ariaAssociationMode.\n    // This keeps the wrapper cheap in group-safe mode.\n    effect(() => {\n      if (!this.contentInitialized()) return;\n\n      const mode = this.ariaAssociationMode();\n\n      if (mode === 'none') {\n        this.mutationObserver?.disconnect();\n        this.mutationObserver = null;\n        if (this.formControls().length > 0) {\n          this.formControls.set([]);\n        }\n        return;\n      }\n\n      // Ensure controls list is up to date.\n      this.updateFormControls();\n\n      // Ensure MutationObserver is installed (dynamic @if/@for support).\n      if (!this.mutationObserver) {\n        this.mutationObserver = new MutationObserver(() => {\n          this.updateFormControls();\n        });\n\n        this.mutationObserver.observe(this.elementRef.nativeElement, {\n          childList: true,\n          subtree: true,\n        });\n      }\n    });\n  }\n\n  ngAfterContentInit(): void {\n    this.contentInitialized.set(true);\n\n    // ARIA wiring + observer setup is managed by effects so that the wrapper can\n    // opt out (ariaAssociationMode=\"none\").\n  }\n\n  ngOnDestroy(): void {\n    this.mutationObserver?.disconnect();\n    this.mutationObserver = null;\n  }\n\n  /**\n   * Query and update the list of form controls within this wrapper.\n   * Called on init and whenever the DOM structure changes.\n   */\n  private updateFormControls(): void {\n    const controls = this.elementRef.nativeElement.querySelectorAll(\n      'input, select, textarea'\n    );\n    this.formControls.set(Array.from(controls) as HTMLElement[]);\n  }\n}\n","<div class=\"ngx-control-wrapper__content\">\n  <ng-content />\n</div>\n\n<!--\n  WCAG 2.2 AA Compliance for Inline Field Validation:\n\n  IMPORTANT DISTINCTION - Field-level vs Form-level errors:\n  - FIELD-LEVEL errors (this component): Use role=\"status\" with aria-live=\"polite\"\n    These are inline validation messages that appear as users interact with fields.\n    Using \"assertive\" would be too disruptive when users are filling out multiple fields.\n  - FORM-LEVEL blocking errors (e.g., submission failed): Should use role=\"alert\" with\n    aria-live=\"assertive\" in a separate form-level error summary component.\n\n  This component handles FIELD-LEVEL messages:\n  - Errors: role=\"status\" with aria-live=\"polite\" (non-disruptive, field is already\n    marked with aria-invalid=\"true\" and aria-describedby points here)\n  - Warnings: role=\"status\" with aria-live=\"polite\" (informational, doesn't block)\n  - Pending: role=\"status\" with aria-live=\"polite\" (status update)\n\n  The aria-invalid=\"true\" + aria-describedby association on the input provides\n  the primary accessibility pathway; the live region is supplementary.\n\n  @see https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA21 - Using aria-invalid\n  @see https://www.w3.org/WAI/WCAG22/Techniques/aria/ARIA22 - Using role=status\n-->\n<div\n  [id]=\"errorId\"\n  class=\"text-sm text-red-600\"\n  role=\"status\"\n  aria-live=\"polite\"\n  aria-atomic=\"true\"\n>\n  @if (errorDisplay.shouldShowErrors()) {\n    <ul class=\"m-0 mt-1 list-none space-y-1 p-0\">\n      @for (error of errorDisplay.errors(); track error) {\n        <li>{{ error }}</li>\n      }\n    </ul>\n  }\n</div>\n\n<!--\n  Warnings: Non-blocking validation messages (Vest warn())\n  - Use role=\"status\" with aria-live=\"polite\" per WCAG ARIA22\n  - Default: show after validation runs or touch; configurable to require touch only\n  - Warnings do NOT affect field validity - they're informational only\n-->\n<div\n  [id]=\"warningId\"\n  class=\"text-sm text-yellow-700\"\n  role=\"status\"\n  aria-live=\"polite\"\n  aria-atomic=\"true\"\n>\n  @if (shouldShowWarnings()) {\n    <ul class=\"m-0 mt-1 list-none space-y-1 p-0\">\n      @for (warn of errorDisplay.warnings(); track warn) {\n        <li>{{ warn }}</li>\n      }\n    </ul>\n  }\n</div>\n\n<!-- Pending state is also stable; content appears only after the debounce delay -->\n<div\n  [id]=\"pendingId\"\n  class=\"absolute top-0 right-0 flex items-center gap-1 text-xs text-gray-500\"\n  role=\"status\"\n  aria-live=\"polite\"\n  aria-atomic=\"true\"\n>\n  @if (showPendingMessage()) {\n    <span\n      class=\"inline-block h-3 w-3 animate-spin rounded-full border-2 border-gray-400 border-t-transparent\"\n      aria-hidden=\"true\"\n    ></span>\n    Validating…\n  }\n</div>\n","import {\n  ChangeDetectionStrategy,\n  Component,\n  computed,\n  inject,\n  input,\n} from '@angular/core';\nimport { FormErrorDisplayDirective } from '../../directives/form-error-display.directive';\nimport { createDebouncedPendingState } from '../../utils/pending-state.utils';\n\nlet nextUniqueId = 0;\n\n/**\n * Group-safe wrapper for `NgModelGroup` containers.\n *\n * This component renders group-level errors/warnings/pending UI, but intentionally\n * does **not** stamp `aria-describedby` / `aria-invalid` onto descendant controls.\n *\n * Use this when you want a wrapper around a container that has multiple inputs.\n * For single inputs, prefer `<ngx-control-wrapper>`.\n */\n@Component({\n  selector:\n    'ngx-form-group-wrapper, sc-form-group-wrapper, [ngxFormGroupWrapper], [scFormGroupWrapper]',\n  exportAs: 'ngxFormGroupWrapper',\n  templateUrl: './form-group-wrapper.component.html',\n  // Minimal structural styling: custom elements are inline by default.\n  styles: `\n    :host {\n      display: block;\n    }\n  `,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  host: {\n    class: 'ngx-form-group-wrapper sc-form-group-wrapper',\n    '[class.ngx-form-group-wrapper--invalid]':\n      'errorDisplay.shouldShowErrors()',\n    '[attr.aria-busy]': \"errorDisplay.isPending() ? 'true' : null\",\n  },\n  hostDirectives: [\n    {\n      directive: FormErrorDisplayDirective,\n      inputs: ['errorDisplayMode', 'warningDisplayMode'],\n    },\n  ],\n})\nexport class FormGroupWrapperComponent {\n  protected readonly errorDisplay = inject(FormErrorDisplayDirective, {\n    self: true,\n  });\n\n  /**\n   * Controls the debounce behavior for the pending message.\n   * Defaults are conservative to avoid flashing.\n   */\n  readonly pendingDebounce = input<{\n    showAfter: number;\n    minimumDisplay: number;\n  }>({\n    showAfter: 500,\n    minimumDisplay: 500,\n  });\n\n  protected readonly uniqueId = `ngx-form-group-wrapper-${nextUniqueId++}`;\n  readonly errorId = `${this.uniqueId}-error`;\n  readonly warningId = `${this.uniqueId}-warning`;\n  readonly pendingId = `${this.uniqueId}-pending`;\n\n  private readonly pendingState = createDebouncedPendingState(\n    this.errorDisplay.isPending,\n    this.pendingDebounce\n  );\n  protected readonly showPendingMessage = this.pendingState.showPendingMessage;\n\n  /**\n   * Helpful if consumers want to wire aria-describedby manually (e.g. fieldset/legend pattern).\n   */\n  readonly describedByIds = computed(() => {\n    const ids: string[] = [];\n\n    if (this.errorDisplay.shouldShowErrors()) {\n      ids.push(this.errorId);\n    }\n\n    if (this.errorDisplay.shouldShowWarnings()) {\n      ids.push(this.warningId);\n    }\n\n    if (this.showPendingMessage()) {\n      ids.push(this.pendingId);\n    }\n\n    return ids.length > 0 ? ids.join(' ') : null;\n  });\n}\n","<div class=\"ngx-form-group-wrapper__content\">\n  <ng-content />\n</div>\n\n<!--\n  Keep regions stable in the DOM so IDs are always valid targets.\n  This wrapper does NOT modify descendant controls.\n-->\n<div [id]=\"errorId\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n  @if (errorDisplay.shouldShowErrors() && errorDisplay.errors().length > 0) {\n    <ul>\n      @for (error of errorDisplay.errors(); track error) {\n        <li>{{ error }}</li>\n      }\n    </ul>\n  }\n</div>\n\n<div [id]=\"warningId\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n  @if (errorDisplay.shouldShowWarnings()) {\n    <ul>\n      @for (warn of errorDisplay.warnings(); track warn) {\n        <li>{{ warn }}</li>\n      }\n    </ul>\n  }\n</div>\n\n<div [id]=\"pendingId\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n  @if (showPendingMessage()) {\n    <span aria-hidden=\"true\">Validating…</span>\n  }\n</div>\n","import {\n  AfterContentInit,\n  computed,\n  Directive,\n  effect,\n  ElementRef,\n  inject,\n  input,\n  OnDestroy,\n  signal,\n} from '@angular/core';\nimport {\n  AriaAssociationMode,\n  mergeAriaDescribedBy,\n  parseAriaIdTokens,\n  resolveAssociationTargets,\n} from '../utils/aria-association.utils';\nimport { createDebouncedPendingState } from '../utils/pending-state.utils';\nimport { FormErrorDisplayDirective } from './form-error-display.directive';\n\nlet nextUniqueId = 0;\n\n/**\n * Wires a control container to its error/warning/pending regions.\n *\n * This directive is intended for custom wrappers/components.\n * It composes `FormErrorDisplayDirective` (and thus `FormControlStateDirective`)\n * and applies `aria-invalid` / `aria-describedby` to descendant controls.\n *\n * It does not render any UI; you can use the generated IDs to render messages.\n */\n@Directive({\n  selector: '[formErrorControl], [ngxErrorControl]',\n  exportAs: 'formErrorControl, ngxErrorControl',\n  hostDirectives: [\n    {\n      directive: FormErrorDisplayDirective,\n      inputs: ['errorDisplayMode', 'warningDisplayMode'],\n    },\n  ],\n})\nexport class FormErrorControlDirective implements AfterContentInit, OnDestroy {\n  protected readonly errorDisplay = inject(FormErrorDisplayDirective, {\n    self: true,\n  });\n\n  private readonly elementRef = inject(ElementRef<HTMLElement>);\n\n  /**\n   * Controls how this directive applies ARIA attributes to descendant controls.\n   *\n   * - `all-controls` (default): apply ARIA attributes to all input/select/textarea descendants.\n   * - `single-control`: apply ARIA attributes only when exactly one control is found.\n   * - `none`: do not mutate descendant controls.\n   */\n  readonly ariaAssociationMode = input<AriaAssociationMode>('all-controls');\n\n  /**\n   * Unique ID prefix for this instance.\n   * Use these IDs to render message regions and to support aria-describedby.\n   */\n  protected readonly uniqueId = `ngx-error-control-${nextUniqueId++}`;\n  readonly errorId = `${this.uniqueId}-error`;\n  readonly warningId = `${this.uniqueId}-warning`;\n  readonly pendingId = `${this.uniqueId}-pending`;\n\n  private readonly formControls = signal<HTMLElement[]>([]);\n  private readonly contentInitialized = signal(false);\n  private mutationObserver: MutationObserver | null = null;\n\n  private readonly pendingState = createDebouncedPendingState(\n    this.errorDisplay.isPending,\n    { showAfter: 500, minimumDisplay: 500 }\n  );\n  readonly showPendingMessage = this.pendingState.showPendingMessage;\n\n  /**\n   * aria-describedby value representing the *currently relevant* message regions.\n   */\n  readonly ariaDescribedBy = computed(() => {\n    const ids: string[] = [];\n\n    if (this.errorDisplay.shouldShowErrors()) {\n      ids.push(this.errorId);\n    }\n\n    if (this.errorDisplay.shouldShowWarnings()) {\n      ids.push(this.warningId);\n    }\n\n    if (this.showPendingMessage()) {\n      ids.push(this.pendingId);\n    }\n\n    return ids.length > 0 ? ids.join(' ') : null;\n  });\n\n  private readonly ownedDescribedByIds: string[] = [\n    this.errorId,\n    this.warningId,\n    this.pendingId,\n  ];\n\n  constructor() {\n    // Effect for ARIA attribute updates\n    effect(() => {\n      if (!this.contentInitialized()) return;\n\n      const mode = this.ariaAssociationMode();\n      if (mode === 'none') return;\n\n      const describedBy = this.ariaDescribedBy();\n      const activeIds = parseAriaIdTokens(describedBy);\n      const shouldShowErrors = this.errorDisplay.shouldShowErrors();\n\n      const targets = resolveAssociationTargets(this.formControls(), mode);\n\n      for (const control of targets) {\n        const nextDescribedBy = mergeAriaDescribedBy(\n          control.getAttribute('aria-describedby'),\n          activeIds,\n          this.ownedDescribedByIds\n        );\n        if (nextDescribedBy) {\n          control.setAttribute('aria-describedby', nextDescribedBy);\n        } else {\n          control.removeAttribute('aria-describedby');\n        }\n\n        if (shouldShowErrors) {\n          control.setAttribute('aria-invalid', 'true');\n        } else {\n          control.removeAttribute('aria-invalid');\n        }\n      }\n    });\n\n    // Effect for MutationObserver setup with proper cleanup\n    effect((onCleanup) => {\n      if (!this.contentInitialized()) return;\n\n      const mode = this.ariaAssociationMode();\n\n      if (mode === 'none') {\n        this.mutationObserver?.disconnect();\n        this.mutationObserver = null;\n        if (this.formControls().length > 0) {\n          this.formControls.set([]);\n        }\n        return;\n      }\n\n      this.updateFormControls();\n\n      if (!this.mutationObserver) {\n        this.mutationObserver = new MutationObserver(() => {\n          this.updateFormControls();\n        });\n\n        this.mutationObserver.observe(this.elementRef.nativeElement, {\n          childList: true,\n          subtree: true,\n        });\n      }\n\n      // Proper cleanup using onCleanup callback (Angular 21 best practice)\n      onCleanup(() => {\n        this.mutationObserver?.disconnect();\n        this.mutationObserver = null;\n      });\n    });\n  }\n\n  ngAfterContentInit(): void {\n    this.contentInitialized.set(true);\n  }\n\n  ngOnDestroy(): void {\n    this.mutationObserver?.disconnect();\n    this.mutationObserver = null;\n  }\n\n  private updateFormControls(): void {\n    const controls = this.elementRef.nativeElement.querySelectorAll(\n      'input, select, textarea'\n    );\n    this.formControls.set(Array.from(controls) as HTMLElement[]);\n  }\n}\n","import { isDevMode } from '@angular/core';\nimport { AbstractControl, ValidationErrors } from '@angular/forms';\nimport { Observable, from, of } from 'rxjs';\nimport { FormDirective } from './form.directive';\nimport { ValidationOptions } from './validation-options';\n\ntype FieldResolver = (control: AbstractControl) => string;\n\ntype ValidationResult =\n  | Observable<ValidationErrors | null>\n  | Promise<ValidationErrors | null>\n  | ValidationErrors\n  | null;\n\n/**\n * @internal\n * Shared bridge for resolving a field path and invoking FormDirective async validation.\n * Keeps fail-open semantics for missing context/path while consolidating behavior.\n *\n * @param control - Control being validated by Angular forms.\n * @param context - Optional parent form directive context.\n * @param resolveField - Resolver that maps the control to a field path.\n * @param validationOptions - Per-control validation options.\n * @param source - Caller identifier for diagnostics.\n */\nexport function runAsyncValidationBridge(\n  control: AbstractControl,\n  context: FormDirective<Record<string, unknown>> | null,\n  resolveField: FieldResolver,\n  validationOptions: ValidationOptions,\n  source: 'FormModelDirective' | 'FormModelGroupDirective'\n): Observable<ValidationErrors | null> {\n  if (!control) {\n    return of(null);\n  }\n\n  if (!context) {\n    if (isDevMode()) {\n      console.warn(\n        `[ngx-vest-forms] ${source}: No FormDirective context found. Validation skipped (fail-open).`\n      );\n    }\n    return of(null);\n  }\n\n  const field = resolveField(control);\n  if (!field) {\n    if (isDevMode()) {\n      console.warn(\n        `[ngx-vest-forms] ${source}: Could not resolve control path. Ensure the control has a valid name/path and is registered in the form tree.`\n      );\n    }\n    return of(null);\n  }\n\n  const asyncValidator = context.createAsyncValidator(field, validationOptions);\n  const validationResult: ValidationResult = asyncValidator(control);\n\n  if (validationResult instanceof Observable) {\n    return validationResult;\n  }\n\n  if (validationResult instanceof Promise) {\n    return from(validationResult);\n  }\n\n  return of(validationResult ?? null);\n}\n","import { Directive, inject, input } from '@angular/core';\nimport {\n  AbstractControl,\n  AsyncValidator,\n  NG_ASYNC_VALIDATORS,\n  ValidationErrors,\n} from '@angular/forms';\nimport { Observable } from 'rxjs';\nimport { getFormGroupField } from '../utils/form-utils';\nimport { runAsyncValidationBridge } from './async-validator-bridge';\nimport { FormDirective } from './form.directive';\nimport { ValidationOptions } from './validation-options';\n\n/**\n * Hooks into `ngModelGroup`/`ngxModelGroup` and runs async group-level validation\n * through the parent `FormDirective` Vest suite bridge.\n */\n@Directive({\n  selector: '[ngModelGroup],[ngxModelGroup]',\n  providers: [\n    {\n      provide: NG_ASYNC_VALIDATORS,\n      useExisting: FormModelGroupDirective,\n      multi: true,\n    },\n  ],\n})\nexport class FormModelGroupDirective implements AsyncValidator {\n  /**\n   * Per-group async validation options.\n   *\n   * Defaults to no debounce (`{ debounceTime: 0 }`).\n   */\n  validationOptions = input<ValidationOptions>({ debounceTime: 0 });\n  private readonly formDirective: FormDirective<\n    Record<string, unknown>\n  > | null = inject(FormDirective, { optional: true });\n\n  /**\n   * Runs async validation for the current model-group control.\n   *\n   * Returns `null` (fail-open) when used outside an `ngxVestForm` context.\n   */\n  validate(control: AbstractControl): Observable<ValidationErrors | null> {\n    return runAsyncValidationBridge(\n      control,\n      this.formDirective,\n      (currentControl) => {\n        const context = this.formDirective;\n        if (!context) return '';\n        return getFormGroupField(context.ngForm.control, currentControl);\n      },\n      this.validationOptions(),\n      'FormModelGroupDirective'\n    );\n  }\n}\n","import { Directive, inject, input } from '@angular/core';\nimport {\n  AbstractControl,\n  AsyncValidator,\n  NG_ASYNC_VALIDATORS,\n  ValidationErrors,\n} from '@angular/forms';\nimport { Observable } from 'rxjs';\nimport { getFormControlField } from '../utils/form-utils';\nimport { runAsyncValidationBridge } from './async-validator-bridge';\nimport { FormDirective } from './form.directive';\nimport { ValidationOptions } from './validation-options';\n\n/**\n * Hooks into `ngModel`/`ngxModel` and runs async field-level validation\n * through the parent `FormDirective` Vest suite bridge.\n */\n@Directive({\n  selector: '[ngModel],[ngxModel]',\n\n  providers: [\n    {\n      provide: NG_ASYNC_VALIDATORS,\n      useExisting: FormModelDirective,\n      multi: true,\n    },\n  ],\n})\nexport class FormModelDirective implements AsyncValidator {\n  /**\n   * Per-control async validation options.\n   *\n   * Defaults to no debounce (`{ debounceTime: 0 }`).\n   */\n  validationOptions = input<ValidationOptions>({ debounceTime: 0 });\n  /**\n   * Reference to the form that needs to be validated\n   * Injected optionally so that using ngModel outside of an ngxVestForm\n   * does not crash the application. In that case, validation becomes a no-op.\n   */\n  private readonly formDirective: FormDirective<\n    Record<string, unknown>\n  > | null = inject(FormDirective, {\n    optional: true,\n  });\n\n  /**\n   * Runs field-level async validation for this control.\n   *\n   * Returns `null` (fail-open) when used outside an `ngxVestForm` context.\n   */\n  validate(control: AbstractControl): Observable<ValidationErrors | null> {\n    return runAsyncValidationBridge(\n      control,\n      this.formDirective,\n      (currentControl) => {\n        const context = this.formDirective;\n        if (!context) return '';\n        return getFormControlField(context.ngForm.control, currentControl);\n      },\n      this.validationOptions(),\n      'FormModelDirective'\n    );\n  }\n}\n","import {\n  AfterViewInit,\n  booleanAttribute,\n  DestroyRef,\n  Directive,\n  effect,\n  inject,\n  Injector,\n  input,\n  signal,\n  untracked,\n} from '@angular/core';\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';\nimport {\n  AbstractControl,\n  AsyncValidator,\n  AsyncValidatorFn,\n  NG_ASYNC_VALIDATORS,\n  NgForm,\n  ValidationErrors,\n} from '@angular/forms';\nimport {\n  catchError,\n  map,\n  Observable,\n  of,\n  switchMap,\n  take,\n  tap,\n  timer,\n} from 'rxjs';\nimport { ROOT_FORM } from '../constants';\nimport { scheduleMicrotask } from '../utils/destroy-scheduler';\nimport { NgxTypedVestSuite, NgxVestSuite } from '../utils/validation-suite';\nimport { ValidationOptions } from './validation-options';\n\n/**\n * Validates the root form (cross-field validation) using a Vest suite.\n *\n * Use this directive for form-wide validations that span multiple fields, such as:\n * - Password confirmation (`password` must match `confirmPassword`)\n * - Date range validation (`startDate` must be before `endDate`)\n * - Business rules like \"at least one contact method required\"\n *\n * @usageNotes\n *\n * ### Basic Usage\n * ```html\n * <form ngxVestForm ngxValidateRootForm [suite]=\"suite\" (errorsChange)=\"errors.set($event)\">\n *   <!-- form fields -->\n *   @if (errors()['rootForm']) {\n *     <div role=\"alert\">{{ errors()['rootForm'][0] }}</div>\n *   }\n * </form>\n * ```\n *\n * ### Validation Modes\n * - `'submit'` (default): Validates only after form submission. Better UX for complex cross-field rules.\n * - `'live'`: Validates on every value change. Use sparingly for simple two-field comparisons.\n *\n * ```html\n * <form ngxVestForm ngxValidateRootForm [ngxValidateRootFormMode]=\"'live'\">\n * ```\n *\n * ### Vest Suite Pattern\n * ```typescript\n * import { ROOT_FORM } from 'ngx-vest-forms';\n *\n * test(ROOT_FORM, 'Passwords must match', () => {\n *   enforce(model.confirmPassword).equals(model.password);\n * });\n * ```\n *\n * @see {@link https://github.com/ngx-vest-forms/ngx-vest-forms/blob/master/docs/VALIDATION-CONFIG-VS-ROOT-FORM.md}\n *\n * @example\n * ```html\n * <form scVestForm\n *       validateRootForm\n *       [suite]=\"suite\"\n *       [formValue]=\"formValue()\"\n *       [validateRootFormMode]=\"'submit'\"\n *       (errorsChange)=\"errors.set($event)\"\n *       #form=\"ngForm\">\n *   <!-- form fields -->\n *   @if (errors()['rootForm']) {\n *     <div role=\"alert\">{{ errors()['rootForm'][0] }}</div>\n *   }\n * </form>\n * ```\n *\n * @example\n * Validation suite:\n * ```typescript\n * import { ROOT_FORM } from 'ngx-vest-forms';\n *\n * export const suite = staticSuite((model, field?) => {\n *   only(field);\n *\n *   test(ROOT_FORM, 'Passwords must match', () => {\n *     enforce(model.confirmPassword).equals(model.password);\n *   });\n * });\n * ```\n *\n * @publicApi\n */\n@Directive({\n  selector: 'form[validateRootForm], form[ngxValidateRootForm]',\n\n  providers: [\n    {\n      provide: NG_ASYNC_VALIDATORS,\n      useExisting: ValidateRootFormDirective,\n      multi: true,\n    },\n  ],\n})\nexport class ValidateRootFormDirective<T>\n  implements AsyncValidator, AfterViewInit\n{\n  private readonly injector = inject(Injector);\n  private readonly destroyRef = inject(DestroyRef);\n  private readonly lastControl = signal<NgForm | null>(null);\n  validationOptions = input<ValidationOptions>({ debounceTime: 0 });\n  private readonly hasSubmitted = signal(false);\n  private readonly hasSubmitted$: Observable<boolean>;\n  private readonly formValue$: Observable<T | null>;\n\n  readonly formValue = input<T | null>(null);\n  readonly suite = input<NgxVestSuite<T> | NgxTypedVestSuite<T> | null>(null);\n\n  /**\n   * Whether the root form should be validated or not\n   * This will use the field rootForm\n   * Accepts both validateRootForm and ngxValidateRootForm\n   */\n  readonly validateRootForm = input(false, {\n    transform: booleanAttribute,\n  });\n  readonly ngxValidateRootForm = input(false, {\n    transform: booleanAttribute,\n  });\n\n  /**\n   * Validation mode:\n   * - `'submit'` (effective default): Only validates after form submission.\n   * - `'live'`: Validates on every value change.\n   *\n   * Both inputs default to `undefined` so we can detect whether the consumer\n   * set them explicitly. Precedence is `ngx ?? legacy ?? 'submit'`, which\n   * matches the documented behavior — observable only when both attributes\n   * are set explicitly on the same form.\n   */\n  readonly validateRootFormMode = input<'submit' | 'live' | undefined>(\n    undefined\n  );\n  readonly ngxValidateRootFormMode = input<'submit' | 'live' | undefined>(\n    undefined\n  );\n\n  constructor() {\n    // Convert signals to Observables in injection context\n    this.hasSubmitted$ = toObservable(this.hasSubmitted);\n    this.formValue$ = toObservable(this.formValue);\n\n    // Trigger validation when hasSubmitted or formValue changes\n    effect(() => {\n      // Track dependencies\n      this.hasSubmitted();\n      this.formValue();\n\n      // Also track inputs that affect whether validation should run.\n      // These can be set after the first validation pass and we want the\n      // root form to re-evaluate once they become available.\n      this.suite();\n      this.validateRootForm();\n      this.ngxValidateRootForm();\n      this.validateRootFormMode();\n      this.ngxValidateRootFormMode();\n      this.validationOptions();\n\n      // Trigger revalidation if form exists\n      // Use emitEvent: true so the form directive can update its errors\n      // Use untracked() to avoid making the effect reactive to lastControl changes\n      const ngForm = untracked(() => this.lastControl());\n      if (ngForm?.control) {\n        // Defer to the next microtask so Angular has a chance to finish\n        // wiring up controls/groups (ngModel/ngModelGroup) on initial render.\n        // The scheduleMicrotask primitive auto-cancels if the directive is\n        // destroyed before the microtask fires.\n        scheduleMicrotask(() => ngForm.control.updateValueAndValidity(), this.destroyRef);\n      }\n    });\n  }\n\n  /**\n   * Subscribe to form submit event using NgForm.ngSubmit EventEmitter\n   * This approach avoids conflicts with component's (ngSubmit) handlers\n   * Uses Injector to lazily get NgForm, avoiding circular dependency\n   * (Directive → NgForm → AsyncValidators → Directive)\n   */\n  ngAfterViewInit(): void {\n    // Lazily inject NgForm to avoid circular dependency\n    const ngForm = this.injector.get(NgForm, null);\n    this.lastControl.set(ngForm);\n\n    if (!ngForm) {\n      console.error(\n        '[ValidateRootFormDirective] NgForm not found. Ensure the directive is used on a <form> element with the scVestForm directive. ' +\n          'Common setup mistakes: (1) Missing scVestForm directive, (2) Directive on non-form element, (3) NgForm not imported in module/component.'\n      );\n      return;\n    }\n\n    // Ensure we run at least one validation pass after the form is ready.\n    // This matters for 'live' mode root-form errors that should appear\n    // without requiring a user interaction.\n    scheduleMicrotask(() => ngForm.control.updateValueAndValidity(), this.destroyRef);\n\n    // Subscribe to form submission to set hasSubmitted flag\n    ngForm.ngSubmit\n      .pipe(\n        tap(() => {\n          this.hasSubmitted.set(true);\n        }),\n        takeUntilDestroyed(this.destroyRef)\n      )\n      .subscribe();\n  }\n\n  validate(control: AbstractControl): Observable<ValidationErrors | null> {\n    // Skip validation if suite or formValue not set\n    if (!this.suite() || !this.formValue()) {\n      return of(null);\n    }\n\n    // Check both validateRootForm and ngxValidateRootForm inputs\n    const isEnabled = this.validateRootForm() || this.ngxValidateRootForm();\n    if (!isEnabled) {\n      return of(null);\n    }\n\n    // Mode precedence: ngx-prefixed input wins over legacy input; both default\n    // to `undefined` so the precedence rule is implementable without losing\n    // the legacy attribute when the new one is not set.\n    const mode =\n      this.ngxValidateRootFormMode() ??\n      this.validateRootFormMode() ??\n      'submit';\n\n    // In 'submit' mode, skip validation until form is submitted\n    if (mode === 'submit' && !this.hasSubmitted()) {\n      return of(null);\n    }\n\n    // Call the validator and return its Observable\n    // Angular expects this to complete after emitting once\n    const validationResult = this.createAsyncValidator(\n      ROOT_FORM,\n      this.validationOptions()\n    )(control) as Observable<ValidationErrors | null>;\n\n    return validationResult;\n  }\n\n  createAsyncValidator(\n    field: typeof ROOT_FORM,\n    validationOptions: ValidationOptions\n  ): AsyncValidatorFn {\n    if (!this.suite()) {\n      return () => of(null);\n    }\n\n    // Note: AsyncValidatorFn requires (control: AbstractControl) signature,\n    // but root form validation uses formValue input (typed model) instead of control.value.\n    // This is intentional - cross-field validation operates on the complete form model,\n    // not individual control values. The underscore prefix indicates intentional non-use.\n\n    return (_control: AbstractControl) => {\n      const currentFormValue = this.formValue();\n      if (!currentFormValue) {\n        return of(null);\n      }\n      // Use the formValue input which contains the actual model data\n      const mod = structuredClone(currentFormValue) as T;\n\n      const debounce = validationOptions.debounceTime ?? 0;\n      const source$ =\n        debounce > 0 ? timer(debounce).pipe(map(() => mod)) : of(mod);\n\n      return source$.pipe(\n        switchMap((model) => {\n          return new Observable((observer) => {\n            try {\n              const suite = this.suite();\n              if (!suite) {\n                observer.next(null);\n                observer.complete();\n                return;\n              }\n              // NOTE: `suite` can be a union of typed and untyped suite functions.\n              // When calling a union of functions, TypeScript requires arguments\n              // to satisfy all call signatures, which can produce overly-strict\n              // errors in template type-checking. At runtime this is always the\n              // ROOT_FORM field ('rootForm'), which is valid for both variants.\n              const runSuite = suite as unknown as (\n                model: T,\n                field?: unknown\n              ) => {\n                done: (\n                  cb: (result: {\n                    getErrors: () => Record<string, string[]>;\n                  }) => void\n                ) => void;\n              };\n\n              runSuite(model, field).done((result) => {\n                const errors = result.getErrors()[field];\n                // Return { errors: string[] } format expected by getAllFormErrors()\n                observer.next(errors ? { errors } : null);\n                observer.complete();\n              });\n            } catch (err) {\n              console.error(\n                '[validate-root-form] Validation suite error:',\n                err\n              );\n              observer.next(null);\n              observer.complete();\n            }\n          }) as Observable<ValidationErrors | null>;\n        }),\n        catchError((err) => {\n          console.error('[validate-root-form] Observable error:', err);\n          return of(null);\n        }),\n        take(1),\n        takeUntilDestroyed(this.destroyRef)\n      );\n    };\n  }\n}\n","import { Optional, Provider } from '@angular/core';\nimport {\n  ControlContainer,\n  FormsModule,\n  NgForm,\n  NgModelGroup,\n} from '@angular/forms';\nimport { ControlWrapperComponent } from './components/control-wrapper/control-wrapper.component';\nimport { FormGroupWrapperComponent } from './components/form-group-wrapper/form-group-wrapper.component';\nimport { FormControlStateDirective } from './directives/form-control-state.directive';\nimport { FormErrorControlDirective } from './directives/form-error-control.directive';\nimport { FormErrorDisplayDirective } from './directives/form-error-display.directive';\nimport { FormModelGroupDirective } from './directives/form-model-group.directive';\nimport { FormModelDirective } from './directives/form-model.directive';\nimport { FormDirective } from './directives/form.directive';\nimport { ValidateRootFormDirective } from './directives/validate-root-form.directive';\n\n/**\n * This is borrowed from  [https://github.com/wardbell/ngc-validate/blob/main/src/app/core/form-container-view-provider.ts](https://github.com/wardbell/ngc-validate/blob/main/src/app/core/form-container-view-provider.ts)\n * Thank you so much Ward Bell for your effort!:\n *\n * Provide a ControlContainer to a form component from the\n * nearest parent NgModelGroup (preferred) or NgForm.\n *\n * Required for Reactive Forms as well (unless you write CVA)\n *\n * @example\n * ```\n *   @Component({\n *     ...\n *    viewProviders[ formViewProvider ]\n *   })\n * ```\n * @see Kara's AngularConnect 2017 talk: https://youtu.be/CD_t3m2WMM8?t=1826\n *\n * Without this provider\n * - Controls are not registered with parent NgForm or NgModelGroup\n * - Form-level flags say \"untouched\" and \"valid\"\n * - No form-level validation roll-up\n * - Controls still validate, update model, and update their statuses\n * - If within NgForm, no compiler error because ControlContainer is optional for ngModel\n *\n * Note: if the SubForm Component that uses this Provider\n * is not within a Form or NgModelGroup, the provider returns `null`\n * resulting in an error, something like\n * ```\n * preview-fef3604083950c709c52b.js:1 ERROR Error:\n *  ngModelGroup cannot be used with a parent formGroup directive.\n *```\n */\nconst formViewProvider: Provider = {\n  provide: ControlContainer,\n  useFactory: _formViewProviderFactory,\n  deps: [\n    [new Optional(), NgForm],\n    [new Optional(), NgModelGroup],\n  ],\n};\n\nfunction _formViewProviderFactory(ngForm: NgForm, ngModelGroup: NgModelGroup) {\n  return ngModelGroup || ngForm || null;\n}\n\n/**\n * The providers we need in every child component that holds an ngModelGroup\n */\nexport const vestFormsViewProviders = [\n  { provide: ControlContainer, useExisting: NgForm },\n  formViewProvider, // very important if we want nested components with ngModelGroup\n];\n\n/**\n * Collection of directives, components, and modules required for ngx-vest-forms.\n *\n * This array exports all the necessary components and directives to enable\n * Vest validation integration with Angular template-driven forms.\n *\n * @example\n * ```typescript\n * import { NgxVestForms } from 'ngx-vest-forms';\n *\n * @Component({\n *\n *   imports: [NgxVestForms],\n *   /// ...\n * })\n * export class MyComponent { }\n * ```\n */\nexport const NgxVestForms = [\n  ValidateRootFormDirective,\n  ControlWrapperComponent,\n  FormGroupWrapperComponent,\n  FormControlStateDirective,\n  FormErrorDisplayDirective,\n  FormErrorControlDirective,\n  FormDirective,\n  FormsModule,\n  FormModelDirective,\n  FormModelGroupDirective,\n] as const;\n\n/**\n * @deprecated Use `NgxVestForms` instead\n */\nexport const vestForms = NgxVestForms;\n","/**\n * Primitive types that should not be traversed for nested paths\n */\ntype Primitive = string | number | boolean | Date | null | undefined;\n\n/**\n * Helper type to extract the element type from an array.\n * Used internally for type inference with array paths.\n *\n * @template T - The array type to extract from\n * @example\n * ```typescript\n * type Element = ArrayElement<string[]>; // Result: string\n * type Element2 = ArrayElement<NotArray>; // Result: never\n * ```\n */\n\n/**\n * Recursively generates all valid field paths for a type as string literals.\n * This provides full IDE autocomplete and compile-time validation for field names.\n *\n * **Key Features:**\n * - Supports nested objects with dot notation (e.g., 'user.address.city')\n * - Works with optional properties from DeepPartial types\n * - Handles arrays and readonly arrays\n * - Stops recursion at primitive types\n * - Maximum depth of 10 levels to prevent infinite recursion\n *\n * **Type Safety Benefits:**\n * - IDE autocomplete for all valid field paths\n * - Compile-time errors for typos in field names\n * - Refactoring support (rename property → all usages update)\n * - Self-documenting code through type inference\n *\n * @template T - The model type to extract field paths from\n * @template Prefix - Internal recursion prefix (do not use directly)\n * @template Depth - Internal depth counter to prevent infinite recursion\n *\n * @example\n * ```typescript\n * type Model = {\n *   name: string;\n *   profile: {\n *     age: number;\n *     address: {\n *       city: string;\n *     }\n *   }\n * };\n *\n * type Paths = FieldPath<Model>;\n * /// Result: 'name' | 'profile' | 'profile.age' | 'profile.address' | 'profile.address.city'\n * ```\n *\n * @example With DeepPartial\n * ```typescript\n * type FormModel = DeepPartial<{\n *   user: {\n *     email: string;\n *     phone: string;\n *   }\n * }>;\n *\n * type Paths = FieldPath<FormModel>;\n * /// Result: 'user' | 'user.email' | 'user.phone'\n * ```\n */\nexport type FieldPath<\n  T,\n  Prefix extends string = '',\n  Depth extends readonly number[] = [],\n> = Depth['length'] extends 10\n  ? never // Max depth reached, prevent infinite recursion\n  : T extends Primitive\n    ? never // Don't traverse primitives\n    : T extends ReadonlyArray<infer U>\n      ? // For arrays, generate paths for the element type\n        FieldPath<U, Prefix, [...Depth, 1]>\n      : {\n          [K in keyof T & string]: T[K] extends Primitive\n            ? // Primitive property: just the field name\n              `${Prefix}${K}`\n            : T[K] extends ReadonlyArray<infer U>\n              ? // Array property: field name plus element paths\n                  | `${Prefix}${K}`\n                  | (U extends Primitive\n                      ? never\n                      : FieldPath<U, `${Prefix}${K}.`, [...Depth, 1]>)\n              : // Object property: field name plus nested paths\n                  | `${Prefix}${K}`\n                  | FieldPath<T[K], `${Prefix}${K}.`, [...Depth, 1]>;\n        }[keyof T & string];\n\n/**\n * Type-safe validation configuration map.\n * Maps trigger field paths to arrays of dependent field paths that should be revalidated.\n *\n * **Use Case:**\n * Define which fields should trigger validation of other fields when they change.\n * For example, when password changes, confirmPassword should be revalidated.\n *\n * **Type Safety:**\n * - All keys must be valid field paths from the model\n * - All dependent field paths must be valid\n * - IDE autocomplete works for both keys and values\n * - Compile-time errors for invalid field references\n *\n * @template T - The form model type\n *\n * @example\n * ```typescript\n * type FormModel = DeepPartial<{\n *   password: string;\n *   confirmPassword: string;\n *   addresses: {\n *     billing: { city: string; }\n *   }\n * }>;\n *\n * /// ✅ Type-safe configuration with autocomplete\n * const config: ValidationConfigMap<FormModel> = {\n *   password: ['confirmPassword'],\n *   'addresses.billing.city': ['password'],\n * };\n *\n * /// ❌ TypeScript error - invalid field name\n * const badConfig: ValidationConfigMap<FormModel> = {\n *   passwordd: ['confirmPassword'], // Typo caught at compile time\n * };\n * ```\n */\nexport type ValidationConfigMap<T> = Partial<\n  Record<FieldPath<T>, Array<FieldPath<T>>>\n>;\n\n/**\n * Type-safe field name for use in Vest test() calls and form APIs.\n * Combines valid field paths with the special ROOT_FORM constant.\n *\n * **Use Case:**\n * When defining Vest test() calls, use this type for the field parameter\n * to get autocomplete and type safety.\n *\n * **Special Values:**\n * - Any valid FieldPath from the model\n * - ROOT_FORM constant for form-level validations\n *\n * @template T - The form model type\n *\n * @example\n * ```typescript\n * import { ROOT_FORM } from 'ngx-vest-forms';\n *\n * type FormModel = DeepPartial<{\n *   email: string;\n *   user: { name: string; }\n * }>;\n *\n * export const suite = staticSuite(\n *   (data: FormModel, field?: FormFieldName<FormModel>) => {\n *     only(field);\n *\n *     /// ✅ Autocomplete works\n *     test('email', 'Required', () => {\n *       enforce(data.email).isNotBlank();\n *     });\n *\n *     test('user.name', 'Required', () => {\n *       enforce(data.user?.name).isNotBlank();\n *     });\n *\n *     /// Form-level validation\n *     test(ROOT_FORM, 'At least one contact method', () => {\n *       enforce(data.email || data.user?.name).isTruthy();\n *     });\n *   }\n * );\n * ```\n */\nexport type FormFieldName<T> = FieldPath<T> | typeof ROOT_FORM;\n\n// Re-export ROOT_FORM for convenience\nimport { ROOT_FORM } from '../constants';\nexport { ROOT_FORM };\n\n/**\n * Helper type to infer the value type at a given field path.\n * Useful for creating type-safe utilities that work with field paths.\n *\n * @template T - The model type\n * @template Path - The field path string\n *\n * @example\n * ```typescript\n * type Model = {\n *   user: {\n *     profile: {\n *       age: number;\n *     }\n *   }\n * };\n *\n * type AgeType = FieldPathValue<Model, 'user.profile.age'>;\n * /// Result: number\n * ```\n */\nexport type FieldPathValue<T, Path extends string> = Path extends keyof T\n  ? T[Path]\n  : Path extends `${infer K}.${infer Rest}`\n    ? K extends keyof T\n      ? FieldPathValue<NonNullable<T[K]>, Rest>\n      : never\n    : never;\n\n/**\n * Utility type to check if a path is valid for a given model.\n * Returns the path if valid, never otherwise.\n *\n * @template T - The model type\n * @template Path - The path to validate\n *\n * @example\n * ```typescript\n * type Model = { name: string; age: number; };\n *\n * type Valid = ValidateFieldPath<Model, 'name'>; // 'name'\n * type Invalid = ValidateFieldPath<Model, 'invalid'>; // never\n * ```\n */\nexport type ValidateFieldPath<T, Path extends string> =\n  Path extends FieldPath<T> ? Path : never;\n\n/**\n * Extract all leaf field paths (paths that point to primitive values).\n * Useful when you only want paths to actual values, not intermediate objects.\n *\n * @template T - The model type\n *\n * @example\n * ```typescript\n * type Model = {\n *   user: {\n *     name: string;\n *     profile: {\n *       age: number;\n *     }\n *   }\n * };\n *\n * type Leaves = LeafFieldPath<Model>;\n * /// Result: 'user.name' | 'user.profile.age'\n * /// Note: 'user' and 'user.profile' are excluded (not leaves)\n * ```\n */\nexport type LeafFieldPath<\n  T,\n  Prefix extends string = '',\n  Depth extends readonly number[] = [],\n> = Depth['length'] extends 10\n  ? never\n  : T extends Primitive\n    ? never\n    : T extends ReadonlyArray<infer U>\n      ? LeafFieldPath<U, Prefix, [...Depth, 1]>\n      : {\n          [K in keyof T & string]: T[K] extends Primitive\n            ? `${Prefix}${K}`\n            : T[K] extends ReadonlyArray<infer U>\n              ? U extends Primitive\n                ? never\n                : LeafFieldPath<U, `${Prefix}${K}.`, [...Depth, 1]>\n              : LeafFieldPath<T[K], `${Prefix}${K}.`, [...Depth, 1]>;\n        }[keyof T & string];\n","/**\n * Represents the state of a form managed by scVestForm directive.\n * This is the structure returned by NgxVestFormDirective.formState() or similar.\n */\nexport type NgxFormState<TModel = unknown> = {\n  /** Whether the form is valid */\n  valid: boolean;\n  /** Map of field errors by field path */\n  errors: Record<string, string[]>;\n  /** Current form value (includes disabled fields) */\n  value: TModel | null;\n};\n\n/**\n * Creates an empty NgxFormState with default values.\n *\n * This utility is helpful when you need to provide a fallback for components\n * that require a non-null NgxFormState, such as when child components\n * might not be initialized yet.\n *\n * @template TModel The type of the form model/value\n * @returns A complete NgxFormState object with empty/default values\n *\n * @example\n * ```typescript\n * /// In a parent component that displays child form state\n * protected readonly formState = computed(() =>\n *   this.childForm()?.formState() ?? createEmptyFormState()\n * );\n * ```\n *\n * @example\n * ```typescript\n * /// With specific typing\n * interface MyFormModel {\n *   name: string;\n *   email: string;\n * }\n *\n * const emptyState = createEmptyFormState<MyFormModel>();\n * ```\n */\nexport function createEmptyFormState<TModel = unknown>(): NgxFormState<TModel> {\n  return {\n    value: null,\n    errors: {},\n    valid: true,\n  };\n}\n","import type { FieldPath, ValidationConfigMap } from './field-path-types';\n\n// NOTE: `typeof ngDevMode !== 'undefined' && ngDevMode` is kept inline\n// (not extracted to a helper) because Angular's build optimizer relies on\n// this exact pattern for tree-shaking dev-only code from production bundles.\nconst LOG_PREFIX = '[ngx-vest-forms] ValidationConfigBuilder';\n\n/**\n * Fluent builder for creating type-safe validation configurations.\n *\n * Provides convenience methods for common validation dependency patterns:\n * - **`whenChanged()`**: One-way dependencies (when A changes, revalidate B)\n * - **`bidirectional()`**: Two-way dependencies (A ↔ B revalidate each other)\n * - **`group()`**: All fields in group revalidate each other\n * - **`merge()`**: Combine with existing configurations\n *\n * @template T - The form model type\n *\n * @example Basic usage\n * ```typescript\n * const config = createValidationConfig<MyFormModel>()\n *   .whenChanged('password', 'confirmPassword')\n *   .bidirectional('startDate', 'endDate')\n *   .build();\n * ```\n *\n * @example Complex scenario\n * ```typescript\n * const config = createValidationConfig<OrderFormModel>()\n *   .group(['firstName', 'lastName', 'email'])\n *   .whenChanged('country', ['state', 'zipCode'])\n *   .bidirectional('minPrice', 'maxPrice')\n *   .merge(existingConfig)\n *   .build();\n * ```\n */\nexport class ValidationConfigBuilder<T> {\n  private config: Partial<Record<string, string[]>> = {};\n\n  /**\n   * Add a one-way dependency: when `trigger` changes, revalidate `dependents`.\n   *\n   * This method is cumulative - calling it multiple times with the same trigger\n   * will merge all dependents together.\n   *\n   * **When to Use:**\n   * - ✅ Conditional field requirements (country → state/zipCode)\n   * - ✅ Calculated fields (quantity/price → total)\n   * - ✅ Dependent validations where only one direction matters\n   * - ✅ Cascading validations (A changes → B needs revalidation → C needs revalidation)\n   *\n   * **Real-World Use Case:**\n   * In an e-commerce checkout form, when the user selects a country, the available\n   * states/provinces and zip code format validation rules change. The country field\n   * needs to trigger revalidation of state and zipCode, but changes to state/zipCode\n   * don't need to revalidate country (one-way dependency).\n   *\n   * **Vest.js Patterns That Work Well:**\n   * - `skipWhen(res => res.hasErrors('trigger'), () => { test('dependent', ...) })` -\n   *   Skip expensive validations on dependent field until trigger field is valid\n   * - Async validations on dependent fields that need the trigger's value\n   * - Calculated field validations (e.g., total depends on quantity × price)\n   * - Conditional `omitWhen` based on trigger field state\n   *\n   * @param trigger - The field that triggers revalidation\n   * @param revalidate - Single field or array of fields to revalidate\n   * @returns This builder instance for method chaining\n   *\n   * @example Single dependent\n   * ```typescript\n   * builder.whenChanged('password', 'confirmPassword');\n   * /// Result: { password: ['confirmPassword'] }\n   * ```\n   *\n   * @example Multiple dependents\n   * ```typescript\n   * builder.whenChanged('country', ['state', 'zipCode', 'postalCode']);\n   * /// Result: { country: ['state', 'zipCode', 'postalCode'] }\n   * ```\n   *\n   * @example Cumulative calls\n   * ```typescript\n   * builder\n   *   .whenChanged('password', 'confirmPassword')\n   *   .whenChanged('password', 'securityScore');\n   * /// Result: { password: ['confirmPassword', 'securityScore'] }\n   * ```\n   */\n  whenChanged<K extends FieldPath<T>>(\n    trigger: K,\n    revalidate: FieldPath<T> | ReadonlyArray<FieldPath<T>>\n  ): this {\n    const deps = Array.isArray(revalidate) ? revalidate : [revalidate];\n    const existing = (this.config[trigger] || []) as Array<FieldPath<T>>;\n\n    // Development mode warning for duplicate dependents\n    if (typeof ngDevMode !== 'undefined' && ngDevMode) {\n      const duplicates = deps.filter((d) => existing.includes(d));\n      if (duplicates.length > 0) {\n        console.warn(\n          `${LOG_PREFIX}: Duplicate dependencies detected.\\n` +\n            `  Trigger: '${trigger}'\\n` +\n            `  Duplicates: ${duplicates.map((d) => `'${d}'`).join(', ')}\\n` +\n            `  These will be automatically deduplicated.`\n        );\n      }\n    }\n\n    // Deduplicate dependents\n    const merged = [...existing, ...deps];\n    this.config[trigger] = Array.from(new Set(merged));\n\n    return this;\n  }\n\n  /**\n   * Add bidirectional dependency: when either field changes, revalidate the other.\n   *\n   * This is a convenience method that calls `whenChanged()` in both directions.\n   * Commonly used for password/confirmPassword, min/max ranges, start/end dates.\n   *\n   * **When to Use:**\n   * - ✅ Password confirmation (password ↔ confirmPassword)\n   * - ✅ Min/max range validation (minPrice ↔ maxPrice, minAge ↔ maxAge)\n   * - ✅ Start/end date validation (startDate ↔ endDate)\n   * - ✅ Any field comparison where both fields need mutual revalidation\n   *\n   * **Real-World Use Case:**\n   * In a job posting form, when setting salary range, changing either minSalary or\n   * maxSalary should revalidate the other to ensure minSalary ≤ maxSalary. Users\n   * can change either field first, so both directions need validation. This prevents\n   * invalid ranges like \"$80k min, $50k max\".\n   *\n   * **Vest.js Patterns That Work Well:**\n   * - Comparison validations: `enforce(data.min).lessThanOrEquals(data.max)`\n   * - Password matching: `enforce(data.password).equals(data.confirmPassword)`\n   * - Date range validation with `enforce(data.startDate).lessThan(data.endDate)`\n   * - `skipWhen` to prevent comparison when either field has errors:\n   *   ```typescript\n   *   skipWhen(res => res.hasErrors('field1') || res.hasErrors('field2'), () => {\n   *     test('field1', 'Min must be ≤ Max', () => enforce(min).lessThanOrEquals(max));\n   *   });\n   *   ```\n   *\n   * @param field1 - First field in the bidirectional relationship\n   * @param field2 - Second field in the bidirectional relationship\n   * @returns This builder instance for method chaining\n   *\n   * @example Password confirmation\n   * ```typescript\n   * builder.bidirectional('password', 'confirmPassword');\n   * /// Result: {\n   * ///   password: ['confirmPassword'],\n   * ///   confirmPassword: ['password']\n   * /// }\n   * ```\n   *\n   * @example Date range\n   * ```typescript\n   * builder.bidirectional('startDate', 'endDate');\n   * /// Result: {\n   * ///   startDate: ['endDate'],\n   * ///   endDate: ['startDate']\n   * /// }\n   * ```\n   */\n  bidirectional<K1 extends FieldPath<T>, K2 extends FieldPath<T>>(\n    field1: K1,\n    field2: K2\n  ): this {\n    // Development mode warning for exact duplicate\n    if (typeof ngDevMode !== 'undefined' && ngDevMode) {\n      const hasField1ToField2 =\n        this.config[field1]?.includes(field2 as string) ?? false;\n      const hasField2ToField1 =\n        this.config[field2]?.includes(field1 as string) ?? false;\n\n      if (hasField1ToField2 && hasField2ToField1) {\n        console.warn(\n          `${LOG_PREFIX}: Duplicate bidirectional relationship detected.\\n` +\n            `  Fields: '${field1}' ↔ '${field2}'\\n` +\n            `  This bidirectional relationship was already configured.`\n        );\n      }\n    }\n\n    this.whenChanged(field1, field2);\n    this.whenChanged(field2, field1);\n    return this;\n  }\n\n  /**\n   * Create a validation group where all fields revalidate each other.\n   *\n   * When any field in the group changes, all other fields in the group are revalidated.\n   * This is useful for fields that collectively form a validation rule.\n   *\n   * **When to Use:**\n   * - ✅ \"At least one required\" scenarios (email OR phone OR address)\n   * - ✅ Interdependent field sets (credit card: number + expiry + CVV)\n   * - ✅ Contact information (firstName + lastName + email)\n   * - ✅ Fields that collectively satisfy a business rule\n   *\n   * **Real-World Use Case:**\n   * In a customer registration form with a \"at least one contact method required\"\n   * business rule, the validation suite checks `email || phone || mailingAddress`.\n   * When user fills any of these fields, the other fields need revalidation to clear\n   * the \"at least one required\" error. All three fields are interdependent, so\n   * grouping them ensures validation updates correctly regardless of which field\n   * the user fills first.\n   *\n   * **Vest.js Patterns That Work Well:**\n   * - \"At least one required\" logic:\n   *   ```typescript\n   *   test('email', 'Provide at least one contact method', () => {\n   *     enforce(data.email || data.phone || data.address).isTruthy();\n   *   });\n   *   ```\n   * - Interdependent field validation where all fields collectively satisfy a rule\n   * - Credit card validation (number + expiry + CVV all need each other)\n   * - Use `optional()` for groups where fields can all be empty together:\n   *   ```typescript\n   *   optional(['email', 'phone', 'address']);\n   *   ```\n   *\n   * **Performance Note:** This creates N×(N-1) dependencies, which can impact\n   * performance for large groups. Consider using `whenChanged()` for more targeted\n   * dependencies if performance is a concern (e.g., groups > 10 fields).\n   *\n   * @param fields - Array of fields that should all revalidate each other\n   * @returns This builder instance for method chaining\n   *\n   * @example Contact information group\n   * ```typescript\n   * builder.group(['firstName', 'lastName', 'email']);\n   * /// Result: {\n   * ///   firstName: ['lastName', 'email'],\n   * ///   lastName: ['firstName', 'email'],\n   * ///   email: ['firstName', 'lastName']\n   * /// }\n   * ```\n   *\n   * @example Address validation group\n   * ```typescript\n   * builder.group(['street', 'city', 'state', 'zipCode']);\n   * ```\n   */\n  group<K extends FieldPath<T>>(fields: readonly K[]): this {\n    // Each field triggers validation of all other fields in the group\n    for (const field of fields) {\n      const others = fields.filter((f) => f !== field);\n      this.whenChanged(field, others);\n    }\n    return this;\n  }\n\n  /**\n   * Merge with an existing validation configuration.\n   *\n   * This method is useful for:\n   * - Combining base configurations with conditional configurations\n   * - Composing configurations from multiple sources\n   * - Adding dynamic configurations based on runtime conditions\n   *\n   * **When to Use:**\n   * - ✅ Conditional features (international shipping adds customs fields)\n   * - ✅ Reusable configuration modules (address config, payment config)\n   * - ✅ Dynamic forms where validation rules change at runtime\n   * - ✅ Feature flags or A/B testing variations\n   *\n   * **Real-World Use Case:**\n   * In an e-commerce checkout, your form has base validation (shipping address,\n   * payment info). When user selects international shipping, you need additional\n   * validations (customs declaration, tax ID). Instead of duplicating the base\n   * config, use `merge()` to conditionally add the international validation rules.\n   * This keeps your code DRY and makes it easy to toggle features on/off.\n   *\n   * **Vest.js Patterns That Work Well:**\n   * - Conditional features with `omitWhen`:\n   *   ```typescript\n   *   omitWhen(!isInternational, () => {\n   *     test('customsForm', 'Customs declaration required', () => {\n   *       enforce(data.customsForm).isNotBlank();\n   *     });\n   *   });\n   *   ```\n   * - Reusable validation modules that can be composed\n   * - Feature flags: merge different configs based on enabled features\n   * - A/B testing: conditionally merge test-specific validation rules\n   * - Use with computed signals for reactive configuration:\n   *   ```typescript\n   *   const config = computed(() =>\n   *     createValidationConfig<T>()\n   *       .merge(baseConfig)\n   *       .merge(featureEnabled() ? featureConfig : {})\n   *       .build()\n   *   );\n   *   ```\n   *\n   * **Note:** Dependencies are merged and deduplicated. If both configs have\n   * the same trigger field, dependents are combined into a single array.\n   *\n   * @param other - Existing ValidationConfigMap to merge\n   * @returns This builder instance for method chaining\n   *\n   * @example Conditional configuration\n   * ```typescript\n   * const baseConfig = createValidationConfig<FormModel>()\n   *   .bidirectional('password', 'confirmPassword')\n   *   .build();\n   *\n   * const config = createValidationConfig<FormModel>()\n   *   .merge(baseConfig)\n   *   .merge(\n   *     isInternational\n   *       ? { country: ['customsForm'] }\n   *       : {}\n   *   )\n   *   .build();\n   * ```\n   *\n   * @example Composition\n   * ```typescript\n   * const addressConfig = { 'street': ['city', 'zipCode'] };\n   * const contactConfig = { 'email': ['phone'] };\n   *\n   * const config = createValidationConfig<FormModel>()\n   *   .merge(addressConfig)\n   *   .merge(contactConfig)\n   *   .build();\n   * ```\n   */\n  merge(other: ValidationConfigMap<T>): this {\n    for (const [key, deps] of Object.entries(other)) {\n      if (deps && Array.isArray(deps)) {\n        const existing = this.config[key] || [];\n        const merged = [...existing, ...deps];\n        this.config[key] = Array.from(new Set(merged));\n      }\n    }\n    return this;\n  }\n\n  /**\n   * Build the final validation configuration object.\n   *\n   * Returns a deep copy of the configuration to prevent accidental mutations.\n   * The returned object can be used with the `validationConfig` input of `scVestForm`.\n   *\n   * @returns Immutable ValidationConfigMap ready for use\n   *\n   * @example\n   * ```typescript\n   * protected readonly validationConfig = createValidationConfig<MyFormModel>()\n   *   .bidirectional('password', 'confirmPassword')\n   *   .whenChanged('country', 'state')\n   *   .build();\n   * ```\n   */\n  build(): ValidationConfigMap<T> {\n    // Return a deep copy to prevent external mutations affecting the builder\n    const copy: Partial<Record<string, string[]>> = {};\n    for (const [key, deps] of Object.entries(this.config)) {\n      if (deps && Array.isArray(deps)) {\n        copy[key] = [...deps];\n      }\n    }\n    return copy as ValidationConfigMap<T>;\n  }\n}\n\n/**\n * Factory function to create a type-safe validation configuration builder.\n *\n * This is the recommended entry point for creating validation configurations.\n * It provides full type safety and IDE autocomplete for field names.\n *\n * @template T - The form model type\n * @returns A new ValidationConfigBuilder instance\n *\n * @example Basic usage\n * ```typescript\n * protected readonly validationConfig = createValidationConfig<FormModel>()\n *   .bidirectional('password', 'confirmPassword')\n *   .whenChanged('country', 'state')\n *   .build();\n * ```\n *\n * @example With DeepPartial form model\n * ```typescript\n * type FormModel = DeepPartial<{\n *   user: {\n *     profile: {\n *       email: string;\n *       phone: string;\n *     }\n *   }\n * }>;\n *\n * const config = createValidationConfig<FormModel>()\n *   .bidirectional('user.profile.email', 'user.profile.phone')\n *   .build();\n * ```\n *\n * @example Complex scenario with all methods\n * ```typescript\n * const config = createValidationConfig<OrderFormModel>()\n *   .group(['firstName', 'lastName', 'email'])\n *   .bidirectional('startDate', 'endDate')\n *   .bidirectional('minPrice', 'maxPrice')\n *   .whenChanged('orderType', ['deliveryDate', 'priority'])\n *   .whenChanged('country', ['state', 'zipCode'])\n *   .merge(conditionalConfig)\n *   .build();\n * ```\n */\nexport function createValidationConfig<T>(): ValidationConfigBuilder<T> {\n  return new ValidationConfigBuilder<T>();\n}\n","/**\n * Converts a flat array to an object with numeric keys.\n * Does not recurse into nested arrays or objects.\n * Uses reduce() for optimal single-pass conversion.\n */\nexport type DeepArrayToObject<T> =\n  T extends ReadonlyArray<infer U>\n    ? Record<number, DeepArrayToObject<U>>\n    : T extends object\n      ? { [K in keyof T]: DeepArrayToObject<T[K]> }\n      : T;\n\nexport function arrayToObject<T>(array: readonly T[]): Record<number, T> {\n  return array.reduce(\n    (acc, value, index) => {\n      acc[index] = value;\n      return acc;\n    },\n    {} as Record<number, T>\n  );\n}\n\n/**\n * Recursively converts arrays to objects with numeric keys, including nested arrays in objects.\n * Useful for template-driven forms that require object structure for nested arrays.\n */\nexport function deepArrayToObject<T>(\n  array: readonly T[]\n): Record<number, DeepArrayToObject<T>> {\n  return Object.fromEntries(\n    array.map((value, index) => [\n      index,\n      Array.isArray(value)\n        ? deepArrayToObject(value as unknown[])\n        : value && typeof value === 'object'\n          ? recursivelyConvertArrays(value)\n          : value,\n    ])\n  ) as Record<number, DeepArrayToObject<T>>;\n}\n\n/**\n * Recursively traverses an object and converts any nested arrays to objects.\n */\nfunction recursivelyConvertArrays<T>(object: T): DeepArrayToObject<T> {\n  if (Array.isArray(object)) {\n    return deepArrayToObject(object as unknown[]) as DeepArrayToObject<T>;\n  }\n  if (object && typeof object === 'object') {\n    return Object.fromEntries(\n      Object.entries(object).map(([key, value]) => [\n        key,\n        Array.isArray(value)\n          ? deepArrayToObject(value as unknown[])\n          : value && typeof value === 'object'\n            ? recursivelyConvertArrays(value)\n            : value,\n      ])\n    ) as DeepArrayToObject<T>;\n  }\n  return object as DeepArrayToObject<T>;\n}\n\n/**\n * Converts selected numeric-keyed object properties back to arrays.\n * Only properties listed in keys will be converted; others remain untouched.\n * Useful for converting form models back to array format before saving/sending to backend.\n */\n\n/**\n * Public API: Convert selected numeric-keyed object properties back to arrays.\n * Note: Conversion is explicit (by key) but will cascade inside converted branches\n * so nested numeric objects representing arrays become real arrays recursively.\n */\nexport function objectToArray<const K extends readonly string[]>(\n  object: unknown,\n  keys: K\n): unknown {\n  const processed = objectToArrayInternal(object, keys);\n  if (processed && typeof processed === 'object' && !Array.isArray(processed)) {\n    const entries: Array<[string, unknown]> = Object.entries(\n      processed as Record<string, unknown>\n    );\n    if (entries.length === 1) {\n      const firstEntry = entries[0];\n      if (!firstEntry) {\n        return processed;\n      }\n      const [k, v] = firstEntry;\n      if (\n        keys.includes(k) &&\n        Array.isArray(v) &&\n        (v as unknown[]).every(\n          (element) => typeof element === 'object' && element !== null\n        )\n      ) {\n        return v;\n      }\n    }\n  }\n  return processed;\n}\n\n/**\n * Internal recursive worker with cascade flag: once a targeted key is converted, all nested numeric objects become arrays even if their keys were not explicitly listed.\n */\nfunction objectToArrayInternal(\n  object: unknown,\n  keys: readonly string[],\n  currentKey?: string,\n  parentCascade = false\n): unknown {\n  if (Array.isArray(object)) {\n    // Recursively process each item in the array\n    return object.map((item) =>\n      objectToArrayInternal(item, keys, undefined, parentCascade)\n    );\n  }\n\n  if (object && typeof object === 'object') {\n    if (isNumericObject(object)) {\n      // First, recursively process the contents\n      const processedContents: Record<string, unknown> = {};\n      let hasChanges = false;\n\n      const explicit = !!currentKey && keys.includes(currentKey);\n      const childCascade = parentCascade || explicit;\n\n      for (const [key, value] of Object.entries(object)) {\n        const processedValue = objectToArrayInternal(\n          value,\n          keys,\n          key,\n          childCascade\n        );\n        processedContents[key] = processedValue;\n        if (processedValue !== value) {\n          hasChanges = true;\n        }\n      }\n\n      // Decision: should we convert this numeric object to an array?\n      // Yes, if: explicitly targeted, parent was converted, or children changed.\n      const shouldConvert = explicit || parentCascade || hasChanges;\n\n      return shouldConvert\n        ? Object.keys(processedContents)\n            .sort((a, b) => Number(a) - Number(b))\n            .map((k) => processedContents[k])\n        : processedContents;\n    }\n\n    // For regular objects, process recursively\n    const result: Record<string, unknown> = {};\n    for (const [key, value] of Object.entries(object)) {\n      result[key] = objectToArrayInternal(value, keys, key, parentCascade);\n    }\n    return result;\n  }\n\n  return object;\n}\n\n/**\n * Checks if a value is an object with only numeric keys (not an array).\n */\nfunction isNumericObject(value: unknown): value is Record<string, unknown> {\n  if (!value || typeof value !== 'object' || Array.isArray(value)) return false;\n  return Object.keys(value).every((k) => /^\\d+$/.test(k));\n}\n","/**\n * Utility functions for managing form field state in dynamic forms.\n * These functions help maintain component state consistency when form structure changes.\n */\n\n/**\n * Conditionally clears fields from form state based on provided conditions.\n *\n * **CRITICAL: When This Utility is Required**\n * This utility is specifically needed when conditional logic switches between:\n * - **Form inputs** (e.g., `<input>`, `<select>`, `<textarea>`)\n * - **NON-form elements** (e.g., `<p>`, `<div>`, informational content)\n *\n * **Primary Use Case - Form Input ↔ Non-Form Content:**\n * ```typescript\n * @if (mode === 'input') {\n *   <input name=\"field\" [ngModel]=\"value\" />  // Form input\n * } @else {\n *   <p>No input required</p>                  // NON-form element\n * }\n * ```\n *\n * **Why This Creates a Problem:**\n * 1. Switching FROM input TO non-form content: Angular removes FormControl, but component signal retains old value\n * 2. This creates state inconsistency between `ngForm.form.value` (clean) and `formValue()` (stale)\n * 3. Manual clearing synchronizes component state with actual form structure\n *\n * **When NOT Required:**\n * Pure form-to-form conditionals usually don't need manual clearing:\n * ```typescript\n * @if (type === 'text') {\n *   <input name=\"field\" [ngModel]=\"value\" type=\"text\" />\n * } @else {\n *   <input name=\"field\" [ngModel]=\"value\" type=\"number\" />  // Still a form input\n * }\n * ```\n *\n * **Performance Note:**\n * Uses `Object.entries()` for efficient field clearing without mutation.\n * Only processes fields that need to be cleared, preserving other field values.\n *\n * @template T - The form model type, must extend Record<string, unknown>\n * @param currentState - The current form state object\n * @param conditions - Object mapping field names to boolean conditions (true = clear field)\n * @returns New state object with specified fields cleared (set to undefined)\n *\n * @example\n * ```typescript\n * ///  REQUIRED: Form input switching to non-form content\n * onProcedureTypeChange(newValue: string) {\n *   this.formValue.update((current) =>\n *     clearFieldsWhen(current, {\n *       fieldA: newValue !== 'typeA',  // Clear when switching to non-form content\n *       fieldB: newValue !== 'typeB',  // Clear when switching to non-form content\n *     })\n *   );\n * }\n *\n * ///  Template structure that REQUIRES clearing:\n * ///  @if (type === 'typeA') { <input name=\"fieldA\" /> }\n * ///  @else if (type === 'typeB') { <input name=\"fieldB\" /> }\n * ///  @else { <p>No input needed</p> }  // ← NON-form element!\n * ```\n *\n * @example\n * ```typescript\n * ///  Complex conditional clearing with mixed form/non-form scenarios\n * const cleanedState = clearFieldsWhen(form, {\n *   shippingAddress: !form.useShippingAddress,    // Clear when not using shipping\n *   emergencyContact: (form.age || 0) >= 18,      // Clear when adult (no emergency contact form)\n *   childInfo: form.userType !== 'parent',        // Clear when not parent (shows info text instead)\n * });\n * ```\n *\n * @example\n * ```typescript\n * ///  State inconsistency example - WHY manual clearing is needed:\n *\n * ///  BEFORE switching from input to non-form content (typeA → typeC):\n * formValue() = { procedureType: 'typeA', fieldA: 'user-input' }\n * ngForm.form.value = { procedureType: 'typeA', fieldA: 'user-input' }\n *\n * ///  AFTER switching WITHOUT clearing (PROBLEMATIC):\n * formValue() = { procedureType: 'typeC', fieldA: 'user-input' }  // ❌ Stale fieldA!\n * ngForm.form.value = { procedureType: 'typeC' }                  // ✅ Clean (Angular removed FormControl)\n *\n * ///  AFTER switching WITH clearing (CONSISTENT):\n * formValue() = { procedureType: 'typeC' }  // ✅ Clean component state\n * ngForm.form.value = { procedureType: 'typeC' }  // ✅ Clean form state\n * ```\n *\n */\nexport function clearFieldsWhen<T extends Record<string, unknown>>(\n  currentState: T,\n  conditions: Readonly<Partial<Record<keyof T, boolean>>>\n): T {\n  const result: Record<string, unknown> = { ...currentState };\n\n  for (const fieldName of Object.keys(conditions) as Array<keyof T>) {\n    const shouldClear = conditions[fieldName];\n    if (shouldClear) {\n      result[fieldName as string] = undefined;\n    }\n  }\n\n  return result as T;\n}\n\n/**\n * Clears multiple fields from form state unconditionally.\n *\n * **Use Cases:**\n * - Form reset operations when switching between form modes\n * - Clearing temporary/wizard data when exiting multi-step forms\n * - Cleanup after form submission or cancellation\n * - When you want explicit control over which fields to clear\n *\n * **Note:** Unlike `clearFieldsWhen`, this function always clears the specified fields\n * regardless of conditions. Use this when you want unconditional field removal.\n *\n * @template T - The form model type, must extend Record<string, unknown>\n * @param currentState - The current form state object\n * @param fieldsToClear - Array of field names to clear (set to undefined)\n * @returns New state object with specified fields cleared\n *\n * @example\n * ```typescript\n * ///  Clear specific fields during form mode transitions\n * const cleanedState = clearFields(currentFormValue, ['fieldA', 'fieldB']);\n *\n * ///  Reset wizard or temporary data\n * onFormModeChange() {\n *   this.formValue.update((current) =>\n *     clearFields(current, ['temporaryData', 'wizardStep', 'draftSaved'])\n *   );\n * }\n *\n * ///  Clear all optional fields on form submission\n * save() {\n *   const finalData = clearFields(this.formValue(), ['draftField', 'tempNotes']);\n *   this.submitForm(finalData);\n * }\n * ```\n */\nexport function clearFields<T extends Record<string, unknown>>(\n  currentState: T,\n  fieldsToClear: ReadonlyArray<keyof T>\n): T {\n  const result: Record<string, unknown> = { ...currentState };\n\n  for (const fieldName of fieldsToClear) {\n    result[fieldName as string] = undefined;\n  }\n\n  return result as T;\n}\n\n/**\n * Creates a clean form state containing only fields that meet specified conditions.\n *\n * **Philosophy:** Instead of clearing unwanted fields (like `clearFieldsWhen`), this function\n * takes a \"whitelist\" approach - building a new state with only the fields you explicitly want to keep.\n *\n * **Best Use Cases:**\n * - Complex form transformations where you want to be explicit about kept fields\n * - Building clean data objects for API submission (exclude UI-only fields)\n * - Form mode switching where different modes have completely different field sets\n * - Data export scenarios where only certain fields should be included\n *\n * **Returns:** `Partial<T>` because the result may not contain all original fields.\n *\n * @template T - The form model type, must extend Record<string, unknown>\n * @param currentState - The current form state object\n * @param conditions - Object mapping field names to boolean conditions (true = keep field)\n * @returns New state object containing only fields where condition is true\n *\n * @example\n * ```typescript\n * ///  Keep only relevant fields based on form mode\n * const filteredState = keepFieldsWhen(currentFormValue, {\n *   procedureType: true, // always keep\n *   fieldA: procedureType === 'typeA',\n *   fieldB: procedureType === 'typeB',\n *   // Note: fieldC is omitted when procedureType === 'typeC' (non-form content)\n * });\n *\n * ///  Build clean data for API submission (exclude UI-only fields)\n * const apiData = keepFieldsWhen(formValue(), {\n *   // Business data - keep these\n *   userName: true,\n *   email: true,\n *   preferences: true,\n *   // UI state fields omitted: wizardStep, draftSaved, validationErrors, etc.\n * });\n *\n * ///  Dynamic form sections based on user permissions\n * const relevantData = keepFieldsWhen(form, {\n *   basicInfo: true,\n *   addressInfo: form.needsAddress && userCanEditAddress,\n *   paymentInfo: form.requiresPayment && userCanMakePayments,\n *   adminFields: userIsAdmin,\n * });\n * ```\n *\n * @since 1.0.0\n */\nexport function keepFieldsWhen<T extends Record<string, unknown>>(\n  currentState: T,\n  conditions: Readonly<Partial<Record<keyof T, boolean>>>\n): Partial<T> {\n  const result: Record<string, unknown> = {};\n\n  for (const fieldName of Object.keys(conditions) as Array<keyof T>) {\n    const shouldKeep = conditions[fieldName];\n    if (shouldKeep && Object.hasOwn(currentState, fieldName)) {\n      result[fieldName as string] = currentState[fieldName];\n    }\n  }\n\n  return result as Partial<T>;\n}\n","/*\n * Public API Surface of ngx-vest-forms\n */\n\nexport { NgxVestForms, vestForms, vestFormsViewProviders } from './lib/exports';\n\n// Type utilities\nexport type { DeepPartial, NgxDeepPartial } from './lib/utils/deep-partial';\nexport type {\n  DeepRequired,\n  FormCompatibleDeepRequired,\n  NgxDeepRequired,\n  NgxFormCompatibleDeepRequired,\n} from './lib/utils/deep-required';\n/** @deprecated Use ROOT_FORM from 'ngx-vest-forms' instead */\nexport { ROOT_FORM as ROOT_FORM_CONSTANT } from './lib/utils/field-path-types';\nexport type {\n  FieldPath,\n  FieldPathValue,\n  FormFieldName,\n  LeafFieldPath,\n  ValidateFieldPath,\n  ValidationConfigMap,\n} from './lib/utils/field-path-types';\nexport { createEmptyFormState } from './lib/utils/form-state.utils';\nexport type { NgxFormState } from './lib/utils/form-state.utils';\nexport {\n  ValidationConfigBuilder,\n  createValidationConfig,\n} from './lib/utils/validation-config-builder';\nexport type {\n  NgxFieldKey,\n  NgxTypedVestSuite,\n  NgxVestSuite,\n} from './lib/utils/validation-suite';\n\n// Form utilities\nexport {\n  arrayToObject,\n  deepArrayToObject,\n  objectToArray,\n} from './lib/utils/array-to-object';\nexport {\n  clearFields,\n  clearFieldsWhen,\n  keepFieldsWhen,\n} from './lib/utils/field-clearing';\nexport { stringifyFieldPath } from './lib/utils/field-path.utils';\nexport { setValueAtPath } from './lib/utils/form-utils';\nexport { createDebouncedPendingState } from './lib/utils/pending-state.utils';\nexport type {\n  DebouncedPendingStateOptions,\n  DebouncedPendingStateOptionsInput,\n  DebouncedPendingStateResult,\n} from './lib/utils/pending-state.utils';\nexport { validateShape } from './lib/utils/shape-validation';\n\n// ARIA association utilities\nexport {\n  mergeAriaDescribedBy,\n  parseAriaIdTokens,\n  resolveAssociationTargets,\n} from './lib/utils/aria-association.utils';\nexport type { AriaAssociationMode } from './lib/utils/aria-association.utils';\n\n// Internal utilities - exported for advanced use cases but not part of the primary API\n// These are marked with @internal in their source files and may change without notice\n/** @internal */ export {\n  fastDeepEqual,\n  shallowEqual,\n} from './lib/utils/equality';\n/** @internal */ export { parseFieldPath } from './lib/utils/field-path.utils';\n/** @internal */ export {\n  getAllFormErrors,\n  getFormControlField,\n  getFormGroupField,\n  mergeValuesAndRawValues,\n} from './lib/utils/form-utils';\n\n// Deprecated - kept for backward compatibility, will be removed in future major version\n/** @deprecated Use setValueAtPath instead */ export {\n  cloneDeep,\n  set,\n} from './lib/utils/form-utils';\n\n// Constants\nexport { ROOT_FORM } from './lib/constants';\n\n// Tokens\nexport {\n  NGX_ERROR_DISPLAY_MODE_TOKEN,\n  NGX_WARNING_DISPLAY_MODE_TOKEN,\n  SC_ERROR_DISPLAY_MODE_TOKEN,\n} from './lib/directives/error-display-mode.token';\nexport { NGX_VALIDATION_CONFIG_DEBOUNCE_TOKEN } from './lib/tokens/debounce.token';\nexport { NGX_EQUALITY_FN } from './lib/tokens/equality.token';\nexport type { NgxEqualityFn } from './lib/tokens/equality.token';\n\n// Components\nexport { ControlWrapperComponent } from './lib/components/control-wrapper/control-wrapper.component';\nexport { FormGroupWrapperComponent } from './lib/components/form-group-wrapper/form-group-wrapper.component';\n\n// Directives\nexport { FormControlStateDirective } from './lib/directives/form-control-state.directive';\nexport { FormErrorControlDirective } from './lib/directives/form-error-control.directive';\nexport { FormErrorDisplayDirective } from './lib/directives/form-error-display.directive';\nexport type {\n  NgxWarningDisplayMode,\n  ScErrorDisplayMode,\n} from './lib/directives/form-error-display.directive';\nexport { FormModelGroupDirective } from './lib/directives/form-model-group.directive';\nexport { FormModelDirective } from './lib/directives/form-model.directive';\nexport { FormDirective } from './lib/directives/form.directive';\nexport type {\n  NgxFieldBlurEvent,\n  NgxValidationConfig,\n} from './lib/directives/form.directive';\nexport { ValidateRootFormDirective } from './lib/directives/validate-root-form.directive';\nexport type { ValidationOptions } from './lib/directives/validation-options';\nexport {\n  DEFAULT_FOCUS_SELECTOR,\n  DEFAULT_INVALID_SELECTOR,\n} from './lib/utils/first-invalid.utils';\nexport type { NgxFirstInvalidOptions } from './lib/utils/first-invalid.utils';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["isPrimitive","LOG_PREFIX","rxMerge","i1.FormControlStateDirective","nextUniqueId","i1.FormErrorDisplayDirective"],"mappings":"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"}