{"version":3,"file":"gnss-state.mjs","sources":["../../../projects/gnss-state/src/models/state.model.ts","../../../projects/gnss-state/src/lib/bp.state.ts","../../../projects/gnss-state/src/lib/data.state.ts","../../../projects/gnss-state/src/lib/event.state.ts","../../../projects/gnss-state/src/lib/rules.state.ts","../../../projects/gnss-state/src/lib/server.state.ts","../../../projects/gnss-state/src/lib/settings.state.ts","../../../projects/gnss-state/src/lib/ui.state.ts","../../../projects/gnss-state/src/public-api.ts","../../../projects/gnss-state/src/gnss-state.ts"],"sourcesContent":["// Angular Imports\r\nimport { Injectable } from '@angular/core';\r\n// RxJs Imports\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\n// Types\r\nimport { StateObjType } from '../types/state-obj.type';\r\n\r\n/**\r\n * A comprehensive reactive state management service for Angular applications that provides\r\n * centralized state storage, hierarchical organization, and robust backup/rollback functionality.\r\n *\r\n * This service implements a sophisticated state management pattern using RxJS BehaviorSubjects\r\n * to enable reactive data flow throughout Angular applications. It supports both flat and\r\n * hierarchical state organization through groups, automatic backup creation for rollback\r\n * operations, and deep merging capabilities for complex state updates.\r\n *\r\n * ## Key Features\r\n *\r\n * - **Reactive State Management**: Built on RxJS BehaviorSubjects for reactive data flow\r\n * - **Hierarchical Organization**: Support for grouped state subjects with nested structures\r\n * - **Backup & Rollback**: Automatic backup creation with reset functionality for undo operations\r\n * - **Deep Merging**: Intelligent object merging for partial state updates\r\n * - **Type Safety**: Full TypeScript support with type guards and strict typing\r\n * - **Memory Management**: Proper cleanup and resource management to prevent memory leaks\r\n * - **Change Detection**: Optimized updates with deep equality checks to prevent unnecessary emissions\r\n *\r\n * ## Usage Patterns\r\n *\r\n * ### Basic State Operations\r\n * ```typescript\r\n * // Inject the service\r\n * constructor(private stateModel: StateModel) {}\r\n *\r\n * // Set initial state\r\n * this.stateModel.set('userProfile', { id: 1, name: 'John', email: 'john@example.com' });\r\n *\r\n * // Subscribe to state changes\r\n * this.stateModel.observe('userProfile').subscribe(profile => {\r\n *   console.log('Profile updated:', profile);\r\n * });\r\n *\r\n * // Update existing state\r\n * this.stateModel.update('userProfile', { name: 'Jane Doe' });\r\n *\r\n * // Reset to backup value\r\n * this.stateModel.reset('userProfile');\r\n * ```\r\n *\r\n * ### Grouped State Management\r\n * ```typescript\r\n * // Create and populate a group\r\n * const users = [\r\n *   { id: 'user1', name: 'John', role: 'admin' },\r\n *   { id: 'user2', name: 'Jane', role: 'user' }\r\n * ];\r\n * this.stateModel.loadGroup('users', 'id', users);\r\n *\r\n * // Access grouped subjects\r\n * this.stateModel.observe('user1', 'users').subscribe(user => {\r\n *   console.log('User updated:', user);\r\n * });\r\n *\r\n * // Update grouped state\r\n * this.stateModel.set('currentUser', { id: 3, name: 'Bob' }, 'users');\r\n * ```\r\n *\r\n * ### Form Integration with Backup/Reset\r\n * ```typescript\r\n * // Initialize form state\r\n * this.stateModel.set('formData', this.form.value);\r\n *\r\n * // Track form changes\r\n * this.form.valueChanges.subscribe(value => {\r\n *   this.stateModel.update('formData', value);\r\n * });\r\n *\r\n * // Reset form to initial state\r\n * onResetClick() {\r\n *   this.stateModel.reset('formData');\r\n *   this.form.patchValue(this.stateModel.value('formData'));\r\n * }\r\n * ```\r\n *\r\n * ## Architecture\r\n *\r\n * The service maintains several core registries:\r\n * - **Main Directory**: Flat registry of named BehaviorSubjects\r\n * - **Groups**: Hierarchical registry for organized state subjects\r\n * - **Backups**: Rollback data for main directory subjects\r\n * - **Group Backups**: Rollback data for grouped subjects\r\n * - **Change Tracking**: Reactive notifications for state modifications\r\n *\r\n * ## Performance Optimizations\r\n *\r\n * - Deep equality checks prevent unnecessary BehaviorSubject emissions\r\n * - Automatic cleanup prevents memory leaks\r\n * - Smart merging preserves existing state properties\r\n * - Lazy initialization of subjects and groups\r\n *\r\n * @example\r\n * ## Complete Example: User Management with Groups\r\n * ```typescript\r\n * @Component({...})\r\n * export class UserManagementComponent implements OnInit {\r\n *   constructor(private stateModel: StateModel) {}\r\n *\r\n *   ngOnInit() {\r\n *     // Initialize user management state\r\n *     this.loadUsers();\r\n *     this.setupSubscriptions();\r\n *   }\r\n *\r\n *   private loadUsers() {\r\n *     const users = [\r\n *       { id: 'user1', name: 'John Doe', email: 'john@example.com', active: true },\r\n *       { id: 'user2', name: 'Jane Smith', email: 'jane@example.com', active: false }\r\n *     ];\r\n *\r\n *     // Create grouped state for users\r\n *     this.stateModel.loadGroup('users', 'id', users);\r\n *\r\n *     // Set selected user\r\n *     this.stateModel.set('selectedUser', users[0], 'users');\r\n *   }\r\n *\r\n *   private setupSubscriptions() {\r\n *     // React to selected user changes\r\n *     this.stateModel.observe('selectedUser', 'users').subscribe(user => {\r\n *       if (user) {\r\n *         this.loadUserDetails(user);\r\n *       }\r\n *     });\r\n *\r\n *     // Monitor all group changes\r\n *     this.stateModel.groupList.subscribe(groups => {\r\n *       console.log('Available groups:', groups);\r\n *     });\r\n *   }\r\n *\r\n *   updateUser(userId: string, updates: Partial<User>) {\r\n *     // Merge partial updates with existing user data\r\n *     this.stateModel.dirMerge(updates, userId, 'users');\r\n *   }\r\n *\r\n *   resetUserChanges(userId: string) {\r\n *     // Reset user to backup state\r\n *     this.stateModel.reset(userId, 'users');\r\n *   }\r\n * }\r\n * ```\r\n *\r\n * @see {@link StateObjType} - Type definition for state values\r\n * @see {@link BehaviorSubject} - RxJS reactive primitive used for state storage\r\n *\r\n * @public\r\n * @injectable\r\n * @since 1.0.0\r\n */\r\n@Injectable({\r\n  providedIn: 'root',\r\n})\r\nexport class StateModel {\r\n  // -------------------- SUBSCRIPTIONS -------------------- //\r\n\r\n  // -------------------- SUBSCRIBER_ATTRIBUTES -------------------- //\r\n\r\n  // -------------------- SUBSCRIBER_OBJECT_REFERENCES -------------------- //\r\n\r\n  // -------------------- ATTRIBUTES -------------------- //\r\n\r\n  // -------------------- OBJECTS -------------------- //\r\n  /**\r\n   * Registry of backup values for state subjects to enable rollback functionality.\r\n   *\r\n   * Stores the original values of state subjects when they are created or modified through the\r\n   * {@link StateModel.set} method. These backup values remain immutable during subsequent\r\n   * {@link StateModel.update} operations and can be restored using {@link StateModel.reset}.\r\n   * This mechanism supports undo/reset patterns commonly used in form controls and dialog\r\n   * components.\r\n   *\r\n   * @remarks\r\n   * The backup system follows these rules:\r\n   * - Backups are created/updated only by the `set()` method\r\n   * - The `update()` method does not modify backup values\r\n   * - The `reset()` method restores values from this backup registry\r\n   * - Backups are stored as deep clones to prevent reference mutations\r\n   *\r\n   * @example\r\n   * Basic backup and reset workflow:\r\n   * ```typescript\r\n   * // Setting creates backup automatically\r\n   * stateModel.set('userForm', { name: 'John', email: 'john@example.com' });\r\n   *\r\n   * // Backup contains original value\r\n   * console.log(stateModel.backups['userForm']);\r\n   * // Output: { name: 'John', email: 'john@example.com' }\r\n   *\r\n   * // Updates don't affect backup\r\n   * stateModel.update('userForm', { name: 'Jane', email: 'jane@example.com' });\r\n   *\r\n   * // Backup remains unchanged\r\n   * console.log(stateModel.backups['userForm']);\r\n   * // Output: { name: 'John', email: 'john@example.com' }\r\n   *\r\n   * // Reset restores from backup\r\n   * stateModel.reset('userForm');\r\n   * // Current value: { name: 'John', email: 'john@example.com' }\r\n   * ```\r\n   *\r\n   * @see {@link StateModel.set} - Creates and updates backup values\r\n   * @see {@link StateModel.update} - Modifies state without affecting backups\r\n   * @see {@link StateModel.reset} - Restores state from backup values\r\n   * @see {@link StateModel.groupBackups} - Backup registry for grouped subjects\r\n   *\r\n   * @since 1.0.0\r\n   */\r\n  public backups: Record<string, StateObjType> = {};\r\n  /**\r\n   * A registry of reactive state subjects that can be observed by any component\r\n   * throughout the application. This registry uses a key-value mapping pattern\r\n   * where each key represents a unique state identifier and each value is a\r\n   * BehaviorSubject containing the state data.\r\n   *\r\n   * This design pattern provides centralized state management with reactive\r\n   * capabilities, allowing components to subscribe to specific state changes\r\n   * without tight coupling to state producers.\r\n   *\r\n   * @example\r\n   * ```typescript\r\n   * // Subscribe to a specific state\r\n   * this.stateModel.dir['userProfile'].subscribe(profile => {\r\n   *   console.log('User profile updated:', profile);\r\n   * });\r\n   *\r\n   * // Access current value\r\n   * const currentUser = this.stateModel.dir['userProfile'].value;\r\n   * ```\r\n   *\r\n   * @see {@link StateModel.observe} For safe access to subjects with automatic creation\r\n   * @see {@link StateModel.set} For creating and updating state subjects\r\n   * @see {@link StateModel.update} For modifying existing state subjects\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public dir: Record<string, BehaviorSubject<StateObjType>> = {};\r\n  /**\r\n   * A reactive registry of all group names currently managed by the state system.\r\n   *\r\n   * This BehaviorSubject maintains an array of string identifiers representing\r\n   * all group names that exist in the {@link StateModel.groups} registry. It provides\r\n   * a reactive way to track when new groups are created or existing groups are removed,\r\n   * enabling components to respond to structural changes in the grouped state architecture.\r\n   *\r\n   * The group list is automatically maintained by the state management system:\r\n   * - Group names are added when {@link StateModel.loadGroup} creates new groups\r\n   * - Group names are removed when {@link StateModel.removeGroup} deletes groups\r\n   * - The list is kept in sync with the actual {@link StateModel.groups} registry\r\n   *\r\n   * @example\r\n   * Subscribe to group registry changes:\r\n   * ```typescript\r\n   * this.stateModel.groupList.subscribe(groupNames => {\r\n   *   console.log('Available groups:', groupNames);\r\n   *   // Output: ['users', 'settings', 'navigation']\r\n   * });\r\n   * ```\r\n   *\r\n   * @example\r\n   * Check if a specific group exists:\r\n   * ```typescript\r\n   * const hasUsersGroup = this.stateModel.groupList.value.includes('users');\r\n   * ```\r\n   *\r\n   * @see {@link StateModel.groups} - The actual group registry this list tracks\r\n   * @see {@link StateModel.loadGroup} - Method that adds group names to this list\r\n   * @see {@link StateModel.removeGroup} - Method that removes group names from this list\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public groupList = new BehaviorSubject<string[]>([]);\r\n  /**\r\n   * Hierarchical registry of backup values for grouped state subjects to enable rollback functionality.\r\n   *\r\n   * This two-tier backup system maintains original values for state subjects organized within groups,\r\n   * complementing the main {@link StateModel.backups} registry for ungrouped subjects. Each group\r\n   * maintains its own backup registry, where backup values remain immutable during subsequent\r\n   * {@link StateModel.update} operations and can be restored using {@link StateModel.reset}.\r\n   *\r\n   * The structure follows a group-name → subject-name → backup-value hierarchy, allowing for\r\n   * fine-grained backup management within the grouped state architecture. This supports complex\r\n   * UI patterns where different feature areas require independent rollback capabilities.\r\n   *\r\n   * @remarks\r\n   * The hierarchical backup system follows these rules:\r\n   * - Group backups are created/updated only by the `set()` method when a group name is specified\r\n   * - The `update()` method does not modify backup values in any group\r\n   * - The `reset()` method can restore individual subjects within specific groups\r\n   * - Group removal via `removeGroup()` clears all backup data for that group\r\n   * - Backups are stored as deep clones to prevent reference mutations\r\n   *\r\n   * @example\r\n   * Grouped backup and reset workflow:\r\n   * ```typescript\r\n   * // Setting with group creates backup automatically\r\n   * stateModel.set('currentUser', { id: 1, name: 'John' }, 'users');\r\n   * stateModel.set('permissions', ['read', 'write'], 'users');\r\n   *\r\n   * // Group backup structure:\r\n   * // {\r\n   * //   'users': {\r\n   * //     'currentUser': { id: 1, name: 'John' },\r\n   * //     'permissions': ['read', 'write']\r\n   * //   }\r\n   * // }\r\n   *\r\n   * // Updates don't affect group backups\r\n   * stateModel.update('currentUser', { id: 1, name: 'Jane' }, 'users');\r\n   *\r\n   * // Group backup remains unchanged\r\n   * console.log(stateModel.groupBackups['users']['currentUser']);\r\n   * // Output: { id: 1, name: 'John' }\r\n   *\r\n   * // Reset specific subject within group\r\n   * stateModel.reset('currentUser', 'users');\r\n   * // Current value restored: { id: 1, name: 'John' }\r\n   * ```\r\n   *\r\n   * @see {@link StateModel.backups} - Main backup registry for ungrouped subjects\r\n   * @see {@link StateModel.groups} - The grouped subjects this backup system supports\r\n   * @see {@link StateModel.set} - Creates and updates group backup values\r\n   * @see {@link StateModel.reset} - Restores state from group backup values\r\n   * @see {@link StateModel.removeGroup} - Clears all backups for a specific group\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public groupBackups: Record<string, Record<string, StateObjType>> = {};\r\n  /**\r\n   * A Directory of grouped BehaviorSubjects where each group is itself a BehaviorSubject\r\n   * containing a Record of named BehaviorSubjects. This nested structure allows for\r\n   * reactive group management where the entire group can be observed for changes,\r\n   * and individual subjects within each group can also be observed independently.\r\n   *\r\n   * The outer Record maps group names to BehaviorSubjects, where each BehaviorSubject\r\n   * contains a Record mapping subject names to their respective BehaviorSubjects.\r\n   * This enables hierarchical state management with both group-level and item-level\r\n   * reactivity.\r\n   *\r\n   * @example\r\n   * ```typescript\r\n   * // Access a specific subject within a group\r\n   * const userSubject = this.groups['users'].value['john'];\r\n   *\r\n   * // Subscribe to changes in the entire group\r\n   * this.groups['users'].subscribe(groupRecord => {\r\n   *   console.log('Group changed:', Object.keys(groupRecord));\r\n   * });\r\n   *\r\n   * // Subscribe to changes in a specific subject within the group\r\n   * this.groups['users'].value['john'].subscribe(userData => {\r\n   *   console.log('User data changed:', userData);\r\n   * });\r\n   * ```\r\n   */\r\n  public groups: Record<\r\n    string,\r\n    BehaviorSubject<Record<string, BehaviorSubject<StateObjType>>>\r\n  > = {};\r\n  /**\r\n   * A reactive tracker that emits the name of the most recently updated state subject.\r\n   *\r\n   * This BehaviorSubject provides a centralized way to monitor state change activity\r\n   * across the entire state management system. It emits the subject name whenever\r\n   * any state modification occurs through the {@link StateModel.set}, {@link StateModel.update},\r\n   * or {@link StateModel.initiate} methods, enabling reactive side effects and UI updates\r\n   * based on specific state changes.\r\n   *\r\n   * The tracker operates across both individual subjects in {@link StateModel.dir}\r\n   * and grouped subjects in {@link StateModel.groups}, providing unified change\r\n   * detection regardless of state organization.\r\n   *\r\n   * @example\r\n   * Monitor all state changes:\r\n   * ```typescript\r\n   * this.stateModel.updated.subscribe(subjectName => {\r\n   *   if (subjectName) {\r\n   *     console.log(`State subject '${subjectName}' was updated`);\r\n   *     // Trigger side effects, analytics, or UI updates\r\n   *   }\r\n   * });\r\n   * ```\r\n   *\r\n   * @example\r\n   * React to specific subject changes:\r\n   * ```typescript\r\n   * this.stateModel.updated.pipe(\r\n   *   filter(name => name === 'userProfile'),\r\n   *   switchMap(() => this.stateModel.observe('userProfile'))\r\n   * ).subscribe(profile => {\r\n   *   // Handle user profile changes\r\n   * });\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - Emits `undefined` on initialization\r\n   * - Always emits the subject name, not the group name for grouped subjects\r\n   * - Useful for implementing global state change listeners and audit trails\r\n   * - Can be used to invalidate caches or trigger data synchronization\r\n   *\r\n   * @see {@link StateModel.set} - Method that triggers updates when setting state\r\n   * @see {@link StateModel.update} - Method that triggers updates when modifying state\r\n   * @see {@link StateModel.initiate} - Method that triggers updates when initializing state\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public updated: BehaviorSubject<string | undefined> = new BehaviorSubject<\r\n    string | undefined\r\n  >(undefined);\r\n\r\n  // -------------------- CONSTRUCTOR -------------------- //\r\n\r\n  // -------------------- LIFE_CYCLE_HOOKS -------------------- //\r\n\r\n  // -------------------- INITIATOR_LOADER_METHODS -------------------- //\r\n\r\n  // -------------------- PRIVATE_METHODS -------------------- //\r\n  /**\r\n   * Type guard that determines whether a value is a plain object suitable for deep merging operations.\r\n   *\r\n   * This utility method implements a type-safe check to identify plain objects created by object\r\n   * literals or the Object constructor, distinguishing them from arrays, dates, class instances,\r\n   * and other specialized object types. It uses the reliable `Object.prototype.toString.call()`\r\n   * approach to ensure accurate type detection across different JavaScript contexts and\r\n   * inheritance chains.\r\n   *\r\n   * Plain objects are defined as objects with `[object Object]` as their internal [[Class]] slot,\r\n   * which includes:\r\n   * - Object literals: `{ key: 'value' }`\r\n   * - Objects created with `new Object()`\r\n   * - Objects created with `Object.create(Object.prototype)`\r\n   *\r\n   * Non-plain objects that return `false` include:\r\n   * - Arrays: `[1, 2, 3]`\r\n   * - Dates: `new Date()`\r\n   * - RegExp: `/pattern/`\r\n   * - Functions: `() => {}`\r\n   * - Class instances: `new MyClass()`\r\n   * - Built-in objects: `Math`, `JSON`, etc.\r\n   * - Primitives: `null`, `undefined`, strings, numbers, booleans\r\n   *\r\n   * @param val - The value to test for plain object status. Accepts any type including\r\n   *   primitives, objects, arrays, null, or undefined.\r\n   *\r\n   * @returns Type predicate indicating whether the value is a plain object. When `true`,\r\n   *   TypeScript narrows the type to `Record<string, unknown>`, enabling safe property access\r\n   *   and iteration. When `false`, the value is not suitable for deep merging operations.\r\n   *\r\n   * @example\r\n   * Basic plain object detection:\r\n   * ```typescript\r\n   * this.isPlainObject({});                    // true\r\n   * this.isPlainObject({ name: 'John' });      // true\r\n   * this.isPlainObject(new Object());          // true\r\n   * this.isPlainObject([1, 2, 3]);             // false\r\n   * this.isPlainObject(new Date());            // false\r\n   * this.isPlainObject(null);                  // false\r\n   * this.isPlainObject('string');              // false\r\n   * ```\r\n   *\r\n   * @example\r\n   * Usage in merge operations:\r\n   * ```typescript\r\n   * if (this.isPlainObject(sourceObj) && this.isPlainObject(targetObj)) {\r\n   *   // Safe to perform recursive merge\r\n   *   return this.merge(sourceObj, targetObj);\r\n   * } else {\r\n   *   // Replace non-plain objects completely\r\n   *   return sourceObj;\r\n   * }\r\n   * ```\r\n   *\r\n   * @example\r\n   * Type narrowing with type guard:\r\n   * ```typescript\r\n   * function processValue(input: unknown) {\r\n   *   if (this.isPlainObject(input)) {\r\n   *     // TypeScript knows 'input' is Record<string, unknown>\r\n   *     console.log(Object.keys(input)); // No type error\r\n   *     return input.someProperty;        // Safe property access\r\n   *   }\r\n   *   // Handle non-plain objects differently\r\n   *   return input;\r\n   * }\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - Uses `Object.prototype.toString.call()` for reliable cross-frame type detection\r\n   * - Serves as a TypeScript type guard for enhanced type safety in merge operations\r\n   * - Essential for preventing incorrect recursive merging of arrays, dates, and class instances\r\n   * - Performance is O(1) with minimal overhead for type checking\r\n   * - Does not check for object enumerability or property descriptors\r\n   *\r\n   * @see {@link StateModel.merge} - Primary consumer of this type guard for safe object merging\r\n   * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString\r\n   *\r\n   * @internal\r\n   * @since 1.0.0\r\n   */\r\n  private isPlainObject(val: unknown): val is Record<string, unknown> {\r\n    return Object.prototype.toString.call(val) === '[object Object]';\r\n  }\r\n\r\n  // -------------------- PUBLIC_METHODS -------------------- //\r\n  /**\r\n   * Retrieves the current values from all BehaviorSubjects in the state registry.\r\n   *\r\n   * Extracts and returns the current values from all registered state subjects,\r\n   * either from the main {@link StateModel.dir} registry or from a specific group\r\n   * within {@link StateModel.groups}. The returned object uses subject names as keys\r\n   * and their current values as the corresponding values, providing a snapshot\r\n   * of the current state at the time of invocation.\r\n   *\r\n   * Values are deep cloned through the {@link StateModel.value} method to prevent\r\n   * external mutations from affecting the state management system.\r\n   *\r\n   * @param groupName - Optional group name to limit extraction to subjects within\r\n   *   a specific group. When `null` (default), retrieves values from all subjects\r\n   *   in the main directory. When specified, only retrieves values from subjects\r\n   *   within the named group.\r\n   *\r\n   * @returns A record object where keys are subject names and values are the\r\n   *   current state values of the corresponding BehaviorSubjects. Returns an\r\n   *   empty object if no subjects exist or if the specified group doesn't exist.\r\n   *\r\n   * @example\r\n   * Get all values from the main directory:\r\n   * ```typescript\r\n   * const allValues = this.stateModel.getDirValues();\r\n   * // Returns: { userProfile: {...}, settings: {...}, navigation: {...} }\r\n   * ```\r\n   *\r\n   * @example\r\n   * Get values from a specific group:\r\n   * ```typescript\r\n   * const userValues = this.stateModel.getDirValues('users');\r\n   * // Returns: { currentUser: {...}, permissions: [...] }\r\n   * ```\r\n   *\r\n   * @see {@link StateModel.dir} - Main state subject registry\r\n   * @see {@link StateModel.groups} - Grouped state subject registry\r\n   * @see {@link StateModel.value} - Method used internally to extract values\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public getDirValues(\r\n    groupName: string | null = null,\r\n  ): Record<string, StateObjType> {\r\n    const subjectDirectory: Record<string, StateObjType> = {};\r\n    if (!groupName) {\r\n      for (const key in this.dir) {\r\n        subjectDirectory[key] = this.value(key);\r\n      }\r\n    }\r\n    if (groupName && groupName in this.groups) {\r\n      for (const key in this.groups[groupName].value) {\r\n        subjectDirectory[key] = this.value(key, groupName);\r\n      }\r\n    }\r\n    return subjectDirectory;\r\n  }\r\n\r\n  /**\r\n   * Determines whether a BehaviorSubject with the specified name exists in the state registry.\r\n   *\r\n   * This method performs existence checks in either the main {@link StateModel.dir} registry\r\n   * or within a specific group in {@link StateModel.groups}. When a group name is provided,\r\n   * the method first verifies the group exists before checking for the subject within that group.\r\n   * This dual-level checking supports the hierarchical state management architecture.\r\n   *\r\n   * @param subjectName - The name of the BehaviorSubject to check for existence.\r\n   *   This parameter is required and represents the unique identifier for the state subject.\r\n   * @param groupName - Optional group name to limit the search to subjects within\r\n   *   a specific group. When `null` (default), searches in the main directory registry.\r\n   *   When specified, searches only within the named group.\r\n   *\r\n   * @returns `true` if the subject exists in the specified location (main directory\r\n   *   or within the specified group), `false` otherwise. Returns `false` if the\r\n   *   specified group doesn't exist.\r\n   *\r\n   * @example\r\n   * Check for subject in main directory:\r\n   * ```typescript\r\n   * const hasUserProfile = this.stateModel.has('userProfile');\r\n   * // Returns true if 'userProfile' exists in main directory\r\n   * ```\r\n   *\r\n   * @example\r\n   * Check for subject within a specific group:\r\n   * ```typescript\r\n   * const hasCurrentUser = this.stateModel.has('currentUser', 'users');\r\n   * // Returns true if 'currentUser' exists within 'users' group\r\n   * ```\r\n   *\r\n   * @see {@link StateModel.dir} - Main state subject registry\r\n   * @see {@link StateModel.groups} - Grouped state subject registry\r\n   * @see {@link StateModel.observe} - Method for safely accessing subjects with automatic creation\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public has(subjectName: string, groupName: string | null = null): boolean {\r\n    if (!groupName) {\r\n      if (this.dir[subjectName]) {\r\n        return true;\r\n      }\r\n    }\r\n    if (groupName) {\r\n      if (this.groups[groupName] && this.groups[groupName].value[subjectName]) {\r\n        return true;\r\n      }\r\n    }\r\n    return false;\r\n  }\r\n\r\n  /**\r\n   * Initializes or resets a BehaviorSubject to an undefined state within the state management system.\r\n   *\r\n   * This method creates new BehaviorSubjects with an initial value of `undefined`, or resets existing\r\n   * subjects to `undefined` if they currently contain other values. It supports both standalone subjects\r\n   * in the main {@link StateModel.dir} registry and grouped subjects within {@link StateModel.groups}.\r\n   * When working with grouped subjects, the method will automatically create the parent group if it\r\n   * doesn't exist.\r\n   *\r\n   * The initialization process includes:\r\n   * - Creating new BehaviorSubjects with `undefined` as the initial value\r\n   * - Resetting existing subjects to `undefined` (no-op if already `undefined`)\r\n   * - Setting up corresponding backup entries for rollback functionality\r\n   * - Auto-creating group structures when specified\r\n   * - Triggering the {@link StateModel.updated} notification system\r\n   *\r\n   * @param subjectName - The unique identifier for the BehaviorSubject to initialize or reset.\r\n   *   Must be a non-empty string that will serve as the key in the state registry.\r\n   * @param groupName - Optional group name to organize the subject within a hierarchical structure.\r\n   *   When `null` (default), the subject is created in the main directory. When specified, the subject\r\n   *   is created within the named group, and the group itself is created if it doesn't exist.\r\n   *\r\n   * @returns void - This method performs side effects but returns no value.\r\n   *\r\n   * @example\r\n   * Initialize a standalone subject:\r\n   * ```typescript\r\n   * // Creates a new BehaviorSubject with undefined value\r\n   * this.stateModel.initiate('userProfile');\r\n   *\r\n   * // Access the initialized subject\r\n   * this.stateModel.observe('userProfile').subscribe(value => {\r\n   *   console.log(value); // undefined initially\r\n   * });\r\n   * ```\r\n   *\r\n   * @example\r\n   * Initialize a subject within a group:\r\n   * ```typescript\r\n   * // Creates both 'users' group and 'currentUser' subject if they don't exist\r\n   * this.stateModel.initiate('currentUser', 'users');\r\n   *\r\n   * // Reset an existing grouped subject to undefined\r\n   * this.stateModel.set('currentUser', { id: 1, name: 'John' }, 'users');\r\n   * this.stateModel.initiate('currentUser', 'users'); // Resets to undefined\r\n   * ```\r\n   *\r\n   * @example\r\n   * Resetting existing subjects:\r\n   * ```typescript\r\n   * // Subject with existing data\r\n   * this.stateModel.set('settings', { theme: 'dark', lang: 'en' });\r\n   *\r\n   * // Reset to undefined (triggers backup and notification)\r\n   * this.stateModel.initiate('settings');\r\n   *\r\n   * // No-op if already undefined\r\n   * this.stateModel.initiate('settings'); // No change, no notification\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - Early return optimization: If the target subject already has an `undefined` value, the method returns early without triggering notifications\r\n   * - Group auto-creation: When a group name is specified but the group doesn't exist, both the group and backup registry are automatically created\r\n   * - Backup management: All initiated subjects receive corresponding backup entries set to `undefined`\r\n   * - Notification system: The {@link StateModel.updated} BehaviorSubject is notified with the subject name after successful operations\r\n   *\r\n   * @see {@link StateModel.set} - For setting subjects with specific initial values\r\n   * @see {@link StateModel.observe} - For safely accessing and subscribing to subjects\r\n   * @see {@link StateModel.reset} - For restoring subjects from backup values\r\n   * @see {@link StateModel.loadGroup} - For bulk group creation with multiple subjects\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public initiate(subjectName: string, groupName: string | null = null): void {\r\n    if (subjectName) {\r\n      if (!groupName) {\r\n        if (!this.dir[subjectName]) {\r\n          this.dir[subjectName] = new BehaviorSubject<StateObjType>(undefined);\r\n          this.backups[subjectName] = undefined;\r\n        } else {\r\n          const currentValue = this.dir[subjectName].value;\r\n          if (currentValue === undefined) return;\r\n          this.dir[subjectName].next(undefined);\r\n          this.backups[subjectName] = undefined;\r\n        }\r\n      }\r\n      if (groupName) {\r\n        if (!this.groups[groupName]) {\r\n          this.groups[groupName] = new BehaviorSubject<\r\n            Record<string, BehaviorSubject<StateObjType>>\r\n          >({});\r\n          this.groupBackups[groupName] = {};\r\n        }\r\n        if (!this.groups[groupName].value[subjectName]) {\r\n          this.groups[groupName].value[subjectName] =\r\n            new BehaviorSubject<StateObjType>(undefined);\r\n          this.groupBackups[groupName][subjectName] = undefined;\r\n        } else {\r\n          const currentValue = this.groups[groupName].value[subjectName].value;\r\n          if (currentValue === undefined) return;\r\n          this.groups[groupName].value[subjectName].next(undefined);\r\n          this.groupBackups[groupName][subjectName] = undefined;\r\n        }\r\n      }\r\n    }\r\n    this.updated.next(subjectName);\r\n  }\r\n\r\n  /**\r\n   * Performs deep equality comparison between two values to determine if they are structurally identical.\r\n   *\r\n   * This utility method implements recursive deep comparison for complex data structures including\r\n   * objects, arrays, and primitives. It's used throughout the state management system to prevent\r\n   * unnecessary BehaviorSubject emissions when values haven't actually changed, optimizing\r\n   * performance and preventing infinite subscription loops.\r\n   *\r\n   * The comparison follows these rules:\r\n   * - Uses strict equality (`===`) for primitives and identical references\r\n   * - Considers `null` and `undefined` as distinct values (not equal to each other)\r\n   * - Recursively compares array elements in order\r\n   * - Recursively compares object properties by key-value pairs\r\n   * - Returns `false` for mismatched types or structures\r\n   *\r\n   * @param value - The first value to compare. Can be any type including primitives,\r\n   *   objects, arrays, null, or undefined.\r\n   * @param other - The second value to compare against. Can be any type including\r\n   *   primitives, objects, arrays, null, or undefined.\r\n   *\r\n   * @returns `true` if the values are deeply equal, `false` if they differ in structure\r\n   *   or content, or `undefined` if the comparison cannot be determined (currently this\r\n   *   method always returns a boolean).\r\n   *\r\n   * @example\r\n   * Primitive comparisons:\r\n   * ```typescript\r\n   * this.stateModel.isEqual(5, 5);           // true\r\n   * this.stateModel.isEqual('hello', 'hi');  // false\r\n   * this.stateModel.isEqual(null, undefined); // false\r\n   * ```\r\n   *\r\n   * @example\r\n   * Array comparisons:\r\n   * ```typescript\r\n   * this.stateModel.isEqual([1, 2, 3], [1, 2, 3]);     // true\r\n   * this.stateModel.isEqual([1, 2], [1, 2, 3]);        // false\r\n   * this.stateModel.isEqual([[1, 2]], [[1, 2]]);       // true (nested arrays)\r\n   * ```\r\n   *\r\n   * @example\r\n   * Object comparisons:\r\n   * ```typescript\r\n   * const obj1 = { name: 'John', age: 30, hobbies: ['read', 'code'] };\r\n   * const obj2 = { name: 'John', age: 30, hobbies: ['read', 'code'] };\r\n   * const obj3 = { age: 30, name: 'John', hobbies: ['read', 'code'] };\r\n   *\r\n   * this.stateModel.isEqual(obj1, obj2); // true\r\n   * this.stateModel.isEqual(obj1, obj3); // true (key order doesn't matter)\r\n   * ```\r\n   *\r\n   * @example\r\n   * Usage in state management optimization:\r\n   * ```typescript\r\n   * // Prevents unnecessary emissions\r\n   * const currentValue = this.dir['userProfile'].value;\r\n   * if (!this.isEqual(currentValue, newValue)) {\r\n   *   this.dir['userProfile'].next(newValue);\r\n   * }\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - This method is used internally by {@link StateModel.set}, {@link StateModel.update},\r\n   *   and {@link StateModel.reset} to optimize performance\r\n   * - Handles circular references gracefully by comparing object structure\r\n   * - Performance scales with object depth and complexity\r\n   * - Does not compare object prototypes or non-enumerable properties\r\n   *\r\n   * @see {@link StateModel.set} - Uses this method to prevent duplicate state updates\r\n   * @see {@link StateModel.update} - Uses this method for change detection\r\n   * @see {@link StateModel.dirEquals} - Higher-level equality check for directory objects\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public isEqual(value: unknown, other: unknown): boolean | undefined {\r\n    // 1. Apply strict equality check for primitive types and identical references\r\n    if (value === other) return true;\r\n\r\n    // 2. Handle null/undefined cases\r\n    if (\r\n      value === null ||\r\n      other === null ||\r\n      value === undefined ||\r\n      other === undefined\r\n    ) {\r\n      return false;\r\n    }\r\n\r\n    // 3. Handle array comparison\r\n    if (Array.isArray(value) && Array.isArray(other)) {\r\n      if (value.length !== other.length) return false;\r\n      for (let i = 0; i < value.length; i++) {\r\n        if (!this.isEqual(value[i], other[i])) {\r\n          return false;\r\n        }\r\n      }\r\n      return true;\r\n    }\r\n\r\n    // 4. Handle object comparison\r\n    if (typeof value === 'object' && typeof other === 'object') {\r\n      // Gather keys from both objects\r\n      const valueKeys = Object.keys(value as Record<string, unknown>);\r\n      const otherKeys = Object.keys(other as Record<string, unknown>);\r\n\r\n      // Return false if number of keys differ\r\n      if (valueKeys.length !== otherKeys.length) return false;\r\n\r\n      // Check if all keys and values are equal\r\n      for (const key of valueKeys) {\r\n        if (!otherKeys.includes(key)) return false;\r\n        const valueValue = (value as Record<string, unknown>)[key];\r\n        const otherValue = (other as Record<string, unknown>)[key];\r\n        if (!this.isEqual(valueValue, otherValue)) return false;\r\n      }\r\n      return true;\r\n    }\r\n\r\n    // 5. If none of the above conditions match, values are not equal\r\n    return false;\r\n  }\r\n\r\n  /**\r\n   * Creates and initializes a hierarchical group within the state management system.\r\n   *\r\n   * This method establishes a new group in the {@link StateModel.groups} registry as a\r\n   * BehaviorSubject containing a Record of named BehaviorSubjects. The group provides\r\n   * hierarchical state organization where both the group container and individual subjects\r\n   * within it are reactive. Optionally populates the group with BehaviorSubjects created\r\n   * from an array of objects, using a specified property as the subject identifier.\r\n   *\r\n   * The method performs the following operations:\r\n   * - Creates the group BehaviorSubject if it doesn't exist\r\n   * - Optionally creates individual BehaviorSubjects from object array using keyName as identifier\r\n   * - Updates the reactive {@link StateModel.groupList} registry\r\n   * - Maintains referential integrity within the hierarchical state structure\r\n   *\r\n   * @param groupName - The unique identifier for the group to create or initialize.\r\n   *   This name will be used as the key in the {@link StateModel.groups} registry.\r\n   * @param keyName - Optional property name within objects to use as BehaviorSubject\r\n   *   identifiers. When provided with `objArray`, this property's value becomes the\r\n   *   subject name within the group. Must exist as a string or number property in each object.\r\n   * @param objArray - Optional array of objects to transform into BehaviorSubjects within\r\n   *   the group. Each object becomes the initial value of a BehaviorSubject, with the\r\n   *   subject name derived from the object's `keyName` property.\r\n   *\r\n   * @example\r\n   * Create an empty group:\r\n   * ```typescript\r\n   * this.stateModel.loadGroup('users');\r\n   * // Creates: groups['users'] = BehaviorSubject<Record<string, BehaviorSubject<StateObjType>>>({})\r\n   * ```\r\n   *\r\n   * @example\r\n   * Populate group from object array:\r\n   * ```typescript\r\n   * const userData = [\r\n   *   { id: 'user1', name: 'John', role: 'admin' },\r\n   *   { id: 'user2', name: 'Jane', role: 'user' }\r\n   * ];\r\n   * this.stateModel.loadGroup('users', 'id', userData);\r\n   * // Creates subjects: groups['users'].value['user1'], groups['users'].value['user2']\r\n   * ```\r\n   *\r\n   * @see {@link StateModel.groups} - The hierarchical group registry this method modifies\r\n   * @see {@link StateModel.groupList} - Reactive list of all group names, updated by this method\r\n   * @see {@link StateModel.removeGroup} - Method for removing entire groups\r\n   * @see {@link StateModel.observe} - Method for accessing subjects within groups\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public loadGroup(\r\n    groupName: string,\r\n    keyName: string | null = null,\r\n    objArray: unknown[] | null = null,\r\n  ): void {\r\n    if (!this.groups[groupName]) {\r\n      this.groups[groupName] = new BehaviorSubject<\r\n        Record<string, BehaviorSubject<StateObjType>>\r\n      >({});\r\n    }\r\n    if (keyName && objArray && objArray.length > 0) {\r\n      const currentGroupValue = { ...this.groups[groupName].value };\r\n      for (const obj of objArray) {\r\n        // Check if keyName exists in obj and if the value is a string\r\n        if (typeof obj === 'object' && obj !== null && keyName in obj) {\r\n          const castedObj = obj as Record<string, unknown>;\r\n          const objName = castedObj[keyName];\r\n          if (typeof objName === 'string' || typeof objName === 'number') {\r\n            currentGroupValue[objName] = new BehaviorSubject<StateObjType>(\r\n              castedObj,\r\n            );\r\n          }\r\n        }\r\n      }\r\n      this.groups[groupName].next(currentGroupValue);\r\n    }\r\n    if (!this.groupList.value.includes(groupName)) {\r\n      const listValue = JSON.parse(JSON.stringify(this.groupList.value));\r\n      listValue.push(groupName);\r\n      this.groupList.next(listValue);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Performs a deep merge of two objects, combining their properties into a new object.\r\n   *\r\n   * This method recursively merges nested objects while preserving the structure of both input objects.\r\n   * Properties from `newObj` take precedence over properties from `oldObj`. For nested plain objects,\r\n   * the merge operation continues recursively. For primitives, arrays, dates, and other non-plain\r\n   * object types, values from `newObj` completely replace corresponding values from `oldObj`.\r\n   *\r\n   * The merge operation follows these rules:\r\n   * - If `newObj` is not a plain object (null, undefined, array, etc.), returns `oldObj` unchanged\r\n   * - If `oldObj` is null or undefined, treats it as an empty object for merging purposes\r\n   * - Nested plain objects are merged recursively using the same rules\r\n   * - Non-object values (primitives, arrays, dates, etc.) from `newObj` replace values in `oldObj`\r\n   * - Returns a new object without mutating the original input objects\r\n   *\r\n   * @param newObj - The source object whose properties will be merged into the base object.\r\n   *   If not a plain object, the merge operation returns `oldObj` unchanged.\r\n   * @param oldObj - The base object to merge into. Null or undefined values are treated as empty objects.\r\n   *\r\n   * @returns A new merged object containing properties from both inputs, with `newObj` properties\r\n   *   taking precedence. Returns `oldObj` unchanged if `newObj` is not a plain object.\r\n   *\r\n   * @example\r\n   * Basic object merging:\r\n   * ```typescript\r\n   * const base = { name: 'John', age: 30, city: 'New York' };\r\n   * const updates = { age: 31, country: 'USA' };\r\n   * const result = this.stateModel.merge(updates, base);\r\n   * // Result: { name: 'John', age: 31, city: 'New York', country: 'USA' }\r\n   * ```\r\n   *\r\n   * @example\r\n   * Nested object merging:\r\n   * ```typescript\r\n   * const base = { user: { name: 'John', settings: { theme: 'light', lang: 'en' } } };\r\n   * const updates = { user: { settings: { theme: 'dark' } } };\r\n   * const result = this.stateModel.merge(updates, base);\r\n   * // Result: { user: { name: 'John', settings: { theme: 'dark', lang: 'en' } } }\r\n   * ```\r\n   *\r\n   * @example\r\n   * Handling non-plain objects:\r\n   * ```typescript\r\n   * const base = { items: [1, 2, 3], date: new Date('2023-01-01') };\r\n   * const updates = { items: [4, 5], date: new Date('2024-01-01') };\r\n   * const result = this.stateModel.merge(updates, base);\r\n   * // Arrays and dates are replaced, not merged\r\n   * // Result: { items: [4, 5], date: new Date('2024-01-01') }\r\n   * ```\r\n   *\r\n   * @example\r\n   * State update pattern:\r\n   * ```typescript\r\n   * // Merge partial user profile updates\r\n   * const currentProfile = this.stateModel.value('userProfile');\r\n   * const profileUpdates = { preferences: { notifications: false } };\r\n   * const mergedProfile = this.stateModel.merge(profileUpdates, currentProfile);\r\n   * this.stateModel.set('userProfile', mergedProfile);\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - Uses {@link StateModel.isPlainObject} to determine if objects can be merged recursively\r\n   * - Preserves prototype chains and does not modify input objects\r\n   * - Performance scales with object depth and number of properties\r\n   * - Ideal for implementing partial state updates and configuration merging\r\n   *\r\n   * @see {@link StateModel.isPlainObject} - Helper method used to identify mergeable objects\r\n   * @see {@link StateModel.update} - Method that could benefit from merge operations\r\n   * @see {@link StateModel.set} - Method for applying merged results to state\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public merge(\r\n    newObj: Record<string, unknown> | null | undefined,\r\n    oldObj: Record<string, unknown> | null | undefined,\r\n  ): Record<string, unknown> | null | undefined {\r\n    // Enforce the doc's contract\r\n    if (!this.isPlainObject(newObj)) return oldObj;\r\n\r\n    // Base for the merge (treat null/undefined old as empty object)\r\n    const base = this.isPlainObject(oldObj) ? oldObj : {};\r\n    const merged: Record<string, unknown> = { ...base };\r\n\r\n    for (const key of Object.keys(newObj)) {\r\n      const newVal = newObj[key];\r\n      const oldVal = base[key];\r\n\r\n      if (this.isPlainObject(newVal) && this.isPlainObject(oldVal)) {\r\n        // Correct argument order: (new, old)\r\n        const nested = this.merge(newVal, oldVal);\r\n        if (nested !== undefined) merged[key] = nested;\r\n      } else {\r\n        // Replace primitives, arrays, dates, etc. with new\r\n        merged[key] = newVal;\r\n      }\r\n    }\r\n\r\n    return merged;\r\n  }\r\n\r\n  /**\r\n   * Compares an external object with the current value of a state subject for\r\n   * deep equality.\r\n   *\r\n   * This method performs deep equality comparison between a provided object and the current\r\n   * value of a BehaviorSubject stored in either the main {@link StateModel.dir} registry\r\n   * or within a specific group in {@link StateModel.groups}. It leverages the internal\r\n   * {@link StateModel.isEqual} method to provide structural comparison rather than reference\r\n   * equality, making it ideal for change detection and validation scenarios.\r\n   *\r\n   * The comparison process follows this hierarchy:\r\n   * 1. First checks for the subject in the main directory registry\r\n   * 2. If not found and a group name is provided, searches within the specified group\r\n   * 3. Returns `undefined` if the subject doesn't exist in either location\r\n   * 4. Performs deep equality comparison if the subject is found\r\n   *\r\n   * @param obj - The external object to compare against the state subject's current value.\r\n   *   Can be any type including primitives, objects, arrays, null, or undefined.\r\n   * @param dirObjName - The name of the state subject to compare against. This identifier\r\n   *   is used to locate the BehaviorSubject in either the main directory or specified group.\r\n   * @param groupName - Optional group name to limit the search to subjects within a specific\r\n   *   group. When `null` (default), searches only in the main directory. When specified,\r\n   *   searches only within the named group if not found in the main directory.\r\n   *\r\n   * @returns `true` if the objects are deeply equal, `false` if they differ in structure\r\n   *   or content, or `undefined` if the specified subject doesn't exist in the target location.\r\n   *\r\n   * @example\r\n   * Compare with main directory subject:\r\n   * ```typescript\r\n   * const userProfile = { id: 1, name: 'John', email: 'john@example.com' };\r\n   * const isEqual = this.stateModel.dirEquals(userProfile, 'currentUser');\r\n   *\r\n   * if (isEqual === true) {\r\n   *   console.log('Objects are identical');\r\n   * } else if (isEqual === false) {\r\n   *   console.log('Objects differ');\r\n   * } else {\r\n   *   console.log('Subject does not exist');\r\n   * }\r\n   * ```\r\n   *\r\n   * @example\r\n   * Compare with grouped subject:\r\n   * ```typescript\r\n   * const settingsData = { theme: 'dark', language: 'en', notifications: true };\r\n   * const isEqual = this.stateModel.dirEquals(settingsData, 'preferences', 'user');\r\n   *\r\n   * // Use result for change detection\r\n   * if (isEqual === false) {\r\n   *   // Settings have changed, update UI or trigger side effects\r\n   *   this.stateModel.set('preferences', settingsData, 'user');\r\n   * }\r\n   * ```\r\n   *\r\n   * @example\r\n   * Form validation use case:\r\n   * ```typescript\r\n   * // Check if form data matches current state before submission\r\n   * const formData = this.userForm.value;\r\n   * const hasChanges = this.stateModel.dirEquals(formData, 'userProfile') === false;\r\n   *\r\n   * if (hasChanges) {\r\n   *   // Enable save button or show unsaved changes indicator\r\n   *   this.showUnsavedChanges = true;\r\n   * }\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - This method is particularly useful for change detection in reactive forms and components\r\n   * - The comparison is structural, not referential, allowing for meaningful equality checks\r\n   * - Returning `undefined` allows callers to distinguish between \"different values\" and \"subject not found\"\r\n   * - Performance scales with object complexity due to deep comparison algorithm\r\n   *\r\n   * @see {@link StateModel.isEqual} - The underlying deep equality comparison method\r\n   * @see {@link StateModel.dir} - Main state subject registry searched by this method\r\n   * @see {@link StateModel.groups} - Grouped state registry searched when group name is specified\r\n   * @see {@link StateModel.has} - Method to check subject existence without value comparison\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public dirEquals(\r\n    obj: unknown,\r\n    dirObjName: string,\r\n    groupName: string | null = null,\r\n  ): boolean | undefined {\r\n    let dirObj: unknown;\r\n\r\n    // 1. Check if dirObjName exists in dir\r\n    if (!groupName && dirObjName in this.dir) {\r\n      dirObj = this.dir[dirObjName].value;\r\n    } else if (\r\n      groupName &&\r\n      this.groups[groupName] &&\r\n      this.groups[groupName].value[dirObjName]\r\n    ) {\r\n      dirObj = this.groups[groupName].value[dirObjName].value;\r\n    } else {\r\n      return undefined;\r\n    }\r\n\r\n    // 2. Use isEqual to compare obj and dirObj\r\n    const isEqual = this.isEqual(obj, dirObj);\r\n\r\n    return isEqual;\r\n  }\r\n\r\n  /**\r\n   * Merges a new object with the current value of a state subject, updating the subject if changes are detected.\r\n   *\r\n   * This method provides intelligent merging capabilities by combining a new object with the existing\r\n   * value of a BehaviorSubject stored in either the main {@link StateModel.dir} registry or within\r\n   * a specific group in {@link StateModel.groups}. It leverages the internal {@link StateModel.merge}\r\n   * method for deep merging and automatically updates the state subject only when the merged result\r\n   * differs from the current value, providing optimization for unnecessary operations.\r\n   *\r\n   * The merge operation follows this workflow:\r\n   * 1. Locates the target state subject in the main directory or specified group\r\n   * 2. If the subject doesn't exist, creates it using {@link StateModel.set} with the new object\r\n   * 3. If the subject exists, performs a deep merge of the new object with the current value\r\n   * 4. Updates the subject only if the merged result differs from the current value\r\n   * 5. Returns the final merged result for further use\r\n   *\r\n   * This method is ideal for implementing partial state updates, configuration merging, and\r\n   * incremental data modifications without losing existing state properties.\r\n   *\r\n   * @param newObj - The source object to merge with the current state subject value.\r\n   *   Properties from this object take precedence during the merge operation. If not a plain\r\n   *   object (null, undefined, array, etc.), the merge may not behave as expected.\r\n   * @param dirObjName - The name of the state subject to merge with. This identifier is used\r\n   *   to locate the BehaviorSubject in either the main directory or specified group.\r\n   * @param groupName - Optional group name to locate the subject within a hierarchical structure.\r\n   *   When `null` (default), searches in the main directory. When specified, searches within\r\n   *   the named group and creates the subject there if it doesn't exist.\r\n   *\r\n   * @returns The merged object result, or the original `newObj` if the target subject didn't\r\n   *   exist and was newly created. Returns `undefined` if the merge operation cannot be completed.\r\n   *\r\n   * @example\r\n   * Merge with existing main directory subject:\r\n   * ```typescript\r\n   * // Existing state\r\n   * this.stateModel.set('userProfile', { name: 'John', email: 'john@example.com', age: 30 });\r\n   *\r\n   * // Merge partial updates\r\n   * const updates = { email: 'john.doe@example.com', city: 'New York' };\r\n   * const result = this.stateModel.dirMerge(updates, 'userProfile');\r\n   * // Result: { name: 'John', email: 'john.doe@example.com', age: 30, city: 'New York' }\r\n   * ```\r\n   *\r\n   * @example\r\n   * Merge with grouped subject:\r\n   * ```typescript\r\n   * // Existing grouped state\r\n   * this.stateModel.set('preferences', { theme: 'light', language: 'en' }, 'settings');\r\n   *\r\n   * // Merge new preferences\r\n   * const newPrefs = { theme: 'dark', notifications: true };\r\n   * const result = this.stateModel.dirMerge(newPrefs, 'preferences', 'settings');\r\n   * // Result: { theme: 'dark', language: 'en', notifications: true }\r\n   * ```\r\n   *\r\n   * @example\r\n   * Auto-creation when subject doesn't exist:\r\n   * ```typescript\r\n   * // Subject doesn't exist yet\r\n   * const initialData = { status: 'active', priority: 'high' };\r\n   * const result = this.stateModel.dirMerge(initialData, 'taskState');\r\n   * // Creates new subject with initialData and returns it\r\n   * ```\r\n   *\r\n   * @example\r\n   * Nested object merging:\r\n   * ```typescript\r\n   * // Existing nested state\r\n   * this.stateModel.set('appConfig', {\r\n   *   ui: { theme: 'light', sidebar: 'expanded' },\r\n   *   api: { timeout: 5000, retries: 3 }\r\n   * });\r\n   *\r\n   * // Merge partial nested updates\r\n   * const updates = { ui: { theme: 'dark' }, api: { timeout: 8000 } };\r\n   * const result = this.stateModel.dirMerge(updates, 'appConfig');\r\n   * // Result: {\r\n   * //   ui: { theme: 'dark', sidebar: 'expanded' },\r\n   * //   api: { timeout: 8000, retries: 3 }\r\n   * // }\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - Uses {@link StateModel.merge} internally for deep merging operations\r\n   * - Automatically creates missing subjects using {@link StateModel.set} when needed\r\n   * - Updates subjects only when merged results differ from current values (performance optimization)\r\n   * - Supports both standalone subjects and grouped subjects within hierarchical organization\r\n   * - The merge operation preserves existing properties not present in the new object\r\n   * - Does not affect backup values - only updates current state values\r\n   *\r\n   * @see {@link StateModel.merge} - The underlying deep merge method used by this operation\r\n   * @see {@link StateModel.set} - Method used to create subjects when they don't exist\r\n   * @see {@link StateModel.isEqual} - Method used for change detection optimization\r\n   * @see {@link StateModel.dir} - Main state subject registry\r\n   * @see {@link StateModel.groups} - Grouped state registry for hierarchical organization\r\n   * @see {@link StateModel.dirEquals} - Method for comparing objects with state subjects\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public dirMerge(\r\n    newObj: Record<string, unknown> | null | undefined,\r\n    dirObjName: string,\r\n    groupName: string | null = null,\r\n  ): Record<string, unknown> | null | undefined {\r\n    let dirObj: unknown;\r\n    let merged: Record<string, unknown> | null | undefined;\r\n\r\n    // 1. Check if dirObjName exists in dir\r\n    if (!groupName && dirObjName in this.dir) {\r\n      dirObj = this.dir[dirObjName].value;\r\n    }\r\n\r\n    // 2. Check if dirObjName exists in groups\r\n    if (\r\n      groupName &&\r\n      this.groups[groupName] &&\r\n      this.groups[groupName].value[dirObjName]\r\n    ) {\r\n      dirObj = this.groups[groupName].value[dirObjName].value;\r\n    }\r\n\r\n    // 3. Replace dirObj with newObj if dirObj doesn't exist\r\n    if (!dirObj) {\r\n      if (!groupName) {\r\n        this.set(dirObjName, newObj);\r\n      }\r\n      if (groupName) {\r\n        this.set(dirObjName, newObj, groupName);\r\n      }\r\n      return newObj;\r\n    }\r\n\r\n    // 4. Use merge to combine newObj and dirObj\r\n    if (dirObj) {\r\n      merged = this.merge(newObj, dirObj as Record<string, unknown>);\r\n    }\r\n\r\n    // 5. Assign merged if different from dirObj\r\n    if (!groupName && merged && !this.isEqual(merged, dirObj)) {\r\n      this.dir[dirObjName].next(merged);\r\n    }\r\n    if (groupName && merged && !this.isEqual(merged, dirObj)) {\r\n      this.groups[groupName].value[dirObjName].next(merged);\r\n    }\r\n    return merged;\r\n  }\r\n\r\n  /**\r\n   * Provides safe access to a BehaviorSubject with automatic initialization if it doesn't exist.\r\n   *\r\n   * This method serves as the primary access point for retrieving BehaviorSubjects from either\r\n   * the main {@link StateModel.dir} registry or from grouped subjects within {@link StateModel.groups}.\r\n   * It implements a fail-safe pattern by automatically creating missing subjects or groups with\r\n   * `undefined` initial values, enabling reactive subscription patterns even when the target\r\n   * state hasn't been explicitly initialized yet.\r\n   *\r\n   * The method follows a hierarchical search pattern:\r\n   * - For ungrouped subjects: searches in the main directory registry\r\n   * - For grouped subjects: searches within the specified group, creating the group if necessary\r\n   * - Auto-initializes missing subjects using {@link StateModel.initiate} with `undefined` values\r\n   * - Guarantees that a valid BehaviorSubject is always returned for subscription\r\n   *\r\n   * This design pattern supports reactive programming where components can subscribe to state\r\n   * changes before the state producer has set initial values, preventing timing-related issues\r\n   * in component initialization and data flow.\r\n   *\r\n   * @param subjectName - The unique identifier for the BehaviorSubject to retrieve or create.\r\n   *   Must be a non-empty string that serves as the key in the state registry.\r\n   * @param groupName - Optional group name to locate the subject within a hierarchical structure.\r\n   *   When `null` (default), searches in the main directory. When specified, searches within\r\n   *   the named group and creates the group if it doesn't exist.\r\n   *\r\n   * @returns A BehaviorSubject that can be immediately subscribed to. If the subject didn't\r\n   *   exist, it will be initialized with an `undefined` value and can be updated later through\r\n   *   {@link StateModel.set} or {@link StateModel.update} methods.\r\n   *\r\n   * @example\r\n   * Subscribe to an ungrouped subject:\r\n   * ```typescript\r\n   * // Safe subscription even if 'userProfile' doesn't exist yet\r\n   * this.stateModel.observe('userProfile').subscribe(profile => {\r\n   *   if (profile) {\r\n   *     console.log('User profile loaded:', profile);\r\n   *   } else {\r\n   *     console.log('User profile not yet initialized');\r\n   *   }\r\n   * });\r\n   * ```\r\n   *\r\n   * @example\r\n   * Subscribe to a grouped subject:\r\n   * ```typescript\r\n   * // Creates 'users' group and 'currentUser' subject if they don't exist\r\n   * this.stateModel.observe('currentUser', 'users').subscribe(user => {\r\n   *   this.handleUserChange(user);\r\n   * });\r\n   *\r\n   * // Later, another component can set the value\r\n   * this.stateModel.set('currentUser', { id: 1, name: 'John' }, 'users');\r\n   * ```\r\n   *\r\n   * @example\r\n   * Reactive form integration:\r\n   * ```typescript\r\n   * // Component can subscribe before data is loaded\r\n   * ngOnInit() {\r\n   *   this.stateModel.observe('formData').subscribe(data => {\r\n   *     if (data) {\r\n   *       this.form.patchValue(data);\r\n   *     }\r\n   *   });\r\n   * }\r\n   *\r\n   * // Service loads data asynchronously\r\n   * loadFormData() {\r\n   *   this.http.get('/api/form-data').subscribe(data => {\r\n   *     this.stateModel.set('formData', data);\r\n   *   });\r\n   * }\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - This method is idempotent: multiple calls with the same parameters return the same BehaviorSubject instance\r\n   * - Auto-initialization uses `undefined` as the default value to indicate uninitialized state\r\n   * - The returned BehaviorSubject maintains referential integrity for consistent subscription behavior\r\n   * - Group creation is transparent and doesn't emit notifications to {@link StateModel.updated}\r\n   *\r\n   * @see {@link StateModel.dir} - Main state subject registry accessed by this method\r\n   * @see {@link StateModel.groups} - Grouped state registry for hierarchical organization\r\n   * @see {@link StateModel.initiate} - Method used internally for auto-initialization\r\n   * @see {@link StateModel.has} - Method to check subject existence without auto-creation\r\n   * @see {@link StateModel.set} - Method for setting initial or updated values\r\n   * @see {@link StateModel.update} - Method for modifying existing state values\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public observe(\r\n    subjectName: string,\r\n    groupName: string | null = null,\r\n  ): Observable<StateObjType> {\r\n    if (!groupName) {\r\n      if (!this.dir[subjectName]) {\r\n        this.initiate(subjectName);\r\n      }\r\n      return this.dir[subjectName].asObservable();\r\n    }\r\n    if (groupName) {\r\n      if (!this.groups[groupName]) {\r\n        this.initiate(subjectName, groupName);\r\n      }\r\n      if (!this.groups[groupName].value[subjectName]) {\r\n        this.initiate(subjectName, groupName);\r\n      }\r\n    }\r\n    return this.groups[groupName].value[subjectName].asObservable();\r\n  }\r\n\r\n  public observeGroup(\r\n    groupName: string,\r\n  ): Observable<Record<string, BehaviorSubject<StateObjType>>> {\r\n    if (!this.groups[groupName]) {\r\n      this.groups[groupName] = new BehaviorSubject<\r\n        Record<string, BehaviorSubject<StateObjType>>\r\n      >({});\r\n    }\r\n\r\n    return this.groups[groupName].asObservable();\r\n  }\r\n\r\n  // public observeReg() {}\r\n\r\n  /**\r\n   * Safely removes a BehaviorSubject from the state management system and cleans up all associated resources.\r\n   *\r\n   * This method performs comprehensive cleanup of state subjects by removing them from the appropriate\r\n   * registry ({@link StateModel.dir} or {@link StateModel.groups}), properly completing the BehaviorSubject\r\n   * to prevent memory leaks, and removing corresponding backup entries to maintain system integrity.\r\n   * The method supports both standalone subjects and grouped subjects with automatic resource cleanup.\r\n   *\r\n   * The removal process includes:\r\n   * - Calling `complete()` on the BehaviorSubject to properly terminate all subscriptions\r\n   * - Removing the subject from the main directory or specified group registry\r\n   * - Cleaning up corresponding backup entries to prevent stale data\r\n   * - Updating group BehaviorSubjects to reflect structural changes when removing grouped subjects\r\n   *\r\n   * @param subjectName - The unique identifier of the BehaviorSubject to remove from the state system.\r\n   *   Must match an existing subject name in either the main directory or specified group.\r\n   * @param groupName - Optional group name containing the subject to remove. When `null` (default),\r\n   *   removes the subject from the main {@link StateModel.dir} registry. When specified, removes\r\n   *   the subject from within the named group in {@link StateModel.groups}.\r\n   *\r\n   * @example\r\n   * Remove a standalone subject:\r\n   * ```typescript\r\n   * // Remove 'userProfile' from main directory\r\n   * this.stateModel.rem('userProfile');\r\n   * // Subject is completed and removed from dir and backups\r\n   * ```\r\n   *\r\n   * @example\r\n   * Remove a grouped subject:\r\n   * ```typescript\r\n   * // Remove 'currentUser' from 'users' group\r\n   * this.stateModel.rem('currentUser', 'users');\r\n   * // Subject is completed and removed from the group and group backups\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - Safe to call even if the subject doesn't exist (no-op behavior)\r\n   * - Always calls `complete()` before deletion to prevent memory leaks\r\n   * - Group structure is automatically updated when removing grouped subjects\r\n   * - Does not remove empty groups - use {@link StateModel.removeGroup} for complete group removal\r\n   * - Backup cleanup ensures no stale rollback data remains in the system\r\n   *\r\n   * @see {@link StateModel.dir} - Main state subject registry\r\n   * @see {@link StateModel.groups} - Grouped state subject registry\r\n   * @see {@link StateModel.backups} - Backup registry for rollback functionality\r\n   * @see {@link StateModel.groupBackups} - Group-specific backup registry\r\n   * @see {@link StateModel.removeGroup} - Method for removing entire groups\r\n   * @see {@link StateModel.observe} - Method for accessing subjects safely\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public rem(subjectName: string, groupName: string | null = null): void {\r\n    if (this.dir[subjectName]) {\r\n      this.dir[subjectName].complete();\r\n      delete this.dir[subjectName];\r\n    }\r\n    if (this.backups[subjectName]) {\r\n      delete this.backups[subjectName];\r\n    }\r\n    if (\r\n      groupName &&\r\n      this.groups[groupName] &&\r\n      this.groups[groupName].value[subjectName]\r\n    ) {\r\n      this.groups[groupName].value[subjectName].complete();\r\n      delete this.groups[groupName].value[subjectName];\r\n      // Update the group's BehaviorSubject to reflect the change\r\n      this.groups[groupName].next(this.groups[groupName].value);\r\n    }\r\n    if (\r\n      groupName &&\r\n      this.groupBackups[groupName] &&\r\n      Object.prototype.hasOwnProperty.call(\r\n        this.groupBackups[groupName],\r\n        subjectName,\r\n      )\r\n    ) {\r\n      delete this.groupBackups[groupName][subjectName];\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Completely removes a hierarchical group from the state management system and cleans up all associated resources.\r\n   *\r\n   * This method performs comprehensive cleanup of an entire group by removing it from the {@link StateModel.groups}\r\n   * registry, updating the reactive {@link StateModel.groupList} to reflect the structural change, and clearing\r\n   * all corresponding backup entries from {@link StateModel.groupBackups}. Unlike {@link StateModel.rem} which\r\n   * removes individual subjects, this method eliminates the entire group container and all nested BehaviorSubjects\r\n   * within it.\r\n   *\r\n   * The removal process includes:\r\n   * - Deleting the entire group BehaviorSubject and all nested subject BehaviorSubjects\r\n   * - Removing the group name from the reactive {@link StateModel.groupList}\r\n   * - Clearing all backup data associated with the group to prevent memory leaks\r\n   * - Automatically updating subscribers to the {@link StateModel.groupList} about the structural change\r\n   *\r\n   * @param groupName - The unique identifier of the group to remove from the state management system.\r\n   *   Must match an existing group name in the {@link StateModel.groups} registry. If the group doesn't\r\n   *   exist, the method safely performs no operations without throwing errors.\r\n   *\r\n   * @example\r\n   * Remove an entire user management group:\r\n   * ```typescript\r\n   * // Assume group contains multiple subjects: 'currentUser', 'permissions', 'settings'\r\n   * this.stateModel.removeGroup('users');\r\n   *\r\n   * // All subjects within 'users' group are now inaccessible\r\n   * // Group is removed from groupList array\r\n   * // All backup data for the group is cleared\r\n   * ```\r\n   *\r\n   * @example\r\n   * Reactive cleanup detection:\r\n   * ```typescript\r\n   * // Subscribe to group list changes\r\n   * this.stateModel.groupList.subscribe(groups => {\r\n   *   console.log('Available groups:', groups);\r\n   *   // Will show updated list after removeGroup() is called\r\n   * });\r\n   *\r\n   * // Remove group and observe the change\r\n   * this.stateModel.removeGroup('temporaryData');\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - Safe to call even if the group doesn't exist (no-op behavior)\r\n   * - All nested BehaviorSubjects are automatically cleaned up with the group removal\r\n   * - Backup data cleanup prevents memory leaks and stale rollback information\r\n   * - The {@link StateModel.groupList} BehaviorSubject automatically notifies subscribers of the change\r\n   * - Use {@link StateModel.rem} instead if you only need to remove individual subjects within a group\r\n   *\r\n   * @see {@link StateModel.groups} - The hierarchical group registry this method modifies\r\n   * @see {@link StateModel.groupList} - Reactive list automatically updated by this method\r\n   * @see {@link StateModel.groupBackups} - Backup registry cleared by this method\r\n   * @see {@link StateModel.loadGroup} - Method for creating new groups\r\n   * @see {@link StateModel.rem} - Method for removing individual subjects within groups\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public removeGroup(groupName: string): void {\r\n    if (this.groups[groupName]) {\r\n      delete this.groups[groupName];\r\n    }\r\n    if (this.groupList.value.includes(groupName)) {\r\n      const itemIndex = this.groupList.value.indexOf(groupName);\r\n      const listValue = JSON.parse(JSON.stringify(this.groupList.value));\r\n      listValue.splice(itemIndex, 1);\r\n      this.groupList.next(listValue);\r\n    }\r\n    if (this.groupBackups[groupName]) {\r\n      delete this.groupBackups[groupName];\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Restores a BehaviorSubject to its backup value, effectively rolling back any changes made since the last {@link StateModel.set} operation.\r\n   *\r\n   * This method implements the rollback functionality of the state management system by restoring\r\n   * a BehaviorSubject's value from its corresponding backup entry. It operates on both standalone\r\n   * subjects in the main {@link StateModel.dir} registry and grouped subjects within {@link StateModel.groups}.\r\n   * The restoration only occurs if the current value differs from the backup value, providing\r\n   * optimization for unnecessary operations.\r\n   *\r\n   * Common use cases include:\r\n   * - Reset button functionality in forms and dialogs\r\n   * - Canceling unsaved changes in user interfaces\r\n   * - Implementing undo operations in data entry workflows\r\n   * - Reverting state when dialogs are closed without saving\r\n   *\r\n   * The method performs deep cloning of backup values to prevent reference mutations and uses\r\n   * {@link StateModel.isEqual} for efficient change detection before applying the reset operation.\r\n   *\r\n   * @param subjectName - The unique identifier of the BehaviorSubject to reset. Must correspond\r\n   *   to an existing subject in either the main directory or specified group.\r\n   * @param groupName - Optional group name containing the subject to reset. When `null` (default),\r\n   *   resets the subject from the main {@link StateModel.dir} registry. When specified, resets\r\n   *   the subject from within the named group in {@link StateModel.groups}.\r\n   *\r\n   * @example\r\n   * Reset a standalone subject:\r\n   * ```typescript\r\n   * // Set initial value and backup\r\n   * this.stateModel.set('userForm', { name: 'John', email: 'john@example.com' });\r\n   *\r\n   * // Make changes to the state\r\n   * this.stateModel.update('userForm', { name: 'Jane', email: 'jane@example.com' });\r\n   *\r\n   * // Reset to backup value\r\n   * this.stateModel.reset('userForm');\r\n   * // Current value is now: { name: 'John', email: 'john@example.com' }\r\n   * ```\r\n   *\r\n   * @example\r\n   * Reset a grouped subject:\r\n   * ```typescript\r\n   * // Set initial grouped value\r\n   * this.stateModel.set('preferences', { theme: 'light', lang: 'en' }, 'settings');\r\n   *\r\n   * // Update the grouped subject\r\n   * this.stateModel.update('preferences', { theme: 'dark', lang: 'es' }, 'settings');\r\n   *\r\n   * // Reset grouped subject to backup\r\n   * this.stateModel.reset('preferences', 'settings');\r\n   * // Restored to: { theme: 'light', lang: 'en' }\r\n   * ```\r\n   *\r\n   * @example\r\n   * Integration with UI components:\r\n   * ```typescript\r\n   * // In a component with reset functionality\r\n   * onResetClick(): void {\r\n   *   this.stateModel.reset('formData');\r\n   *   this.form.patchValue(this.stateModel.value('formData'));\r\n   * }\r\n   *\r\n   * onDialogCancel(): void {\r\n   *   this.stateModel.reset('dialogState');\r\n   *   this.dialogRef.close();\r\n   * }\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - No-op if the subject doesn't exist or has no backup value\r\n   * - No-op if current value equals backup value (optimized for performance)\r\n   * - Uses deep cloning to prevent reference mutations during reset\r\n   * - Does not trigger {@link StateModel.updated} notifications to prevent reset loops\r\n   * - Backup values are created and updated only by the {@link StateModel.set} method\r\n   *\r\n   * @see {@link StateModel.set} - Creates and updates backup values used by this method\r\n   * @see {@link StateModel.backups} - Main backup registry for ungrouped subjects\r\n   * @see {@link StateModel.groupBackups} - Backup registry for grouped subjects\r\n   * @see {@link StateModel.isEqual} - Method used for change detection optimization\r\n   * @see {@link StateModel.value} - Method for retrieving current subject values\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public reset(subjectName: string, groupName: string | null = null): void {\r\n    if (!groupName) {\r\n      if (\r\n        Object.prototype.hasOwnProperty.call(this.dir, subjectName) &&\r\n        Object.prototype.hasOwnProperty.call(this.backups, subjectName)\r\n      ) {\r\n        const currentValue = this.dir[subjectName].value;\r\n        const backupValue = this.backups[subjectName];\r\n        if (this.isEqual(currentValue, backupValue)) return;\r\n        const backupObjCopy = JSON.parse(\r\n          JSON.stringify(this.backups[subjectName]),\r\n        );\r\n        this.dir[subjectName].next(backupObjCopy);\r\n      }\r\n    }\r\n    if (groupName) {\r\n      if (\r\n        Object.prototype.hasOwnProperty.call(this.groups, groupName) &&\r\n        Object.prototype.hasOwnProperty.call(\r\n          this.groups[groupName].value,\r\n          subjectName,\r\n        ) &&\r\n        Object.prototype.hasOwnProperty.call(this.groupBackups, groupName) &&\r\n        Object.prototype.hasOwnProperty.call(\r\n          this.groupBackups[groupName],\r\n          subjectName,\r\n        )\r\n      ) {\r\n        const backupObjCopy = JSON.parse(\r\n          JSON.stringify(this.groupBackups[groupName][subjectName]),\r\n        );\r\n        const currentValue = this.groups[groupName].value[subjectName].value;\r\n        const backupValue = this.groupBackups[groupName][subjectName];\r\n        if (this.isEqual(currentValue, backupValue)) return;\r\n        this.groups[groupName].value[subjectName].next(backupObjCopy);\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Creates or updates a BehaviorSubject with a specified value and establishes a backup for rollback functionality.\r\n   *\r\n   * This method serves as the primary state setting mechanism within the state management system. It creates new\r\n   * BehaviorSubjects or updates existing ones with the provided value, while simultaneously creating or updating\r\n   * corresponding backup entries that enable rollback operations via {@link StateModel.reset}. The method supports\r\n   * both standalone subjects in the main {@link StateModel.dir} registry and hierarchically organized subjects\r\n   * within named groups in {@link StateModel.groups}.\r\n   *\r\n   * Key behaviors include:\r\n   * - Deep cloning of input values to prevent reference mutations\r\n   * - Automatic backup creation/updates for rollback functionality\r\n   * - Early return optimization when setting identical values (via {@link StateModel.isEqual})\r\n   * - Auto-creation of group structures when targeting grouped subjects\r\n   * - Notification emission through {@link StateModel.updated} for reactive subscribers\r\n   *\r\n   * Unlike {@link StateModel.update}, this method always updates the backup registry, making it ideal for\r\n   * establishing \"checkpoint\" values that can be restored later. This pattern is commonly used in form\r\n   * controls, dialog components, and any UI requiring save/cancel functionality.\r\n   *\r\n   * @param subjectName - The unique identifier for the BehaviorSubject to create or update.\r\n   *   Must be a non-empty string that serves as the key in the state registry.\r\n   * @param initialValue - The value to assign to the BehaviorSubject and store as the backup value.\r\n   *   This value is deep cloned to prevent external reference mutations.\r\n   * @param groupName - Optional group name for hierarchical organization. When `null` (default),\r\n   *   the subject is managed in the main directory. When specified, the subject is organized\r\n   *   within the named group, and the group is auto-created if it doesn't exist.\r\n   *\r\n   * @example\r\n   * Set a standalone subject with backup:\r\n   * ```typescript\r\n   * // Creates subject and backup for rollback capability\r\n   * this.stateModel.set('userProfile', { name: 'John', email: 'john@example.com' });\r\n   *\r\n   * // Later modifications don't affect the backup\r\n   * this.stateModel.update('userProfile', { name: 'Jane', email: 'jane@example.com' });\r\n   *\r\n   * // Reset restores the original set() value\r\n   * this.stateModel.reset('userProfile'); // Back to John's data\r\n   * ```\r\n   *\r\n   * @example\r\n   * Set a grouped subject with hierarchical organization:\r\n   * ```typescript\r\n   * // Creates 'settings' group and 'theme' subject within it\r\n   * this.stateModel.set('theme', { mode: 'dark', accent: 'blue' }, 'settings');\r\n   * this.stateModel.set('language', 'en-US', 'settings');\r\n   *\r\n   * // Access grouped subject\r\n   * this.stateModel.observe('theme', 'settings').subscribe(theme => {\r\n   *   console.log('Theme changed:', theme);\r\n   * });\r\n   * ```\r\n   *\r\n   * @example\r\n   * Form checkpoint pattern:\r\n   * ```typescript\r\n   * // Establish initial form state as checkpoint\r\n   * const formData = { name: '', email: '', preferences: {} };\r\n   * this.stateModel.set('formState', formData);\r\n   *\r\n   * // User makes changes via updates (backups remain unchanged)\r\n   * onFormChange(newData: any) {\r\n   *   this.stateModel.update('formState', newData);\r\n   * }\r\n   *\r\n   * // Cancel button restores checkpoint\r\n   * onCancel() {\r\n   *   this.stateModel.reset('formState'); // Back to initial formData\r\n   * }\r\n   *\r\n   * // Save button establishes new checkpoint\r\n   * onSave() {\r\n   *   const currentData = this.stateModel.value('formState');\r\n   *   this.stateModel.set('formState', currentData); // New backup point\r\n   * }\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - Values are automatically deep cloned to prevent external mutations\r\n   * - Setting identical values triggers early return (no notification or backup update)\r\n   * - Group structures are transparently created when needed\r\n   * - Backup values are only updated by this method, not by {@link StateModel.update}\r\n   * - The {@link StateModel.updated} BehaviorSubject emits the subject name after successful operations\r\n   *\r\n   * @see {@link StateModel.update} - For modifying subjects without affecting backups\r\n   * @see {@link StateModel.reset} - For restoring subjects from backup values\r\n   * @see {@link StateModel.observe} - For safely accessing and subscribing to subjects\r\n   * @see {@link StateModel.backups} - Main backup registry updated by this method\r\n   * @see {@link StateModel.groupBackups} - Group backup registry for hierarchical subjects\r\n   * @see {@link StateModel.isEqual} - Deep equality method used for change detection\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public set(\r\n    subjectName: string,\r\n    initialValue: StateObjType,\r\n    groupName: string | null = null,\r\n  ): void {\r\n    let value: StateObjType;\r\n    // Create a deep clone of the initial value to avoid reference issues\r\n    if (initialValue) {\r\n      value = JSON.parse(JSON.stringify(initialValue));\r\n    } else {\r\n      value = initialValue;\r\n    }\r\n\r\n    // Set the BehaviorSubject in dir if no groupName is provided\r\n    if (!groupName) {\r\n      if (!this.dir[subjectName]) {\r\n        if (initialValue as StateObjType) {\r\n          this.dir[subjectName] = new BehaviorSubject(value);\r\n        } else {\r\n          this.dir[subjectName] = new BehaviorSubject(initialValue);\r\n        }\r\n      } else {\r\n        const currentValue = this.dir[subjectName].value;\r\n        // Checks if the current value is equal to the new value\r\n        if (this.isEqual(currentValue, value)) return;\r\n        this.dir[subjectName].next(value);\r\n      }\r\n      this.backups[subjectName] = value;\r\n      this.updated.next(subjectName);\r\n    }\r\n\r\n    // Set the BehaviorSubject in a group if groupName is provided\r\n    if (groupName) {\r\n      if (!this.groups[groupName]) {\r\n        this.groups[groupName] = new BehaviorSubject<\r\n          Record<string, BehaviorSubject<StateObjType>>\r\n        >({});\r\n      }\r\n      if (!this.groups[groupName].value[subjectName]) {\r\n        this.groups[groupName].value[subjectName] =\r\n          new BehaviorSubject<StateObjType>(value);\r\n        // Update the group's BehaviorSubject to reflect the change\r\n        this.groups[groupName].next(this.groups[groupName].value);\r\n      } else {\r\n        // Checks if the current value is equal to the new value\r\n        const currentValue = this.groups[groupName].value[subjectName].value;\r\n        if (this.isEqual(currentValue, value)) return;\r\n        this.groups[groupName].value[subjectName].next(value);\r\n      }\r\n      if (!this.groupBackups[groupName]) {\r\n        this.groupBackups[groupName] = {};\r\n      }\r\n      this.groupBackups[groupName][subjectName] = value;\r\n      this.updated.next(subjectName);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Retrieves a deep clone of the current value from a BehaviorSubject in the state management system.\r\n   *\r\n   * This method provides safe access to the current value of a BehaviorSubject stored in either\r\n   * the main {@link StateModel.dir} registry or within a specific group in {@link StateModel.groups}.\r\n   * The returned value is always a deep clone to prevent external mutations from affecting the\r\n   * internal state management system, ensuring data integrity and preventing unintended side effects.\r\n   *\r\n   * The method searches hierarchically:\r\n   * - For ungrouped subjects: retrieves from the main directory registry\r\n   * - For grouped subjects: retrieves from within the specified group\r\n   * - Returns `null` if the subject or group doesn't exist\r\n   * - Handles special cases like `false` values correctly without treating them as falsy\r\n   *\r\n   * This is the recommended way to access current state values for display, computation, or\r\n   * external API calls, as it provides a safe snapshot without risking state corruption.\r\n   *\r\n   * @param subjectName - The unique identifier of the BehaviorSubject whose value should be retrieved.\r\n   *   Must correspond to an existing subject in either the main directory or specified group.\r\n   * @param groupName - Optional group name containing the target subject. When `null` (default),\r\n   *   searches in the main {@link StateModel.dir} registry. When specified, searches within\r\n   *   the named group in {@link StateModel.groups}.\r\n   *\r\n   * @returns A deep clone of the BehaviorSubject's current value, preserving the original data\r\n   *   type and structure. Returns `null` if the subject doesn't exist in the specified location\r\n   *   or if the target group doesn't exist. Returns `false` explicitly when the stored value\r\n   *   is boolean `false` to distinguish it from other falsy values.\r\n   *\r\n   * @example\r\n   * Retrieve value from main directory:\r\n   * ```typescript\r\n   * // Get user profile data safely\r\n   * const userProfile = this.stateModel.value('userProfile');\r\n   * if (userProfile) {\r\n   *   console.log('User name:', userProfile.name);\r\n   *   // Mutations to userProfile won't affect the state\r\n   *   userProfile.name = 'Modified'; // Safe - doesn't change state\r\n   * }\r\n   * ```\r\n   *\r\n   * @example\r\n   * Retrieve value from a grouped subject:\r\n   * ```typescript\r\n   * // Get settings from specific group\r\n   * const themeSettings = this.stateModel.value('theme', 'userSettings');\r\n   * if (themeSettings) {\r\n   *   this.applyTheme(themeSettings);\r\n   * }\r\n   * ```\r\n   *\r\n   * @example\r\n   * Handle boolean false values correctly:\r\n   * ```typescript\r\n   * // Set a boolean false value\r\n   * this.stateModel.set('feature', false);\r\n   *\r\n   * // Retrieve handles false correctly\r\n   * const featureEnabled = this.stateModel.value('feature');\r\n   * console.log(featureEnabled); // false (not null)\r\n   * console.log(featureEnabled === false); // true\r\n   * ```\r\n   *\r\n   * @example\r\n   * Safe data manipulation pattern:\r\n   * ```typescript\r\n   * // Get current form data\r\n   * const formData = this.stateModel.value('userForm');\r\n   * if (formData) {\r\n   *   // Create modified copy for submission\r\n   *   const submissionData = {\r\n   *     ...formData,\r\n   *     lastModified: new Date(),\r\n   *     submitted: true\r\n   *   };\r\n   *\r\n   *   // Submit without affecting original state\r\n   *   this.submitForm(submissionData);\r\n   * }\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - Values are deep cloned using `JSON.parse(JSON.stringify())` for complete isolation\r\n   * - Special handling for `false` values to prevent incorrect falsy evaluation\r\n   * - Returns `null` consistently for non-existent subjects to distinguish from `undefined` values\r\n   * - Performance scales with object complexity due to deep cloning operation\r\n   * - Does not trigger any state changes or notifications\r\n   *\r\n   * @see {@link StateModel.observe} - For reactive subscription to state changes\r\n   * @see {@link StateModel.set} - For setting state values\r\n   * @see {@link StateModel.update} - For modifying existing state values\r\n   * @see {@link StateModel.has} - For checking subject existence without retrieving values\r\n   * @see {@link StateModel.dir} - Main state subject registry\r\n   * @see {@link StateModel.groups} - Grouped state subject registry\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public value(subjectName: string, groupName: string | null = null) {\r\n    if (!groupName && this.dir[subjectName]) {\r\n      if (this.dir[subjectName].value) {\r\n        const valueClone = JSON.parse(\r\n          JSON.stringify(this.dir[subjectName].value),\r\n        );\r\n        return valueClone;\r\n      }\r\n      if (this.dir[subjectName].value === false) {\r\n        return false;\r\n      }\r\n      if (this.dir[subjectName].value === undefined) {\r\n        return undefined;\r\n      }\r\n    }\r\n    if (\r\n      groupName &&\r\n      this.groups[groupName] &&\r\n      subjectName in this.groups[groupName].value\r\n    ) {\r\n      const value = this.groups[groupName].value[subjectName].value;\r\n      if (value) {\r\n        const valueClone = JSON.parse(JSON.stringify(value));\r\n        return valueClone;\r\n      } else {\r\n        return value;\r\n      }\r\n    }\r\n    return null;\r\n  }\r\n\r\n  /**\r\n   * Modifies the value of an existing BehaviorSubject without affecting backup values used for rollback operations.\r\n   *\r\n   * This method provides non-destructive state updates by modifying the current value of a BehaviorSubject\r\n   * while preserving the backup values established by {@link StateModel.set}. It supports both standalone\r\n   * subjects in the main {@link StateModel.dir} registry and grouped subjects within {@link StateModel.groups}.\r\n   * When the target subject doesn't exist, the method automatically delegates to {@link StateModel.set}\r\n   * to create the subject with proper backup initialization.\r\n   *\r\n   * Key behaviors include:\r\n   * - Deep cloning of input values to prevent reference mutations\r\n   * - Preservation of existing backup values (unlike {@link StateModel.set})\r\n   * - Early return optimization when updating to identical values (via {@link StateModel.isEqual})\r\n   * - Auto-creation of subjects via {@link StateModel.set} when they don't exist\r\n   * - Auto-creation of group structures when targeting non-existent grouped subjects\r\n   *\r\n   * This method is ideal for temporary state changes, form input handling, and any scenario where\r\n   * you want to modify state while maintaining the ability to rollback to previously set checkpoint values.\r\n   *\r\n   * @param subjectName - The unique identifier of the BehaviorSubject to update. Must be a non-empty\r\n   *   string that serves as the key in the state registry.\r\n   * @param newValue - The new value to assign to the BehaviorSubject. This value is deep cloned\r\n   *   to prevent external reference mutations. Can be any valid {@link StateObjType} including\r\n   *   primitives, objects, arrays, or null/undefined values.\r\n   * @param groupName - Optional group name for hierarchical organization. When `null` (default),\r\n   *   updates the subject in the main directory. When specified, updates the subject within\r\n   *   the named group, creating the group if it doesn't exist.\r\n   *\r\n   * @example\r\n   * Update existing subject without affecting backup:\r\n   * ```typescript\r\n   * // Set initial value with backup\r\n   * this.stateModel.set('userForm', { name: 'John', email: 'john@example.com' });\r\n   *\r\n   * // Update without changing backup\r\n   * this.stateModel.update('userForm', { name: 'Jane', email: 'jane@example.com' });\r\n   *\r\n   * // Backup still contains original data\r\n   * this.stateModel.reset('userForm'); // Restores to John's data\r\n   * ```\r\n   *\r\n   * @example\r\n   * Form input handling pattern:\r\n   * ```typescript\r\n   * // Initialize form with checkpoint\r\n   * this.stateModel.set('formData', this.initialFormState);\r\n   *\r\n   * // Handle user input changes\r\n   * onInputChange(fieldName: string, value: any) {\r\n   *   const currentData = this.stateModel.value('formData');\r\n   *   const updatedData = { ...currentData, [fieldName]: value };\r\n   *   this.stateModel.update('formData', updatedData);\r\n   * }\r\n   *\r\n   * // Reset discards all updates, restoring checkpoint\r\n   * onReset() {\r\n   *   this.stateModel.reset('formData');\r\n   * }\r\n   * ```\r\n   *\r\n   * @example\r\n   * Auto-creation when subject doesn't exist:\r\n   * ```typescript\r\n   * // Subject doesn't exist yet - delegates to set() method\r\n   * this.stateModel.update('newSubject', { created: true });\r\n   * // Equivalent to: this.stateModel.set('newSubject', { created: true });\r\n   * ```\r\n   *\r\n   * @remarks\r\n   * - Values are automatically deep cloned to prevent external mutations\r\n   * - Updating to identical values triggers early return (no state change or notification)\r\n   * - Does not emit {@link StateModel.updated} notifications for existing subjects (only when creating new ones via delegation)\r\n   * - Backup values remain unchanged, preserving rollback capability to the last {@link StateModel.set} operation\r\n   * - Group structures are transparently created when targeting non-existent groups\r\n   *\r\n   * @see {@link StateModel.set} - For creating subjects with backup checkpoints\r\n   * @see {@link StateModel.reset} - For restoring subjects from backup values\r\n   * @see {@link StateModel.observe} - For reactive subscription to state changes\r\n   * @see {@link StateModel.isEqual} - Deep equality method used for change detection\r\n   * @see {@link StateObjType} - Type definition for acceptable values\r\n   *\r\n   * @public\r\n   * @since 1.0.0\r\n   */\r\n  public update(\r\n    subjectName: string,\r\n    newValue: StateObjType,\r\n    groupName: string | null = null,\r\n  ): void {\r\n    let valueCopy: StateObjType;\r\n    if (newValue) {\r\n      valueCopy = JSON.parse(JSON.stringify(newValue));\r\n    } else {\r\n      valueCopy = newValue;\r\n    }\r\n\r\n    if (!groupName) {\r\n      if (this.dir[subjectName]) {\r\n        const currentValue = this.dir[subjectName].value;\r\n        if (this.isEqual(currentValue, valueCopy)) return;\r\n        this.dir[subjectName].next(valueCopy);\r\n      } else {\r\n        this.set(subjectName, valueCopy);\r\n      }\r\n    }\r\n    if (groupName) {\r\n      if (!this.groups[groupName]) {\r\n        this.groups[groupName] = new BehaviorSubject<\r\n          Record<string, BehaviorSubject<StateObjType>>\r\n        >({});\r\n      }\r\n      if (this.groups[groupName].value[subjectName]) {\r\n        const groupValue = this.groups[groupName].value;\r\n        const currentValue = this.groups[groupName].value[subjectName].value;\r\n\r\n        if (this.isEqual(currentValue, valueCopy)) return;\r\n\r\n        groupValue[subjectName].next(valueCopy);\r\n\r\n        this.groups[groupName].next({\r\n          ...groupValue,\r\n        });\r\n      } else {\r\n        this.set(subjectName, valueCopy, groupName);\r\n      }\r\n    }\r\n  }\r\n}\r\n","// Angular Imports\r\nimport { Injectable } from '@angular/core';\r\n// Model Imports\r\nimport { StateModel } from '../models/state.model';\r\n\r\n/**\r\n * Directories are services that contain a [list]{@link DirectoryModel#list} of\r\n * [BehaviorSubjects]{@link https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject}\r\n * that contain an array of names of the BehaviorSubjects contained in the\r\n * [dir]{@link DirectoryModel#dir} object, a 'dir' object that is a Directory of\r\n * BehaviorSubjects, and a [backupObjs]{@link DirectoryModel#backupObjs}\r\n * Directory of JSON objects. A Directory is a specific term for this framework\r\n * where instead of using an array of objects, we use an object where the top-level\r\n * keys are the name of the object, and the value is the object itself. Most\r\n * Angular frameworks and tutorials recomend using arrays of objects for their\r\n * templating, and then use the filter or sort methods to control the display or\r\n * selection of a particular object within the array of objects. But for massive\r\n * arrays, the filter method can be incredibly slow. The BpDirectory (Blueprint\r\n * Directory) contains all of the Blueprints in the site's blueprint collection.\r\n */\r\n@Injectable({\r\n  providedIn: 'root',\r\n})\r\nexport class BpState extends StateModel {}\r\n","// Angular Imports\r\nimport { Injectable } from '@angular/core';\r\n// Model Imports\r\nimport { StateModel } from '../models/state.model';\r\n\r\n/**\r\n * Directories are services that contain a\r\n * [list]{@link DirectoryModel#list}\r\n * of the names of the\r\n * [BehaviorSubjects]{@link https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject}\r\n * contained in the\r\n * [dir]{@link DirectoryModel#dir}\r\n * object, a 'dir' object that is a Directory of BehaviorSubjects, and a\r\n * [backupObjs]{@link DirectoryModel#backupObjs}\r\n * Directory of JSON objects. A Directory is a specific term for this framework\r\n * where instead of using an array of objects, we use an object where the top-level\r\n * keys are the name of an object, and the value is the object itself. Most\r\n * Angular frameworks and tutorials recomend using arrays of objects for their\r\n * templating, and then use the filter or sort methods to control the display or\r\n * selection of a particular object within the array of objects. But for massive\r\n * arrays, the filter method can be incredibly slow. The DataDirectory contains\r\n * all of the objects that different components will use to share values.\r\n */\r\n@Injectable({\r\n  providedIn: 'root',\r\n})\r\nexport class DataState extends StateModel {}\r\n","// Angular Imports\r\nimport { Injectable } from '@angular/core';\r\n// Model Imports\r\nimport { StateModel } from '../models/state.model';\r\n\r\n@Injectable({\r\n  providedIn: 'root',\r\n})\r\nexport class EventState extends StateModel {}\r\n","// Angular Imports\r\nimport { Injectable } from '@angular/core';\r\n// Model Imports\r\nimport { StateModel } from '../models/state.model';\r\n\r\n@Injectable({\r\n  providedIn: 'root',\r\n})\r\nexport class RulesState extends StateModel {}\r\n","// Angular Imports\r\nimport { Injectable } from '@angular/core';\r\n// Model Imports\r\nimport { StateModel } from '../models/state.model';\r\n\r\n/**\r\n * Directories are services that contain a\r\n * [list]{@link DirectoryModel#list}\r\n * of the names of the\r\n * [BehaviorSubjects]{@link https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject}\r\n * contained in the\r\n * [dir]{@link DirectoryModel#dir}\r\n * object, a 'dir' object that is a Directory of BehaviorSubjects, and a\r\n * [backupObjs]{@link DirectoryModel#backupObjs}\r\n * Directory of JSON objects. A Directory is a specific term for this framework\r\n * where instead of using an array of objects, we use an object where the top-level\r\n * keys are the name of an object, and the value is the object itself. Most\r\n * Angular frameworks and tutorials recomend using arrays of objects for their\r\n * templating, and then use the filter or sort methods to control the display or\r\n * selection of a particular object within the array of objects. But for massive\r\n * arrays, the filter method can be incredibly slow. The DataDirectory contains\r\n * all of the objects that different components will use to share values.\r\n */\r\n@Injectable({\r\n  providedIn: 'root',\r\n})\r\nexport class ServerState extends StateModel {}\r\n","// Angular Imports\r\nimport { Injectable } from '@angular/core';\r\n// Model Imports\r\nimport { StateModel } from '../models/state.model';\r\n\r\n/**\r\n * Directories are services that contain a\r\n * [list]{@link DirectoryModel#list}\r\n * of the names of the\r\n * [BehaviorSubjects]{@link https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject}\r\n * contained in the\r\n * [dir]{@link DirectoryModel#dir}\r\n * object, a 'dir' object that is a Directory of BehaviorSubjects, and a\r\n * [backupObjs]{@link DirectoryModel#backupObjs}\r\n * Directory of JSON objects. A Directory is a specific term for this framework\r\n * where instead of using an array of objects, we use an object where the top-level\r\n * keys are the name of an object, and the value is the object itself. Most\r\n * Angular frameworks and tutorials recomend using arrays of objects for their\r\n * templating, and then use the filter or sort methods to control the display or\r\n * selection of a particular object within the array of objects. But for massive\r\n * arrays, the filter method can be incredibly slow. The DataDirectory contains\r\n * all of the objects that different components will use to share values.\r\n */\r\n@Injectable({\r\n  providedIn: 'root',\r\n})\r\nexport class SettingsState extends StateModel {}\r\n","// Angular Imports\r\nimport { Injectable } from '@angular/core';\r\n// Model Imports\r\nimport { StateModel } from '../models/state.model';\r\n\r\n/**\r\n * Directories are services that contain a\r\n * [list]{@link DirectoryModel#list}\r\n * of the names of the\r\n * [BehaviorSubjects]{@link https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject}\r\n * contained in the\r\n * [dir]{@link DirectoryModel#dir}\r\n * object, a 'dir' object that is a Directory of BehaviorSubjects, and a\r\n * [backupObjs]{@link DirectoryModel#backupObjs}\r\n * Directory of JSON objects. A Directory is a specific term for this framework\r\n * where instead of using an array of objects, we use an object where the top-level\r\n * keys are the name of an object, and the value is the object itself. Most\r\n * Angular frameworks and tutorials recomend using arrays of objects for their\r\n * templating, and then use the filter or sort methods to control the display or\r\n * selection of a particular object within the array of objects. But for massive\r\n * arrays, the filter method can be incredibly slow. The UiDirectory contains\r\n * all of the JSON objects that serve as instructions for components used to\r\n * build themselves. These UI objects are further organized into 'groups' such\r\n * as 'buttons', 'panels, and 'pages'. A component (such as a button) that has\r\n * received a name, can then search the respective group (such as 'buttons') to\r\n * find its own name and assign those instructions to itself.\r\n */\r\n@Injectable({\r\n  providedIn: 'root',\r\n})\r\nexport class UiState extends StateModel {}\r\n","/*\r\n * Public API Surface of gnss-state\r\n */\r\n\r\nexport * from './models/state.model';\r\nexport * from './lib/bp.state';\r\nexport * from './lib/data.state';\r\nexport * from './lib/event.state';\r\nexport * from './lib/rules.state';\r\nexport * from './lib/server.state';\r\nexport * from './lib/settings.state';\r\nexport * from './lib/ui.state';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}