@toolbox-web/grid-angular 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -55
- package/fesm2022/toolbox-web-grid-angular-features-editing.mjs +14 -4
- package/fesm2022/toolbox-web-grid-angular-features-editing.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs +10 -30
- package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-shell.mjs +2 -3
- package/fesm2022/toolbox-web-grid-angular-features-shell.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-tree.mjs +47 -14
- package/fesm2022/toolbox-web-grid-angular-features-tree.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular.mjs +7 -0
- package/fesm2022/toolbox-web-grid-angular.mjs.map +1 -1
- package/package.json +1 -1
- package/types/toolbox-web-grid-angular-features-editing.d.ts +11 -3
- package/types/toolbox-web-grid-angular-features-editing.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-filtering.d.ts +6 -22
- package/types/toolbox-web-grid-angular-features-filtering.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-tree.d.ts +23 -4
- package/types/toolbox-web-grid-angular-features-tree.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular.d.ts +7 -1
- package/types/toolbox-web-grid-angular.d.ts.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolbox-web-grid-angular-features-editing.mjs","sources":["../../../../libs/grid-angular/features/editing/src/grid-column-editor.directive.ts","../../../../libs/grid-angular/features/editing/src/grid-form-array.directive.ts","../../../../libs/grid-angular/features/editing/src/grid-lazy-form.directive.ts","../../../../libs/grid-angular/features/editing/src/structural-editor.directive.ts","../../../../libs/grid-angular/features/editing/src/grid-editing.directive.ts","../../../../libs/grid-angular/features/editing/src/base-grid-editor.ts","../../../../libs/grid-angular/features/editing/src/base-grid-editor-cva.ts","../../../../libs/grid-angular/features/editing/src/base-overlay-editor.ts","../../../../libs/grid-angular/features/editing/src/index.ts","../../../../libs/grid-angular/features/editing/src/toolbox-web-grid-angular-features-editing.ts"],"sourcesContent":["import { contentChild, Directive, effect, ElementRef, inject, TemplateRef } from '@angular/core';\nimport type { AbstractControl } from '@angular/forms';\n\n/**\n * Context object passed to the cell editor template.\n * Contains the cell value, row data, column configuration, and commit/cancel functions.\n * @since 0.1.0\n */\nexport interface GridEditorContext<TValue = unknown, TRow = unknown> {\n /** The cell value for this column */\n $implicit: TValue;\n /** The cell value (explicit binding) */\n value: TValue;\n /** The full row data object */\n row: TRow;\n /** Field name being edited */\n field: string;\n /** The column configuration */\n column: unknown;\n /** Stable row identifier (from `getRowId`). Empty string if no `getRowId` is configured. */\n rowId: string;\n /**\n * Callback function to commit the edited value.\n * Use with Angular event binding: `(commit)=\"onCommit($event)\"`\n */\n onCommit: (value: TValue) => void;\n /**\n * Callback function to cancel editing.\n * Use with Angular event binding: `(cancel)=\"onCancel()\"`\n */\n onCancel: () => void;\n /**\n * Update other fields in this row while the editor is open.\n * Changes trigger `cell-change` events with source `'cascade'`.\n */\n updateRow: (changes: Partial<TRow>) => void;\n /**\n * Register a callback to receive value updates when the cell is modified\n * externally (e.g., via `updateRow()` from another cell's commit).\n *\n * The framework adapter auto-patches `value`/`$implicit` for template editors,\n * but custom components may use this for additional reactivity.\n */\n onValueChange?: (callback: (newValue: TValue) => void) => void;\n /**\n * The FormControl for this cell, if the grid is bound to a FormArray with FormGroups.\n *\n * This allows custom editors to bind directly to the control for validation display:\n * ```html\n * <input *tbwEditor=\"let value; control as ctrl\"\n * [formControl]=\"ctrl\"\n * [class.is-invalid]=\"ctrl?.invalid && ctrl?.touched\" />\n * ```\n *\n * Returns `undefined` if:\n * - The grid is not bound to a FormArray\n * - The FormArray doesn't contain FormGroups\n * - The field doesn't exist in the FormGroup\n */\n control?: AbstractControl;\n}\n\n// Global registry mapping DOM elements to their templates\nconst editorTemplateRegistry = new Map<HTMLElement, TemplateRef<GridEditorContext>>();\n\n/**\n * Gets the editor template registered for a given element.\n * Used by AngularGridAdapter to retrieve templates at render time.\n */\nexport function getEditorTemplate(element: HTMLElement): TemplateRef<GridEditorContext> | undefined {\n return editorTemplateRegistry.get(element);\n}\n\n/**\n * Directive that captures an `<ng-template>` for use as a cell editor.\n *\n * This enables declarative Angular component usage with proper input bindings\n * that satisfy Angular's AOT compiler.\n *\n * ## Usage\n *\n * ```html\n * <tbw-grid-column field=\"status\" editable>\n * <tbw-grid-column-editor>\n * <ng-template let-value let-row=\"row\" let-onCommit=\"onCommit\" let-onCancel=\"onCancel\">\n * <app-status-select\n * [value]=\"value\"\n * [row]=\"row\"\n * (commit)=\"onCommit($event)\"\n * (cancel)=\"onCancel()\"\n * />\n * </ng-template>\n * </tbw-grid-column-editor>\n * </tbw-grid-column>\n * ```\n *\n * The template context provides:\n * - `$implicit` / `value`: The cell value\n * - `row`: The full row data object\n * - `column`: The column configuration\n * - `onCommit`: Callback function to commit the new value\n * - `onCancel`: Callback function to cancel editing\n *\n * Import the directive in your component:\n *\n * ```typescript\n * import { GridColumnEditor } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * imports: [GridColumnEditor],\n * // ...\n * })\n * ```\n *\n * @category Directive\n *\n * @since 0.1.0\n */\n@Directive({ selector: 'tbw-grid-column-editor' })\nexport class GridColumnEditor {\n private elementRef = inject(ElementRef<HTMLElement>);\n\n /**\n * Query for the ng-template content child.\n */\n template = contentChild(TemplateRef<GridEditorContext>);\n\n /** Effect that triggers when the template is available */\n private onTemplateReceived = effect(() => {\n const template = this.template();\n if (template) {\n // Register the template for this element\n editorTemplateRegistry.set(this.elementRef.nativeElement, template);\n }\n });\n\n /**\n * Static type guard for template context.\n * Enables type inference in templates.\n */\n static ngTemplateContextGuard(dir: GridColumnEditor, ctx: unknown): ctx is GridEditorContext {\n return true;\n }\n}\n","import { DestroyRef, Directive, effect, ElementRef, inject, input, OnDestroy, OnInit } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { AbstractControl, FormArray, FormGroup } from '@angular/forms';\nimport type { DataGridElement as GridElement } from '@toolbox-web/grid';\nimport { Subscription } from 'rxjs';\nimport { debounceTime, startWith } from 'rxjs/operators';\n\n/**\n * Interface for EditingPlugin validation methods.\n * We use a minimal interface to avoid importing the full EditingPlugin class.\n */\ninterface EditingPluginValidation {\n setInvalid(rowId: string, field: string, message?: string): void;\n clearInvalid(rowId: string, field: string): void;\n clearRowInvalid(rowId: string): void;\n}\n\n/**\n * Interface for EditingPlugin config to check mode.\n */\ninterface EditingPluginConfig {\n config?: { mode?: 'row' | 'grid' };\n}\n\n/**\n * Context provided to the grid containing form-related information.\n * This can be accessed by other directives to get form controls.\n * @since 0.5.0\n */\nexport interface FormArrayContext {\n /** Get the row data at a specific index */\n getRow<T = unknown>(rowIndex: number): T | null;\n /** Update a field value at a specific row */\n updateField(rowIndex: number, field: string, value: unknown): void;\n /** Get the current form value (all rows) */\n getValue<T = unknown>(): T[];\n /**\n * Get the FormControl for a specific cell.\n * Only available when using FormArray with FormGroup rows.\n *\n * @param rowIndex - The row index\n * @param field - The field name\n * @returns The AbstractControl for the cell, or undefined if not available\n */\n getControl(rowIndex: number, field: string): AbstractControl | undefined;\n /**\n * Whether the grid is backed by a FormArray of FormGroups.\n * When true, `getControl()` will return cell-level controls.\n */\n hasFormGroups: boolean;\n /**\n * Get the FormGroup for a specific row.\n * Only available when using FormArray with FormGroup rows.\n *\n * @param rowIndex - The row index\n * @returns The FormGroup for the row, or undefined if not available\n */\n getRowFormGroup(rowIndex: number): FormGroup | undefined;\n /**\n * Check if a row is valid (all controls in the FormGroup are valid).\n * Returns true if not using FormArray or if the row doesn't exist.\n *\n * @param rowIndex - The row index\n * @returns true if the row is valid, false if any control is invalid\n */\n isRowValid(rowIndex: number): boolean;\n /**\n * Check if a row has been touched (any control in the FormGroup is touched).\n * Returns false if not using FormArray or if the row doesn't exist.\n *\n * @param rowIndex - The row index\n * @returns true if any control in the row is touched\n */\n isRowTouched(rowIndex: number): boolean;\n /**\n * Check if a row is dirty (any control in the FormGroup is dirty).\n * Returns false if not using FormArray or if the row doesn't exist.\n *\n * @param rowIndex - The row index\n * @returns true if any control in the row is dirty\n */\n isRowDirty(rowIndex: number): boolean;\n /**\n * Get validation errors for a specific row.\n * Aggregates errors from all controls in the FormGroup.\n *\n * @param rowIndex - The row index\n * @returns Object with field names as keys and their errors, or null if no errors\n */\n getRowErrors(rowIndex: number): Record<string, unknown> | null;\n}\n\n// Symbol for storing form context on the grid element\nconst FORM_ARRAY_CONTEXT = Symbol('formArrayContext');\n\n/**\n * Gets the FormArrayContext from a grid element, if present.\n * @internal\n * @since 0.5.0\n */\nexport function getFormArrayContext(gridElement: HTMLElement): FormArrayContext | undefined {\n return (gridElement as unknown as Record<symbol, FormArrayContext>)[FORM_ARRAY_CONTEXT];\n}\n\n/**\n * Directive that binds a FormArray directly to the grid.\n *\n * This is the recommended way to integrate tbw-grid with Angular Reactive Forms.\n * Use a FormArray of FormGroups for row-level validation and cell-level control access.\n *\n * ## Usage\n *\n * ```typescript\n * import { Component, inject } from '@angular/core';\n * import { FormBuilder, ReactiveFormsModule } from '@angular/forms';\n * import { Grid, GridFormArray } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * imports: [Grid, GridFormArray, ReactiveFormsModule],\n * template: \\`\n * <form [formGroup]=\"form\">\n * <tbw-grid [formArray]=\"form.controls.rows\" [columns]=\"columns\" />\n * </form>\n * \\`\n * })\n * export class MyComponent {\n * private fb = inject(FormBuilder);\n *\n * form = this.fb.group({\n * rows: this.fb.array([\n * this.fb.group({ name: 'Alice', age: 30 }),\n * this.fb.group({ name: 'Bob', age: 25 }),\n * ])\n * });\n *\n * columns = [\n * { field: 'name', header: 'Name', editable: true },\n * { field: 'age', header: 'Age', editable: true }\n * ];\n * }\n * ```\n *\n * ## How It Works\n *\n * - **FormArray → Grid**: The grid displays the FormArray's value as rows\n * - **Grid → FormArray**: When a cell is edited, the corresponding FormControl is updated\n * - FormArrayContext is available for accessing cell-level controls\n *\n * ## Features\n *\n * - Works naturally with FormArray inside a FormGroup\n * - Provides cell-level FormControl access for validation\n * - Supports row-level validation state aggregation\n * - Automatically syncs FormArray changes to the grid\n *\n * @example\n * ```html\n * <form [formGroup]=\"form\">\n * <tbw-grid [formArray]=\"form.controls.rows\" [columns]=\"columns\" />\n * </form>\n * ```\n *\n * @category Directive\n *\n * @since 0.5.0\n */\n@Directive({\n selector: 'tbw-grid[formArray]',\n})\nexport class GridFormArray implements OnInit, OnDestroy {\n private readonly destroyRef = inject(DestroyRef);\n private elementRef = inject(ElementRef<GridElement>);\n private cellCommitUnsub: (() => void) | null = null;\n private cellCancelUnsub: (() => void) | null = null;\n private rowCommitUnsub: (() => void) | null = null;\n private touchListener: ((e: Event) => void) | null = null;\n private valueChangesSubscription: Subscription | null = null;\n private statusChangesSubscriptions: Subscription[] = [];\n\n /**\n * The FormArray to bind to the grid.\n */\n readonly formArray = input.required<FormArray>();\n\n /**\n * Whether to automatically sync Angular validation state to grid's visual invalid styling.\n *\n * When enabled:\n * - After a cell commit, if the FormControl is invalid, the cell is marked with `setInvalid()`\n * - When a FormControl becomes valid, `clearInvalid()` is called\n * - On `row-commit`, if the row's FormGroup has invalid controls, the commit is prevented\n * - In grid mode: validation state is synced on initial render and updated reactively\n *\n * @default true\n */\n readonly syncValidation = input<boolean>(true);\n\n /**\n * Effect that sets up valueChanges subscription when FormArray changes.\n * This handles both initial binding and when the FormArray reference changes.\n */\n private syncFormArrayToGrid = effect(() => {\n const formArray = this.formArray();\n const grid = this.elementRef.nativeElement;\n if (!grid || !formArray) return;\n\n // Unsubscribe from previous FormArray if any\n this.valueChangesSubscription?.unsubscribe();\n\n // Subscribe to valueChanges to sync grid rows when FormArray content changes.\n // Use startWith to immediately sync the current value.\n // Note: We use getRawValue() to include disabled controls.\n //\n // In grid mode, editors bind directly to FormControls, so every keystroke\n // fires valueChanges. We skip the sync when an editor input is focused to\n // prevent destroying/recreating editors mid-edit (which orphans overlays\n // like mat-autocomplete/mat-select panels and causes focus loss).\n this.valueChangesSubscription = formArray.valueChanges\n .pipe(startWith(formArray.getRawValue()), takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n // Skip sync while an editor is actively focused in the grid.\n // The FormArray already has the latest values via its own controls;\n // re-setting grid.rows would create new object references and trigger\n // an unnecessary render cycle.\n if (this.#isEditorFocused(grid)) return;\n\n grid.rows = formArray.getRawValue();\n });\n });\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n // Store the form context on the grid element for other directives to access\n this.#storeFormContext(grid);\n\n // Intercept cell-commit events to update the FormArray\n this.cellCommitUnsub = grid.on(\n 'cell-commit',\n (detail: { rowIndex: number; field: string; value: unknown; oldValue: unknown; rowId: string }) => {\n this.#handleCellCommit(detail);\n },\n );\n\n // Intercept cell-cancel events to revert FormControls (grid mode Escape)\n this.cellCancelUnsub = grid.on(\n 'cell-cancel',\n (detail: { rowIndex: number; field: string; previousValue: unknown }) => {\n this.#handleCellCancel(detail);\n },\n );\n\n // Intercept row-commit events to prevent if FormGroup is invalid\n this.rowCommitUnsub = grid.on(\n 'row-commit',\n (detail: { rowIndex: number; rowId?: string; changed: boolean }, event: CustomEvent) => {\n if (!this.syncValidation()) return;\n this.#handleRowCommit(event, detail);\n },\n );\n\n // Mark FormArray as touched on first interaction\n this.touchListener = () => {\n this.formArray().markAsTouched();\n // Remove after first touch\n if (this.touchListener) {\n grid.removeEventListener('click', this.touchListener);\n this.touchListener = null;\n }\n };\n grid.addEventListener('click', this.touchListener);\n\n // If in grid mode with syncValidation, set up reactive validation\n // Wait for grid to be ready so we can detect the editing mode\n grid.ready?.().then(() => {\n if (this.syncValidation() && this.#isGridMode()) {\n this.#setupReactiveValidation();\n // Sync initial validation state for all existing controls\n this.#syncAllValidationState();\n }\n });\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n this.cellCommitUnsub?.();\n this.cellCancelUnsub?.();\n this.rowCommitUnsub?.();\n if (this.touchListener) {\n grid.removeEventListener('click', this.touchListener);\n }\n if (this.valueChangesSubscription) {\n this.valueChangesSubscription.unsubscribe();\n }\n // Clean up status change subscriptions (grid mode)\n this.statusChangesSubscriptions.forEach((sub) => sub.unsubscribe());\n this.statusChangesSubscriptions = [];\n\n this.#clearFormContext(grid);\n }\n\n /**\n * Checks if the EditingPlugin is in 'grid' mode.\n */\n #isGridMode(): boolean {\n const grid = this.elementRef.nativeElement;\n if (!grid) return false;\n\n const editingPlugin = grid.getPluginByName?.('editing') as\n | (EditingPluginValidation & EditingPluginConfig)\n | undefined;\n\n return editingPlugin?.config?.mode === 'grid';\n }\n\n /**\n * Checks if a focusable editor element inside the grid currently has focus.\n * Used to skip valueChanges → grid.rows sync while a user is actively editing,\n * preventing editor destruction (which orphans overlay panels like autocomplete/select).\n */\n #isEditorFocused(grid: GridElement): boolean {\n if (!this.#isGridMode()) return false;\n const active = document.activeElement;\n if (!active) return false;\n // Check if the focused element is inside the grid\n return grid.contains(active) && active.closest('.editing') != null;\n }\n\n /**\n * Sets up reactive validation syncing for grid mode.\n * Subscribes to statusChanges on all FormControls to update validation state in real-time.\n */\n #setupReactiveValidation(): void {\n const formArray = this.formArray();\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n // Clean up any existing subscriptions\n this.statusChangesSubscriptions.forEach((sub) => sub.unsubscribe());\n this.statusChangesSubscriptions = [];\n\n // Subscribe to each FormGroup's statusChanges\n for (let rowIndex = 0; rowIndex < formArray.length; rowIndex++) {\n const rowFormGroup = this.#getRowFormGroup(rowIndex);\n if (!rowFormGroup) continue;\n\n // Get the row ID for this row\n const rowId = this.#getRowId(grid, rowIndex);\n if (!rowId) continue;\n\n // Subscribe to status changes for each control in the FormGroup\n Object.keys(rowFormGroup.controls).forEach((field) => {\n const control = rowFormGroup.get(field);\n if (!control) return;\n\n const sub = control.statusChanges.pipe(debounceTime(50), takeUntilDestroyed(this.destroyRef)).subscribe(() => {\n this.#syncControlValidationToGrid(rowId, field, control);\n });\n\n this.statusChangesSubscriptions.push(sub);\n });\n }\n }\n\n /**\n * Syncs validation state for all controls in the FormArray.\n * Called once on init in grid mode to show pre-existing validation errors.\n */\n #syncAllValidationState(): void {\n const formArray = this.formArray();\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n for (let rowIndex = 0; rowIndex < formArray.length; rowIndex++) {\n const rowFormGroup = this.#getRowFormGroup(rowIndex);\n if (!rowFormGroup) continue;\n\n const rowId = this.#getRowId(grid, rowIndex);\n if (!rowId) continue;\n\n Object.keys(rowFormGroup.controls).forEach((field) => {\n const control = rowFormGroup.get(field);\n if (control) {\n this.#syncControlValidationToGrid(rowId, field, control);\n }\n });\n }\n }\n\n /**\n * Gets the row ID for a given row index using the grid's getRowId method.\n */\n #getRowId(grid: GridElement, rowIndex: number): string | undefined {\n try {\n const rows = grid.rows;\n const row = rows?.[rowIndex];\n if (!row) return undefined;\n return grid.getRowId?.(row);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Checks if the FormArray contains FormGroups.\n */\n #isFormArrayOfFormGroups(): boolean {\n const formArray = this.formArray();\n if (formArray.length === 0) return false;\n return formArray.at(0) instanceof FormGroup;\n }\n\n /**\n * Gets the FormGroup at a specific row index.\n */\n #getRowFormGroup(rowIndex: number): FormGroup | undefined {\n const formArray = this.formArray();\n const rowControl = formArray.at(rowIndex);\n return rowControl instanceof FormGroup ? rowControl : undefined;\n }\n\n /**\n * Stores the FormArrayContext on the grid element.\n */\n #storeFormContext(grid: GridElement): void {\n const getRowFormGroup = (rowIndex: number) => this.#getRowFormGroup(rowIndex);\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n\n const context: FormArrayContext = {\n getRow: <T>(rowIndex: number): T | null => {\n const formArray = this.formArray();\n const rowControl = formArray.at(rowIndex);\n return rowControl ? (rowControl.value as T) : null;\n },\n updateField: (rowIndex: number, field: string, value: unknown) => {\n const rowFormGroup = getRowFormGroup(rowIndex);\n if (rowFormGroup) {\n const control = rowFormGroup.get(field);\n if (control) {\n control.setValue(value);\n control.markAsDirty();\n }\n }\n },\n getValue: <T>(): T[] => {\n return this.formArray().getRawValue() as T[];\n },\n get hasFormGroups() {\n return self.#isFormArrayOfFormGroups();\n },\n getControl: (rowIndex: number, field: string): AbstractControl | undefined => {\n const rowFormGroup = getRowFormGroup(rowIndex);\n if (!rowFormGroup) return undefined;\n return rowFormGroup.get(field) ?? undefined;\n },\n getRowFormGroup,\n isRowValid: (rowIndex: number): boolean => {\n const rowFormGroup = getRowFormGroup(rowIndex);\n if (!rowFormGroup) return true;\n return rowFormGroup.valid;\n },\n isRowTouched: (rowIndex: number): boolean => {\n const rowFormGroup = getRowFormGroup(rowIndex);\n if (!rowFormGroup) return false;\n return rowFormGroup.touched;\n },\n isRowDirty: (rowIndex: number): boolean => {\n const rowFormGroup = getRowFormGroup(rowIndex);\n if (!rowFormGroup) return false;\n return rowFormGroup.dirty;\n },\n getRowErrors: (rowIndex: number): Record<string, unknown> | null => {\n const rowFormGroup = getRowFormGroup(rowIndex);\n if (!rowFormGroup) return null;\n\n const errors: Record<string, unknown> = {};\n let hasErrors = false;\n\n Object.keys(rowFormGroup.controls).forEach((field) => {\n const control = rowFormGroup.get(field);\n if (control?.errors) {\n errors[field] = control.errors;\n hasErrors = true;\n }\n });\n\n if (rowFormGroup.errors) {\n errors['_group'] = rowFormGroup.errors;\n hasErrors = true;\n }\n\n return hasErrors ? errors : null;\n },\n };\n (grid as unknown as Record<symbol, FormArrayContext>)[FORM_ARRAY_CONTEXT] = context;\n }\n\n /**\n * Clears the FormArrayContext from the grid element.\n */\n #clearFormContext(grid: GridElement): void {\n delete (grid as unknown as Record<symbol, FormArrayContext>)[FORM_ARRAY_CONTEXT];\n }\n\n /**\n * Handles cell-commit events by updating the FormControl in the FormGroup.\n */\n #handleCellCommit(detail: { rowIndex: number; field: string; value: unknown; rowId: string }): void {\n const { rowIndex, field, value, rowId } = detail;\n\n const rowFormGroup = this.#getRowFormGroup(rowIndex);\n if (rowFormGroup) {\n const control = rowFormGroup.get(field);\n if (control) {\n control.setValue(value);\n control.markAsDirty();\n control.markAsTouched();\n\n // Sync Angular validation state to grid's visual invalid styling\n if (this.syncValidation() && rowId) {\n this.#syncControlValidationToGrid(rowId, field, control);\n }\n }\n }\n }\n\n /**\n * Handles row-commit events - prevents commit if FormGroup has invalid controls.\n */\n #handleRowCommit(event: Event, detail: { rowIndex: number }): void {\n const { rowIndex } = detail;\n const rowFormGroup = this.#getRowFormGroup(rowIndex);\n\n if (rowFormGroup && rowFormGroup.invalid) {\n // Prevent row commit if the FormGroup is invalid\n event.preventDefault();\n }\n }\n\n /**\n * Handles cell-cancel events (grid mode Escape) — reverts the FormControl\n * to the value it had before the edit session began.\n */\n #handleCellCancel(detail: { rowIndex: number; field: string; previousValue: unknown }): void {\n const { rowIndex, field, previousValue } = detail;\n const rowFormGroup = this.#getRowFormGroup(rowIndex);\n\n if (rowFormGroup) {\n const control = rowFormGroup.get(field);\n if (control) {\n control.setValue(previousValue, { emitEvent: false });\n control.markAsPristine();\n }\n }\n }\n\n /**\n * Syncs a FormControl's validation state to the grid's visual invalid styling.\n */\n #syncControlValidationToGrid(rowId: string, field: string, control: AbstractControl): void {\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n // Get EditingPlugin via getPluginByName\n const editingPlugin = grid.getPluginByName?.('editing') as EditingPluginValidation | undefined;\n\n if (!editingPlugin) return;\n\n if (control.invalid) {\n // Get first error message to display\n const errorMessage = this.#getFirstErrorMessage(control);\n editingPlugin.setInvalid(rowId, field, errorMessage);\n } else {\n editingPlugin.clearInvalid(rowId, field);\n }\n }\n\n /**\n * Gets a human-readable error message from the first validation error.\n */\n #getFirstErrorMessage(control: AbstractControl): string {\n const errors = control.errors;\n if (!errors) return '';\n\n const firstKey = Object.keys(errors)[0];\n const error = errors[firstKey];\n\n // Common Angular validators\n switch (firstKey) {\n case 'required':\n return 'This field is required';\n case 'minlength':\n return `Minimum length is ${error.requiredLength}`;\n case 'maxlength':\n return `Maximum length is ${error.requiredLength}`;\n case 'min':\n return `Minimum value is ${error.min}`;\n case 'max':\n return `Maximum value is ${error.max}`;\n case 'email':\n return 'Invalid email address';\n case 'pattern':\n return 'Invalid format';\n default:\n // Custom validators may provide a message property\n return typeof error === 'string' ? error : (error?.message ?? `Validation error: ${firstKey}`);\n }\n }\n}\n","import { Directive, ElementRef, inject, input, OnDestroy, OnInit, output } from '@angular/core';\nimport { AbstractControl, FormGroup } from '@angular/forms';\nimport type { DataGridElement as GridElement } from '@toolbox-web/grid';\nimport type { FormArrayContext } from './grid-form-array.directive';\n\n/**\n * Interface for EditingPlugin validation methods.\n * We use a minimal interface to avoid importing the full EditingPlugin class.\n */\ninterface EditingPluginValidation {\n setInvalid(rowId: string, field: string, message?: string): void;\n clearInvalid(rowId: string, field: string): void;\n clearRowInvalid(rowId: string): void;\n}\n\n// Symbol for storing form context on the grid element (shared with GridFormArray)\nconst FORM_ARRAY_CONTEXT = Symbol('formArrayContext');\n\n/**\n * Gets the FormArrayContext from a grid element, if present.\n * @internal\n * @since 0.11.0\n */\nexport function getLazyFormContext(gridElement: HTMLElement): FormArrayContext | undefined {\n return (gridElement as unknown as Record<symbol, FormArrayContext>)[FORM_ARRAY_CONTEXT];\n}\n\n/**\n * Factory function type for creating FormGroups lazily.\n * Called when a row enters edit mode for the first time.\n *\n * @template TRow The row data type\n * @param row The row data object\n * @param rowIndex The row index in the grid\n * @returns A FormGroup for the row (only include editable fields)\n * @since 0.11.0\n */\nexport type LazyFormFactory<TRow = unknown> = (row: TRow, rowIndex: number) => FormGroup;\n\n/**\n * Event emitted when a row's form values have changed.\n * @since 0.11.0\n */\nexport interface RowFormChangeEvent<TRow = unknown> {\n /** The row index */\n rowIndex: number;\n /** The row ID (if available) */\n rowId?: string;\n /** The original row data */\n row: TRow;\n /** The FormGroup for this row */\n formGroup: FormGroup;\n /** The current form values */\n values: Partial<TRow>;\n /** Whether the form is valid */\n valid: boolean;\n /** Whether the form is dirty */\n dirty: boolean;\n}\n\n/**\n * Directive that provides lazy FormGroup creation for grid editing.\n *\n * Unlike `GridFormArray` which creates all FormGroups upfront, this directive\n * creates FormGroups on-demand only when a row enters edit mode. This provides\n * much better performance for large datasets while still enabling full\n * Angular Reactive Forms integration.\n *\n * ## Key Benefits\n *\n * - **Performance**: Only creates FormGroups for rows being edited (20-100x fewer controls)\n * - **Same DX**: Editors still receive `control` in their context for validation\n * - **Memory efficient**: FormGroups are cleaned up when rows exit edit mode\n *\n * ## Usage\n *\n * ```typescript\n * import { Component, inject, signal } from '@angular/core';\n * import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';\n * import { Grid, GridLazyForm, TbwEditor } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * imports: [Grid, GridLazyForm, TbwEditor, ReactiveFormsModule],\n * template: \\`\n * <tbw-grid\n * [rows]=\"employees()\"\n * [lazyForm]=\"createRowForm\"\n * [gridConfig]=\"config\">\n *\n * <tbw-grid-column field=\"firstName\">\n * <input *tbwEditor=\"let _; control as ctrl\"\n * [formControl]=\"ctrl\"\n * [class.is-invalid]=\"ctrl?.invalid && ctrl?.touched\" />\n * </tbw-grid-column>\n * </tbw-grid>\n * \\`\n * })\n * export class MyComponent {\n * private fb = inject(FormBuilder);\n * employees = signal(generateEmployees(1000));\n *\n * // Factory called when editing starts - only include editable fields!\n * createRowForm = (row: Employee): FormGroup => this.fb.group({\n * firstName: [row.firstName, Validators.required],\n * lastName: [row.lastName, Validators.minLength(2)],\n * salary: [row.salary, [Validators.required, Validators.min(0)]],\n * });\n *\n * gridConfig = { columns: [...] };\n * }\n * ```\n *\n * ## How It Works\n *\n * 1. Rows come from `[rows]` input (plain data array)\n * 2. When a cell enters edit mode, the FormGroup is created lazily\n * 3. Editors receive the FormControl in their template context\n * 4. On commit, FormGroup values are synced back to the row\n * 5. FormGroup is cleaned up when the row exits edit mode (configurable)\n *\n * ## Performance Comparison\n *\n * | Rows | GridFormArray (20 fields) | GridLazyForm |\n * |------|---------------------------|--------------|\n * | 100 | 2,000 controls | ~20 controls |\n * | 500 | 10,000 controls | ~20 controls |\n * | 1000 | 20,000 controls | ~20 controls |\n *\n * @example\n * ```html\n * <tbw-grid [rows]=\"employees()\" [lazyForm]=\"createRowForm\" [gridConfig]=\"gridConfig\" />\n * ```\n *\n * @see GridFormArray For small datasets with full upfront validation\n * @category Directive\n *\n * @since 0.11.0\n */\n@Directive({\n selector: 'tbw-grid[lazyForm]',\n})\nexport class GridLazyForm<TRow = unknown> implements OnInit, OnDestroy {\n private elementRef = inject(ElementRef<GridElement<TRow>>);\n\n // Cache of FormGroups by row reference\n private formGroupCache = new Map<TRow, FormGroup>();\n // Map from row reference to rowIndex (needed for getControl)\n private rowIndexMap = new Map<TRow, number>();\n // Track which row is currently being edited\n private editingRowIndex: number | null = null;\n\n private cellCommitUnsub: (() => void) | null = null;\n private rowCommitUnsub: (() => void) | null = null;\n private rowsChangeUnsub: (() => void) | null = null;\n\n /**\n * Factory function to create a FormGroup for a row.\n * Called lazily when the row first enters edit mode.\n *\n * @example\n * ```typescript\n * createRowForm = (row: Employee): FormGroup => this.fb.group({\n * firstName: [row.firstName, Validators.required],\n * lastName: [row.lastName],\n * salary: [row.salary, [Validators.min(0)]],\n * });\n * ```\n */\n readonly lazyForm = input.required<LazyFormFactory<TRow>>();\n\n /**\n * Whether to automatically sync Angular validation state to grid's visual invalid styling.\n *\n * When enabled:\n * - After a cell commit, if the FormControl is invalid, the cell is marked with `setInvalid()`\n * - When a FormControl becomes valid, `clearInvalid()` is called\n * - On `row-commit`, if the row's FormGroup has invalid controls, the commit is prevented\n *\n * @default true\n */\n readonly syncValidation = input<boolean>(true);\n\n /**\n * Whether to keep FormGroups cached after a row exits edit mode.\n *\n * - `true`: FormGroups are kept, preserving dirty/touched state across edit sessions\n * - `false`: FormGroups are disposed when the row exits edit mode (default)\n *\n * @default false\n */\n readonly keepFormGroups = input<boolean>(false);\n\n /**\n * Emitted when a row's form values change.\n * Useful for auto-save, validation display, or syncing to external state.\n */\n readonly rowFormChange = output<RowFormChangeEvent<TRow>>();\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n // Store the form context for AngularGridAdapter to access\n this.#storeFormContext(grid);\n\n // Listen for cell-commit to update FormControl and sync validation\n this.cellCommitUnsub = grid.on(\n 'cell-commit',\n (detail: { rowIndex: number; field: string; value: unknown; oldValue: unknown; rowId: string }) => {\n this.#handleCellCommit(detail);\n },\n );\n\n // Listen for row-commit to sync FormGroup values back to row and cleanup\n this.rowCommitUnsub = grid.on('row-commit', (detail: { rowIndex: number; rowId?: string }, event: CustomEvent) => {\n this.#handleRowCommit(event, detail);\n });\n\n // Listen for rows-change to update row index mappings\n this.rowsChangeUnsub = grid.on('rows-change', () => {\n this.#updateRowIndexMap();\n });\n\n // Initial row index mapping\n this.#updateRowIndexMap();\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n this.cellCommitUnsub?.();\n this.rowCommitUnsub?.();\n this.rowsChangeUnsub?.();\n\n this.#clearFormContext(grid);\n this.formGroupCache.clear();\n this.rowIndexMap.clear();\n }\n\n // #region FormArrayContext Implementation\n\n /**\n * Gets or creates the FormGroup for a row.\n * This is the core lazy initialization logic.\n */\n #getOrCreateFormGroup(row: TRow, rowIndex: number): FormGroup {\n let formGroup = this.formGroupCache.get(row);\n if (!formGroup) {\n const factory = this.lazyForm();\n formGroup = factory(row, rowIndex);\n this.formGroupCache.set(row, formGroup);\n this.rowIndexMap.set(row, rowIndex);\n }\n return formGroup;\n }\n\n /**\n * Gets the FormGroup for a row if it exists (without creating).\n */\n #getRowFormGroup(rowIndex: number): FormGroup | undefined {\n const grid = this.elementRef.nativeElement;\n const rows = grid?.rows;\n if (!rows || rowIndex < 0 || rowIndex >= rows.length) return undefined;\n\n const row = rows[rowIndex];\n return this.formGroupCache.get(row);\n }\n\n /**\n * Stores the FormArrayContext on the grid element.\n * This uses the same interface as GridFormArray for compatibility.\n */\n #storeFormContext(grid: GridElement<TRow>): void {\n const context: FormArrayContext = {\n getRow: <T>(rowIndex: number): T | null => {\n const rows = grid.rows;\n if (!rows || rowIndex < 0 || rowIndex >= rows.length) return null;\n return rows[rowIndex] as unknown as T;\n },\n\n updateField: (rowIndex: number, field: string, value: unknown) => {\n const formGroup = this.#getRowFormGroup(rowIndex);\n if (formGroup) {\n const control = formGroup.get(field);\n if (control) {\n control.setValue(value);\n control.markAsDirty();\n }\n }\n },\n\n getValue: <T>(): T[] => {\n return (grid.rows ?? []) as unknown as T[];\n },\n\n // Always true for lazy forms - we create FormGroups on demand\n hasFormGroups: true,\n\n getControl: (rowIndex: number, field: string): AbstractControl | undefined => {\n const rows = grid.rows;\n if (!rows || rowIndex < 0 || rowIndex >= rows.length) return undefined;\n\n const row = rows[rowIndex] as TRow;\n // LAZY: Create the FormGroup when first needed\n const formGroup = this.#getOrCreateFormGroup(row, rowIndex);\n return formGroup.get(field) ?? undefined;\n },\n\n getRowFormGroup: (rowIndex: number): FormGroup | undefined => {\n const rows = grid.rows;\n if (!rows || rowIndex < 0 || rowIndex >= rows.length) return undefined;\n\n const row = rows[rowIndex] as TRow;\n // LAZY: Create the FormGroup when first needed\n return this.#getOrCreateFormGroup(row, rowIndex);\n },\n\n isRowValid: (rowIndex: number): boolean => {\n const formGroup = this.#getRowFormGroup(rowIndex);\n // If no FormGroup exists yet, consider it valid (not edited)\n if (!formGroup) return true;\n return formGroup.valid;\n },\n\n isRowTouched: (rowIndex: number): boolean => {\n const formGroup = this.#getRowFormGroup(rowIndex);\n if (!formGroup) return false;\n return formGroup.touched;\n },\n\n isRowDirty: (rowIndex: number): boolean => {\n const formGroup = this.#getRowFormGroup(rowIndex);\n if (!formGroup) return false;\n return formGroup.dirty;\n },\n\n getRowErrors: (rowIndex: number): Record<string, unknown> | null => {\n const formGroup = this.#getRowFormGroup(rowIndex);\n if (!formGroup) return null;\n\n const errors: Record<string, unknown> = {};\n let hasErrors = false;\n\n Object.keys(formGroup.controls).forEach((field) => {\n const control = formGroup.get(field);\n if (control?.errors) {\n errors[field] = control.errors;\n hasErrors = true;\n }\n });\n\n if (formGroup.errors) {\n errors['_group'] = formGroup.errors;\n hasErrors = true;\n }\n\n return hasErrors ? errors : null;\n },\n };\n\n (grid as unknown as Record<symbol, FormArrayContext>)[FORM_ARRAY_CONTEXT] = context;\n }\n\n /**\n * Clears the FormArrayContext from the grid element.\n */\n #clearFormContext(grid: GridElement<TRow>): void {\n delete (grid as unknown as Record<symbol, FormArrayContext>)[FORM_ARRAY_CONTEXT];\n }\n\n // #endregion\n\n // #region Event Handlers\n\n /**\n * Updates the row index map when rows change.\n * This ensures we can find FormGroups by row reference after sorting/filtering.\n */\n #updateRowIndexMap(): void {\n const grid = this.elementRef.nativeElement;\n const rows = grid?.rows;\n if (!rows) return;\n\n this.rowIndexMap.clear();\n rows.forEach((row: TRow, index: number) => {\n if (this.formGroupCache.has(row)) {\n this.rowIndexMap.set(row, index);\n }\n });\n }\n\n /**\n * Handles cell-commit events by updating the FormControl in the FormGroup.\n */\n #handleCellCommit(detail: { rowIndex: number; field: string; value: unknown; rowId: string }): void {\n const { rowIndex, field, value, rowId } = detail;\n\n const formGroup = this.#getRowFormGroup(rowIndex);\n if (formGroup) {\n const control = formGroup.get(field);\n if (control) {\n control.setValue(value);\n control.markAsDirty();\n control.markAsTouched();\n\n // Sync Angular validation state to grid's visual invalid styling\n if (this.syncValidation() && rowId) {\n this.#syncControlValidationToGrid(rowId, field, control);\n }\n\n // Emit change event\n const grid = this.elementRef.nativeElement;\n const row = grid?.rows?.[rowIndex];\n if (row) {\n this.rowFormChange.emit({\n rowIndex,\n rowId,\n row,\n formGroup,\n values: formGroup.value,\n valid: formGroup.valid,\n dirty: formGroup.dirty,\n });\n }\n }\n }\n }\n\n /**\n * Handles row-commit events.\n * - Prevents commit if FormGroup is invalid (when syncValidation is true)\n * - Syncs FormGroup values back to the row\n * - Cleans up FormGroup if keepFormGroups is false\n */\n #handleRowCommit(event: Event, detail: { rowIndex: number; rowId?: string }): void {\n const { rowIndex, rowId } = detail;\n const grid = this.elementRef.nativeElement;\n const rows = grid?.rows;\n if (!rows || rowIndex < 0 || rowIndex >= rows.length) return;\n\n const row = rows[rowIndex];\n const formGroup = this.formGroupCache.get(row);\n\n if (!formGroup) return;\n\n // Prevent commit if invalid (when syncValidation is enabled)\n if (this.syncValidation() && formGroup.invalid) {\n // Mark all controls as touched to show validation errors\n formGroup.markAllAsTouched();\n event.preventDefault();\n return;\n }\n\n // Sync FormGroup values back to the row object\n if (formGroup.dirty) {\n const formValue = formGroup.value;\n Object.keys(formValue).forEach((field) => {\n if (field in row) {\n (row as Record<string, unknown>)[field] = formValue[field];\n }\n });\n }\n\n // Clean up FormGroup if not keeping them\n if (!this.keepFormGroups()) {\n this.formGroupCache.delete(row);\n this.rowIndexMap.delete(row);\n\n // Clear any validation state in the grid\n if (rowId) {\n const editingPlugin = grid.getPluginByName?.('editing') as EditingPluginValidation | undefined;\n editingPlugin?.clearRowInvalid(rowId);\n }\n }\n }\n\n // #endregion\n\n // #region Validation Sync\n\n /**\n * Syncs a FormControl's validation state to the grid's visual invalid styling.\n */\n #syncControlValidationToGrid(rowId: string, field: string, control: AbstractControl): void {\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n const editingPlugin = grid.getPluginByName?.('editing') as EditingPluginValidation | undefined;\n\n if (!editingPlugin) return;\n\n if (control.invalid) {\n const errorMessage = this.#getFirstErrorMessage(control);\n editingPlugin.setInvalid(rowId, field, errorMessage);\n } else {\n editingPlugin.clearInvalid(rowId, field);\n }\n }\n\n /**\n * Gets a human-readable error message from the first validation error.\n */\n #getFirstErrorMessage(control: AbstractControl): string {\n const errors = control.errors;\n if (!errors) return '';\n\n const firstKey = Object.keys(errors)[0];\n const error = errors[firstKey];\n\n switch (firstKey) {\n case 'required':\n return 'This field is required';\n case 'minlength':\n return `Minimum length is ${error.requiredLength}`;\n case 'maxlength':\n return `Maximum length is ${error.requiredLength}`;\n case 'min':\n return `Minimum value is ${error.min}`;\n case 'max':\n return `Maximum value is ${error.max}`;\n case 'email':\n return 'Invalid email address';\n case 'pattern':\n return 'Invalid format';\n default:\n return typeof error === 'string' ? error : (error?.message ?? `Validation error: ${firstKey}`);\n }\n }\n\n // #endregion\n\n // #region Public API\n\n /**\n * Gets the FormGroup for a row, if it exists.\n * Unlike the context methods, this does NOT create a FormGroup lazily.\n *\n * @param rowIndex The row index\n * @returns The FormGroup or undefined\n */\n getFormGroup(rowIndex: number): FormGroup | undefined {\n return this.#getRowFormGroup(rowIndex);\n }\n\n /**\n * Gets all cached FormGroups.\n * Useful for bulk validation or inspection.\n *\n * @returns Map of row objects to their FormGroups\n */\n getAllFormGroups(): ReadonlyMap<TRow, FormGroup> {\n return this.formGroupCache;\n }\n\n /**\n * Clears all cached FormGroups.\n * Useful when the underlying data changes significantly.\n */\n clearAllFormGroups(): void {\n this.formGroupCache.clear();\n this.rowIndexMap.clear();\n }\n\n /**\n * Validates all currently cached FormGroups.\n *\n * @returns true if all FormGroups are valid, false otherwise\n */\n validateAll(): boolean {\n for (const formGroup of this.formGroupCache.values()) {\n if (formGroup.invalid) {\n formGroup.markAllAsTouched();\n return false;\n }\n }\n return true;\n }\n\n // #endregion\n}\n","import { Directive, effect, ElementRef, inject, OnDestroy, TemplateRef } from '@angular/core';\nimport type { AbstractControl } from '@angular/forms';\nimport { getEditorTemplate } from './grid-column-editor.directive';\n\n/**\n * Context type for structural editor directives with `any` defaults.\n * This provides better ergonomics in templates without requiring explicit type annotations.\n *\n * @internal Use `GridEditorContext` in application code for stricter typing.\n * @since 0.1.1\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface StructuralEditorContext<TValue = any, TRow = any> {\n /** The cell value for this column */\n $implicit: TValue;\n /** The cell value (explicit binding) */\n value: TValue;\n /** The full row data object */\n row: TRow;\n /** The column configuration */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n column: any;\n /**\n * Callback function to commit the edited value.\n */\n onCommit: (value: TValue) => void;\n /**\n * Callback function to cancel editing.\n */\n onCancel: () => void;\n /**\n * The FormControl for this cell, if the grid is bound to a FormArray with FormGroups.\n *\n * Returns `undefined` if:\n * - The grid is not bound to a FormArray\n * - The FormArray doesn't contain FormGroups\n * - The field doesn't exist in the FormGroup\n */\n control?: AbstractControl;\n}\n\n// Registry for structural editor templates\nconst structuralEditorRegistry = new Map<HTMLElement, TemplateRef<StructuralEditorContext>>();\n\n/**\n * Gets the editor template registered by the structural directive for a given column element.\n * Falls back to the non-structural directive registry.\n */\nexport function getStructuralEditorTemplate(\n columnElement: HTMLElement,\n): TemplateRef<StructuralEditorContext> | undefined {\n // First check structural directive registry\n const template = structuralEditorRegistry.get(columnElement);\n if (template) return template;\n\n // Fall back to the nested element registry\n const editorEl = columnElement.querySelector('tbw-grid-column-editor');\n if (editorEl) {\n return getEditorTemplate(editorEl as HTMLElement) as TemplateRef<StructuralEditorContext> | undefined;\n }\n return undefined;\n}\n\n/**\n * Structural directive for cell editor rendering.\n *\n * This provides a cleaner syntax for defining custom cell editors without\n * the nested `<tbw-grid-column-editor>` and `<ng-template>` boilerplate.\n *\n * ## Usage\n *\n * ```html\n * <!-- Instead of this verbose syntax: -->\n * <tbw-grid-column field=\"status\">\n * <tbw-grid-column-editor>\n * <ng-template let-value let-onCommit=\"onCommit\" let-onCancel=\"onCancel\">\n * <app-status-editor [value]=\"value\" (commit)=\"onCommit($event)\" (cancel)=\"onCancel()\" />\n * </ng-template>\n * </tbw-grid-column-editor>\n * </tbw-grid-column>\n *\n * <!-- Use this cleaner syntax (with auto-wiring - no explicit bindings needed!): -->\n * <tbw-grid-column field=\"status\">\n * <app-status-editor *tbwEditor=\"let value\" [value]=\"value\" />\n * </tbw-grid-column>\n * ```\n *\n * ## Template Context\n *\n * The structural directive provides the same context as `GridColumnEditor`:\n * - `$implicit` / `value`: The cell value\n * - `row`: The full row data object\n * - `column`: The column configuration\n * - `onCommit`: Callback function to commit the new value (optional - auto-wired if component emits `commit` event)\n * - `onCancel`: Callback function to cancel editing (optional - auto-wired if component emits `cancel` event)\n *\n * ## Import\n *\n * ```typescript\n * import { TbwEditor } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * imports: [TbwEditor],\n * // ...\n * })\n * ```\n *\n * @example\n * ```html\n * <tbw-grid-column field=\"status\" editable>\n * <app-status-editor *tbwEditor=\"let value\" [value]=\"value\" />\n * </tbw-grid-column>\n * ```\n *\n * @category Directive\n * @since 0.1.1\n */\n@Directive({ selector: '[tbwEditor]' })\nexport class TbwEditor implements OnDestroy {\n private template = inject(TemplateRef<StructuralEditorContext>);\n private elementRef = inject(ElementRef<HTMLElement>);\n private columnElement: HTMLElement | null = null;\n\n constructor() {\n effect(() => {\n this.registerTemplate();\n });\n }\n\n private registerTemplate(): void {\n // Find the parent tbw-grid-column or tbw-grid-type element\n let parent = this.elementRef.nativeElement?.parentElement;\n while (parent && parent.tagName !== 'TBW-GRID-COLUMN' && parent.tagName !== 'TBW-GRID-TYPE') {\n parent = parent.parentElement;\n }\n\n if (parent) {\n this.columnElement = parent;\n structuralEditorRegistry.set(parent, this.template);\n }\n }\n\n ngOnDestroy(): void {\n if (this.columnElement) {\n structuralEditorRegistry.delete(this.columnElement);\n }\n }\n\n /**\n * Static type guard for template context.\n * Uses `any` defaults for ergonomic template usage.\n */\n static ngTemplateContextGuard(dir: TbwEditor, ctx: unknown): ctx is StructuralEditorContext {\n return true;\n }\n}\n","/**\n * `GridEditingDirective` — owns `[editing]` and the editing-specific\n * outputs on `<tbw-grid>`. The shared outputs `cellChange` and `dataChange`\n * stay on `Grid` because they are emitted by multiple sources, not just\n * the editing plugin. See `GridFilteringDirective` for full rationale.\n *\n * Output type compatibility note: this directive uses the Angular adapter\n * wrapper types `CellCommitEvent` / `RowCommitEvent` (re-exported from the\n * package barrel) to stay binary-compatible with apps migrating from the\n * deprecated bindings on `Grid`.\n *\n * @category Directive\n */\nimport { Directive, ElementRef, inject, input, OnDestroy, OnInit, output } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport {\n type CellCommitEvent,\n claimEvent,\n registerFeatureClaim,\n type RowCommitEvent,\n unclaimEvent,\n unregisterFeatureClaim,\n} from '@toolbox-web/grid-angular';\nimport type {\n BeforeEditCloseDetail,\n CellCancelDetail,\n ChangedRowsResetDetail,\n DirtyChangeDetail,\n EditCloseDetail,\n EditingConfig,\n EditOpenDetail,\n} from '@toolbox-web/grid/plugins/editing';\n\n/**\n * Owns the binding(s) `[editing], [cellCommit], [cellCancel], [rowCommit], [changedRowsReset], [editOpen], [beforeEditClose], [editClose], [dirtyChange]` on `<tbw-grid>` for the matching feature plugin. See `GridFilteringDirective` for the full rationale.\n *\n * @category Directive\n */\n@Directive({\n selector:\n 'tbw-grid[editing], tbw-grid[cellCommit], tbw-grid[cellCancel], tbw-grid[rowCommit], tbw-grid[changedRowsReset], tbw-grid[editOpen], tbw-grid[beforeEditClose], tbw-grid[editClose], tbw-grid[dirtyChange]',\n standalone: true,\n})\nexport class GridEditingDirective implements OnInit, OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n readonly editing = input<boolean | 'click' | 'dblclick' | 'manual' | EditingConfig>();\n readonly cellCommit = output<CellCommitEvent>();\n readonly cellCancel = output<CellCancelDetail>();\n readonly rowCommit = output<RowCommitEvent>();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly changedRowsReset = output<ChangedRowsResetDetail<any>>();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly editOpen = output<EditOpenDetail<any>>();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly beforeEditClose = output<BeforeEditCloseDetail<any>>();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly editClose = output<EditCloseDetail<any>>();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly dirtyChange = output<DirtyChangeDetail<any>>();\n\n private readonly listeners = new Map<string, (e: Event) => void>();\n private static readonly EVENTS = [\n 'cell-commit',\n 'cell-cancel',\n 'row-commit',\n 'changed-rows-reset',\n 'edit-open',\n 'before-edit-close',\n 'edit-close',\n 'dirty-change',\n ] as const;\n\n constructor() {\n const grid = this.elementRef.nativeElement;\n registerFeatureClaim(grid, 'editing', () => this.editing());\n for (const ev of GridEditingDirective.EVENTS) claimEvent(grid, ev);\n }\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n const wire = <T>(name: string, out: { emit: (v: T) => void }): void => {\n const l = (e: Event): void => out.emit((e as CustomEvent<T>).detail);\n grid.addEventListener(name, l);\n this.listeners.set(name, l);\n };\n wire<CellCommitEvent>('cell-commit', this.cellCommit);\n wire<CellCancelDetail>('cell-cancel', this.cellCancel);\n wire<RowCommitEvent>('row-commit', this.rowCommit);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n wire<ChangedRowsResetDetail<any>>('changed-rows-reset', this.changedRowsReset);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n wire<EditOpenDetail<any>>('edit-open', this.editOpen);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n wire<BeforeEditCloseDetail<any>>('before-edit-close', this.beforeEditClose);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n wire<EditCloseDetail<any>>('edit-close', this.editClose);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n wire<DirtyChangeDetail<any>>('dirty-change', this.dirtyChange);\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n for (const [name, l] of this.listeners) grid.removeEventListener(name, l);\n this.listeners.clear();\n unregisterFeatureClaim(grid, 'editing');\n for (const ev of GridEditingDirective.EVENTS) unclaimEvent(grid, ev);\n }\n}\n","import { afterNextRender, computed, DestroyRef, Directive, ElementRef, inject, input, output } from '@angular/core';\nimport type { AbstractControl } from '@angular/forms';\nimport type { ColumnConfig } from '@toolbox-web/grid';\n\n/**\n * Base class for grid cell editors.\n *\n * Provides common functionality for Angular cell editors:\n * - Automatic value resolution from FormControl or value input\n * - Common inputs (value, row, column, control)\n * - Common outputs (commit, cancel)\n * - Validation state helpers\n *\n * ## Usage\n *\n * ```typescript\n * import { Component } from '@angular/core';\n * import { BaseGridEditor } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * selector: 'app-my-editor',\n * template: \\`\n * <input\n * [value]=\"currentValue()\"\n * [class.is-invalid]=\"isInvalid()\"\n * (input)=\"commitValue($event.target.value)\"\n * (keydown.escape)=\"cancelEdit()\"\n * />\n * @if (hasErrors()) {\n * <div class=\"error\">{{ firstErrorMessage() }}</div>\n * }\n * \\`\n * })\n * export class MyEditorComponent extends BaseGridEditor<MyRow, string> {\n * // Override to customize error messages\n * protected override getErrorMessage(errorKey: string): string {\n * if (errorKey === 'required') return 'This field is required';\n * if (errorKey === 'minlength') return 'Too short';\n * return super.getErrorMessage(errorKey);\n * }\n * }\n * ```\n *\n * ## Template Syntax\n *\n * When using the base class, you only need to pass the control:\n *\n * ```html\n * <tbw-grid-column field=\"name\">\n * <app-my-editor *tbwEditor=\"let _; control as control\" [control]=\"control\" />\n * </tbw-grid-column>\n * ```\n *\n * Or without FormArray binding (fallback to value):\n *\n * ```html\n * <tbw-grid-column field=\"name\">\n * <app-my-editor *tbwEditor=\"let value\" [value]=\"value\" />\n * </tbw-grid-column>\n * ```\n *\n * @typeParam TRow - The row data type\n * @typeParam TValue - The cell value type\n *\n * @since 0.5.0\n */\n@Directive()\nexport abstract class BaseGridEditor<TRow = unknown, TValue = unknown> {\n protected readonly elementRef = inject(ElementRef);\n private readonly _destroyRef = inject(DestroyRef);\n\n /** Cleanup function for the edit-close listener */\n private _editCloseCleanup: (() => void) | null = null;\n\n // ============================================================================\n // Inputs\n // ============================================================================\n\n /**\n * The cell value. Used when FormControl is not available.\n * When a FormControl is provided, value is derived from control.value instead.\n */\n readonly value = input<TValue>();\n\n /**\n * The full row data object.\n */\n readonly row = input<TRow>();\n\n /**\n * The column configuration.\n */\n readonly column = input<ColumnConfig<TRow>>();\n\n /**\n * The FormControl for this cell, if the grid is bound to a FormArray.\n * When provided, the editor uses control.value instead of the value input.\n */\n readonly control = input<AbstractControl>();\n\n // ============================================================================\n // Outputs\n // ============================================================================\n\n /**\n * Emits when the user commits a new value.\n * Emits `null` when a nullable field is cleared.\n */\n readonly commit = output<TValue | null>();\n\n /**\n * Emits when the user cancels editing.\n */\n readonly cancel = output<void>();\n\n // ============================================================================\n // Computed State\n // ============================================================================\n\n /**\n * The current value, derived from FormControl if available, otherwise from value input.\n * This is the recommended way to get the current value in your editor template.\n */\n readonly currentValue = computed<TValue | undefined>(() => {\n const ctrl = this.control();\n if (ctrl) {\n return ctrl.value as TValue;\n }\n return this.value();\n });\n\n /**\n * Whether the control is invalid (has validation errors).\n * Returns false if no FormControl is available.\n */\n readonly isInvalid = computed(() => {\n return this.control()?.invalid ?? false;\n });\n\n /**\n * Whether the control is dirty (has been modified).\n * Returns false if no FormControl is available.\n */\n readonly isDirty = computed(() => {\n return this.control()?.dirty ?? false;\n });\n\n /**\n * Whether the control has been touched.\n * Returns false if no FormControl is available.\n */\n readonly isTouched = computed(() => {\n return this.control()?.touched ?? false;\n });\n\n /**\n * Whether the control has any validation errors.\n */\n readonly hasErrors = computed(() => {\n const ctrl = this.control();\n return ctrl?.errors != null && Object.keys(ctrl.errors).length > 0;\n });\n\n /**\n * The first error message from the control's validation errors.\n * Returns an empty string if no errors.\n */\n readonly firstErrorMessage = computed(() => {\n const ctrl = this.control();\n if (!ctrl?.errors) return '';\n\n const firstKey = Object.keys(ctrl.errors)[0];\n return this.getErrorMessage(firstKey, ctrl.errors[firstKey]);\n });\n\n /**\n * All error messages from the control's validation errors.\n */\n readonly allErrorMessages = computed(() => {\n const ctrl = this.control();\n if (!ctrl?.errors) return [];\n\n return Object.entries(ctrl.errors).map(([key, value]) => this.getErrorMessage(key, value));\n });\n\n // ============================================================================\n // Lifecycle\n // ============================================================================\n\n constructor() {\n afterNextRender(() => this._initEditCloseListener());\n this._destroyRef.onDestroy(() => {\n this._editCloseCleanup?.();\n this._editCloseCleanup = null;\n });\n }\n\n private _initEditCloseListener(): void {\n const grid = this.elementRef.nativeElement.closest('tbw-grid, [data-tbw-grid]') as\n | import('@toolbox-web/grid').DataGridElement\n | null;\n if (!grid) return;\n\n let unsubBefore: (() => void) | undefined;\n let unsubClose: (() => void) | undefined;\n\n unsubBefore = grid.on('before-edit-close', () => {\n this.onBeforeEditClose();\n unsubBefore?.();\n unsubBefore = undefined;\n });\n\n unsubClose = grid.on('edit-close', () => {\n this.onEditClose();\n unsubClose?.();\n unsubClose = undefined;\n });\n\n this._editCloseCleanup = () => {\n unsubBefore?.();\n unsubClose?.();\n };\n }\n\n // ============================================================================\n // Methods\n // ============================================================================\n\n /**\n * Whether this editor's cell is the currently focused cell.\n *\n * In row editing mode the grid creates editors for every editable cell\n * in the row simultaneously. Use this to conditionally auto-focus inputs\n * or open panels only in the active cell.\n *\n * Performs a synchronous DOM check — safe to call from `ngAfterViewInit`.\n */\n protected isCellFocused(): boolean {\n return this.elementRef.nativeElement.closest('[part=\"cell\"]')?.classList.contains('cell-focus') ?? false;\n }\n\n /**\n * Called **before** the grid clears editing state and destroys editor DOM.\n *\n * At this point the commit callback is still active, so subclasses can\n * call {@link commitValue} to flush any pending/deferred values.\n *\n * This fires only on the **commit** path (not on revert/cancel).\n * Use {@link onEditClose} for cleanup that should happen on both paths.\n */\n protected onBeforeEditClose(): void {\n // Default: no-op. Subclasses override to flush pending values.\n }\n\n /**\n * Called when the grid ends the editing session for this cell.\n *\n * Override to perform cleanup such as closing overlay panels, autocomplete\n * dropdowns, or other floating UI that lives at `<body>` level and would\n * otherwise persist after the editor DOM is removed.\n *\n * The listener is set up automatically via `afterNextRender` — no manual\n * wiring required.\n */\n protected onEditClose(): void {\n // Default: no-op. Subclasses override.\n }\n\n /**\n * Called by the grid adapter when the cell value changes externally\n * (e.g., via `updateRow()` cascade or undo/redo).\n *\n * Override in subclasses to reset internal state (search text, selection\n * flags, etc.) so the editor displays the updated value.\n *\n * This runs **synchronously** before the value input is updated, giving\n * the editor a chance to clear stale state before the next change-detection\n * pass re-reads the template.\n *\n * @param _newVal The new cell value being pushed from the grid\n */\n onExternalValueChange(_newVal: TValue): void {\n // Default: no-op. Subclasses override as needed.\n }\n\n /**\n * Commit a new value. Emits the commit output AND dispatches a DOM event.\n * The DOM event enables the grid's auto-wiring to catch the commit.\n * Call this when the user confirms their edit.\n */\n commitValue(newValue: TValue | null): void {\n // Emit Angular output for template bindings\n this.commit.emit(newValue);\n\n // Dispatch DOM CustomEvent for grid's auto-wiring\n // This allows the adapter to catch commits without explicit (commit)=\"...\" bindings\n this.elementRef.nativeElement.dispatchEvent(new CustomEvent('commit', { detail: newValue, bubbles: true }));\n }\n\n /**\n * Cancel editing. Emits the cancel output AND dispatches a DOM event.\n * Call this when the user cancels (e.g., presses Escape).\n */\n cancelEdit(): void {\n // Emit Angular output for template bindings\n this.cancel.emit();\n\n // Dispatch DOM CustomEvent for grid's auto-wiring\n this.elementRef.nativeElement.dispatchEvent(new CustomEvent('cancel', { bubbles: true }));\n }\n\n /**\n * Get a human-readable error message for a validation error.\n * Override this method to customize error messages for your editor.\n *\n * @param errorKey - The validation error key (e.g., 'required', 'minlength')\n * @param errorValue - The error value (e.g., { requiredLength: 5, actualLength: 3 })\n * @returns A human-readable error message\n */\n protected getErrorMessage(errorKey: string, errorValue?: unknown): string {\n switch (errorKey) {\n case 'required':\n return 'This field is required';\n case 'minlength': {\n const err = errorValue as { requiredLength?: number };\n return `Minimum length is ${err?.requiredLength ?? 'unknown'}`;\n }\n case 'maxlength': {\n const err = errorValue as { requiredLength?: number };\n return `Maximum length is ${err?.requiredLength ?? 'unknown'}`;\n }\n case 'min': {\n const err = errorValue as { min?: number };\n return `Minimum value is ${err?.min ?? 'unknown'}`;\n }\n case 'max': {\n const err = errorValue as { max?: number };\n return `Maximum value is ${err?.max ?? 'unknown'}`;\n }\n case 'email':\n return 'Invalid email address';\n case 'pattern':\n return 'Invalid format';\n default:\n return `Invalid value (${errorKey})`;\n }\n }\n}\n","import { computed, Directive, signal } from '@angular/core';\nimport type { ControlValueAccessor } from '@angular/forms';\nimport { BaseGridEditor } from './base-grid-editor';\n\n/**\n * Base class for grid editors that also work as Angular form controls.\n *\n * Combines `BaseGridEditor` with `ControlValueAccessor` so the same component\n * can be used inside a `<tbw-grid>` **and** in a standalone `<form>`.\n *\n * ## What it provides\n *\n * | Member | Purpose |\n * |--------|---------|\n * | `cvaValue` | Signal holding the value written by the form control |\n * | `disabledState` | Signal tracking `setDisabledState` calls |\n * | `displayValue` | Computed that prefers grid value (`currentValue`) and falls back to `cvaValue` |\n * | `commitBoth(v)` | Commits via both CVA `onChange` and grid `commitValue` |\n * | `writeValue` / `registerOn*` / `setDisabledState` | Full CVA implementation |\n *\n * ## Usage\n *\n * ```typescript\n * import { Component, forwardRef } from '@angular/core';\n * import { NG_VALUE_ACCESSOR } from '@angular/forms';\n * import { BaseGridEditorCVA } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * selector: 'app-date-picker',\n * providers: [{\n * provide: NG_VALUE_ACCESSOR,\n * useExisting: forwardRef(() => DatePickerComponent),\n * multi: true,\n * }],\n * template: `\n * <input\n * type=\"date\"\n * [value]=\"displayValue()\"\n * [disabled]=\"disabledState()\"\n * (change)=\"commitBoth($event.target.value)\"\n * (keydown.escape)=\"cancelEdit()\"\n * />\n * `\n * })\n * export class DatePickerComponent extends BaseGridEditorCVA<MyRow, string> {}\n * ```\n *\n * > **Note:** Subclasses must still provide `NG_VALUE_ACCESSOR` themselves\n * > because `forwardRef(() => ConcreteClass)` must reference the concrete\n * > component — this is an Angular limitation.\n *\n * @typeParam TRow - The row data type\n * @typeParam TValue - The cell/control value type\n *\n * @since 0.13.0\n */\n@Directive()\nexport abstract class BaseGridEditorCVA<TRow = unknown, TValue = unknown>\n extends BaseGridEditor<TRow, TValue>\n implements ControlValueAccessor\n{\n // ============================================================================\n // CVA State\n // ============================================================================\n\n /** Internal onChange callback registered by the form control. */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private _onChange: (value: TValue | null) => void = () => {};\n\n /** Internal onTouched callback registered by the form control. */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private _onTouched: () => void = () => {};\n\n /**\n * Signal holding the value written by the form control via `writeValue()`.\n * Updated when the form control pushes a new value (e.g. `patchValue`, `setValue`).\n */\n protected readonly cvaValue = signal<TValue | null>(null);\n\n /**\n * Signal tracking the disabled state set by the form control.\n * Updated when `setDisabledState()` is called by Angular's forms module.\n */\n readonly disabledState = signal(false);\n\n /**\n * Resolved display value.\n *\n * Prefers `currentValue()` (grid context — from `control.value` or `value` input)\n * and falls back to `cvaValue()` (standalone form context — from `writeValue`).\n *\n * Use this in your template instead of reading `currentValue()` directly\n * so the component works in both grid and standalone form contexts.\n */\n readonly displayValue = computed<TValue | null>(() => {\n return (this.currentValue() as TValue | undefined) ?? this.cvaValue();\n });\n\n // ============================================================================\n // ControlValueAccessor Implementation\n // ============================================================================\n\n /**\n * Called by Angular forms when the form control value changes programmatically.\n */\n writeValue(value: TValue | null): void {\n this.cvaValue.set(value);\n }\n\n /**\n * Called by Angular forms to register a change callback.\n */\n registerOnChange(fn: (value: TValue | null) => void): void {\n this._onChange = fn;\n }\n\n /**\n * Called by Angular forms to register a touched callback.\n */\n registerOnTouched(fn: () => void): void {\n this._onTouched = fn;\n }\n\n /**\n * Called by Angular forms to set the disabled state.\n */\n setDisabledState(isDisabled: boolean): void {\n this.disabledState.set(isDisabled);\n }\n\n // ============================================================================\n // Dual-Commit Helpers\n // ============================================================================\n\n /**\n * Commit a value through both the CVA (form control) and the grid.\n *\n * - Calls the CVA `onChange` callback (updates the form control)\n * - Marks the control as touched\n * - Calls `commitValue()` (emits grid commit event + DOM `CustomEvent`)\n *\n * Use this instead of `commitValue()` when your editor doubles as a form control.\n *\n * @param value - The new value to commit\n */\n protected commitBoth(value: TValue | null): void {\n // Update CVA\n this.cvaValue.set(value);\n this._onChange(value);\n this._onTouched();\n\n // Update grid (null is valid for nullable columns — the grid's cell-commit\n // handler and EditingPlugin will apply it correctly)\n this.commitValue(value);\n }\n}\n","import { afterNextRender, DestroyRef, Directive, ElementRef, inject } from '@angular/core';\nimport { BaseGridEditor } from './base-grid-editor';\n\n// #region Overlay Position Types\n\n/**\n * Position of the overlay panel relative to its anchor cell.\n *\n * - `'below'` — panel appears below the cell, left-aligned (default)\n * - `'above'` — panel appears above the cell, left-aligned\n * - `'below-right'` — panel appears below the cell, right-aligned\n * - `'over-top-left'` — panel top-left corner aligns with cell top-left corner (opens downward)\n * - `'over-bottom-left'` — panel bottom-left corner aligns with cell bottom-left corner (opens upward)\n * @since 0.13.0\n */\nexport type OverlayPosition = 'below' | 'above' | 'below-right' | 'over-top-left' | 'over-bottom-left';\n\n// #endregion\n\n// #region Global Styles\n\n/** Tracks whether the global overlay stylesheet has been injected. */\nlet overlayStylesInjected = false;\n\n/**\n * CSS for the overlay panel base layer.\n * Injected once into `<head>` on first `BaseOverlayEditor` use.\n *\n * Uses CSS Anchor Positioning as primary strategy with a JS fallback\n * for browsers that don't support it (Firefox, Safari as of late 2025).\n */\nconst OVERLAY_STYLES = /* css */ `\n.tbw-overlay-panel {\n position: fixed;\n z-index: 10000;\n background: var(--tbw-overlay-bg, #fff);\n border: 1px solid var(--tbw-overlay-border, #ccc);\n border-radius: var(--tbw-overlay-radius, 4px);\n box-shadow: var(--tbw-overlay-shadow, 0 4px 12px rgba(0, 0, 0, 0.15));\n box-sizing: border-box;\n overflow: auto;\n}\n\n/* Hide panels that have not been initialised via initOverlay() yet.\n Prevents a flash-of-unstyled-content when the subclass defers\n the initOverlay call (e.g. via setTimeout or afterNextRender). */\n.tbw-overlay-panel:not([data-anchor-id]) {\n display: none;\n}\n\n.tbw-overlay-panel:popover-open {\n display: block;\n}\n\n@supports (anchor-name: --a) {\n .tbw-overlay-panel[data-anchor-id] {\n position: fixed;\n position-anchor: var(--tbw-overlay-anchor);\n inset: unset;\n }\n .tbw-overlay-panel[data-pos=\"below\"] {\n top: anchor(bottom);\n left: anchor(left);\n position-try-fallbacks: flip-block;\n }\n .tbw-overlay-panel[data-pos=\"above\"] {\n bottom: anchor(top);\n left: anchor(left);\n position-try-fallbacks: flip-block;\n }\n .tbw-overlay-panel[data-pos=\"below-right\"] {\n top: anchor(bottom);\n right: anchor(right);\n position-try-fallbacks: flip-block;\n }\n .tbw-overlay-panel[data-pos=\"over-top-left\"] {\n top: anchor(top);\n left: anchor(left);\n }\n .tbw-overlay-panel[data-pos=\"over-bottom-left\"] {\n bottom: anchor(bottom);\n left: anchor(left);\n }\n}\n`;\n\nfunction ensureOverlayStyles(): void {\n if (overlayStylesInjected) return;\n overlayStylesInjected = true;\n\n const style = document.createElement('style');\n style.setAttribute('data-tbw-overlay', '');\n style.textContent = OVERLAY_STYLES;\n document.head.appendChild(style);\n}\n\n// #endregion\n\n// #region Anchor ID Counter\nlet anchorCounter = 0;\n// #endregion\n\n/**\n * Base class for grid editors that display a floating overlay panel.\n *\n * Provides infrastructure for:\n * - **Overlay positioning** — CSS Anchor Positioning with JS fallback\n * - **Focus gating** — in row editing mode, the panel only opens for the focused cell\n * - **Click-outside detection** — closes the panel when clicking outside\n * - **MutationObserver** — detects cell focus changes (row editing mode)\n * - **Escape handling** — closes the panel and returns focus to the inline input\n * - **Synthetic Tab dispatch** — advances grid focus after overlay close\n * - **Automatic teardown** — removes the panel from `<body>` and cleans up listeners\n * - **External focus registration** — auto-registers the panel via `grid.registerExternalFocusContainer()` so the grid keeps `data-has-focus` and editors stay open while the overlay has focus\n *\n * ## Usage\n *\n * ```typescript\n * import { Component, viewChild, ElementRef, effect } from '@angular/core';\n * import { BaseOverlayEditor } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * selector: 'app-date-editor',\n * template: `\n * <input\n * #inlineInput\n * readonly\n * [value]=\"currentValue()\"\n * (click)=\"onInlineClick()\"\n * (keydown)=\"onInlineKeydown($event)\"\n * />\n * <div #panel class=\"tbw-overlay-panel\" style=\"width: 280px;\">\n * <!-- your date picker UI here -->\n * <div class=\"actions\">\n * <button (click)=\"selectAndClose(selectedDate)\">OK</button>\n * <button (click)=\"hideOverlay()\">Cancel</button>\n * </div>\n * </div>\n * `\n * })\n * export class DateEditorComponent extends BaseOverlayEditor<MyRow, string> {\n * panelRef = viewChild.required<ElementRef<HTMLElement>>('panel');\n * inputRef = viewChild.required<ElementRef<HTMLInputElement>>('inlineInput');\n *\n * protected override overlayPosition = 'below' as const;\n *\n * constructor() {\n * super();\n * effect(() => {\n * const panel = this.panelRef().nativeElement;\n * this.initOverlay(panel);\n * if (this.isCellFocused()) this.showOverlay();\n * });\n * }\n *\n * protected getInlineInput(): HTMLInputElement | null {\n * return this.inputRef()?.nativeElement ?? null;\n * }\n *\n * protected onOverlayOutsideClick(): void {\n * this.hideOverlay();\n * }\n *\n * selectAndClose(date: string): void {\n * this.commitValue(date);\n * this.hideOverlay();\n * }\n * }\n * ```\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <input #inlineInput readonly [value]=\"currentValue()\"\n * (click)=\"onInlineClick()\" (keydown)=\"onInlineKeydown($event)\" />\n * <div #panel style=\"width: 280px\">\n * <!-- overlay content -->\n * </div>\n * `\n * })\n * export class MyEditor extends BaseOverlayEditor<MyRow, string> {\n * panelRef = viewChild.required<ElementRef<HTMLElement>>('panel');\n * inputRef = viewChild.required<ElementRef<HTMLInputElement>>('inlineInput');\n *\n * constructor() {\n * super();\n * effect(() => this.initOverlay(this.panelRef().nativeElement));\n * }\n *\n * protected getInlineInput() { return this.inputRef()?.nativeElement ?? null; }\n * protected onOverlayOutsideClick() { this.hideOverlay(); }\n * }\n * ```\n *\n * @typeParam TRow - The row data type\n * @typeParam TValue - The cell value type\n *\n * @since 0.13.0\n */\n@Directive()\nexport abstract class BaseOverlayEditor<TRow = unknown, TValue = unknown> extends BaseGridEditor<TRow, TValue> {\n private readonly _elementRef = inject(ElementRef);\n private readonly _overlayDestroyRef = inject(DestroyRef);\n\n // ============================================================================\n // Configuration\n // ============================================================================\n\n /**\n * Position of the overlay panel relative to the anchor cell.\n * Override in subclasses to change the default position.\n *\n * @default 'below'\n */\n protected overlayPosition: OverlayPosition = 'below';\n\n // ============================================================================\n // Internal State\n // ============================================================================\n\n /** The overlay panel element (set via `initOverlay()`). */\n private _panel: HTMLElement | null = null;\n\n /** Whether the overlay is currently visible. */\n protected _isOpen = false;\n\n /** Unique anchor ID for CSS Anchor Positioning. */\n private _anchorId = '';\n\n /** Whether the browser supports CSS Anchor Positioning. */\n private _supportsAnchor = false;\n\n /** AbortController for all overlay-related listeners. */\n private _abortCtrl: AbortController | null = null;\n\n /** MutationObserver watching cell focus class changes. */\n protected _focusObserver: MutationObserver | null = null;\n\n // ============================================================================\n // Lifecycle\n // ============================================================================\n\n constructor() {\n super();\n this._supportsAnchor = typeof CSS !== 'undefined' && CSS.supports('anchor-name', '--a');\n ensureOverlayStyles();\n\n afterNextRender(() => this._setupFocusObserver());\n this._overlayDestroyRef.onDestroy(() => this.teardownOverlay());\n }\n\n // ============================================================================\n // Public API — Subclass Interface\n // ============================================================================\n\n /**\n * Initialise the overlay with the panel element.\n *\n * Call this in an `effect()` or `afterNextRender()` with your `viewChild` panel reference.\n * The panel is moved to `<body>` and hidden until {@link showOverlay} is called.\n *\n * @param panel - The overlay panel DOM element\n */\n protected initOverlay(panel: HTMLElement): void {\n this._panel = panel;\n\n // Assign a unique anchor ID\n this._anchorId = `tbw-anchor-${++anchorCounter}`;\n panel.classList.add('tbw-overlay-panel');\n panel.setAttribute('data-pos', this.overlayPosition);\n panel.setAttribute('data-anchor-id', this._anchorId);\n panel.style.display = 'none';\n\n // Set up CSS Anchor Positioning on the cell\n if (this._supportsAnchor) {\n const cell = this._getCell();\n if (cell) {\n cell.style.setProperty('anchor-name', `--${this._anchorId}`);\n panel.style.setProperty('--tbw-overlay-anchor', `--${this._anchorId}`);\n }\n }\n\n // Move panel to body so it escapes grid overflow clipping\n document.body.appendChild(panel);\n\n // Register the panel as an external focus container on the grid\n // so focus moving into the overlay is treated as \"still in the grid\"\n this._getGridElement()?.registerExternalFocusContainer?.(panel);\n\n // Set up click-outside detection\n this._abortCtrl = new AbortController();\n document.addEventListener('pointerdown', (e) => this._onDocumentPointerDown(e), {\n signal: this._abortCtrl.signal,\n });\n\n // Close overlay when the grid viewport scrolls. Mirrors outside-click\n // semantics so subclasses' `onOverlayOutsideClick()` drives commit/cancel.\n // Uses the public `tbw-scroll` CustomEvent dispatched on the grid host —\n // no shadow-DOM reach-arounds required (composed: true crosses boundaries).\n const grid = this._getGridElement();\n if (grid) {\n grid.addEventListener('tbw-scroll', () => this._onGridScroll(), {\n signal: this._abortCtrl.signal,\n });\n }\n\n // If the focus observer already fired before the panel was initialised\n // (e.g. initOverlay called from a deferred setTimeout), the showOverlay()\n // call was silently ignored because _panel was still null. Catch up now.\n if (this._getCell()?.classList.contains('cell-focus')) {\n this.showOverlay();\n this.onOverlayOpened();\n }\n }\n\n /**\n * Show the overlay panel.\n *\n * If CSS Anchor Positioning is not supported, falls back to JS-based\n * positioning using `getBoundingClientRect()`.\n */\n protected showOverlay(): void {\n if (!this._panel || this._isOpen) return;\n\n this._isOpen = true;\n this._panel.style.display = '';\n\n // JS fallback positioning for browsers without CSS Anchor Positioning\n if (!this._supportsAnchor) {\n this._positionWithJs();\n }\n }\n\n /**\n * Hide the overlay panel.\n *\n * @param suppressTabAdvance - When `true`, skip synthetic Tab dispatch\n * (useful when hiding is triggered by an external focus change).\n */\n protected hideOverlay(suppressTabAdvance?: boolean): void {\n if (!this._panel || !this._isOpen) return;\n\n this._isOpen = false;\n this._panel.style.display = 'none';\n\n if (!suppressTabAdvance) {\n this.getInlineInput()?.focus();\n }\n }\n\n /**\n * Close and immediately re-open the overlay.\n * Useful after the panel content changes size and needs repositioning.\n */\n protected reopenOverlay(): void {\n if (!this._panel) return;\n this._isOpen = false;\n this._panel.style.display = 'none';\n this.showOverlay();\n }\n\n /**\n * Remove the overlay from the DOM and clean up all listeners.\n *\n * Called automatically on `DestroyRef.onDestroy`. Can also be called\n * manually if the editor needs early cleanup.\n */\n protected teardownOverlay(): void {\n this._abortCtrl?.abort();\n this._abortCtrl = null;\n\n this._focusObserver?.disconnect();\n this._focusObserver = null;\n\n // Unregister the panel from the grid's external focus container registry\n if (this._panel) {\n this._getGridElement()?.unregisterExternalFocusContainer?.(this._panel);\n }\n\n if (this._panel?.parentNode) {\n this._panel.parentNode.removeChild(this._panel);\n }\n this._panel = null;\n this._isOpen = false;\n\n // Clean up anchor-name on the cell\n if (this._supportsAnchor) {\n const cell = this._getCell();\n if (cell) {\n cell.style.removeProperty('anchor-name');\n }\n }\n }\n\n /**\n * Override in `edit-close` handler to also hide the overlay.\n * This is called automatically by `BaseGridEditor` when the grid\n * ends the editing session.\n */\n protected override onEditClose(): void {\n this.hideOverlay(true);\n }\n\n // ============================================================================\n // Keyboard & Click Helpers\n // ============================================================================\n\n /**\n * Keydown handler for the inline readonly input.\n *\n * - **Enter / Space / ArrowDown / F2** → open overlay\n * - **Escape** → calls {@link handleEscape}\n *\n * Bind this to `(keydown)` on your inline input element.\n */\n onInlineKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'Enter':\n case ' ':\n case 'ArrowDown':\n case 'F2':\n event.preventDefault();\n this.showOverlay();\n this.onOverlayOpened();\n break;\n case 'Escape':\n this.handleEscape(event);\n break;\n }\n }\n\n /**\n * Click handler for the inline input.\n * Opens the overlay and calls {@link onOverlayOpened}.\n *\n * Bind this to `(click)` on your inline input element.\n */\n onInlineClick(): void {\n if (this._isOpen) {\n this.hideOverlay();\n } else {\n this.showOverlay();\n this.onOverlayOpened();\n }\n }\n\n /**\n * Handle Escape key press.\n *\n * If the overlay is open, closes it and returns focus to the inline input.\n * If the overlay is already closed, cancels the edit entirely.\n */\n protected handleEscape(event: Event): void {\n if (this._isOpen) {\n event.stopPropagation();\n this.hideOverlay();\n } else {\n this.cancelEdit();\n }\n }\n\n /**\n * Dispatch a synthetic Tab key event to advance grid focus.\n *\n * Call this after committing a value and closing the overlay so the\n * grid moves focus to the next cell.\n *\n * @param backward - When `true`, dispatch Shift+Tab to move backwards.\n */\n protected advanceGridFocus(backward = false): void {\n const cell = this._getCell();\n if (!cell) return;\n\n cell.dispatchEvent(\n new KeyboardEvent('keydown', {\n key: 'Tab',\n shiftKey: backward,\n bubbles: true,\n cancelable: true,\n }),\n );\n }\n\n // ============================================================================\n // Abstract / Hook Methods\n // ============================================================================\n\n /**\n * Return the inline input element, if any.\n *\n * Used by overlay infrastructure to return focus after hiding.\n * Return `null` if there is no inline input.\n */\n protected abstract getInlineInput(): HTMLInputElement | null;\n\n /**\n * Called when a pointerdown event occurs outside the overlay panel\n * and outside the editor's host element.\n *\n * Typically, subclasses call `hideOverlay()` here.\n */\n protected abstract onOverlayOutsideClick(): void;\n\n /**\n * Called after the overlay is shown.\n *\n * Override to focus an element inside the panel, start animations, etc.\n * Default implementation is a no-op.\n */\n protected onOverlayOpened(): void {\n // Default: no-op. Subclasses override.\n }\n\n // ============================================================================\n // Private Helpers\n // ============================================================================\n\n /** Find the parent cell element for this editor. */\n private _getCell(): HTMLElement | null {\n return this._elementRef.nativeElement.closest('[part=\"cell\"]') ?? null;\n }\n\n /** Find the parent `<tbw-grid>` element for this editor. */\n private _getGridElement():\n | (HTMLElement & {\n registerExternalFocusContainer?(el: Element): void;\n unregisterExternalFocusContainer?(el: Element): void;\n })\n | null {\n return this._elementRef.nativeElement.closest('tbw-grid, [data-tbw-grid]') ?? null;\n }\n\n /**\n * JS fallback positioning for browsers without CSS Anchor Positioning.\n * Uses `getBoundingClientRect()` with viewport overflow detection.\n */\n private _positionWithJs(): void {\n const cell = this._getCell();\n const panel = this._panel;\n if (!cell || !panel) return;\n\n const cellRect = cell.getBoundingClientRect();\n\n // Temporarily make visible to measure\n panel.style.visibility = 'hidden';\n panel.style.display = '';\n const panelRect = panel.getBoundingClientRect();\n panel.style.visibility = '';\n\n const viewportH = window.innerHeight;\n const viewportW = window.innerWidth;\n\n let top: number;\n let left: number;\n\n switch (this.overlayPosition) {\n case 'above': {\n top = cellRect.top - panelRect.height;\n left = cellRect.left;\n // Flip to below if off-screen\n if (top < 0) top = cellRect.bottom;\n break;\n }\n case 'below-right': {\n top = cellRect.bottom;\n left = cellRect.right - panelRect.width;\n // Flip to above if off-screen\n if (top + panelRect.height > viewportH) top = cellRect.top - panelRect.height;\n break;\n }\n case 'over-top-left': {\n top = cellRect.top;\n left = cellRect.left;\n break;\n }\n case 'over-bottom-left': {\n top = cellRect.bottom - panelRect.height;\n left = cellRect.left;\n break;\n }\n case 'below':\n default: {\n top = cellRect.bottom;\n left = cellRect.left;\n // Flip to above if off-screen\n if (top + panelRect.height > viewportH) top = cellRect.top - panelRect.height;\n break;\n }\n }\n\n // Clamp to viewport\n if (left + panelRect.width > viewportW) left = viewportW - panelRect.width - 4;\n if (left < 0) left = 4;\n if (top < 0) top = 4;\n\n panel.style.top = `${top}px`;\n panel.style.left = `${left}px`;\n }\n\n /**\n * Document pointerdown handler for click-outside detection.\n * Fires `onOverlayOutsideClick()` if the click is outside the panel\n * and outside the editor's host element.\n */\n private _onDocumentPointerDown(event: PointerEvent): void {\n if (!this._isOpen || !this._panel) return;\n\n const target = event.target as Node;\n const hostEl = this._elementRef.nativeElement;\n\n // Click inside panel or host — ignore\n if (this._panel.contains(target) || hostEl.contains(target)) return;\n\n this.onOverlayOutsideClick();\n }\n\n /**\n * Handle the grid's `tbw-scroll` CustomEvent while the overlay is open.\n *\n * When the viewport scrolls, the anchored overlay would otherwise float\n * over content that no longer corresponds to the edited cell (or the\n * cell may be virtualized out entirely). Treat scroll as a dismissal\n * signal equivalent to clicking outside so subclasses' overlay-outside\n * handler drives the appropriate commit/cancel path.\n */\n private _onGridScroll(): void {\n if (!this._isOpen || !this._panel) return;\n this.onOverlayOutsideClick();\n }\n\n /**\n * Set up a MutationObserver on the parent cell to watch for\n * `cell-focus` class changes. This handles row-editing mode where\n * all editors exist simultaneously but only the focused cell's\n * editor should have its overlay visible.\n *\n * A `justOpened` flash guard suppresses the observer from\n * immediately closing the overlay when `beginBulkEdit()` moves\n * focus to the first editable column. Without this guard,\n * double-click triggers a \"flash open then close\" effect.\n */\n protected _setupFocusObserver(): void {\n const cell = this._getCell();\n if (!cell) return;\n\n let justOpened = false;\n\n let pendingHideRaf = 0;\n\n const hostEl = this._elementRef.nativeElement;\n\n this._focusObserver = new MutationObserver((mutations) => {\n // Guard: if the editor's host element is no longer inside the cell,\n // it means the component was detached (e.g., editing session ended\n // and the render pipeline cleared the cell DOM). Disconnect to\n // prevent orphaned observers from opening stale overlay panels.\n if (!cell.contains(hostEl)) {\n this._focusObserver?.disconnect();\n this._focusObserver = null;\n return;\n }\n\n for (const mutation of mutations) {\n if (mutation.type !== 'attributes' || mutation.attributeName !== 'class') continue;\n\n const isFocused = cell.classList.contains('cell-focus');\n if (isFocused && !this._isOpen) {\n // Cell just gained focus — cancel any pending hide and open overlay.\n if (pendingHideRaf) {\n cancelAnimationFrame(pendingHideRaf);\n pendingHideRaf = 0;\n }\n justOpened = true;\n this.showOverlay();\n this.onOverlayOpened();\n // Clear the guard after a macrotask so that an immediate\n // focus-away (e.g. beginBulkEdit focus adjustment) does\n // not close the overlay in the same event loop tick.\n setTimeout(() => {\n justOpened = false;\n }, 0);\n } else if (!isFocused && this._isOpen && !justOpened) {\n // Cell lost focus — defer hide to allow render cycles to settle.\n // Re-renders (e.g., from ResizeObserver after a footer appears)\n // may transiently toggle cell-focus within the same frame.\n // Deferring to the next animation frame lets the render pipeline\n // finish before we decide whether the overlay should actually close.\n if (pendingHideRaf) cancelAnimationFrame(pendingHideRaf);\n pendingHideRaf = requestAnimationFrame(() => {\n pendingHideRaf = 0;\n // Re-check settled state — cell-focus may have been re-applied\n if (!cell.classList.contains('cell-focus') && this._isOpen) {\n this.hideOverlay(true);\n }\n });\n }\n }\n });\n\n this._focusObserver.observe(cell, { attributes: true, attributeFilter: ['class'] });\n }\n}\n","/**\n * Editing feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `editing` input on Grid directive AND to\n * install the `before-edit-close` blur bridge that flushes pending input from\n * Angular editors that commit on `(blur)` before the cell DOM is torn down by\n * Tab / programmatic row exit.\n *\n * Without this import, Angular `(blur)`-committing editors silently lose\n * pending input on programmatic row exit.\n *\n * @example\n * ```typescript\n * import '@toolbox-web/grid-angular/features/editing';\n *\n * <tbw-grid [editing]=\"'dblclick'\" />\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { ColumnEditorContext, ColumnEditorSpec } from '@toolbox-web/grid';\nimport {\n type GridAdapter,\n makeFlushFocusedInput,\n registerEditorMountHook,\n registerEditorSpecBridge,\n} from '@toolbox-web/grid-angular';\nimport '@toolbox-web/grid/features/editing';\nimport { getEditorTemplate, type GridEditorContext } from './grid-column-editor.directive';\nimport { getFormArrayContext } from './grid-form-array.directive';\nimport { getLazyFormContext } from './grid-lazy-form.directive';\nimport { getStructuralEditorTemplate } from './structural-editor.directive';\n\nexport { GridEditingDirective } from './grid-editing.directive';\nexport type { _Augmentation as _EditingAugmentation } from '@toolbox-web/grid/features/editing';\n\n// ---------------------------------------------------------------------------\n// Editing-owned public API. These symbols physically live in this secondary\n// entry; the grid core only exposes generic embedded-view primitives and\n// delegates all template-editor resolution to the bridge installed below.\n// ---------------------------------------------------------------------------\nexport { BaseGridEditor } from './base-grid-editor';\nexport { BaseGridEditorCVA } from './base-grid-editor-cva';\nexport { BaseOverlayEditor } from './base-overlay-editor';\nexport type { OverlayPosition } from './base-overlay-editor';\nexport { getEditorTemplate, GridColumnEditor } from './grid-column-editor.directive';\nexport type { GridEditorContext } from './grid-column-editor.directive';\nexport { getFormArrayContext, GridFormArray } from './grid-form-array.directive';\nexport type { FormArrayContext } from './grid-form-array.directive';\nexport { getLazyFormContext, GridLazyForm } from './grid-lazy-form.directive';\nexport type { LazyFormFactory, RowFormChangeEvent } from './grid-lazy-form.directive';\nexport { getStructuralEditorTemplate, TbwEditor } from './structural-editor.directive';\nexport type { StructuralEditorContext } from './structural-editor.directive';\n\n// ---------------------------------------------------------------------------\n// Install the template-based editor bridge. The grid adapter delegates\n// `createEditor()` / `canHandle()` to this function, which resolves the\n// Angular editor template (`*tbwEditor` or nested `<tbw-grid-column-editor>`),\n// wires the FormArray control (if the grid is bound to a FormArray), and\n// mounts the template via the adapter's generic editor-view primitive.\n// ---------------------------------------------------------------------------\nregisterEditorSpecBridge(\n <TRow, TValue>(element: HTMLElement, adapter: GridAdapter): ColumnEditorSpec<TRow, TValue> | undefined => {\n // Resolve the editor template: structural `*tbwEditor` first, then the\n // nested `<tbw-grid-column-editor>` directive. The cast target is derived\n // from `getStructuralEditorTemplate` (same package instance as the adapter),\n // NOT from a local `import type { TemplateRef } from '@angular/core'` — the\n // latter resolves through Bun's `.bun/` cache during ng-packagr build and\n // produces a brand-incompatible `TemplateRef` vs the built adapter `.d.ts`\n // (see the shell feature entry for the same guard). `StructuralEditorContext`\n // uses `any` type defaults, which preserves assignability with the generic\n // `GridEditorContext<TValue, TRow>` at the `createEditorTemplateView` call.\n const template = (getStructuralEditorTemplate(element) ?? getEditorTemplate(element)) as\n | ReturnType<typeof getStructuralEditorTemplate>\n | undefined;\n\n if (!template) {\n // No template registered — let the grid use its built-in editors. This\n // allows columns with only `*tbwRenderer` (no `*tbwEditor`) to remain\n // editable via the default text/number/boolean editors.\n return undefined;\n }\n\n // Find the parent grid element for FormArray context access.\n const gridElement = element.closest('tbw-grid, [data-tbw-grid]') as HTMLElement | null;\n\n return (ctx: ColumnEditorContext<TRow, TValue>) => {\n const onCommit = (value: TValue) => ctx.commit(value);\n const onCancel = () => ctx.cancel();\n\n // Resolve the FormControl from the FormArrayContext, if available.\n // Both GridFormArray and GridLazyForm expose a FormArrayContext, but each\n // stores it under its own module-local Symbol. Check both so control-based\n // template editors (`*tbwEditor=\"let _; control as control\"`) receive the\n // FormControl whether the grid uses `[formArray]` or `[lazyForm]`.\n let control: GridEditorContext<TValue, TRow>['control'];\n if (gridElement) {\n const formContext = getFormArrayContext(gridElement) ?? getLazyFormContext(gridElement);\n if (formContext?.hasFormGroups) {\n const gridRows = (gridElement as { rows?: TRow[] }).rows;\n if (gridRows) {\n const rowIndex = gridRows.indexOf(ctx.row);\n if (rowIndex >= 0) {\n control = formContext.getControl(rowIndex, ctx.field as string);\n }\n }\n }\n }\n\n const context: GridEditorContext<TValue, TRow> = {\n $implicit: ctx.value,\n value: ctx.value,\n row: ctx.row,\n field: ctx.field as string,\n column: ctx.column,\n rowId: ctx.rowId ?? '',\n onCommit,\n onCancel,\n updateRow: ctx.updateRow,\n onValueChange: ctx.onValueChange,\n control,\n };\n\n // Mount the template via the adapter's generic editor-view primitive\n // (tracks the view in the per-cell editor pool, wraps root nodes in a\n // stable `display:contents` span, and runs editor-mount hooks).\n const { container, viewRef } = adapter.createEditorTemplateView(template, context);\n\n // Auto-wire: listen for commit/cancel events on the rendered component so\n // components can just emit `(commit)` / `(cancel)` without explicit\n // template bindings.\n container.addEventListener('commit', (e: Event) => {\n ctx.commit((e as CustomEvent<TValue>).detail);\n });\n container.addEventListener('cancel', () => {\n ctx.cancel();\n });\n\n // Auto-update the editor when the value changes externally (e.g. updateRow\n // cascade or Escape-revert). Angular's own bindings/control flow handle the\n // re-render; we just re-sync root nodes in case control flow changed them.\n ctx.onValueChange?.((newVal: unknown) => {\n context.$implicit = newVal as TValue;\n context.value = newVal as TValue;\n viewRef.detectChanges();\n adapter.syncEditorTemplateView(viewRef, container);\n });\n\n return container;\n };\n },\n);\n\n// Bridge the editing plugin's `before-edit-close` event to a synchronous\n// `.blur()` on the focused input/textarea/select inside the editor host.\n// Angular editors that commit on `(blur)` rely on the focused control firing\n// blur naturally, but Tab / programmatic row exit rebuilds the cell DOM\n// synchronously without giving the focused control a chance to blur first.\nregisterEditorMountHook(({ container, gridEl }) => {\n const flush = makeFlushFocusedInput(container);\n gridEl.addEventListener('before-edit-close', flush);\n return () => gridEl.removeEventListener('before-edit-close', flush);\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["FORM_ARRAY_CONTEXT"],"mappings":";;;;;;;;AA8DA;AACA,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAA+C;AAErF;;;AAGG;AACG,SAAU,iBAAiB,CAAC,OAAoB,EAAA;AACpD,IAAA,OAAO,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC;AAC5C;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CG;MAEU,gBAAgB,CAAA;AACnB,IAAA,UAAU,GAAG,MAAM,EAAC,UAAuB,EAAC;AAEpD;;AAEG;AACH,IAAA,QAAQ,GAAG,YAAY,EAAC,WAA8B;iFAAC;;AAG/C,IAAA,kBAAkB,GAAG,MAAM,CAAC,MAAK;AACvC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE;QAChC,IAAI,QAAQ,EAAE;;YAEZ,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,QAAQ,CAAC;QACrE;IACF,CAAC;2FAAC;AAEF;;;AAGG;AACH,IAAA,OAAO,sBAAsB,CAAC,GAAqB,EAAE,GAAY,EAAA;AAC/D,QAAA,OAAO,IAAI;IACb;uGAvBW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,OAAA,EAAA,CAAA,EAAA,YAAA,EAAA,UAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,GAMH,WAA8B,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAN3C,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,SAAS;mBAAC,EAAE,QAAQ,EAAE,wBAAwB,EAAE;6FAOvB,WAA8B,CAAA,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;ACjCxD;AACA,MAAMA,oBAAkB,GAAG,MAAM,CAAC,kBAAkB,CAAC;AAErD;;;;AAIG;AACG,SAAU,mBAAmB,CAAC,WAAwB,EAAA;AAC1D,IAAA,OAAQ,WAA2D,CAACA,oBAAkB,CAAC;AACzF;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DG;MAIU,aAAa,CAAA;AACP,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AACxC,IAAA,UAAU,GAAG,MAAM,EAAC,UAAuB,EAAC;IAC5C,eAAe,GAAwB,IAAI;IAC3C,eAAe,GAAwB,IAAI;IAC3C,cAAc,GAAwB,IAAI;IAC1C,aAAa,GAAgC,IAAI;IACjD,wBAAwB,GAAwB,IAAI;IACpD,0BAA0B,GAAmB,EAAE;AAEvD;;AAEG;IACM,SAAS,GAAG,KAAK,CAAC,QAAQ;kFAAa;AAEhD;;;;;;;;;;AAUG;IACM,cAAc,GAAG,KAAK,CAAU,IAAI;uFAAC;AAE9C;;;AAGG;AACK,IAAA,mBAAmB,GAAG,MAAM,CAAC,MAAK;AACxC,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;AAClC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS;YAAE;;AAGzB,QAAA,IAAI,CAAC,wBAAwB,EAAE,WAAW,EAAE;;;;;;;;;AAU5C,QAAA,IAAI,CAAC,wBAAwB,GAAG,SAAS,CAAC;AACvC,aAAA,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;aAC5E,SAAS,CAAC,MAAK;;;;;AAKd,YAAA,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;gBAAE;AAEjC,YAAA,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,WAAW,EAAE;AACrC,QAAA,CAAC,CAAC;IACN,CAAC;4FAAC;IAEF,QAAQ,GAAA;AACN,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;;AAGX,QAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;;AAG5B,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,EAAE,CAC5B,aAAa,EACb,CAAC,MAA6F,KAAI;AAChG,YAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;AAChC,QAAA,CAAC,CACF;;AAGD,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,EAAE,CAC5B,aAAa,EACb,CAAC,MAAmE,KAAI;AACtE,YAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;AAChC,QAAA,CAAC,CACF;;AAGD,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,CAC3B,YAAY,EACZ,CAAC,MAA8D,EAAE,KAAkB,KAAI;AACrF,YAAA,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;gBAAE;AAC5B,YAAA,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC;AACtC,QAAA,CAAC,CACF;;AAGD,QAAA,IAAI,CAAC,aAAa,GAAG,MAAK;AACxB,YAAA,IAAI,CAAC,SAAS,EAAE,CAAC,aAAa,EAAE;;AAEhC,YAAA,IAAI,IAAI,CAAC,aAAa,EAAE;gBACtB,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC;AACrD,gBAAA,IAAI,CAAC,aAAa,GAAG,IAAI;YAC3B;AACF,QAAA,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC;;;QAIlD,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAK;YACvB,IAAI,IAAI,CAAC,cAAc,EAAE,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;gBAC/C,IAAI,CAAC,wBAAwB,EAAE;;gBAE/B,IAAI,CAAC,uBAAuB,EAAE;YAChC;AACF,QAAA,CAAC,CAAC;IACJ;IAEA,WAAW,GAAA;AACT,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,IAAI,CAAC,eAAe,IAAI;AACxB,QAAA,IAAI,CAAC,eAAe,IAAI;AACxB,QAAA,IAAI,CAAC,cAAc,IAAI;AACvB,QAAA,IAAI,IAAI,CAAC,aAAa,EAAE;YACtB,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC;QACvD;AACA,QAAA,IAAI,IAAI,CAAC,wBAAwB,EAAE;AACjC,YAAA,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE;QAC7C;;AAEA,QAAA,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC;AACnE,QAAA,IAAI,CAAC,0BAA0B,GAAG,EAAE;AAEpC,QAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;IAC9B;AAEA;;AAEG;IACH,WAAW,GAAA;AACT,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;AAAE,YAAA,OAAO,KAAK;QAEvB,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,GAAG,SAAS,CAEzC;AAEb,QAAA,OAAO,aAAa,EAAE,MAAM,EAAE,IAAI,KAAK,MAAM;IAC/C;AAEA;;;;AAIG;AACH,IAAA,gBAAgB,CAAC,IAAiB,EAAA;AAChC,QAAA,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;AAAE,YAAA,OAAO,KAAK;AACrC,QAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa;AACrC,QAAA,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,KAAK;;AAEzB,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,IAAI;IACpE;AAEA;;;AAGG;IACH,wBAAwB,GAAA;AACtB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;AAClC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;;AAGX,QAAA,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC;AACnE,QAAA,IAAI,CAAC,0BAA0B,GAAG,EAAE;;AAGpC,QAAA,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;YAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AACpD,YAAA,IAAI,CAAC,YAAY;gBAAE;;YAGnB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC;AAC5C,YAAA,IAAI,CAAC,KAAK;gBAAE;;AAGZ,YAAA,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;gBACnD,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;AACvC,gBAAA,IAAI,CAAC,OAAO;oBAAE;gBAEd,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,MAAK;oBAC3G,IAAI,CAAC,4BAA4B,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC;AAC1D,gBAAA,CAAC,CAAC;AAEF,gBAAA,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC;AAC3C,YAAA,CAAC,CAAC;QACJ;IACF;AAEA;;;AAGG;IACH,uBAAuB,GAAA;AACrB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;AAClC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;YAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AACpD,YAAA,IAAI,CAAC,YAAY;gBAAE;YAEnB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC;AAC5C,YAAA,IAAI,CAAC,KAAK;gBAAE;AAEZ,YAAA,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;gBACnD,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;gBACvC,IAAI,OAAO,EAAE;oBACX,IAAI,CAAC,4BAA4B,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC;gBAC1D;AACF,YAAA,CAAC,CAAC;QACJ;IACF;AAEA;;AAEG;IACH,SAAS,CAAC,IAAiB,EAAE,QAAgB,EAAA;AAC3C,QAAA,IAAI;AACF,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;AACtB,YAAA,MAAM,GAAG,GAAG,IAAI,GAAG,QAAQ,CAAC;AAC5B,YAAA,IAAI,CAAC,GAAG;AAAE,gBAAA,OAAO,SAAS;AAC1B,YAAA,OAAO,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC;QAC7B;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,SAAS;QAClB;IACF;AAEA;;AAEG;IACH,wBAAwB,GAAA;AACtB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;AAClC,QAAA,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;AAAE,YAAA,OAAO,KAAK;QACxC,OAAO,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,SAAS;IAC7C;AAEA;;AAEG;AACH,IAAA,gBAAgB,CAAC,QAAgB,EAAA;AAC/B,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;QAClC,MAAM,UAAU,GAAG,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC;QACzC,OAAO,UAAU,YAAY,SAAS,GAAG,UAAU,GAAG,SAAS;IACjE;AAEA;;AAEG;AACH,IAAA,iBAAiB,CAAC,IAAiB,EAAA;AACjC,QAAA,MAAM,eAAe,GAAG,CAAC,QAAgB,KAAK,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;;QAE7E,MAAM,IAAI,GAAG,IAAI;AAEjB,QAAA,MAAM,OAAO,GAAqB;AAChC,YAAA,MAAM,EAAE,CAAI,QAAgB,KAAc;AACxC,gBAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;gBAClC,MAAM,UAAU,GAAG,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC;gBACzC,OAAO,UAAU,GAAI,UAAU,CAAC,KAAW,GAAG,IAAI;YACpD,CAAC;YACD,WAAW,EAAE,CAAC,QAAgB,EAAE,KAAa,EAAE,KAAc,KAAI;AAC/D,gBAAA,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC;gBAC9C,IAAI,YAAY,EAAE;oBAChB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;oBACvC,IAAI,OAAO,EAAE;AACX,wBAAA,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;wBACvB,OAAO,CAAC,WAAW,EAAE;oBACvB;gBACF;YACF,CAAC;YACD,QAAQ,EAAE,MAAa;AACrB,gBAAA,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,WAAW,EAAS;YAC9C,CAAC;AACD,YAAA,IAAI,aAAa,GAAA;AACf,gBAAA,OAAO,IAAI,CAAC,wBAAwB,EAAE;YACxC,CAAC;AACD,YAAA,UAAU,EAAE,CAAC,QAAgB,EAAE,KAAa,KAAiC;AAC3E,gBAAA,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC;AAC9C,gBAAA,IAAI,CAAC,YAAY;AAAE,oBAAA,OAAO,SAAS;gBACnC,OAAO,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,SAAS;YAC7C,CAAC;YACD,eAAe;AACf,YAAA,UAAU,EAAE,CAAC,QAAgB,KAAa;AACxC,gBAAA,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC;AAC9C,gBAAA,IAAI,CAAC,YAAY;AAAE,oBAAA,OAAO,IAAI;gBAC9B,OAAO,YAAY,CAAC,KAAK;YAC3B,CAAC;AACD,YAAA,YAAY,EAAE,CAAC,QAAgB,KAAa;AAC1C,gBAAA,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC;AAC9C,gBAAA,IAAI,CAAC,YAAY;AAAE,oBAAA,OAAO,KAAK;gBAC/B,OAAO,YAAY,CAAC,OAAO;YAC7B,CAAC;AACD,YAAA,UAAU,EAAE,CAAC,QAAgB,KAAa;AACxC,gBAAA,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC;AAC9C,gBAAA,IAAI,CAAC,YAAY;AAAE,oBAAA,OAAO,KAAK;gBAC/B,OAAO,YAAY,CAAC,KAAK;YAC3B,CAAC;AACD,YAAA,YAAY,EAAE,CAAC,QAAgB,KAAoC;AACjE,gBAAA,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC;AAC9C,gBAAA,IAAI,CAAC,YAAY;AAAE,oBAAA,OAAO,IAAI;gBAE9B,MAAM,MAAM,GAA4B,EAAE;gBAC1C,IAAI,SAAS,GAAG,KAAK;AAErB,gBAAA,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;oBACnD,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;AACvC,oBAAA,IAAI,OAAO,EAAE,MAAM,EAAE;AACnB,wBAAA,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM;wBAC9B,SAAS,GAAG,IAAI;oBAClB;AACF,gBAAA,CAAC,CAAC;AAEF,gBAAA,IAAI,YAAY,CAAC,MAAM,EAAE;AACvB,oBAAA,MAAM,CAAC,QAAQ,CAAC,GAAG,YAAY,CAAC,MAAM;oBACtC,SAAS,GAAG,IAAI;gBAClB;gBAEA,OAAO,SAAS,GAAG,MAAM,GAAG,IAAI;YAClC,CAAC;SACF;AACA,QAAA,IAAoD,CAACA,oBAAkB,CAAC,GAAG,OAAO;IACrF;AAEA;;AAEG;AACH,IAAA,iBAAiB,CAAC,IAAiB,EAAA;AACjC,QAAA,OAAQ,IAAoD,CAACA,oBAAkB,CAAC;IAClF;AAEA;;AAEG;AACH,IAAA,iBAAiB,CAAC,MAA0E,EAAA;QAC1F,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM;QAEhD,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;QACpD,IAAI,YAAY,EAAE;YAChB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;YACvC,IAAI,OAAO,EAAE;AACX,gBAAA,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACvB,OAAO,CAAC,WAAW,EAAE;gBACrB,OAAO,CAAC,aAAa,EAAE;;AAGvB,gBAAA,IAAI,IAAI,CAAC,cAAc,EAAE,IAAI,KAAK,EAAE;oBAClC,IAAI,CAAC,4BAA4B,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC;gBAC1D;YACF;QACF;IACF;AAEA;;AAEG;IACH,gBAAgB,CAAC,KAAY,EAAE,MAA4B,EAAA;AACzD,QAAA,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM;QAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AAEpD,QAAA,IAAI,YAAY,IAAI,YAAY,CAAC,OAAO,EAAE;;YAExC,KAAK,CAAC,cAAc,EAAE;QACxB;IACF;AAEA;;;AAGG;AACH,IAAA,iBAAiB,CAAC,MAAmE,EAAA;QACnF,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM;QACjD,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;QAEpD,IAAI,YAAY,EAAE;YAChB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;YACvC,IAAI,OAAO,EAAE;gBACX,OAAO,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;gBACrD,OAAO,CAAC,cAAc,EAAE;YAC1B;QACF;IACF;AAEA;;AAEG;AACH,IAAA,4BAA4B,CAAC,KAAa,EAAE,KAAa,EAAE,OAAwB,EAAA;AACjF,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;;QAGX,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,GAAG,SAAS,CAAwC;AAE9F,QAAA,IAAI,CAAC,aAAa;YAAE;AAEpB,QAAA,IAAI,OAAO,CAAC,OAAO,EAAE;;YAEnB,MAAM,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC;YACxD,aAAa,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC;QACtD;aAAO;AACL,YAAA,aAAa,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;QAC1C;IACF;AAEA;;AAEG;AACH,IAAA,qBAAqB,CAAC,OAAwB,EAAA;AAC5C,QAAA,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM;AAC7B,QAAA,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,EAAE;QAEtB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvC,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC;;QAG9B,QAAQ,QAAQ;AACd,YAAA,KAAK,UAAU;AACb,gBAAA,OAAO,wBAAwB;AACjC,YAAA,KAAK,WAAW;AACd,gBAAA,OAAO,CAAA,kBAAA,EAAqB,KAAK,CAAC,cAAc,EAAE;AACpD,YAAA,KAAK,WAAW;AACd,gBAAA,OAAO,CAAA,kBAAA,EAAqB,KAAK,CAAC,cAAc,EAAE;AACpD,YAAA,KAAK,KAAK;AACR,gBAAA,OAAO,CAAA,iBAAA,EAAoB,KAAK,CAAC,GAAG,EAAE;AACxC,YAAA,KAAK,KAAK;AACR,gBAAA,OAAO,CAAA,iBAAA,EAAoB,KAAK,CAAC,GAAG,EAAE;AACxC,YAAA,KAAK,OAAO;AACV,gBAAA,OAAO,uBAAuB;AAChC,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,gBAAgB;AACzB,YAAA;;gBAEE,OAAO,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,IAAI,KAAK,EAAE,OAAO,IAAI,qBAAqB,QAAQ,CAAA,CAAE,CAAC;;IAEpG;uGA1bW,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAb,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAb,aAAa,EAAA,UAAA,EAAA,CAAA;kBAHzB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,qBAAqB;AAChC,iBAAA;;;ACzJD;AACA,MAAM,kBAAkB,GAAG,MAAM,CAAC,kBAAkB,CAAC;AAErD;;;;AAIG;AACG,SAAU,kBAAkB,CAAC,WAAwB,EAAA;AACzD,IAAA,OAAQ,WAA2D,CAAC,kBAAkB,CAAC;AACzF;AAmCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6EG;MAIU,YAAY,CAAA;AACf,IAAA,UAAU,GAAG,MAAM,EAAC,UAA6B,EAAC;;AAGlD,IAAA,cAAc,GAAG,IAAI,GAAG,EAAmB;;AAE3C,IAAA,WAAW,GAAG,IAAI,GAAG,EAAgB;;IAErC,eAAe,GAAkB,IAAI;IAErC,eAAe,GAAwB,IAAI;IAC3C,cAAc,GAAwB,IAAI;IAC1C,eAAe,GAAwB,IAAI;AAEnD;;;;;;;;;;;;AAYG;IACM,QAAQ,GAAG,KAAK,CAAC,QAAQ;iFAAyB;AAE3D;;;;;;;;;AASG;IACM,cAAc,GAAG,KAAK,CAAU,IAAI;uFAAC;AAE9C;;;;;;;AAOG;IACM,cAAc,GAAG,KAAK,CAAU,KAAK;uFAAC;AAE/C;;;AAGG;IACM,aAAa,GAAG,MAAM,EAA4B;IAE3D,QAAQ,GAAA;AACN,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;;AAGX,QAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;;AAG5B,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,EAAE,CAC5B,aAAa,EACb,CAAC,MAA6F,KAAI;AAChG,YAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;AAChC,QAAA,CAAC,CACF;;AAGD,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,MAA4C,EAAE,KAAkB,KAAI;AAC/G,YAAA,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC;AACtC,QAAA,CAAC,CAAC;;QAGF,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,MAAK;YACjD,IAAI,CAAC,kBAAkB,EAAE;AAC3B,QAAA,CAAC,CAAC;;QAGF,IAAI,CAAC,kBAAkB,EAAE;IAC3B;IAEA,WAAW,GAAA;AACT,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,IAAI,CAAC,eAAe,IAAI;AACxB,QAAA,IAAI,CAAC,cAAc,IAAI;AACvB,QAAA,IAAI,CAAC,eAAe,IAAI;AAExB,QAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;AAC5B,QAAA,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE;AAC3B,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE;IAC1B;;AAIA;;;AAGG;IACH,qBAAqB,CAAC,GAAS,EAAE,QAAgB,EAAA;QAC/C,IAAI,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;QAC5C,IAAI,CAAC,SAAS,EAAE;AACd,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC/B,YAAA,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC;YAClC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC;YACvC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC;QACrC;AACA,QAAA,OAAO,SAAS;IAClB;AAEA;;AAEG;AACH,IAAA,gBAAgB,CAAC,QAAgB,EAAA;AAC/B,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI;QACvB,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,IAAI,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,SAAS;AAEtE,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC1B,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;IACrC;AAEA;;;AAGG;AACH,IAAA,iBAAiB,CAAC,IAAuB,EAAA;AACvC,QAAA,MAAM,OAAO,GAAqB;AAChC,YAAA,MAAM,EAAE,CAAI,QAAgB,KAAc;AACxC,gBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;gBACtB,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,IAAI,IAAI,CAAC,MAAM;AAAE,oBAAA,OAAO,IAAI;AACjE,gBAAA,OAAO,IAAI,CAAC,QAAQ,CAAiB;YACvC,CAAC;YAED,WAAW,EAAE,CAAC,QAAgB,EAAE,KAAa,EAAE,KAAc,KAAI;gBAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;gBACjD,IAAI,SAAS,EAAE;oBACb,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;oBACpC,IAAI,OAAO,EAAE;AACX,wBAAA,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;wBACvB,OAAO,CAAC,WAAW,EAAE;oBACvB;gBACF;YACF,CAAC;YAED,QAAQ,EAAE,MAAa;AACrB,gBAAA,QAAQ,IAAI,CAAC,IAAI,IAAI,EAAE;YACzB,CAAC;;AAGD,YAAA,aAAa,EAAE,IAAI;AAEnB,YAAA,UAAU,EAAE,CAAC,QAAgB,EAAE,KAAa,KAAiC;AAC3E,gBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;gBACtB,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,IAAI,IAAI,CAAC,MAAM;AAAE,oBAAA,OAAO,SAAS;AAEtE,gBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAS;;gBAElC,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,QAAQ,CAAC;gBAC3D,OAAO,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,SAAS;YAC1C,CAAC;AAED,YAAA,eAAe,EAAE,CAAC,QAAgB,KAA2B;AAC3D,gBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;gBACtB,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,IAAI,IAAI,CAAC,MAAM;AAAE,oBAAA,OAAO,SAAS;AAEtE,gBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAS;;gBAElC,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,QAAQ,CAAC;YAClD,CAAC;AAED,YAAA,UAAU,EAAE,CAAC,QAAgB,KAAa;gBACxC,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;;AAEjD,gBAAA,IAAI,CAAC,SAAS;AAAE,oBAAA,OAAO,IAAI;gBAC3B,OAAO,SAAS,CAAC,KAAK;YACxB,CAAC;AAED,YAAA,YAAY,EAAE,CAAC,QAAgB,KAAa;gBAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AACjD,gBAAA,IAAI,CAAC,SAAS;AAAE,oBAAA,OAAO,KAAK;gBAC5B,OAAO,SAAS,CAAC,OAAO;YAC1B,CAAC;AAED,YAAA,UAAU,EAAE,CAAC,QAAgB,KAAa;gBACxC,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AACjD,gBAAA,IAAI,CAAC,SAAS;AAAE,oBAAA,OAAO,KAAK;gBAC5B,OAAO,SAAS,CAAC,KAAK;YACxB,CAAC;AAED,YAAA,YAAY,EAAE,CAAC,QAAgB,KAAoC;gBACjE,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AACjD,gBAAA,IAAI,CAAC,SAAS;AAAE,oBAAA,OAAO,IAAI;gBAE3B,MAAM,MAAM,GAA4B,EAAE;gBAC1C,IAAI,SAAS,GAAG,KAAK;AAErB,gBAAA,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;oBAChD,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;AACpC,oBAAA,IAAI,OAAO,EAAE,MAAM,EAAE;AACnB,wBAAA,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM;wBAC9B,SAAS,GAAG,IAAI;oBAClB;AACF,gBAAA,CAAC,CAAC;AAEF,gBAAA,IAAI,SAAS,CAAC,MAAM,EAAE;AACpB,oBAAA,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC,MAAM;oBACnC,SAAS,GAAG,IAAI;gBAClB;gBAEA,OAAO,SAAS,GAAG,MAAM,GAAG,IAAI;YAClC,CAAC;SACF;AAEA,QAAA,IAAoD,CAAC,kBAAkB,CAAC,GAAG,OAAO;IACrF;AAEA;;AAEG;AACH,IAAA,iBAAiB,CAAC,IAAuB,EAAA;AACvC,QAAA,OAAQ,IAAoD,CAAC,kBAAkB,CAAC;IAClF;;;AAMA;;;AAGG;IACH,kBAAkB,GAAA;AAChB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI;AACvB,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE;QACxB,IAAI,CAAC,OAAO,CAAC,CAAC,GAAS,EAAE,KAAa,KAAI;YACxC,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;gBAChC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;YAClC;AACF,QAAA,CAAC,CAAC;IACJ;AAEA;;AAEG;AACH,IAAA,iBAAiB,CAAC,MAA0E,EAAA;QAC1F,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM;QAEhD,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;QACjD,IAAI,SAAS,EAAE;YACb,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;YACpC,IAAI,OAAO,EAAE;AACX,gBAAA,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACvB,OAAO,CAAC,WAAW,EAAE;gBACrB,OAAO,CAAC,aAAa,EAAE;;AAGvB,gBAAA,IAAI,IAAI,CAAC,cAAc,EAAE,IAAI,KAAK,EAAE;oBAClC,IAAI,CAAC,4BAA4B,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC;gBAC1D;;AAGA,gBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;gBAC1C,MAAM,GAAG,GAAG,IAAI,EAAE,IAAI,GAAG,QAAQ,CAAC;gBAClC,IAAI,GAAG,EAAE;AACP,oBAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;wBACtB,QAAQ;wBACR,KAAK;wBACL,GAAG;wBACH,SAAS;wBACT,MAAM,EAAE,SAAS,CAAC,KAAK;wBACvB,KAAK,EAAE,SAAS,CAAC,KAAK;wBACtB,KAAK,EAAE,SAAS,CAAC,KAAK;AACvB,qBAAA,CAAC;gBACJ;YACF;QACF;IACF;AAEA;;;;;AAKG;IACH,gBAAgB,CAAC,KAAY,EAAE,MAA4C,EAAA;AACzE,QAAA,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,MAAM;AAClC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI;QACvB,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,IAAI,IAAI,CAAC,MAAM;YAAE;AAEtD,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;AAE9C,QAAA,IAAI,CAAC,SAAS;YAAE;;QAGhB,IAAI,IAAI,CAAC,cAAc,EAAE,IAAI,SAAS,CAAC,OAAO,EAAE;;YAE9C,SAAS,CAAC,gBAAgB,EAAE;YAC5B,KAAK,CAAC,cAAc,EAAE;YACtB;QACF;;AAGA,QAAA,IAAI,SAAS,CAAC,KAAK,EAAE;AACnB,YAAA,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK;YACjC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;AACvC,gBAAA,IAAI,KAAK,IAAI,GAAG,EAAE;oBACf,GAA+B,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC;gBAC5D;AACF,YAAA,CAAC,CAAC;QACJ;;AAGA,QAAA,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE;AAC1B,YAAA,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC;AAC/B,YAAA,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC;;YAG5B,IAAI,KAAK,EAAE;gBACT,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,GAAG,SAAS,CAAwC;AAC9F,gBAAA,aAAa,EAAE,eAAe,CAAC,KAAK,CAAC;YACvC;QACF;IACF;;;AAMA;;AAEG;AACH,IAAA,4BAA4B,CAAC,KAAa,EAAE,KAAa,EAAE,OAAwB,EAAA;AACjF,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;QAEX,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,GAAG,SAAS,CAAwC;AAE9F,QAAA,IAAI,CAAC,aAAa;YAAE;AAEpB,QAAA,IAAI,OAAO,CAAC,OAAO,EAAE;YACnB,MAAM,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC;YACxD,aAAa,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC;QACtD;aAAO;AACL,YAAA,aAAa,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;QAC1C;IACF;AAEA;;AAEG;AACH,IAAA,qBAAqB,CAAC,OAAwB,EAAA;AAC5C,QAAA,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM;AAC7B,QAAA,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,EAAE;QAEtB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvC,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC;QAE9B,QAAQ,QAAQ;AACd,YAAA,KAAK,UAAU;AACb,gBAAA,OAAO,wBAAwB;AACjC,YAAA,KAAK,WAAW;AACd,gBAAA,OAAO,CAAA,kBAAA,EAAqB,KAAK,CAAC,cAAc,EAAE;AACpD,YAAA,KAAK,WAAW;AACd,gBAAA,OAAO,CAAA,kBAAA,EAAqB,KAAK,CAAC,cAAc,EAAE;AACpD,YAAA,KAAK,KAAK;AACR,gBAAA,OAAO,CAAA,iBAAA,EAAoB,KAAK,CAAC,GAAG,EAAE;AACxC,YAAA,KAAK,KAAK;AACR,gBAAA,OAAO,CAAA,iBAAA,EAAoB,KAAK,CAAC,GAAG,EAAE;AACxC,YAAA,KAAK,OAAO;AACV,gBAAA,OAAO,uBAAuB;AAChC,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,gBAAgB;AACzB,YAAA;gBACE,OAAO,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,IAAI,KAAK,EAAE,OAAO,IAAI,qBAAqB,QAAQ,CAAA,CAAE,CAAC;;IAEpG;;;AAMA;;;;;;AAMG;AACH,IAAA,YAAY,CAAC,QAAgB,EAAA;AAC3B,QAAA,OAAO,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;IACxC;AAEA;;;;;AAKG;IACH,gBAAgB,GAAA;QACd,OAAO,IAAI,CAAC,cAAc;IAC5B;AAEA;;;AAGG;IACH,kBAAkB,GAAA;AAChB,QAAA,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE;AAC3B,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE;IAC1B;AAEA;;;;AAIG;IACH,WAAW,GAAA;QACT,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE;AACpD,YAAA,IAAI,SAAS,CAAC,OAAO,EAAE;gBACrB,SAAS,CAAC,gBAAgB,EAAE;AAC5B,gBAAA,OAAO,KAAK;YACd;QACF;AACA,QAAA,OAAO,IAAI;IACb;uGApbW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAZ,YAAY,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,aAAA,EAAA,eAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAZ,YAAY,EAAA,UAAA,EAAA,CAAA;kBAHxB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,oBAAoB;AAC/B,iBAAA;;;ACnGD;AACA,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAqD;AAE7F;;;AAGG;AACG,SAAU,2BAA2B,CACzC,aAA0B,EAAA;;IAG1B,MAAM,QAAQ,GAAG,wBAAwB,CAAC,GAAG,CAAC,aAAa,CAAC;AAC5D,IAAA,IAAI,QAAQ;AAAE,QAAA,OAAO,QAAQ;;IAG7B,MAAM,QAAQ,GAAG,aAAa,CAAC,aAAa,CAAC,wBAAwB,CAAC;IACtE,IAAI,QAAQ,EAAE;AACZ,QAAA,OAAO,iBAAiB,CAAC,QAAuB,CAAqD;IACvG;AACA,IAAA,OAAO,SAAS;AAClB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDG;MAEU,SAAS,CAAA;AACZ,IAAA,QAAQ,GAAG,MAAM,EAAC,WAAoC,EAAC;AACvD,IAAA,UAAU,GAAG,MAAM,EAAC,UAAuB,EAAC;IAC5C,aAAa,GAAuB,IAAI;AAEhD,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,gBAAgB,EAAE;AACzB,QAAA,CAAC,CAAC;IACJ;IAEQ,gBAAgB,GAAA;;QAEtB,IAAI,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,aAAa;AACzD,QAAA,OAAO,MAAM,IAAI,MAAM,CAAC,OAAO,KAAK,iBAAiB,IAAI,MAAM,CAAC,OAAO,KAAK,eAAe,EAAE;AAC3F,YAAA,MAAM,GAAG,MAAM,CAAC,aAAa;QAC/B;QAEA,IAAI,MAAM,EAAE;AACV,YAAA,IAAI,CAAC,aAAa,GAAG,MAAM;YAC3B,wBAAwB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC;QACrD;IACF;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,IAAI,CAAC,aAAa,EAAE;AACtB,YAAA,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;QACrD;IACF;AAEA;;;AAGG;AACH,IAAA,OAAO,sBAAsB,CAAC,GAAc,EAAE,GAAY,EAAA;AACxD,QAAA,OAAO,IAAI;IACb;uGApCW,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAT,SAAS,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAT,SAAS,EAAA,UAAA,EAAA,CAAA;kBADrB,SAAS;mBAAC,EAAE,QAAQ,EAAE,aAAa,EAAE;;;ACrHtC;;;;;;;;;;;;AAYG;AAqBH;;;;AAIG;MAMU,oBAAoB,CAAA;AACd,IAAA,UAAU,GAAG,MAAM,EAAC,UAA2B,EAAC;AAExD,IAAA,OAAO,GAAG,KAAK;2FAA6D;IAC5E,UAAU,GAAG,MAAM,EAAmB;IACtC,UAAU,GAAG,MAAM,EAAoB;IACvC,SAAS,GAAG,MAAM,EAAkB;;IAEpC,gBAAgB,GAAG,MAAM,EAA+B;;IAExD,QAAQ,GAAG,MAAM,EAAuB;;IAExC,eAAe,GAAG,MAAM,EAA8B;;IAEtD,SAAS,GAAG,MAAM,EAAwB;;IAE1C,WAAW,GAAG,MAAM,EAA0B;AAEtC,IAAA,SAAS,GAAG,IAAI,GAAG,EAA8B;IAC1D,OAAgB,MAAM,GAAG;QAC/B,aAAa;QACb,aAAa;QACb,YAAY;QACZ,oBAAoB;QACpB,WAAW;QACX,mBAAmB;QACnB,YAAY;QACZ,cAAc;KACN;AAEV,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;AAC3D,QAAA,KAAK,MAAM,EAAE,IAAI,oBAAoB,CAAC,MAAM;AAAE,YAAA,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;IACpE;IAEA,QAAQ,GAAA;AACN,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,MAAM,IAAI,GAAG,CAAI,IAAY,EAAE,GAA6B,KAAU;AACpE,YAAA,MAAM,CAAC,GAAG,CAAC,CAAQ,KAAW,GAAG,CAAC,IAAI,CAAE,CAAoB,CAAC,MAAM,CAAC;AACpE,YAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;AAC7B,QAAA,CAAC;AACD,QAAA,IAAI,CAAkB,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;AACrD,QAAA,IAAI,CAAmB,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;AACtD,QAAA,IAAI,CAAiB,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC;;AAElD,QAAA,IAAI,CAA8B,oBAAoB,EAAE,IAAI,CAAC,gBAAgB,CAAC;;AAE9E,QAAA,IAAI,CAAsB,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC;;AAErD,QAAA,IAAI,CAA6B,mBAAmB,EAAE,IAAI,CAAC,eAAe,CAAC;;AAE3E,QAAA,IAAI,CAAuB,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC;;AAExD,QAAA,IAAI,CAAyB,cAAc,EAAE,IAAI,CAAC,WAAW,CAAC;IAChE;IAEA,WAAW,GAAA;AACT,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;QAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS;AAAE,YAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,CAAC;AACzE,QAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;AACtB,QAAA,sBAAsB,CAAC,IAAI,EAAE,SAAS,CAAC;AACvC,QAAA,KAAK,MAAM,EAAE,IAAI,oBAAoB,CAAC,MAAM;AAAE,YAAA,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;IACtE;uGAhEW,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAApB,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,2MAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,UAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,SAAA,EAAA,WAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,WAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAApB,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBALhC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EACN,2MAA2M;AAC7M,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA;;;ACtCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DG;MAEmB,cAAc,CAAA;AACf,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AACjC,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;;IAGzC,iBAAiB,GAAwB,IAAI;;;;AAMrD;;;AAGG;AACM,IAAA,KAAK,GAAG,KAAK;yFAAU;AAEhC;;AAEG;AACM,IAAA,GAAG,GAAG,KAAK;uFAAQ;AAE5B;;AAEG;AACM,IAAA,MAAM,GAAG,KAAK;0FAAsB;AAE7C;;;AAGG;AACM,IAAA,OAAO,GAAG,KAAK;2FAAmB;;;;AAM3C;;;AAGG;IACM,MAAM,GAAG,MAAM,EAAiB;AAEzC;;AAEG;IACM,MAAM,GAAG,MAAM,EAAQ;;;;AAMhC;;;AAGG;AACM,IAAA,YAAY,GAAG,QAAQ,CAAqB,MAAK;AACxD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE;QAC3B,IAAI,IAAI,EAAE;YACR,OAAO,IAAI,CAAC,KAAe;QAC7B;AACA,QAAA,OAAO,IAAI,CAAC,KAAK,EAAE;IACrB,CAAC;qFAAC;AAEF;;;AAGG;AACM,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAK;QACjC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,IAAI,KAAK;IACzC,CAAC;kFAAC;AAEF;;;AAGG;AACM,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;QAC/B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,IAAI,KAAK;IACvC,CAAC;gFAAC;AAEF;;;AAGG;AACM,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAK;QACjC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,IAAI,KAAK;IACzC,CAAC;kFAAC;AAEF;;AAEG;AACM,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAK;AACjC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE;AAC3B,QAAA,OAAO,IAAI,EAAE,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC;IACpE,CAAC;kFAAC;AAEF;;;AAGG;AACM,IAAA,iBAAiB,GAAG,QAAQ,CAAC,MAAK;AACzC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE;QAC3B,IAAI,CAAC,IAAI,EAAE,MAAM;AAAE,YAAA,OAAO,EAAE;AAE5B,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5C,QAAA,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9D,CAAC;0FAAC;AAEF;;AAEG;AACM,IAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAK;AACxC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE;QAC3B,IAAI,CAAC,IAAI,EAAE,MAAM;AAAE,YAAA,OAAO,EAAE;AAE5B,QAAA,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC5F,CAAC;yFAAC;;;;AAMF,IAAA,WAAA,GAAA;QACE,eAAe,CAAC,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;AACpD,QAAA,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,MAAK;AAC9B,YAAA,IAAI,CAAC,iBAAiB,IAAI;AAC1B,YAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI;AAC/B,QAAA,CAAC,CAAC;IACJ;IAEQ,sBAAsB,GAAA;AAC5B,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,2BAA2B,CAEtE;AACR,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,IAAI,WAAqC;AACzC,QAAA,IAAI,UAAoC;QAExC,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC,mBAAmB,EAAE,MAAK;YAC9C,IAAI,CAAC,iBAAiB,EAAE;YACxB,WAAW,IAAI;YACf,WAAW,GAAG,SAAS;AACzB,QAAA,CAAC,CAAC;QAEF,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,MAAK;YACtC,IAAI,CAAC,WAAW,EAAE;YAClB,UAAU,IAAI;YACd,UAAU,GAAG,SAAS;AACxB,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,CAAC,iBAAiB,GAAG,MAAK;YAC5B,WAAW,IAAI;YACf,UAAU,IAAI;AAChB,QAAA,CAAC;IACH;;;;AAMA;;;;;;;;AAQG;IACO,aAAa,GAAA;AACrB,QAAA,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,KAAK;IAC1G;AAEA;;;;;;;;AAQG;IACO,iBAAiB,GAAA;;IAE3B;AAEA;;;;;;;;;AASG;IACO,WAAW,GAAA;;IAErB;AAEA;;;;;;;;;;;;AAYG;AACH,IAAA,qBAAqB,CAAC,OAAe,EAAA;;IAErC;AAEA;;;;AAIG;AACH,IAAA,WAAW,CAAC,QAAuB,EAAA;;AAEjC,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;;;QAI1B,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7G;AAEA;;;AAGG;IACH,UAAU,GAAA;;AAER,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;;AAGlB,QAAA,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3F;AAEA;;;;;;;AAOG;IACO,eAAe,CAAC,QAAgB,EAAE,UAAoB,EAAA;QAC9D,QAAQ,QAAQ;AACd,YAAA,KAAK,UAAU;AACb,gBAAA,OAAO,wBAAwB;YACjC,KAAK,WAAW,EAAE;gBAChB,MAAM,GAAG,GAAG,UAAyC;AACrD,gBAAA,OAAO,qBAAqB,GAAG,EAAE,cAAc,IAAI,SAAS,EAAE;YAChE;YACA,KAAK,WAAW,EAAE;gBAChB,MAAM,GAAG,GAAG,UAAyC;AACrD,gBAAA,OAAO,qBAAqB,GAAG,EAAE,cAAc,IAAI,SAAS,EAAE;YAChE;YACA,KAAK,KAAK,EAAE;gBACV,MAAM,GAAG,GAAG,UAA8B;AAC1C,gBAAA,OAAO,oBAAoB,GAAG,EAAE,GAAG,IAAI,SAAS,EAAE;YACpD;YACA,KAAK,KAAK,EAAE;gBACV,MAAM,GAAG,GAAG,UAA8B;AAC1C,gBAAA,OAAO,oBAAoB,GAAG,EAAE,GAAG,IAAI,SAAS,EAAE;YACpD;AACA,YAAA,KAAK,OAAO;AACV,gBAAA,OAAO,uBAAuB;AAChC,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,gBAAgB;AACzB,YAAA;gBACE,OAAO,CAAA,eAAA,EAAkB,QAAQ,CAAA,CAAA,CAAG;;IAE1C;uGAvRoB,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAd,cAAc,EAAA,YAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAd,cAAc,EAAA,UAAA,EAAA,CAAA;kBADnC;;;AC9DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDG;AAEG,MAAgB,iBACpB,SAAQ,cAA4B,CAAA;;;;;;AAS5B,IAAA,SAAS,GAAmC,MAAK,EAAE,CAAC;;;AAIpD,IAAA,UAAU,GAAe,MAAK,EAAE,CAAC;AAEzC;;;AAGG;IACgB,QAAQ,GAAG,MAAM,CAAgB,IAAI;iFAAC;AAEzD;;;AAGG;IACM,aAAa,GAAG,MAAM,CAAC,KAAK;sFAAC;AAEtC;;;;;;;;AAQG;AACM,IAAA,YAAY,GAAG,QAAQ,CAAgB,MAAK;QACnD,OAAQ,IAAI,CAAC,YAAY,EAAyB,IAAI,IAAI,CAAC,QAAQ,EAAE;IACvE,CAAC;qFAAC;;;;AAMF;;AAEG;AACH,IAAA,UAAU,CAAC,KAAoB,EAAA;AAC7B,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;IAC1B;AAEA;;AAEG;AACH,IAAA,gBAAgB,CAAC,EAAkC,EAAA;AACjD,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;IACrB;AAEA;;AAEG;AACH,IAAA,iBAAiB,CAAC,EAAc,EAAA;AAC9B,QAAA,IAAI,CAAC,UAAU,GAAG,EAAE;IACtB;AAEA;;AAEG;AACH,IAAA,gBAAgB,CAAC,UAAmB,EAAA;AAClC,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC;IACpC;;;;AAMA;;;;;;;;;;AAUG;AACO,IAAA,UAAU,CAAC,KAAoB,EAAA;;AAEvC,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;AACxB,QAAA,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;QACrB,IAAI,CAAC,UAAU,EAAE;;;AAIjB,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;IACzB;uGAjGoB,iBAAiB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAjB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBADtC;;;ACvCD;AAEA;AAEA;AACA,IAAI,qBAAqB,GAAG,KAAK;AAEjC;;;;;;AAMG;AACH,MAAM,cAAc,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqDhC;AAED,SAAS,mBAAmB,GAAA;AAC1B,IAAA,IAAI,qBAAqB;QAAE;IAC3B,qBAAqB,GAAG,IAAI;IAE5B,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC;AAC7C,IAAA,KAAK,CAAC,YAAY,CAAC,kBAAkB,EAAE,EAAE,CAAC;AAC1C,IAAA,KAAK,CAAC,WAAW,GAAG,cAAc;AAClC,IAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AAClC;AAEA;AAEA;AACA,IAAI,aAAa,GAAG,CAAC;AACrB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiGG;AAEG,MAAgB,iBAAoD,SAAQ,cAA4B,CAAA;AAC3F,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;AAChC,IAAA,kBAAkB,GAAG,MAAM,CAAC,UAAU,CAAC;;;;AAMxD;;;;;AAKG;IACO,eAAe,GAAoB,OAAO;;;;;IAO5C,MAAM,GAAuB,IAAI;;IAG/B,OAAO,GAAG,KAAK;;IAGjB,SAAS,GAAG,EAAE;;IAGd,eAAe,GAAG,KAAK;;IAGvB,UAAU,GAA2B,IAAI;;IAGvC,cAAc,GAA4B,IAAI;;;;AAMxD,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,eAAe,GAAG,OAAO,GAAG,KAAK,WAAW,IAAI,GAAG,CAAC,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAC;AACvF,QAAA,mBAAmB,EAAE;QAErB,eAAe,CAAC,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;AACjD,QAAA,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;IACjE;;;;AAMA;;;;;;;AAOG;AACO,IAAA,WAAW,CAAC,KAAkB,EAAA;AACtC,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;;AAGnB,QAAA,IAAI,CAAC,SAAS,GAAG,cAAc,EAAE,aAAa,EAAE;AAChD,QAAA,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACxC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,eAAe,CAAC;QACpD,KAAK,CAAC,YAAY,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC;AACpD,QAAA,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM;;AAG5B,QAAA,IAAI,IAAI,CAAC,eAAe,EAAE;AACxB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;YAC5B,IAAI,IAAI,EAAE;AACR,gBAAA,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,CAAA,EAAA,EAAK,IAAI,CAAC,SAAS,CAAA,CAAE,CAAC;AAC5D,gBAAA,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,sBAAsB,EAAE,CAAA,EAAA,EAAK,IAAI,CAAC,SAAS,CAAA,CAAE,CAAC;YACxE;QACF;;AAGA,QAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;;;QAIhC,IAAI,CAAC,eAAe,EAAE,EAAE,8BAA8B,GAAG,KAAK,CAAC;;AAG/D,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI,eAAe,EAAE;AACvC,QAAA,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE;AAC9E,YAAA,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM;AAC/B,SAAA,CAAC;;;;;AAMF,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,EAAE;QACnC,IAAI,IAAI,EAAE;AACR,YAAA,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC,aAAa,EAAE,EAAE;AAC9D,gBAAA,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM;AAC/B,aAAA,CAAC;QACJ;;;;AAKA,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE;YACrD,IAAI,CAAC,WAAW,EAAE;YAClB,IAAI,CAAC,eAAe,EAAE;QACxB;IACF;AAEA;;;;;AAKG;IACO,WAAW,GAAA;AACnB,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO;YAAE;AAElC,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI;QACnB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE;;AAG9B,QAAA,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;YACzB,IAAI,CAAC,eAAe,EAAE;QACxB;IACF;AAEA;;;;;AAKG;AACO,IAAA,WAAW,CAAC,kBAA4B,EAAA;QAChD,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;AAEnC,QAAA,IAAI,CAAC,OAAO,GAAG,KAAK;QACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM;QAElC,IAAI,CAAC,kBAAkB,EAAE;AACvB,YAAA,IAAI,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE;QAChC;IACF;AAEA;;;AAGG;IACO,aAAa,GAAA;QACrB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE;AAClB,QAAA,IAAI,CAAC,OAAO,GAAG,KAAK;QACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM;QAClC,IAAI,CAAC,WAAW,EAAE;IACpB;AAEA;;;;;AAKG;IACO,eAAe,GAAA;AACvB,QAAA,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE;AACxB,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI;AAEtB,QAAA,IAAI,CAAC,cAAc,EAAE,UAAU,EAAE;AACjC,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI;;AAG1B,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,IAAI,CAAC,eAAe,EAAE,EAAE,gCAAgC,GAAG,IAAI,CAAC,MAAM,CAAC;QACzE;AAEA,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE;YAC3B,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC;QACjD;AACA,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,QAAA,IAAI,CAAC,OAAO,GAAG,KAAK;;AAGpB,QAAA,IAAI,IAAI,CAAC,eAAe,EAAE;AACxB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;YAC5B,IAAI,IAAI,EAAE;AACR,gBAAA,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,CAAC;YAC1C;QACF;IACF;AAEA;;;;AAIG;IACgB,WAAW,GAAA;AAC5B,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IACxB;;;;AAMA;;;;;;;AAOG;AACH,IAAA,eAAe,CAAC,KAAoB,EAAA;AAClC,QAAA,QAAQ,KAAK,CAAC,GAAG;AACf,YAAA,KAAK,OAAO;AACZ,YAAA,KAAK,GAAG;AACR,YAAA,KAAK,WAAW;AAChB,YAAA,KAAK,IAAI;gBACP,KAAK,CAAC,cAAc,EAAE;gBACtB,IAAI,CAAC,WAAW,EAAE;gBAClB,IAAI,CAAC,eAAe,EAAE;gBACtB;AACF,YAAA,KAAK,QAAQ;AACX,gBAAA,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;gBACxB;;IAEN;AAEA;;;;;AAKG;IACH,aAAa,GAAA;AACX,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,IAAI,CAAC,WAAW,EAAE;QACpB;aAAO;YACL,IAAI,CAAC,WAAW,EAAE;YAClB,IAAI,CAAC,eAAe,EAAE;QACxB;IACF;AAEA;;;;;AAKG;AACO,IAAA,YAAY,CAAC,KAAY,EAAA;AACjC,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,KAAK,CAAC,eAAe,EAAE;YACvB,IAAI,CAAC,WAAW,EAAE;QACpB;aAAO;YACL,IAAI,CAAC,UAAU,EAAE;QACnB;IACF;AAEA;;;;;;;AAOG;IACO,gBAAgB,CAAC,QAAQ,GAAG,KAAK,EAAA;AACzC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC5B,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,IAAI,CAAC,aAAa,CAChB,IAAI,aAAa,CAAC,SAAS,EAAE;AAC3B,YAAA,GAAG,EAAE,KAAK;AACV,YAAA,QAAQ,EAAE,QAAQ;AAClB,YAAA,OAAO,EAAE,IAAI;AACb,YAAA,UAAU,EAAE,IAAI;AACjB,SAAA,CAAC,CACH;IACH;AAsBA;;;;;AAKG;IACO,eAAe,GAAA;;IAEzB;;;;;IAOQ,QAAQ,GAAA;AACd,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,IAAI;IACxE;;IAGQ,eAAe,GAAA;AAMrB,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,2BAA2B,CAAC,IAAI,IAAI;IACpF;AAEA;;;AAGG;IACK,eAAe,GAAA;AACrB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC5B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM;AACzB,QAAA,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK;YAAE;AAErB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,qBAAqB,EAAE;;AAG7C,QAAA,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,QAAQ;AACjC,QAAA,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE;AACxB,QAAA,MAAM,SAAS,GAAG,KAAK,CAAC,qBAAqB,EAAE;AAC/C,QAAA,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE;AAE3B,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW;AACpC,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU;AAEnC,QAAA,IAAI,GAAW;AACf,QAAA,IAAI,IAAY;AAEhB,QAAA,QAAQ,IAAI,CAAC,eAAe;YAC1B,KAAK,OAAO,EAAE;gBACZ,GAAG,GAAG,QAAQ,CAAC,GAAG,GAAG,SAAS,CAAC,MAAM;AACrC,gBAAA,IAAI,GAAG,QAAQ,CAAC,IAAI;;gBAEpB,IAAI,GAAG,GAAG,CAAC;AAAE,oBAAA,GAAG,GAAG,QAAQ,CAAC,MAAM;gBAClC;YACF;YACA,KAAK,aAAa,EAAE;AAClB,gBAAA,GAAG,GAAG,QAAQ,CAAC,MAAM;gBACrB,IAAI,GAAG,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK;;AAEvC,gBAAA,IAAI,GAAG,GAAG,SAAS,CAAC,MAAM,GAAG,SAAS;oBAAE,GAAG,GAAG,QAAQ,CAAC,GAAG,GAAG,SAAS,CAAC,MAAM;gBAC7E;YACF;YACA,KAAK,eAAe,EAAE;AACpB,gBAAA,GAAG,GAAG,QAAQ,CAAC,GAAG;AAClB,gBAAA,IAAI,GAAG,QAAQ,CAAC,IAAI;gBACpB;YACF;YACA,KAAK,kBAAkB,EAAE;gBACvB,GAAG,GAAG,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM;AACxC,gBAAA,IAAI,GAAG,QAAQ,CAAC,IAAI;gBACpB;YACF;AACA,YAAA,KAAK,OAAO;YACZ,SAAS;AACP,gBAAA,GAAG,GAAG,QAAQ,CAAC,MAAM;AACrB,gBAAA,IAAI,GAAG,QAAQ,CAAC,IAAI;;AAEpB,gBAAA,IAAI,GAAG,GAAG,SAAS,CAAC,MAAM,GAAG,SAAS;oBAAE,GAAG,GAAG,QAAQ,CAAC,GAAG,GAAG,SAAS,CAAC,MAAM;gBAC7E;YACF;;;AAIF,QAAA,IAAI,IAAI,GAAG,SAAS,CAAC,KAAK,GAAG,SAAS;YAAE,IAAI,GAAG,SAAS,GAAG,SAAS,CAAC,KAAK,GAAG,CAAC;QAC9E,IAAI,IAAI,GAAG,CAAC;YAAE,IAAI,GAAG,CAAC;QACtB,IAAI,GAAG,GAAG,CAAC;YAAE,GAAG,GAAG,CAAC;QAEpB,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAA,EAAG,GAAG,IAAI;QAC5B,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,CAAA,EAAG,IAAI,IAAI;IAChC;AAEA;;;;AAIG;AACK,IAAA,sBAAsB,CAAC,KAAmB,EAAA;QAChD,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE;AAEnC,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAc;AACnC,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa;;AAG7C,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE;QAE7D,IAAI,CAAC,qBAAqB,EAAE;IAC9B;AAEA;;;;;;;;AAQG;IACK,aAAa,GAAA;QACnB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE;QACnC,IAAI,CAAC,qBAAqB,EAAE;IAC9B;AAEA;;;;;;;;;;AAUG;IACO,mBAAmB,GAAA;AAC3B,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC5B,QAAA,IAAI,CAAC,IAAI;YAAE;QAEX,IAAI,UAAU,GAAG,KAAK;QAEtB,IAAI,cAAc,GAAG,CAAC;AAEtB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa;QAE7C,IAAI,CAAC,cAAc,GAAG,IAAI,gBAAgB,CAAC,CAAC,SAAS,KAAI;;;;;YAKvD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AAC1B,gBAAA,IAAI,CAAC,cAAc,EAAE,UAAU,EAAE;AACjC,gBAAA,IAAI,CAAC,cAAc,GAAG,IAAI;gBAC1B;YACF;AAEA,YAAA,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;gBAChC,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY,IAAI,QAAQ,CAAC,aAAa,KAAK,OAAO;oBAAE;gBAE1E,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC;AACvD,gBAAA,IAAI,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;;oBAE9B,IAAI,cAAc,EAAE;wBAClB,oBAAoB,CAAC,cAAc,CAAC;wBACpC,cAAc,GAAG,CAAC;oBACpB;oBACA,UAAU,GAAG,IAAI;oBACjB,IAAI,CAAC,WAAW,EAAE;oBAClB,IAAI,CAAC,eAAe,EAAE;;;;oBAItB,UAAU,CAAC,MAAK;wBACd,UAAU,GAAG,KAAK;oBACpB,CAAC,EAAE,CAAC,CAAC;gBACP;qBAAO,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,EAAE;;;;;;AAMpD,oBAAA,IAAI,cAAc;wBAAE,oBAAoB,CAAC,cAAc,CAAC;AACxD,oBAAA,cAAc,GAAG,qBAAqB,CAAC,MAAK;wBAC1C,cAAc,GAAG,CAAC;;AAElB,wBAAA,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE;AAC1D,4BAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;wBACxB;AACF,oBAAA,CAAC,CAAC;gBACJ;YACF;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACrF;uGApfoB,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAjB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBADtC;;;ACxMD;;;;;;;;;;;;;;;;;;;AAmBG;AAoCH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,CACtB,CAAe,OAAoB,EAAE,OAAoB,KAAgD;;;;;;;;;;AAUvG,IAAA,MAAM,QAAQ,IAAI,2BAA2B,CAAC,OAAO,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAEvE;IAEb,IAAI,CAAC,QAAQ,EAAE;;;;AAIb,QAAA,OAAO,SAAS;IAClB;;IAGA,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAuB;IAEtF,OAAO,CAAC,GAAsC,KAAI;AAChD,QAAA,MAAM,QAAQ,GAAG,CAAC,KAAa,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;QACrD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE;;;;;;AAOnC,QAAA,IAAI,OAAmD;QACvD,IAAI,WAAW,EAAE;YACf,MAAM,WAAW,GAAG,mBAAmB,CAAC,WAAW,CAAC,IAAI,kBAAkB,CAAC,WAAW,CAAC;AACvF,YAAA,IAAI,WAAW,EAAE,aAAa,EAAE;AAC9B,gBAAA,MAAM,QAAQ,GAAI,WAAiC,CAAC,IAAI;gBACxD,IAAI,QAAQ,EAAE;oBACZ,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;AAC1C,oBAAA,IAAI,QAAQ,IAAI,CAAC,EAAE;wBACjB,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAe,CAAC;oBACjE;gBACF;YACF;QACF;AAEA,QAAA,MAAM,OAAO,GAAoC;YAC/C,SAAS,EAAE,GAAG,CAAC,KAAK;YACpB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,KAAK,EAAE,GAAG,CAAC,KAAe;YAC1B,MAAM,EAAE,GAAG,CAAC,MAAM;AAClB,YAAA,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE;YACtB,QAAQ;YACR,QAAQ;YACR,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,aAAa,EAAE,GAAG,CAAC,aAAa;YAChC,OAAO;SACR;;;;AAKD,QAAA,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC;;;;QAKlF,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAQ,KAAI;AAChD,YAAA,GAAG,CAAC,MAAM,CAAE,CAAyB,CAAC,MAAM,CAAC;AAC/C,QAAA,CAAC,CAAC;AACF,QAAA,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAK;YACxC,GAAG,CAAC,MAAM,EAAE;AACd,QAAA,CAAC,CAAC;;;;AAKF,QAAA,GAAG,CAAC,aAAa,GAAG,CAAC,MAAe,KAAI;AACtC,YAAA,OAAO,CAAC,SAAS,GAAG,MAAgB;AACpC,YAAA,OAAO,CAAC,KAAK,GAAG,MAAgB;YAChC,OAAO,CAAC,aAAa,EAAE;AACvB,YAAA,OAAO,CAAC,sBAAsB,CAAC,OAAO,EAAE,SAAS,CAAC;AACpD,QAAA,CAAC,CAAC;AAEF,QAAA,OAAO,SAAS;AAClB,IAAA,CAAC;AACH,CAAC,CACF;AAED;AACA;AACA;AACA;AACA;AACA,uBAAuB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,KAAI;AAChD,IAAA,MAAM,KAAK,GAAG,qBAAqB,CAAC,SAAS,CAAC;AAC9C,IAAA,MAAM,CAAC,gBAAgB,CAAC,mBAAmB,EAAE,KAAK,CAAC;IACnD,OAAO,MAAM,MAAM,CAAC,mBAAmB,CAAC,mBAAmB,EAAE,KAAK,CAAC;AACrE,CAAC,CAAC;;ACnKF;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"toolbox-web-grid-angular-features-editing.mjs","sources":["../../../../libs/grid-angular/features/editing/src/grid-column-editor.directive.ts","../../../../libs/grid-angular/features/editing/src/grid-form-array.directive.ts","../../../../libs/grid-angular/features/editing/src/grid-lazy-form.directive.ts","../../../../libs/grid-angular/features/editing/src/structural-editor.directive.ts","../../../../libs/grid-angular/features/editing/src/grid-editing.directive.ts","../../../../libs/grid-angular/features/editing/src/base-grid-editor.ts","../../../../libs/grid-angular/features/editing/src/base-grid-editor-cva.ts","../../../../libs/grid-angular/features/editing/src/base-overlay-editor.ts","../../../../libs/grid-angular/features/editing/src/index.ts","../../../../libs/grid-angular/features/editing/src/toolbox-web-grid-angular-features-editing.ts"],"sourcesContent":["import { contentChild, Directive, effect, ElementRef, inject, TemplateRef } from '@angular/core';\nimport type { AbstractControl } from '@angular/forms';\n\n/**\n * Context object passed to the cell editor template.\n * Contains the cell value, row data, column configuration, and commit/cancel functions.\n * @since 0.1.0\n */\nexport interface GridEditorContext<TValue = unknown, TRow = unknown> {\n /** The cell value for this column */\n $implicit: TValue;\n /** The cell value (explicit binding) */\n value: TValue;\n /** The full row data object */\n row: TRow;\n /** Field name being edited */\n field: string;\n /** The column configuration */\n column: unknown;\n /** Stable row identifier (from `getRowId`). Empty string if no `getRowId` is configured. */\n rowId: string;\n /**\n * Callback function to commit the edited value.\n * Use with Angular event binding: `(commit)=\"onCommit($event)\"`\n */\n onCommit: (value: TValue) => void;\n /**\n * Callback function to cancel editing.\n * Use with Angular event binding: `(cancel)=\"onCancel()\"`\n */\n onCancel: () => void;\n /**\n * Update other fields in this row while the editor is open.\n * Changes trigger `cell-change` events with source `'cascade'`.\n */\n updateRow: (changes: Partial<TRow>) => void;\n /**\n * Register a callback to receive value updates when the cell is modified\n * externally (e.g., via `updateRow()` from another cell's commit).\n *\n * The framework adapter auto-patches `value`/`$implicit` for template editors,\n * but custom components may use this for additional reactivity.\n */\n onValueChange?: (callback: (newValue: TValue) => void) => void;\n /**\n * The FormControl for this cell, if the grid is bound to a FormArray with FormGroups.\n *\n * This allows custom editors to bind directly to the control for validation display:\n * ```html\n * <input *tbwEditor=\"let value; control as ctrl\"\n * [formControl]=\"ctrl\"\n * [class.is-invalid]=\"ctrl?.invalid && ctrl?.touched\" />\n * ```\n *\n * Returns `undefined` if:\n * - The grid is not bound to a FormArray\n * - The FormArray doesn't contain FormGroups\n * - The field doesn't exist in the FormGroup\n */\n control?: AbstractControl;\n}\n\n// Global registry mapping DOM elements to their templates\nconst editorTemplateRegistry = new Map<HTMLElement, TemplateRef<GridEditorContext>>();\n\n/**\n * Gets the editor template registered for a given element.\n * Used by AngularGridAdapter to retrieve templates at render time.\n */\nexport function getEditorTemplate(element: HTMLElement): TemplateRef<GridEditorContext> | undefined {\n return editorTemplateRegistry.get(element);\n}\n\n/**\n * Directive that captures an `<ng-template>` for use as a cell editor.\n *\n * This enables declarative Angular component usage with proper input bindings\n * that satisfy Angular's AOT compiler.\n *\n * ## Usage\n *\n * ```html\n * <tbw-grid-column field=\"status\" editable>\n * <tbw-grid-column-editor>\n * <ng-template let-value let-row=\"row\" let-onCommit=\"onCommit\" let-onCancel=\"onCancel\">\n * <app-status-select\n * [value]=\"value\"\n * [row]=\"row\"\n * (commit)=\"onCommit($event)\"\n * (cancel)=\"onCancel()\"\n * />\n * </ng-template>\n * </tbw-grid-column-editor>\n * </tbw-grid-column>\n * ```\n *\n * The template context provides:\n * - `$implicit` / `value`: The cell value\n * - `row`: The full row data object\n * - `column`: The column configuration\n * - `onCommit`: Callback function to commit the new value\n * - `onCancel`: Callback function to cancel editing\n *\n * Import the directive in your component:\n *\n * ```typescript\n * import { GridColumnEditor } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * imports: [GridColumnEditor],\n * // ...\n * })\n * ```\n *\n * @category Directive\n *\n * @since 0.1.0\n */\n@Directive({ selector: 'tbw-grid-column-editor' })\nexport class GridColumnEditor {\n private elementRef = inject(ElementRef<HTMLElement>);\n\n /**\n * Query for the ng-template content child.\n */\n template = contentChild(TemplateRef<GridEditorContext>);\n\n /** Effect that triggers when the template is available */\n private onTemplateReceived = effect(() => {\n const template = this.template();\n if (template) {\n // Register the template for this element\n editorTemplateRegistry.set(this.elementRef.nativeElement, template);\n }\n });\n\n /**\n * Static type guard for template context.\n * Enables type inference in templates.\n */\n static ngTemplateContextGuard(dir: GridColumnEditor, ctx: unknown): ctx is GridEditorContext {\n return true;\n }\n}\n","import { DestroyRef, Directive, effect, ElementRef, inject, input, OnDestroy, OnInit } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { AbstractControl, FormArray, FormGroup } from '@angular/forms';\nimport type { DataGridElement as GridElement } from '@toolbox-web/grid';\nimport { Subscription } from 'rxjs';\nimport { debounceTime, startWith } from 'rxjs/operators';\n\n/**\n * Interface for EditingPlugin validation methods.\n * We use a minimal interface to avoid importing the full EditingPlugin class.\n */\ninterface EditingPluginValidation {\n setInvalid(rowId: string, field: string, message?: string): void;\n clearInvalid(rowId: string, field: string): void;\n clearRowInvalid(rowId: string): void;\n}\n\n/**\n * Interface for EditingPlugin config to check mode.\n */\ninterface EditingPluginConfig {\n config?: { mode?: 'row' | 'grid' };\n}\n\n/**\n * Context provided to the grid containing form-related information.\n * This can be accessed by other directives to get form controls.\n * @since 0.5.0\n */\nexport interface FormArrayContext {\n /** Get the row data at a specific index */\n getRow<T = unknown>(rowIndex: number): T | null;\n /** Update a field value at a specific row */\n updateField(rowIndex: number, field: string, value: unknown): void;\n /** Get the current form value (all rows) */\n getValue<T = unknown>(): T[];\n /**\n * Get the FormControl for a specific cell.\n * Only available when using FormArray with FormGroup rows.\n *\n * @param rowIndex - The row index\n * @param field - The field name\n * @returns The AbstractControl for the cell, or undefined if not available\n */\n getControl(rowIndex: number, field: string): AbstractControl | undefined;\n /**\n * Whether the grid is backed by a FormArray of FormGroups.\n * When true, `getControl()` will return cell-level controls.\n */\n hasFormGroups: boolean;\n /**\n * Get the FormGroup for a specific row.\n * Only available when using FormArray with FormGroup rows.\n *\n * @param rowIndex - The row index\n * @returns The FormGroup for the row, or undefined if not available\n */\n getRowFormGroup(rowIndex: number): FormGroup | undefined;\n /**\n * Check if a row is valid (all controls in the FormGroup are valid).\n * Returns true if not using FormArray or if the row doesn't exist.\n *\n * @param rowIndex - The row index\n * @returns true if the row is valid, false if any control is invalid\n */\n isRowValid(rowIndex: number): boolean;\n /**\n * Check if a row has been touched (any control in the FormGroup is touched).\n * Returns false if not using FormArray or if the row doesn't exist.\n *\n * @param rowIndex - The row index\n * @returns true if any control in the row is touched\n */\n isRowTouched(rowIndex: number): boolean;\n /**\n * Check if a row is dirty (any control in the FormGroup is dirty).\n * Returns false if not using FormArray or if the row doesn't exist.\n *\n * @param rowIndex - The row index\n * @returns true if any control in the row is dirty\n */\n isRowDirty(rowIndex: number): boolean;\n /**\n * Get validation errors for a specific row.\n * Aggregates errors from all controls in the FormGroup.\n *\n * @param rowIndex - The row index\n * @returns Object with field names as keys and their errors, or null if no errors\n */\n getRowErrors(rowIndex: number): Record<string, unknown> | null;\n}\n\n// Symbol for storing form context on the grid element\nconst FORM_ARRAY_CONTEXT = Symbol('formArrayContext');\n\n/**\n * Gets the FormArrayContext from a grid element, if present.\n * @internal\n * @since 0.5.0\n */\nexport function getFormArrayContext(gridElement: HTMLElement): FormArrayContext | undefined {\n return (gridElement as unknown as Record<symbol, FormArrayContext>)[FORM_ARRAY_CONTEXT];\n}\n\n/**\n * Directive that binds a FormArray directly to the grid.\n *\n * This is the recommended way to integrate tbw-grid with Angular Reactive Forms.\n * Use a FormArray of FormGroups for row-level validation and cell-level control access.\n *\n * ## Usage\n *\n * ```typescript\n * import { Component, inject } from '@angular/core';\n * import { FormBuilder, ReactiveFormsModule } from '@angular/forms';\n * import { Grid, GridFormArray } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * imports: [Grid, GridFormArray, ReactiveFormsModule],\n * template: \\`\n * <form [formGroup]=\"form\">\n * <tbw-grid [formArray]=\"form.controls.rows\" [columns]=\"columns\" />\n * </form>\n * \\`\n * })\n * export class MyComponent {\n * private fb = inject(FormBuilder);\n *\n * form = this.fb.group({\n * rows: this.fb.array([\n * this.fb.group({ name: 'Alice', age: 30 }),\n * this.fb.group({ name: 'Bob', age: 25 }),\n * ])\n * });\n *\n * columns = [\n * { field: 'name', header: 'Name', editable: true },\n * { field: 'age', header: 'Age', editable: true }\n * ];\n * }\n * ```\n *\n * ## How It Works\n *\n * - **FormArray → Grid**: The grid displays the FormArray's value as rows\n * - **Grid → FormArray**: When a cell is edited, the corresponding FormControl is updated\n * - FormArrayContext is available for accessing cell-level controls\n *\n * ## Features\n *\n * - Works naturally with FormArray inside a FormGroup\n * - Provides cell-level FormControl access for validation\n * - Supports row-level validation state aggregation\n * - Automatically syncs FormArray changes to the grid\n *\n * @example\n * ```html\n * <form [formGroup]=\"form\">\n * <tbw-grid [formArray]=\"form.controls.rows\" [columns]=\"columns\" />\n * </form>\n * ```\n *\n * @category Directive\n *\n * @since 0.5.0\n */\n@Directive({\n selector: 'tbw-grid[formArray]',\n})\nexport class GridFormArray implements OnInit, OnDestroy {\n private readonly destroyRef = inject(DestroyRef);\n private elementRef = inject(ElementRef<GridElement>);\n private cellCommitUnsub: (() => void) | null = null;\n private cellCancelUnsub: (() => void) | null = null;\n private rowCommitUnsub: (() => void) | null = null;\n private touchListener: ((e: Event) => void) | null = null;\n private valueChangesSubscription: Subscription | null = null;\n private statusChangesSubscriptions: Subscription[] = [];\n\n /**\n * The FormArray to bind to the grid.\n */\n readonly formArray = input.required<FormArray>();\n\n /**\n * Whether to automatically sync Angular validation state to grid's visual invalid styling.\n *\n * When enabled:\n * - After a cell commit, if the FormControl is invalid, the cell is marked with `setInvalid()`\n * - When a FormControl becomes valid, `clearInvalid()` is called\n * - On `row-commit`, if the row's FormGroup has invalid controls, the commit is prevented\n * - In grid mode: validation state is synced on initial render and updated reactively\n *\n * @default true\n */\n readonly syncValidation = input<boolean>(true);\n\n /**\n * Effect that sets up valueChanges subscription when FormArray changes.\n * This handles both initial binding and when the FormArray reference changes.\n */\n private syncFormArrayToGrid = effect(() => {\n const formArray = this.formArray();\n const grid = this.elementRef.nativeElement;\n if (!grid || !formArray) return;\n\n // Unsubscribe from previous FormArray if any\n this.valueChangesSubscription?.unsubscribe();\n\n // Subscribe to valueChanges to sync grid rows when FormArray content changes.\n // Use startWith to immediately sync the current value.\n // Note: We use getRawValue() to include disabled controls.\n //\n // In grid mode, editors bind directly to FormControls, so every keystroke\n // fires valueChanges. We skip the sync when an editor input is focused to\n // prevent destroying/recreating editors mid-edit (which orphans overlays\n // like mat-autocomplete/mat-select panels and causes focus loss).\n this.valueChangesSubscription = formArray.valueChanges\n .pipe(startWith(formArray.getRawValue()), takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n // Skip sync while an editor is actively focused in the grid.\n // The FormArray already has the latest values via its own controls;\n // re-setting grid.rows would create new object references and trigger\n // an unnecessary render cycle.\n if (this.#isEditorFocused(grid)) return;\n\n grid.rows = formArray.getRawValue();\n });\n });\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n // Store the form context on the grid element for other directives to access\n this.#storeFormContext(grid);\n\n // Intercept cell-commit events to update the FormArray\n this.cellCommitUnsub = grid.on(\n 'cell-commit',\n (detail: { rowIndex: number; field: string; value: unknown; oldValue: unknown; rowId: string }) => {\n this.#handleCellCommit(detail);\n },\n );\n\n // Intercept cell-cancel events to revert FormControls (grid mode Escape)\n this.cellCancelUnsub = grid.on(\n 'cell-cancel',\n (detail: { rowIndex: number; field: string; previousValue: unknown }) => {\n this.#handleCellCancel(detail);\n },\n );\n\n // Intercept row-commit events to prevent if FormGroup is invalid\n this.rowCommitUnsub = grid.on(\n 'row-commit',\n (detail: { rowIndex: number; rowId?: string; changed: boolean }, event: CustomEvent) => {\n if (!this.syncValidation()) return;\n this.#handleRowCommit(event, detail);\n },\n );\n\n // Mark FormArray as touched on first interaction\n this.touchListener = () => {\n this.formArray().markAsTouched();\n // Remove after first touch\n if (this.touchListener) {\n grid.removeEventListener('click', this.touchListener);\n this.touchListener = null;\n }\n };\n grid.addEventListener('click', this.touchListener);\n\n // If in grid mode with syncValidation, set up reactive validation\n // Wait for grid to be ready so we can detect the editing mode\n grid.ready?.().then(() => {\n if (this.syncValidation() && this.#isGridMode()) {\n this.#setupReactiveValidation();\n // Sync initial validation state for all existing controls\n this.#syncAllValidationState();\n }\n });\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n this.cellCommitUnsub?.();\n this.cellCancelUnsub?.();\n this.rowCommitUnsub?.();\n if (this.touchListener) {\n grid.removeEventListener('click', this.touchListener);\n }\n if (this.valueChangesSubscription) {\n this.valueChangesSubscription.unsubscribe();\n }\n // Clean up status change subscriptions (grid mode)\n this.statusChangesSubscriptions.forEach((sub) => sub.unsubscribe());\n this.statusChangesSubscriptions = [];\n\n this.#clearFormContext(grid);\n }\n\n /**\n * Checks if the EditingPlugin is in 'grid' mode.\n */\n #isGridMode(): boolean {\n const grid = this.elementRef.nativeElement;\n if (!grid) return false;\n\n const editingPlugin = grid.getPluginByName?.('editing') as\n | (EditingPluginValidation & EditingPluginConfig)\n | undefined;\n\n return editingPlugin?.config?.mode === 'grid';\n }\n\n /**\n * Checks if a focusable editor element inside the grid currently has focus.\n * Used to skip valueChanges → grid.rows sync while a user is actively editing,\n * preventing editor destruction (which orphans overlay panels like autocomplete/select).\n */\n #isEditorFocused(grid: GridElement): boolean {\n if (!this.#isGridMode()) return false;\n const active = document.activeElement;\n if (!active) return false;\n // Check if the focused element is inside the grid\n return grid.contains(active) && active.closest('.editing') != null;\n }\n\n /**\n * Sets up reactive validation syncing for grid mode.\n * Subscribes to statusChanges on all FormControls to update validation state in real-time.\n */\n #setupReactiveValidation(): void {\n const formArray = this.formArray();\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n // Clean up any existing subscriptions\n this.statusChangesSubscriptions.forEach((sub) => sub.unsubscribe());\n this.statusChangesSubscriptions = [];\n\n // Subscribe to each FormGroup's statusChanges\n for (let rowIndex = 0; rowIndex < formArray.length; rowIndex++) {\n const rowFormGroup = this.#getRowFormGroup(rowIndex);\n if (!rowFormGroup) continue;\n\n // Get the row ID for this row\n const rowId = this.#getRowId(grid, rowIndex);\n if (!rowId) continue;\n\n // Subscribe to status changes for each control in the FormGroup\n Object.keys(rowFormGroup.controls).forEach((field) => {\n const control = rowFormGroup.get(field);\n if (!control) return;\n\n const sub = control.statusChanges.pipe(debounceTime(50), takeUntilDestroyed(this.destroyRef)).subscribe(() => {\n this.#syncControlValidationToGrid(rowId, field, control);\n });\n\n this.statusChangesSubscriptions.push(sub);\n });\n }\n }\n\n /**\n * Syncs validation state for all controls in the FormArray.\n * Called once on init in grid mode to show pre-existing validation errors.\n */\n #syncAllValidationState(): void {\n const formArray = this.formArray();\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n for (let rowIndex = 0; rowIndex < formArray.length; rowIndex++) {\n const rowFormGroup = this.#getRowFormGroup(rowIndex);\n if (!rowFormGroup) continue;\n\n const rowId = this.#getRowId(grid, rowIndex);\n if (!rowId) continue;\n\n Object.keys(rowFormGroup.controls).forEach((field) => {\n const control = rowFormGroup.get(field);\n if (control) {\n this.#syncControlValidationToGrid(rowId, field, control);\n }\n });\n }\n }\n\n /**\n * Gets the row ID for a given row index using the grid's getRowId method.\n */\n #getRowId(grid: GridElement, rowIndex: number): string | undefined {\n try {\n const rows = grid.rows;\n const row = rows?.[rowIndex];\n if (!row) return undefined;\n return grid.getRowId?.(row);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Checks if the FormArray contains FormGroups.\n */\n #isFormArrayOfFormGroups(): boolean {\n const formArray = this.formArray();\n if (formArray.length === 0) return false;\n return formArray.at(0) instanceof FormGroup;\n }\n\n /**\n * Gets the FormGroup at a specific row index.\n */\n #getRowFormGroup(rowIndex: number): FormGroup | undefined {\n const formArray = this.formArray();\n const rowControl = formArray.at(rowIndex);\n return rowControl instanceof FormGroup ? rowControl : undefined;\n }\n\n /**\n * Stores the FormArrayContext on the grid element.\n */\n #storeFormContext(grid: GridElement): void {\n const getRowFormGroup = (rowIndex: number) => this.#getRowFormGroup(rowIndex);\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n\n const context: FormArrayContext = {\n getRow: <T>(rowIndex: number): T | null => {\n const formArray = this.formArray();\n const rowControl = formArray.at(rowIndex);\n return rowControl ? (rowControl.value as T) : null;\n },\n updateField: (rowIndex: number, field: string, value: unknown) => {\n const rowFormGroup = getRowFormGroup(rowIndex);\n if (rowFormGroup) {\n const control = rowFormGroup.get(field);\n if (control) {\n control.setValue(value);\n control.markAsDirty();\n }\n }\n },\n getValue: <T>(): T[] => {\n return this.formArray().getRawValue() as T[];\n },\n get hasFormGroups() {\n return self.#isFormArrayOfFormGroups();\n },\n getControl: (rowIndex: number, field: string): AbstractControl | undefined => {\n const rowFormGroup = getRowFormGroup(rowIndex);\n if (!rowFormGroup) return undefined;\n return rowFormGroup.get(field) ?? undefined;\n },\n getRowFormGroup,\n isRowValid: (rowIndex: number): boolean => {\n const rowFormGroup = getRowFormGroup(rowIndex);\n if (!rowFormGroup) return true;\n return rowFormGroup.valid;\n },\n isRowTouched: (rowIndex: number): boolean => {\n const rowFormGroup = getRowFormGroup(rowIndex);\n if (!rowFormGroup) return false;\n return rowFormGroup.touched;\n },\n isRowDirty: (rowIndex: number): boolean => {\n const rowFormGroup = getRowFormGroup(rowIndex);\n if (!rowFormGroup) return false;\n return rowFormGroup.dirty;\n },\n getRowErrors: (rowIndex: number): Record<string, unknown> | null => {\n const rowFormGroup = getRowFormGroup(rowIndex);\n if (!rowFormGroup) return null;\n\n const errors: Record<string, unknown> = {};\n let hasErrors = false;\n\n Object.keys(rowFormGroup.controls).forEach((field) => {\n const control = rowFormGroup.get(field);\n if (control?.errors) {\n errors[field] = control.errors;\n hasErrors = true;\n }\n });\n\n if (rowFormGroup.errors) {\n errors['_group'] = rowFormGroup.errors;\n hasErrors = true;\n }\n\n return hasErrors ? errors : null;\n },\n };\n (grid as unknown as Record<symbol, FormArrayContext>)[FORM_ARRAY_CONTEXT] = context;\n }\n\n /**\n * Clears the FormArrayContext from the grid element.\n */\n #clearFormContext(grid: GridElement): void {\n delete (grid as unknown as Record<symbol, FormArrayContext>)[FORM_ARRAY_CONTEXT];\n }\n\n /**\n * Handles cell-commit events by updating the FormControl in the FormGroup.\n */\n #handleCellCommit(detail: { rowIndex: number; field: string; value: unknown; rowId: string }): void {\n const { rowIndex, field, value, rowId } = detail;\n\n const rowFormGroup = this.#getRowFormGroup(rowIndex);\n if (rowFormGroup) {\n const control = rowFormGroup.get(field);\n if (control) {\n control.setValue(value);\n control.markAsDirty();\n control.markAsTouched();\n\n // Sync Angular validation state to grid's visual invalid styling\n if (this.syncValidation() && rowId) {\n this.#syncControlValidationToGrid(rowId, field, control);\n }\n }\n }\n }\n\n /**\n * Handles row-commit events - prevents commit if FormGroup has invalid controls.\n */\n #handleRowCommit(event: Event, detail: { rowIndex: number }): void {\n const { rowIndex } = detail;\n const rowFormGroup = this.#getRowFormGroup(rowIndex);\n\n if (rowFormGroup && rowFormGroup.invalid) {\n // Prevent row commit if the FormGroup is invalid\n event.preventDefault();\n }\n }\n\n /**\n * Handles cell-cancel events (grid mode Escape) — reverts the FormControl\n * to the value it had before the edit session began.\n */\n #handleCellCancel(detail: { rowIndex: number; field: string; previousValue: unknown }): void {\n const { rowIndex, field, previousValue } = detail;\n const rowFormGroup = this.#getRowFormGroup(rowIndex);\n\n if (rowFormGroup) {\n const control = rowFormGroup.get(field);\n if (control) {\n control.setValue(previousValue, { emitEvent: false });\n control.markAsPristine();\n }\n }\n }\n\n /**\n * Syncs a FormControl's validation state to the grid's visual invalid styling.\n */\n #syncControlValidationToGrid(rowId: string, field: string, control: AbstractControl): void {\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n // Get EditingPlugin via getPluginByName\n const editingPlugin = grid.getPluginByName?.('editing') as EditingPluginValidation | undefined;\n\n if (!editingPlugin) return;\n\n if (control.invalid) {\n // Get first error message to display\n const errorMessage = this.#getFirstErrorMessage(control);\n editingPlugin.setInvalid(rowId, field, errorMessage);\n } else {\n editingPlugin.clearInvalid(rowId, field);\n }\n }\n\n /**\n * Gets a human-readable error message from the first validation error.\n */\n #getFirstErrorMessage(control: AbstractControl): string {\n const errors = control.errors;\n if (!errors) return '';\n\n const firstKey = Object.keys(errors)[0];\n const error = errors[firstKey];\n\n // Common Angular validators\n switch (firstKey) {\n case 'required':\n return 'This field is required';\n case 'minlength':\n return `Minimum length is ${error.requiredLength}`;\n case 'maxlength':\n return `Maximum length is ${error.requiredLength}`;\n case 'min':\n return `Minimum value is ${error.min}`;\n case 'max':\n return `Maximum value is ${error.max}`;\n case 'email':\n return 'Invalid email address';\n case 'pattern':\n return 'Invalid format';\n default:\n // Custom validators may provide a message property\n return typeof error === 'string' ? error : (error?.message ?? `Validation error: ${firstKey}`);\n }\n }\n}\n","import { Directive, ElementRef, inject, input, OnDestroy, OnInit, output } from '@angular/core';\nimport { AbstractControl, FormGroup } from '@angular/forms';\nimport type { DataGridElement as GridElement } from '@toolbox-web/grid';\nimport type { FormArrayContext } from './grid-form-array.directive';\n\n/**\n * Interface for EditingPlugin validation methods.\n * We use a minimal interface to avoid importing the full EditingPlugin class.\n */\ninterface EditingPluginValidation {\n setInvalid(rowId: string, field: string, message?: string): void;\n clearInvalid(rowId: string, field: string): void;\n clearRowInvalid(rowId: string): void;\n}\n\n// Symbol for storing form context on the grid element (shared with GridFormArray)\nconst FORM_ARRAY_CONTEXT = Symbol('formArrayContext');\n\n/**\n * Gets the FormArrayContext from a grid element, if present.\n * @internal\n * @since 0.11.0\n */\nexport function getLazyFormContext(gridElement: HTMLElement): FormArrayContext | undefined {\n return (gridElement as unknown as Record<symbol, FormArrayContext>)[FORM_ARRAY_CONTEXT];\n}\n\n/**\n * Factory function type for creating FormGroups lazily.\n * Called when a row enters edit mode for the first time.\n *\n * @template TRow The row data type\n * @param row The row data object\n * @param rowIndex The row index in the grid\n * @returns A FormGroup for the row (only include editable fields)\n * @since 0.11.0\n */\nexport type LazyFormFactory<TRow = unknown> = (row: TRow, rowIndex: number) => FormGroup;\n\n/**\n * Event emitted when a row's form values have changed.\n * @since 0.11.0\n */\nexport interface RowFormChangeEvent<TRow = unknown> {\n /** The row index */\n rowIndex: number;\n /** The row ID (if available) */\n rowId?: string;\n /** The original row data */\n row: TRow;\n /** The FormGroup for this row */\n formGroup: FormGroup;\n /** The current form values */\n values: Partial<TRow>;\n /** Whether the form is valid */\n valid: boolean;\n /** Whether the form is dirty */\n dirty: boolean;\n}\n\n/**\n * Directive that provides lazy FormGroup creation for grid editing.\n *\n * Unlike `GridFormArray` which creates all FormGroups upfront, this directive\n * creates FormGroups on-demand only when a row enters edit mode. This provides\n * much better performance for large datasets while still enabling full\n * Angular Reactive Forms integration.\n *\n * ## Key Benefits\n *\n * - **Performance**: Only creates FormGroups for rows being edited (20-100x fewer controls)\n * - **Same DX**: Editors still receive `control` in their context for validation\n * - **Memory efficient**: FormGroups are cleaned up when rows exit edit mode\n *\n * ## Usage\n *\n * ```typescript\n * import { Component, inject, signal } from '@angular/core';\n * import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';\n * import { Grid, GridLazyForm, TbwEditor } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * imports: [Grid, GridLazyForm, TbwEditor, ReactiveFormsModule],\n * template: \\`\n * <tbw-grid\n * [rows]=\"employees()\"\n * [lazyForm]=\"createRowForm\"\n * [gridConfig]=\"config\">\n *\n * <tbw-grid-column field=\"firstName\">\n * <input *tbwEditor=\"let _; control as ctrl\"\n * [formControl]=\"ctrl\"\n * [class.is-invalid]=\"ctrl?.invalid && ctrl?.touched\" />\n * </tbw-grid-column>\n * </tbw-grid>\n * \\`\n * })\n * export class MyComponent {\n * private fb = inject(FormBuilder);\n * employees = signal(generateEmployees(1000));\n *\n * // Factory called when editing starts - only include editable fields!\n * createRowForm = (row: Employee): FormGroup => this.fb.group({\n * firstName: [row.firstName, Validators.required],\n * lastName: [row.lastName, Validators.minLength(2)],\n * salary: [row.salary, [Validators.required, Validators.min(0)]],\n * });\n *\n * gridConfig = { columns: [...] };\n * }\n * ```\n *\n * ## How It Works\n *\n * 1. Rows come from `[rows]` input (plain data array)\n * 2. When a cell enters edit mode, the FormGroup is created lazily\n * 3. Editors receive the FormControl in their template context\n * 4. On commit, FormGroup values are synced back to the row\n * 5. FormGroup is cleaned up when the row exits edit mode (configurable)\n *\n * ## Performance Comparison\n *\n * | Rows | GridFormArray (20 fields) | GridLazyForm |\n * |------|---------------------------|--------------|\n * | 100 | 2,000 controls | ~20 controls |\n * | 500 | 10,000 controls | ~20 controls |\n * | 1000 | 20,000 controls | ~20 controls |\n *\n * @example\n * ```html\n * <tbw-grid [rows]=\"employees()\" [lazyForm]=\"createRowForm\" [gridConfig]=\"gridConfig\" />\n * ```\n *\n * @see GridFormArray For small datasets with full upfront validation\n * @category Directive\n *\n * @since 0.11.0\n */\n@Directive({\n selector: 'tbw-grid[lazyForm]',\n})\nexport class GridLazyForm<TRow = unknown> implements OnInit, OnDestroy {\n private elementRef = inject(ElementRef<GridElement<TRow>>);\n\n // Cache of FormGroups by row reference\n private formGroupCache = new Map<TRow, FormGroup>();\n // Map from row reference to rowIndex (needed for getControl)\n private rowIndexMap = new Map<TRow, number>();\n // Track which row is currently being edited\n private editingRowIndex: number | null = null;\n\n private cellCommitUnsub: (() => void) | null = null;\n private rowCommitUnsub: (() => void) | null = null;\n private rowsChangeUnsub: (() => void) | null = null;\n\n /**\n * Factory function to create a FormGroup for a row.\n * Called lazily when the row first enters edit mode.\n *\n * @example\n * ```typescript\n * createRowForm = (row: Employee): FormGroup => this.fb.group({\n * firstName: [row.firstName, Validators.required],\n * lastName: [row.lastName],\n * salary: [row.salary, [Validators.min(0)]],\n * });\n * ```\n */\n readonly lazyForm = input.required<LazyFormFactory<TRow>>();\n\n /**\n * Whether to automatically sync Angular validation state to grid's visual invalid styling.\n *\n * When enabled:\n * - After a cell commit, if the FormControl is invalid, the cell is marked with `setInvalid()`\n * - When a FormControl becomes valid, `clearInvalid()` is called\n * - On `row-commit`, if the row's FormGroup has invalid controls, the commit is prevented\n *\n * @default true\n */\n readonly syncValidation = input<boolean>(true);\n\n /**\n * Whether to keep FormGroups cached after a row exits edit mode.\n *\n * - `true`: FormGroups are kept, preserving dirty/touched state across edit sessions\n * - `false`: FormGroups are disposed when the row exits edit mode (default)\n *\n * @default false\n */\n readonly keepFormGroups = input<boolean>(false);\n\n /**\n * Emitted when a row's form values change.\n * Useful for auto-save, validation display, or syncing to external state.\n */\n readonly rowFormChange = output<RowFormChangeEvent<TRow>>();\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n // Store the form context for AngularGridAdapter to access\n this.#storeFormContext(grid);\n\n // Listen for cell-commit to update FormControl and sync validation\n this.cellCommitUnsub = grid.on(\n 'cell-commit',\n (detail: { rowIndex: number; field: string; value: unknown; oldValue: unknown; rowId: string }) => {\n this.#handleCellCommit(detail);\n },\n );\n\n // Listen for row-commit to sync FormGroup values back to row and cleanup\n this.rowCommitUnsub = grid.on('row-commit', (detail: { rowIndex: number; rowId?: string }, event: CustomEvent) => {\n this.#handleRowCommit(event, detail);\n });\n\n // Listen for rows-change to update row index mappings\n this.rowsChangeUnsub = grid.on('rows-change', () => {\n this.#updateRowIndexMap();\n });\n\n // Initial row index mapping\n this.#updateRowIndexMap();\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n this.cellCommitUnsub?.();\n this.rowCommitUnsub?.();\n this.rowsChangeUnsub?.();\n\n this.#clearFormContext(grid);\n this.formGroupCache.clear();\n this.rowIndexMap.clear();\n }\n\n // #region FormArrayContext Implementation\n\n /**\n * Gets or creates the FormGroup for a row.\n * This is the core lazy initialization logic.\n */\n #getOrCreateFormGroup(row: TRow, rowIndex: number): FormGroup {\n let formGroup = this.formGroupCache.get(row);\n if (!formGroup) {\n const factory = this.lazyForm();\n formGroup = factory(row, rowIndex);\n this.formGroupCache.set(row, formGroup);\n this.rowIndexMap.set(row, rowIndex);\n }\n return formGroup;\n }\n\n /**\n * Gets the FormGroup for a row if it exists (without creating).\n */\n #getRowFormGroup(rowIndex: number): FormGroup | undefined {\n const grid = this.elementRef.nativeElement;\n const rows = grid?.rows;\n if (!rows || rowIndex < 0 || rowIndex >= rows.length) return undefined;\n\n const row = rows[rowIndex];\n return this.formGroupCache.get(row);\n }\n\n /**\n * Stores the FormArrayContext on the grid element.\n * This uses the same interface as GridFormArray for compatibility.\n */\n #storeFormContext(grid: GridElement<TRow>): void {\n const context: FormArrayContext = {\n getRow: <T>(rowIndex: number): T | null => {\n const rows = grid.rows;\n if (!rows || rowIndex < 0 || rowIndex >= rows.length) return null;\n return rows[rowIndex] as unknown as T;\n },\n\n updateField: (rowIndex: number, field: string, value: unknown) => {\n const formGroup = this.#getRowFormGroup(rowIndex);\n if (formGroup) {\n const control = formGroup.get(field);\n if (control) {\n control.setValue(value);\n control.markAsDirty();\n }\n }\n },\n\n getValue: <T>(): T[] => {\n return (grid.rows ?? []) as unknown as T[];\n },\n\n // Always true for lazy forms - we create FormGroups on demand\n hasFormGroups: true,\n\n getControl: (rowIndex: number, field: string): AbstractControl | undefined => {\n const rows = grid.rows;\n if (!rows || rowIndex < 0 || rowIndex >= rows.length) return undefined;\n\n const row = rows[rowIndex] as TRow;\n // LAZY: Create the FormGroup when first needed\n const formGroup = this.#getOrCreateFormGroup(row, rowIndex);\n return formGroup.get(field) ?? undefined;\n },\n\n getRowFormGroup: (rowIndex: number): FormGroup | undefined => {\n const rows = grid.rows;\n if (!rows || rowIndex < 0 || rowIndex >= rows.length) return undefined;\n\n const row = rows[rowIndex] as TRow;\n // LAZY: Create the FormGroup when first needed\n return this.#getOrCreateFormGroup(row, rowIndex);\n },\n\n isRowValid: (rowIndex: number): boolean => {\n const formGroup = this.#getRowFormGroup(rowIndex);\n // If no FormGroup exists yet, consider it valid (not edited)\n if (!formGroup) return true;\n return formGroup.valid;\n },\n\n isRowTouched: (rowIndex: number): boolean => {\n const formGroup = this.#getRowFormGroup(rowIndex);\n if (!formGroup) return false;\n return formGroup.touched;\n },\n\n isRowDirty: (rowIndex: number): boolean => {\n const formGroup = this.#getRowFormGroup(rowIndex);\n if (!formGroup) return false;\n return formGroup.dirty;\n },\n\n getRowErrors: (rowIndex: number): Record<string, unknown> | null => {\n const formGroup = this.#getRowFormGroup(rowIndex);\n if (!formGroup) return null;\n\n const errors: Record<string, unknown> = {};\n let hasErrors = false;\n\n Object.keys(formGroup.controls).forEach((field) => {\n const control = formGroup.get(field);\n if (control?.errors) {\n errors[field] = control.errors;\n hasErrors = true;\n }\n });\n\n if (formGroup.errors) {\n errors['_group'] = formGroup.errors;\n hasErrors = true;\n }\n\n return hasErrors ? errors : null;\n },\n };\n\n (grid as unknown as Record<symbol, FormArrayContext>)[FORM_ARRAY_CONTEXT] = context;\n }\n\n /**\n * Clears the FormArrayContext from the grid element.\n */\n #clearFormContext(grid: GridElement<TRow>): void {\n delete (grid as unknown as Record<symbol, FormArrayContext>)[FORM_ARRAY_CONTEXT];\n }\n\n // #endregion\n\n // #region Event Handlers\n\n /**\n * Updates the row index map when rows change.\n * This ensures we can find FormGroups by row reference after sorting/filtering.\n */\n #updateRowIndexMap(): void {\n const grid = this.elementRef.nativeElement;\n const rows = grid?.rows;\n if (!rows) return;\n\n this.rowIndexMap.clear();\n rows.forEach((row: TRow, index: number) => {\n if (this.formGroupCache.has(row)) {\n this.rowIndexMap.set(row, index);\n }\n });\n }\n\n /**\n * Handles cell-commit events by updating the FormControl in the FormGroup.\n */\n #handleCellCommit(detail: { rowIndex: number; field: string; value: unknown; rowId: string }): void {\n const { rowIndex, field, value, rowId } = detail;\n\n const formGroup = this.#getRowFormGroup(rowIndex);\n if (formGroup) {\n const control = formGroup.get(field);\n if (control) {\n control.setValue(value);\n control.markAsDirty();\n control.markAsTouched();\n\n // Sync Angular validation state to grid's visual invalid styling\n if (this.syncValidation() && rowId) {\n this.#syncControlValidationToGrid(rowId, field, control);\n }\n\n // Emit change event\n const grid = this.elementRef.nativeElement;\n const row = grid?.rows?.[rowIndex];\n if (row) {\n this.rowFormChange.emit({\n rowIndex,\n rowId,\n row,\n formGroup,\n values: formGroup.value,\n valid: formGroup.valid,\n dirty: formGroup.dirty,\n });\n }\n }\n }\n }\n\n /**\n * Handles row-commit events.\n * - Prevents commit if FormGroup is invalid (when syncValidation is true)\n * - Syncs FormGroup values back to the row\n * - Cleans up FormGroup if keepFormGroups is false\n */\n #handleRowCommit(event: Event, detail: { rowIndex: number; rowId?: string }): void {\n const { rowIndex, rowId } = detail;\n const grid = this.elementRef.nativeElement;\n const rows = grid?.rows;\n if (!rows || rowIndex < 0 || rowIndex >= rows.length) return;\n\n const row = rows[rowIndex];\n const formGroup = this.formGroupCache.get(row);\n\n if (!formGroup) return;\n\n // Prevent commit if invalid (when syncValidation is enabled)\n if (this.syncValidation() && formGroup.invalid) {\n // Mark all controls as touched to show validation errors\n formGroup.markAllAsTouched();\n event.preventDefault();\n return;\n }\n\n // Sync FormGroup values back to the row object\n if (formGroup.dirty) {\n const formValue = formGroup.value;\n Object.keys(formValue).forEach((field) => {\n if (field in row) {\n (row as Record<string, unknown>)[field] = formValue[field];\n }\n });\n }\n\n // Clean up FormGroup if not keeping them\n if (!this.keepFormGroups()) {\n this.formGroupCache.delete(row);\n this.rowIndexMap.delete(row);\n\n // Clear any validation state in the grid\n if (rowId) {\n const editingPlugin = grid.getPluginByName?.('editing') as EditingPluginValidation | undefined;\n editingPlugin?.clearRowInvalid(rowId);\n }\n }\n }\n\n // #endregion\n\n // #region Validation Sync\n\n /**\n * Syncs a FormControl's validation state to the grid's visual invalid styling.\n */\n #syncControlValidationToGrid(rowId: string, field: string, control: AbstractControl): void {\n const grid = this.elementRef.nativeElement;\n if (!grid) return;\n\n const editingPlugin = grid.getPluginByName?.('editing') as EditingPluginValidation | undefined;\n\n if (!editingPlugin) return;\n\n if (control.invalid) {\n const errorMessage = this.#getFirstErrorMessage(control);\n editingPlugin.setInvalid(rowId, field, errorMessage);\n } else {\n editingPlugin.clearInvalid(rowId, field);\n }\n }\n\n /**\n * Gets a human-readable error message from the first validation error.\n */\n #getFirstErrorMessage(control: AbstractControl): string {\n const errors = control.errors;\n if (!errors) return '';\n\n const firstKey = Object.keys(errors)[0];\n const error = errors[firstKey];\n\n switch (firstKey) {\n case 'required':\n return 'This field is required';\n case 'minlength':\n return `Minimum length is ${error.requiredLength}`;\n case 'maxlength':\n return `Maximum length is ${error.requiredLength}`;\n case 'min':\n return `Minimum value is ${error.min}`;\n case 'max':\n return `Maximum value is ${error.max}`;\n case 'email':\n return 'Invalid email address';\n case 'pattern':\n return 'Invalid format';\n default:\n return typeof error === 'string' ? error : (error?.message ?? `Validation error: ${firstKey}`);\n }\n }\n\n // #endregion\n\n // #region Public API\n\n /**\n * Gets the FormGroup for a row, if it exists.\n * Unlike the context methods, this does NOT create a FormGroup lazily.\n *\n * @param rowIndex The row index\n * @returns The FormGroup or undefined\n */\n getFormGroup(rowIndex: number): FormGroup | undefined {\n return this.#getRowFormGroup(rowIndex);\n }\n\n /**\n * Gets all cached FormGroups.\n * Useful for bulk validation or inspection.\n *\n * @returns Map of row objects to their FormGroups\n */\n getAllFormGroups(): ReadonlyMap<TRow, FormGroup> {\n return this.formGroupCache;\n }\n\n /**\n * Clears all cached FormGroups.\n * Useful when the underlying data changes significantly.\n */\n clearAllFormGroups(): void {\n this.formGroupCache.clear();\n this.rowIndexMap.clear();\n }\n\n /**\n * Validates all currently cached FormGroups.\n *\n * @returns true if all FormGroups are valid, false otherwise\n */\n validateAll(): boolean {\n for (const formGroup of this.formGroupCache.values()) {\n if (formGroup.invalid) {\n formGroup.markAllAsTouched();\n return false;\n }\n }\n return true;\n }\n\n // #endregion\n}\n","import { Directive, effect, ElementRef, inject, OnDestroy, TemplateRef } from '@angular/core';\nimport type { AbstractControl } from '@angular/forms';\nimport { getEditorTemplate } from './grid-column-editor.directive';\n\n/**\n * Context type for structural editor directives with `any` defaults.\n * This provides better ergonomics in templates without requiring explicit type annotations.\n *\n * @internal Use `GridEditorContext` in application code for stricter typing.\n * @since 0.1.1\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface StructuralEditorContext<TValue = any, TRow = any> {\n /** The cell value for this column */\n $implicit: TValue;\n /** The cell value (explicit binding) */\n value: TValue;\n /** The full row data object */\n row: TRow;\n /** The column configuration */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n column: any;\n /**\n * Callback function to commit the edited value.\n */\n onCommit: (value: TValue) => void;\n /**\n * Callback function to cancel editing.\n */\n onCancel: () => void;\n /**\n * The FormControl for this cell, if the grid is bound to a FormArray with FormGroups.\n *\n * Returns `undefined` if:\n * - The grid is not bound to a FormArray\n * - The FormArray doesn't contain FormGroups\n * - The field doesn't exist in the FormGroup\n */\n control?: AbstractControl;\n}\n\n// Registry for structural editor templates\nconst structuralEditorRegistry = new Map<HTMLElement, TemplateRef<StructuralEditorContext>>();\n\n/**\n * Gets the editor template registered by the structural directive for a given column element.\n * Falls back to the non-structural directive registry.\n */\nexport function getStructuralEditorTemplate(\n columnElement: HTMLElement,\n): TemplateRef<StructuralEditorContext> | undefined {\n // First check structural directive registry\n const template = structuralEditorRegistry.get(columnElement);\n if (template) return template;\n\n // Fall back to the nested element registry\n const editorEl = columnElement.querySelector('tbw-grid-column-editor');\n if (editorEl) {\n return getEditorTemplate(editorEl as HTMLElement) as TemplateRef<StructuralEditorContext> | undefined;\n }\n return undefined;\n}\n\n/**\n * Structural directive for cell editor rendering.\n *\n * This provides a cleaner syntax for defining custom cell editors without\n * the nested `<tbw-grid-column-editor>` and `<ng-template>` boilerplate.\n *\n * ## Usage\n *\n * ```html\n * <!-- Instead of this verbose syntax: -->\n * <tbw-grid-column field=\"status\">\n * <tbw-grid-column-editor>\n * <ng-template let-value let-onCommit=\"onCommit\" let-onCancel=\"onCancel\">\n * <app-status-editor [value]=\"value\" (commit)=\"onCommit($event)\" (cancel)=\"onCancel()\" />\n * </ng-template>\n * </tbw-grid-column-editor>\n * </tbw-grid-column>\n *\n * <!-- Use this cleaner syntax (with auto-wiring - no explicit bindings needed!): -->\n * <tbw-grid-column field=\"status\">\n * <app-status-editor *tbwEditor=\"let value\" [value]=\"value\" />\n * </tbw-grid-column>\n * ```\n *\n * ## Template Context\n *\n * The structural directive provides the same context as `GridColumnEditor`:\n * - `$implicit` / `value`: The cell value\n * - `row`: The full row data object\n * - `column`: The column configuration\n * - `onCommit`: Callback function to commit the new value (optional - auto-wired if component emits `commit` event)\n * - `onCancel`: Callback function to cancel editing (optional - auto-wired if component emits `cancel` event)\n *\n * ## Import\n *\n * ```typescript\n * import { TbwEditor } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * imports: [TbwEditor],\n * // ...\n * })\n * ```\n *\n * @example\n * ```html\n * <tbw-grid-column field=\"status\" editable>\n * <app-status-editor *tbwEditor=\"let value\" [value]=\"value\" />\n * </tbw-grid-column>\n * ```\n *\n * @category Directive\n * @since 0.1.1\n */\n@Directive({ selector: '[tbwEditor]' })\nexport class TbwEditor implements OnDestroy {\n private template = inject(TemplateRef<StructuralEditorContext>);\n private elementRef = inject(ElementRef<HTMLElement>);\n private columnElement: HTMLElement | null = null;\n\n constructor() {\n effect(() => {\n this.registerTemplate();\n });\n }\n\n private registerTemplate(): void {\n // Find the parent tbw-grid-column or tbw-grid-type element\n let parent = this.elementRef.nativeElement?.parentElement;\n while (parent && parent.tagName !== 'TBW-GRID-COLUMN' && parent.tagName !== 'TBW-GRID-TYPE') {\n parent = parent.parentElement;\n }\n\n if (parent) {\n this.columnElement = parent;\n structuralEditorRegistry.set(parent, this.template);\n }\n }\n\n ngOnDestroy(): void {\n if (this.columnElement) {\n structuralEditorRegistry.delete(this.columnElement);\n }\n }\n\n /**\n * Static type guard for template context.\n * Uses `any` defaults for ergonomic template usage.\n */\n static ngTemplateContextGuard(dir: TbwEditor, ctx: unknown): ctx is StructuralEditorContext {\n return true;\n }\n}\n","/**\n * `GridEditingDirective` — owns `[editing]` and the editing-specific\n * outputs on `<tbw-grid>`. The shared outputs `cellChange` and `dataChange`\n * stay on `Grid` because they are emitted by multiple sources, not just\n * the editing plugin. See `GridFilteringDirective` for full rationale.\n *\n * Output type compatibility note: this directive uses the Angular adapter\n * wrapper types `CellCommitEvent` / `RowCommitEvent` (re-exported from the\n * package barrel) to stay binary-compatible with apps migrating from the\n * deprecated bindings on `Grid`.\n *\n * @category Directive\n */\nimport { Directive, ElementRef, inject, input, OnDestroy, OnInit, output } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport {\n type CellCommitEvent,\n claimEvent,\n registerFeatureClaim,\n type RowCommitEvent,\n unclaimEvent,\n unregisterFeatureClaim,\n} from '@toolbox-web/grid-angular';\nimport type {\n BaselinesCapturedDetail,\n BeforeEditCloseDetail,\n CellCancelDetail,\n ChangedRowsResetDetail,\n DirtyChangeDetail,\n EditCloseDetail,\n EditingConfig,\n EditOpenDetail,\n} from '@toolbox-web/grid/plugins/editing';\n\n/**\n * Owns the binding(s) `[editing], [cellCommit], [cellCancel], [rowCommit], [changedRowsReset], [editOpen], [beforeEditClose], [editClose], [dirtyChange], [baselinesCaptured]` on `<tbw-grid>` for the matching feature plugin. See `GridFilteringDirective` for the full rationale.\n *\n * @category Directive\n */\n@Directive({\n selector:\n 'tbw-grid[editing], tbw-grid[cellCommit], tbw-grid[cellCancel], tbw-grid[rowCommit], tbw-grid[changedRowsReset], tbw-grid[editOpen], tbw-grid[beforeEditClose], tbw-grid[editClose], tbw-grid[dirtyChange], tbw-grid[baselinesCaptured]',\n standalone: true,\n})\nexport class GridEditingDirective implements OnInit, OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n readonly editing = input<boolean | 'click' | 'dblclick' | 'manual' | EditingConfig>();\n readonly cellCommit = output<CellCommitEvent>();\n readonly cellCancel = output<CellCancelDetail>();\n readonly rowCommit = output<RowCommitEvent>();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly changedRowsReset = output<ChangedRowsResetDetail<any>>();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly editOpen = output<EditOpenDetail<any>>();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly beforeEditClose = output<BeforeEditCloseDetail<any>>();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly editClose = output<EditCloseDetail<any>>();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly dirtyChange = output<DirtyChangeDetail<any>>();\n /**\n * Fired after the render pipeline captures new dirty-tracking baseline\n * snapshots. `detail.count` is the **total** number of tracked baselines,\n * not just the newly captured ones.\n *\n * @since 2.3.0\n */\n readonly baselinesCaptured = output<BaselinesCapturedDetail>();\n\n private readonly listeners = new Map<string, (e: Event) => void>();\n private static readonly EVENTS = [\n 'cell-commit',\n 'cell-cancel',\n 'row-commit',\n 'changed-rows-reset',\n 'edit-open',\n 'before-edit-close',\n 'edit-close',\n 'dirty-change',\n 'baselines-captured',\n ] as const;\n\n constructor() {\n const grid = this.elementRef.nativeElement;\n registerFeatureClaim(grid, 'editing', () => this.editing());\n for (const ev of GridEditingDirective.EVENTS) claimEvent(grid, ev);\n }\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n const wire = <T>(name: string, out: { emit: (v: T) => void }): void => {\n const l = (e: Event): void => out.emit((e as CustomEvent<T>).detail);\n grid.addEventListener(name, l);\n this.listeners.set(name, l);\n };\n wire<CellCommitEvent>('cell-commit', this.cellCommit);\n wire<CellCancelDetail>('cell-cancel', this.cellCancel);\n wire<RowCommitEvent>('row-commit', this.rowCommit);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n wire<ChangedRowsResetDetail<any>>('changed-rows-reset', this.changedRowsReset);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n wire<EditOpenDetail<any>>('edit-open', this.editOpen);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n wire<BeforeEditCloseDetail<any>>('before-edit-close', this.beforeEditClose);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n wire<EditCloseDetail<any>>('edit-close', this.editClose);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n wire<DirtyChangeDetail<any>>('dirty-change', this.dirtyChange);\n wire<BaselinesCapturedDetail>('baselines-captured', this.baselinesCaptured);\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n for (const [name, l] of this.listeners) grid.removeEventListener(name, l);\n this.listeners.clear();\n unregisterFeatureClaim(grid, 'editing');\n for (const ev of GridEditingDirective.EVENTS) unclaimEvent(grid, ev);\n }\n}\n","import { afterNextRender, computed, DestroyRef, Directive, ElementRef, inject, input, output } from '@angular/core';\nimport type { AbstractControl } from '@angular/forms';\nimport type { ColumnConfig } from '@toolbox-web/grid';\n\n/**\n * Base class for grid cell editors.\n *\n * Provides common functionality for Angular cell editors:\n * - Automatic value resolution from FormControl or value input\n * - Common inputs (value, row, column, control)\n * - Common outputs (commit, cancel)\n * - Validation state helpers\n *\n * ## Usage\n *\n * ```typescript\n * import { Component } from '@angular/core';\n * import { BaseGridEditor } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * selector: 'app-my-editor',\n * template: \\`\n * <input\n * [value]=\"currentValue()\"\n * [class.is-invalid]=\"isInvalid()\"\n * (input)=\"commitValue($event.target.value)\"\n * (keydown.escape)=\"cancelEdit()\"\n * />\n * @if (hasErrors()) {\n * <div class=\"error\">{{ firstErrorMessage() }}</div>\n * }\n * \\`\n * })\n * export class MyEditorComponent extends BaseGridEditor<MyRow, string> {\n * // Override to customize error messages\n * protected override getErrorMessage(errorKey: string): string {\n * if (errorKey === 'required') return 'This field is required';\n * if (errorKey === 'minlength') return 'Too short';\n * return super.getErrorMessage(errorKey);\n * }\n * }\n * ```\n *\n * ## Template Syntax\n *\n * When using the base class, you only need to pass the control:\n *\n * ```html\n * <tbw-grid-column field=\"name\">\n * <app-my-editor *tbwEditor=\"let _; control as control\" [control]=\"control\" />\n * </tbw-grid-column>\n * ```\n *\n * Or without FormArray binding (fallback to value):\n *\n * ```html\n * <tbw-grid-column field=\"name\">\n * <app-my-editor *tbwEditor=\"let value\" [value]=\"value\" />\n * </tbw-grid-column>\n * ```\n *\n * @typeParam TRow - The row data type\n * @typeParam TValue - The cell value type\n *\n * @since 0.5.0\n */\n@Directive()\nexport abstract class BaseGridEditor<TRow = unknown, TValue = unknown> {\n protected readonly elementRef = inject(ElementRef);\n private readonly _destroyRef = inject(DestroyRef);\n\n /** Cleanup function for the edit-close listener */\n private _editCloseCleanup: (() => void) | null = null;\n\n // ============================================================================\n // Inputs\n // ============================================================================\n\n /**\n * The cell value. Used when FormControl is not available.\n * When a FormControl is provided, value is derived from control.value instead.\n */\n readonly value = input<TValue>();\n\n /**\n * The full row data object.\n */\n readonly row = input<TRow>();\n\n /**\n * The column configuration.\n */\n readonly column = input<ColumnConfig<TRow>>();\n\n /**\n * The FormControl for this cell, if the grid is bound to a FormArray.\n * When provided, the editor uses control.value instead of the value input.\n */\n readonly control = input<AbstractControl>();\n\n // ============================================================================\n // Outputs\n // ============================================================================\n\n /**\n * Emits when the user commits a new value.\n * Emits `null` when a nullable field is cleared.\n */\n readonly commit = output<TValue | null>();\n\n /**\n * Emits when the user cancels editing.\n */\n readonly cancel = output<void>();\n\n // ============================================================================\n // Computed State\n // ============================================================================\n\n /**\n * The current value, derived from FormControl if available, otherwise from value input.\n * This is the recommended way to get the current value in your editor template.\n */\n readonly currentValue = computed<TValue | undefined>(() => {\n const ctrl = this.control();\n if (ctrl) {\n return ctrl.value as TValue;\n }\n return this.value();\n });\n\n /**\n * Whether the control is invalid (has validation errors).\n * Returns false if no FormControl is available.\n */\n readonly isInvalid = computed(() => {\n return this.control()?.invalid ?? false;\n });\n\n /**\n * Whether the control is dirty (has been modified).\n * Returns false if no FormControl is available.\n */\n readonly isDirty = computed(() => {\n return this.control()?.dirty ?? false;\n });\n\n /**\n * Whether the control has been touched.\n * Returns false if no FormControl is available.\n */\n readonly isTouched = computed(() => {\n return this.control()?.touched ?? false;\n });\n\n /**\n * Whether the control has any validation errors.\n */\n readonly hasErrors = computed(() => {\n const ctrl = this.control();\n return ctrl?.errors != null && Object.keys(ctrl.errors).length > 0;\n });\n\n /**\n * The first error message from the control's validation errors.\n * Returns an empty string if no errors.\n */\n readonly firstErrorMessage = computed(() => {\n const ctrl = this.control();\n if (!ctrl?.errors) return '';\n\n const firstKey = Object.keys(ctrl.errors)[0];\n return this.getErrorMessage(firstKey, ctrl.errors[firstKey]);\n });\n\n /**\n * All error messages from the control's validation errors.\n */\n readonly allErrorMessages = computed(() => {\n const ctrl = this.control();\n if (!ctrl?.errors) return [];\n\n return Object.entries(ctrl.errors).map(([key, value]) => this.getErrorMessage(key, value));\n });\n\n // ============================================================================\n // Lifecycle\n // ============================================================================\n\n constructor() {\n afterNextRender(() => this._initEditCloseListener());\n this._destroyRef.onDestroy(() => {\n this._editCloseCleanup?.();\n this._editCloseCleanup = null;\n });\n }\n\n private _initEditCloseListener(): void {\n const grid = this.elementRef.nativeElement.closest('tbw-grid, [data-tbw-grid]') as\n | import('@toolbox-web/grid').DataGridElement\n | null;\n if (!grid) return;\n\n let unsubBefore: (() => void) | undefined;\n let unsubClose: (() => void) | undefined;\n\n unsubBefore = grid.on('before-edit-close', () => {\n this.onBeforeEditClose();\n unsubBefore?.();\n unsubBefore = undefined;\n });\n\n unsubClose = grid.on('edit-close', () => {\n this.onEditClose();\n unsubClose?.();\n unsubClose = undefined;\n });\n\n this._editCloseCleanup = () => {\n unsubBefore?.();\n unsubClose?.();\n };\n }\n\n // ============================================================================\n // Methods\n // ============================================================================\n\n /**\n * Whether this editor's cell is the currently focused cell.\n *\n * In row editing mode the grid creates editors for every editable cell\n * in the row simultaneously. Use this to conditionally auto-focus inputs\n * or open panels only in the active cell.\n *\n * Performs a synchronous DOM check — safe to call from `ngAfterViewInit`.\n */\n protected isCellFocused(): boolean {\n return this.elementRef.nativeElement.closest('[part=\"cell\"]')?.classList.contains('cell-focus') ?? false;\n }\n\n /**\n * Called **before** the grid clears editing state and destroys editor DOM.\n *\n * At this point the commit callback is still active, so subclasses can\n * call {@link commitValue} to flush any pending/deferred values.\n *\n * This fires only on the **commit** path (not on revert/cancel).\n * Use {@link onEditClose} for cleanup that should happen on both paths.\n */\n protected onBeforeEditClose(): void {\n // Default: no-op. Subclasses override to flush pending values.\n }\n\n /**\n * Called when the grid ends the editing session for this cell.\n *\n * Override to perform cleanup such as closing overlay panels, autocomplete\n * dropdowns, or other floating UI that lives at `<body>` level and would\n * otherwise persist after the editor DOM is removed.\n *\n * The listener is set up automatically via `afterNextRender` — no manual\n * wiring required.\n */\n protected onEditClose(): void {\n // Default: no-op. Subclasses override.\n }\n\n /**\n * Called by the grid adapter when the cell value changes externally\n * (e.g., via `updateRow()` cascade or undo/redo).\n *\n * Override in subclasses to reset internal state (search text, selection\n * flags, etc.) so the editor displays the updated value.\n *\n * This runs **synchronously** before the value input is updated, giving\n * the editor a chance to clear stale state before the next change-detection\n * pass re-reads the template.\n *\n * @param _newVal The new cell value being pushed from the grid\n */\n onExternalValueChange(_newVal: TValue): void {\n // Default: no-op. Subclasses override as needed.\n }\n\n /**\n * Commit a new value. Emits the commit output AND dispatches a DOM event.\n * The DOM event enables the grid's auto-wiring to catch the commit.\n * Call this when the user confirms their edit.\n */\n commitValue(newValue: TValue | null): void {\n // Emit Angular output for template bindings\n this.commit.emit(newValue);\n\n // Dispatch DOM CustomEvent for grid's auto-wiring\n // This allows the adapter to catch commits without explicit (commit)=\"...\" bindings\n this.elementRef.nativeElement.dispatchEvent(new CustomEvent('commit', { detail: newValue, bubbles: true }));\n }\n\n /**\n * Cancel editing. Emits the cancel output AND dispatches a DOM event.\n * Call this when the user cancels (e.g., presses Escape).\n */\n cancelEdit(): void {\n // Emit Angular output for template bindings\n this.cancel.emit();\n\n // Dispatch DOM CustomEvent for grid's auto-wiring\n this.elementRef.nativeElement.dispatchEvent(new CustomEvent('cancel', { bubbles: true }));\n }\n\n /**\n * Get a human-readable error message for a validation error.\n * Override this method to customize error messages for your editor.\n *\n * @param errorKey - The validation error key (e.g., 'required', 'minlength')\n * @param errorValue - The error value (e.g., { requiredLength: 5, actualLength: 3 })\n * @returns A human-readable error message\n */\n protected getErrorMessage(errorKey: string, errorValue?: unknown): string {\n switch (errorKey) {\n case 'required':\n return 'This field is required';\n case 'minlength': {\n const err = errorValue as { requiredLength?: number };\n return `Minimum length is ${err?.requiredLength ?? 'unknown'}`;\n }\n case 'maxlength': {\n const err = errorValue as { requiredLength?: number };\n return `Maximum length is ${err?.requiredLength ?? 'unknown'}`;\n }\n case 'min': {\n const err = errorValue as { min?: number };\n return `Minimum value is ${err?.min ?? 'unknown'}`;\n }\n case 'max': {\n const err = errorValue as { max?: number };\n return `Maximum value is ${err?.max ?? 'unknown'}`;\n }\n case 'email':\n return 'Invalid email address';\n case 'pattern':\n return 'Invalid format';\n default:\n return `Invalid value (${errorKey})`;\n }\n }\n}\n","import { computed, Directive, signal } from '@angular/core';\nimport type { ControlValueAccessor } from '@angular/forms';\nimport { BaseGridEditor } from './base-grid-editor';\n\n/**\n * Base class for grid editors that also work as Angular form controls.\n *\n * Combines `BaseGridEditor` with `ControlValueAccessor` so the same component\n * can be used inside a `<tbw-grid>` **and** in a standalone `<form>`.\n *\n * ## What it provides\n *\n * | Member | Purpose |\n * |--------|---------|\n * | `cvaValue` | Signal holding the value written by the form control |\n * | `disabledState` | Signal tracking `setDisabledState` calls |\n * | `displayValue` | Computed that prefers grid value (`currentValue`) and falls back to `cvaValue` |\n * | `commitBoth(v)` | Commits via both CVA `onChange` and grid `commitValue` |\n * | `writeValue` / `registerOn*` / `setDisabledState` | Full CVA implementation |\n *\n * ## Usage\n *\n * ```typescript\n * import { Component, forwardRef } from '@angular/core';\n * import { NG_VALUE_ACCESSOR } from '@angular/forms';\n * import { BaseGridEditorCVA } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * selector: 'app-date-picker',\n * providers: [{\n * provide: NG_VALUE_ACCESSOR,\n * useExisting: forwardRef(() => DatePickerComponent),\n * multi: true,\n * }],\n * template: `\n * <input\n * type=\"date\"\n * [value]=\"displayValue()\"\n * [disabled]=\"disabledState()\"\n * (change)=\"commitBoth($event.target.value)\"\n * (keydown.escape)=\"cancelEdit()\"\n * />\n * `\n * })\n * export class DatePickerComponent extends BaseGridEditorCVA<MyRow, string> {}\n * ```\n *\n * > **Note:** Subclasses must still provide `NG_VALUE_ACCESSOR` themselves\n * > because `forwardRef(() => ConcreteClass)` must reference the concrete\n * > component — this is an Angular limitation.\n *\n * @typeParam TRow - The row data type\n * @typeParam TValue - The cell/control value type\n *\n * @since 0.13.0\n */\n@Directive()\nexport abstract class BaseGridEditorCVA<TRow = unknown, TValue = unknown>\n extends BaseGridEditor<TRow, TValue>\n implements ControlValueAccessor\n{\n // ============================================================================\n // CVA State\n // ============================================================================\n\n /** Internal onChange callback registered by the form control. */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private _onChange: (value: TValue | null) => void = () => {};\n\n /** Internal onTouched callback registered by the form control. */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private _onTouched: () => void = () => {};\n\n /**\n * Signal holding the value written by the form control via `writeValue()`.\n * Updated when the form control pushes a new value (e.g. `patchValue`, `setValue`).\n */\n protected readonly cvaValue = signal<TValue | null>(null);\n\n /**\n * Signal tracking the disabled state set by the form control.\n * Updated when `setDisabledState()` is called by Angular's forms module.\n */\n readonly disabledState = signal(false);\n\n /**\n * Resolved display value.\n *\n * Prefers `currentValue()` (grid context — from `control.value` or `value` input)\n * and falls back to `cvaValue()` (standalone form context — from `writeValue`).\n *\n * Use this in your template instead of reading `currentValue()` directly\n * so the component works in both grid and standalone form contexts.\n */\n readonly displayValue = computed<TValue | null>(() => {\n return (this.currentValue() as TValue | undefined) ?? this.cvaValue();\n });\n\n // ============================================================================\n // ControlValueAccessor Implementation\n // ============================================================================\n\n /**\n * Called by Angular forms when the form control value changes programmatically.\n */\n writeValue(value: TValue | null): void {\n this.cvaValue.set(value);\n }\n\n /**\n * Called by Angular forms to register a change callback.\n */\n registerOnChange(fn: (value: TValue | null) => void): void {\n this._onChange = fn;\n }\n\n /**\n * Called by Angular forms to register a touched callback.\n */\n registerOnTouched(fn: () => void): void {\n this._onTouched = fn;\n }\n\n /**\n * Called by Angular forms to set the disabled state.\n */\n setDisabledState(isDisabled: boolean): void {\n this.disabledState.set(isDisabled);\n }\n\n // ============================================================================\n // Dual-Commit Helpers\n // ============================================================================\n\n /**\n * Commit a value through both the CVA (form control) and the grid.\n *\n * - Calls the CVA `onChange` callback (updates the form control)\n * - Marks the control as touched\n * - Calls `commitValue()` (emits grid commit event + DOM `CustomEvent`)\n *\n * Use this instead of `commitValue()` when your editor doubles as a form control.\n *\n * @param value - The new value to commit\n */\n protected commitBoth(value: TValue | null): void {\n // Update CVA\n this.cvaValue.set(value);\n this._onChange(value);\n this._onTouched();\n\n // Update grid (null is valid for nullable columns — the grid's cell-commit\n // handler and EditingPlugin will apply it correctly)\n this.commitValue(value);\n }\n}\n","import { afterNextRender, DestroyRef, Directive, ElementRef, inject } from '@angular/core';\nimport { BaseGridEditor } from './base-grid-editor';\n\n// #region Overlay Position Types\n\n/**\n * Position of the overlay panel relative to its anchor cell.\n *\n * - `'below'` — panel appears below the cell, left-aligned (default)\n * - `'above'` — panel appears above the cell, left-aligned\n * - `'below-right'` — panel appears below the cell, right-aligned\n * - `'over-top-left'` — panel top-left corner aligns with cell top-left corner (opens downward)\n * - `'over-bottom-left'` — panel bottom-left corner aligns with cell bottom-left corner (opens upward)\n * @since 0.13.0\n */\nexport type OverlayPosition = 'below' | 'above' | 'below-right' | 'over-top-left' | 'over-bottom-left';\n\n// #endregion\n\n// #region Global Styles\n\n/** Tracks whether the global overlay stylesheet has been injected. */\nlet overlayStylesInjected = false;\n\n/**\n * CSS for the overlay panel base layer.\n * Injected once into `<head>` on first `BaseOverlayEditor` use.\n *\n * Uses CSS Anchor Positioning as primary strategy with a JS fallback\n * for browsers that don't support it (Firefox, Safari as of late 2025).\n */\nconst OVERLAY_STYLES = /* css */ `\n.tbw-overlay-panel {\n position: fixed;\n z-index: 10000;\n background: var(--tbw-overlay-bg, #fff);\n border: 1px solid var(--tbw-overlay-border, #ccc);\n border-radius: var(--tbw-overlay-radius, 4px);\n box-shadow: var(--tbw-overlay-shadow, 0 4px 12px rgba(0, 0, 0, 0.15));\n box-sizing: border-box;\n overflow: auto;\n}\n\n/* Hide panels that have not been initialised via initOverlay() yet.\n Prevents a flash-of-unstyled-content when the subclass defers\n the initOverlay call (e.g. via setTimeout or afterNextRender). */\n.tbw-overlay-panel:not([data-anchor-id]) {\n display: none;\n}\n\n.tbw-overlay-panel:popover-open {\n display: block;\n}\n\n@supports (anchor-name: --a) {\n .tbw-overlay-panel[data-anchor-id] {\n position: fixed;\n position-anchor: var(--tbw-overlay-anchor);\n inset: unset;\n }\n .tbw-overlay-panel[data-pos=\"below\"] {\n top: anchor(bottom);\n left: anchor(left);\n position-try-fallbacks: flip-block;\n }\n .tbw-overlay-panel[data-pos=\"above\"] {\n bottom: anchor(top);\n left: anchor(left);\n position-try-fallbacks: flip-block;\n }\n .tbw-overlay-panel[data-pos=\"below-right\"] {\n top: anchor(bottom);\n right: anchor(right);\n position-try-fallbacks: flip-block;\n }\n .tbw-overlay-panel[data-pos=\"over-top-left\"] {\n top: anchor(top);\n left: anchor(left);\n }\n .tbw-overlay-panel[data-pos=\"over-bottom-left\"] {\n bottom: anchor(bottom);\n left: anchor(left);\n }\n}\n`;\n\nfunction ensureOverlayStyles(): void {\n if (overlayStylesInjected) return;\n overlayStylesInjected = true;\n\n const style = document.createElement('style');\n style.setAttribute('data-tbw-overlay', '');\n style.textContent = OVERLAY_STYLES;\n document.head.appendChild(style);\n}\n\n// #endregion\n\n// #region Anchor ID Counter\nlet anchorCounter = 0;\n// #endregion\n\n/**\n * Base class for grid editors that display a floating overlay panel.\n *\n * Provides infrastructure for:\n * - **Overlay positioning** — CSS Anchor Positioning with JS fallback\n * - **Focus gating** — in row editing mode, the panel only opens for the focused cell\n * - **Click-outside detection** — closes the panel when clicking outside\n * - **MutationObserver** — detects cell focus changes (row editing mode)\n * - **Escape handling** — closes the panel and returns focus to the inline input\n * - **Synthetic Tab dispatch** — advances grid focus after overlay close\n * - **Automatic teardown** — removes the panel from `<body>` and cleans up listeners\n * - **External focus registration** — auto-registers the panel via `grid.registerExternalFocusContainer()` so the grid keeps `data-has-focus` and editors stay open while the overlay has focus\n *\n * ## Usage\n *\n * ```typescript\n * import { Component, viewChild, ElementRef, effect } from '@angular/core';\n * import { BaseOverlayEditor } from '@toolbox-web/grid-angular/features/editing';\n *\n * @Component({\n * selector: 'app-date-editor',\n * template: `\n * <input\n * #inlineInput\n * readonly\n * [value]=\"currentValue()\"\n * (click)=\"onInlineClick()\"\n * (keydown)=\"onInlineKeydown($event)\"\n * />\n * <div #panel class=\"tbw-overlay-panel\" style=\"width: 280px;\">\n * <!-- your date picker UI here -->\n * <div class=\"actions\">\n * <button (click)=\"selectAndClose(selectedDate)\">OK</button>\n * <button (click)=\"hideOverlay()\">Cancel</button>\n * </div>\n * </div>\n * `\n * })\n * export class DateEditorComponent extends BaseOverlayEditor<MyRow, string> {\n * panelRef = viewChild.required<ElementRef<HTMLElement>>('panel');\n * inputRef = viewChild.required<ElementRef<HTMLInputElement>>('inlineInput');\n *\n * protected override overlayPosition = 'below' as const;\n *\n * constructor() {\n * super();\n * effect(() => {\n * const panel = this.panelRef().nativeElement;\n * this.initOverlay(panel);\n * if (this.isCellFocused()) this.showOverlay();\n * });\n * }\n *\n * protected getInlineInput(): HTMLInputElement | null {\n * return this.inputRef()?.nativeElement ?? null;\n * }\n *\n * protected onOverlayOutsideClick(): void {\n * this.hideOverlay();\n * }\n *\n * selectAndClose(date: string): void {\n * this.commitValue(date);\n * this.hideOverlay();\n * }\n * }\n * ```\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <input #inlineInput readonly [value]=\"currentValue()\"\n * (click)=\"onInlineClick()\" (keydown)=\"onInlineKeydown($event)\" />\n * <div #panel style=\"width: 280px\">\n * <!-- overlay content -->\n * </div>\n * `\n * })\n * export class MyEditor extends BaseOverlayEditor<MyRow, string> {\n * panelRef = viewChild.required<ElementRef<HTMLElement>>('panel');\n * inputRef = viewChild.required<ElementRef<HTMLInputElement>>('inlineInput');\n *\n * constructor() {\n * super();\n * effect(() => this.initOverlay(this.panelRef().nativeElement));\n * }\n *\n * protected getInlineInput() { return this.inputRef()?.nativeElement ?? null; }\n * protected onOverlayOutsideClick() { this.hideOverlay(); }\n * }\n * ```\n *\n * @typeParam TRow - The row data type\n * @typeParam TValue - The cell value type\n *\n * @since 0.13.0\n */\n@Directive()\nexport abstract class BaseOverlayEditor<TRow = unknown, TValue = unknown> extends BaseGridEditor<TRow, TValue> {\n private readonly _elementRef = inject(ElementRef);\n private readonly _overlayDestroyRef = inject(DestroyRef);\n\n // ============================================================================\n // Configuration\n // ============================================================================\n\n /**\n * Position of the overlay panel relative to the anchor cell.\n * Override in subclasses to change the default position.\n *\n * @default 'below'\n */\n protected overlayPosition: OverlayPosition = 'below';\n\n // ============================================================================\n // Internal State\n // ============================================================================\n\n /** The overlay panel element (set via `initOverlay()`). */\n private _panel: HTMLElement | null = null;\n\n /** Whether the overlay is currently visible. */\n protected _isOpen = false;\n\n /** Unique anchor ID for CSS Anchor Positioning. */\n private _anchorId = '';\n\n /** Whether the browser supports CSS Anchor Positioning. */\n private _supportsAnchor = false;\n\n /** AbortController for all overlay-related listeners. */\n private _abortCtrl: AbortController | null = null;\n\n /** MutationObserver watching cell focus class changes. */\n protected _focusObserver: MutationObserver | null = null;\n\n // ============================================================================\n // Lifecycle\n // ============================================================================\n\n constructor() {\n super();\n this._supportsAnchor = typeof CSS !== 'undefined' && CSS.supports('anchor-name', '--a');\n ensureOverlayStyles();\n\n afterNextRender(() => this._setupFocusObserver());\n this._overlayDestroyRef.onDestroy(() => this.teardownOverlay());\n }\n\n // ============================================================================\n // Public API — Subclass Interface\n // ============================================================================\n\n /**\n * Initialise the overlay with the panel element.\n *\n * Call this in an `effect()` or `afterNextRender()` with your `viewChild` panel reference.\n * The panel is moved to `<body>` and hidden until {@link showOverlay} is called.\n *\n * @param panel - The overlay panel DOM element\n */\n protected initOverlay(panel: HTMLElement): void {\n this._panel = panel;\n\n // Assign a unique anchor ID\n this._anchorId = `tbw-anchor-${++anchorCounter}`;\n panel.classList.add('tbw-overlay-panel');\n panel.setAttribute('data-pos', this.overlayPosition);\n panel.setAttribute('data-anchor-id', this._anchorId);\n panel.style.display = 'none';\n\n // Set up CSS Anchor Positioning on the cell\n if (this._supportsAnchor) {\n const cell = this._getCell();\n if (cell) {\n cell.style.setProperty('anchor-name', `--${this._anchorId}`);\n panel.style.setProperty('--tbw-overlay-anchor', `--${this._anchorId}`);\n }\n }\n\n // Move panel to body so it escapes grid overflow clipping\n document.body.appendChild(panel);\n\n // Register the panel as an external focus container on the grid\n // so focus moving into the overlay is treated as \"still in the grid\"\n this._getGridElement()?.registerExternalFocusContainer?.(panel);\n\n // Set up click-outside detection\n this._abortCtrl = new AbortController();\n document.addEventListener('pointerdown', (e) => this._onDocumentPointerDown(e), {\n signal: this._abortCtrl.signal,\n });\n\n // Close overlay when the grid viewport scrolls. Mirrors outside-click\n // semantics so subclasses' `onOverlayOutsideClick()` drives commit/cancel.\n // Uses the public `tbw-scroll` CustomEvent dispatched on the grid host —\n // no shadow-DOM reach-arounds required (composed: true crosses boundaries).\n const grid = this._getGridElement();\n if (grid) {\n grid.addEventListener('tbw-scroll', () => this._onGridScroll(), {\n signal: this._abortCtrl.signal,\n });\n }\n\n // If the focus observer already fired before the panel was initialised\n // (e.g. initOverlay called from a deferred setTimeout), the showOverlay()\n // call was silently ignored because _panel was still null. Catch up now.\n if (this._getCell()?.classList.contains('cell-focus')) {\n this.showOverlay();\n this.onOverlayOpened();\n }\n }\n\n /**\n * Show the overlay panel.\n *\n * If CSS Anchor Positioning is not supported, falls back to JS-based\n * positioning using `getBoundingClientRect()`.\n */\n protected showOverlay(): void {\n if (!this._panel || this._isOpen) return;\n\n this._isOpen = true;\n this._panel.style.display = '';\n\n // JS fallback positioning for browsers without CSS Anchor Positioning\n if (!this._supportsAnchor) {\n this._positionWithJs();\n }\n }\n\n /**\n * Hide the overlay panel.\n *\n * @param suppressTabAdvance - When `true`, skip synthetic Tab dispatch\n * (useful when hiding is triggered by an external focus change).\n */\n protected hideOverlay(suppressTabAdvance?: boolean): void {\n if (!this._panel || !this._isOpen) return;\n\n this._isOpen = false;\n this._panel.style.display = 'none';\n\n if (!suppressTabAdvance) {\n this.getInlineInput()?.focus();\n }\n }\n\n /**\n * Close and immediately re-open the overlay.\n * Useful after the panel content changes size and needs repositioning.\n */\n protected reopenOverlay(): void {\n if (!this._panel) return;\n this._isOpen = false;\n this._panel.style.display = 'none';\n this.showOverlay();\n }\n\n /**\n * Remove the overlay from the DOM and clean up all listeners.\n *\n * Called automatically on `DestroyRef.onDestroy`. Can also be called\n * manually if the editor needs early cleanup.\n */\n protected teardownOverlay(): void {\n this._abortCtrl?.abort();\n this._abortCtrl = null;\n\n this._focusObserver?.disconnect();\n this._focusObserver = null;\n\n // Unregister the panel from the grid's external focus container registry\n if (this._panel) {\n this._getGridElement()?.unregisterExternalFocusContainer?.(this._panel);\n }\n\n if (this._panel?.parentNode) {\n this._panel.parentNode.removeChild(this._panel);\n }\n this._panel = null;\n this._isOpen = false;\n\n // Clean up anchor-name on the cell\n if (this._supportsAnchor) {\n const cell = this._getCell();\n if (cell) {\n cell.style.removeProperty('anchor-name');\n }\n }\n }\n\n /**\n * Override in `edit-close` handler to also hide the overlay.\n * This is called automatically by `BaseGridEditor` when the grid\n * ends the editing session.\n */\n protected override onEditClose(): void {\n this.hideOverlay(true);\n }\n\n // ============================================================================\n // Keyboard & Click Helpers\n // ============================================================================\n\n /**\n * Keydown handler for the inline readonly input.\n *\n * - **Enter / Space / ArrowDown / F2** → open overlay\n * - **Escape** → calls {@link handleEscape}\n *\n * Bind this to `(keydown)` on your inline input element.\n */\n onInlineKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'Enter':\n case ' ':\n case 'ArrowDown':\n case 'F2':\n event.preventDefault();\n this.showOverlay();\n this.onOverlayOpened();\n break;\n case 'Escape':\n this.handleEscape(event);\n break;\n }\n }\n\n /**\n * Click handler for the inline input.\n * Opens the overlay and calls {@link onOverlayOpened}.\n *\n * Bind this to `(click)` on your inline input element.\n */\n onInlineClick(): void {\n if (this._isOpen) {\n this.hideOverlay();\n } else {\n this.showOverlay();\n this.onOverlayOpened();\n }\n }\n\n /**\n * Handle Escape key press.\n *\n * If the overlay is open, closes it and returns focus to the inline input.\n * If the overlay is already closed, cancels the edit entirely.\n */\n protected handleEscape(event: Event): void {\n if (this._isOpen) {\n event.stopPropagation();\n this.hideOverlay();\n } else {\n this.cancelEdit();\n }\n }\n\n /**\n * Dispatch a synthetic Tab key event to advance grid focus.\n *\n * Call this after committing a value and closing the overlay so the\n * grid moves focus to the next cell.\n *\n * @param backward - When `true`, dispatch Shift+Tab to move backwards.\n */\n protected advanceGridFocus(backward = false): void {\n const cell = this._getCell();\n if (!cell) return;\n\n cell.dispatchEvent(\n new KeyboardEvent('keydown', {\n key: 'Tab',\n shiftKey: backward,\n bubbles: true,\n cancelable: true,\n }),\n );\n }\n\n // ============================================================================\n // Abstract / Hook Methods\n // ============================================================================\n\n /**\n * Return the inline input element, if any.\n *\n * Used by overlay infrastructure to return focus after hiding.\n * Return `null` if there is no inline input.\n */\n protected abstract getInlineInput(): HTMLInputElement | null;\n\n /**\n * Called when a pointerdown event occurs outside the overlay panel\n * and outside the editor's host element.\n *\n * Typically, subclasses call `hideOverlay()` here.\n */\n protected abstract onOverlayOutsideClick(): void;\n\n /**\n * Called after the overlay is shown.\n *\n * Override to focus an element inside the panel, start animations, etc.\n * Default implementation is a no-op.\n */\n protected onOverlayOpened(): void {\n // Default: no-op. Subclasses override.\n }\n\n // ============================================================================\n // Private Helpers\n // ============================================================================\n\n /** Find the parent cell element for this editor. */\n private _getCell(): HTMLElement | null {\n return this._elementRef.nativeElement.closest('[part=\"cell\"]') ?? null;\n }\n\n /** Find the parent `<tbw-grid>` element for this editor. */\n private _getGridElement():\n | (HTMLElement & {\n registerExternalFocusContainer?(el: Element): void;\n unregisterExternalFocusContainer?(el: Element): void;\n })\n | null {\n return this._elementRef.nativeElement.closest('tbw-grid, [data-tbw-grid]') ?? null;\n }\n\n /**\n * JS fallback positioning for browsers without CSS Anchor Positioning.\n * Uses `getBoundingClientRect()` with viewport overflow detection.\n */\n private _positionWithJs(): void {\n const cell = this._getCell();\n const panel = this._panel;\n if (!cell || !panel) return;\n\n const cellRect = cell.getBoundingClientRect();\n\n // Temporarily make visible to measure\n panel.style.visibility = 'hidden';\n panel.style.display = '';\n const panelRect = panel.getBoundingClientRect();\n panel.style.visibility = '';\n\n const viewportH = window.innerHeight;\n const viewportW = window.innerWidth;\n\n let top: number;\n let left: number;\n\n switch (this.overlayPosition) {\n case 'above': {\n top = cellRect.top - panelRect.height;\n left = cellRect.left;\n // Flip to below if off-screen\n if (top < 0) top = cellRect.bottom;\n break;\n }\n case 'below-right': {\n top = cellRect.bottom;\n left = cellRect.right - panelRect.width;\n // Flip to above if off-screen\n if (top + panelRect.height > viewportH) top = cellRect.top - panelRect.height;\n break;\n }\n case 'over-top-left': {\n top = cellRect.top;\n left = cellRect.left;\n break;\n }\n case 'over-bottom-left': {\n top = cellRect.bottom - panelRect.height;\n left = cellRect.left;\n break;\n }\n case 'below':\n default: {\n top = cellRect.bottom;\n left = cellRect.left;\n // Flip to above if off-screen\n if (top + panelRect.height > viewportH) top = cellRect.top - panelRect.height;\n break;\n }\n }\n\n // Clamp to viewport\n if (left + panelRect.width > viewportW) left = viewportW - panelRect.width - 4;\n if (left < 0) left = 4;\n if (top < 0) top = 4;\n\n panel.style.top = `${top}px`;\n panel.style.left = `${left}px`;\n }\n\n /**\n * Document pointerdown handler for click-outside detection.\n * Fires `onOverlayOutsideClick()` if the click is outside the panel\n * and outside the editor's host element.\n */\n private _onDocumentPointerDown(event: PointerEvent): void {\n if (!this._isOpen || !this._panel) return;\n\n const target = event.target as Node;\n const hostEl = this._elementRef.nativeElement;\n\n // Click inside panel or host — ignore\n if (this._panel.contains(target) || hostEl.contains(target)) return;\n\n this.onOverlayOutsideClick();\n }\n\n /**\n * Handle the grid's `tbw-scroll` CustomEvent while the overlay is open.\n *\n * When the viewport scrolls, the anchored overlay would otherwise float\n * over content that no longer corresponds to the edited cell (or the\n * cell may be virtualized out entirely). Treat scroll as a dismissal\n * signal equivalent to clicking outside so subclasses' overlay-outside\n * handler drives the appropriate commit/cancel path.\n */\n private _onGridScroll(): void {\n if (!this._isOpen || !this._panel) return;\n this.onOverlayOutsideClick();\n }\n\n /**\n * Set up a MutationObserver on the parent cell to watch for\n * `cell-focus` class changes. This handles row-editing mode where\n * all editors exist simultaneously but only the focused cell's\n * editor should have its overlay visible.\n *\n * A `justOpened` flash guard suppresses the observer from\n * immediately closing the overlay when `beginBulkEdit()` moves\n * focus to the first editable column. Without this guard,\n * double-click triggers a \"flash open then close\" effect.\n */\n protected _setupFocusObserver(): void {\n const cell = this._getCell();\n if (!cell) return;\n\n let justOpened = false;\n\n let pendingHideRaf = 0;\n\n const hostEl = this._elementRef.nativeElement;\n\n this._focusObserver = new MutationObserver((mutations) => {\n // Guard: if the editor's host element is no longer inside the cell,\n // it means the component was detached (e.g., editing session ended\n // and the render pipeline cleared the cell DOM). Disconnect to\n // prevent orphaned observers from opening stale overlay panels.\n if (!cell.contains(hostEl)) {\n this._focusObserver?.disconnect();\n this._focusObserver = null;\n return;\n }\n\n for (const mutation of mutations) {\n if (mutation.type !== 'attributes' || mutation.attributeName !== 'class') continue;\n\n const isFocused = cell.classList.contains('cell-focus');\n if (isFocused && !this._isOpen) {\n // Cell just gained focus — cancel any pending hide and open overlay.\n if (pendingHideRaf) {\n cancelAnimationFrame(pendingHideRaf);\n pendingHideRaf = 0;\n }\n justOpened = true;\n this.showOverlay();\n this.onOverlayOpened();\n // Clear the guard after a macrotask so that an immediate\n // focus-away (e.g. beginBulkEdit focus adjustment) does\n // not close the overlay in the same event loop tick.\n setTimeout(() => {\n justOpened = false;\n }, 0);\n } else if (!isFocused && this._isOpen && !justOpened) {\n // Cell lost focus — defer hide to allow render cycles to settle.\n // Re-renders (e.g., from ResizeObserver after a footer appears)\n // may transiently toggle cell-focus within the same frame.\n // Deferring to the next animation frame lets the render pipeline\n // finish before we decide whether the overlay should actually close.\n if (pendingHideRaf) cancelAnimationFrame(pendingHideRaf);\n pendingHideRaf = requestAnimationFrame(() => {\n pendingHideRaf = 0;\n // Re-check settled state — cell-focus may have been re-applied\n if (!cell.classList.contains('cell-focus') && this._isOpen) {\n this.hideOverlay(true);\n }\n });\n }\n }\n });\n\n this._focusObserver.observe(cell, { attributes: true, attributeFilter: ['class'] });\n }\n}\n","/**\n * Editing feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `editing` input on Grid directive AND to\n * install the `before-edit-close` blur bridge that flushes pending input from\n * Angular editors that commit on `(blur)` before the cell DOM is torn down by\n * Tab / programmatic row exit.\n *\n * Without this import, Angular `(blur)`-committing editors silently lose\n * pending input on programmatic row exit.\n *\n * @example\n * ```typescript\n * import '@toolbox-web/grid-angular/features/editing';\n *\n * <tbw-grid [editing]=\"'dblclick'\" />\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { ColumnEditorContext, ColumnEditorSpec } from '@toolbox-web/grid';\nimport {\n type GridAdapter,\n makeFlushFocusedInput,\n registerEditorMountHook,\n registerEditorSpecBridge,\n} from '@toolbox-web/grid-angular';\nimport '@toolbox-web/grid/features/editing';\nimport { getEditorTemplate, type GridEditorContext } from './grid-column-editor.directive';\nimport { getFormArrayContext } from './grid-form-array.directive';\nimport { getLazyFormContext } from './grid-lazy-form.directive';\nimport { getStructuralEditorTemplate } from './structural-editor.directive';\n\nexport { GridEditingDirective } from './grid-editing.directive';\nexport type { _Augmentation as _EditingAugmentation } from '@toolbox-web/grid/features/editing';\n\n// ---------------------------------------------------------------------------\n// Editing-owned public API. These symbols physically live in this secondary\n// entry; the grid core only exposes generic embedded-view primitives and\n// delegates all template-editor resolution to the bridge installed below.\n// ---------------------------------------------------------------------------\nexport { BaseGridEditor } from './base-grid-editor';\nexport { BaseGridEditorCVA } from './base-grid-editor-cva';\nexport { BaseOverlayEditor } from './base-overlay-editor';\nexport type { OverlayPosition } from './base-overlay-editor';\nexport { getEditorTemplate, GridColumnEditor } from './grid-column-editor.directive';\nexport type { GridEditorContext } from './grid-column-editor.directive';\nexport { getFormArrayContext, GridFormArray } from './grid-form-array.directive';\nexport type { FormArrayContext } from './grid-form-array.directive';\nexport { getLazyFormContext, GridLazyForm } from './grid-lazy-form.directive';\nexport type { LazyFormFactory, RowFormChangeEvent } from './grid-lazy-form.directive';\nexport { getStructuralEditorTemplate, TbwEditor } from './structural-editor.directive';\nexport type { StructuralEditorContext } from './structural-editor.directive';\n\n// ---------------------------------------------------------------------------\n// Install the template-based editor bridge. The grid adapter delegates\n// `createEditor()` / `canHandle()` to this function, which resolves the\n// Angular editor template (`*tbwEditor` or nested `<tbw-grid-column-editor>`),\n// wires the FormArray control (if the grid is bound to a FormArray), and\n// mounts the template via the adapter's generic editor-view primitive.\n// ---------------------------------------------------------------------------\nregisterEditorSpecBridge(\n <TRow, TValue>(element: HTMLElement, adapter: GridAdapter): ColumnEditorSpec<TRow, TValue> | undefined => {\n // Resolve the editor template: structural `*tbwEditor` first, then the\n // nested `<tbw-grid-column-editor>` directive. The cast target is derived\n // from `getStructuralEditorTemplate` (same package instance as the adapter),\n // NOT from a local `import type { TemplateRef } from '@angular/core'` — the\n // latter resolves through Bun's `.bun/` cache during ng-packagr build and\n // produces a brand-incompatible `TemplateRef` vs the built adapter `.d.ts`\n // (see the shell feature entry for the same guard). `StructuralEditorContext`\n // uses `any` type defaults, which preserves assignability with the generic\n // `GridEditorContext<TValue, TRow>` at the `createEditorTemplateView` call.\n const template = (getStructuralEditorTemplate(element) ?? getEditorTemplate(element)) as\n | ReturnType<typeof getStructuralEditorTemplate>\n | undefined;\n\n if (!template) {\n // No template registered — let the grid use its built-in editors. This\n // allows columns with only `*tbwRenderer` (no `*tbwEditor`) to remain\n // editable via the default text/number/boolean editors.\n return undefined;\n }\n\n // Find the parent grid element for FormArray context access.\n const gridElement = element.closest('tbw-grid, [data-tbw-grid]') as HTMLElement | null;\n\n return (ctx: ColumnEditorContext<TRow, TValue>) => {\n const onCommit = (value: TValue) => ctx.commit(value);\n const onCancel = () => ctx.cancel();\n\n // Resolve the FormControl from the FormArrayContext, if available.\n // Both GridFormArray and GridLazyForm expose a FormArrayContext, but each\n // stores it under its own module-local Symbol. Check both so control-based\n // template editors (`*tbwEditor=\"let _; control as control\"`) receive the\n // FormControl whether the grid uses `[formArray]` or `[lazyForm]`.\n let control: GridEditorContext<TValue, TRow>['control'];\n if (gridElement) {\n const formContext = getFormArrayContext(gridElement) ?? getLazyFormContext(gridElement);\n if (formContext?.hasFormGroups) {\n const gridRows = (gridElement as { rows?: TRow[] }).rows;\n if (gridRows) {\n const rowIndex = gridRows.indexOf(ctx.row);\n if (rowIndex >= 0) {\n control = formContext.getControl(rowIndex, ctx.field as string);\n }\n }\n }\n }\n\n const context: GridEditorContext<TValue, TRow> = {\n $implicit: ctx.value,\n value: ctx.value,\n row: ctx.row,\n field: ctx.field as string,\n column: ctx.column,\n rowId: ctx.rowId ?? '',\n onCommit,\n onCancel,\n updateRow: ctx.updateRow,\n onValueChange: ctx.onValueChange,\n control,\n };\n\n // Mount the template via the adapter's generic editor-view primitive\n // (tracks the view in the per-cell editor pool, wraps root nodes in a\n // stable `display:contents` span, and runs editor-mount hooks).\n const { container, viewRef } = adapter.createEditorTemplateView(template, context);\n\n // Auto-wire: listen for commit/cancel events on the rendered component so\n // components can just emit `(commit)` / `(cancel)` without explicit\n // template bindings.\n container.addEventListener('commit', (e: Event) => {\n ctx.commit((e as CustomEvent<TValue>).detail);\n });\n container.addEventListener('cancel', () => {\n ctx.cancel();\n });\n\n // Auto-update the editor when the value changes externally (e.g. updateRow\n // cascade or Escape-revert). Angular's own bindings/control flow handle the\n // re-render; we just re-sync root nodes in case control flow changed them.\n ctx.onValueChange?.((newVal: unknown) => {\n context.$implicit = newVal as TValue;\n context.value = newVal as TValue;\n viewRef.detectChanges();\n adapter.syncEditorTemplateView(viewRef, container);\n });\n\n return container;\n };\n },\n);\n\n// Bridge the editing plugin's `before-edit-close` event to a synchronous\n// `.blur()` on the focused input/textarea/select inside the editor host.\n// Angular editors that commit on `(blur)` rely on the focused control firing\n// blur naturally, but Tab / programmatic row exit rebuilds the cell DOM\n// synchronously without giving the focused control a chance to blur first.\nregisterEditorMountHook(({ container, gridEl }) => {\n const flush = makeFlushFocusedInput(container);\n gridEl.addEventListener('before-edit-close', flush);\n return () => gridEl.removeEventListener('before-edit-close', flush);\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["FORM_ARRAY_CONTEXT"],"mappings":";;;;;;;;AA8DA;AACA,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAA+C;AAErF;;;AAGG;AACG,SAAU,iBAAiB,CAAC,OAAoB,EAAA;AACpD,IAAA,OAAO,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC;AAC5C;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CG;MAEU,gBAAgB,CAAA;AACnB,IAAA,UAAU,GAAG,MAAM,EAAC,UAAuB,EAAC;AAEpD;;AAEG;AACH,IAAA,QAAQ,GAAG,YAAY,EAAC,WAA8B;iFAAC;;AAG/C,IAAA,kBAAkB,GAAG,MAAM,CAAC,MAAK;AACvC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE;QAChC,IAAI,QAAQ,EAAE;;YAEZ,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,QAAQ,CAAC;QACrE;IACF,CAAC;2FAAC;AAEF;;;AAGG;AACH,IAAA,OAAO,sBAAsB,CAAC,GAAqB,EAAE,GAAY,EAAA;AAC/D,QAAA,OAAO,IAAI;IACb;uGAvBW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,OAAA,EAAA,CAAA,EAAA,YAAA,EAAA,UAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,GAMH,WAA8B,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAN3C,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,SAAS;mBAAC,EAAE,QAAQ,EAAE,wBAAwB,EAAE;6FAOvB,WAA8B,CAAA,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;ACjCxD;AACA,MAAMA,oBAAkB,GAAG,MAAM,CAAC,kBAAkB,CAAC;AAErD;;;;AAIG;AACG,SAAU,mBAAmB,CAAC,WAAwB,EAAA;AAC1D,IAAA,OAAQ,WAA2D,CAACA,oBAAkB,CAAC;AACzF;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DG;MAIU,aAAa,CAAA;AACP,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AACxC,IAAA,UAAU,GAAG,MAAM,EAAC,UAAuB,EAAC;IAC5C,eAAe,GAAwB,IAAI;IAC3C,eAAe,GAAwB,IAAI;IAC3C,cAAc,GAAwB,IAAI;IAC1C,aAAa,GAAgC,IAAI;IACjD,wBAAwB,GAAwB,IAAI;IACpD,0BAA0B,GAAmB,EAAE;AAEvD;;AAEG;IACM,SAAS,GAAG,KAAK,CAAC,QAAQ;kFAAa;AAEhD;;;;;;;;;;AAUG;IACM,cAAc,GAAG,KAAK,CAAU,IAAI;uFAAC;AAE9C;;;AAGG;AACK,IAAA,mBAAmB,GAAG,MAAM,CAAC,MAAK;AACxC,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;AAClC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS;YAAE;;AAGzB,QAAA,IAAI,CAAC,wBAAwB,EAAE,WAAW,EAAE;;;;;;;;;AAU5C,QAAA,IAAI,CAAC,wBAAwB,GAAG,SAAS,CAAC;AACvC,aAAA,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;aAC5E,SAAS,CAAC,MAAK;;;;;AAKd,YAAA,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;gBAAE;AAEjC,YAAA,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,WAAW,EAAE;AACrC,QAAA,CAAC,CAAC;IACN,CAAC;4FAAC;IAEF,QAAQ,GAAA;AACN,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;;AAGX,QAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;;AAG5B,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,EAAE,CAC5B,aAAa,EACb,CAAC,MAA6F,KAAI;AAChG,YAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;AAChC,QAAA,CAAC,CACF;;AAGD,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,EAAE,CAC5B,aAAa,EACb,CAAC,MAAmE,KAAI;AACtE,YAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;AAChC,QAAA,CAAC,CACF;;AAGD,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,CAC3B,YAAY,EACZ,CAAC,MAA8D,EAAE,KAAkB,KAAI;AACrF,YAAA,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;gBAAE;AAC5B,YAAA,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC;AACtC,QAAA,CAAC,CACF;;AAGD,QAAA,IAAI,CAAC,aAAa,GAAG,MAAK;AACxB,YAAA,IAAI,CAAC,SAAS,EAAE,CAAC,aAAa,EAAE;;AAEhC,YAAA,IAAI,IAAI,CAAC,aAAa,EAAE;gBACtB,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC;AACrD,gBAAA,IAAI,CAAC,aAAa,GAAG,IAAI;YAC3B;AACF,QAAA,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC;;;QAIlD,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAK;YACvB,IAAI,IAAI,CAAC,cAAc,EAAE,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;gBAC/C,IAAI,CAAC,wBAAwB,EAAE;;gBAE/B,IAAI,CAAC,uBAAuB,EAAE;YAChC;AACF,QAAA,CAAC,CAAC;IACJ;IAEA,WAAW,GAAA;AACT,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,IAAI,CAAC,eAAe,IAAI;AACxB,QAAA,IAAI,CAAC,eAAe,IAAI;AACxB,QAAA,IAAI,CAAC,cAAc,IAAI;AACvB,QAAA,IAAI,IAAI,CAAC,aAAa,EAAE;YACtB,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC;QACvD;AACA,QAAA,IAAI,IAAI,CAAC,wBAAwB,EAAE;AACjC,YAAA,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE;QAC7C;;AAEA,QAAA,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC;AACnE,QAAA,IAAI,CAAC,0BAA0B,GAAG,EAAE;AAEpC,QAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;IAC9B;AAEA;;AAEG;IACH,WAAW,GAAA;AACT,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;AAAE,YAAA,OAAO,KAAK;QAEvB,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,GAAG,SAAS,CAEzC;AAEb,QAAA,OAAO,aAAa,EAAE,MAAM,EAAE,IAAI,KAAK,MAAM;IAC/C;AAEA;;;;AAIG;AACH,IAAA,gBAAgB,CAAC,IAAiB,EAAA;AAChC,QAAA,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;AAAE,YAAA,OAAO,KAAK;AACrC,QAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa;AACrC,QAAA,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,KAAK;;AAEzB,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,IAAI;IACpE;AAEA;;;AAGG;IACH,wBAAwB,GAAA;AACtB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;AAClC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;;AAGX,QAAA,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC;AACnE,QAAA,IAAI,CAAC,0BAA0B,GAAG,EAAE;;AAGpC,QAAA,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;YAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AACpD,YAAA,IAAI,CAAC,YAAY;gBAAE;;YAGnB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC;AAC5C,YAAA,IAAI,CAAC,KAAK;gBAAE;;AAGZ,YAAA,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;gBACnD,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;AACvC,gBAAA,IAAI,CAAC,OAAO;oBAAE;gBAEd,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,MAAK;oBAC3G,IAAI,CAAC,4BAA4B,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC;AAC1D,gBAAA,CAAC,CAAC;AAEF,gBAAA,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC;AAC3C,YAAA,CAAC,CAAC;QACJ;IACF;AAEA;;;AAGG;IACH,uBAAuB,GAAA;AACrB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;AAClC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;YAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AACpD,YAAA,IAAI,CAAC,YAAY;gBAAE;YAEnB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC;AAC5C,YAAA,IAAI,CAAC,KAAK;gBAAE;AAEZ,YAAA,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;gBACnD,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;gBACvC,IAAI,OAAO,EAAE;oBACX,IAAI,CAAC,4BAA4B,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC;gBAC1D;AACF,YAAA,CAAC,CAAC;QACJ;IACF;AAEA;;AAEG;IACH,SAAS,CAAC,IAAiB,EAAE,QAAgB,EAAA;AAC3C,QAAA,IAAI;AACF,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;AACtB,YAAA,MAAM,GAAG,GAAG,IAAI,GAAG,QAAQ,CAAC;AAC5B,YAAA,IAAI,CAAC,GAAG;AAAE,gBAAA,OAAO,SAAS;AAC1B,YAAA,OAAO,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC;QAC7B;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,SAAS;QAClB;IACF;AAEA;;AAEG;IACH,wBAAwB,GAAA;AACtB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;AAClC,QAAA,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;AAAE,YAAA,OAAO,KAAK;QACxC,OAAO,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,SAAS;IAC7C;AAEA;;AAEG;AACH,IAAA,gBAAgB,CAAC,QAAgB,EAAA;AAC/B,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;QAClC,MAAM,UAAU,GAAG,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC;QACzC,OAAO,UAAU,YAAY,SAAS,GAAG,UAAU,GAAG,SAAS;IACjE;AAEA;;AAEG;AACH,IAAA,iBAAiB,CAAC,IAAiB,EAAA;AACjC,QAAA,MAAM,eAAe,GAAG,CAAC,QAAgB,KAAK,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;;QAE7E,MAAM,IAAI,GAAG,IAAI;AAEjB,QAAA,MAAM,OAAO,GAAqB;AAChC,YAAA,MAAM,EAAE,CAAI,QAAgB,KAAc;AACxC,gBAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;gBAClC,MAAM,UAAU,GAAG,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC;gBACzC,OAAO,UAAU,GAAI,UAAU,CAAC,KAAW,GAAG,IAAI;YACpD,CAAC;YACD,WAAW,EAAE,CAAC,QAAgB,EAAE,KAAa,EAAE,KAAc,KAAI;AAC/D,gBAAA,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC;gBAC9C,IAAI,YAAY,EAAE;oBAChB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;oBACvC,IAAI,OAAO,EAAE;AACX,wBAAA,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;wBACvB,OAAO,CAAC,WAAW,EAAE;oBACvB;gBACF;YACF,CAAC;YACD,QAAQ,EAAE,MAAa;AACrB,gBAAA,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,WAAW,EAAS;YAC9C,CAAC;AACD,YAAA,IAAI,aAAa,GAAA;AACf,gBAAA,OAAO,IAAI,CAAC,wBAAwB,EAAE;YACxC,CAAC;AACD,YAAA,UAAU,EAAE,CAAC,QAAgB,EAAE,KAAa,KAAiC;AAC3E,gBAAA,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC;AAC9C,gBAAA,IAAI,CAAC,YAAY;AAAE,oBAAA,OAAO,SAAS;gBACnC,OAAO,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,SAAS;YAC7C,CAAC;YACD,eAAe;AACf,YAAA,UAAU,EAAE,CAAC,QAAgB,KAAa;AACxC,gBAAA,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC;AAC9C,gBAAA,IAAI,CAAC,YAAY;AAAE,oBAAA,OAAO,IAAI;gBAC9B,OAAO,YAAY,CAAC,KAAK;YAC3B,CAAC;AACD,YAAA,YAAY,EAAE,CAAC,QAAgB,KAAa;AAC1C,gBAAA,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC;AAC9C,gBAAA,IAAI,CAAC,YAAY;AAAE,oBAAA,OAAO,KAAK;gBAC/B,OAAO,YAAY,CAAC,OAAO;YAC7B,CAAC;AACD,YAAA,UAAU,EAAE,CAAC,QAAgB,KAAa;AACxC,gBAAA,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC;AAC9C,gBAAA,IAAI,CAAC,YAAY;AAAE,oBAAA,OAAO,KAAK;gBAC/B,OAAO,YAAY,CAAC,KAAK;YAC3B,CAAC;AACD,YAAA,YAAY,EAAE,CAAC,QAAgB,KAAoC;AACjE,gBAAA,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC;AAC9C,gBAAA,IAAI,CAAC,YAAY;AAAE,oBAAA,OAAO,IAAI;gBAE9B,MAAM,MAAM,GAA4B,EAAE;gBAC1C,IAAI,SAAS,GAAG,KAAK;AAErB,gBAAA,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;oBACnD,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;AACvC,oBAAA,IAAI,OAAO,EAAE,MAAM,EAAE;AACnB,wBAAA,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM;wBAC9B,SAAS,GAAG,IAAI;oBAClB;AACF,gBAAA,CAAC,CAAC;AAEF,gBAAA,IAAI,YAAY,CAAC,MAAM,EAAE;AACvB,oBAAA,MAAM,CAAC,QAAQ,CAAC,GAAG,YAAY,CAAC,MAAM;oBACtC,SAAS,GAAG,IAAI;gBAClB;gBAEA,OAAO,SAAS,GAAG,MAAM,GAAG,IAAI;YAClC,CAAC;SACF;AACA,QAAA,IAAoD,CAACA,oBAAkB,CAAC,GAAG,OAAO;IACrF;AAEA;;AAEG;AACH,IAAA,iBAAiB,CAAC,IAAiB,EAAA;AACjC,QAAA,OAAQ,IAAoD,CAACA,oBAAkB,CAAC;IAClF;AAEA;;AAEG;AACH,IAAA,iBAAiB,CAAC,MAA0E,EAAA;QAC1F,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM;QAEhD,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;QACpD,IAAI,YAAY,EAAE;YAChB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;YACvC,IAAI,OAAO,EAAE;AACX,gBAAA,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACvB,OAAO,CAAC,WAAW,EAAE;gBACrB,OAAO,CAAC,aAAa,EAAE;;AAGvB,gBAAA,IAAI,IAAI,CAAC,cAAc,EAAE,IAAI,KAAK,EAAE;oBAClC,IAAI,CAAC,4BAA4B,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC;gBAC1D;YACF;QACF;IACF;AAEA;;AAEG;IACH,gBAAgB,CAAC,KAAY,EAAE,MAA4B,EAAA;AACzD,QAAA,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM;QAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AAEpD,QAAA,IAAI,YAAY,IAAI,YAAY,CAAC,OAAO,EAAE;;YAExC,KAAK,CAAC,cAAc,EAAE;QACxB;IACF;AAEA;;;AAGG;AACH,IAAA,iBAAiB,CAAC,MAAmE,EAAA;QACnF,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM;QACjD,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;QAEpD,IAAI,YAAY,EAAE;YAChB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;YACvC,IAAI,OAAO,EAAE;gBACX,OAAO,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;gBACrD,OAAO,CAAC,cAAc,EAAE;YAC1B;QACF;IACF;AAEA;;AAEG;AACH,IAAA,4BAA4B,CAAC,KAAa,EAAE,KAAa,EAAE,OAAwB,EAAA;AACjF,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;;QAGX,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,GAAG,SAAS,CAAwC;AAE9F,QAAA,IAAI,CAAC,aAAa;YAAE;AAEpB,QAAA,IAAI,OAAO,CAAC,OAAO,EAAE;;YAEnB,MAAM,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC;YACxD,aAAa,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC;QACtD;aAAO;AACL,YAAA,aAAa,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;QAC1C;IACF;AAEA;;AAEG;AACH,IAAA,qBAAqB,CAAC,OAAwB,EAAA;AAC5C,QAAA,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM;AAC7B,QAAA,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,EAAE;QAEtB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvC,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC;;QAG9B,QAAQ,QAAQ;AACd,YAAA,KAAK,UAAU;AACb,gBAAA,OAAO,wBAAwB;AACjC,YAAA,KAAK,WAAW;AACd,gBAAA,OAAO,CAAA,kBAAA,EAAqB,KAAK,CAAC,cAAc,EAAE;AACpD,YAAA,KAAK,WAAW;AACd,gBAAA,OAAO,CAAA,kBAAA,EAAqB,KAAK,CAAC,cAAc,EAAE;AACpD,YAAA,KAAK,KAAK;AACR,gBAAA,OAAO,CAAA,iBAAA,EAAoB,KAAK,CAAC,GAAG,EAAE;AACxC,YAAA,KAAK,KAAK;AACR,gBAAA,OAAO,CAAA,iBAAA,EAAoB,KAAK,CAAC,GAAG,EAAE;AACxC,YAAA,KAAK,OAAO;AACV,gBAAA,OAAO,uBAAuB;AAChC,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,gBAAgB;AACzB,YAAA;;gBAEE,OAAO,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,IAAI,KAAK,EAAE,OAAO,IAAI,qBAAqB,QAAQ,CAAA,CAAE,CAAC;;IAEpG;uGA1bW,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAb,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAb,aAAa,EAAA,UAAA,EAAA,CAAA;kBAHzB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,qBAAqB;AAChC,iBAAA;;;ACzJD;AACA,MAAM,kBAAkB,GAAG,MAAM,CAAC,kBAAkB,CAAC;AAErD;;;;AAIG;AACG,SAAU,kBAAkB,CAAC,WAAwB,EAAA;AACzD,IAAA,OAAQ,WAA2D,CAAC,kBAAkB,CAAC;AACzF;AAmCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6EG;MAIU,YAAY,CAAA;AACf,IAAA,UAAU,GAAG,MAAM,EAAC,UAA6B,EAAC;;AAGlD,IAAA,cAAc,GAAG,IAAI,GAAG,EAAmB;;AAE3C,IAAA,WAAW,GAAG,IAAI,GAAG,EAAgB;;IAErC,eAAe,GAAkB,IAAI;IAErC,eAAe,GAAwB,IAAI;IAC3C,cAAc,GAAwB,IAAI;IAC1C,eAAe,GAAwB,IAAI;AAEnD;;;;;;;;;;;;AAYG;IACM,QAAQ,GAAG,KAAK,CAAC,QAAQ;iFAAyB;AAE3D;;;;;;;;;AASG;IACM,cAAc,GAAG,KAAK,CAAU,IAAI;uFAAC;AAE9C;;;;;;;AAOG;IACM,cAAc,GAAG,KAAK,CAAU,KAAK;uFAAC;AAE/C;;;AAGG;IACM,aAAa,GAAG,MAAM,EAA4B;IAE3D,QAAQ,GAAA;AACN,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;;AAGX,QAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;;AAG5B,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,EAAE,CAC5B,aAAa,EACb,CAAC,MAA6F,KAAI;AAChG,YAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;AAChC,QAAA,CAAC,CACF;;AAGD,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,MAA4C,EAAE,KAAkB,KAAI;AAC/G,YAAA,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC;AACtC,QAAA,CAAC,CAAC;;QAGF,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,MAAK;YACjD,IAAI,CAAC,kBAAkB,EAAE;AAC3B,QAAA,CAAC,CAAC;;QAGF,IAAI,CAAC,kBAAkB,EAAE;IAC3B;IAEA,WAAW,GAAA;AACT,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,IAAI,CAAC,eAAe,IAAI;AACxB,QAAA,IAAI,CAAC,cAAc,IAAI;AACvB,QAAA,IAAI,CAAC,eAAe,IAAI;AAExB,QAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;AAC5B,QAAA,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE;AAC3B,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE;IAC1B;;AAIA;;;AAGG;IACH,qBAAqB,CAAC,GAAS,EAAE,QAAgB,EAAA;QAC/C,IAAI,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;QAC5C,IAAI,CAAC,SAAS,EAAE;AACd,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC/B,YAAA,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC;YAClC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC;YACvC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC;QACrC;AACA,QAAA,OAAO,SAAS;IAClB;AAEA;;AAEG;AACH,IAAA,gBAAgB,CAAC,QAAgB,EAAA;AAC/B,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI;QACvB,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,IAAI,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,SAAS;AAEtE,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC1B,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;IACrC;AAEA;;;AAGG;AACH,IAAA,iBAAiB,CAAC,IAAuB,EAAA;AACvC,QAAA,MAAM,OAAO,GAAqB;AAChC,YAAA,MAAM,EAAE,CAAI,QAAgB,KAAc;AACxC,gBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;gBACtB,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,IAAI,IAAI,CAAC,MAAM;AAAE,oBAAA,OAAO,IAAI;AACjE,gBAAA,OAAO,IAAI,CAAC,QAAQ,CAAiB;YACvC,CAAC;YAED,WAAW,EAAE,CAAC,QAAgB,EAAE,KAAa,EAAE,KAAc,KAAI;gBAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;gBACjD,IAAI,SAAS,EAAE;oBACb,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;oBACpC,IAAI,OAAO,EAAE;AACX,wBAAA,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;wBACvB,OAAO,CAAC,WAAW,EAAE;oBACvB;gBACF;YACF,CAAC;YAED,QAAQ,EAAE,MAAa;AACrB,gBAAA,QAAQ,IAAI,CAAC,IAAI,IAAI,EAAE;YACzB,CAAC;;AAGD,YAAA,aAAa,EAAE,IAAI;AAEnB,YAAA,UAAU,EAAE,CAAC,QAAgB,EAAE,KAAa,KAAiC;AAC3E,gBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;gBACtB,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,IAAI,IAAI,CAAC,MAAM;AAAE,oBAAA,OAAO,SAAS;AAEtE,gBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAS;;gBAElC,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,QAAQ,CAAC;gBAC3D,OAAO,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,SAAS;YAC1C,CAAC;AAED,YAAA,eAAe,EAAE,CAAC,QAAgB,KAA2B;AAC3D,gBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;gBACtB,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,IAAI,IAAI,CAAC,MAAM;AAAE,oBAAA,OAAO,SAAS;AAEtE,gBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAS;;gBAElC,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,QAAQ,CAAC;YAClD,CAAC;AAED,YAAA,UAAU,EAAE,CAAC,QAAgB,KAAa;gBACxC,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;;AAEjD,gBAAA,IAAI,CAAC,SAAS;AAAE,oBAAA,OAAO,IAAI;gBAC3B,OAAO,SAAS,CAAC,KAAK;YACxB,CAAC;AAED,YAAA,YAAY,EAAE,CAAC,QAAgB,KAAa;gBAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AACjD,gBAAA,IAAI,CAAC,SAAS;AAAE,oBAAA,OAAO,KAAK;gBAC5B,OAAO,SAAS,CAAC,OAAO;YAC1B,CAAC;AAED,YAAA,UAAU,EAAE,CAAC,QAAgB,KAAa;gBACxC,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AACjD,gBAAA,IAAI,CAAC,SAAS;AAAE,oBAAA,OAAO,KAAK;gBAC5B,OAAO,SAAS,CAAC,KAAK;YACxB,CAAC;AAED,YAAA,YAAY,EAAE,CAAC,QAAgB,KAAoC;gBACjE,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AACjD,gBAAA,IAAI,CAAC,SAAS;AAAE,oBAAA,OAAO,IAAI;gBAE3B,MAAM,MAAM,GAA4B,EAAE;gBAC1C,IAAI,SAAS,GAAG,KAAK;AAErB,gBAAA,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;oBAChD,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;AACpC,oBAAA,IAAI,OAAO,EAAE,MAAM,EAAE;AACnB,wBAAA,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM;wBAC9B,SAAS,GAAG,IAAI;oBAClB;AACF,gBAAA,CAAC,CAAC;AAEF,gBAAA,IAAI,SAAS,CAAC,MAAM,EAAE;AACpB,oBAAA,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC,MAAM;oBACnC,SAAS,GAAG,IAAI;gBAClB;gBAEA,OAAO,SAAS,GAAG,MAAM,GAAG,IAAI;YAClC,CAAC;SACF;AAEA,QAAA,IAAoD,CAAC,kBAAkB,CAAC,GAAG,OAAO;IACrF;AAEA;;AAEG;AACH,IAAA,iBAAiB,CAAC,IAAuB,EAAA;AACvC,QAAA,OAAQ,IAAoD,CAAC,kBAAkB,CAAC;IAClF;;;AAMA;;;AAGG;IACH,kBAAkB,GAAA;AAChB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI;AACvB,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE;QACxB,IAAI,CAAC,OAAO,CAAC,CAAC,GAAS,EAAE,KAAa,KAAI;YACxC,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;gBAChC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;YAClC;AACF,QAAA,CAAC,CAAC;IACJ;AAEA;;AAEG;AACH,IAAA,iBAAiB,CAAC,MAA0E,EAAA;QAC1F,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM;QAEhD,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;QACjD,IAAI,SAAS,EAAE;YACb,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;YACpC,IAAI,OAAO,EAAE;AACX,gBAAA,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACvB,OAAO,CAAC,WAAW,EAAE;gBACrB,OAAO,CAAC,aAAa,EAAE;;AAGvB,gBAAA,IAAI,IAAI,CAAC,cAAc,EAAE,IAAI,KAAK,EAAE;oBAClC,IAAI,CAAC,4BAA4B,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC;gBAC1D;;AAGA,gBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;gBAC1C,MAAM,GAAG,GAAG,IAAI,EAAE,IAAI,GAAG,QAAQ,CAAC;gBAClC,IAAI,GAAG,EAAE;AACP,oBAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;wBACtB,QAAQ;wBACR,KAAK;wBACL,GAAG;wBACH,SAAS;wBACT,MAAM,EAAE,SAAS,CAAC,KAAK;wBACvB,KAAK,EAAE,SAAS,CAAC,KAAK;wBACtB,KAAK,EAAE,SAAS,CAAC,KAAK;AACvB,qBAAA,CAAC;gBACJ;YACF;QACF;IACF;AAEA;;;;;AAKG;IACH,gBAAgB,CAAC,KAAY,EAAE,MAA4C,EAAA;AACzE,QAAA,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,MAAM;AAClC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI;QACvB,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,IAAI,IAAI,CAAC,MAAM;YAAE;AAEtD,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;AAE9C,QAAA,IAAI,CAAC,SAAS;YAAE;;QAGhB,IAAI,IAAI,CAAC,cAAc,EAAE,IAAI,SAAS,CAAC,OAAO,EAAE;;YAE9C,SAAS,CAAC,gBAAgB,EAAE;YAC5B,KAAK,CAAC,cAAc,EAAE;YACtB;QACF;;AAGA,QAAA,IAAI,SAAS,CAAC,KAAK,EAAE;AACnB,YAAA,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK;YACjC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;AACvC,gBAAA,IAAI,KAAK,IAAI,GAAG,EAAE;oBACf,GAA+B,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC;gBAC5D;AACF,YAAA,CAAC,CAAC;QACJ;;AAGA,QAAA,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE;AAC1B,YAAA,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC;AAC/B,YAAA,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC;;YAG5B,IAAI,KAAK,EAAE;gBACT,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,GAAG,SAAS,CAAwC;AAC9F,gBAAA,aAAa,EAAE,eAAe,CAAC,KAAK,CAAC;YACvC;QACF;IACF;;;AAMA;;AAEG;AACH,IAAA,4BAA4B,CAAC,KAAa,EAAE,KAAa,EAAE,OAAwB,EAAA;AACjF,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,IAAI,CAAC,IAAI;YAAE;QAEX,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,GAAG,SAAS,CAAwC;AAE9F,QAAA,IAAI,CAAC,aAAa;YAAE;AAEpB,QAAA,IAAI,OAAO,CAAC,OAAO,EAAE;YACnB,MAAM,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC;YACxD,aAAa,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC;QACtD;aAAO;AACL,YAAA,aAAa,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;QAC1C;IACF;AAEA;;AAEG;AACH,IAAA,qBAAqB,CAAC,OAAwB,EAAA;AAC5C,QAAA,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM;AAC7B,QAAA,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,EAAE;QAEtB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvC,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC;QAE9B,QAAQ,QAAQ;AACd,YAAA,KAAK,UAAU;AACb,gBAAA,OAAO,wBAAwB;AACjC,YAAA,KAAK,WAAW;AACd,gBAAA,OAAO,CAAA,kBAAA,EAAqB,KAAK,CAAC,cAAc,EAAE;AACpD,YAAA,KAAK,WAAW;AACd,gBAAA,OAAO,CAAA,kBAAA,EAAqB,KAAK,CAAC,cAAc,EAAE;AACpD,YAAA,KAAK,KAAK;AACR,gBAAA,OAAO,CAAA,iBAAA,EAAoB,KAAK,CAAC,GAAG,EAAE;AACxC,YAAA,KAAK,KAAK;AACR,gBAAA,OAAO,CAAA,iBAAA,EAAoB,KAAK,CAAC,GAAG,EAAE;AACxC,YAAA,KAAK,OAAO;AACV,gBAAA,OAAO,uBAAuB;AAChC,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,gBAAgB;AACzB,YAAA;gBACE,OAAO,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,IAAI,KAAK,EAAE,OAAO,IAAI,qBAAqB,QAAQ,CAAA,CAAE,CAAC;;IAEpG;;;AAMA;;;;;;AAMG;AACH,IAAA,YAAY,CAAC,QAAgB,EAAA;AAC3B,QAAA,OAAO,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;IACxC;AAEA;;;;;AAKG;IACH,gBAAgB,GAAA;QACd,OAAO,IAAI,CAAC,cAAc;IAC5B;AAEA;;;AAGG;IACH,kBAAkB,GAAA;AAChB,QAAA,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE;AAC3B,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE;IAC1B;AAEA;;;;AAIG;IACH,WAAW,GAAA;QACT,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE;AACpD,YAAA,IAAI,SAAS,CAAC,OAAO,EAAE;gBACrB,SAAS,CAAC,gBAAgB,EAAE;AAC5B,gBAAA,OAAO,KAAK;YACd;QACF;AACA,QAAA,OAAO,IAAI;IACb;uGApbW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAZ,YAAY,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,aAAA,EAAA,eAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAZ,YAAY,EAAA,UAAA,EAAA,CAAA;kBAHxB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,oBAAoB;AAC/B,iBAAA;;;ACnGD;AACA,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAqD;AAE7F;;;AAGG;AACG,SAAU,2BAA2B,CACzC,aAA0B,EAAA;;IAG1B,MAAM,QAAQ,GAAG,wBAAwB,CAAC,GAAG,CAAC,aAAa,CAAC;AAC5D,IAAA,IAAI,QAAQ;AAAE,QAAA,OAAO,QAAQ;;IAG7B,MAAM,QAAQ,GAAG,aAAa,CAAC,aAAa,CAAC,wBAAwB,CAAC;IACtE,IAAI,QAAQ,EAAE;AACZ,QAAA,OAAO,iBAAiB,CAAC,QAAuB,CAAqD;IACvG;AACA,IAAA,OAAO,SAAS;AAClB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDG;MAEU,SAAS,CAAA;AACZ,IAAA,QAAQ,GAAG,MAAM,EAAC,WAAoC,EAAC;AACvD,IAAA,UAAU,GAAG,MAAM,EAAC,UAAuB,EAAC;IAC5C,aAAa,GAAuB,IAAI;AAEhD,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,gBAAgB,EAAE;AACzB,QAAA,CAAC,CAAC;IACJ;IAEQ,gBAAgB,GAAA;;QAEtB,IAAI,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,aAAa;AACzD,QAAA,OAAO,MAAM,IAAI,MAAM,CAAC,OAAO,KAAK,iBAAiB,IAAI,MAAM,CAAC,OAAO,KAAK,eAAe,EAAE;AAC3F,YAAA,MAAM,GAAG,MAAM,CAAC,aAAa;QAC/B;QAEA,IAAI,MAAM,EAAE;AACV,YAAA,IAAI,CAAC,aAAa,GAAG,MAAM;YAC3B,wBAAwB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC;QACrD;IACF;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,IAAI,CAAC,aAAa,EAAE;AACtB,YAAA,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;QACrD;IACF;AAEA;;;AAGG;AACH,IAAA,OAAO,sBAAsB,CAAC,GAAc,EAAE,GAAY,EAAA;AACxD,QAAA,OAAO,IAAI;IACb;uGApCW,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAT,SAAS,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAT,SAAS,EAAA,UAAA,EAAA,CAAA;kBADrB,SAAS;mBAAC,EAAE,QAAQ,EAAE,aAAa,EAAE;;;ACrHtC;;;;;;;;;;;;AAYG;AAsBH;;;;AAIG;MAMU,oBAAoB,CAAA;AACd,IAAA,UAAU,GAAG,MAAM,EAAC,UAA2B,EAAC;AAExD,IAAA,OAAO,GAAG,KAAK;2FAA6D;IAC5E,UAAU,GAAG,MAAM,EAAmB;IACtC,UAAU,GAAG,MAAM,EAAoB;IACvC,SAAS,GAAG,MAAM,EAAkB;;IAEpC,gBAAgB,GAAG,MAAM,EAA+B;;IAExD,QAAQ,GAAG,MAAM,EAAuB;;IAExC,eAAe,GAAG,MAAM,EAA8B;;IAEtD,SAAS,GAAG,MAAM,EAAwB;;IAE1C,WAAW,GAAG,MAAM,EAA0B;AACvD;;;;;;AAMG;IACM,iBAAiB,GAAG,MAAM,EAA2B;AAE7C,IAAA,SAAS,GAAG,IAAI,GAAG,EAA8B;IAC1D,OAAgB,MAAM,GAAG;QAC/B,aAAa;QACb,aAAa;QACb,YAAY;QACZ,oBAAoB;QACpB,WAAW;QACX,mBAAmB;QACnB,YAAY;QACZ,cAAc;QACd,oBAAoB;KACZ;AAEV,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;AAC3D,QAAA,KAAK,MAAM,EAAE,IAAI,oBAAoB,CAAC,MAAM;AAAE,YAAA,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;IACpE;IAEA,QAAQ,GAAA;AACN,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAC1C,QAAA,MAAM,IAAI,GAAG,CAAI,IAAY,EAAE,GAA6B,KAAU;AACpE,YAAA,MAAM,CAAC,GAAG,CAAC,CAAQ,KAAW,GAAG,CAAC,IAAI,CAAE,CAAoB,CAAC,MAAM,CAAC;AACpE,YAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;AAC7B,QAAA,CAAC;AACD,QAAA,IAAI,CAAkB,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;AACrD,QAAA,IAAI,CAAmB,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC;AACtD,QAAA,IAAI,CAAiB,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC;;AAElD,QAAA,IAAI,CAA8B,oBAAoB,EAAE,IAAI,CAAC,gBAAgB,CAAC;;AAE9E,QAAA,IAAI,CAAsB,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC;;AAErD,QAAA,IAAI,CAA6B,mBAAmB,EAAE,IAAI,CAAC,eAAe,CAAC;;AAE3E,QAAA,IAAI,CAAuB,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC;;AAExD,QAAA,IAAI,CAAyB,cAAc,EAAE,IAAI,CAAC,WAAW,CAAC;AAC9D,QAAA,IAAI,CAA0B,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC;IAC7E;IAEA,WAAW,GAAA;AACT,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;QAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS;AAAE,YAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,CAAC;AACzE,QAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;AACtB,QAAA,sBAAsB,CAAC,IAAI,EAAE,SAAS,CAAC;AACvC,QAAA,KAAK,MAAM,EAAE,IAAI,oBAAoB,CAAC,MAAM;AAAE,YAAA,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;IACtE;uGA1EW,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAApB,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wOAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,UAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,SAAA,EAAA,WAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,WAAA,EAAA,WAAA,EAAA,aAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAApB,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBALhC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EACN,wOAAwO;AAC1O,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA;;;ACvCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DG;MAEmB,cAAc,CAAA;AACf,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AACjC,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;;IAGzC,iBAAiB,GAAwB,IAAI;;;;AAMrD;;;AAGG;AACM,IAAA,KAAK,GAAG,KAAK;yFAAU;AAEhC;;AAEG;AACM,IAAA,GAAG,GAAG,KAAK;uFAAQ;AAE5B;;AAEG;AACM,IAAA,MAAM,GAAG,KAAK;0FAAsB;AAE7C;;;AAGG;AACM,IAAA,OAAO,GAAG,KAAK;2FAAmB;;;;AAM3C;;;AAGG;IACM,MAAM,GAAG,MAAM,EAAiB;AAEzC;;AAEG;IACM,MAAM,GAAG,MAAM,EAAQ;;;;AAMhC;;;AAGG;AACM,IAAA,YAAY,GAAG,QAAQ,CAAqB,MAAK;AACxD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE;QAC3B,IAAI,IAAI,EAAE;YACR,OAAO,IAAI,CAAC,KAAe;QAC7B;AACA,QAAA,OAAO,IAAI,CAAC,KAAK,EAAE;IACrB,CAAC;qFAAC;AAEF;;;AAGG;AACM,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAK;QACjC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,IAAI,KAAK;IACzC,CAAC;kFAAC;AAEF;;;AAGG;AACM,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;QAC/B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,IAAI,KAAK;IACvC,CAAC;gFAAC;AAEF;;;AAGG;AACM,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAK;QACjC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,IAAI,KAAK;IACzC,CAAC;kFAAC;AAEF;;AAEG;AACM,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAK;AACjC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE;AAC3B,QAAA,OAAO,IAAI,EAAE,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC;IACpE,CAAC;kFAAC;AAEF;;;AAGG;AACM,IAAA,iBAAiB,GAAG,QAAQ,CAAC,MAAK;AACzC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE;QAC3B,IAAI,CAAC,IAAI,EAAE,MAAM;AAAE,YAAA,OAAO,EAAE;AAE5B,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5C,QAAA,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9D,CAAC;0FAAC;AAEF;;AAEG;AACM,IAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAK;AACxC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE;QAC3B,IAAI,CAAC,IAAI,EAAE,MAAM;AAAE,YAAA,OAAO,EAAE;AAE5B,QAAA,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC5F,CAAC;yFAAC;;;;AAMF,IAAA,WAAA,GAAA;QACE,eAAe,CAAC,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;AACpD,QAAA,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,MAAK;AAC9B,YAAA,IAAI,CAAC,iBAAiB,IAAI;AAC1B,YAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI;AAC/B,QAAA,CAAC,CAAC;IACJ;IAEQ,sBAAsB,GAAA;AAC5B,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,2BAA2B,CAEtE;AACR,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,IAAI,WAAqC;AACzC,QAAA,IAAI,UAAoC;QAExC,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC,mBAAmB,EAAE,MAAK;YAC9C,IAAI,CAAC,iBAAiB,EAAE;YACxB,WAAW,IAAI;YACf,WAAW,GAAG,SAAS;AACzB,QAAA,CAAC,CAAC;QAEF,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,MAAK;YACtC,IAAI,CAAC,WAAW,EAAE;YAClB,UAAU,IAAI;YACd,UAAU,GAAG,SAAS;AACxB,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,CAAC,iBAAiB,GAAG,MAAK;YAC5B,WAAW,IAAI;YACf,UAAU,IAAI;AAChB,QAAA,CAAC;IACH;;;;AAMA;;;;;;;;AAQG;IACO,aAAa,GAAA;AACrB,QAAA,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,KAAK;IAC1G;AAEA;;;;;;;;AAQG;IACO,iBAAiB,GAAA;;IAE3B;AAEA;;;;;;;;;AASG;IACO,WAAW,GAAA;;IAErB;AAEA;;;;;;;;;;;;AAYG;AACH,IAAA,qBAAqB,CAAC,OAAe,EAAA;;IAErC;AAEA;;;;AAIG;AACH,IAAA,WAAW,CAAC,QAAuB,EAAA;;AAEjC,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;;;QAI1B,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7G;AAEA;;;AAGG;IACH,UAAU,GAAA;;AAER,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;;AAGlB,QAAA,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3F;AAEA;;;;;;;AAOG;IACO,eAAe,CAAC,QAAgB,EAAE,UAAoB,EAAA;QAC9D,QAAQ,QAAQ;AACd,YAAA,KAAK,UAAU;AACb,gBAAA,OAAO,wBAAwB;YACjC,KAAK,WAAW,EAAE;gBAChB,MAAM,GAAG,GAAG,UAAyC;AACrD,gBAAA,OAAO,qBAAqB,GAAG,EAAE,cAAc,IAAI,SAAS,EAAE;YAChE;YACA,KAAK,WAAW,EAAE;gBAChB,MAAM,GAAG,GAAG,UAAyC;AACrD,gBAAA,OAAO,qBAAqB,GAAG,EAAE,cAAc,IAAI,SAAS,EAAE;YAChE;YACA,KAAK,KAAK,EAAE;gBACV,MAAM,GAAG,GAAG,UAA8B;AAC1C,gBAAA,OAAO,oBAAoB,GAAG,EAAE,GAAG,IAAI,SAAS,EAAE;YACpD;YACA,KAAK,KAAK,EAAE;gBACV,MAAM,GAAG,GAAG,UAA8B;AAC1C,gBAAA,OAAO,oBAAoB,GAAG,EAAE,GAAG,IAAI,SAAS,EAAE;YACpD;AACA,YAAA,KAAK,OAAO;AACV,gBAAA,OAAO,uBAAuB;AAChC,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,gBAAgB;AACzB,YAAA;gBACE,OAAO,CAAA,eAAA,EAAkB,QAAQ,CAAA,CAAA,CAAG;;IAE1C;uGAvRoB,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAd,cAAc,EAAA,YAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAd,cAAc,EAAA,UAAA,EAAA,CAAA;kBADnC;;;AC9DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDG;AAEG,MAAgB,iBACpB,SAAQ,cAA4B,CAAA;;;;;;AAS5B,IAAA,SAAS,GAAmC,MAAK,EAAE,CAAC;;;AAIpD,IAAA,UAAU,GAAe,MAAK,EAAE,CAAC;AAEzC;;;AAGG;IACgB,QAAQ,GAAG,MAAM,CAAgB,IAAI;iFAAC;AAEzD;;;AAGG;IACM,aAAa,GAAG,MAAM,CAAC,KAAK;sFAAC;AAEtC;;;;;;;;AAQG;AACM,IAAA,YAAY,GAAG,QAAQ,CAAgB,MAAK;QACnD,OAAQ,IAAI,CAAC,YAAY,EAAyB,IAAI,IAAI,CAAC,QAAQ,EAAE;IACvE,CAAC;qFAAC;;;;AAMF;;AAEG;AACH,IAAA,UAAU,CAAC,KAAoB,EAAA;AAC7B,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;IAC1B;AAEA;;AAEG;AACH,IAAA,gBAAgB,CAAC,EAAkC,EAAA;AACjD,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;IACrB;AAEA;;AAEG;AACH,IAAA,iBAAiB,CAAC,EAAc,EAAA;AAC9B,QAAA,IAAI,CAAC,UAAU,GAAG,EAAE;IACtB;AAEA;;AAEG;AACH,IAAA,gBAAgB,CAAC,UAAmB,EAAA;AAClC,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC;IACpC;;;;AAMA;;;;;;;;;;AAUG;AACO,IAAA,UAAU,CAAC,KAAoB,EAAA;;AAEvC,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;AACxB,QAAA,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;QACrB,IAAI,CAAC,UAAU,EAAE;;;AAIjB,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;IACzB;uGAjGoB,iBAAiB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAjB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBADtC;;;ACvCD;AAEA;AAEA;AACA,IAAI,qBAAqB,GAAG,KAAK;AAEjC;;;;;;AAMG;AACH,MAAM,cAAc,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqDhC;AAED,SAAS,mBAAmB,GAAA;AAC1B,IAAA,IAAI,qBAAqB;QAAE;IAC3B,qBAAqB,GAAG,IAAI;IAE5B,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC;AAC7C,IAAA,KAAK,CAAC,YAAY,CAAC,kBAAkB,EAAE,EAAE,CAAC;AAC1C,IAAA,KAAK,CAAC,WAAW,GAAG,cAAc;AAClC,IAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AAClC;AAEA;AAEA;AACA,IAAI,aAAa,GAAG,CAAC;AACrB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiGG;AAEG,MAAgB,iBAAoD,SAAQ,cAA4B,CAAA;AAC3F,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;AAChC,IAAA,kBAAkB,GAAG,MAAM,CAAC,UAAU,CAAC;;;;AAMxD;;;;;AAKG;IACO,eAAe,GAAoB,OAAO;;;;;IAO5C,MAAM,GAAuB,IAAI;;IAG/B,OAAO,GAAG,KAAK;;IAGjB,SAAS,GAAG,EAAE;;IAGd,eAAe,GAAG,KAAK;;IAGvB,UAAU,GAA2B,IAAI;;IAGvC,cAAc,GAA4B,IAAI;;;;AAMxD,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,eAAe,GAAG,OAAO,GAAG,KAAK,WAAW,IAAI,GAAG,CAAC,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAC;AACvF,QAAA,mBAAmB,EAAE;QAErB,eAAe,CAAC,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;AACjD,QAAA,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;IACjE;;;;AAMA;;;;;;;AAOG;AACO,IAAA,WAAW,CAAC,KAAkB,EAAA;AACtC,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;;AAGnB,QAAA,IAAI,CAAC,SAAS,GAAG,cAAc,EAAE,aAAa,EAAE;AAChD,QAAA,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACxC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,eAAe,CAAC;QACpD,KAAK,CAAC,YAAY,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC;AACpD,QAAA,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM;;AAG5B,QAAA,IAAI,IAAI,CAAC,eAAe,EAAE;AACxB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;YAC5B,IAAI,IAAI,EAAE;AACR,gBAAA,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,CAAA,EAAA,EAAK,IAAI,CAAC,SAAS,CAAA,CAAE,CAAC;AAC5D,gBAAA,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,sBAAsB,EAAE,CAAA,EAAA,EAAK,IAAI,CAAC,SAAS,CAAA,CAAE,CAAC;YACxE;QACF;;AAGA,QAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;;;QAIhC,IAAI,CAAC,eAAe,EAAE,EAAE,8BAA8B,GAAG,KAAK,CAAC;;AAG/D,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI,eAAe,EAAE;AACvC,QAAA,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE;AAC9E,YAAA,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM;AAC/B,SAAA,CAAC;;;;;AAMF,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,EAAE;QACnC,IAAI,IAAI,EAAE;AACR,YAAA,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC,aAAa,EAAE,EAAE;AAC9D,gBAAA,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM;AAC/B,aAAA,CAAC;QACJ;;;;AAKA,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE;YACrD,IAAI,CAAC,WAAW,EAAE;YAClB,IAAI,CAAC,eAAe,EAAE;QACxB;IACF;AAEA;;;;;AAKG;IACO,WAAW,GAAA;AACnB,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO;YAAE;AAElC,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI;QACnB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE;;AAG9B,QAAA,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;YACzB,IAAI,CAAC,eAAe,EAAE;QACxB;IACF;AAEA;;;;;AAKG;AACO,IAAA,WAAW,CAAC,kBAA4B,EAAA;QAChD,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;AAEnC,QAAA,IAAI,CAAC,OAAO,GAAG,KAAK;QACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM;QAElC,IAAI,CAAC,kBAAkB,EAAE;AACvB,YAAA,IAAI,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE;QAChC;IACF;AAEA;;;AAGG;IACO,aAAa,GAAA;QACrB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE;AAClB,QAAA,IAAI,CAAC,OAAO,GAAG,KAAK;QACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM;QAClC,IAAI,CAAC,WAAW,EAAE;IACpB;AAEA;;;;;AAKG;IACO,eAAe,GAAA;AACvB,QAAA,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE;AACxB,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI;AAEtB,QAAA,IAAI,CAAC,cAAc,EAAE,UAAU,EAAE;AACjC,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI;;AAG1B,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,IAAI,CAAC,eAAe,EAAE,EAAE,gCAAgC,GAAG,IAAI,CAAC,MAAM,CAAC;QACzE;AAEA,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE;YAC3B,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC;QACjD;AACA,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,QAAA,IAAI,CAAC,OAAO,GAAG,KAAK;;AAGpB,QAAA,IAAI,IAAI,CAAC,eAAe,EAAE;AACxB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;YAC5B,IAAI,IAAI,EAAE;AACR,gBAAA,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,CAAC;YAC1C;QACF;IACF;AAEA;;;;AAIG;IACgB,WAAW,GAAA;AAC5B,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IACxB;;;;AAMA;;;;;;;AAOG;AACH,IAAA,eAAe,CAAC,KAAoB,EAAA;AAClC,QAAA,QAAQ,KAAK,CAAC,GAAG;AACf,YAAA,KAAK,OAAO;AACZ,YAAA,KAAK,GAAG;AACR,YAAA,KAAK,WAAW;AAChB,YAAA,KAAK,IAAI;gBACP,KAAK,CAAC,cAAc,EAAE;gBACtB,IAAI,CAAC,WAAW,EAAE;gBAClB,IAAI,CAAC,eAAe,EAAE;gBACtB;AACF,YAAA,KAAK,QAAQ;AACX,gBAAA,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;gBACxB;;IAEN;AAEA;;;;;AAKG;IACH,aAAa,GAAA;AACX,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,IAAI,CAAC,WAAW,EAAE;QACpB;aAAO;YACL,IAAI,CAAC,WAAW,EAAE;YAClB,IAAI,CAAC,eAAe,EAAE;QACxB;IACF;AAEA;;;;;AAKG;AACO,IAAA,YAAY,CAAC,KAAY,EAAA;AACjC,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,KAAK,CAAC,eAAe,EAAE;YACvB,IAAI,CAAC,WAAW,EAAE;QACpB;aAAO;YACL,IAAI,CAAC,UAAU,EAAE;QACnB;IACF;AAEA;;;;;;;AAOG;IACO,gBAAgB,CAAC,QAAQ,GAAG,KAAK,EAAA;AACzC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC5B,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,IAAI,CAAC,aAAa,CAChB,IAAI,aAAa,CAAC,SAAS,EAAE;AAC3B,YAAA,GAAG,EAAE,KAAK;AACV,YAAA,QAAQ,EAAE,QAAQ;AAClB,YAAA,OAAO,EAAE,IAAI;AACb,YAAA,UAAU,EAAE,IAAI;AACjB,SAAA,CAAC,CACH;IACH;AAsBA;;;;;AAKG;IACO,eAAe,GAAA;;IAEzB;;;;;IAOQ,QAAQ,GAAA;AACd,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,IAAI;IACxE;;IAGQ,eAAe,GAAA;AAMrB,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,2BAA2B,CAAC,IAAI,IAAI;IACpF;AAEA;;;AAGG;IACK,eAAe,GAAA;AACrB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC5B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM;AACzB,QAAA,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK;YAAE;AAErB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,qBAAqB,EAAE;;AAG7C,QAAA,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,QAAQ;AACjC,QAAA,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE;AACxB,QAAA,MAAM,SAAS,GAAG,KAAK,CAAC,qBAAqB,EAAE;AAC/C,QAAA,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE;AAE3B,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW;AACpC,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU;AAEnC,QAAA,IAAI,GAAW;AACf,QAAA,IAAI,IAAY;AAEhB,QAAA,QAAQ,IAAI,CAAC,eAAe;YAC1B,KAAK,OAAO,EAAE;gBACZ,GAAG,GAAG,QAAQ,CAAC,GAAG,GAAG,SAAS,CAAC,MAAM;AACrC,gBAAA,IAAI,GAAG,QAAQ,CAAC,IAAI;;gBAEpB,IAAI,GAAG,GAAG,CAAC;AAAE,oBAAA,GAAG,GAAG,QAAQ,CAAC,MAAM;gBAClC;YACF;YACA,KAAK,aAAa,EAAE;AAClB,gBAAA,GAAG,GAAG,QAAQ,CAAC,MAAM;gBACrB,IAAI,GAAG,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK;;AAEvC,gBAAA,IAAI,GAAG,GAAG,SAAS,CAAC,MAAM,GAAG,SAAS;oBAAE,GAAG,GAAG,QAAQ,CAAC,GAAG,GAAG,SAAS,CAAC,MAAM;gBAC7E;YACF;YACA,KAAK,eAAe,EAAE;AACpB,gBAAA,GAAG,GAAG,QAAQ,CAAC,GAAG;AAClB,gBAAA,IAAI,GAAG,QAAQ,CAAC,IAAI;gBACpB;YACF;YACA,KAAK,kBAAkB,EAAE;gBACvB,GAAG,GAAG,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM;AACxC,gBAAA,IAAI,GAAG,QAAQ,CAAC,IAAI;gBACpB;YACF;AACA,YAAA,KAAK,OAAO;YACZ,SAAS;AACP,gBAAA,GAAG,GAAG,QAAQ,CAAC,MAAM;AACrB,gBAAA,IAAI,GAAG,QAAQ,CAAC,IAAI;;AAEpB,gBAAA,IAAI,GAAG,GAAG,SAAS,CAAC,MAAM,GAAG,SAAS;oBAAE,GAAG,GAAG,QAAQ,CAAC,GAAG,GAAG,SAAS,CAAC,MAAM;gBAC7E;YACF;;;AAIF,QAAA,IAAI,IAAI,GAAG,SAAS,CAAC,KAAK,GAAG,SAAS;YAAE,IAAI,GAAG,SAAS,GAAG,SAAS,CAAC,KAAK,GAAG,CAAC;QAC9E,IAAI,IAAI,GAAG,CAAC;YAAE,IAAI,GAAG,CAAC;QACtB,IAAI,GAAG,GAAG,CAAC;YAAE,GAAG,GAAG,CAAC;QAEpB,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAA,EAAG,GAAG,IAAI;QAC5B,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,CAAA,EAAG,IAAI,IAAI;IAChC;AAEA;;;;AAIG;AACK,IAAA,sBAAsB,CAAC,KAAmB,EAAA;QAChD,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE;AAEnC,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAc;AACnC,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa;;AAG7C,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE;QAE7D,IAAI,CAAC,qBAAqB,EAAE;IAC9B;AAEA;;;;;;;;AAQG;IACK,aAAa,GAAA;QACnB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE;QACnC,IAAI,CAAC,qBAAqB,EAAE;IAC9B;AAEA;;;;;;;;;;AAUG;IACO,mBAAmB,GAAA;AAC3B,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC5B,QAAA,IAAI,CAAC,IAAI;YAAE;QAEX,IAAI,UAAU,GAAG,KAAK;QAEtB,IAAI,cAAc,GAAG,CAAC;AAEtB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa;QAE7C,IAAI,CAAC,cAAc,GAAG,IAAI,gBAAgB,CAAC,CAAC,SAAS,KAAI;;;;;YAKvD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AAC1B,gBAAA,IAAI,CAAC,cAAc,EAAE,UAAU,EAAE;AACjC,gBAAA,IAAI,CAAC,cAAc,GAAG,IAAI;gBAC1B;YACF;AAEA,YAAA,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;gBAChC,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY,IAAI,QAAQ,CAAC,aAAa,KAAK,OAAO;oBAAE;gBAE1E,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC;AACvD,gBAAA,IAAI,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;;oBAE9B,IAAI,cAAc,EAAE;wBAClB,oBAAoB,CAAC,cAAc,CAAC;wBACpC,cAAc,GAAG,CAAC;oBACpB;oBACA,UAAU,GAAG,IAAI;oBACjB,IAAI,CAAC,WAAW,EAAE;oBAClB,IAAI,CAAC,eAAe,EAAE;;;;oBAItB,UAAU,CAAC,MAAK;wBACd,UAAU,GAAG,KAAK;oBACpB,CAAC,EAAE,CAAC,CAAC;gBACP;qBAAO,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,EAAE;;;;;;AAMpD,oBAAA,IAAI,cAAc;wBAAE,oBAAoB,CAAC,cAAc,CAAC;AACxD,oBAAA,cAAc,GAAG,qBAAqB,CAAC,MAAK;wBAC1C,cAAc,GAAG,CAAC;;AAElB,wBAAA,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE;AAC1D,4BAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;wBACxB;AACF,oBAAA,CAAC,CAAC;gBACJ;YACF;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACrF;uGApfoB,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAjB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBADtC;;;ACxMD;;;;;;;;;;;;;;;;;;;AAmBG;AAoCH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,CACtB,CAAe,OAAoB,EAAE,OAAoB,KAAgD;;;;;;;;;;AAUvG,IAAA,MAAM,QAAQ,IAAI,2BAA2B,CAAC,OAAO,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAEvE;IAEb,IAAI,CAAC,QAAQ,EAAE;;;;AAIb,QAAA,OAAO,SAAS;IAClB;;IAGA,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAuB;IAEtF,OAAO,CAAC,GAAsC,KAAI;AAChD,QAAA,MAAM,QAAQ,GAAG,CAAC,KAAa,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;QACrD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE;;;;;;AAOnC,QAAA,IAAI,OAAmD;QACvD,IAAI,WAAW,EAAE;YACf,MAAM,WAAW,GAAG,mBAAmB,CAAC,WAAW,CAAC,IAAI,kBAAkB,CAAC,WAAW,CAAC;AACvF,YAAA,IAAI,WAAW,EAAE,aAAa,EAAE;AAC9B,gBAAA,MAAM,QAAQ,GAAI,WAAiC,CAAC,IAAI;gBACxD,IAAI,QAAQ,EAAE;oBACZ,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;AAC1C,oBAAA,IAAI,QAAQ,IAAI,CAAC,EAAE;wBACjB,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAe,CAAC;oBACjE;gBACF;YACF;QACF;AAEA,QAAA,MAAM,OAAO,GAAoC;YAC/C,SAAS,EAAE,GAAG,CAAC,KAAK;YACpB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,KAAK,EAAE,GAAG,CAAC,KAAe;YAC1B,MAAM,EAAE,GAAG,CAAC,MAAM;AAClB,YAAA,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE;YACtB,QAAQ;YACR,QAAQ;YACR,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,aAAa,EAAE,GAAG,CAAC,aAAa;YAChC,OAAO;SACR;;;;AAKD,QAAA,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC;;;;QAKlF,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAQ,KAAI;AAChD,YAAA,GAAG,CAAC,MAAM,CAAE,CAAyB,CAAC,MAAM,CAAC;AAC/C,QAAA,CAAC,CAAC;AACF,QAAA,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAK;YACxC,GAAG,CAAC,MAAM,EAAE;AACd,QAAA,CAAC,CAAC;;;;AAKF,QAAA,GAAG,CAAC,aAAa,GAAG,CAAC,MAAe,KAAI;AACtC,YAAA,OAAO,CAAC,SAAS,GAAG,MAAgB;AACpC,YAAA,OAAO,CAAC,KAAK,GAAG,MAAgB;YAChC,OAAO,CAAC,aAAa,EAAE;AACvB,YAAA,OAAO,CAAC,sBAAsB,CAAC,OAAO,EAAE,SAAS,CAAC;AACpD,QAAA,CAAC,CAAC;AAEF,QAAA,OAAO,SAAS;AAClB,IAAA,CAAC;AACH,CAAC,CACF;AAED;AACA;AACA;AACA;AACA;AACA,uBAAuB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,KAAI;AAChD,IAAA,MAAM,KAAK,GAAG,qBAAqB,CAAC,SAAS,CAAC;AAC9C,IAAA,MAAM,CAAC,gBAAgB,CAAC,mBAAmB,EAAE,KAAK,CAAC;IACnD,OAAO,MAAM,MAAM,CAAC,mBAAmB,CAAC,mBAAmB,EAAE,KAAK,CAAC;AACrE,CAAC,CAAC;;ACnKF;;AAEG;;;;"}
|