UNPKG

ng-fusion-ui

Version:

Angular data table library!

3,235 lines 338 kB
import * as i0 from '@angular/core';
import { input, booleanAttribute, inject, ElementRef, Renderer2, Directive, NgModule, Injectable, Component, ChangeDetectionStrategy, ViewEncapsulation, HostBinding, signal, computed, effect, Pipe, model, contentChild, TemplateRef, DestroyRef, Injector, output, EventEmitter, untracked, Output, HostListener, linkedSignal, viewChild, afterRenderEffect } from '@angular/core';
import * as i1$1 from '@angular/common';
import { CommonModule, NgTemplateOutlet, DatePipe } from '@angular/common';
import * as i1 from '@angular/platform-browser';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import * as i3 from '@angular/cdk/drag-drop';
import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
import { CdkContextMenuTrigger, CdkMenu } from '@angular/cdk/menu';
import * as i2 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { Overlay } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';

class ButtonDirective {
    constructor() {
        this.variant = input('filled');
        this.severity = input('primary');
        this.iconButton = input(false, {
            transform: booleanAttribute,
        });
        this.rounded = input(false, {
            transform: booleanAttribute,
        });
        this.compact = input(false, {
            transform: booleanAttribute,
        });
        this.raised = input(false, {
            transform: booleanAttribute,
        });
        this.el = inject(ElementRef);
        this.renderer = inject(Renderer2);
    }
    ngOnInit() {
        this.setInitialStyles();
    }
    setInitialStyles() {
        this.renderer.addClass(this.el.nativeElement, 'fu-btn');
        this.renderer.addClass(this.el.nativeElement, `fu-btn-${this.variant()}`);
        this.renderer.addClass(this.el.nativeElement, `fu-btn-${this.severity()}`);
        if (this.iconButton()) {
            this.renderer.setAttribute(this.el.nativeElement, 'icon', 'true');
        }
        if (this.rounded()) {
            this.renderer.setAttribute(this.el.nativeElement, 'rounded', 'true');
        }
        if (this.compact()) {
            this.renderer.setAttribute(this.el.nativeElement, 'compact', 'true');
        }
        if (this.raised()) {
            this.renderer.setAttribute(this.el.nativeElement, 'raised', 'true');
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: ButtonDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: ButtonDirective, isStandalone: true, selector: "[fuButton]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null }, iconButton: { classPropertyName: "iconButton", publicName: "iconButton", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, raised: { classPropertyName: "raised", publicName: "raised", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: ButtonDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuButton]',
                }]
        }] });

class ButtonModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: ButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.6", ngImport: i0, type: ButtonModule, imports: [ButtonDirective, CommonModule], exports: [ButtonDirective] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: ButtonModule, imports: [CommonModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: ButtonModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [ButtonDirective, CommonModule],
                    exports: [ButtonDirective],
                }]
        }] });

const edit = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M4 20h4L18.5 9.5a2.828 2.828 0 1 0-4-4L4 16zm9.5-13.5l4 4"/></svg>`;
const editOff = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="m10 10l-6 6v4h4l6-6m1.99-1.99l2.504-2.504a2.828 2.828 0 1 0-4-4l-2.5 2.5M13.5 6.5l4 4M3 3l18 18"/></svg>`;
const editSave = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M4 20h4L18.5 9.5a2.828 2.828 0 1 0-4-4L4 16zm9.5-13.5l4 4M15 19l2 2l4-4"/></svg>`;
const trash = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M4 7h16m-10 4v6m4-6v6M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2l1-12M9 7V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3"/></svg>`;
const doubleArrowRight = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="m7 7l5 5l-5 5m6-10l5 5l-5 5"/></svg>`;
const doubleArrowLeft = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="m11 7l-5 5l5 5m6-10l-5 5l5 5"/></svg>`;
const arrowLeft = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="m15 6l-6 6l6 6"/></svg>`;
const arrowRight = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="m9 6l6 6l-6 6"/></svg>`;
const sort = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="m3 9l4-4l4 4M7 5v14m14-4l-4 4l-4-4m4 4V5"/></svg>`;
const sortAsc = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M4 6h7m-7 6h7m-7 6h9m2-9l3-3l3 3m-3-3v12"/></svg>`;
const sortDesc = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M4 6h9m-9 6h7m-7 6h7m4-3l3 3l3-3m-3-9v12"/></svg>`;
const filterRemove = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M13.758 19.414L9 21v-8.5L4.52 7.572A2 2 0 0 1 4 6.227V4h16v2.172a2 2 0 0 1-.586 1.414L15 12v1.5m7 8.5l-5-5m0 5l5-5"/></svg>`;
const filterPlus = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="m12 20l-3 1v-8.5L4.52 7.572A2 2 0 0 1 4 6.227V4h16v2.172a2 2 0 0 1-.586 1.414L15 12v3m1 4h6m-3-3v6"/></svg>`;
const filterEdit = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M10.97 20.344L9 21v-8.5L4.52 7.572A2 2 0 0 1 4 6.227V4h16v2.172a2 2 0 0 1-.586 1.414L15 12v1.5m3.42 2.11a2.1 2.1 0 0 1 2.97 2.97L18 22h-3v-3z"/></svg>`;
const check = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="m5 12l5 5L20 7"/></svg>`;
const save = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M21 7v12q0 .825-.587 1.413T19 21H5q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h12zm-2 .85L16.15 5H5v14h14zM12 18q1.25 0 2.125-.875T15 15t-.875-2.125T12 12t-2.125.875T9 15t.875 2.125T12 18m-6-8h9V6H6zM5 7.85V19V5z"/></svg>`;
const search = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5A6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5S14 7.01 14 9.5S11.99 14 9.5 14" /></svg>`;
const building = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g fill="currentColor"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M4 2.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zM4 5.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zM7.5 5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm2.5.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zM4.5 8a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm2.5.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5z"/><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M2 1a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1zm11 0H3v14h3v-2.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5V15h3z"/></g></svg>`;
const buildingHand = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g fill="currentColor"><path d="m2 1c0-0.55228 0.44772-1 1-1h10c0.55228 0 1 0.44772 1 1v6.5c0 0.66667-1 0.66667-1 0v-6.5h-10v14h3s2.2783-0.07879 2 1h-5c-0.55228 0-1-0.44772-1-1z"/><path d="M4.5 2a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm3 0a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm3 0a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm-6 3a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm3 0a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm3 0a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm-6 3a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm3 0a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5z"/><path d="m4.0496 13.493v0.43773l4.5597 1.0943 3.9897-0.83169v0.61283h3.4198v-4.8151h-4.5597l-3.5338 1.0068c-0.56996 0.17509-1.0259 0.6566-1.0259 1.1819h-1.1399c-0.96894 0-1.7099 0.56905-1.7099 1.3132m9.6894 0.43773v-3.0641h1.1399v3.0641zm-8.4925-0.61282q0.17099-0.26264 0.51297-0.26264h3.0778c0.28498 0 0.62696-0.04377 0.91194-0.08756l1.3109-0.35018-0.34198-0.83169-1.3679 0.35018c-0.17099 0-1.3109 0.04377-1.3109 0.04377 0-0.17509 0.11399-0.30641 0.34198-0.35018l3.3058-0.963h0.91194v2.4075l-3.9897 0.83169z" fill="currentColor" stroke-width=".49949"/></g></svg>`;
const buildingUser = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" ><path d="m-12.888 20.361a4.25 4.25 0 0 0-2.1938 0.56919 4.25 4.25 0 0 0-2.1226 3.5432l-0.0024 0.13755 0.0024 0.13755a4.25 4.25 0 1 0 4.3164-4.3875zm0.60951 2.7036h0.62611v2.6657l-2.3076 0.5929-2.6396-0.88936c0-0.1482 0.06709-0.29647 0.16601-0.41503 0.13191-0.11856 0.29543-0.17787 0.4933-0.17787h2.31l0.69252-0.23716-0.09961-0.26562-0.59291 0.20633h-0.92493c-0.09894 0-0.23051-0.05931-0.29646-0.11859-0.06595-0.05928-0.09724-0.14824-0.09724-0.23716 0-0.1482 0.09835-0.26563 0.26325-0.32491zm1.2854 0h1.3186v3.2586h-1.3186z" stroke-width=".425"/><g fill="currentColor"></g><path d="m2.0619 18.318a4.9999 4.9999 0 0 0-2.5808 0.66962 4.9999 4.9999 0 0 0-2.4971 4.1684l-0.0028 0.16182 0.0028 0.16183a4.9999 4.9999 0 1 0 5.078-5.1617zm0.71705 3.1807h0.73658v3.1361l-2.7148 0.69752-3.1054-1.0463c0-0.17435 0.07893-0.34878 0.19531-0.48826 0.15518-0.13948 0.34756-0.20926 0.58034-0.20926h2.7175l0.81471-0.27901-0.11719-0.31249-0.69753 0.24274h-1.0881c-0.1164 0-0.27118-0.06977-0.34876-0.13951-0.07759-0.06974-0.1144-0.1744-0.1144-0.27901 0-0.17435 0.1157-0.3125 0.3097-0.38224zm1.5122 0h1.5513v3.8336h-1.5513z" stroke-width=".49999"/><g transform="matrix(.86364 0 0 .86364 26.355 .79387)"><path d="m16 10.5c0-3.025-2.475-5.5-5.5-5.5-3.025 0-5.5 2.475-5.5 5.5 0 3.025 2.475 5.5 5.5 5.5 3.025 0 5.5-2.475 5.5-5.5m-3.85-3.025 1.925 1.925-1.925 1.925v-1.375h-2.2v-1.1h2.2zm-3.3 6.05-1.925-1.925 1.925-1.925v1.375h2.2v1.1h-2.2z" fill="currentColor" stroke-width=".55"/></g><path d="m38.863 0.91746c0 1.4444-0.6447 2.7386-1.6625 3.61a4.7327 4.7327 0 0 1-3.0875 1.14c-1.1789 0-2.2571-0.42923-3.0875-1.14a4.7414 4.7414 0 0 1-1.6625-3.61c0-2.6233 2.1267-4.75 4.75-4.75s4.75 2.1267 4.75 4.75m-3.0227-1.5114a1.7273 1.7273 0 1 0-3.4545 0 1.7273 1.7273 0 0 0 3.4545 0m1.0795 4.1994v-0.09716a1.7273 1.7273 0 0 0-1.7273-1.7273h-2.1591a1.7273 1.7273 0 0 0-1.7273 1.7273v0.09716q0.13386 0.13948 0.28068 0.26557a3.8691 3.8691 0 0 0 2.5261 0.93273 3.8691 3.8691 0 0 0 2.8068-1.1983" fill="currentColor" stroke-width=".43182"/><g fill="currentColor"><g fill="currentColor"><path d="m3 0a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h5v-0.62695a5.25 5.25 0 0 1-1.9102-3.1582 0.5 0.5 0 0 0-0.089844 0.28516v2.5h-3v-14h10v5.3008a5.25 5.25 0 0 1 1 0.47852v-5.7793a1 1 0 0 0-1-1z"/><path d="m4.5 2a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h0.66797a5.25 5.25 0 0 1 0.83203-0.49219 0.5 0.5 0 0 0 0-0.0078125v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v0.65234a5.25 5.25 0 0 1 1.248-0.15234 5.25 5.25 0 0 1 0.75195 0.054688v-0.55469a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5z"/></g><path d="m11.25 7.3636a3.8864 3.8864 0 0 0-3.8864 3.8864 3.8691 3.8691 0 0 0 0.76561 2.3167 2.1591 2.1591 0 0 1 2.0412-1.4531h2.1591a2.1591 2.1591 0 0 1 2.0412 1.4531 3.8691 3.8691 0 0 0 0.76561-2.3167 3.8864 3.8864 0 0 0-3.8864-3.8864m2.375 6.9631v-0.05398a1.2955 1.2955 0 0 0-1.2955-1.2955h-2.1591a1.2955 1.2955 0 0 0-1.2955 1.2955v0.05398a3.8691 3.8691 0 0 0 2.375 0.80966c0.89473 0 1.7182-0.30227 2.375-0.80966m-7.125-3.0767c0-2.6233 2.1267-4.75 4.75-4.75 2.6233 0 4.75 2.1267 4.75 4.75a4.7414 4.7414 0 0 1-1.6625 3.61 4.7327 4.7327 0 0 1-3.0875 1.14 4.7327 4.7327 0 0 1-3.0875-1.14 4.7414 4.7414 0 0 1-1.6625-3.61m4.75-2.5909a1.0795 1.0795 0 1 0 0 2.1591 1.0795 1.0795 0 0 0 0-2.1591m-1.9432 1.0795a1.9432 1.9432 0 1 1 3.8864 0 1.9432 1.9432 0 0 1-3.8864 0" stroke-width=".43182"/></g></svg>`;
const buildingSwap = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" ><path d="m-12.888 20.361a4.25 4.25 0 0 0-2.1938 0.56919 4.25 4.25 0 0 0-2.1226 3.5432l-0.0024 0.13755 0.0024 0.13755a4.25 4.25 0 1 0 4.3164-4.3875zm0.60951 2.7036h0.62611v2.6657l-2.3076 0.5929-2.6396-0.88936c0-0.1482 0.06709-0.29647 0.16601-0.41503 0.13191-0.11856 0.29543-0.17787 0.4933-0.17787h2.31l0.69252-0.23716-0.09961-0.26562-0.59291 0.20633h-0.92493c-0.09894 0-0.23051-0.05931-0.29646-0.11859-0.06595-0.05928-0.09724-0.14824-0.09724-0.23716 0-0.1482 0.09835-0.26563 0.26325-0.32491zm1.2854 0h1.3186v3.2586h-1.3186z" stroke-width=".425"/><g fill="currentColor"></g><path d="m2.0619 18.318a4.9999 4.9999 0 0 0-2.5808 0.66962 4.9999 4.9999 0 0 0-2.4971 4.1684l-0.0028 0.16182 0.0028 0.16183a4.9999 4.9999 0 1 0 5.078-5.1617zm0.71705 3.1807h0.73658v3.1361l-2.7148 0.69752-3.1054-1.0463c0-0.17435 0.07893-0.34878 0.19531-0.48826 0.15518-0.13948 0.34756-0.20926 0.58034-0.20926h2.7175l0.81471-0.27901-0.11719-0.31249-0.69753 0.24274h-1.0881c-0.1164 0-0.27118-0.06977-0.34876-0.13951-0.07759-0.06974-0.1144-0.1744-0.1144-0.27901 0-0.17435 0.1157-0.3125 0.3097-0.38224zm1.5122 0h1.5513v3.8336h-1.5513z" stroke-width=".49999"/><g fill="currentColor"><g fill="currentColor"><path d="m3 0a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h5v-0.62695a5.25 5.25 0 0 1-1.9102-3.1582 0.5 0.5 0 0 0-0.089844 0.28516v2.5h-3v-14h10v5.3008a5.25 5.25 0 0 1 1 0.47852v-5.7793a1 1 0 0 0-1-1z"/><path d="m4.5 2a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h0.66797a5.25 5.25 0 0 1 0.83203-0.49219 0.5 0.5 0 0 0 0-0.0078125v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v0.65234a5.25 5.25 0 0 1 1.248-0.15234 5.25 5.25 0 0 1 0.75195 0.054688v-0.55469a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5z"/></g></g><path d="m11.25 6.5c-2.6125 0-4.75 2.1375-4.75 4.75 0 2.6125 2.1375 4.75 4.75 4.75s4.75-2.1375 4.75-4.75c0-2.6125-2.1375-4.75-4.75-4.75m0 8.55c-2.0948 0-3.8-1.7052-3.8-3.8 0-2.0948 1.7052-3.8 3.8-3.8 2.0948 0 3.8 1.7053 3.8 3.8 0 2.0948-1.7052 3.8-3.8 3.8m1.425-6.4125v1.1875h-1.9v0.95h1.9v1.1875l1.6625-1.6625zm-2.85 1.9-1.6625 1.6625 1.6625 1.6625v-1.1875h1.9v-0.95h-1.9z" fill="currentColor" stroke-width=".475"/></svg>`;
const buildingBuild = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" ><path d="m-12.888 20.361a4.25 4.25 0 0 0-2.1938 0.56919 4.25 4.25 0 0 0-2.1226 3.5432l-0.0024 0.13755 0.0024 0.13755a4.25 4.25 0 1 0 4.3164-4.3875zm0.60951 2.7036h0.62611v2.6657l-2.3076 0.5929-2.6396-0.88936c0-0.1482 0.06709-0.29647 0.16601-0.41503 0.13191-0.11856 0.29543-0.17787 0.4933-0.17787h2.31l0.69252-0.23716-0.09961-0.26562-0.59291 0.20633h-0.92493c-0.09894 0-0.23051-0.05931-0.29646-0.11859-0.06595-0.05928-0.09724-0.14824-0.09724-0.23716 0-0.1482 0.09835-0.26563 0.26325-0.32491zm1.2854 0h1.3186v3.2586h-1.3186z" stroke-width=".425"/><g fill="currentColor"></g><g fill="currentColor"><g fill="currentColor"><path d="m3 0a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h5v-0.62695a5.25 5.25 0 0 1-1.9102-3.1582 0.5 0.5 0 0 0-0.089844 0.28516v2.5h-3v-14h10v5.3008a5.25 5.25 0 0 1 1 0.47852v-5.7793a1 1 0 0 0-1-1z"/><path d="m4.5 2a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h0.66797a5.25 5.25 0 0 1 0.83203-0.49219 0.5 0.5 0 0 0 0-0.0078125v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v0.65234a5.25 5.25 0 0 1 1.248-0.15234 5.25 5.25 0 0 1 0.75195 0.054688v-0.55469a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5z"/></g></g><path d="m11.25 6.5c2.619 0 4.75 2.131 4.75 4.75 0 2.619-2.131 4.75-4.75 4.75-2.619 0-4.75-2.131-4.75-4.75 0-2.619 2.131-4.75 4.75-4.75m0 0.95001c-2.1028 0-3.8 1.6972-3.8 3.8 0 2.1028 1.6972 3.8 3.8 3.8 2.1028 0 3.8-1.6972 3.8-3.8 0-2.1028-1.6972-3.8-3.8-3.8m0.0204 1.6205c0.3593 0.4672 0.48051 1.0419 0.36538 1.4615q-0.0215 0.10358 1.5192 1.6153 0.5038 0.5038 0 1.0076-0.47417 0.47414-0.94836 0.0558l-1.667-1.5825c-0.41962 0.11514-0.99434-6e-3 -1.4615-0.36537-0.34267-0.45055-0.46084-1.0395-0.36538-1.4615l0.73075 0.73076 0.73076-0.36538 0.36538-0.73076-0.73076-0.73078c0.42209-0.0954 1.011 0.0227 1.4615 0.36538" fill="currentColor" fill-rule="evenodd" stroke-width=".022266"/></svg>`;
const buildingGear = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" ><path d="m-14.269 23.484a4.75 4.75 0 0 0-2.4518 0.63615 4.75 4.75 0 0 0-2.3723 3.96l-0.0027 0.15374 0.0027 0.15374a4.75 4.75 0 1 0 4.8242-4.9037zm0.68121 3.0217h0.69976v2.9793l-2.5791 0.66266-2.9502-0.99399c0-0.16564 0.07498-0.33135 0.18554-0.46386 0.14743-0.13251 0.33018-0.1988 0.55133-0.1988h2.5817l0.77399-0.26506-0.11133-0.29687-0.66266 0.23061h-1.0337c-0.11058 0-0.25762-0.06629-0.33133-0.13254-0.07371-0.06625-0.10868-0.16568-0.10868-0.26506 0-0.16564 0.10992-0.29688 0.29422-0.36314zm1.4366 0h1.4738v3.642h-1.4738z" stroke-width=".475"/><g fill="currentColor"></g><g transform="translate(.11566 1.0024)"><g transform="translate(-.11566 -1.0024)"><g fill="currentColor"><g fill="currentColor"><path d="m3 0a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h5v-0.62695a5.25 5.25 0 0 1-1.9102-3.1582 0.5 0.5 0 0 0-0.089844 0.28516v2.5h-3v-14h10v5.3008a5.25 5.25 0 0 1 1 0.47852v-5.7793a1 1 0 0 0-1-1z"/><path d="m4.5 2a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h0.66797a5.25 5.25 0 0 1 0.83203-0.49219 0.5 0.5 0 0 0 0-0.0078125v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v0.65234a5.25 5.25 0 0 1 1.248-0.15234 5.25 5.25 0 0 1 0.75195 0.054688v-0.55469a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5z"/></g></g></g><path d="m14.281 9.329 1.1442 0.18703a0.19356 0.19356 0 0 1 0.16209 0.19119v1.0646a0.19356 0.19356 0 0 1-0.16031 0.19059l-1.1459 0.20128q-0.09915 0.34556-0.27253 0.65966l0.67747 0.9405a0.19356 0.19356 0 0 1-0.02018 0.25056l-0.75288 0.75288a0.19356 0.19356 0 0 1-0.24819 0.02198l-0.95-0.66678a3.2656 3.2656 0 0 1-0.66381 0.27788l-0.20188 1.1406a0.19356 0.19356 0 0 1-0.19119 0.15972h-1.064a0.19297 0.19297 0 0 1-0.19059-0.1615l-0.18941-1.1347a3.2656 3.2656 0 0 1-0.66678-0.27609l-0.94287 0.66084a0.19356 0.19356 0 0 1-0.24819-0.021975l-0.75347-0.75288a0.19594 0.19594 0 0 1-0.020776-0.24938l0.66678-0.93219a3.2656 3.2656 0 0 1-0.27907-0.67034l-1.1287-0.20009a0.19356 0.19356 0 0 1-0.15972-0.19059v-1.0646c0-0.09499 0.06828-0.17575 0.16209-0.19119l1.1287-0.18822q0.10272-0.35031 0.27906-0.66975l-0.65906-0.94169a0.19356 0.19356 0 0 1 0.021975-0.24759l0.75347-0.75228a0.19356 0.19356 0 0 1 0.24938-0.020776l0.93516 0.66797q0.31647-0.17338 0.66559-0.27313l0.18525-1.1341a0.19356 0.19356 0 0 1 0.19119-0.16209h1.0646c0.0944 0 0.17456 0.067688 0.19119 0.16031l0.1995 1.14q0.34734 0.10034 0.665 0.27609l0.93694-0.67391a0.19356 0.19356 0 0 1 0.25056 0.019591l0.75287 0.75288a0.19356 0.19356 0 0 1 0.02137 0.24819l-0.66797 0.95178q0.17219 0.31469 0.27312 0.65906zm-4.503 0.91853a1.3555 1.3555 0 1 0 2.7111 0 1.3555 1.3555 0 0 0-2.7111 0z" clip-rule="evenodd" fill="none" stroke="currentColor" stroke-width=".59375"/></g></svg>`;
const buildingGearBuild = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" ><path d="m-14.269 23.484a4.75 4.75 0 0 0-2.4518 0.63615 4.75 4.75 0 0 0-2.3723 3.96l-0.0027 0.15374 0.0027 0.15374a4.75 4.75 0 1 0 4.8242-4.9037zm0.68121 3.0217h0.69976v2.9793l-2.5791 0.66266-2.9502-0.99399c0-0.16564 0.07498-0.33135 0.18554-0.46386 0.14743-0.13251 0.33018-0.1988 0.55133-0.1988h2.5817l0.77399-0.26506-0.11133-0.29687-0.66266 0.23061h-1.0337c-0.11058 0-0.25762-0.06629-0.33133-0.13254-0.07371-0.06625-0.10868-0.16568-0.10868-0.26506 0-0.16564 0.10992-0.29688 0.29422-0.36314zm1.4366 0h1.4738v3.642h-1.4738z" stroke-width=".475"/><g fill="currentColor"></g><g transform="translate(.11566 1.0024)"><g transform="translate(-.11566 -1.0024)"><g fill="currentColor"><g fill="currentColor"><path d="m3 0a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h5v-0.62695a5.25 5.25 0 0 1-1.9102-3.1582 0.5 0.5 0 0 0-0.089844 0.28516v2.5h-3v-14h10v5.3008a5.25 5.25 0 0 1 1 0.47852v-5.7793a1 1 0 0 0-1-1z"/><path d="m4.5 2a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h0.66797a5.25 5.25 0 0 1 0.83203-0.49219 0.5 0.5 0 0 0 0-0.0078125v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v0.65234a5.25 5.25 0 0 1 1.248-0.15234 5.25 5.25 0 0 1 0.75195 0.054688v-0.55469a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5z"/></g></g></g><path d="m14.281 9.329 1.1442 0.18703c0.09357 0.015417 0.16219 0.096356 0.16209 0.19119v1.0646c-4.5e-5 0.09404-0.06767 0.17444-0.16031 0.19059l-1.1459 0.20128c-0.0661 0.23038-0.15694 0.45026-0.27253 0.65966l0.67747 0.9405c0.0558 0.07712 0.04724 0.18337-0.02018 0.25056l-0.75288 0.75288c-0.06639 0.06668-0.17111 0.07595-0.24819 0.02198l-0.95-0.66678c-0.21036 0.1168-0.43298 0.20999-0.66381 0.27788l-0.20188 1.1406c-0.01645 0.09263-0.09711 0.16001-0.19119 0.15972h-1.064c-0.09451 1.02e-4 -0.17518-0.06826-0.19059-0.1615l-0.18941-1.1347c-0.23178-0.067114-0.4554-0.15971-0.66678-0.27609l-0.94287 0.66084c-0.077074 0.05397-0.1818 0.0447-0.24819-0.02197l-0.75347-0.75288c-0.066017-0.0673-0.074746-0.17208-0.020776-0.24938l0.66678-0.93219c-0.11765-0.21238-0.21125-0.43722-0.27907-0.67034l-1.1287-0.20009c-0.092404-0.01641-0.15972-0.096743-0.15972-0.19059v-1.0646c0-0.09499 0.06828-0.17575 0.16209-0.19119l1.1287-0.18822c0.068482-0.23354 0.1615-0.45679 0.27906-0.66975l-0.65906-0.94169c-0.053635-0.076954-0.044375-0.18129 0.021975-0.24759l0.75347-0.75228c0.066872-0.06695 0.17235-0.075737 0.24938-0.020776l0.93516 0.66797c0.21098-0.11558 0.43284-0.20663 0.66559-0.27313l0.18525-1.1341c0.01542-0.093571 0.09635-0.16219 0.19119-0.16209h1.0646c0.0944 0 0.17456 0.067688 0.19119 0.16031l0.1995 1.14c0.23156 0.066893 0.45323 0.15892 0.665 0.27609l0.93694-0.67391c0.07698-0.055954 0.18322-0.047648 0.25056 0.019591l0.75287 0.75288c0.06648 0.066546 0.0755 0.17125 0.02137 0.24819l-0.66797 0.95178c0.11479 0.20979 0.20583 0.42948 0.27312 0.65906z" clip-rule="evenodd" fill="none" stroke="currentColor" stroke-width=".59375"/><path d="m10.231 8.372c0.62223 0 1.1267 0.50443 1.1267 1.1267 0 0.11382-0.01688 0.22369-0.04827 0.32727l1.1749 1.1749c0.20741 0.20741 0.20741 0.54369 0 0.7511-0.20741 0.20741-0.5437 0.20741-0.7511 0l-1.1749-1.1749c-0.10357 0.03139-0.21345 0.04827-0.32727 0.04827-0.62223 0-1.1267-0.50442-1.1267-1.1267 0-0.12008 0.01878-0.23577 0.05358-0.34429l0.53294 0.53206 0.52824-0.17593 0.02359-0.023589 0.17608-0.52775-0.53356-0.53309c0.10895-0.035102 0.22516-0.054062 0.34579-0.054062" fill="currentColor" fill-rule="evenodd" stroke-width=".008802"/></g></svg>`;
const buildingRemove = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="m-14.269 23.484a4.75 4.75 0 0 0-2.4518 0.63615 4.75 4.75 0 0 0-2.3723 3.96l-0.0027 0.15374 0.0027 0.15374a4.75 4.75 0 1 0 4.8242-4.9037zm0.68121 3.0217h0.69976v2.9793l-2.5791 0.66266-2.9502-0.99399c0-0.16564 0.07498-0.33135 0.18554-0.46386 0.14743-0.13251 0.33018-0.1988 0.55133-0.1988h2.5817l0.77399-0.26506-0.11133-0.29687-0.66266 0.23061h-1.0337c-0.11058 0-0.25762-0.06629-0.33133-0.13254-0.07371-0.06625-0.10868-0.16568-0.10868-0.26506 0-0.16564 0.10992-0.29688 0.29422-0.36314zm1.4366 0h1.4738v3.642h-1.4738z" stroke-width=".475"/><g fill="currentColor"></g><g transform="translate(.11566 1.0024)"><g transform="translate(-.11566 -1.0024)"><g fill="currentColor"><g fill="currentColor"><path d="m3 0a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h5v-0.62695a5.25 5.25 0 0 1-1.9102-3.1582 0.5 0.5 0 0 0-0.089844 0.28516v2.5h-3v-14h10v5.3008a5.25 5.25 0 0 1 1 0.47852v-5.7793a1 1 0 0 0-1-1z"/><path d="m4.5 2a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h0.66797a5.25 5.25 0 0 1 0.83203-0.49219 0.5 0.5 0 0 0 0-0.0078125v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v0.65234a5.25 5.25 0 0 1 1.248-0.15234 5.25 5.25 0 0 1 0.75195 0.054688v-0.55469a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5z"/></g></g></g><path d="m11.134 14.048c-2.0947 0-3.8-1.7052-3.8-3.8 0-2.0947 1.7052-3.8 3.8-3.8 2.0948 0 3.8 1.7052 3.8 3.8 0 2.0948-1.7052 3.8-3.8 3.8m0-8.55c-2.6267 0-4.75 2.1232-4.75 4.75 0 2.6268 2.1232 4.75 4.75 4.75 2.6268 0 4.75-2.1232 4.75-4.75 0-2.6267-2.1232-4.75-4.75-4.75m1.2302 2.85-1.2302 1.2302-1.2302-1.2302-0.66975 0.66975 1.2302 1.2302-1.2302 1.2302 0.66975 0.66975 1.2302-1.2302 1.2302 1.2302 0.66975-0.66975-1.2302-1.2302 1.2302-1.2302z" fill="currentColor" stroke-width=".475"/></g></svg>`;
const buildingAdd = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="m-14.269 23.484a4.75 4.75 0 0 0-2.4518 0.63615 4.75 4.75 0 0 0-2.3723 3.96l-0.0027 0.15374 0.0027 0.15374a4.75 4.75 0 1 0 4.8242-4.9037zm0.68121 3.0217h0.69976v2.9793l-2.5791 0.66266-2.9502-0.99399c0-0.16564 0.07498-0.33135 0.18554-0.46386 0.14743-0.13251 0.33018-0.1988 0.55133-0.1988h2.5817l0.77399-0.26506-0.11133-0.29687-0.66266 0.23061h-1.0337c-0.11058 0-0.25762-0.06629-0.33133-0.13254-0.07371-0.06625-0.10868-0.16568-0.10868-0.26506 0-0.16564 0.10992-0.29688 0.29422-0.36314zm1.4366 0h1.4738v3.642h-1.4738z" stroke-width=".475"/><g fill="currentColor"></g><g transform="translate(.11566 1.0024)"><g transform="translate(-.11566 -1.0024)"><g fill="currentColor"><g fill="currentColor"><path d="m3 0a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h5v-0.62695a5.25 5.25 0 0 1-1.9102-3.1582 0.5 0.5 0 0 0-0.089844 0.28516v2.5h-3v-14h10v5.3008a5.25 5.25 0 0 1 1 0.47852v-5.7793a1 1 0 0 0-1-1z"/><path d="m4.5 2a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h0.66797a5.25 5.25 0 0 1 0.83203-0.49219 0.5 0.5 0 0 0 0-0.0078125v-1a0.5 0.5 0 0 0-0.5-0.5zm3 0a0.5 0.5 0 0 0-0.5 0.5v0.65234a5.25 5.25 0 0 1 1.248-0.15234 5.25 5.25 0 0 1 0.75195 0.054688v-0.55469a0.5 0.5 0 0 0-0.5-0.5zm-6 3a0.5 0.5 0 0 0-0.5 0.5v1a0.5 0.5 0 0 0 0.5 0.5h1a0.5 0.5 0 0 0 0.5-0.5v-1a0.5 0.5 0 0 0-0.5-0.5z"/></g></g></g><path d="m11.134 6.4476c2.0952 0 3.8 1.7048 3.8 3.8 0 2.0952-1.7048 3.8-3.8 3.8-2.0952 0-3.8-1.7048-3.8-3.8 0-2.0952 1.7048-3.8 3.8-3.8m0-0.95c-2.6234 0-4.75 2.1266-4.75 4.75 0 2.6234 2.1266 4.75 4.75 4.75 2.6234 0 4.75-2.1266 4.75-4.75 0-2.6234-2.1266-4.75-4.75-4.75m2.375 4.275h-1.9v-1.9h-0.95v1.9h-1.9v0.95h1.9v1.9h0.95v-1.9h1.9z" fill="currentColor" stroke-width=".475"/></g></svg>`;
const exchange = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="m21 9l-4-4v3h-7v2h7v3M7 11l-4 4l4 4v-3h7v-2H7z"/></svg>`;
const exchangeCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M12.005 22.003c-5.523 0-10-4.477-10-10s4.477-10 10-10s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16m-5-7h9v2h-4v3zm5-4v-3l5 5h-9v-2z"/></svg>`;
const cancel = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M6.758 17.243L12.001 12m5.243-5.243L12 12m0 0L6.758 6.757M12.001 12l5.243 5.243"/></svg>`;
const cancelCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="m8.4 17l3.6-3.6l3.6 3.6l1.4-1.4l-3.6-3.6L17 8.4L15.6 7L12 10.6L8.4 7L7 8.4l3.6 3.6L7 15.6zm3.6 5q-2.075 0-3.9-.788t-3.175-2.137T2.788 15.9T2 12t.788-3.9t2.137-3.175T8.1 2.788T12 2t3.9.788t3.175 2.137T21.213 8.1T22 12t-.788 3.9t-2.137 3.175t-3.175 2.138T12 22m0-2q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8"/></svg>`;
const plus = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" style="stroke-width:var(--fu-icon-stroke-width, 2)" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M12 5v14m-7-7h14"/></svg>`;
const plusCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" style="stroke-width:var(--fu-icon-stroke-width, 2)" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"  d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0m6 0h6m-3-3v6"/></svg>`;
const eye = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" style="stroke-width:var(--fu-icon-stroke-width, 2)"><path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0-4 0" /><path d="M21 12q-3.6 6-9 6t-9-6q3.6-6 9-6t9 6" /></g></svg>`;
const chevronRight = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M12 8L5.68 1.68L4 3.35L8.65 8L4 12.65l1.68 1.67z"/></svg>`;
const link = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M17 7h-3c-.55 0-1 .45-1 1s.45 1 1 1h3c1.65 0 3 1.35 3 3s-1.35 3-3 3h-3c-.55 0-1 .45-1 1s.45 1 1 1h3c2.76 0 5-2.24 5-5s-2.24-5-5-5m-9 5c0 .55.45 1 1 1h6c.55 0 1-.45 1-1s-.45-1-1-1H9c-.55 0-1 .45-1 1m2 3H7c-1.65 0-3-1.35-3-3s1.35-3 3-3h3c.55 0 1-.45 1-1s-.45-1-1-1H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h3c.55 0 1-.45 1-1s-.45-1-1-1" /></svg>`;
const certificate = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="M128 136a8 8 0 0 1-8 8H72a8 8 0 0 1 0-16h48a8 8 0 0 1 8 8m-8-40H72a8 8 0 0 0 0 16h48a8 8 0 0 0 0-16m112 65.47V224a8 8 0 0 1-12 7l-24-13.74L172 231a8 8 0 0 1-12-7v-24H40a16 16 0 0 1-16-16V56a16 16 0 0 1 16-16h176a16 16 0 0 1 16 16v30.53a51.88 51.88 0 0 1 0 74.94M160 184v-22.53A52 52 0 0 1 216 76V56H40v128Zm56-12a51.88 51.88 0 0 1-40 0v38.22l16-9.16a8 8 0 0 1 7.94 0l16 9.16Zm16-48a36 36 0 1 0-36 36a36 36 0 0 0 36-36" /></svg>`;
const elevator = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 2)" d="m7 2l4 4H8v4H6V6H3zm10 8l-4-4h3V2h2v4h3zM7 12h10a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-6a2 2 0 0 1 2-2m0 2v6h10v-6z" /></svg>`;
const report = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 2)"><path stroke-linecap="round" stroke-linejoin="round" d="M10 9H6m9.5 2a2.5 2.5 0 1 1 0-5a2.5 2.5 0 0 1 0 5M6 6h3m9 12l-4.5-3l-2.5 2l-5-4" /><path d="M3 20.4V3.6a.6.6 0 0 1 .6-.6h16.8a.6.6 0 0 1 .6.6v16.8a.6.6 0 0 1-.6.6H3.6a.6.6 0 0 1-.6-.6Z" /></g></svg>`;
const templateEdit = `<svg xmlns="http://www.w3.org/2000/svg"  viewBox="0 0 24 24"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 2)" fill-rule="evenodd" d="M10.944 1.25h2.112c1.838 0 3.294 0 4.433.153c1.172.158 2.121.49 2.87 1.238a.75.75 0 0 1-1.06 1.06c-.424-.422-1.004-.676-2.01-.811c-1.027-.138-2.382-.14-4.289-.14h-2c-1.907 0-3.261.002-4.29.14c-1.005.135-1.585.389-2.008.812S4.025 4.705 3.89 5.71c-.138 1.029-.14 2.383-.14 4.29v4c0 1.907.002 3.262.14 4.29c.135 1.005.389 1.585.812 2.008s1.003.677 2.009.812c1.028.138 2.382.14 4.289.14h2c1.907 0 3.262-.002 4.29-.14c1.005-.135 1.585-.389 2.008-.812c.696-.696.907-1.777.943-4.309a.75.75 0 0 1 1.5.022c-.035 2.427-.192 4.158-1.382 5.348c-.749.748-1.698 1.08-2.87 1.238c-1.14.153-2.595.153-4.433.153h-2.112c-1.838 0-3.294 0-4.433-.153c-1.172-.158-2.121-.49-2.87-1.238c-.748-.749-1.08-1.698-1.238-2.87c-.153-1.14-.153-2.595-.153-4.433V9.944c0-1.838 0-3.294.153-4.433c.158-1.172.49-2.121 1.238-2.87c.749-.748 1.698-1.08 2.87-1.238c1.14-.153 2.595-.153 4.433-.153m7.17 5.796a2.716 2.716 0 1 1 3.84 3.84L17.2 15.643a7 7 0 0 1-.63.587q-.346.27-.744.46c-.224.107-.46.185-.806.3l-2.084.695a1.28 1.28 0 0 1-1.62-1.62l.681-2.04l.014-.043c.116-.347.194-.582.301-.806a4 4 0 0 1 .46-.744c.153-.196.328-.371.587-.63l.031-.031zm2.78 1.06a1.216 1.216 0 0 0-1.72 0l-.182.182l.034.107c.094.27.273.63.611.968a2.55 2.55 0 0 0 1.075.645l.182-.182a1.216 1.216 0 0 0 0-1.72m-1.328 3.048a4 4 0 0 1-.99-.73a4 4 0 0 1-.73-.99L14.45 12.83c-.301.301-.407.409-.496.523q-.17.218-.289.467c-.062.131-.111.274-.246.678l-.4 1.2l.283.283l1.2-.4c.404-.135.547-.184.678-.246q.248-.12.467-.289c.114-.089.222-.195.523-.496zM7.25 9A.75.75 0 0 1 8 8.25h6.5a.75.75 0 0 1 0 1.5H8A.75.75 0 0 1 7.25 9m0 4a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5H8a.75.75 0 0 1-.75-.75m0 4a.75.75 0 0 1 .75-.75h1.5a.75.75 0 0 1 0 1.5H8a.75.75 0 0 1-.75-.75" clip-rule="evenodd" /></svg>`;
const draftEdit = `<svg xmlns="http://www.w3.org/2000/svg"  viewBox="0 0 24 24"><g fill="none" stroke="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 1.5)" ><path d="m18.18 8.04l.463-.464a1.966 1.966 0 1 1 2.781 2.78l-.463.464M18.18 8.04s.058.984.927 1.853s1.854.927 1.854.927M18.18 8.04l-4.26 4.26c-.29.288-.434.433-.558.592q-.22.282-.374.606c-.087.182-.151.375-.28.762l-.413 1.24l-.134.401m8.8-5.081l-4.26 4.26c-.29.29-.434.434-.593.558q-.282.22-.606.374c-.182.087-.375.151-.762.28l-1.24.413l-.401.134m0 0l-.401.134a.53.53 0 0 1-.67-.67l.133-.402m.938.938l-.938-.938" /><path stroke-linecap="round" d="M8 13h2.5M8 9h6.5M8 17h1.5M3 14v-4c0-3.771 0-5.657 1.172-6.828S7.229 2 11 2h2c3.771 0 5.657 0 6.828 1.172M21 14c0 3.771 0 5.657-1.172 6.828m-15.656 0C5.343 22 7.229 22 11 22h2c3.771 0 5.657 0 6.828-1.172m0 0c.944-.943 1.127-2.348 1.163-4.828" /></g></svg>`;
const widgets = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 1.5)" d="M16.65 13L11 7.35l5.65-5.65l5.65 5.65zM3 11V3h8v8zm10 10v-8h8v8zM3 21v-8h8v8z" /></svg>`;
const starOutline = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 1.5)" d="m8.85 16.825l3.15-1.9l3.15 1.925l-.825-3.6l2.775-2.4l-3.65-.325l-1.45-3.4l-1.45 3.375l-3.65.325l2.775 2.425zM5.825 21l1.625-7.025L2 9.25l7.2-.625L12 2l2.8 6.625l7.2.625l-5.45 4.725L18.175 21L12 17.275zM12 12.25" /></svg>`;
const starSolid = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" style="stroke-width:var(--fu-icon-stroke-width, 1.5)" d="m5.825 21l1.625-7.025L2 9.25l7.2-.625L12 2l2.8 6.625l7.2.625l-5.45 4.725L18.175 21L12 17.275z" /></svg>`;

class IconRegistryService {
    constructor(sanitizer) {
        this.sanitizer = sanitizer;
        this.icons = new Map();
        this.registerIcon('edit', edit);
        this.registerIcon('editOff', editOff);
        this.registerIcon('editSave', editSave);
        this.registerIcon('trash', trash);
        this.registerIcon('arrowLeft', arrowLeft);
        this.registerIcon('arrowRight', arrowRight);
        this.registerIcon('doubleArrowLeft', doubleArrowLeft);
        this.registerIcon('doubleArrowRight', doubleArrowRight);
        this.registerIcon('sort', sort);
        this.registerIcon('sortAsc', sortAsc);
        this.registerIcon('sortDesc', sortDesc);
        this.registerIcon('filterRemove', filterRemove);
        this.registerIcon('filterPlus', filterPlus);
        this.registerIcon('filterEdit', filterEdit);
        this.registerIcon('check', check);
        this.registerIcon('save', save);
        this.registerIcon('building', building);
        this.registerIcon('buildingHand', buildingHand);
        this.registerIcon('buildingBuild', buildingBuild);
        this.registerIcon('buildingSwap', buildingSwap);
        this.registerIcon('buildingUser', buildingUser);
        this.registerIcon('buildingGear', buildingGear);
        this.registerIcon('buildingGearBuild', buildingGearBuild);
        this.registerIcon('buildingRemove', buildingRemove);
        this.registerIcon('buildingAdd', buildingAdd);
        this.registerIcon('exchange', exchange);
        this.registerIcon('exchangeCircle', exchangeCircle);
        this.registerIcon('cancel', cancel);
        this.registerIcon('cancelCircle', cancelCircle);
        this.registerIcon('plus', plus);
        this.registerIcon('plusCircle', plusCircle);
        this.registerIcon('search', search);
        this.registerIcon('eye', eye);
        this.registerIcon('chevronRight', chevronRight);
        this.registerIcon('link', link);
        this.registerIcon('certificate', certificate);
        this.registerIcon('report', report);
        this.registerIcon('elevator', elevator);
        this.registerIcon('templateEdit', templateEdit);
        this.registerIcon('draftEdit', draftEdit);
        this.registerIcon('widgets', widgets);
        this.registerIcon('starOutline', starOutline);
        this.registerIcon('starSolid', starSolid);
    }
    registerIcon(name, svg) {
        const safeSvg = this.sanitizer.bypassSecurityTrustHtml(svg);
        this.icons.set(name, safeSvg);
    }
    getIcon(name) {
        return this.icons.get(name);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: IconRegistryService, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: IconRegistryService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: IconRegistryService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root',
                }]
        }], ctorParameters: () => [{ type: i1.DomSanitizer }] });

class IconComponent {
    get classList() {
        return `fu-icon`;
    }
    constructor(iconRegistry, elementRef) {
        this.iconRegistry = iconRegistry;
        this.elementRef = elementRef;
        this.iconName = input.required();
        this.size = input('');
        this.strokeWidth = input('');
        this.color = input('');
    }
    ngOnChanges(changes) {
        if (changes['size']) {
            this.setIconSize();
        }
        if (changes['color']) {
            this.setIconColor();
        }
        if (changes['strokeWidth']) {
            this.setIconStrokeWidth();
        }
    }
    ngOnInit() {
        this.iconSvg = this.iconRegistry.getIcon(this.iconName());
    }
    setIconColor() {
        this.elementRef.nativeElement.style.removeProperty('color');
        if (this.color() !== undefined) {
            this.elementRef.nativeElement.style.setProperty('color', this.color());
        }
    }
    setIconSize() {
        this.elementRef.nativeElement.style.removeProperty('--fu-icon-size');
        if (this.size() !== undefined) {
            this.elementRef.nativeElement.style.setProperty('--fu-icon-size', this.size().toString());
        }
    }
    setIconStrokeWidth() {
        this.elementRef.nativeElement.style.removeProperty('--fu-icon-stroke-width');
        if (this.strokeWidth() !== undefined) {
            this.elementRef.nativeElement.style.setProperty('--fu-icon-stroke-width', this.strokeWidth().toString());
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: IconComponent, deps: [{ token: IconRegistryService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.0.6", type: IconComponent, isStandalone: false, selector: "fu-icon", inputs: { iconName: { classPropertyName: "iconName", publicName: "iconName", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, strokeWidth: { classPropertyName: "strokeWidth", publicName: "strokeWidth", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.classList" } }, usesOnChanges: true, ngImport: i0, template: "<span [innerHTML]=\"iconSvg\" class=\"fu-icon-container\"></span>\r\n", styles: ["fu-icon{display:inline-block;width:var(--fu-icon-size, 1.1rem);height:var(--fu-icon-size, 1.1rem)}.fu-icon-container{display:inline-block;width:var(--fu-icon-size, 1.1rem);height:var(--fu-icon-size, 1.1rem);line-height:initial;vertical-align:initial;overflow:hidden}.fu-icon-container svg{width:inherit;height:inherit;vertical-align:inherit}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: IconComponent, decorators: [{
            type: Component,
            args: [{ selector: 'fu-icon', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, standalone: false, template: "<span [innerHTML]=\"iconSvg\" class=\"fu-icon-container\"></span>\r\n", styles: ["fu-icon{display:inline-block;width:var(--fu-icon-size, 1.1rem);height:var(--fu-icon-size, 1.1rem)}.fu-icon-container{display:inline-block;width:var(--fu-icon-size, 1.1rem);height:var(--fu-icon-size, 1.1rem);line-height:initial;vertical-align:initial;overflow:hidden}.fu-icon-container svg{width:inherit;height:inherit;vertical-align:inherit}\n"] }]
        }], ctorParameters: () => [{ type: IconRegistryService }, { type: i0.ElementRef }], propDecorators: { classList: [{
                type: HostBinding,
                args: ['class']
            }] } });

class IconModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: IconModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.6", ngImport: i0, type: IconModule, declarations: [IconComponent], imports: [CommonModule], exports: [IconComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: IconModule, providers: [IconRegistryService], imports: [CommonModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: IconModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [IconComponent],
                    imports: [CommonModule],
                    providers: [IconRegistryService],
                    exports: [IconComponent],
                }]
        }] });

class TableUtilityService {
    constructor() {
        this.headerTexts = [];
        this.headerCount = signal(0);
        this.isLoading = signal(false);
        this.sortCellIndex = signal(-1);
        this.expanded = signal(false);
    }
    setSortCellIndex(index) {
        this.sortCellIndex.set(index);
    }
    resetSortCellIndex() {
        this.sortCellIndex.set(-1);
    }
    setHeaderText(index, text) {
        this.headerTexts[index] = text;
    }
    getHeaderText(index) {
        return this.headerTexts[index];
    }
    clearHeaderText() {
        this.headerTexts = [];
    }
    setColumnCount() {
        this.headerCount.update(count => count + 1);
    }
    resetColumnCount() {
        this.headerCount.set(0);
    }
    setIsLoading(loading) {
        this.isLoading.set(loading);
    }
    getExpanded(expanded) {
        this.expanded.set(expanded);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableUtilityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableUtilityService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableUtilityService, decorators: [{
            type: Injectable
        }] });

const initialState = {
    currentPage: 0,
    pageSize: 10,
    sortKey: '',
    sortDirection: '',
    searchText: '',
};
class TableStorageService {
    constructor() {
        this.storageState = signal(initialState);
        this.localStorageKey = signal('');
        this.currentPage = computed(() => this.storageState().currentPage);
        this.pageSize = computed(() => this.storageState().pageSize);
        this.sortKey = computed(() => this.storageState().sortKey);
        this.sortDirection = computed(() => this.storageState().sortDirection);
        this.searchText = computed(() => this.storageState().searchText);
        this.storageStateEffect = effect(() => {
            if (this.localStorageKey()) {
                const state = this.storageState();
                this.updateLocalStorage(state);
            }
        });
    }
    setCurrentPage(currentPage) {
        this.storageState.update(state => ({
            ...state,
            currentPage,
        }));
    }
    setPageSize(pageSize) {
        this.storageState.update(state => ({
            ...state,
            pageSize,
        }));
    }
    setSortKey(sortKey) {
        this.storageState.update(state => ({
            ...state,
            sortKey,
        }));
    }
    setSortDirection(sortDirection) {
        this.storageState.update(state => ({
            ...state,
            sortDirection,
        }));
    }
    setSearchText(searchText) {
        this.storageState.update(state => ({
            ...state,
            searchText,
        }));
    }
    setLocalStorageKey(key) {
        const storedValues = window.localStorage.getItem(key);
        if (storedValues && key) {
            this.storageState.set(JSON.parse(storedValues));
        }
        this.localStorageKey.set(key);
    }
    resetStorageKey() {
        this.localStorageKey.set('');
    }
    resetState() {
        this.storageState.set(initialState);
    }
    updateLocalStorage(state) {
        window.localStorage.setItem(this.localStorageKey(), JSON.stringify(state));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableStorageService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableStorageService, decorators: [{
            type: Injectable
        }] });

class TableIntlService {
    constructor() {
        this.searchPlaceholder = signal('Search...');
        this.pageSizeLabel = signal('Page size');
        this.noRecordsText = signal('No records found');
        this.noEntriesLabel = signal('No entries');
        this.entriesLabel = (first, last, total) => `${first} to ${last} of ${total} entries`;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableIntlService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableIntlService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableIntlService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root',
                }]
        }] });

class TableEditService {
    constructor() {
        this.editIndex = signal(null);
        this.editValues = signal({});
        this.savingIndex = signal(-1);
    }
    startEditing(rowIndex) {
        this.editValues.set({});
        this.editIndex.set(rowIndex);
    }
    stopEditing() {
        this.editIndex.set(null);
    }
    updateEditValues(key, value) {
        this.editValues.update(values => ({
            ...values,
            [key]: value,
        }));
    }
    resetEditValues() {
        this.editValues.set({});
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableEditService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableEditService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableEditService, decorators: [{
            type: Injectable
        }] });

class TablePaginatorComponent {
    constructor() {
        this.pageSizeOptions = input([]);
        this.quickPageJump = input(false);
        this.dataLenght = input(0);
        this.tableEditService = inject(TableEditService);
        this.tableStorageService = inject(TableStorageService);
        this.tableIntl = inject(TableIntlService);
        this.pageSizeLabel = this.tableIntl.pageSizeLabel;
        this.pageSize = this.tableStorageService.pageSize;
        this.currentPage = this.tableStorageService.currentPage;
        this.searchText = this.tableStorageService.searchText;
        this.first = computed(() => this.currentPage() * this.pageSize() + 1);
        this.last = computed(() => Math.min((this.currentPage() + 1) * this.pageSize(), this.dataLenght()));
        this.totalPages = computed(() => Math.ceil(this.dataLenght() / this.pageSize()));
        this.totalItems = computed(() => this.dataLenght());
        this.noEntriesLabel = this.tableIntl.noEntriesLabel;
        this.entriesLabel = computed(() => this.tableIntl.entriesLabel(this.first(), this.last(), this.totalItems()));
    }
    goToPage(page) {
        if (page < 0 || page > this.totalPages()) {
            return;
        }
        this.stopEditing();
        this.tableStorageService.setCurrentPage(page);
    }
    changePageSize(event) {
        const pageSize = Number(event.target.value);
        this.tableStorageService.setCurrentPage(0);
        this.tableStorageService.setPageSize(pageSize);
        this.stopEditing();
    }
    jumpToPage(input) {
        const previousValue = this.tableStorageService.currentPage() + 1;
        const inputValue = input.value.trim();
        const value = Number(inputValue);
        const min = Number(input.min);
        const max = Number(input.max);
        if (isNaN(value) || inputValue !== value.toString()) {
            input.value = previousValue.toString();
            return;
        }
        if (value < min) {
            input.value = min.toString();
            this.tableStorageService.setCurrentPage(min - 1);
        }
        else if (value > max) {
            input.value = max.toString();
            this.tableStorageService.setCurrentPage(max - 1);
        }
        else {
            this.tableStorageService.setCurrentPage(value - 1);
        }
        this.stopEditing();
    }
    adjustWidth(input) {
        input.style.width = this.calculateWidth(input.value) + 'px';
    }
    calculateWidth(value) {
        if (!value || value.toString().trim() === '') {
            return 24;
        }
        const length = value.toString().length;
        return length === 1 ? 24 : length === 2 ? 24 : 36;
    }
    stopEditing() {
        if (this.tableEditService.editIndex() !== null) {
            this.tableEditService.stopEditing();
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TablePaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: TablePaginatorComponent, isStandalone: true, selector: "fu-table-paginator", inputs: { pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, quickPageJump: { classPropertyName: "quickPageJump", publicName: "quickPageJump", isSignal: true, isRequired: false, transformFunction: null }, dataLenght: { classPropertyName: "dataLenght", publicName: "dataLenght", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"fu-table-paginator\">\r\n  <div class=\"fu-paginator-page-select\">\r\n    <div class=\"fu-item-count\">\r\n      @if (totalItems() !== 0) {\r\n        {{ entriesLabel() }}\r\n      } @else {\r\n        {{ noEntriesLabel() }}\r\n      }\r\n    </div>\r\n\r\n    <div>\r\n      <span>{{ pageSizeLabel() }}:</span>\r\n      <select class=\"fu-page-size-select\" (change)=\"changePageSize($event)\">\r\n        @for (size of pageSizeOptions(); track $index) {\r\n          <option [value]=\"size\" [selected]=\"size === pageSize()\">\r\n            {{ size }}\r\n          </option>\r\n        }\r\n      </select>\r\n    </div>\r\n  </div>\r\n\r\n  <div class=\"fu-paginator-controls\">\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      variant=\"text\"\r\n      (click)=\"goToPage(0)\"\r\n      [disabled]=\"currentPage() === 0\"\r\n    >\r\n      <fu-icon size=\"20px\" iconName=\"doubleArrowLeft\" />\r\n    </button>\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      variant=\"text\"\r\n      (click)=\"goToPage(currentPage() - 1)\"\r\n      [disabled]=\"currentPage() === 0\"\r\n    >\r\n      <fu-icon size=\"20px\" iconName=\"arrowLeft\" />\r\n    </button>\r\n\r\n    @if (quickPageJump()) {\r\n      @if (totalPages() === 0) {\r\n        <div class=\"fu-no-pages\">\r\n          <span>-</span><span>/</span><span>-</span>\r\n        </div>\r\n      } @else {\r\n        <div class=\"fu-jump-to-page\">\r\n          <input\r\n            #pageInput\r\n            [min]=\"1\"\r\n            [max]=\"totalPages()\"\r\n            [value]=\"currentPage() + 1\"\r\n            (input)=\"adjustWidth(pageInput)\"\r\n            (change)=\"jumpToPage(pageInput)\"\r\n            [disabled]=\"totalPages() === 0\"\r\n            [style.width.px]=\"calculateWidth(pageInput.value)\"\r\n          />\r\n          <span>/</span>\r\n          <span>{{ totalPages() }}</span>\r\n        </div>\r\n      }\r\n      <!-- <div class=\"fu-jump-to-page\">\r\n        <input\r\n          #pageInput\r\n          [min]=\"1\"\r\n          [max]=\"totalPages()\"\r\n          [value]=\"currentPage() + 1\"\r\n          (input)=\"adjustWidth(pageInput)\"\r\n          (change)=\"jumpToPage(pageInput)\"\r\n          [disabled]=\"totalPages() === 0\"\r\n          [style.width.px]=\"calculateWidth(pageInput.value)\"\r\n        />\r\n        <span>/</span>\r\n        <span>{{ totalPages() }}</span>\r\n      </div> -->\r\n    }\r\n\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      variant=\"text\"\r\n      (click)=\"goToPage(currentPage() + 1)\"\r\n      [disabled]=\"currentPage() + 1 >= totalPages()\"\r\n    >\r\n      <fu-icon size=\"20px\" iconName=\"arrowRight\" />\r\n    </button>\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      variant=\"text\"\r\n      (click)=\"goToPage(totalPages() - 1)\"\r\n      [disabled]=\"currentPage() + 1 >= totalPages()\"\r\n    >\r\n      <fu-icon size=\"20px\" iconName=\"doubleArrowRight\" />\r\n    </button>\r\n  </div>\r\n</div>\r\n", styles: [".fu-table-paginator{position:relative;display:grid;grid-template-columns:1fr max-content}@media (max-width: 900px){.fu-table-paginator{grid-template-columns:1fr}}.fu-table-paginator .fu-page-size-select{background-color:inherit;color:inherit;padding:4px;border:1px solid var(--fu-table-border-color)}.fu-table-paginator .fu-paginator-page-select{display:flex;justify-content:flex-end;align-items:center;margin-right:12px;font-size:14px}@media (max-width: 900px){.fu-table-paginator .fu-paginator-page-select{margin-right:0;margin-bottom:8px}}.fu-table-paginator .fu-paginator-page-select .fu-item-count{margin-right:auto}.fu-table-paginator .fu-paginator-page-select span{margin-right:8px}.fu-table-paginator .fu-paginator-controls{display:flex;justify-content:flex-end;align-items:center;gap:4px}.fu-jump-to-page{display:flex;justify-content:center;align-items:center;gap:4px;margin:0 8px}.fu-jump-to-page input{height:22px;text-align:center;background-color:inherit;color:inherit;border:1px solid var(--fu-quick-jump-border-color, var(--fu-primary-500));border-radius:4px}.fu-jump-to-page input:focus{outline:1px solid var(--fu-quick-jump-border-color, var(--fu-primary-500))}.fu-no-pages{display:flex;gap:10px;color:#4e4e4e;font-weight:700}.dark option{background-color:var(--fu-table-bg-color);color:#fff}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: ButtonDirective, selector: "[fuButton]", inputs: ["variant", "severity", "iconButton", "rounded", "compact", "raised"] }, { kind: "ngmodule", type: IconModule }, { kind: "component", type: IconComponent, selector: "fu-icon", inputs: ["iconName", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TablePaginatorComponent, decorators: [{
            type: Component,
            args: [{ selector: 'fu-table-paginator', imports: [ButtonModule, IconModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"fu-table-paginator\">\r\n  <div class=\"fu-paginator-page-select\">\r\n    <div class=\"fu-item-count\">\r\n      @if (totalItems() !== 0) {\r\n        {{ entriesLabel() }}\r\n      } @else {\r\n        {{ noEntriesLabel() }}\r\n      }\r\n    </div>\r\n\r\n    <div>\r\n      <span>{{ pageSizeLabel() }}:</span>\r\n      <select class=\"fu-page-size-select\" (change)=\"changePageSize($event)\">\r\n        @for (size of pageSizeOptions(); track $index) {\r\n          <option [value]=\"size\" [selected]=\"size === pageSize()\">\r\n            {{ size }}\r\n          </option>\r\n        }\r\n      </select>\r\n    </div>\r\n  </div>\r\n\r\n  <div class=\"fu-paginator-controls\">\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      variant=\"text\"\r\n      (click)=\"goToPage(0)\"\r\n      [disabled]=\"currentPage() === 0\"\r\n    >\r\n      <fu-icon size=\"20px\" iconName=\"doubleArrowLeft\" />\r\n    </button>\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      variant=\"text\"\r\n      (click)=\"goToPage(currentPage() - 1)\"\r\n      [disabled]=\"currentPage() === 0\"\r\n    >\r\n      <fu-icon size=\"20px\" iconName=\"arrowLeft\" />\r\n    </button>\r\n\r\n    @if (quickPageJump()) {\r\n      @if (totalPages() === 0) {\r\n        <div class=\"fu-no-pages\">\r\n          <span>-</span><span>/</span><span>-</span>\r\n        </div>\r\n      } @else {\r\n        <div class=\"fu-jump-to-page\">\r\n          <input\r\n            #pageInput\r\n            [min]=\"1\"\r\n            [max]=\"totalPages()\"\r\n            [value]=\"currentPage() + 1\"\r\n            (input)=\"adjustWidth(pageInput)\"\r\n            (change)=\"jumpToPage(pageInput)\"\r\n            [disabled]=\"totalPages() === 0\"\r\n            [style.width.px]=\"calculateWidth(pageInput.value)\"\r\n          />\r\n          <span>/</span>\r\n          <span>{{ totalPages() }}</span>\r\n        </div>\r\n      }\r\n      <!-- <div class=\"fu-jump-to-page\">\r\n        <input\r\n          #pageInput\r\n          [min]=\"1\"\r\n          [max]=\"totalPages()\"\r\n          [value]=\"currentPage() + 1\"\r\n          (input)=\"adjustWidth(pageInput)\"\r\n          (change)=\"jumpToPage(pageInput)\"\r\n          [disabled]=\"totalPages() === 0\"\r\n          [style.width.px]=\"calculateWidth(pageInput.value)\"\r\n        />\r\n        <span>/</span>\r\n        <span>{{ totalPages() }}</span>\r\n      </div> -->\r\n    }\r\n\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      variant=\"text\"\r\n      (click)=\"goToPage(currentPage() + 1)\"\r\n      [disabled]=\"currentPage() + 1 >= totalPages()\"\r\n    >\r\n      <fu-icon size=\"20px\" iconName=\"arrowRight\" />\r\n    </button>\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      variant=\"text\"\r\n      (click)=\"goToPage(totalPages() - 1)\"\r\n      [disabled]=\"currentPage() + 1 >= totalPages()\"\r\n    >\r\n      <fu-icon size=\"20px\" iconName=\"doubleArrowRight\" />\r\n    </button>\r\n  </div>\r\n</div>\r\n", styles: [".fu-table-paginator{position:relative;display:grid;grid-template-columns:1fr max-content}@media (max-width: 900px){.fu-table-paginator{grid-template-columns:1fr}}.fu-table-paginator .fu-page-size-select{background-color:inherit;color:inherit;padding:4px;border:1px solid var(--fu-table-border-color)}.fu-table-paginator .fu-paginator-page-select{display:flex;justify-content:flex-end;align-items:center;margin-right:12px;font-size:14px}@media (max-width: 900px){.fu-table-paginator .fu-paginator-page-select{margin-right:0;margin-bottom:8px}}.fu-table-paginator .fu-paginator-page-select .fu-item-count{margin-right:auto}.fu-table-paginator .fu-paginator-page-select span{margin-right:8px}.fu-table-paginator .fu-paginator-controls{display:flex;justify-content:flex-end;align-items:center;gap:4px}.fu-jump-to-page{display:flex;justify-content:center;align-items:center;gap:4px;margin:0 8px}.fu-jump-to-page input{height:22px;text-align:center;background-color:inherit;color:inherit;border:1px solid var(--fu-quick-jump-border-color, var(--fu-primary-500));border-radius:4px}.fu-jump-to-page input:focus{outline:1px solid var(--fu-quick-jump-border-color, var(--fu-primary-500))}.fu-no-pages{display:flex;gap:10px;color:#4e4e4e;font-weight:700}.dark option{background-color:var(--fu-table-bg-color);color:#fff}\n"] }]
        }] });

class BodyTemplateDirective {
    constructor() {
        this.dataSource = input([], { alias: 'fuBodyTemplate' });
    }
    static ngTemplateContextGuard(dir, ctx) {
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BodyTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: BodyTemplateDirective, isStandalone: true, selector: "[fuBodyTemplate]", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "fuBodyTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BodyTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuBodyTemplate]',
                }]
        }] });

class ExpandTemplateDirective {
    constructor() {
        this.dataSource = input([], { alias: 'fuExpandTemplate' });
    }
    static ngTemplateContextGuard(dir, ctx) {
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: ExpandTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: ExpandTemplateDirective, isStandalone: true, selector: "[fuExpandTemplate]", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "fuExpandTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: ExpandTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuExpandTemplate]',
                }]
        }] });

class HeaderTemplateDirective {
    constructor() {
        this.dataSource = input([], { alias: 'fuHeaderTemplate' });
    }
    static ngTemplateContextGuard(dir, ctx) {
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: HeaderTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: HeaderTemplateDirective, isStandalone: true, selector: "[fuHeaderTemplate]", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "fuHeaderTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: HeaderTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuHeaderTemplate]',
                }]
        }] });

class KeyMappingPipe {
    transform(value) {
        if (!value || typeof value !== 'object') {
            return value;
        }
        const mappedObject = {};
        Object.keys(value).forEach(key => {
            mappedObject[key] = key;
        });
        return mappedObject;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: KeyMappingPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.6", ngImport: i0, type: KeyMappingPipe, isStandalone: true, name: "keyMapping" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: KeyMappingPipe, decorators: [{
            type: Pipe,
            args: [{
                    name: 'keyMapping',
                }]
        }] });

class TbodyCellComponent {
    constructor() {
        this.cellValue = input(undefined);
        this.editKey = input('');
        this.headerText = signal('');
        this.rowIndex = signal(-1);
        this.cellValueType = computed(() => typeof this.cellValue());
        this.isEditing = computed(() => this.rowIndex() === this.tableEditService.editIndex() && !!this.editKey());
        this.tableStorageService = inject(TableStorageService);
        this.tableUtilityService = inject(TableUtilityService);
        this.tableEditService = inject(TableEditService);
        this.elementRef = inject(ElementRef);
        this.expanded = this.tableUtilityService.expanded;
        this.isLoading = this.tableUtilityService.isLoading;
        this.searchText = this.tableStorageService.searchText;
        this.editIndex = this.tableEditService.editIndex;
        this.savingIndex = this.tableEditService.savingIndex;
        this.highLightedText = computed(() => this.highlightText());
        this.sortCell = computed(() => this.tableUtilityService.sortCellIndex() === this.cellIndex());
        this.cellIndex = signal(-2);
        this.editSavingEffect = effect(() => {
            if (this.savingIndex() > -1 && !this.isLoading() && this.isEditing()) {
                this.tableEditService.savingIndex.set(-1);
                this.tableEditService.stopEditing();
            }
        });
    }
    ngOnInit() {
        const rowIndex = this.getRowIndex();
        this.rowIndex.set(rowIndex);
        const cellIndex = this.getCellIndex();
        this.cellIndex.set(cellIndex);
        this.headerText.set(this.tableUtilityService.getHeaderText(cellIndex) || '');
    }
    highlightText() {
        const cellValue = this.cellValue();
        const searchText = this.searchText();
        if (!searchText || (!cellValue && cellValue !== 0)) {
            return cellValue;
        }
        const cellValueStr = cellValue.toString();
        const searchTerm = searchText.toString().toLowerCase();
        const regex = new RegExp(`(${searchTerm})`, 'gi');
        return cellValueStr.replace(regex, '<span class="fu-highlight">$1</span>');
    }
    onInputChange(value) {
        this.tableEditService.updateEditValues(this.editKey(), value);
    }
    getCellIndex() {
        const parent = this.elementRef.nativeElement.parentElement;
        return Array.from(parent.children).indexOf(this.elementRef.nativeElement);
    }
    getRowIndex() {
        const element = this.elementRef.nativeElement.parentElement;
        const parent = element.parentElement;
        if (!parent)
            return -1;
        const children = Array.from(parent.children);
        return children.indexOf(element);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TbodyCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: TbodyCellComponent, isStandalone: true, selector: "fu-tbody-cell", inputs: { cellValue: { classPropertyName: "cellValue", publicName: "cellValue", isSignal: true, isRequired: false, transformFunction: null }, editKey: { classPropertyName: "editKey", publicName: "editKey", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.role": "\"cell\"", "class.sorting": "sortCell()", "class.loading": "isLoading()", "class.expanded": "!expanded()" } }, ngImport: i0, template: "<div>\r\n  <span class=\"fu-header-text\">{{ headerText() }}</span>\r\n\r\n  @if ((isLoading() && savingIndex() < 0) || savingIndex() === rowIndex()) {\r\n    <span class=\"fu-skeleton-loader\"></span>\r\n  } @else {\r\n    @if (cellValue() !== undefined) {\r\n      @if (isEditing()) {\r\n        @switch (cellValueType()) {\r\n          @case ('string') {\r\n            <input\r\n              class=\"fu-edit\"\r\n              #editInput\r\n              [value]=\"cellValue()\"\r\n              (input)=\"onInputChange(editInput.value)\"\r\n              (click)=\"$event.stopPropagation()\"\r\n            />\r\n          }\r\n          @case ('number') {\r\n            <input\r\n              class=\"fu-edit\"\r\n              #editInput\r\n              type=\"number\"\r\n              [value]=\"cellValue()\"\r\n              (input)=\"onInputChange(editInput.value)\"\r\n              (click)=\"$event.stopPropagation()\"\r\n            />\r\n          }\r\n          @case ('boolean') {\r\n            <div class=\"fu-checkbox-wrapper\" [class.editing]=\"isEditing()\">\r\n              <input\r\n                type=\"checkbox\"\r\n                class=\"fu-input-checkbox\"\r\n                #editInput\r\n                [id]=\"cellIndex()\"\r\n                [checked]=\"cellValue()\"\r\n                (change)=\"onInputChange(editInput.checked)\"\r\n              />\r\n              <svg><use xlink:href=\"#fu-checkmark\" /></svg>\r\n              <label [for]=\"cellIndex()\"></label>\r\n              <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none\">\r\n                <symbol id=\"fu-checkmark\" viewBox=\"0 0 24 24\">\r\n                  <path\r\n                    stroke-linecap=\"round\"\r\n                    stroke-miterlimit=\"10\"\r\n                    fill=\"none\"\r\n                    d=\"M22.9 3.7l-15.2 16.6-6.6-7.1\"\r\n                  ></path>\r\n                </symbol>\r\n              </svg>\r\n            </div>\r\n          }\r\n        }\r\n      } @else {\r\n        @switch (cellValueType()) {\r\n          @case ('boolean') {\r\n            <div class=\"fu-checkbox-wrapper fu-checkbox-disabled\">\r\n              <input\r\n                type=\"checkbox\"\r\n                class=\"fu-input-checkbox\"\r\n                disabled\r\n                [checked]=\"cellValue()\"\r\n              />\r\n              <svg><use xlink:href=\"#fu-checkmark\" /></svg>\r\n              <label></label>\r\n              <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none\">\r\n                <symbol id=\"fu-checkmark\" viewBox=\"0 0 24 24\">\r\n                  <path\r\n                    stroke-linecap=\"round\"\r\n                    stroke-miterlimit=\"10\"\r\n                    fill=\"none\"\r\n                    d=\"M22.9 3.7l-15.2 16.6-6.6-7.1\"\r\n                  ></path>\r\n                </symbol>\r\n              </svg>\r\n            </div>\r\n          }\r\n          @default {\r\n            <span class=\"fu-cell-text\" [innerHTML]=\"highLightedText()\"></span>\r\n          }\r\n        }\r\n      }\r\n    } @else {\r\n      <span class=\"fu-cell-text\" [style.display]=\"'flex'\"> <ng-content /></span>\r\n    }\r\n  }\r\n</div>\r\n", styles: ["fu-tbody-cell{display:table-cell;text-align:left;vertical-align:middle;height:40px}fu-tbody-cell.expanded{border-bottom:1px solid var(--fu-table-border-color)}fu-tbody-cell.loading{pointer-events:none}fu-tbody-cell.sorting{background-color:var(--fu-table-sort-bg-color)}fu-tbody-cell>div{padding:0 8px}fu-tbody-cell input{width:100%;padding:4px 3px;background-color:inherit;color:inherit;border:1px solid var(--fu-table-text-color);border-radius:2px;background-color:var(--fu-table-edit-input-bg-color)}fu-tbody-cell .fu-edit{margin-left:-4px}@media (max-width: 900px){fu-tbody-cell .fu-edit{margin-left:0}}fu-tbody-cell input:focus{outline:1px solid var(--fu-table-text-color)}fu-tbody-cell .fu-cell-text{display:block;overflow:hidden;text-overflow:ellipsis}@media (max-width: 900px){fu-tbody-cell .fu-cell-text{margin-left:4px}fu-tbody-cell .fu-cell-text .fu-edit{margin-left:0}}fu-tbody-cell .fu-cell-text:has(svg){margin-left:2px}fu-tbody-cell .fu-header-text{display:none}@media (max-width: 900px){fu-tbody-cell{display:block;min-height:40px;height:auto;align-content:center}fu-tbody-cell div{display:grid;grid-template-columns:40% 1fr}fu-tbody-cell .fu-header-text{font-weight:700;text-transform:capitalize;display:flex;align-items:center;margin-right:12px}}.fu-skeleton-loader{display:block;height:16px;background:var(--fu-table-skeleton-color);position:relative;overflow:hidden;border-radius:4px;animation:fade 1.5s infinite ease-in-out}@media (max-width: 900px){.fu-skeleton-loader{height:20px;margin:3.6px 0}}@keyframes fade{0%,to{opacity:.5}50%{opacity:1}}.fu-highlight{background-color:var(--fu-table-highlight-bg-color);color:var(--fu-table-highlight-color);font-weight:700}.fu-checkbox-wrapper{--size: 24px;position:relative}.fu-checkbox-wrapper *,.fu-checkbox-wrapper *:before,.fu-checkbox-wrapper *:after{box-sizing:border-box}.fu-checkbox-wrapper .fu-input-checkbox{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.fu-checkbox-wrapper input:checked~svg{height:calc(var(--size) * .6)}.fu-checkbox-wrapper label:active:after{background-color:var(--fu-table-edit-input-bg-color)}.fu-checkbox-wrapper label{color:var(--fu-table-text-color);line-height:var(--size);cursor:pointer;position:relative}.fu-checkbox-wrapper label:after{content:\"\";height:var(--size);width:var(--size);margin-right:8px;float:left;border:1.5px solid var(--fu-table-border-color);border-radius:3px;transition:.15s all ease-out}.fu-checkbox-wrapper.editing label:after{border-color:var(--fu-table-text-color)}.fu-checkbox-wrapper svg{stroke:var(--fu-table-text-color);stroke-width:3px;height:0;width:calc(var(--size) * .6);position:absolute;left:calc(var(--size) * .21);top:calc(var(--size) * .2);stroke-dasharray:33}.fu-checkbox-disabled{pointer-events:none}@-webkit-keyframes draw-checkbox-28{0%{stroke-dashoffset:33}to{stroke-dashoffset:0}}@keyframes draw-checkbox-28{0%{stroke-dashoffset:33}to{stroke-dashoffset:0}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TbodyCellComponent, decorators: [{
            type: Component,
            args: [{ selector: 'fu-tbody-cell', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        '[attr.role]': '"cell"',
                        '[class.sorting]': 'sortCell()',
                        '[class.loading]': 'isLoading()',
                        '[class.expanded]': '!expanded()',
                    }, template: "<div>\r\n  <span class=\"fu-header-text\">{{ headerText() }}</span>\r\n\r\n  @if ((isLoading() && savingIndex() < 0) || savingIndex() === rowIndex()) {\r\n    <span class=\"fu-skeleton-loader\"></span>\r\n  } @else {\r\n    @if (cellValue() !== undefined) {\r\n      @if (isEditing()) {\r\n        @switch (cellValueType()) {\r\n          @case ('string') {\r\n            <input\r\n              class=\"fu-edit\"\r\n              #editInput\r\n              [value]=\"cellValue()\"\r\n              (input)=\"onInputChange(editInput.value)\"\r\n              (click)=\"$event.stopPropagation()\"\r\n            />\r\n          }\r\n          @case ('number') {\r\n            <input\r\n              class=\"fu-edit\"\r\n              #editInput\r\n              type=\"number\"\r\n              [value]=\"cellValue()\"\r\n              (input)=\"onInputChange(editInput.value)\"\r\n              (click)=\"$event.stopPropagation()\"\r\n            />\r\n          }\r\n          @case ('boolean') {\r\n            <div class=\"fu-checkbox-wrapper\" [class.editing]=\"isEditing()\">\r\n              <input\r\n                type=\"checkbox\"\r\n                class=\"fu-input-checkbox\"\r\n                #editInput\r\n                [id]=\"cellIndex()\"\r\n                [checked]=\"cellValue()\"\r\n                (change)=\"onInputChange(editInput.checked)\"\r\n              />\r\n              <svg><use xlink:href=\"#fu-checkmark\" /></svg>\r\n              <label [for]=\"cellIndex()\"></label>\r\n              <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none\">\r\n                <symbol id=\"fu-checkmark\" viewBox=\"0 0 24 24\">\r\n                  <path\r\n                    stroke-linecap=\"round\"\r\n                    stroke-miterlimit=\"10\"\r\n                    fill=\"none\"\r\n                    d=\"M22.9 3.7l-15.2 16.6-6.6-7.1\"\r\n                  ></path>\r\n                </symbol>\r\n              </svg>\r\n            </div>\r\n          }\r\n        }\r\n      } @else {\r\n        @switch (cellValueType()) {\r\n          @case ('boolean') {\r\n            <div class=\"fu-checkbox-wrapper fu-checkbox-disabled\">\r\n              <input\r\n                type=\"checkbox\"\r\n                class=\"fu-input-checkbox\"\r\n                disabled\r\n                [checked]=\"cellValue()\"\r\n              />\r\n              <svg><use xlink:href=\"#fu-checkmark\" /></svg>\r\n              <label></label>\r\n              <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none\">\r\n                <symbol id=\"fu-checkmark\" viewBox=\"0 0 24 24\">\r\n                  <path\r\n                    stroke-linecap=\"round\"\r\n                    stroke-miterlimit=\"10\"\r\n                    fill=\"none\"\r\n                    d=\"M22.9 3.7l-15.2 16.6-6.6-7.1\"\r\n                  ></path>\r\n                </symbol>\r\n              </svg>\r\n            </div>\r\n          }\r\n          @default {\r\n            <span class=\"fu-cell-text\" [innerHTML]=\"highLightedText()\"></span>\r\n          }\r\n        }\r\n      }\r\n    } @else {\r\n      <span class=\"fu-cell-text\" [style.display]=\"'flex'\"> <ng-content /></span>\r\n    }\r\n  }\r\n</div>\r\n", styles: ["fu-tbody-cell{display:table-cell;text-align:left;vertical-align:middle;height:40px}fu-tbody-cell.expanded{border-bottom:1px solid var(--fu-table-border-color)}fu-tbody-cell.loading{pointer-events:none}fu-tbody-cell.sorting{background-color:var(--fu-table-sort-bg-color)}fu-tbody-cell>div{padding:0 8px}fu-tbody-cell input{width:100%;padding:4px 3px;background-color:inherit;color:inherit;border:1px solid var(--fu-table-text-color);border-radius:2px;background-color:var(--fu-table-edit-input-bg-color)}fu-tbody-cell .fu-edit{margin-left:-4px}@media (max-width: 900px){fu-tbody-cell .fu-edit{margin-left:0}}fu-tbody-cell input:focus{outline:1px solid var(--fu-table-text-color)}fu-tbody-cell .fu-cell-text{display:block;overflow:hidden;text-overflow:ellipsis}@media (max-width: 900px){fu-tbody-cell .fu-cell-text{margin-left:4px}fu-tbody-cell .fu-cell-text .fu-edit{margin-left:0}}fu-tbody-cell .fu-cell-text:has(svg){margin-left:2px}fu-tbody-cell .fu-header-text{display:none}@media (max-width: 900px){fu-tbody-cell{display:block;min-height:40px;height:auto;align-content:center}fu-tbody-cell div{display:grid;grid-template-columns:40% 1fr}fu-tbody-cell .fu-header-text{font-weight:700;text-transform:capitalize;display:flex;align-items:center;margin-right:12px}}.fu-skeleton-loader{display:block;height:16px;background:var(--fu-table-skeleton-color);position:relative;overflow:hidden;border-radius:4px;animation:fade 1.5s infinite ease-in-out}@media (max-width: 900px){.fu-skeleton-loader{height:20px;margin:3.6px 0}}@keyframes fade{0%,to{opacity:.5}50%{opacity:1}}.fu-highlight{background-color:var(--fu-table-highlight-bg-color);color:var(--fu-table-highlight-color);font-weight:700}.fu-checkbox-wrapper{--size: 24px;position:relative}.fu-checkbox-wrapper *,.fu-checkbox-wrapper *:before,.fu-checkbox-wrapper *:after{box-sizing:border-box}.fu-checkbox-wrapper .fu-input-checkbox{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.fu-checkbox-wrapper input:checked~svg{height:calc(var(--size) * .6)}.fu-checkbox-wrapper label:active:after{background-color:var(--fu-table-edit-input-bg-color)}.fu-checkbox-wrapper label{color:var(--fu-table-text-color);line-height:var(--size);cursor:pointer;position:relative}.fu-checkbox-wrapper label:after{content:\"\";height:var(--size);width:var(--size);margin-right:8px;float:left;border:1.5px solid var(--fu-table-border-color);border-radius:3px;transition:.15s all ease-out}.fu-checkbox-wrapper.editing label:after{border-color:var(--fu-table-text-color)}.fu-checkbox-wrapper svg{stroke:var(--fu-table-text-color);stroke-width:3px;height:0;width:calc(var(--size) * .6);position:absolute;left:calc(var(--size) * .21);top:calc(var(--size) * .2);stroke-dasharray:33}.fu-checkbox-disabled{pointer-events:none}@-webkit-keyframes draw-checkbox-28{0%{stroke-dashoffset:33}to{stroke-dashoffset:0}}@keyframes draw-checkbox-28{0%{stroke-dashoffset:33}to{stroke-dashoffset:0}}\n"] }]
        }] });

class PopupTemplateDirective {
    constructor() {
        this.dataSource = input([], { alias: 'fuPopupTemplate' });
    }
    static ngTemplateContextGuard(dir, ctx) {
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: PopupTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: PopupTemplateDirective, isStandalone: true, selector: "[fuPopupTemplate]", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "fuPopupTemplate", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: PopupTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuPopupTemplate]',
                }]
        }] });

class TableFilterComponent {
    constructor() {
        this.title = input();
        this.tableStorageService = inject(TableStorageService);
        this.tableEditService = inject(TableEditService);
        this.tableIntl = inject(TableIntlService);
        this.placeholder = this.tableIntl.searchPlaceholder;
        this.searchText = this.tableStorageService.searchText;
    }
    resetSearch() {
        this.resetEdit();
        this.tableStorageService.setSearchText('');
        this.tableStorageService.setCurrentPage(0);
    }
    searchFilter(text) {
        this.resetEdit();
        this.tableStorageService.setSearchText(text);
        this.tableStorageService.setCurrentPage(0);
    }
    resetEdit() {
        if (this.tableEditService.editIndex() !== null) {
            this.tableEditService.stopEditing();
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: TableFilterComponent, isStandalone: true, selector: "fu-table-filter", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"fu-table-search\" [class.title]=\"title()\">\r\n  @if (title()) {\r\n    <div class=\"fu-table-title\">\r\n      <h3>{{ title() }}</h3>\r\n    </div>\r\n  }\r\n\r\n  <input\r\n    #searchInput\r\n    type=\"text\"\r\n    [placeholder]=\"placeholder()\"\r\n    [value]=\"searchText()\"\r\n    (input)=\"searchFilter(searchInput.value)\"\r\n  />\r\n\r\n  @if (searchText()) {\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      variant=\"text\"\r\n      class=\"fu-table-clear-button\"\r\n      (click)=\"resetSearch()\"\r\n    >\r\n      <fu-icon color=\"gray\" iconName=\"cancel\" />\r\n    </button>\r\n  }\r\n</div>\r\n", styles: [".fu-table-search{position:relative;margin-bottom:12px;display:grid}.fu-table-search.title{grid-template-columns:max-content 1fr}.fu-table-search .fu-table-title{display:flex;align-items:center;margin-right:12px}.fu-table-search input{padding:8px 40px 8px 8px;width:100%;box-sizing:border-box;background-color:inherit;color:inherit;border:1px solid var(--fu-table-border-color);outline:none;border-radius:4px}.fu-table-search input:focus{outline:1px solid var(--fu-primary-500)}.fu-table-search .fu-table-clear-button{position:absolute;top:50%;right:0;transform:translateY(-50%)}\n"], dependencies: [{ kind: "ngmodule", type: IconModule }, { kind: "component", type: IconComponent, selector: "fu-icon", inputs: ["iconName", "size", "strokeWidth", "color"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: ButtonDirective, selector: "[fuButton]", inputs: ["variant", "severity", "iconButton", "rounded", "compact", "raised"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableFilterComponent, decorators: [{
            type: Component,
            args: [{ selector: 'fu-table-filter', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [IconModule, ButtonModule], template: "<div class=\"fu-table-search\" [class.title]=\"title()\">\r\n  @if (title()) {\r\n    <div class=\"fu-table-title\">\r\n      <h3>{{ title() }}</h3>\r\n    </div>\r\n  }\r\n\r\n  <input\r\n    #searchInput\r\n    type=\"text\"\r\n    [placeholder]=\"placeholder()\"\r\n    [value]=\"searchText()\"\r\n    (input)=\"searchFilter(searchInput.value)\"\r\n  />\r\n\r\n  @if (searchText()) {\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      variant=\"text\"\r\n      class=\"fu-table-clear-button\"\r\n      (click)=\"resetSearch()\"\r\n    >\r\n      <fu-icon color=\"gray\" iconName=\"cancel\" />\r\n    </button>\r\n  }\r\n</div>\r\n", styles: [".fu-table-search{position:relative;margin-bottom:12px;display:grid}.fu-table-search.title{grid-template-columns:max-content 1fr}.fu-table-search .fu-table-title{display:flex;align-items:center;margin-right:12px}.fu-table-search input{padding:8px 40px 8px 8px;width:100%;box-sizing:border-box;background-color:inherit;color:inherit;border:1px solid var(--fu-table-border-color);outline:none;border-radius:4px}.fu-table-search input:focus{outline:1px solid var(--fu-primary-500)}.fu-table-search .fu-table-clear-button{position:absolute;top:50%;right:0;transform:translateY(-50%)}\n"] }]
        }] });

class TableSortService {
    constructor() {
        this.tableStorageService = inject(TableStorageService);
        this.sortKey = this.tableStorageService.sortKey;
        this.sortDirection = this.tableStorageService.sortDirection;
    }
    updateSort(column) {
        const newDirection = this.sortKey() === column && this.sortDirection() === 'asc'
            ? 'desc'
            : 'asc';
        this.tableStorageService.setCurrentPage(0);
        this.tableStorageService.setSortKey(column);
        this.tableStorageService.setSortDirection(newDirection);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableSortService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableSortService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableSortService, decorators: [{
            type: Injectable
        }] });

class TableComponent {
    constructor() {
        this.dataSource = input.required();
        this.localStorageKey = input('', {
            transform: val => `fu-table-${val}`,
        });
        this.tableLayout = input('auto');
        this.firstPageOnInit = input(false);
        this.pageSizeOptions = input([10, 15, 20]);
        this.isLoading = input(false);
        this.totalCount = input();
        this.serverPagination = input(false);
        this.stripedRows = input(true);
        this.expandable = input(false);
        this.expanded = input(false);
        this.showFilter = input(false);
        this.showPaginator = input(true);
        this.quickPageJump = input(true);
        this.popupOffset = input(0);
        this.tableTitle = input();
        this.variant = input('raised');
        this.sideBar = input(false);
        this.setsFirstPage$ = input();
        this.expandIndex = model(null);
        this.sidebarTemplate = contentChild('sidebarTemplate');
        this.noRecordsTemplate = contentChild('noRecordsTemplate');
        this.footerTemplate = contentChild('footerTemplate');
        this.popupTemplate = contentChild(PopupTemplateDirective, {
            read: TemplateRef,
        });
        this.expandTemplate = contentChild(ExpandTemplateDirective, {
            read: TemplateRef,
        });
        this.bodyTemplate = contentChild.required(BodyTemplateDirective, {
            read: TemplateRef,
        });
        this.headerTemplate = contentChild.required(HeaderTemplateDirective, {
            read: TemplateRef,
        });
        this.isInitLoad = signal(true);
        this.filteredData = signal([]);
        this.sortedData = signal([]);
        this.destroyRef = inject(DestroyRef);
        this.tableIntl = inject(TableIntlService);
        this.tableUtilityService = inject(TableUtilityService);
        this.tableStorageService = inject(TableStorageService);
        this.injector = inject(Injector);
        this.noRecordsText = this.tableIntl.noRecordsText;
        this.columnCount = this.tableUtilityService.headerCount;
        this.pageSize = this.tableStorageService.pageSize;
        this.currentPage = this.tableStorageService.currentPage;
        this.searchText = this.tableStorageService.searchText;
        this.sortColumn = this.tableStorageService.sortKey;
        this.sortDirection = this.tableStorageService.sortDirection;
        this.totalItems = computed(() => this.totalCount() || this.filteredData().length);
        this.expandedRowIndex = null;
        this.arrayFromSize = computed(() => Array.from({ length: this.pageSize() }));
        this.arrayFromCols = computed(() => Array.from({ length: this.expandColumnSpan() }));
        this.expandColumnSpan = computed(() => {
            if (this.expandable()) {
                return this.columnCount() + 1;
            }
            else {
                return this.columnCount();
            }
        });
        this.hoveredRow = signal(null);
        this.popupPosition = signal({ top: 0, left: 0, right: 0 });
        this.isMobile = signal(false);
        this.hidePopupTimeout = undefined;
        this.isPopupReady = computed(() => this.popupTemplate() && !this.isMobile() && !this.isLoading());
        this.tableActions = output();
        this.selectRowAction = new EventEmitter();
        this.tableActionsEffect = effect(() => {
            if (this.serverPagination()) {
                this.emitTableActions();
            }
            else {
                this.toggleSort();
            }
        });
        this.loadingEffect = effect(() => {
            this.tableUtilityService.setIsLoading(this.isLoading());
            this.watchInitLoad();
            untracked(() => {
                this.expandedRowIndex = null;
                this.expandIndex.set(null);
            });
        });
    }
    ngOnChanges(changes) {
        if (changes['localStorageKey']) {
            this.tableStorageService.setLocalStorageKey(this.localStorageKey());
        }
        if (changes['expanded']) {
            this.tableUtilityService.getExpanded(this.expanded());
        }
        if (changes['dataSource']) {
            if (this.serverPagination()) {
                this.loadServerData();
            }
            else {
                this.filteredData.set([...this.dataSource()]);
            }
        }
    }
    ngOnInit() {
        this.isMobile.set(window.innerWidth < 900);
        this.setsFirstPage$()
            ?.pipe(takeUntilDestroyed(this.destroyRef))
            .subscribe(() => {
            this.tableStorageService.setCurrentPage(0);
        });
        if (this.firstPageOnInit()) {
            this.tableStorageService.setCurrentPage(0);
        }
    }
    onResize() {
        const mobile = window.innerWidth < 900;
        this.isMobile.set(mobile);
    }
    toggleRow(row, index = 0) {
        if (this.isLoading())
            return;
        if (this.expandable()) {
            if (this.expandedRowIndex === index) {
                this.expandedRowIndex = null;
            }
            else {
                this.expandedRowIndex = index;
            }
            return;
        }
        this.selectRowAction.emit(row);
    }
    filterData() {
        const filteredData = this.dataSource().filter(item => Object.values(item).some((value) => {
            if (typeof value !== 'string' && typeof value !== 'number') {
                return;
            }
            return value
                .toString()
                .toLowerCase()
                .includes(this.searchText().toLowerCase());
        }));
        this.filteredData.set(filteredData);
    }
    sortData() {
        if (!this.sortDirection()) {
            this.filterData();
            return;
        }
        this.filterData();
        this.filteredData().sort((a, b) => {
            const valA = a[this.sortColumn()];
            const valB = b[this.sortColumn()];
            if (typeof valA === 'number' && typeof valB === 'number') {
                return this.sortDirection() === 'asc' ? valA - valB : valB - valA;
            }
            return this.sortDirection() === 'asc'
                ? String(valA).localeCompare(String(valB))
                : String(valB).localeCompare(String(valA));
        });
    }
    paginateData() {
        this.expandedRowIndex = null;
        this.expandIndex.set(null);
        const startIndex = this.currentPage() * this.pageSize();
        const endIndex = startIndex + this.pageSize();
        const sortedData = this.filteredData().slice(startIndex, endIndex);
        this.sortedData.set(sortedData);
    }
    loadServerData() {
        this.sortedData.set([...this.dataSource()]);
    }
    watchInitLoad() {
        if (this.isInitLoad()) {
            this.isInitLoad.set(this.isLoading());
        }
    }
    emitTableActions() {
        this.tableActions.emit({
            sortDirection: this.sortDirection(),
            sortKey: this.sortColumn(),
            pageSize: this.pageSize(),
            page: this.currentPage(),
        });
    }
    toggleSort() {
        this.sortData();
        this.paginateData();
    }
    onRowHover(event, row) {
        if (!this.isPopupReady())
            return;
        clearTimeout(this.hidePopupTimeout);
        this.hoveredRow.set(row);
        const rowElement = event.target.closest('tr');
        if (rowElement) {
            const rect = rowElement.getBoundingClientRect();
            this.popupPosition.set({
                top: rect.top + window.scrollY,
                left: rect.right + window.scrollX,
                right: window.innerWidth - rect.right + this.popupOffset(),
            });
        }
    }
    onRowLeave() {
        if (!this.isPopupReady())
            return;
        this.hidePopupTimeout = setTimeout(() => {
            this.hoveredRow.set(null);
        }, 100);
    }
    onPopupHover() {
        clearTimeout(this.hidePopupTimeout);
    }
    onPopupLeave() {
        this.hidePopupTimeout = setTimeout(() => {
            this.hoveredRow.set(null);
        }, 100);
    }
    onExpandHover() {
        if (!this.isPopupReady())
            return;
        this.hoveredRow.set(null);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: TableComponent, isStandalone: true, selector: "fu-table", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, localStorageKey: { classPropertyName: "localStorageKey", publicName: "localStorageKey", isSignal: true, isRequired: false, transformFunction: null }, tableLayout: { classPropertyName: "tableLayout", publicName: "tableLayout", isSignal: true, isRequired: false, transformFunction: null }, firstPageOnInit: { classPropertyName: "firstPageOnInit", publicName: "firstPageOnInit", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, totalCount: { classPropertyName: "totalCount", publicName: "totalCount", isSignal: true, isRequired: false, transformFunction: null }, serverPagination: { classPropertyName: "serverPagination", publicName: "serverPagination", isSignal: true, isRequired: false, transformFunction: null }, stripedRows: { classPropertyName: "stripedRows", publicName: "stripedRows", isSignal: true, isRequired: false, transformFunction: null }, expandable: { classPropertyName: "expandable", publicName: "expandable", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null }, showFilter: { classPropertyName: "showFilter", publicName: "showFilter", isSignal: true, isRequired: false, transformFunction: null }, showPaginator: { classPropertyName: "showPaginator", publicName: "showPaginator", isSignal: true, isRequired: false, transformFunction: null }, quickPageJump: { classPropertyName: "quickPageJump", publicName: "quickPageJump", isSignal: true, isRequired: false, transformFunction: null }, popupOffset: { classPropertyName: "popupOffset", publicName: "popupOffset", isSignal: true, isRequired: false, transformFunction: null }, tableTitle: { classPropertyName: "tableTitle", publicName: "tableTitle", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, sideBar: { classPropertyName: "sideBar", publicName: "sideBar", isSignal: true, isRequired: false, transformFunction: null }, setsFirstPage$: { classPropertyName: "setsFirstPage$", publicName: "setsFirstPage$", isSignal: true, isRequired: false, transformFunction: null }, expandIndex: { classPropertyName: "expandIndex", publicName: "expandIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expandIndex: "expandIndexChange", tableActions: "tableActions", selectRowAction: "selectRowAction" }, host: { listeners: { "window:resize": "onResize()" } }, providers: [
            TableUtilityService,
            TableStorageService,
            TableSortService,
            TableEditService,
        ], queries: [{ propertyName: "sidebarTemplate", first: true, predicate: ["sidebarTemplate"], descendants: true, isSignal: true }, { propertyName: "noRecordsTemplate", first: true, predicate: ["noRecordsTemplate"], descendants: true, isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: ["footerTemplate"], descendants: true, isSignal: true }, { propertyName: "popupTemplate", first: true, predicate: PopupTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "expandTemplate", first: true, predicate: ExpandTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "bodyTemplate", first: true, predicate: BodyTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "headerTemplate", first: true, predicate: HeaderTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"fu-table-wrapper\" [attr.outlined]=\"variant() === 'outlined'\">\r\n  <!-- Search Filter -->\r\n  @if (showFilter()) {\r\n    <fu-table-filter [title]=\"tableTitle()\" />\r\n  } @else if (tableTitle()) {\r\n    <div style=\"margin-bottom: 12px\">\r\n      <h3>{{ tableTitle() }}</h3>\r\n    </div>\r\n  }\r\n\r\n  <!-- Table -->\r\n  <table [attr.role]=\"'table'\" [style.table-layout]=\"tableLayout()\">\r\n    <thead [attr.role]=\"'rowgroup'\">\r\n      <tr [attr.role]=\"'row'\">\r\n        @if (expandable()) {\r\n          <th class=\"fu-expand-head\"></th>\r\n        }\r\n        <ng-container\r\n          *ngTemplateOutlet=\"\r\n            headerTemplate();\r\n            context: { $implicit: dataSource()[0] | keyMapping }\r\n          \"\r\n        />\r\n      </tr>\r\n    </thead>\r\n\r\n    <tbody [attr.role]=\"'rowgroup'\">\r\n      @if (sideBar()) {\r\n        <div class=\"fu-sidebar\">\r\n          <ng-container *ngTemplateOutlet=\"sidebarTemplate() || null\" />\r\n        </div>\r\n      }\r\n\r\n      @if (isInitLoad()) {\r\n        <ng-container *ngTemplateOutlet=\"initLoadTemplate\" />\r\n      } @else {\r\n        @for (row of sortedData(); track $index; let odd = $odd) {\r\n          <tr\r\n            [attr.outlined]=\"variant() === 'outlined'\"\r\n            [attr.role]=\"'row'\"\r\n            class=\"fu-body-row\"\r\n            [ngClass]=\"{\r\n              striped: stripedRows() && odd,\r\n              hoverable: expandable() || selectRowAction.observed,\r\n            }\"\r\n            (mouseenter)=\"onRowHover($event, row)\"\r\n            (mouseleave)=\"onRowLeave()\"\r\n            (click)=\"toggleRow(row, $index)\"\r\n          >\r\n            @if (expandable()) {\r\n              <td\r\n                class=\"fu-expand-cell\"\r\n                [attr.data-expand]=\"expandedRowIndex === $index\"\r\n              >\r\n                <fu-icon size=\"16px\" iconName=\"chevronRight\" />\r\n              </td>\r\n            }\r\n            <ng-container\r\n              *ngTemplateOutlet=\"\r\n                bodyTemplate();\r\n                context: {\r\n                  $implicit: row,\r\n                  index: $index,\r\n                  keys: row | keyMapping,\r\n                }\r\n              \"\r\n            />\r\n          </tr>\r\n\r\n          @if (\r\n            (expandable() && expandedRowIndex === $index) ||\r\n            expandIndex() === $index ||\r\n            expanded()\r\n          ) {\r\n            <tr\r\n              class=\"fu-expand-row\"\r\n              [ngClass]=\"{\r\n                striped: stripedRows() && odd && expanded(),\r\n              }\"\r\n              [attr.expanded]=\"expanded()\"\r\n              (mouseenter)=\"onExpandHover()\"\r\n            >\r\n              <td [attr.colspan]=\"expandColumnSpan()\">\r\n                @if (isLoading() && expanded()) {\r\n                  <span class=\"fu-skeleton-loader\"></span>\r\n                } @else {\r\n                  <ng-container\r\n                    *ngTemplateOutlet=\"\r\n                      expandTemplate() || null;\r\n                      context: { $implicit: row, index: $index }\r\n                    \"\r\n                  />\r\n                }\r\n              </td>\r\n            </tr>\r\n          }\r\n        } @empty {\r\n          <tr class=\"fu-empty-row\">\r\n            <td [attr.colspan]=\"expandColumnSpan()\">\r\n              <ng-container\r\n                *ngTemplateOutlet=\"\r\n                  noRecordsTemplate() || defaultNoRecordsTemplate\r\n                \"\r\n              />\r\n            </td>\r\n          </tr>\r\n        }\r\n      }\r\n    </tbody>\r\n  </table>\r\n\r\n  @if (footerTemplate()) {\r\n    <div class=\"fu-table-footer\">\r\n      <ng-container\r\n        *ngTemplateOutlet=\"\r\n          footerTemplate() || null;\r\n          context: { $implicit: sortedData() }\r\n        \"\r\n      />\r\n    </div>\r\n  }\r\n\r\n  @if (showPaginator()) {\r\n    <fu-table-paginator\r\n      [dataLenght]=\"totalItems()\"\r\n      [quickPageJump]=\"quickPageJump()\"\r\n      [pageSizeOptions]=\"pageSizeOptions()\"\r\n    />\r\n  }\r\n</div>\r\n\r\n@if (hoveredRow()) {\r\n  <div\r\n    class=\"fu-action-popup\"\r\n    [style.top.px]=\"popupPosition().top\"\r\n    [style.right.px]=\"popupPosition().right\"\r\n    (mouseenter)=\"onPopupHover()\"\r\n    (mouseleave)=\"onPopupLeave()\"\r\n  >\r\n    <ng-container\r\n      *ngTemplateOutlet=\"\r\n        popupTemplate() || null;\r\n        context: { $implicit: hoveredRow() }\r\n      \"\r\n    />\r\n  </div>\r\n}\r\n\r\n<ng-template #defaultNoRecordsTemplate>\r\n  <div class=\"fu-no-records\">\r\n    <svg\r\n      xmlns=\"http://www.w3.org/2000/svg\"\r\n      width=\"24\"\r\n      height=\"24\"\r\n      viewBox=\"0 0 24 24\"\r\n    >\r\n      <path\r\n        fill=\"none\"\r\n        stroke=\"currentColor\"\r\n        stroke-linecap=\"round\"\r\n        stroke-linejoin=\"round\"\r\n        stroke-width=\"1.5\"\r\n        d=\"M12 8v4m0 4.01l.01-.011M9 3H4v3m0 5v2m16-2v2M15 3h5v3M9 21H4v-3m11 3h5v-3\"\r\n      />\r\n    </svg>\r\n    <p>{{ noRecordsText() }}</p>\r\n  </div>\r\n</ng-template>\r\n\r\n<ng-template #initLoadTemplate>\r\n  @for (item of arrayFromSize(); track $index) {\r\n    <tr class=\"fu-empty-row\">\r\n      @for (item of arrayFromCols(); track $index) {\r\n        <fu-tbody-cell />\r\n      }\r\n    </tr>\r\n  }\r\n</ng-template>\r\n", styles: [".fu-table-wrapper{position:relative;overflow-x:auto;padding:12px;font-family:Roboto,sans-serif;font-size:14px;background-color:var(--fu-table-bg-color);color:var(--fu-table-text-color);border-radius:4px}.fu-table-wrapper[outlined=true]{border:1px solid var(--fu-table-border-color)}.fu-table-wrapper[outlined=false]{box-shadow:0 1px 4px #0000005e}table{border-collapse:collapse;width:100%;margin-bottom:12px}thead tr{background-color:var(--fu-table-header-bg-color)}thead tr .fu-expand-head{width:40px;border-bottom:1px solid var(--fu-table-border-color)}@media (max-width: 900px){thead tr .fu-expand-head{display:none}}tbody tr .fu-expand-cell{border-bottom:1px solid var(--fu-table-border-color);text-align:center;vertical-align:middle}tbody tr .fu-expand-cell fu-icon{margin-top:3px}@media (max-width: 900px){tbody tr .fu-expand-cell{display:none}}tbody tr .fu-expand-cell[data-expand=true] fu-icon{transition:.1s ease-in-out;transform:rotate(90deg)}.fu-body-row{transition:.2s ease-in-out}.fu-body-row.striped{background-color:var(--fu-table-striped-row-bg-color)}.fu-body-row.hoverable:hover{background-color:var(--fu-table-bg-hover-color);cursor:pointer}.fu-expand-row[expanded=false]{border-top:1px solid var(--fu-table-border-color)}.fu-expand-row.striped{background-color:var(--fu-table-striped-row-bg-color)}tr.fu-expand-row>td{border-bottom:1px solid var(--fu-table-border-color);padding:8px}tr.fu-empty-row>td{border-bottom:1px solid var(--fu-table-border-color);border-top:1px solid var(--fu-table-border-color);padding:8px;text-align:center}tr.fu-empty-row>td svg{width:100px;height:100px;color:var(--fu-table-border-color)}@media (max-width: 900px){table{border:none;box-shadow:none;min-width:100%}thead{border-bottom:1px solid var(--fu-table-border-color)}tbody tr[outlined=true]{border-right:1px solid var(--fu-table-border-color);border-left:1px solid var(--fu-table-border-color);border-top:1px solid var(--fu-table-border-color)}tbody tr:first-child{border-top:none}tbody tr:last-child{margin-bottom:0}tr{display:block;margin-bottom:12px}tr[outlined=false]{box-shadow:0 2px 1px -1px #0003,0 1px 1px #00000024,0 1px 3px #0000001f}tr.fu-expand-row{margin-top:-8px;display:block;width:100%}tr.fu-expand-row>td{display:block;width:100%;padding:8px;box-sizing:border-box}tr.fu-empty-row>td{display:block;width:100%;padding:8px;box-sizing:border-box}}.fu-table-footer{position:relative;min-height:40px;margin-bottom:8px;background-color:var(--fu-table-header-bg-color);border-bottom:1px solid var(--fu-table-border-color);border-top:1px solid var(--fu-table-border-color)}.fu-action-popup{position:absolute;display:flex;align-items:center;gap:8px;background:var(--fu-table-bg-color);box-shadow:0 4px 6px #0000001a;border:1px solid var(--fu-table-border-color);border-radius:4px;min-height:40px;z-index:10;padding:0 8px}.fu-no-records{display:flex;flex-direction:column;justify-content:center;align-items:center;height:180px}.fu-no-records>p{color:#aeadad}tbody{position:relative}tbody .fu-sidebar{position:absolute;right:0;top:0;min-width:200px;height:100%;background-color:var(--fu-table-bg-color);border-left:2px solid var(--fu-table-border-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: IconModule }, { kind: "component", type: IconComponent, selector: "fu-icon", inputs: ["iconName", "size", "strokeWidth", "color"] }, { kind: "component", type: TablePaginatorComponent, selector: "fu-table-paginator", inputs: ["pageSizeOptions", "quickPageJump", "dataLenght"] }, { kind: "component", type: TableFilterComponent, selector: "fu-table-filter", inputs: ["title"] }, { kind: "component", type: TbodyCellComponent, selector: "fu-tbody-cell", inputs: ["cellValue", "editKey"] }, { kind: "pipe", type: KeyMappingPipe, name: "keyMapping" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TableComponent, decorators: [{
            type: Component,
            args: [{ selector: 'fu-table', imports: [
                        CommonModule,
                        ButtonModule,
                        IconModule,
                        TablePaginatorComponent,
                        TableFilterComponent,
                        TbodyCellComponent,
                        KeyMappingPipe,
                    ], providers: [
                        TableUtilityService,
                        TableStorageService,
                        TableSortService,
                        TableEditService,
                    ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"fu-table-wrapper\" [attr.outlined]=\"variant() === 'outlined'\">\r\n  <!-- Search Filter -->\r\n  @if (showFilter()) {\r\n    <fu-table-filter [title]=\"tableTitle()\" />\r\n  } @else if (tableTitle()) {\r\n    <div style=\"margin-bottom: 12px\">\r\n      <h3>{{ tableTitle() }}</h3>\r\n    </div>\r\n  }\r\n\r\n  <!-- Table -->\r\n  <table [attr.role]=\"'table'\" [style.table-layout]=\"tableLayout()\">\r\n    <thead [attr.role]=\"'rowgroup'\">\r\n      <tr [attr.role]=\"'row'\">\r\n        @if (expandable()) {\r\n          <th class=\"fu-expand-head\"></th>\r\n        }\r\n        <ng-container\r\n          *ngTemplateOutlet=\"\r\n            headerTemplate();\r\n            context: { $implicit: dataSource()[0] | keyMapping }\r\n          \"\r\n        />\r\n      </tr>\r\n    </thead>\r\n\r\n    <tbody [attr.role]=\"'rowgroup'\">\r\n      @if (sideBar()) {\r\n        <div class=\"fu-sidebar\">\r\n          <ng-container *ngTemplateOutlet=\"sidebarTemplate() || null\" />\r\n        </div>\r\n      }\r\n\r\n      @if (isInitLoad()) {\r\n        <ng-container *ngTemplateOutlet=\"initLoadTemplate\" />\r\n      } @else {\r\n        @for (row of sortedData(); track $index; let odd = $odd) {\r\n          <tr\r\n            [attr.outlined]=\"variant() === 'outlined'\"\r\n            [attr.role]=\"'row'\"\r\n            class=\"fu-body-row\"\r\n            [ngClass]=\"{\r\n              striped: stripedRows() && odd,\r\n              hoverable: expandable() || selectRowAction.observed,\r\n            }\"\r\n            (mouseenter)=\"onRowHover($event, row)\"\r\n            (mouseleave)=\"onRowLeave()\"\r\n            (click)=\"toggleRow(row, $index)\"\r\n          >\r\n            @if (expandable()) {\r\n              <td\r\n                class=\"fu-expand-cell\"\r\n                [attr.data-expand]=\"expandedRowIndex === $index\"\r\n              >\r\n                <fu-icon size=\"16px\" iconName=\"chevronRight\" />\r\n              </td>\r\n            }\r\n            <ng-container\r\n              *ngTemplateOutlet=\"\r\n                bodyTemplate();\r\n                context: {\r\n                  $implicit: row,\r\n                  index: $index,\r\n                  keys: row | keyMapping,\r\n                }\r\n              \"\r\n            />\r\n          </tr>\r\n\r\n          @if (\r\n            (expandable() && expandedRowIndex === $index) ||\r\n            expandIndex() === $index ||\r\n            expanded()\r\n          ) {\r\n            <tr\r\n              class=\"fu-expand-row\"\r\n              [ngClass]=\"{\r\n                striped: stripedRows() && odd && expanded(),\r\n              }\"\r\n              [attr.expanded]=\"expanded()\"\r\n              (mouseenter)=\"onExpandHover()\"\r\n            >\r\n              <td [attr.colspan]=\"expandColumnSpan()\">\r\n                @if (isLoading() && expanded()) {\r\n                  <span class=\"fu-skeleton-loader\"></span>\r\n                } @else {\r\n                  <ng-container\r\n                    *ngTemplateOutlet=\"\r\n                      expandTemplate() || null;\r\n                      context: { $implicit: row, index: $index }\r\n                    \"\r\n                  />\r\n                }\r\n              </td>\r\n            </tr>\r\n          }\r\n        } @empty {\r\n          <tr class=\"fu-empty-row\">\r\n            <td [attr.colspan]=\"expandColumnSpan()\">\r\n              <ng-container\r\n                *ngTemplateOutlet=\"\r\n                  noRecordsTemplate() || defaultNoRecordsTemplate\r\n                \"\r\n              />\r\n            </td>\r\n          </tr>\r\n        }\r\n      }\r\n    </tbody>\r\n  </table>\r\n\r\n  @if (footerTemplate()) {\r\n    <div class=\"fu-table-footer\">\r\n      <ng-container\r\n        *ngTemplateOutlet=\"\r\n          footerTemplate() || null;\r\n          context: { $implicit: sortedData() }\r\n        \"\r\n      />\r\n    </div>\r\n  }\r\n\r\n  @if (showPaginator()) {\r\n    <fu-table-paginator\r\n      [dataLenght]=\"totalItems()\"\r\n      [quickPageJump]=\"quickPageJump()\"\r\n      [pageSizeOptions]=\"pageSizeOptions()\"\r\n    />\r\n  }\r\n</div>\r\n\r\n@if (hoveredRow()) {\r\n  <div\r\n    class=\"fu-action-popup\"\r\n    [style.top.px]=\"popupPosition().top\"\r\n    [style.right.px]=\"popupPosition().right\"\r\n    (mouseenter)=\"onPopupHover()\"\r\n    (mouseleave)=\"onPopupLeave()\"\r\n  >\r\n    <ng-container\r\n      *ngTemplateOutlet=\"\r\n        popupTemplate() || null;\r\n        context: { $implicit: hoveredRow() }\r\n      \"\r\n    />\r\n  </div>\r\n}\r\n\r\n<ng-template #defaultNoRecordsTemplate>\r\n  <div class=\"fu-no-records\">\r\n    <svg\r\n      xmlns=\"http://www.w3.org/2000/svg\"\r\n      width=\"24\"\r\n      height=\"24\"\r\n      viewBox=\"0 0 24 24\"\r\n    >\r\n      <path\r\n        fill=\"none\"\r\n        stroke=\"currentColor\"\r\n        stroke-linecap=\"round\"\r\n        stroke-linejoin=\"round\"\r\n        stroke-width=\"1.5\"\r\n        d=\"M12 8v4m0 4.01l.01-.011M9 3H4v3m0 5v2m16-2v2M15 3h5v3M9 21H4v-3m11 3h5v-3\"\r\n      />\r\n    </svg>\r\n    <p>{{ noRecordsText() }}</p>\r\n  </div>\r\n</ng-template>\r\n\r\n<ng-template #initLoadTemplate>\r\n  @for (item of arrayFromSize(); track $index) {\r\n    <tr class=\"fu-empty-row\">\r\n      @for (item of arrayFromCols(); track $index) {\r\n        <fu-tbody-cell />\r\n      }\r\n    </tr>\r\n  }\r\n</ng-template>\r\n", styles: [".fu-table-wrapper{position:relative;overflow-x:auto;padding:12px;font-family:Roboto,sans-serif;font-size:14px;background-color:var(--fu-table-bg-color);color:var(--fu-table-text-color);border-radius:4px}.fu-table-wrapper[outlined=true]{border:1px solid var(--fu-table-border-color)}.fu-table-wrapper[outlined=false]{box-shadow:0 1px 4px #0000005e}table{border-collapse:collapse;width:100%;margin-bottom:12px}thead tr{background-color:var(--fu-table-header-bg-color)}thead tr .fu-expand-head{width:40px;border-bottom:1px solid var(--fu-table-border-color)}@media (max-width: 900px){thead tr .fu-expand-head{display:none}}tbody tr .fu-expand-cell{border-bottom:1px solid var(--fu-table-border-color);text-align:center;vertical-align:middle}tbody tr .fu-expand-cell fu-icon{margin-top:3px}@media (max-width: 900px){tbody tr .fu-expand-cell{display:none}}tbody tr .fu-expand-cell[data-expand=true] fu-icon{transition:.1s ease-in-out;transform:rotate(90deg)}.fu-body-row{transition:.2s ease-in-out}.fu-body-row.striped{background-color:var(--fu-table-striped-row-bg-color)}.fu-body-row.hoverable:hover{background-color:var(--fu-table-bg-hover-color);cursor:pointer}.fu-expand-row[expanded=false]{border-top:1px solid var(--fu-table-border-color)}.fu-expand-row.striped{background-color:var(--fu-table-striped-row-bg-color)}tr.fu-expand-row>td{border-bottom:1px solid var(--fu-table-border-color);padding:8px}tr.fu-empty-row>td{border-bottom:1px solid var(--fu-table-border-color);border-top:1px solid var(--fu-table-border-color);padding:8px;text-align:center}tr.fu-empty-row>td svg{width:100px;height:100px;color:var(--fu-table-border-color)}@media (max-width: 900px){table{border:none;box-shadow:none;min-width:100%}thead{border-bottom:1px solid var(--fu-table-border-color)}tbody tr[outlined=true]{border-right:1px solid var(--fu-table-border-color);border-left:1px solid var(--fu-table-border-color);border-top:1px solid var(--fu-table-border-color)}tbody tr:first-child{border-top:none}tbody tr:last-child{margin-bottom:0}tr{display:block;margin-bottom:12px}tr[outlined=false]{box-shadow:0 2px 1px -1px #0003,0 1px 1px #00000024,0 1px 3px #0000001f}tr.fu-expand-row{margin-top:-8px;display:block;width:100%}tr.fu-expand-row>td{display:block;width:100%;padding:8px;box-sizing:border-box}tr.fu-empty-row>td{display:block;width:100%;padding:8px;box-sizing:border-box}}.fu-table-footer{position:relative;min-height:40px;margin-bottom:8px;background-color:var(--fu-table-header-bg-color);border-bottom:1px solid var(--fu-table-border-color);border-top:1px solid var(--fu-table-border-color)}.fu-action-popup{position:absolute;display:flex;align-items:center;gap:8px;background:var(--fu-table-bg-color);box-shadow:0 4px 6px #0000001a;border:1px solid var(--fu-table-border-color);border-radius:4px;min-height:40px;z-index:10;padding:0 8px}.fu-no-records{display:flex;flex-direction:column;justify-content:center;align-items:center;height:180px}.fu-no-records>p{color:#aeadad}tbody{position:relative}tbody .fu-sidebar{position:absolute;right:0;top:0;min-width:200px;height:100%;background-color:var(--fu-table-bg-color);border-left:2px solid var(--fu-table-border-color)}\n"] }]
        }], propDecorators: { selectRowAction: [{
                type: Output
            }], onResize: [{
                type: HostListener,
                args: ['window:resize']
            }] } });

class TheadCellComponent {
    constructor() {
        this.headerText = input('');
        this.sortKey = input(undefined);
        this.width = input('auto');
        this.tableStorageService = inject(TableStorageService);
        this.tableSortService = inject(TableSortService);
        this.tableUtilityService = inject(TableUtilityService);
        this.elementRef = inject(ElementRef);
        this.sortColumn = this.tableStorageService.sortKey;
        this.sortDirection = this.tableStorageService.sortDirection;
        this.cellIndex = signal(-1);
        this.initSortEffect = effect(() => {
            this.initSortCell();
        });
    }
    ngOnInit() {
        const index = this.getIndex();
        this.cellIndex.set(index);
        this.tableUtilityService.setHeaderText(index, this.headerText());
        this.tableUtilityService.setColumnCount();
    }
    toogleSort() {
        this.tableUtilityService.setSortCellIndex(this.cellIndex());
        this.tableSortService.updateSort(this.sortKey());
    }
    initSortCell() {
        if (this.sortColumn() === this.sortKey()) {
            this.tableUtilityService.setSortCellIndex(this.cellIndex());
        }
    }
    getIndex() {
        const parent = this.elementRef.nativeElement.parentElement;
        return Array.from(parent.children).indexOf(this.elementRef.nativeElement);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TheadCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: TheadCellComponent, isStandalone: true, selector: "fu-thead-cell", inputs: { headerText: { classPropertyName: "headerText", publicName: "headerText", isSignal: true, isRequired: false, transformFunction: null }, sortKey: { classPropertyName: "sortKey", publicName: "sortKey", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.role": "\"columnheader\"", "style.width": "width()", "class.sorting": "sortKey() !== undefined" } }, ngImport: i0, template: "<div\r\n  class=\"fu-header-cell\"\r\n  (click)=\"toogleSort()\"\r\n  [ngClass]=\"{ disabled: !sortKey() }\"\r\n>\r\n  <span class=\"fu-header-text\">{{ headerText() }} </span>\r\n\r\n  @if (sortKey()) {\r\n    @if (sortColumn() === sortKey()) {\r\n      @switch (sortDirection()) {\r\n        @case ('asc') {\r\n          <fu-icon size=\"1rem\" strokeWidth=\"2.5\" iconName=\"sortAsc\" />\r\n        }\r\n        @case ('desc') {\r\n          <fu-icon size=\"1rem\" strokeWidth=\"2.5\" iconName=\"sortDesc\" />\r\n        }\r\n        @default {\r\n          <fu-icon size=\"1rem\" color=\"gray\" iconName=\"sort\" />\r\n        }\r\n      }\r\n    } @else {\r\n      <fu-icon size=\"1rem\" color=\"gray\" iconName=\"sort\" />\r\n    }\r\n  }\r\n\r\n  <span class=\"fu-header-cell-content\">\r\n    <ng-content />\r\n  </span>\r\n</div>\r\n", styles: ["fu-thead-cell{display:table-cell;text-align:left;font-weight:700;border-bottom:1px solid var(--fu-table-border-color)}@media (max-width: 900px){fu-thead-cell{width:auto!important}}fu-thead-cell .fu-header-cell{display:flex;align-items:center;padding:12px 8px;cursor:pointer}fu-thead-cell .fu-header-cell:hover{background-color:var(--fu-table-bg-hover-color);transition:background-color .3s}fu-thead-cell .fu-header-cell .fu-header-text{margin-right:4px}fu-thead-cell .disabled{pointer-events:none}@media (max-width: 900px){fu-thead-cell{display:none}}@media (max-width: 900px){fu-thead-cell.sorting{display:inline-block;border-bottom:none}}.fu-header-cell-content{margin-left:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: IconModule }, { kind: "component", type: IconComponent, selector: "fu-icon", inputs: ["iconName", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TheadCellComponent, decorators: [{
            type: Component,
            args: [{ selector: 'fu-thead-cell', imports: [CommonModule, IconModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        '[attr.role]': '"columnheader"',
                        '[style.width]': 'width()',
                        '[class.sorting]': 'sortKey() !== undefined',
                    }, template: "<div\r\n  class=\"fu-header-cell\"\r\n  (click)=\"toogleSort()\"\r\n  [ngClass]=\"{ disabled: !sortKey() }\"\r\n>\r\n  <span class=\"fu-header-text\">{{ headerText() }} </span>\r\n\r\n  @if (sortKey()) {\r\n    @if (sortColumn() === sortKey()) {\r\n      @switch (sortDirection()) {\r\n        @case ('asc') {\r\n          <fu-icon size=\"1rem\" strokeWidth=\"2.5\" iconName=\"sortAsc\" />\r\n        }\r\n        @case ('desc') {\r\n          <fu-icon size=\"1rem\" strokeWidth=\"2.5\" iconName=\"sortDesc\" />\r\n        }\r\n        @default {\r\n          <fu-icon size=\"1rem\" color=\"gray\" iconName=\"sort\" />\r\n        }\r\n      }\r\n    } @else {\r\n      <fu-icon size=\"1rem\" color=\"gray\" iconName=\"sort\" />\r\n    }\r\n  }\r\n\r\n  <span class=\"fu-header-cell-content\">\r\n    <ng-content />\r\n  </span>\r\n</div>\r\n", styles: ["fu-thead-cell{display:table-cell;text-align:left;font-weight:700;border-bottom:1px solid var(--fu-table-border-color)}@media (max-width: 900px){fu-thead-cell{width:auto!important}}fu-thead-cell .fu-header-cell{display:flex;align-items:center;padding:12px 8px;cursor:pointer}fu-thead-cell .fu-header-cell:hover{background-color:var(--fu-table-bg-hover-color);transition:background-color .3s}fu-thead-cell .fu-header-cell .fu-header-text{margin-right:4px}fu-thead-cell .disabled{pointer-events:none}@media (max-width: 900px){fu-thead-cell{display:none}}@media (max-width: 900px){fu-thead-cell.sorting{display:inline-block;border-bottom:none}}.fu-header-cell-content{margin-left:auto}\n"] }]
        }] });

class TbodyActionsComponent {
    constructor() {
        this.editRowData = input();
        this.disabled = input(false);
        this.tableUtilityService = inject(TableUtilityService);
        this.tableEditService = inject(TableEditService);
        this.elementRef = inject(ElementRef);
        this.isLoading = this.tableUtilityService.isLoading;
        this.editIndex = this.tableEditService.editIndex;
        this.rowIndex = signal(-1);
        this.editSaveAction = new EventEmitter();
        this.deleteAction = new EventEmitter();
        this.cancelEditEffect = effect(() => {
            if (this.isLoading() &&
                this.editIndex() !== null &&
                this.tableEditService.savingIndex() < 0) {
                this.tableEditService.stopEditing();
            }
        });
    }
    startEditing(event) {
        const rowIndex = this.getRowIndex();
        this.rowIndex.set(rowIndex);
        this.tableEditService.startEditing(rowIndex);
        event.stopPropagation();
    }
    cancelEditing(event) {
        this.tableEditService.stopEditing();
        event.stopPropagation();
    }
    saveEditing(event) {
        this.tableEditService.savingIndex.set(this.rowIndex());
        const editedValues = this.tableEditService.editValues();
        const updatedRow = { ...this.editRowData(), ...editedValues };
        this.editSaveAction.emit(updatedRow);
        this.tableEditService.resetEditValues();
        event.stopPropagation();
    }
    deleteRow(event) {
        this.deleteAction.emit();
        event.stopPropagation();
    }
    getRowIndex() {
        const element = this.elementRef.nativeElement.parentElement;
        const parent = element.parentElement;
        if (!parent)
            return -1;
        const children = Array.from(parent.children);
        return children.indexOf(element);
    }
    ngOnDestroy() {
        this.tableEditService.stopEditing();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TbodyActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: TbodyActionsComponent, isStandalone: true, selector: "fu-tbody-actions", inputs: { editRowData: { classPropertyName: "editRowData", publicName: "editRowData", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { editSaveAction: "editSaveAction", deleteAction: "deleteAction" }, host: { properties: { "attr.role": "\"cell\"" } }, ngImport: i0, template: "<div class=\"fu-row-actions\" (click)=\"$event.stopPropagation()\">\r\n  @if (editIndex() === rowIndex()) {\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      raised\r\n      variant=\"text\"\r\n      severity=\"warning\"\r\n      [disabled]=\"isLoading() || disabled()\"\r\n      (click)=\"cancelEditing($event)\"\r\n    >\r\n      <fu-icon iconName=\"cancel\" />\r\n    </button>\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      raised\r\n      variant=\"text\"\r\n      severity=\"success\"\r\n      [disabled]=\"isLoading() || disabled()\"\r\n      (click)=\"saveEditing($event)\"\r\n    >\r\n      <fu-icon iconName=\"save\" />\r\n    </button>\r\n  } @else if (editSaveAction.observed) {\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      raised\r\n      variant=\"text\"\r\n      [disabled]=\"isLoading() || disabled()\"\r\n      (click)=\"startEditing($event)\"\r\n    >\r\n      <fu-icon iconName=\"edit\" />\r\n    </button>\r\n  }\r\n  @if (editIndex() !== rowIndex() && deleteAction.observed) {\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      raised\r\n      variant=\"text\"\r\n      severity=\"danger\"\r\n      [disabled]=\"isLoading() || disabled()\"\r\n      (click)=\"deleteRow($event)\"\r\n    >\r\n      <fu-icon iconName=\"trash\" />\r\n    </button>\r\n  }\r\n\r\n  <ng-content />\r\n</div>\r\n", styles: ["fu-tbody-actions{display:table-cell;border-bottom:1px solid var(--fu-table-border-color);border-left:1px solid var(--fu-table-border-color);text-align:center;vertical-align:middle;height:40px}fu-tbody-actions .fu-row-actions button{margin:0 4px}@media (max-width: 900px){fu-tbody-actions{display:flex;justify-content:center;padding:4px 0;border-left:none}}\n"], dependencies: [{ kind: "ngmodule", type: IconModule }, { kind: "component", type: IconComponent, selector: "fu-icon", inputs: ["iconName", "size", "strokeWidth", "color"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: ButtonDirective, selector: "[fuButton]", inputs: ["variant", "severity", "iconButton", "rounded", "compact", "raised"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TbodyActionsComponent, decorators: [{
            type: Component,
            args: [{ selector: 'fu-tbody-actions', imports: [IconModule, ButtonModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        '[attr.role]': '"cell"',
                    }, template: "<div class=\"fu-row-actions\" (click)=\"$event.stopPropagation()\">\r\n  @if (editIndex() === rowIndex()) {\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      raised\r\n      variant=\"text\"\r\n      severity=\"warning\"\r\n      [disabled]=\"isLoading() || disabled()\"\r\n      (click)=\"cancelEditing($event)\"\r\n    >\r\n      <fu-icon iconName=\"cancel\" />\r\n    </button>\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      raised\r\n      variant=\"text\"\r\n      severity=\"success\"\r\n      [disabled]=\"isLoading() || disabled()\"\r\n      (click)=\"saveEditing($event)\"\r\n    >\r\n      <fu-icon iconName=\"save\" />\r\n    </button>\r\n  } @else if (editSaveAction.observed) {\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      raised\r\n      variant=\"text\"\r\n      [disabled]=\"isLoading() || disabled()\"\r\n      (click)=\"startEditing($event)\"\r\n    >\r\n      <fu-icon iconName=\"edit\" />\r\n    </button>\r\n  }\r\n  @if (editIndex() !== rowIndex() && deleteAction.observed) {\r\n    <button\r\n      fuButton\r\n      iconButton\r\n      raised\r\n      variant=\"text\"\r\n      severity=\"danger\"\r\n      [disabled]=\"isLoading() || disabled()\"\r\n      (click)=\"deleteRow($event)\"\r\n    >\r\n      <fu-icon iconName=\"trash\" />\r\n    </button>\r\n  }\r\n\r\n  <ng-content />\r\n</div>\r\n", styles: ["fu-tbody-actions{display:table-cell;border-bottom:1px solid var(--fu-table-border-color);border-left:1px solid var(--fu-table-border-color);text-align:center;vertical-align:middle;height:40px}fu-tbody-actions .fu-row-actions button{margin:0 4px}@media (max-width: 900px){fu-tbody-actions{display:flex;justify-content:center;padding:4px 0;border-left:none}}\n"] }]
        }], propDecorators: { editSaveAction: [{
                type: Output
            }], deleteAction: [{
                type: Output
            }] } });

class HighlightDirective {
    constructor() {
        this.fuHighlight = input('');
        this.storageService = inject(TableStorageService);
        this.el = inject(ElementRef);
        this.searchText = this.storageService.searchText;
        this.highlightEffect = effect(() => {
            this.highlightText();
        });
    }
    highlightText() {
        const value = this.fuHighlight();
        if (!this.searchText() || !value) {
            this.el.nativeElement.innerHTML = value;
            return;
        }
        const regex = new RegExp(`(${this.searchText()})`, 'gi');
        this.el.nativeElement.innerHTML = `${value}`.replace(regex, '<span class="fu-highlight">$1</span>');
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: HighlightDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: HighlightDirective, isStandalone: true, selector: "[fuHighlight]", inputs: { fuHighlight: { classPropertyName: "fuHighlight", publicName: "fuHighlight", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: HighlightDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuHighlight]',
                }]
        }] });

/**
 * @deprecated DataTableModule is deprecated and will be removed in v1.
 * Please migrate to the new - FuTableModule API.
 */
class DataTableModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: DataTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.6", ngImport: i0, type: DataTableModule, imports: [TableComponent,
            TbodyCellComponent,
            TheadCellComponent,
            TbodyActionsComponent,
            BodyTemplateDirective,
            HeaderTemplateDirective,
            ExpandTemplateDirective,
            PopupTemplateDirective,
            HighlightDirective], exports: [TableComponent,
            TbodyCellComponent,
            TheadCellComponent,
            TbodyActionsComponent,
            BodyTemplateDirective,
            HeaderTemplateDirective,
            ExpandTemplateDirective,
            PopupTemplateDirective,
            HighlightDirective] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: DataTableModule, imports: [TableComponent,
            TheadCellComponent,
            TbodyActionsComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: DataTableModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [],
                    imports: [
                        TableComponent,
                        TbodyCellComponent,
                        TheadCellComponent,
                        TbodyActionsComponent,
                        BodyTemplateDirective,
                        HeaderTemplateDirective,
                        ExpandTemplateDirective,
                        PopupTemplateDirective,
                        HighlightDirective,
                    ],
                    exports: [
                        TableComponent,
                        TbodyCellComponent,
                        TheadCellComponent,
                        TbodyActionsComponent,
                        BodyTemplateDirective,
                        HeaderTemplateDirective,
                        ExpandTemplateDirective,
                        PopupTemplateDirective,
                        HighlightDirective,
                    ],
                }]
        }] });

class TreeComponent {
    constructor() {
        this.dataSource = input.required();
        this.onExpand = output();
        this.onCollapse = output();
        this.onSelect = output();
        this.actionTemplate = contentChild('actionTemplate');
    }
    toggleExpand(event, item) {
        event.stopPropagation();
        item.isExpanded = !item.isExpanded;
        this.emitEvents(item);
        if (item.hasChildren && item.children) {
            item.children.forEach(sub => {
                sub.isExpanded = false;
            });
        }
    }
    toggleSelect(item) {
        this.onSelect.emit(item);
    }
    emitEvents(item) {
        if (item.isExpanded) {
            this.onExpand.emit(item);
        }
        else {
            this.onCollapse.emit(item);
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: TreeComponent, isStandalone: true, selector: "fu-tree", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onExpand: "onExpand", onCollapse: "onCollapse", onSelect: "onSelect" }, queries: [{ propertyName: "actionTemplate", first: true, predicate: ["actionTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"fu-tree-container\">\r\n  <ul>\r\n    <ng-container\r\n      *ngTemplateOutlet=\"recursiveList; context: { $implicit: dataSource() }\"\r\n    />\r\n  </ul>\r\n</div>\r\n\r\n<ng-template #recursiveList let-items>\r\n  @for (item of items; track $index) {\r\n    <li>\r\n      <div class=\"fu-tree-item\" (click)=\"toggleSelect(item)\">\r\n        @if (item.hasChildren) {\r\n          <button\r\n            fuButton\r\n            variant=\"text\"\r\n            iconButton\r\n            (click)=\"toggleExpand($event, item)\"\r\n          >\r\n            <fu-icon\r\n              size=\"16px\"\r\n              strokeWidth=\"3px\"\r\n              [class.fu-rotate]=\"item.isExpanded\"\r\n              iconName=\"arrowRight\"\r\n            />\r\n          </button>\r\n        }\r\n\r\n        <span\r\n          [style.margin-left]=\"!item.hasChildren ? '40px' : '0'\"\r\n          class=\"fu-tree-item-text\"\r\n          >{{ item.label }}</span\r\n        >\r\n\r\n        <ng-container\r\n          *ngTemplateOutlet=\"\r\n            actionTemplate() || null;\r\n            context: { $implicit: item }\r\n          \"\r\n        />\r\n      </div>\r\n\r\n      @if (item.hasChildren && item.isExpanded) {\r\n        <ul style=\"padding-left: 16px\">\r\n          <ng-container\r\n            *ngTemplateOutlet=\"\r\n              recursiveList;\r\n              context: { $implicit: item.children }\r\n            \"\r\n          />\r\n        </ul>\r\n      }\r\n    </li>\r\n  }\r\n</ng-template>\r\n", styles: [".fu-tree-container{padding:8px 12px;margin:16px;box-shadow:0 1px 4px #0000005e;background-color:var(--fu-tree-bg-color);width:400px;overflow-y:auto}.fu-tree-item{display:flex;align-items:center;cursor:pointer;gap:8px;background-color:var(--fu-tree-item-bg-color);margin:6px 0;min-height:32px;transition:.1s ease-in-out}.fu-tree-item:hover{background-color:var(--fu-tree-bg-hover-color)}.fu-tree-item .fu-rotate{transform:rotate(90deg);transition:.1s ease-in-out}.fu-tree-item-text{margin-right:auto}.fu-item-current,.fu-item-access{padding:4px 0}.tree-dropdown{max-height:calc(100% - 40px)}ul{list-style-type:none}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:#f1f1f1;border-radius:10px}::-webkit-scrollbar-thumb{background:#888;border-radius:10px}::-webkit-scrollbar-thumb:hover{background:#555}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: ButtonDirective, selector: "[fuButton]", inputs: ["variant", "severity", "iconButton", "rounded", "compact", "raised"] }, { kind: "ngmodule", type: IconModule }, { kind: "component", type: IconComponent, selector: "fu-icon", inputs: ["iconName", "size", "strokeWidth", "color"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TreeComponent, decorators: [{
            type: Component,
            args: [{ selector: 'fu-tree', imports: [NgTemplateOutlet, ButtonModule, IconModule], template: "<div class=\"fu-tree-container\">\r\n  <ul>\r\n    <ng-container\r\n      *ngTemplateOutlet=\"recursiveList; context: { $implicit: dataSource() }\"\r\n    />\r\n  </ul>\r\n</div>\r\n\r\n<ng-template #recursiveList let-items>\r\n  @for (item of items; track $index) {\r\n    <li>\r\n      <div class=\"fu-tree-item\" (click)=\"toggleSelect(item)\">\r\n        @if (item.hasChildren) {\r\n          <button\r\n            fuButton\r\n            variant=\"text\"\r\n            iconButton\r\n            (click)=\"toggleExpand($event, item)\"\r\n          >\r\n            <fu-icon\r\n              size=\"16px\"\r\n              strokeWidth=\"3px\"\r\n              [class.fu-rotate]=\"item.isExpanded\"\r\n              iconName=\"arrowRight\"\r\n            />\r\n          </button>\r\n        }\r\n\r\n        <span\r\n          [style.margin-left]=\"!item.hasChildren ? '40px' : '0'\"\r\n          class=\"fu-tree-item-text\"\r\n          >{{ item.label }}</span\r\n        >\r\n\r\n        <ng-container\r\n          *ngTemplateOutlet=\"\r\n            actionTemplate() || null;\r\n            context: { $implicit: item }\r\n          \"\r\n        />\r\n      </div>\r\n\r\n      @if (item.hasChildren && item.isExpanded) {\r\n        <ul style=\"padding-left: 16px\">\r\n          <ng-container\r\n            *ngTemplateOutlet=\"\r\n              recursiveList;\r\n              context: { $implicit: item.children }\r\n            \"\r\n          />\r\n        </ul>\r\n      }\r\n    </li>\r\n  }\r\n</ng-template>\r\n", styles: [".fu-tree-container{padding:8px 12px;margin:16px;box-shadow:0 1px 4px #0000005e;background-color:var(--fu-tree-bg-color);width:400px;overflow-y:auto}.fu-tree-item{display:flex;align-items:center;cursor:pointer;gap:8px;background-color:var(--fu-tree-item-bg-color);margin:6px 0;min-height:32px;transition:.1s ease-in-out}.fu-tree-item:hover{background-color:var(--fu-tree-bg-hover-color)}.fu-tree-item .fu-rotate{transform:rotate(90deg);transition:.1s ease-in-out}.fu-tree-item-text{margin-right:auto}.fu-item-current,.fu-item-access{padding:4px 0}.tree-dropdown{max-height:calc(100% - 40px)}ul{list-style-type:none}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:#f1f1f1;border-radius:10px}::-webkit-scrollbar-thumb{background:#888;border-radius:10px}::-webkit-scrollbar-thumb:hover{background:#555}\n"] }]
        }] });

class TreeModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TreeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.6", ngImport: i0, type: TreeModule, imports: [TreeComponent], exports: [TreeComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TreeModule, imports: [TreeComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: TreeModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [],
                    imports: [TreeComponent],
                    exports: [TreeComponent],
                }]
        }] });

/**
 * Defines a custom expand-row template for a `fu-table`.
 *
 * The template context exposes:
 * - `row` – the current row data
 * - `index` – row index
 * - `searchTerm` – current search term
 *
 * ## Typing
 * To enable strong typing for `row`, provide the table data using `rowOf`.
 * This is used only for type inference and does not affect rendering.
 *
 * Usage:
 * ```html
 * <ng-template fuTableExpandRow let-row  let-index="index">
 *   {{ row.name }} {{row.age}}
 * </ng-template>
 * ```
 *
 * If `rowOf` is omitted, `row` will be typed as `any`.
 */
class FuTableExpandRowTemplateDirective {
    constructor() {
        /**
         * Provides typing context for the expand row template.
         * Used only for type inference – not consumed at runtime.
         */
        this.of = input(null, {
            alias: 'rowOf',
        });
    }
    static ngTemplateContextGuard(_dir, ctx) {
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableExpandRowTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: FuTableExpandRowTemplateDirective, isStandalone: true, selector: "[fuTableExpandRow]", inputs: { of: { classPropertyName: "of", publicName: "rowOf", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableExpandRowTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuTableExpandRow]',
                }]
        }] });

/**
 * Defines a custom no data template for a `fu-table`.
 *
 * Usage:
 * ```html
 * <ng-template fuTableNoData >
 *   no data available
 * </ng-template>
 * ```
 */
class FuTableNoDataTemplateDirective {
    static ngTemplateContextGuard(_dir, ctx) {
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableNoDataTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.6", type: FuTableNoDataTemplateDirective, isStandalone: true, selector: "[fuTableNoData]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableNoDataTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuTableNoData]',
                }]
        }] });

/**
 * Defines a custom sidebar template for a `fu-table`.
 *
 * Usage:
 * ```html
 * <ng-template fuTableSidebar >
 *   custom content
 * </ng-template>
 * ```
 */
class FuTableSidebarTemplateDirective {
    static ngTemplateContextGuard(_dir, ctx) {
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableSidebarTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.6", type: FuTableSidebarTemplateDirective, isStandalone: true, selector: "[fuTableSidebar]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableSidebarTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuTableSidebar]',
                }]
        }] });

class FuClickOutsideDirective {
    constructor(el) {
        this.el = el;
        this.fuClickOutside = output();
    }
    onPointerDown(event) {
        const target = event.target;
        if (!(target instanceof Node))
            return;
        if (!this.el.nativeElement.contains(target)) {
            this.fuClickOutside.emit();
        }
    }
    onEscape() {
        this.fuClickOutside.emit();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuClickOutsideDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.6", type: FuClickOutsideDirective, isStandalone: true, selector: "[fuClickOutside]", outputs: { fuClickOutside: "fuClickOutside" }, host: { listeners: { "document:pointerdown": "onPointerDown($event)", "document:keydown.escape": "onEscape()" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuClickOutsideDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuClickOutside]',
                }]
        }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { onPointerDown: [{
                type: HostListener,
                args: ['document:pointerdown', ['$event']]
            }], onEscape: [{
                type: HostListener,
                args: ['document:keydown.escape']
            }] } });

/**
 * Defines a custom cell context menu template for a `fu-column`.
 *
 * The template context exposes:
 * - `value` – the current cell value
 * - `row` – the current row data
 * - `colIndex` – column index
 * - `rowIndex` – row index
 * - `trigger` – the context menu trigger
 *
 * ## Typing
 * To enable strong typing for `row`, provide the table data using `rowOf`.
 * This is used only for type inference and does not affect rendering.
 *
 * Usage:
 * ```html
 * <ng-template fuTableCellContextMenu let-row="row" let-colIndex="colIndex">
 *   {{ row.name }}
 * </ng-template>
 * ```
 *
 * If `rowOf` is omitted, `row` will be typed as `any`.
 */
class FuTableCellContextMenuTemplateDirective {
    constructor() {
        /**
         * Provides typing context for the row context menu template.
         * Used only for type inference – not consumed at runtime.
         */
        this.of = input(null, {
            alias: 'rowOf',
        });
    }
    static ngTemplateContextGuard(_dir, ctx) {
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableCellContextMenuTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: FuTableCellContextMenuTemplateDirective, isStandalone: true, selector: "[fuTableCellContextMenu]", inputs: { of: { classPropertyName: "of", publicName: "rowOf", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableCellContextMenuTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuTableCellContextMenu]',
                }]
        }] });

/**
 * Prevents click handlers from being triggered.
 *
 * ## Usage
 * ```html
 * <button fuStopPropagation>Save</button>
 *
 * <input fuStopPropagation />
 *
 * <button fuStopPropagation (click)="editRow(row)">✏️</button>
 * ```
 *
 * ## Notes
 * - Does **not** call `preventDefault()`
 * - Safe to use on form controls
 * - Intended for use inside `fu-table` rows
 */
class FuStopPropagationDirective {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuStopPropagationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.6", type: FuStopPropagationDirective, isStandalone: true, selector: "[fuStopPropagation]", host: { listeners: { "click": "$event.stopPropagation()", "mousedown": "$event.stopPropagation()" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuStopPropagationDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuStopPropagation]',
                    host: {
                        '(click)': '$event.stopPropagation()',
                        '(mousedown)': '$event.stopPropagation()',
                    },
                }]
        }] });

class FuHighlightDirective {
    constructor() {
        this.fuHighlight = input('');
        this.fuHighlightTerm = input('');
        this.fuHighlightActive = input(false);
        this.el = inject((ElementRef));
        this.highlightEffect = effect(() => {
            this.highlightText();
        });
    }
    highlightText() {
        const value = this.fuHighlight();
        const term = this.fuHighlightTerm();
        if (!value) {
            this.el.nativeElement.innerHTML = '';
            return;
        }
        if (!term) {
            this.el.nativeElement.innerHTML = String(value);
            return;
        }
        const escaped = term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        const regex = new RegExp(`(${escaped})`, 'gi');
        this.el.nativeElement.innerHTML = String(value).replace(regex, match => this.fuHighlightActive()
            ? `<mark class="fu-search-highlight active">${match}</mark>`
            : `<mark class="fu-search-highlight">${match}</mark>`);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuHighlightDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: FuHighlightDirective, isStandalone: true, selector: "[fuHighlight]", inputs: { fuHighlight: { classPropertyName: "fuHighlight", publicName: "fuHighlight", isSignal: true, isRequired: false, transformFunction: null }, fuHighlightTerm: { classPropertyName: "fuHighlightTerm", publicName: "fuHighlightTerm", isSignal: true, isRequired: false, transformFunction: null }, fuHighlightActive: { classPropertyName: "fuHighlightActive", publicName: "fuHighlightActive", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuHighlightDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuHighlight]',
                }]
        }] });

class FuCellComponent {
    constructor() {
        this.value = model();
        this.id = input();
        this.type = input();
        this.editing = input(false);
        this.editable = input(false);
        this.searchTerm = input('');
        this.activeMatch = input(false);
        this.loading = input(false);
        this.searchable = input(false);
        this.valueType = computed(() => {
            return this.type() ?? typeof this.value();
        });
        this.dateValue = linkedSignal(() => {
            if (this.type() === 'date') {
                return this.value().toISOString().slice(0, 10);
            }
        });
        this.cellValueChange = output();
    }
    dateChange(event) {
        const input = event.target;
        const value = input.valueAsDate;
        this.cellValueChange.emit(value);
    }
    numberChange(value) {
        this.cellValueChange.emit(value);
    }
    booleanChange(value) {
        this.cellValueChange.emit(value);
    }
    textChange(value) {
        this.cellValueChange.emit(value);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: FuCellComponent, isStandalone: true, selector: "fu-cell", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, editing: { classPropertyName: "editing", publicName: "editing", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, searchTerm: { classPropertyName: "searchTerm", publicName: "searchTerm", isSignal: true, isRequired: false, transformFunction: null }, activeMatch: { classPropertyName: "activeMatch", publicName: "activeMatch", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", cellValueChange: "cellValueChange" }, ngImport: i0, template: "@if (editable() && editing()) {\r\n  @switch (valueType()) {\r\n    @case ('number') {\r\n      <input\r\n        type=\"number\"\r\n        [(ngModel)]=\"value\"\r\n        (ngModelChange)=\"numberChange($event)\"\r\n        fuStopPropagation\r\n      />\r\n    }\r\n\r\n    @case ('boolean') {\r\n      <div class=\"fu-checkbox-wrapper\" [class.editing]=\"editing()\">\r\n        <input\r\n          type=\"checkbox\"\r\n          class=\"fu-input-checkbox\"\r\n          [(ngModel)]=\"value\"\r\n          [id]=\"id()\"\r\n          (ngModelChange)=\"booleanChange($event)\"\r\n        />\r\n        <svg><use xlink:href=\"#fu-checkmark\" /></svg>\r\n        <label [for]=\"id()\"></label>\r\n        <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none\">\r\n          <symbol id=\"fu-checkmark\" viewBox=\"0 0 24 24\">\r\n            <path\r\n              stroke-linecap=\"round\"\r\n              stroke-miterlimit=\"10\"\r\n              fill=\"none\"\r\n              d=\"M22.9 3.7l-15.2 16.6-6.6-7.1\"\r\n            ></path>\r\n          </symbol>\r\n        </svg>\r\n      </div>\r\n    }\r\n\r\n    @case ('date') {\r\n      <input\r\n        type=\"date\"\r\n        [(ngModel)]=\"dateValue\"\r\n        (change)=\"dateChange($event)\"\r\n        fuStopPropagation\r\n      />\r\n    }\r\n\r\n    @case ('string') {\r\n      <input\r\n        type=\"text\"\r\n        [(ngModel)]=\"value\"\r\n        (ngModelChange)=\"textChange($event)\"\r\n        fuStopPropagation\r\n      />\r\n    }\r\n\r\n    @case ('text') {\r\n      <input\r\n        type=\"text\"\r\n        [(ngModel)]=\"value\"\r\n        (ngModelChange)=\"textChange($event)\"\r\n        fuStopPropagation\r\n      />\r\n    }\r\n  }\r\n} @else {\r\n  <div>\r\n    @switch (valueType()) {\r\n      @case ('date') {\r\n        <span>{{ value() | date }}</span>\r\n      }\r\n\r\n      @case ('text') {\r\n        <span\r\n          [fuHighlight]=\"value()\"\r\n          [fuHighlightTerm]=\"searchTerm()\"\r\n          [fuHighlightActive]=\"activeMatch()\"\r\n        ></span>\r\n      }\r\n\r\n      @case ('number') {\r\n        <span\r\n          [fuHighlight]=\"value()\"\r\n          [fuHighlightTerm]=\"searchTerm()\"\r\n          [fuHighlightActive]=\"activeMatch()\"\r\n        ></span>\r\n      }\r\n\r\n      @case ('boolean') {\r\n        <div class=\"fu-checkbox-wrapper fu-checkbox-disabled\">\r\n          <input\r\n            type=\"checkbox\"\r\n            class=\"fu-input-checkbox\"\r\n            disabled\r\n            [checked]=\"value()\"\r\n          />\r\n          <svg><use xlink:href=\"#fu-checkmark\" /></svg>\r\n          <label></label>\r\n          <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none\">\r\n            <symbol id=\"fu-checkmark\" viewBox=\"0 0 24 24\">\r\n              <path\r\n                stroke-linecap=\"round\"\r\n                stroke-miterlimit=\"10\"\r\n                fill=\"none\"\r\n                d=\"M22.9 3.7l-15.2 16.6-6.6-7.1\"\r\n              ></path>\r\n            </symbol>\r\n          </svg>\r\n        </div>\r\n      }\r\n\r\n      @default {\r\n        <span\r\n          [fuHighlight]=\"value()\"\r\n          [fuHighlightTerm]=\"searchTerm()\"\r\n          [fuHighlightActive]=\"activeMatch()\"\r\n        ></span>\r\n      }\r\n    }\r\n  </div>\r\n}\r\n", styles: ["input{padding:6px 8px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-input-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}input[type=number],input[type=text]{width:100%}input::placeholder{color:#999}input:focus{border-color:var(--fu-table-sticky-border)}::ng-deep .fu-search-highlight{background-color:#fde047;padding:0 2px;border-radius:2px}::ng-deep .fu-search-highlight.active{background-color:#fb7185!important}.fu-checkbox-wrapper{--size: 20px;position:relative}.fu-checkbox-wrapper *,.fu-checkbox-wrapper *:before,.fu-checkbox-wrapper *:after{box-sizing:border-box}.fu-checkbox-wrapper .fu-input-checkbox{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.fu-checkbox-wrapper input:checked~svg{height:calc(var(--size) * .6)}.fu-checkbox-wrapper label:active:after{background-color:var(--fu-table-input-bg)}.fu-checkbox-wrapper label{color:var(--fu-table-text);line-height:var(--size);cursor:pointer;position:relative}.fu-checkbox-wrapper label:after{content:\"\";height:var(--size);width:var(--size);float:left;border:1.5px solid var(--fu-table-border);border-radius:3px;transition:.15s all ease-out}.fu-checkbox-wrapper.editing label:after{border-color:var(--fu-table-text)}.fu-checkbox-wrapper svg{stroke:var(--fu-table-text);stroke-width:3px;height:0;width:calc(var(--size) * .6);position:absolute;left:calc(var(--size) * .21);top:calc(var(--size) * .2);stroke-dasharray:33}.fu-checkbox-disabled{pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "directive", type: FuStopPropagationDirective, selector: "[fuStopPropagation]" }, { kind: "directive", type: FuHighlightDirective, selector: "[fuHighlight]", inputs: ["fuHighlight", "fuHighlightTerm", "fuHighlightActive"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuCellComponent, decorators: [{
            type: Component,
            args: [{ selector: 'fu-cell', imports: [
                        FormsModule,
                        DatePipe,
                        FuStopPropagationDirective,
                        FuHighlightDirective,
                    ], template: "@if (editable() && editing()) {\r\n  @switch (valueType()) {\r\n    @case ('number') {\r\n      <input\r\n        type=\"number\"\r\n        [(ngModel)]=\"value\"\r\n        (ngModelChange)=\"numberChange($event)\"\r\n        fuStopPropagation\r\n      />\r\n    }\r\n\r\n    @case ('boolean') {\r\n      <div class=\"fu-checkbox-wrapper\" [class.editing]=\"editing()\">\r\n        <input\r\n          type=\"checkbox\"\r\n          class=\"fu-input-checkbox\"\r\n          [(ngModel)]=\"value\"\r\n          [id]=\"id()\"\r\n          (ngModelChange)=\"booleanChange($event)\"\r\n        />\r\n        <svg><use xlink:href=\"#fu-checkmark\" /></svg>\r\n        <label [for]=\"id()\"></label>\r\n        <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none\">\r\n          <symbol id=\"fu-checkmark\" viewBox=\"0 0 24 24\">\r\n            <path\r\n              stroke-linecap=\"round\"\r\n              stroke-miterlimit=\"10\"\r\n              fill=\"none\"\r\n              d=\"M22.9 3.7l-15.2 16.6-6.6-7.1\"\r\n            ></path>\r\n          </symbol>\r\n        </svg>\r\n      </div>\r\n    }\r\n\r\n    @case ('date') {\r\n      <input\r\n        type=\"date\"\r\n        [(ngModel)]=\"dateValue\"\r\n        (change)=\"dateChange($event)\"\r\n        fuStopPropagation\r\n      />\r\n    }\r\n\r\n    @case ('string') {\r\n      <input\r\n        type=\"text\"\r\n        [(ngModel)]=\"value\"\r\n        (ngModelChange)=\"textChange($event)\"\r\n        fuStopPropagation\r\n      />\r\n    }\r\n\r\n    @case ('text') {\r\n      <input\r\n        type=\"text\"\r\n        [(ngModel)]=\"value\"\r\n        (ngModelChange)=\"textChange($event)\"\r\n        fuStopPropagation\r\n      />\r\n    }\r\n  }\r\n} @else {\r\n  <div>\r\n    @switch (valueType()) {\r\n      @case ('date') {\r\n        <span>{{ value() | date }}</span>\r\n      }\r\n\r\n      @case ('text') {\r\n        <span\r\n          [fuHighlight]=\"value()\"\r\n          [fuHighlightTerm]=\"searchTerm()\"\r\n          [fuHighlightActive]=\"activeMatch()\"\r\n        ></span>\r\n      }\r\n\r\n      @case ('number') {\r\n        <span\r\n          [fuHighlight]=\"value()\"\r\n          [fuHighlightTerm]=\"searchTerm()\"\r\n          [fuHighlightActive]=\"activeMatch()\"\r\n        ></span>\r\n      }\r\n\r\n      @case ('boolean') {\r\n        <div class=\"fu-checkbox-wrapper fu-checkbox-disabled\">\r\n          <input\r\n            type=\"checkbox\"\r\n            class=\"fu-input-checkbox\"\r\n            disabled\r\n            [checked]=\"value()\"\r\n          />\r\n          <svg><use xlink:href=\"#fu-checkmark\" /></svg>\r\n          <label></label>\r\n          <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none\">\r\n            <symbol id=\"fu-checkmark\" viewBox=\"0 0 24 24\">\r\n              <path\r\n                stroke-linecap=\"round\"\r\n                stroke-miterlimit=\"10\"\r\n                fill=\"none\"\r\n                d=\"M22.9 3.7l-15.2 16.6-6.6-7.1\"\r\n              ></path>\r\n            </symbol>\r\n          </svg>\r\n        </div>\r\n      }\r\n\r\n      @default {\r\n        <span\r\n          [fuHighlight]=\"value()\"\r\n          [fuHighlightTerm]=\"searchTerm()\"\r\n          [fuHighlightActive]=\"activeMatch()\"\r\n        ></span>\r\n      }\r\n    }\r\n  </div>\r\n}\r\n", styles: ["input{padding:6px 8px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-input-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}input[type=number],input[type=text]{width:100%}input::placeholder{color:#999}input:focus{border-color:var(--fu-table-sticky-border)}::ng-deep .fu-search-highlight{background-color:#fde047;padding:0 2px;border-radius:2px}::ng-deep .fu-search-highlight.active{background-color:#fb7185!important}.fu-checkbox-wrapper{--size: 20px;position:relative}.fu-checkbox-wrapper *,.fu-checkbox-wrapper *:before,.fu-checkbox-wrapper *:after{box-sizing:border-box}.fu-checkbox-wrapper .fu-input-checkbox{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.fu-checkbox-wrapper input:checked~svg{height:calc(var(--size) * .6)}.fu-checkbox-wrapper label:active:after{background-color:var(--fu-table-input-bg)}.fu-checkbox-wrapper label{color:var(--fu-table-text);line-height:var(--size);cursor:pointer;position:relative}.fu-checkbox-wrapper label:after{content:\"\";height:var(--size);width:var(--size);float:left;border:1.5px solid var(--fu-table-border);border-radius:3px;transition:.15s all ease-out}.fu-checkbox-wrapper.editing label:after{border-color:var(--fu-table-text)}.fu-checkbox-wrapper svg{stroke:var(--fu-table-text);stroke-width:3px;height:0;width:calc(var(--size) * .6);position:absolute;left:calc(var(--size) * .21);top:calc(var(--size) * .2);stroke-dasharray:33}.fu-checkbox-disabled{pointer-events:none}\n"] }]
        }] });

class FuTableIntlService {
    constructor() {
        this.searchPlaceholder = signal('Search...');
        this.visible = signal('visible');
        this.previous = signal('Previous');
        this.next = signal('Next');
        this.noEntries = signal('No entries');
        this.noData = signal('No data available');
        this.responsiveLabel = signal('Responsive');
        this.scrollableLabel = signal('Scrollable');
        this.lockHeaderLabel = signal('Lock header');
        this.lockLeftLabel = signal('Lock left column');
        this.lockRightLabel = signal('Lock right column');
        this.pageLabel = signal('Page');
        this.ofLabel = signal('of');
        this.entriesLabel = (first, last, total) => `${first} to ${last} of ${total} entries`;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableIntlService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableIntlService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableIntlService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root',
                }]
        }] });

class FuTButtonDirective {
    constructor() {
        this.variant = input('default');
        this.severity = input(null);
        this.loading = input(false);
        this.disabled = input(false);
    }
    get classes() {
        return {
            'fu-button': true,
            [`fu-button--${this.variant()}`]: true,
            [`fu-button--${this.severity()}`]: this.severity(),
            'fu-button--loading': this.loading(),
            'fu-button--disabled': this.disabled(),
        };
    }
    get isDisabled() {
        return this.disabled() || this.loading() || null;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTButtonDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: FuTButtonDirective, isStandalone: true, selector: "button[fuTButton], a[fuTButton]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.classes", "attr.disabled": "this.isDisabled" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTButtonDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: 'button[fuTButton], a[fuTButton]',
                }]
        }], propDecorators: { classes: [{
                type: HostBinding,
                args: ['class']
            }], isDisabled: [{
                type: HostBinding,
                args: ['attr.disabled']
            }] } });

/**
 * Defines a custom toolbar template for a `fu-table`.
 * Template rendered above the table content.
 *
 * Usage:
 * ```html
 * <ng-template fuTableToolbar >
 *   <button>Custom Toolbar Button</button>
 * </ng-template>
 * ```
 */
class FuTableToolbarTemplateDirective {
    static ngTemplateContextGuard(_dir, ctx) {
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableToolbarTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.6", type: FuTableToolbarTemplateDirective, isStandalone: true, selector: "[fuTableToolbar]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableToolbarTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuTableToolbar]',
                }]
        }] });

class FuTooltipComponent {
    constructor() {
        this.text = model('');
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.0.6", type: FuTooltipComponent, isStandalone: true, selector: "fu-tooltip", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { text: "textChange" }, ngImport: i0, template: `
    <div class="fu-tooltip">
      {{ text() }}
    </div>
  `, isInline: true, styles: [".fu-tooltip{background:var(--fu-text, #333);color:var(--fu-surface, #fff);padding:6px 10px;border-radius:4px;font-family:var(--fu-font-family, Arial, sans-serif);font-size:12px;letter-spacing:.5px;white-space:pre-line;max-width:240px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTooltipComponent, decorators: [{
            type: Component,
            args: [{ selector: 'fu-tooltip', template: `
    <div class="fu-tooltip">
      {{ text() }}
    </div>
  `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".fu-tooltip{background:var(--fu-text, #333);color:var(--fu-surface, #fff);padding:6px 10px;border-radius:4px;font-family:var(--fu-font-family, Arial, sans-serif);font-size:12px;letter-spacing:.5px;white-space:pre-line;max-width:240px}\n"] }]
        }] });
class FuTooltipDirective {
    constructor() {
        this.fuTooltip = input('');
        this.overlay = inject(Overlay);
        this.elementRef = inject((ElementRef));
    }
    show() {
        if (!this.fuTooltip()?.trim())
            return;
        if (this.overlayRef)
            return;
        const positionStrategy = this.overlay
            .position()
            .flexibleConnectedTo(this.elementRef)
            .withPositions([
            {
                originX: 'center',
                originY: 'top',
                overlayX: 'center',
                overlayY: 'bottom',
                offsetY: -8,
            },
            // fallback (below)
            {
                originX: 'center',
                originY: 'bottom',
                overlayX: 'center',
                overlayY: 'top',
                offsetY: 8,
            },
        ]);
        this.overlayRef = this.overlay.create({
            positionStrategy,
            scrollStrategy: this.overlay.scrollStrategies.reposition(),
            hasBackdrop: false,
        });
        const tooltipPortal = new ComponentPortal(FuTooltipComponent);
        const tooltipRef = this.overlayRef.attach(tooltipPortal);
        tooltipRef.instance.text.set(this.fuTooltip());
    }
    hide() {
        this.overlayRef?.dispose();
        this.overlayRef = undefined;
    }
    ngOnDestroy() {
        this.overlayRef?.dispose();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: FuTooltipDirective, isStandalone: true, selector: "[fuTooltip]", inputs: { fuTooltip: { classPropertyName: "fuTooltip", publicName: "fuTooltip", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "show()", "mouseleave": "hide()" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTooltipDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuTooltip]',
                }]
        }], propDecorators: { show: [{
                type: HostListener,
                args: ['mouseenter']
            }], hide: [{
                type: HostListener,
                args: ['mouseleave']
            }] } });

/**
 * FuTableComponent
 *
 * A flexible data table displaying rows of type `T` with features including
 * pagination, sorting, column visibility/reordering, inline editing,
 * row expansion and optional localStorage persistence.
 *
 * Basic usage:
 * ```html
 * <fu-table [dataSource]="items" [paginator]="true" (onQueryChanged)="load($event)">
 *   <fu-column field="id" header="#" />
 *   <fu-column field="name" header="Name" sortable editable />
 *   <fu-column field="email" header="Email" />
 * </fu-table>
 * ```
 *
 * See the `FuColumnComponent` for column-level configuration and templating.
 *
 * @template T - row object type
 */
class FuTableComponent {
    toggleFilteredSelection(event) {
        const checked = event.target.checked;
        const min = 3;
        if (checked) {
            // select all filtered
            this.filteredHideable().forEach(col => {
                if (!col.visible())
                    col.visible.set(true);
            });
        }
        else {
            // deselect filtered but keep minimum visible
            const visibles = this.visibleColumns();
            this.filteredHideable()
                .filter(col => col.visible())
                .forEach(col => {
                if (visibles.length > min) {
                    col.visible.set(false);
                }
            });
        }
        this.emitColumns();
    }
    constructor(injector) {
        this.injector = injector;
        /**
         * The table's data source.
         * Required input that provides the array of objects to display in the fu-table.
         *
         */
        this.dataSource = model.required();
        /**
         * Total number of items available for server-side pagination.
         * When this value exceeds `dataSource.length`, fu-table operates in server-side mode
         * and expects the parent to handle pagination, sorting, and filtering.
         *
         * @default 0
         */
        this.totalItems = input(0);
        /**
         * Key for persisting table state (pagination, sorting, columns, UI settings) to localStorage.
         * When provided, fu-table will automatically save and restore its state across sessions.
         *
         * @default undefined
         */
        this.stateKey = input(undefined, {
            transform: val => (val ? `fu:table:${val}` : undefined),
        });
        /**
         * External column visibility configuration.
         * When provided, this overrides the `visible` property on individual column definitions.
         * Useful for programmatically controlling which columns are displayed.
         *
         * @default []
         * @example
         * ```typescript
         * columnsConfig = [
         *   { field: 'name', visible: true },
         *   { field: 'email', visible: false }
         * ];
         * ```
         */
        this.columnsConfig = input([]);
        /**
         * Enables the configuration sidebar panel.
         * When true, displays a button to open a sidebar for managing column order,
         * visibility, and layout settings.
         *
         * @default false
         */
        this.configPanel = input(false);
        /**
         * Enables the filter/search panel.
         * When true, displays a search input that filters rows based on column values.
         *
         * @default false
         */
        this.filterPanel = input(false);
        /**
         * Enables pagination controls.
         * When true, displays page navigation and items-per-page selector.
         *
         * @default true
         */
        this.paginator = input(true);
        /**
         * Loading state indicator.
         * When true, displays loading skeletons instead of table data.
         * Useful for showing loading state during async operations.
         *
         * @default false
         */
        this.loading = input(false);
        /**
         * Disables pagination controls while keeping them visible.
         * Useful for temporarily preventing pagination interaction during operations.
         *
         * @default false
         */
        this.disablePaginator = input(false);
        /**
         * Trigger to reset pagination to first page.
         * When this input value changes, the fu-table resets `pageIndex` to 0
         * and emits a new query event. Useful for resetting pagination after filter changes.
         *
         * @example
         * ```typescript
         * resetTrigger = 0;
         * onFilterChange() {
         *   this.resetTrigger++;
         * }
         * ```
         * ```html
         * <fu-table [resetQuery]="resetTrigger">
         * ```
         */
        this.resetQuery = input();
        /**
         * When true, resets the query page index to 0 on component initialization.
         *
         * @default false
         */
        this.resetQueryOnInit = input(false);
        /**
         * Enables responsive mode.
         * When true, fu-table adapts its layout for mobile devices by stacking cell content.
         *
         * @default true
         */
        this.responsive = input(true);
        /**
         * Fixed scroll height in vh.
         * When provided, sets a maximum height for the fu-table scroll container.
         * Useful when `scrollable` is true.
         */
        this.scrollHeight = input();
        /**
         * Enables scrollable container with fixed height.
         * When true, the fu-table body becomes scrollable while headers remain fixed.
         *
         * @default true
         */
        this.scrollable = input(true);
        /**
         * Makes the header row sticky when scrolling.
         * Requires `scrollable` to be true to take effect.
         *
         * @default false
         */
        this.stickyHeader = input(false);
        /**
         * Makes the first column sticky when scrolling horizontally.
         * Useful for keeping identifier columns visible while scrolling.
         *
         * @default false
         */
        this.stickyFirstColumn = input(false);
        /**
         * Makes the last column sticky when scrolling horizontally.
         * Useful for keeping action columns visible while scrolling.
         *
         * @default false
         */
        this.stickyLastColumn = input(false);
        /**
         * Two-way bound row save state managed via `model`.
         *
         * Use two-way binding from the parent to control and observe the save
         * lifecycle for inline edits: `[(rowState)]="rowState"`.
         * Possible values: `'idle' | 'pending' | 'success' | 'error'`.
         *
         * @example
         * ```html
         * <fu-table
         *   [(rowState)]="rowState"
         *   (onRowEditComplete)="save($event)">
         * </fu-table>
         * ```
         * @example
         * ```ts
         *  rowState = signal('idle');
         *
         *  .subscribe({
         *      next: () => this.rowState.set('success'),
         *      error: () => this.rowState.set('error'),
         *  });
         * ```
         */
        this.rowState = model('idle');
        /**
         * Allows custom CSS classes to be applied to rows.
         */
        this.rowClass = input();
        /**
         * Allows inline styles to be applied to rows.
         */
        this.rowStyle = input();
        /**
         * Enables cursor pointer effect on row hover.
         */
        this.rowHoverEffect = input(false);
        /**
         * Options for page size selection in the paginator.
         */
        this.pageSizeOptions = input([5, 10, 15, 20]);
        /**
         * Initial page size for the paginator.
         */
        this.initPageSize = input(10);
        /**
         * Index of the currently expanded row.
         *
         * Model signal to expand/collapse a row programmatically.
         *
         * @default null
         */
        this.expandIndex = model(null);
        this.intl = inject(FuTableIntlService);
        this.responsiveConfig = linkedSignal(this.responsive);
        this.scrollHeightConfig = linkedSignal(this.scrollHeight);
        this.scrollableConfig = linkedSignal(this.scrollable);
        this.stickyHeaderConfig = linkedSignal(this.stickyHeader);
        this.stickyFirstColumnConfig = linkedSignal(this.stickyFirstColumn);
        this.stickyLastColumnConfig = linkedSignal(this.stickyLastColumn);
        this.toolbarTemplate = contentChild(FuTableToolbarTemplateDirective, {
            read: TemplateRef,
        });
        this.sidebarTemplate = contentChild(FuTableSidebarTemplateDirective, {
            read: TemplateRef,
        });
        this.noDataTemplate = contentChild(FuTableNoDataTemplateDirective, {
            read: TemplateRef,
        });
        this.expandRowTemplate = contentChild(FuTableExpandRowTemplateDirective, {
            read: TemplateRef,
        });
        this.cellContextMenuTemplate = contentChild(FuTableCellContextMenuTemplateDirective, {
            read: TemplateRef,
        });
        this.scrollContainer = viewChild('scrollContainer');
        /**
         * Emitted when the table requests new data (server-side mode).
         * Payload: `FuTableQuery` — `{ pageIndex, pageSize, sortField?, sortDirection? }`.
         */
        this.onQueryChanged = output();
        /**
         * Emitted when an editable cell value changes.
         * Payload: object mapping column field -> new value, e.g. `{ "user.name": "Alice" }`.
         */
        this.onCellEdited = output();
        /**
         * Emitted when columns are reordered or visibility is changed via the UI.
         * Payload: `FuColumnConfig[]` describing current order and visibility.
         */
        this.onColReorder = output();
        /**
         * Emitted when an inline row edit is submitted.
         * Payload: the edited row object of type `T`.
         */
        this.onRowEditComplete = output();
        /**
         * Emitted when a row is clicked/selected.
         * Payload: the clicked row object of type `T`.
         */
        this.onRowSelect = output();
        /**
         * Emitted when a row is deleted.
         * Payload: the deleted row object of type `T`.
         */
        this.onRowDelete = output();
        this.columns = signal([]);
        this.searchTerm = signal('');
        this.originalData = signal([]);
        this.pageIndex = signal(0);
        this.pageSize = linkedSignal(() => this.initPageSize());
        this.editingRowIndex = signal(null);
        this.pendingSaveRowIndex = signal(null);
        this.originalRowSnapshot = signal(null);
        this.pendingDeleteRowIndex = signal(null);
        this.rowStates = new Map();
        this.activeMatchIndex = signal(0);
        this.visibleCount = computed(() => this.columns().filter(c => c.visible()).length);
        this.initialLoading = computed(() => this.loading() && this.dataSource().length === 0);
        this.rowsLoading = computed(() => this.loading() &&
            this.pendingSaveRowIndex() === null &&
            this.pendingDeleteRowIndex() === null);
        this.isServerData = computed(() => this.totalItems() > this.dataSource().length);
        this.entriesLabel = computed(() => {
            const total = this.actualTotalItems();
            if (!total)
                return this.intl.noEntries();
            const start = this.pageIndex() * this.pageSize() + 1;
            const end = Math.min((this.pageIndex() + 1) * this.pageSize(), total);
            return this.intl.entriesLabel(start, end, total);
        });
        this.searchableVisibleColumns = computed(() => this.columns().filter(col => col.searchable() && col.visible()));
        this.filteredData = computed(() => {
            const term = this.searchTerm().toLowerCase();
            if (!term)
                return this.dataSource();
            const cols = this.searchableVisibleColumns();
            return this.dataSource().filter(row => cols.some(col => {
                const value = this.getCellValue(row, col.field());
                return this.toSearchString(value).toLowerCase().includes(term);
            }));
        });
        this.visibleRows = computed(() => {
            const data = this.filteredData();
            if (this.isServerData()) {
                return data;
            }
            const start = this.pageIndex() * this.pageSize();
            return data.slice(start, start + this.pageSize());
        });
        this.actualTotalItems = computed(() => {
            if (this.isServerData()) {
                return this.totalItems();
            }
            return this.filteredData().length;
        });
        this.skeletonRowCount = computed(() => this.pageSize());
        this.skeletonColumnCount = computed(() => this.visibleColumns().length + (this.expandRowTemplate() ? 1 : 0));
        this.totalPages = computed(() => Math.ceil(this.actualTotalItems() / this.pageSize()));
        this.visibleColumns = computed(() => this.columns().filter(col => col.visible()));
        this.activeSort = computed(() => {
            const col = this.columns().find(c => c.sortDirection() !== null);
            if (!col)
                return null;
            return {
                field: col.field(),
                sortKey: col.sortField() ?? col.field(),
                direction: col.sortDirection(),
            };
        });
        this.searchMatches = computed(() => {
            const term = this.searchTerm().toLowerCase();
            if (!term)
                return [];
            const rows = this.visibleRows();
            const columns = this.searchableVisibleColumns();
            const matches = [];
            rows.forEach((row, rowIndex) => {
                columns.forEach(col => {
                    const value = this.getCellValue(row, col.field());
                    if (this.toSearchString(value).toLowerCase().includes(term)) {
                        matches.push({ rowIndex, column: col });
                    }
                });
            });
            return matches;
        });
        this.activeSidebarPanel = signal(null);
        this.isSidebarOpen = computed(() => this.activeSidebarPanel() !== null);
        this.isColumnsOpen = computed(() => this.activeSidebarPanel() === 'columns');
        this.isLayoutOpen = computed(() => this.activeSidebarPanel() === 'layout');
        this.isCustomOpen = computed(() => this.activeSidebarPanel() === 'custom');
        this.searchColTerm = signal('');
        this.filteredColumns = computed(() => {
            const term = this.searchColTerm().toLowerCase().trim();
            if (!term)
                return this.columns();
            return this.columns().filter(col => col.description().toLowerCase().includes(term) ||
                col.header().toLowerCase().includes(term));
        });
        this.filteredHideable = computed(() => this.filteredColumns().filter(c => c.hideable()));
        this.filteredVisibleCount = computed(() => this.filteredHideable().filter(c => c.visible()).length);
        this.filteredTotalCount = computed(() => this.filteredHideable().length);
        this.selectAllChecked = computed(() => this.filteredTotalCount() > 0 &&
            this.filteredVisibleCount() === this.filteredTotalCount());
        this.selectAllIndeterminate = computed(() => this.filteredVisibleCount() > 0 &&
            this.filteredVisibleCount() < this.filteredTotalCount());
        // protected rowStylesPerColumn = computed(() => {
        //   const rows = this.visibleRows();
        //   const cols = this.visibleColumns();
        //   const rs = this.rowStyle();
        //   return rows.map((row, rowIndex) =>
        //     cols.map(col => {
        //       if (col.isAction()) return null;
        //       return typeof rs === 'function' ? rs(row, rowIndex) : (rs ?? null);
        //     })
        //   );
        // });
        this.resolvedRowStyles = computed(() => {
            this.editingRowIndex();
            const rows = this.visibleRows();
            const rs = this.rowStyle();
            return rows.map((row, i) => typeof rs === 'function' ? rs(row, i) : (rs ?? null));
        });
        this.resolvedRowClasses = computed(() => {
            this.editingRowIndex();
            const rows = this.visibleRows();
            const rc = this.rowClass();
            if (!rows?.length)
                return [];
            return rows.map((row, i) => typeof rc === 'function' ? rc(row, i) : (rc ?? ''));
        });
        this.persist = afterRenderEffect(() => {
            this.resetLayoutConfig();
            this.scrollableConfig();
            this.stickyHeaderConfig();
            this.stickyFirstColumnConfig();
            this.stickyLastColumnConfig();
            this.saveState();
        });
        this.activeMatchKey = signal(null);
        this.matchEffect = effect(() => {
            const match = this.searchMatches()[this.activeMatchIndex()];
            this.activeMatchKey.set(match ? `${match.rowIndex}:${match.column.field()}` : null);
        });
        this.editStateEffect = effect(() => {
            if (this.pendingSaveRowIndex() !== null && !this.loading()) {
                this.handleRowSaveResult();
            }
        });
        this.deleteInProgress = signal(false);
        this.deleteRowStateEffect = effect(() => {
            const index = this.pendingDeleteRowIndex();
            const loading = this.loading();
            if (index == null)
                return;
            // mark real delete start
            if (loading && !this.deleteInProgress()) {
                this.deleteInProgress.set(true);
                return;
            }
            // delete finished
            if (!loading && this.deleteInProgress()) {
                this.handleRowDeleteResult();
            }
        });
        this.hasRun = false;
        this.resetQueryEffect = effect(() => {
            this.resetQuery();
            const shouldEmit = this.hasRun || this.resetQueryOnInit();
            this.hasRun = true;
            if (!shouldEmit)
                return;
            untracked(() => {
                this.pageIndex.set(0);
                this.emitTableQuery();
            });
        });
        this.columnsInitialized = false;
        this.columnConfigEffect = effect(() => {
            if (this.columnsConfig().length && !this.columnsInitialized) {
                this.columnsInitialized = true;
                return;
            }
            untracked(() => {
                this.applyColumnsConfig();
            });
        });
        this.activeCell = null;
        this.isMobileScreen = signal(window.innerWidth < 900);
    }
    onResize(event) {
        const screenWidth = event.target.innerWidth;
        const smallScreen = screenWidth < 900;
        this.isMobileScreen.set(smallScreen);
    }
    ngOnChanges(changes) {
        if (changes['dataSource']) {
            this.originalData.set([...this.dataSource()]);
        }
    }
    ngAfterContentInit() {
        const persisted = this.loadState();
        // 1️⃣ restore query
        const query = persisted?.query;
        if (query) {
            this.pageIndex.set(query.pageIndex);
            this.pageSize.set(query.pageSize);
            this.searchTerm.set(query.searchTerm ?? '');
            this.restoreSort(query.sortField, query.sortDirection);
            this.applyClientSort();
        }
        // 2️⃣ restore columns
        const colsConfig = this.columnsConfig().length
            ? this.columnsConfig()
            : persisted?.columns;
        if (colsConfig) {
            this.applyColumnsConfig(colsConfig);
        }
        // 🔑 ui settings
        if (persisted?.ui) {
            this.responsiveConfig.set(persisted.ui.responsive);
            this.scrollableConfig.set(persisted.ui.scrollable);
            this.stickyHeaderConfig.set(persisted.ui.stickyHeader);
            this.stickyFirstColumnConfig.set(persisted.ui.stickyFirstColumn);
            this.stickyLastColumnConfig.set(persisted.ui.stickyLastColumn);
        }
        this.emitTableQuery(!this.resetQueryOnInit());
    }
    // protected resolveRowStyle(
    //   row: T,
    //   index: number
    // ): Record<string, string> | null {
    //   const rs = this.rowStyle();
    //   return typeof rs === 'function' ? rs(row, index) : (rs ?? null);
    // }
    // protected resolveRowClass(row: T, index: number): string | null {
    //   const rc = this.rowClass();
    //   return typeof rc === 'function' ? rc(row, index) : (rc ?? null);
    // }
    resetLayoutConfig() {
        if (this.scrollableConfig() === false) {
            this.scrollableConfig.set(false);
            this.stickyHeaderConfig.set(false);
            this.stickyFirstColumnConfig.set(false);
            this.stickyLastColumnConfig.set(false);
        }
    }
    loadState() {
        if (!this.stateKey())
            return null;
        try {
            const raw = localStorage.getItem(this.stateKey());
            return raw ? JSON.parse(raw) : null;
        }
        catch {
            return null;
        }
    }
    saveState() {
        if (!this.stateKey())
            return;
        const state = {
            query: {
                pageIndex: this.pageIndex(),
                pageSize: this.pageSize(),
                sortField: this.activeSort()?.field,
                sortDirection: this.activeSort()?.direction,
                searchTerm: this.searchTerm(),
            },
            columns: this.columns().map(col => ({
                field: col.field(),
                visible: col.visible(),
            })),
            ui: {
                responsive: this.responsiveConfig(),
                scrollable: this.scrollableConfig(),
                stickyHeader: this.stickyHeaderConfig(),
                stickyFirstColumn: this.stickyFirstColumnConfig(),
                stickyLastColumn: this.stickyLastColumnConfig(),
            },
        };
        localStorage.setItem(this.stateKey(), JSON.stringify(state));
    }
    toggleColumnsPanel() {
        this.activeSidebarPanel.update(p => (p === 'columns' ? null : 'columns'));
    }
    toggleLayoutPanel() {
        this.activeSidebarPanel.update(p => (p === 'layout' ? null : 'layout'));
    }
    toggleCustomPanel() {
        this.activeSidebarPanel.update(p => (p === 'custom' ? null : 'custom'));
    }
    applyColumnsConfig(config = this.columnsConfig()) {
        if (!config.length)
            return;
        const byField = new Map(this.columns().map(c => [c.field(), c]));
        const reordered = [];
        for (const cfg of config) {
            const col = byField.get(cfg.field);
            if (!col)
                continue;
            col.visible.set(cfg.visible !== false); // default true
            reordered.push(col);
            byField.delete(cfg.field);
        }
        // columns not mentioned in config → visible by default
        for (const col of byField.values()) {
            col.visible.set(true);
            reordered.push(col);
        }
        this.columns.set(reordered);
        this.saveState();
    }
    startEditRow(index, event) {
        event?.stopPropagation();
        this.resetEditRow();
        this.editingRowIndex.set(index);
        this.originalRowSnapshot.set(structuredClone(this.visibleRows()[index]));
        this.rowStates.set(index, 'pending');
    }
    saveEditRow(event) {
        event?.stopPropagation();
        if (this.editingRowIndex() === null)
            return;
        const row = this.visibleRows()[this.editingRowIndex()];
        this.pendingSaveRowIndex.set(this.editingRowIndex());
        this.editingRowIndex.set(null);
        this.onRowEditComplete.emit(row);
    }
    cancelEditRow(event) {
        event?.stopPropagation();
        if (this.editingRowIndex() === null || !this.originalRowSnapshot())
            return;
        Object.assign(this.visibleRows()[this.editingRowIndex()], this.originalRowSnapshot());
        //     this.filteredData.update(data => {
        //   const copy = [...data];
        //   copy[this.editingRowIndex!] = {
        //     ...copy[this.editingRowIndex!],
        //     ...this.originalRowSnapshot,
        //   };
        //   return copy;
        // });
        // this.rowStates.set(this.editingRowIndex()!, 'idle');
        this.rowStates.clear();
        this.editingRowIndex.set(null);
        this.originalRowSnapshot.set(null);
    }
    resetEditRow() {
        this.expandIndex.set(null);
        if (this.editingRowIndex() === null)
            return;
        this.pendingSaveRowIndex.set(null);
        this.editingRowIndex.set(null);
        this.originalRowSnapshot.set(null);
        this.rowStates.clear();
    }
    deleteRow(index, event) {
        event?.stopPropagation();
        const row = this.visibleRows()[index];
        if (!row)
            return;
        this.resetEditRow();
        this.pendingDeleteRowIndex.set(index);
        this.deleteInProgress.set(false);
        this.rowState.set('pending');
        this.onRowDelete.emit(row);
    }
    handleRowDeleteResult() {
        const result = this.rowState();
        if (this.pendingDeleteRowIndex() === null)
            return;
        if (result === 'error') {
            this.rowStates.set(this.pendingDeleteRowIndex(), 'error');
        }
        else {
            this.rowStates.clear();
        }
        this.deleteInProgress.set(false);
        this.pendingDeleteRowIndex.set(null);
        this.rowState.set('idle');
    }
    handleRowSaveResult() {
        const result = this.rowState();
        if (this.pendingSaveRowIndex() === null)
            return;
        const row = this.visibleRows()[this.pendingSaveRowIndex()];
        if (result === 'success') {
            this.rowStates.set(this.pendingSaveRowIndex(), 'success');
            this.originalRowSnapshot.set(null);
        }
        else if (result === 'error') {
            Object.assign(row, this.originalRowSnapshot());
            this.rowStates.set(this.pendingSaveRowIndex(), 'error');
            this.originalRowSnapshot.set(null);
        }
        else {
            this.originalRowSnapshot.set(null);
            this.rowStates.clear();
        }
        this.pendingSaveRowIndex.set(null);
    }
    onRowClick(row, event) {
        event.stopPropagation();
        this.onRowSelect.emit(row);
    }
    onEditAnimationEnd() {
        this.rowStates.clear();
        this.rowState.set('idle');
    }
    getCellValue(row, field) {
        if (!field)
            return null;
        return field
            .split('.')
            .reduce((acc, key) => acc?.[key], row);
    }
    toggleExpand(index, event) {
        event?.stopPropagation();
        this.expandIndex.update(i => (i === index ? null : index));
    }
    onSort(col, event) {
        event?.stopPropagation();
        this.activeMatchIndex.set(0);
        if (!col.isSortable())
            return;
        col.toggleSort();
        this.columns.update(cols => cols.map(c => {
            if (c.field() !== col.field()) {
                c.sortDirection.set(null);
            }
            return c;
        }));
        this.pageIndex.set(0);
        if (this.isServerData()) {
            this.emitTableQuery();
        }
        else {
            this.applyClientSort();
        }
        this.resetEditRow();
    }
    restoreOriginalOrder() {
        this.dataSource.set([...this.originalData()]);
    }
    applyClientSort() {
        const sort = this.activeSort();
        if (!sort) {
            this.restoreOriginalOrder();
            this.saveState();
            return;
        }
        const { field, direction } = sort;
        const dir = direction === 'asc' ? 1 : -1;
        this.dataSource.update(data => {
            const sorted = [...data].sort((a, b) => {
                const av = this.getCellValue(a, field);
                const bv = this.getCellValue(b, field);
                return this.compareValues(av, bv) * dir;
            });
            return sorted;
        });
        this.saveState();
    }
    compareValues(a, b) {
        if (a == null && b == null)
            return 0;
        if (a == null)
            return -1;
        if (b == null)
            return 1;
        if (typeof a === 'number' && typeof b === 'number') {
            return a - b;
        }
        return String(a).localeCompare(String(b));
    }
    emitTableQuery(emit = true) {
        if (!emit)
            return;
        this.onQueryChanged.emit({
            pageIndex: this.pageIndex(),
            pageSize: this.pageSize(),
            sortField: this.activeSort()?.sortKey,
            sortDirection: this.activeSort()?.direction,
        });
        this.saveState();
    }
    registerColumn(col) {
        this.columns.update(cols => [...cols, col]);
    }
    setCellValue(row, field, value) {
        const keys = field.split('.');
        const lastKey = keys.pop();
        const target = keys.reduce((acc, key) => {
            acc[key] ??= {};
            return acc[key];
        }, row);
        target[lastKey] = value;
    }
    onCellChange(row, col, value) {
        this.setCellValue(row, col.field(), value);
        this.onCellEdited.emit({ [col.field()]: value });
    }
    toSearchString(value) {
        if (value == null)
            return '';
        if (Array.isArray(value)) {
            return value.map(v => this.toSearchString(v)).join(' ');
        }
        if (typeof value === 'object') {
            return Object.values(value)
                .map(v => this.toSearchString(v))
                .join(' ');
        }
        return String(value);
    }
    onSearch(value) {
        this.searchTerm.set(value.toLowerCase());
        this.activeMatchIndex.set(0);
        this.pageIndex.set(0);
        this.saveState();
        this.resetEditRow();
    }
    nextMatch() {
        if (!this.searchMatches().length)
            return;
        this.activeMatchIndex.set((this.activeMatchIndex() + 1) % this.searchMatches().length);
        this.scrollToActiveMatch();
    }
    prevMatch() {
        if (!this.searchMatches().length)
            return;
        this.activeMatchIndex.set((this.activeMatchIndex() - 1 + this.searchMatches().length) %
            this.searchMatches().length);
        this.scrollToActiveMatch();
    }
    scrollToActiveMatch() {
        const match = this.searchMatches()[this.activeMatchIndex()];
        if (!match)
            return;
        const row = this.scrollContainer()?.nativeElement.querySelector(`tr[data-row-index="${match.rowIndex}"]`);
        row?.scrollIntoView({
            behavior: 'smooth',
            block: 'center',
        });
    }
    nextPage() {
        if (this.pageIndex() < this.totalPages() - 1) {
            this.pageIndex.update(val => val + 1);
            this.emitTableQuery();
            this.resetEditRow();
        }
    }
    prevPage() {
        if (this.pageIndex() > 0) {
            this.pageIndex.update(v => v - 1);
            this.emitTableQuery();
            this.resetEditRow();
        }
    }
    jumpToPage(input) {
        const previousValue = this.pageIndex() + 1;
        const inputValue = input.value.trim();
        const value = Number(inputValue);
        const min = Number(input.min);
        const max = Number(input.max);
        if (isNaN(value) || inputValue !== value.toString()) {
            input.value = previousValue.toString();
            return;
        }
        if (value < min) {
            input.value = min.toString();
            this.pageIndex.set(min - 1);
        }
        else if (value > max) {
            input.value = max.toString();
            this.pageIndex.set(max - 1);
        }
        else {
            this.pageIndex.set(value - 1);
        }
        this.emitTableQuery();
        this.resetEditRow();
    }
    adjustWidth(input) {
        input.style.width = this.calculateWidth(input.value) + 'px';
    }
    calculateWidth(value) {
        if (!value || value.toString().trim() === '') {
            return 28;
        }
        const length = value.toString().length;
        return length === 1 ? 28 : length === 2 ? 28 : 36;
    }
    onPageSizeChange(size) {
        this.pageSize.set(Number(size));
        this.pageIndex.set(0);
        this.emitTableQuery();
        this.resetEditRow();
    }
    toggleVisibility(col) {
        if (!col.hideable())
            return;
        if (this.visibleCount() === 3 && col.visible())
            return;
        col.visible.update(val => !val);
        this.emitColumns();
    }
    drop(event) {
        const prevIndex = event.previousIndex;
        const currIndex = event.currentIndex;
        const filtered = [...this.filteredColumns()]; // visible list
        // guard
        if (prevIndex < 0 ||
            currIndex < 0 ||
            prevIndex >= filtered.length ||
            currIndex >= filtered.length) {
            return;
        }
        // reorder the filtered copy according to user action
        moveItemInArray(filtered, prevIndex, currIndex);
        // build a new full array: replace each filtered item in the full array
        const full = [...this.columns()];
        const newFull = [];
        // pointer for walking over filtered items in their new order
        let fPtr = 0;
        const filteredIds = new Set(filtered.map(f => f.field()));
        for (const item of full) {
            if (filteredIds.has(item.field())) {
                // take next element from reordered filtered
                newFull.push(filtered[fPtr]);
                fPtr++;
            }
            else {
                // keep original items (not part of filtered) in their original relative positions
                newFull.push(item);
            }
        }
        // in case filtered items were all removed from full (edge-case), append remaining filtered
        while (fPtr < filtered.length) {
            newFull.push(filtered[fPtr++]);
        }
        // persist and emit
        this.columns.set(newFull);
        this.emitColumns();
    }
    emitColumns() {
        this.saveState();
        this.onColReorder.emit(this.columns().map(c => ({
            field: c.field(),
            visible: c.visible(),
        })));
    }
    restoreSort(sortField, sortDirection) {
        this.columns.update(cols => cols.map(col => {
            col.sortDirection.set(col.field() === sortField ? (sortDirection ?? null) : null);
            return col;
        }));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableComponent, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: FuTableComponent, isStandalone: true, selector: "fu-table", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null }, stateKey: { classPropertyName: "stateKey", publicName: "stateKey", isSignal: true, isRequired: false, transformFunction: null }, columnsConfig: { classPropertyName: "columnsConfig", publicName: "columnsConfig", isSignal: true, isRequired: false, transformFunction: null }, configPanel: { classPropertyName: "configPanel", publicName: "configPanel", isSignal: true, isRequired: false, transformFunction: null }, filterPanel: { classPropertyName: "filterPanel", publicName: "filterPanel", isSignal: true, isRequired: false, transformFunction: null }, paginator: { classPropertyName: "paginator", publicName: "paginator", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disablePaginator: { classPropertyName: "disablePaginator", publicName: "disablePaginator", isSignal: true, isRequired: false, transformFunction: null }, resetQuery: { classPropertyName: "resetQuery", publicName: "resetQuery", isSignal: true, isRequired: false, transformFunction: null }, resetQueryOnInit: { classPropertyName: "resetQueryOnInit", publicName: "resetQueryOnInit", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, scrollHeight: { classPropertyName: "scrollHeight", publicName: "scrollHeight", isSignal: true, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: true, isRequired: false, transformFunction: null }, stickyHeader: { classPropertyName: "stickyHeader", publicName: "stickyHeader", isSignal: true, isRequired: false, transformFunction: null }, stickyFirstColumn: { classPropertyName: "stickyFirstColumn", publicName: "stickyFirstColumn", isSignal: true, isRequired: false, transformFunction: null }, stickyLastColumn: { classPropertyName: "stickyLastColumn", publicName: "stickyLastColumn", isSignal: true, isRequired: false, transformFunction: null }, rowState: { classPropertyName: "rowState", publicName: "rowState", isSignal: true, isRequired: false, transformFunction: null }, rowClass: { classPropertyName: "rowClass", publicName: "rowClass", isSignal: true, isRequired: false, transformFunction: null }, rowStyle: { classPropertyName: "rowStyle", publicName: "rowStyle", isSignal: true, isRequired: false, transformFunction: null }, rowHoverEffect: { classPropertyName: "rowHoverEffect", publicName: "rowHoverEffect", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, initPageSize: { classPropertyName: "initPageSize", publicName: "initPageSize", isSignal: true, isRequired: false, transformFunction: null }, expandIndex: { classPropertyName: "expandIndex", publicName: "expandIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dataSource: "dataSourceChange", rowState: "rowStateChange", expandIndex: "expandIndexChange", onQueryChanged: "onQueryChanged", onCellEdited: "onCellEdited", onColReorder: "onColReorder", onRowEditComplete: "onRowEditComplete", onRowSelect: "onRowSelect", onRowDelete: "onRowDelete" }, host: { listeners: { "window:resize": "onResize($event)" } }, queries: [{ propertyName: "toolbarTemplate", first: true, predicate: FuTableToolbarTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "sidebarTemplate", first: true, predicate: FuTableSidebarTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "noDataTemplate", first: true, predicate: FuTableNoDataTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "expandRowTemplate", first: true, predicate: FuTableExpandRowTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "cellContextMenuTemplate", first: true, predicate: FuTableCellContextMenuTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, isSignal: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"fu-new-table-wrapper\">\r\n  @if (filterPanel()) {\r\n    <div class=\"fu-search\">\r\n      <input\r\n        type=\"search\"\r\n        [placeholder]=\"intl.searchPlaceholder()\"\r\n        [value]=\"searchTerm()\"\r\n        (input)=\"onSearch($any($event.target).value)\"\r\n      />\r\n      <div class=\"fu-search-nav\">\r\n        <button fuTButton (click)=\"prevMatch()\">\r\n          {{ intl.previous() }}\r\n        </button>\r\n        <button fuTButton (click)=\"nextMatch()\">\r\n          {{ intl.next() }}\r\n        </button>\r\n        @if (searchMatches().length > 0) {\r\n          <span class=\"fu-match-counter\">\r\n            {{ activeMatchIndex() + 1 }} / {{ searchMatches().length }}\r\n          </span>\r\n        }\r\n      </div>\r\n    </div>\r\n  }\r\n\r\n  @if (toolbarTemplate()) {\r\n    <div class=\"fu-table-toolbar\">\r\n      <ng-container [ngTemplateOutlet]=\"toolbarTemplate()!\" />\r\n    </div>\r\n  }\r\n\r\n  <div\r\n    class=\"fu-table-layout\"\r\n    [class.fu-with-sidebar]=\"configPanel() || sidebarTemplate()\"\r\n  >\r\n    <div\r\n      #scrollContainer\r\n      class=\"fu-table-scroll\"\r\n      [class.fu-scrollable]=\"scrollableConfig()\"\r\n      [style.max-height.vh]=\"scrollHeightConfig()\"\r\n    >\r\n      <table\r\n        class=\"fu-table\"\r\n        [class.fu-table--responsive]=\"responsiveConfig()\"\r\n        [class.fu-table-scrollable]=\"scrollableConfig()\"\r\n        [class.fu-sticky-header]=\"stickyHeaderConfig()\"\r\n        [class.fu-sticky-first]=\"stickyFirstColumnConfig()\"\r\n        [class.fu-sticky-last]=\"stickyLastColumnConfig()\"\r\n        [class.fu-has-overlay]=\"isSidebarOpen()\"\r\n      >\r\n        <thead>\r\n          <tr>\r\n            @if (expandRowTemplate()) {\r\n              <th class=\"fu-expand-header\"></th>\r\n            }\r\n            <!--  -->\r\n            @for (col of visibleColumns(); track $index) {\r\n              <th\r\n                (click)=\"onSort(col, $event)\"\r\n                [class.fu-sortable]=\"col.isSortable()\"\r\n                [style.width]=\"col.width()\"\r\n              >\r\n                <div class=\"fu-th-content\">\r\n                  @if (col.columnHeaderTemplate()) {\r\n                    <ng-container\r\n                      [ngTemplateOutlet]=\"col.columnHeaderTemplate()!\"\r\n                      [ngTemplateOutletContext]=\"{ index: $index }\"\r\n                    />\r\n                    @if (col.isSortable()) {\r\n                      <ng-container\r\n                        [ngTemplateOutlet]=\"defaultSortIcon\"\r\n                        [ngTemplateOutletContext]=\"{\r\n                          $implicit: col.sortDirection(),\r\n                        }\"\r\n                      />\r\n                    }\r\n                  } @else {\r\n                    <span class=\"fu-header-main\">\r\n                      <span\r\n                        class=\"fu-header-txt\"\r\n                        [class.has-desc]=\"!!col.description()\"\r\n                        [fuTooltip]=\"col.description() || ''\"\r\n                      >\r\n                        {{ col.header() }}\r\n                      </span>\r\n\r\n                      @if (col.isSortable()) {\r\n                        <ng-container\r\n                          [ngTemplateOutlet]=\"defaultSortIcon\"\r\n                          [ngTemplateOutletContext]=\"{\r\n                            $implicit: col.sortDirection(),\r\n                          }\"\r\n                        />\r\n                      }\r\n                    </span>\r\n                  }\r\n                  <!--  -->\r\n                  @if (col.columnHeaderAddonTemplate()) {\r\n                    <span class=\"fu-header-addon\">\r\n                      <ng-container\r\n                        [ngTemplateOutlet]=\"col.columnHeaderAddonTemplate()!\"\r\n                        [ngTemplateOutletContext]=\"{ index: $index }\"\r\n                      />\r\n                    </span>\r\n                  }\r\n                </div>\r\n              </th>\r\n            }\r\n          </tr>\r\n        </thead>\r\n\r\n        <tbody>\r\n          @if (initialLoading()) {\r\n            <ng-container [ngTemplateOutlet]=\"initialLoadingTemplate\" />\r\n          } @else {\r\n            <!--  -->\r\n            @for (row of visibleRows(); let rowIndex = $index; track rowIndex) {\r\n              @if (rowsLoading()) {\r\n                <ng-container [ngTemplateOutlet]=\"loadingTemplate\" />\r\n              } @else {\r\n                <tr\r\n                  [class.fu-cell-success]=\"\r\n                    rowStates.get(rowIndex) === 'success' && !loading()\r\n                  \"\r\n                  [class.fu-cell-error]=\"\r\n                    rowStates.get(rowIndex) === 'error' && !loading()\r\n                  \"\r\n                  [class.fu-row-expanded]=\"expandIndex() === rowIndex\"\r\n                  [class.fu-cursor-pointer]=\"rowHoverEffect()\"\r\n                  [attr.data-row-index]=\"rowIndex\"\r\n                  [class]=\"resolvedRowClasses()[rowIndex]\"\r\n                  (animationend)=\"onEditAnimationEnd()\"\r\n                  (click)=\"onRowClick(row, $event)\"\r\n                >\r\n                  @if (\r\n                    (expandRowTemplate() && !isMobileScreen()) ||\r\n                    (expandRowTemplate() &&\r\n                      isMobileScreen() &&\r\n                      !responsiveConfig())\r\n                  ) {\r\n                    <td\r\n                      class=\"fu-expand-cell\"\r\n                      [style]=\"resolvedRowStyles()[rowIndex]\"\r\n                      [attr.data-expand]=\"expandIndex() === rowIndex\"\r\n                      (click)=\"toggleExpand(rowIndex, $event)\"\r\n                    >\r\n                      <span class=\"fu-icon\">\r\n                        <svg\r\n                          xmlns=\"http://www.w3.org/2000/svg\"\r\n                          width=\"24\"\r\n                          height=\"24\"\r\n                          viewBox=\"0 0 24 24\"\r\n                        >\r\n                          <path\r\n                            fill=\"currentColor\"\r\n                            d=\"M10 6L8.59 7.41L13.17 12l-4.58 4.59L10 18l6-6z\"\r\n                          />\r\n                        </svg>\r\n                      </span>\r\n                    </td>\r\n                  }\r\n                  <!--  -->\r\n                  @for (\r\n                    col of visibleColumns();\r\n                    let colIndex = $index;\r\n                    track colIndex\r\n                  ) {\r\n                    @let isMatch =\r\n                      activeMatchKey() === rowIndex + ':' + col.field();\r\n                    @let cellValue = col.accessor(row);\r\n\r\n                    @if (pendingDeleteRowIndex() === rowIndex && loading()) {\r\n                      <td>\r\n                        <div class=\"fu-skeleton-cell\"></div>\r\n                      </td>\r\n                    } @else {\r\n                      <td\r\n                        #contextTrigger=\"cdkContextMenuTriggerFor\"\r\n                        [cdkContextMenuTriggerFor]=\"cellContextMenu\"\r\n                        [cdkContextMenuTriggerData]=\"{\r\n                          value: cellValue,\r\n                          row,\r\n                          colIndex: colIndex,\r\n                          rowIndex: rowIndex,\r\n                          trigger: contextTrigger,\r\n                        }\"\r\n                        [cdkContextMenuDisabled]=\"!cellContextMenuTemplate()\"\r\n                        (cdkContextMenuOpened)=\"\r\n                          activeCell = col.field() + '-' + rowIndex\r\n                        \"\r\n                        (cdkContextMenuClosed)=\"activeCell = null\"\r\n                        [class.fu-context-open]=\"\r\n                          activeCell === col.field() + '-' + rowIndex\r\n                        \"\r\n                        [class.fu-cell-pending]=\"\r\n                          pendingSaveRowIndex() === rowIndex && loading()\r\n                        \"\r\n                        [class.fu-cell-editing]=\"editingRowIndex() === rowIndex\"\r\n                        [class.fu-cell-sorting]=\"\r\n                          col.isSortable() && col.sortDirection() !== null\r\n                        \"\r\n                        [class.fu-active-match]=\"isMatch\"\r\n                        [style]=\"\r\n                          col.isAction() ? null : resolvedRowStyles()[rowIndex]\r\n                        \"\r\n                      >\r\n                        <div class=\"fu-header-text\">\r\n                          {{ col.description() || col.header() }}\r\n                        </div>\r\n\r\n                        @if (col.columnCellTemplate()) {\r\n                          <ng-container\r\n                            [ngTemplateOutlet]=\"col.columnCellTemplate()!\"\r\n                            [ngTemplateOutletContext]=\"{\r\n                              $implicit: cellValue,\r\n                              row: row,\r\n                              index: rowIndex,\r\n                              searchTerm: searchTerm(),\r\n                              searchable: col.searchable(),\r\n                              activeMatch: isMatch,\r\n                            }\"\r\n                            }\r\n                          />\r\n                        } @else if (col.columnActionsTemplate()) {\r\n                          <ng-container\r\n                            [ngTemplateOutlet]=\"col.columnActionsTemplate()!\"\r\n                            [ngTemplateOutletContext]=\"{\r\n                              row: row,\r\n                              index: rowIndex,\r\n                              editing: editingRowIndex() === rowIndex,\r\n                              expanded: expandIndex() === rowIndex,\r\n                              startEdit: startEditRow.bind(this),\r\n                              saveEdit: saveEditRow.bind(this),\r\n                              cancelEdit: cancelEditRow.bind(this),\r\n                              toggleExpand: toggleExpand.bind(this),\r\n                              deleteRow: deleteRow.bind(this),\r\n                            }\"\r\n                            }\r\n                          />\r\n                        } @else {\r\n                          <fu-cell\r\n                            [id]=\"'cell-' + rowIndex + '-' + colIndex\"\r\n                            [type]=\"col.type()\"\r\n                            [searchTerm]=\"searchTerm()\"\r\n                            [editable]=\"col.editable()\"\r\n                            [searchable]=\"col.searchable()\"\r\n                            [value]=\"cellValue\"\r\n                            [activeMatch]=\"isMatch\"\r\n                            [editing]=\"editingRowIndex() === rowIndex\"\r\n                            (cellValueChange)=\"onCellChange(row, col, $event)\"\r\n                          />\r\n                        }\r\n                      </td>\r\n                    }\r\n                  }\r\n                </tr>\r\n              }\r\n\r\n              @if (\r\n                expandRowTemplate() && isMobileScreen() && responsiveConfig()\r\n              ) {\r\n                <td\r\n                  class=\"fu-expand-cell\"\r\n                  [style]=\"resolvedRowStyles()[rowIndex]\"\r\n                  [attr.data-expand]=\"expandIndex() === rowIndex\"\r\n                  (click)=\"toggleExpand(rowIndex, $event)\"\r\n                >\r\n                  <span class=\"fu-icon\">\r\n                    <svg\r\n                      xmlns=\"http://www.w3.org/2000/svg\"\r\n                      width=\"24\"\r\n                      height=\"24\"\r\n                      viewBox=\"0 0 24 24\"\r\n                    >\r\n                      <path\r\n                        fill=\"currentColor\"\r\n                        d=\"M10 6L8.59 7.41L13.17 12l-4.58 4.59L10 18l6-6z\"\r\n                      />\r\n                    </svg>\r\n                  </span>\r\n                </td>\r\n              }\r\n\r\n              @if (expandIndex() === rowIndex) {\r\n                <tr>\r\n                  <td [attr.colspan]=\"columns().length + 1\">\r\n                    <ng-container\r\n                      [ngTemplateOutlet]=\"expandRowTemplate()!\"\r\n                      [ngTemplateOutletContext]=\"{\r\n                        $implicit: row,\r\n                        index: rowIndex,\r\n                        searchTerm: searchTerm(),\r\n                      }\"\r\n                    />\r\n                  </td>\r\n                </tr>\r\n              }\r\n            } @empty {\r\n              <tr class=\"fu-no-data-row\">\r\n                <td [attr.colspan]=\"columns().length + 1\">\r\n                  <ng-container\r\n                    [ngTemplateOutlet]=\"noDataTemplate() ?? defaultNoData\"\r\n                  />\r\n                </td>\r\n              </tr>\r\n            }\r\n          }\r\n        </tbody>\r\n      </table>\r\n    </div>\r\n\r\n    @if (configPanel() || sidebarTemplate()) {\r\n      <div\r\n        class=\"fu-sidebar\"\r\n        [class.fu-open]=\"isSidebarOpen()\"\r\n        (fuClickOutside)=\"activeSidebarPanel.set(null)\"\r\n      >\r\n        @if (isSidebarOpen()) {\r\n          <!-- Sidebar content -->\r\n          <div class=\"fu-content\">\r\n            @if (isColumnsOpen()) {\r\n              <ng-container [ngTemplateOutlet]=\"defaultSidebar\" />\r\n            } @else if (isLayoutOpen()) {\r\n              <ng-container [ngTemplateOutlet]=\"configSidebar\" />\r\n            } @else if (isCustomOpen()) {\r\n              <ng-container [ngTemplateOutlet]=\"sidebarTemplate()!\" />\r\n            }\r\n          </div>\r\n        }\r\n\r\n        <div class=\"fu-handle\">\r\n          @if (configPanel()) {\r\n            <button\r\n              fuTButton\r\n              variant=\"icon\"\r\n              [severity]=\"isColumnsOpen() ? 'primary' : null\"\r\n              (click)=\"toggleColumnsPanel()\"\r\n            >\r\n              <svg\r\n                xmlns=\"http://www.w3.org/2000/svg\"\r\n                width=\"24\"\r\n                height=\"24\"\r\n                viewBox=\"0 0 24 24\"\r\n              >\r\n                <path\r\n                  fill=\"currentColor\"\r\n                  d=\"M3.25 3a.75.75 0 0 0 0 1.5h.5C4.44 4.5 5 5.06 5 5.75v12.5c0 .69-.56 1.25-1.25 1.25h-.5a.75.75 0 0 0 0 1.5h.5a2.75 2.75 0 0 0 2.75-2.75V5.75A2.75 2.75 0 0 0 3.75 3zm7.5 0A2.75 2.75 0 0 0 8 5.75v12.5A2.75 2.75 0 0 0 10.75 21h.415l.356-1.423l.02-.077h-.791c-.69 0-1.25-.56-1.25-1.25V5.75c0-.69.56-1.25 1.25-1.25h2.5c.69 0 1.25.56 1.25 1.25v10.105l1.5-1.5V5.75A2.75 2.75 0 0 0 13.25 3zM19 11.483q-.325.198-.607.48l-.893.892V5.75A2.75 2.75 0 0 1 20.25 3h.5a.75.75 0 0 1 0 1.5h-.5c-.69 0-1.25.56-1.25 1.25zm.1 1.186l-5.903 5.903a2.7 2.7 0 0 0-.706 1.247l-.458 1.831a1.087 1.087 0 0 0 1.319 1.318l1.83-.457a2.7 2.7 0 0 0 1.248-.707l5.902-5.902A2.286 2.286 0 0 0 19.1 12.67\"\r\n                />\r\n              </svg>\r\n            </button>\r\n            <button\r\n              fuTButton\r\n              variant=\"icon\"\r\n              [severity]=\"isLayoutOpen() ? 'primary' : null\"\r\n              (click)=\"toggleLayoutPanel()\"\r\n            >\r\n              <svg\r\n                xmlns=\"http://www.w3.org/2000/svg\"\r\n                width=\"24\"\r\n                height=\"24\"\r\n                viewBox=\"0 0 24 24\"\r\n              >\r\n                <path\r\n                  fill=\"currentColor\"\r\n                  d=\"M21 13.1c-.1 0-.3.1-.4.2l-1 1l2.1 2.1l1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8l-6.1 6V23h2.1l6.1-6.1zM21 3h-8v6h8zm-2 4h-4V5h4zm-6 11.06V11h8v.1c-.76 0-1.43.4-1.81.79L18.07 13H15v3.07zM11 3H3v10h8zm-2 8H5V5h4zm2 9.06V15H3v6h8zM9 19H5v-2h4z\"\r\n                />\r\n              </svg>\r\n            </button>\r\n          }\r\n          @if (sidebarTemplate()) {\r\n            <button\r\n              fuTButton\r\n              variant=\"icon\"\r\n              [severity]=\"isCustomOpen() ? 'primary' : null\"\r\n              (click)=\"toggleCustomPanel()\"\r\n            >\r\n              <svg\r\n                xmlns=\"http://www.w3.org/2000/svg\"\r\n                width=\"24\"\r\n                height=\"24\"\r\n                viewBox=\"0 0 24 24\"\r\n              >\r\n                <path\r\n                  fill=\"currentColor\"\r\n                  d=\"M12 16c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2M6 16c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m12 12c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2\"\r\n                />\r\n              </svg>\r\n            </button>\r\n          }\r\n        </div>\r\n      </div>\r\n    }\r\n  </div>\r\n\r\n  @if (paginator()) {\r\n    <div class=\"fu-paginator\">\r\n      <div class=\"fu-paginator-entries\">\r\n        {{ entriesLabel() }}\r\n      </div>\r\n\r\n      <button\r\n        fuTButton\r\n        variant=\"icon\"\r\n        (click)=\"prevPage()\"\r\n        [disabled]=\"pageIndex() === 0 || disablePaginator()\"\r\n      >\r\n        <svg\r\n          xmlns=\"http://www.w3.org/2000/svg\"\r\n          width=\"24\"\r\n          height=\"24\"\r\n          viewBox=\"0 0 24 24\"\r\n        >\r\n          <path\r\n            fill=\"none\"\r\n            stroke=\"currentColor\"\r\n            stroke-linecap=\"round\"\r\n            stroke-linejoin=\"round\"\r\n            stroke-width=\"1.5\"\r\n            d=\"m14 7l-5 5l5 5\"\r\n          />\r\n        </svg>\r\n      </button>\r\n\r\n      <div class=\"fu-page-info\">\r\n        {{ intl.pageLabel() }}\r\n\r\n        <input\r\n          class=\"fu-page-jump\"\r\n          #pageInput\r\n          [min]=\"1\"\r\n          [max]=\"totalPages()\"\r\n          [value]=\"pageIndex() + 1\"\r\n          (input)=\"adjustWidth(pageInput)\"\r\n          (change)=\"jumpToPage(pageInput)\"\r\n          [disabled]=\"totalPages() === 0\"\r\n          [style.width.px]=\"calculateWidth(pageInput.value)\"\r\n        />\r\n        <span [style.margin-left.px]=\"4\">/</span>\r\n        <span [style.margin-left.px]=\"4\">{{ totalPages() }}</span>\r\n      </div>\r\n\r\n      <button\r\n        fuTButton\r\n        variant=\"icon\"\r\n        (click)=\"nextPage()\"\r\n        [disabled]=\"pageIndex() >= totalPages() - 1 || disablePaginator()\"\r\n      >\r\n        <svg\r\n          xmlns=\"http://www.w3.org/2000/svg\"\r\n          width=\"24\"\r\n          height=\"24\"\r\n          viewBox=\"0 0 24 24\"\r\n        >\r\n          <path\r\n            fill=\"none\"\r\n            stroke=\"currentColor\"\r\n            stroke-linecap=\"round\"\r\n            stroke-linejoin=\"round\"\r\n            stroke-width=\"1.5\"\r\n            d=\"m10 17l5-5l-5-5\"\r\n          />\r\n        </svg>\r\n      </button>\r\n\r\n      <select [(ngModel)]=\"pageSize\" (ngModelChange)=\"onPageSizeChange($event)\">\r\n        @for (size of pageSizeOptions(); track size) {\r\n          <option class=\"fu-option\" [value]=\"size\">{{ size }}</option>\r\n        }\r\n      </select>\r\n    </div>\r\n  }\r\n</div>\r\n\r\n<ng-template\r\n  #cellContextMenu\r\n  let-value=\"value\"\r\n  let-row=\"row\"\r\n  let-colIndex=\"colIndex\"\r\n  let-rowIndex=\"rowIndex\"\r\n  let-trigger=\"trigger\"\r\n>\r\n  <div cdkMenu class=\"fu-context-menu\">\r\n    <ng-container\r\n      *ngTemplateOutlet=\"\r\n        cellContextMenuTemplate()!;\r\n        context: { value, row, colIndex, rowIndex, trigger }\r\n      \"\r\n    />\r\n  </div>\r\n</ng-template>\r\n\r\n<ng-template #initialLoadingTemplate>\r\n  @for (\r\n    i of [].constructor(skeletonRowCount());\r\n    let rowIndex = $index;\r\n    track rowIndex\r\n  ) {\r\n    <tr class=\"fu-skeleton-row\">\r\n      @for (\r\n        j of [].constructor(skeletonColumnCount());\r\n        let colIndex = $index;\r\n        track colIndex\r\n      ) {\r\n        <td>\r\n          <div class=\"fu-skeleton-cell\"></div>\r\n        </td>\r\n      }\r\n    </tr>\r\n  }\r\n</ng-template>\r\n\r\n<ng-template #loadingTemplate>\r\n  <tr class=\"fu-skeleton-row\">\r\n    @for (\r\n      j of [].constructor(skeletonColumnCount());\r\n      let colIndex = $index;\r\n      track colIndex\r\n    ) {\r\n      <td>\r\n        <div class=\"fu-skeleton-cell\"></div>\r\n      </td>\r\n    }\r\n  </tr>\r\n</ng-template>\r\n\r\n<ng-template #defaultSortIcon let-direction>\r\n  <span class=\"fu-sort-icon\">\r\n    @if (!direction) {\r\n      <svg\r\n        class=\"fu-sort-icon-default\"\r\n        xmlns=\"http://www.w3.org/2000/svg\"\r\n        width=\"16\"\r\n        height=\"16\"\r\n        viewBox=\"0 0 24 24\"\r\n      >\r\n        <path\r\n          fill=\"none\"\r\n          stroke=\"currentColor\"\r\n          stroke-linecap=\"round\"\r\n          stroke-linejoin=\"round\"\r\n          stroke-width=\"2\"\r\n          d=\"m3 9l4-4l4 4M7 5v14m14-4l-4 4l-4-4m4 4V5\"\r\n        />\r\n      </svg>\r\n    }\r\n\r\n    @if (direction === 'asc') {\r\n      <svg\r\n        class=\"fu-sort-icon-active\"\r\n        xmlns=\"http://www.w3.org/2000/svg\"\r\n        width=\"16\"\r\n        height=\"16\"\r\n        viewBox=\"0 0 24 24\"\r\n      >\r\n        <path\r\n          fill=\"none\"\r\n          stroke=\"currentColor\"\r\n          stroke-linecap=\"round\"\r\n          stroke-linejoin=\"round\"\r\n          stroke-width=\"2\"\r\n          d=\"M4 6h7m-7 6h7m-7 6h9m2-9l3-3l3 3m-3-3v12\"\r\n        />\r\n      </svg>\r\n    }\r\n\r\n    @if (direction === 'desc') {\r\n      <svg\r\n        class=\"fu-sort-icon-active\"\r\n        xmlns=\"http://www.w3.org/2000/svg\"\r\n        width=\"16\"\r\n        height=\"16\"\r\n        viewBox=\"0 0 24 24\"\r\n      >\r\n        <path\r\n          fill=\"none\"\r\n          stroke=\"currentColor\"\r\n          stroke-linecap=\"round\"\r\n          stroke-linejoin=\"round\"\r\n          stroke-width=\"2\"\r\n          d=\"M4 6h9m-9 6h7m-7 6h7m4-3l3 3l3-3m-3-9v12\"\r\n        />\r\n      </svg>\r\n    }\r\n  </span>\r\n</ng-template>\r\n\r\n<ng-template #defaultNoData>\r\n  <div class=\"fu-no-data-default\">{{ intl.noData() }}</div>\r\n</ng-template>\r\n\r\n<ng-template #configSidebar>\r\n  <div class=\"fu-config-sidebar\">\r\n    <div class=\"fu-config-item\">\r\n      <label for=\"responsive\">{{ intl.responsiveLabel() }}</label>\r\n      <input id=\"responsive\" type=\"checkbox\" [(ngModel)]=\"responsiveConfig\" />\r\n    </div>\r\n\r\n    <div class=\"fu-config-item\">\r\n      <label for=\"scrollable\">{{ intl.scrollableLabel() }}</label>\r\n      <input id=\"scrollable\" type=\"checkbox\" [(ngModel)]=\"scrollableConfig\" />\r\n    </div>\r\n\r\n    @if (scrollHeight()) {\r\n      <div class=\"fu-config-item\">\r\n        <label for=\"stickyHeader\">{{ intl.lockHeaderLabel() }}</label>\r\n        <input\r\n          id=\"stickyHeader\"\r\n          type=\"checkbox\"\r\n          [(ngModel)]=\"stickyHeaderConfig\"\r\n          [disabled]=\"!scrollableConfig()\"\r\n        />\r\n      </div>\r\n    }\r\n\r\n    <div class=\"fu-config-item\">\r\n      <label for=\"stickyFirstColumn\">{{ intl.lockLeftLabel() }}</label>\r\n      <input\r\n        id=\"stickyFirstColumn\"\r\n        type=\"checkbox\"\r\n        [(ngModel)]=\"stickyFirstColumnConfig\"\r\n        [disabled]=\"!scrollableConfig()\"\r\n      />\r\n    </div>\r\n\r\n    <div class=\"fu-config-item\">\r\n      <label for=\"stickyLastColumn\">{{ intl.lockRightLabel() }}</label>\r\n      <input\r\n        id=\"stickyLastColumn\"\r\n        type=\"checkbox\"\r\n        [(ngModel)]=\"stickyLastColumnConfig\"\r\n        [disabled]=\"!scrollableConfig()\"\r\n      />\r\n    </div>\r\n  </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultSidebar>\r\n  <div class=\"fu-columns-panel\">\r\n    <div class=\"fu-column-search\">\r\n      <input\r\n        class=\"fu-column-search-input\"\r\n        type=\"text\"\r\n        [placeholder]=\"intl.searchPlaceholder()\"\r\n        [(ngModel)]=\"searchColTerm\"\r\n      />\r\n\r\n      <input\r\n        type=\"checkbox\"\r\n        [checked]=\"selectAllChecked()\"\r\n        [indeterminate]=\"selectAllIndeterminate()\"\r\n        (change)=\"toggleFilteredSelection($event)\"\r\n        [disabled]=\"filteredTotalCount() === 0\"\r\n        [style.marginRight.px]=\"8\"\r\n      />\r\n    </div>\r\n\r\n    <div\r\n      class=\"fu-drag-lock fu-drag-list\"\r\n      cdkDropList\r\n      cdkDropListOrientation=\"vertical\"\r\n      (cdkDropListDropped)=\"drop($event)\"\r\n    >\r\n      @for (col of filteredColumns(); track col.field(); let odd = $odd) {\r\n        <div\r\n          class=\"fu-column-item\"\r\n          cdkDrag\r\n          cdkDragLockAxis=\"y\"\r\n          cdkDragBoundary=\".fu-drag-lock\"\r\n          [cdkDragDisabled]=\"!col.reorderable()\"\r\n        >\r\n          <span\r\n            class=\"fu-drag-handle\"\r\n            cdkDragHandle\r\n            [style.color]=\"!col.reorderable() ? 'gray' : 'inherit'\"\r\n            [style.cursor]=\"!col.reorderable() ? 'not-allowed' : 'grab'\"\r\n            >\u2630</span\r\n          >\r\n\r\n          @if (col.description()) {\r\n            <div class=\"fu-column-item-label\">\r\n              <span class=\"fu-label\">{{ col.header() }}</span>\r\n              <span class=\"fu-sub-label\">{{ col.description() }}</span>\r\n            </div>\r\n          } @else {\r\n            <div class=\"fu-column-default\">\r\n              <span class=\"fu-label\" [style.min-height.px]=\"16\">{{\r\n                col.header()\r\n              }}</span>\r\n            </div>\r\n          }\r\n\r\n          <input\r\n            type=\"checkbox\"\r\n            [checked]=\"col.visible()\"\r\n            [disabled]=\"\r\n              !col.hideable() || (visibleCount() === 3 && col.visible())\r\n            \"\r\n            (change)=\"toggleVisibility(col)\"\r\n          />\r\n\r\n          <ng-template cdkDragPreview>\r\n            <div class=\"fu-drag-preview\">\r\n              <svg\r\n                class=\"fu-drag-icon\"\r\n                width=\"16px\"\r\n                height=\"16px\"\r\n                fill=\"currentColor\"\r\n                viewBox=\"0 0 25 25\"\r\n              >\r\n                <path\r\n                  d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\"\r\n                ></path>\r\n              </svg>\r\n              <div class=\"fu-drag-label\">{{ col.header() }}</div>\r\n            </div>\r\n          </ng-template>\r\n        </div>\r\n      }\r\n    </div>\r\n\r\n    <div class=\"fu-column-meta\">\r\n      {{ filteredVisibleCount() }} / {{ filteredTotalCount() }}\r\n      {{ intl.visible() }}\r\n    </div>\r\n  </div>\r\n</ng-template>\r\n", styles: [".fu-new-table-wrapper{--fu-table-bg: oklch(from var(--fu-surface) l c h);--fu-table-text: oklch(from var(--fu-text) l c h);--fu-table-text-secondary: oklch( from var(--fu-text) calc(l*.75) calc(c*.6) h );--fu-table-border: oklch(from var(--fu-border) l c h);--fu-table-input-bg: oklch(from var(--fu-surface) calc(l - .03) c h);--fu-table-header-bg: oklch(from var(--fu-surface) calc(l - .04) c h);--fu-table-header-text: oklch(from var(--fu-text) l c h);--fu-table-header-border: oklch(from var(--fu-border) calc(l - .02) c h);--fu-table-row-bg: oklch(from var(--fu-surface) l c h);--fu-table-row-hover-bg: oklch(from var(--fu-surface) calc(l - .035) c h);--fu-table-row-border: oklch(from var(--fu-border) l c h);--fu-table-row-striped-bg: oklch(from var(--fu-surface) calc(l - .02) c h);--fu-table-row-active-bg: oklch( from var(--fu-accent) calc(l + .3) calc(c/5) h );--fu-table-row-pending-bg: color-mix( in oklch, var(--fu-table-row-bg) 82%, oklch(from var(--fu-accent) calc(l + .06) calc(c*.08) h) 18% );--fu-table-sticky-shadow: color-mix( in oklch, oklch(from var(--fu-text) .2 0 0) 30%, transparent );--fu-table-sticky-bg: oklch(from var(--fu-surface) calc(l - .05) c h);--fu-table-sticky-border: oklch(from var(--fu-border) calc(l - .08) c h);--fu-skeleton-base: color-mix( in srgb, var(--fu-table-row-bg) 90%, var(--fu-text) 10% );--fu-skeleton-highlight: color-mix( in srgb, var(--fu-table-row-bg) 70%, var(--fu-text) 30% );--fu-table-cell-sorting-overlay: color-mix( in oklch, var(--fu-table-row-striped-bg) 76%, oklch(from var(--fu-accent) calc(l + .06) calc(c*.08) h) 24% );border:2px solid var(--fu-table-border);font-family:var(--fu-font-family);font-size:var(--fu-font-size)}.fu-table-scroll.fu-scrollable{width:100%;overflow-x:auto;overflow-y:auto}.fu-table-scroll{width:100%;overflow:hidden;min-height:255px}.fu-table{width:100%;border-collapse:separate;border-spacing:0;position:relative}.fu-table.fu-has-overlay:before{content:\"\";position:absolute;inset:0;background-color:oklch(from var(--fu-surface) calc(l - .1) c h/.1);z-index:5;pointer-events:none;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.fu-scrollable{overflow-x:auto;overflow-y:auto}.fu-table-scrollable{width:max-content;min-width:100%;table-layout:auto}.fu-sticky-header thead th{position:sticky;top:0;z-index:2;background:var(--fu-table-sticky-bg);border-bottom:1px solid var(--fu-table-sticky-border)}.fu-sticky-first th:first-child,.fu-sticky-first td:first-child{position:sticky;left:0;z-index:1;background:var(--fu-table-sticky-bg);border-right:1px solid var(--fu-table-sticky-border)}.fu-sticky-header.fu-sticky-first thead th:first-child{z-index:3}.fu-sticky-last th:last-child,.fu-sticky-last td:last-child{position:sticky;right:0;z-index:1;background:var(--fu-table-sticky-bg);border-left:1px solid var(--fu-table-sticky-border)}.fu-sticky-header.fu-sticky-last thead th:last-child{z-index:3}.fu-sticky-first td:first-child{box-shadow:4px 0 6px -2px var(--fu-table-sticky-shadow)}.fu-sticky-last td:last-child{box-shadow:-4px 0 6px -2px var(--fu-table-sticky-shadow)}.fu-sticky-header thead th{box-shadow:0 4px 6px -2px var(--fu-table-sticky-shadow)}tr{height:40px}tr.fu-cursor-pointer{cursor:pointer}th,td{padding:0 8px;background-color:var(--fu-table-bg);color:var(--fu-table-text);border-right:1px solid var(--fu-table-border);border-bottom:1px solid var(--fu-table-border);vertical-align:middle}th{text-align:left;vertical-align:middle}td .fu-icon{display:flex;justify-content:center;align-items:center;transition:transform .15s cubic-bezier(.4,0,.2,1);transform-origin:center}td[data-expand=true] .fu-icon{transform:rotate(90deg)}thead th{background-color:var(--fu-table-header-bg);border-top:2px solid var(--fu-table-border)}tr:nth-child(2n) td{background-color:var(--fu-table-row-striped-bg)}tbody tr:hover td{background-color:var(--fu-table-row-hover-bg)}th.fu-sortable{cursor:pointer;-webkit-user-select:none;user-select:none}th.fu-sortable:hover{background-color:var(--fu-table-row-hover-bg)}tbody td.fu-cell-sorting{position:relative;z-index:0}tbody td.fu-cell-sorting:before{content:\"\";position:absolute;inset:0;pointer-events:none;background:var(--fu-table-cell-sorting-overlay);opacity:.25;border-radius:0;z-index:-1}.fu-th-content{display:flex;align-items:center;gap:8px;min-width:0;position:relative}.fu-header-main{flex:1;min-width:0;display:inline-flex;align-items:center;gap:8px}.fu-header-txt{min-width:0;position:relative}.fu-header-txt.has-desc:before{content:\"(?)\";position:absolute;right:-7px;top:-7px;font-size:10px;color:var(--fu-accent)}.fu-header-addon{display:inline-flex;align-items:center;border-color:var(--fu-table-sticky-border)}.fu-paginator{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 16px;font-size:14px;background-color:var(--fu-table-bg);color:var(--fu-table-text)}.fu-page-info{white-space:nowrap;color:var(--fu-table-text)}.fu-page-jump{padding:0 4px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}.fu-page-info input:focus{border-color:var(--fu-table-sticky-border)}.fu-paginator select{height:32px;padding:4px 8px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);cursor:pointer;color:var(--fu-table-text)}.fu-paginator select:focus{border-color:var(--fu-table-sticky-border);outline:none}.fu-search{display:flex;align-items:center;padding:8px 16px;background-color:var(--fu-table-bg);gap:16px}.fu-search input[type=search]{width:25%;max-width:100%;padding:6px 10px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}.fu-search input[type=search]::placeholder{color:#999}.fu-search input[type=search]:focus{border-color:var(--fu-table-sticky-border)}.fu-table-toolbar{display:flex;align-items:center;padding:8px 16px;background-color:var(--fu-table-bg);gap:16px}tbody tr.fu-no-data-row td{text-align:center;padding:24px;background-color:var(--fu-table-bg);color:var(--fu-table-text);border-right-color:var(--fu-table-border);height:200px;pointer-events:none}.fu-no-data-default{font-style:italic}.fu-skeleton-row td{padding:10px 8px}.fu-skeleton-cell{height:18px;width:100%;border-radius:var(--fu-border-radius);background-image:linear-gradient(90deg,var(--fu-skeleton-base) 25%,var(--fu-skeleton-highlight) 37%,var(--fu-skeleton-base) 63%);background-size:400% 100%;animation:skeleton-loading 1.4s ease infinite}@media (prefers-reduced-motion: reduce){.fu-skeleton-cell{animation:none;opacity:.6}}@keyframes skeleton-loading{0%{background-position:100% 50%}to{background-position:0 50%}}tbody tr.fu-cell-error td{animation:flash-error 1.6s ease-out}@keyframes flash-error{0%{background-color:red}to{background-color:var(--fu-table-bg)}}tbody tr.fu-cell-success td{animation:flash-success 1.6s ease-out}@keyframes flash-success{0%{background-color:green}to{background-color:var(--fu-table-bg)}}tbody tr td.fu-cell-pending{pointer-events:none;animation:flash-pending 1.4s ease-in-out infinite}@keyframes flash-pending{0%,to{background-color:var(--fu-table-row-bg)}50%{background-color:var(--fu-table-row-pending-bg)}}.fu-table-layout{position:relative;background-color:var(--fu-table-bg)}.fu-table-layout.fu-with-sidebar{padding-right:43px}.fu-sidebar{position:absolute;right:0;bottom:0;top:0;width:41.5px;transition:width .25s ease;background-color:var(--fu-table-bg);border:2px solid var(--fu-table-border);border-right:none;overflow:hidden;display:grid;z-index:6}.fu-sidebar.fu-open{min-width:260px}.fu-handle{position:absolute;right:0;background-color:var(--fu-table-bg);height:100%;display:flex;flex-direction:column;align-items:center;gap:8px;padding:4px}.fu-content{border-right:2px solid var(--fu-table-border);position:absolute;height:100%;width:219px}.fu-columns-panel{display:flex;flex-direction:column;margin:4px 4px 0;position:absolute;height:100%}.fu-drag-list{overflow-y:auto}.fu-column-item{display:flex;align-items:center;gap:8px;padding:0 8px;margin-bottom:4px;background:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius)}.fu-column-item-label{display:flex;flex-direction:column;justify-content:center;flex:1;padding:2px 0;min-width:0;line-height:1.1;width:136px}.fu-sub-label{font-size:11px;color:gray;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-column-default{display:flex;align-items:center;flex:1;min-width:0;padding:6px 0}.fu-column-item:hover{background:var(--fu-table-row-hover-bg)}.fu-column-item .fu-drag-handle{cursor:grab;line-height:1}.fu-column-search{position:sticky;top:0;display:flex;background:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);margin-bottom:4px}.fu-column-search-input{padding:6px 8px;margin-right:8px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;width:100%}.fu-column-meta{position:sticky;bottom:0;display:flex;align-items:center;font-size:12px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);padding:4px 8px;margin-bottom:8px}.fu-config-item{background-color:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius)}.fu-config-item label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-header-text{display:none}@media (max-width: 900px){.fu-table--responsive.fu-table-scrollable{width:100%;min-width:100%;table-layout:fixed}.fu-table--responsive tr{display:flex;flex-wrap:wrap}.fu-table--responsive thead{display:none}.fu-table--responsive thead:has(tr .fu-sortable){display:flex}.fu-table--responsive thead tr{background-color:var(--fu-table-bg);border-bottom:2px solid var(--fu-table-border);border-right:1px solid var(--fu-table-border);width:100%;display:flex;gap:4px}.fu-table--responsive thead tr th{display:none}.fu-table--responsive thead tr .fu-sortable{padding:4px 8px;display:inline-flex;border-block:none;border-left:1px solid var(--fu-table-border);width:auto!important}.fu-table--responsive tbody{display:block}.fu-table--responsive tr{display:block;height:auto;margin-bottom:4px;border-top:2px solid var(--fu-table-border)}.fu-table--responsive tr.fu-row-expanded{margin-bottom:0}.fu-table--responsive th{display:block}.fu-table--responsive td{display:flex;align-items:center;justify-content:space-between;min-height:38px;border-bottom:1px solid var(--fu-table-border)}.fu-table--responsive .fu-header-text{display:block}.fu-search input[type=search]{flex:1}tbody tr.fu-no-data-row td{display:flex;justify-content:center;align-items:center}}.fu-outline-1{outline:1px solid var(--fu-table-border)}.fu-expand-cell{color:var(--fu-accent);cursor:pointer}.fu-search-nav{display:flex;gap:8px}.fu-match-counter{display:flex;align-items:center;margin-left:8px}.fu-expand-header{width:40px}.fu-header-addon{border-left:1px solid var(--fu-table-sticky-border);padding-left:8px;margin-left:8px}.fu-paginator-entries{margin-right:auto}.fu-sort-icon{display:flex;align-items:center;justify-content:center}.fu-sort-icon-default{color:gray}.fu-config-sidebar{display:flex;flex-direction:column;gap:4px;padding:4px}.fu-config-item{display:flex;gap:8px;justify-content:space-between;padding:8px;background-color:var(--fu-table-header-bg)}.fu-config-item:hover{background-color:var(--fu-table-row-hover-bg)}.fu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-drag-preview{display:flex;align-items:center;background:var(--fu-surface-muted);border:1px solid var(--fu-border);border-radius:var(--fu-border-radius);box-shadow:0 4px 6px -2px #00000059}.fu-drag-icon{margin:0 8px}.fu-drag-label{padding:6px 12px}.fu-context-menu{background:var(--fu-surface);border:1px solid var(--fu-border);border-radius:var(--fu-border-radius);box-shadow:0 3px 5px -1px #0003,0 6px 10px #00000024,0 1px 18px #0000001f;min-width:200px;max-width:280px;padding:8px 0}.fu-context-open{outline:2px solid var(--fu-accent, #1976d2);outline-offset:-2px}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--fu-table-bg);border-radius:10px}::-webkit-scrollbar-thumb{background:var(--fu-table-border);border-radius:10px}::-webkit-scrollbar-thumb:hover{background:#9ca3af}*{scrollbar-color:var(--fu-table-border) var(--fu-table-bg)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FuCellComponent, selector: "fu-cell", inputs: ["value", "id", "type", "editing", "editable", "searchTerm", "activeMatch", "loading", "searchable"], outputs: ["valueChange", "cellValueChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i3.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i3.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: FuClickOutsideDirective, selector: "[fuClickOutside]", outputs: ["fuClickOutside"] }, { kind: "directive", type: FuTooltipDirective, selector: "[fuTooltip]", inputs: ["fuTooltip"] }, { kind: "directive", type: CdkContextMenuTrigger, selector: "[cdkContextMenuTriggerFor]", inputs: ["cdkContextMenuTriggerFor", "cdkContextMenuPosition", "cdkContextMenuTriggerData", "cdkContextMenuDisabled"], outputs: ["cdkContextMenuOpened", "cdkContextMenuClosed"], exportAs: ["cdkContextMenuTriggerFor"] }, { kind: "directive", type: FuTButtonDirective, selector: "button[fuTButton], a[fuTButton]", inputs: ["variant", "severity", "loading", "disabled"] }, { kind: "directive", type: CdkMenu, selector: "[cdkMenu]", outputs: ["closed"], exportAs: ["cdkMenu"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableComponent, decorators: [{
            type: Component,
            args: [{ selector: 'fu-table', imports: [
                        CommonModule,
                        FuCellComponent,
                        FormsModule,
                        DragDropModule,
                        FuClickOutsideDirective,
                        FuTooltipDirective,
                        CdkContextMenuTrigger,
                        FuTButtonDirective,
                        CdkMenu,
                    ], template: "<div class=\"fu-new-table-wrapper\">\r\n  @if (filterPanel()) {\r\n    <div class=\"fu-search\">\r\n      <input\r\n        type=\"search\"\r\n        [placeholder]=\"intl.searchPlaceholder()\"\r\n        [value]=\"searchTerm()\"\r\n        (input)=\"onSearch($any($event.target).value)\"\r\n      />\r\n      <div class=\"fu-search-nav\">\r\n        <button fuTButton (click)=\"prevMatch()\">\r\n          {{ intl.previous() }}\r\n        </button>\r\n        <button fuTButton (click)=\"nextMatch()\">\r\n          {{ intl.next() }}\r\n        </button>\r\n        @if (searchMatches().length > 0) {\r\n          <span class=\"fu-match-counter\">\r\n            {{ activeMatchIndex() + 1 }} / {{ searchMatches().length }}\r\n          </span>\r\n        }\r\n      </div>\r\n    </div>\r\n  }\r\n\r\n  @if (toolbarTemplate()) {\r\n    <div class=\"fu-table-toolbar\">\r\n      <ng-container [ngTemplateOutlet]=\"toolbarTemplate()!\" />\r\n    </div>\r\n  }\r\n\r\n  <div\r\n    class=\"fu-table-layout\"\r\n    [class.fu-with-sidebar]=\"configPanel() || sidebarTemplate()\"\r\n  >\r\n    <div\r\n      #scrollContainer\r\n      class=\"fu-table-scroll\"\r\n      [class.fu-scrollable]=\"scrollableConfig()\"\r\n      [style.max-height.vh]=\"scrollHeightConfig()\"\r\n    >\r\n      <table\r\n        class=\"fu-table\"\r\n        [class.fu-table--responsive]=\"responsiveConfig()\"\r\n        [class.fu-table-scrollable]=\"scrollableConfig()\"\r\n        [class.fu-sticky-header]=\"stickyHeaderConfig()\"\r\n        [class.fu-sticky-first]=\"stickyFirstColumnConfig()\"\r\n        [class.fu-sticky-last]=\"stickyLastColumnConfig()\"\r\n        [class.fu-has-overlay]=\"isSidebarOpen()\"\r\n      >\r\n        <thead>\r\n          <tr>\r\n            @if (expandRowTemplate()) {\r\n              <th class=\"fu-expand-header\"></th>\r\n            }\r\n            <!--  -->\r\n            @for (col of visibleColumns(); track $index) {\r\n              <th\r\n                (click)=\"onSort(col, $event)\"\r\n                [class.fu-sortable]=\"col.isSortable()\"\r\n                [style.width]=\"col.width()\"\r\n              >\r\n                <div class=\"fu-th-content\">\r\n                  @if (col.columnHeaderTemplate()) {\r\n                    <ng-container\r\n                      [ngTemplateOutlet]=\"col.columnHeaderTemplate()!\"\r\n                      [ngTemplateOutletContext]=\"{ index: $index }\"\r\n                    />\r\n                    @if (col.isSortable()) {\r\n                      <ng-container\r\n                        [ngTemplateOutlet]=\"defaultSortIcon\"\r\n                        [ngTemplateOutletContext]=\"{\r\n                          $implicit: col.sortDirection(),\r\n                        }\"\r\n                      />\r\n                    }\r\n                  } @else {\r\n                    <span class=\"fu-header-main\">\r\n                      <span\r\n                        class=\"fu-header-txt\"\r\n                        [class.has-desc]=\"!!col.description()\"\r\n                        [fuTooltip]=\"col.description() || ''\"\r\n                      >\r\n                        {{ col.header() }}\r\n                      </span>\r\n\r\n                      @if (col.isSortable()) {\r\n                        <ng-container\r\n                          [ngTemplateOutlet]=\"defaultSortIcon\"\r\n                          [ngTemplateOutletContext]=\"{\r\n                            $implicit: col.sortDirection(),\r\n                          }\"\r\n                        />\r\n                      }\r\n                    </span>\r\n                  }\r\n                  <!--  -->\r\n                  @if (col.columnHeaderAddonTemplate()) {\r\n                    <span class=\"fu-header-addon\">\r\n                      <ng-container\r\n                        [ngTemplateOutlet]=\"col.columnHeaderAddonTemplate()!\"\r\n                        [ngTemplateOutletContext]=\"{ index: $index }\"\r\n                      />\r\n                    </span>\r\n                  }\r\n                </div>\r\n              </th>\r\n            }\r\n          </tr>\r\n        </thead>\r\n\r\n        <tbody>\r\n          @if (initialLoading()) {\r\n            <ng-container [ngTemplateOutlet]=\"initialLoadingTemplate\" />\r\n          } @else {\r\n            <!--  -->\r\n            @for (row of visibleRows(); let rowIndex = $index; track rowIndex) {\r\n              @if (rowsLoading()) {\r\n                <ng-container [ngTemplateOutlet]=\"loadingTemplate\" />\r\n              } @else {\r\n                <tr\r\n                  [class.fu-cell-success]=\"\r\n                    rowStates.get(rowIndex) === 'success' && !loading()\r\n                  \"\r\n                  [class.fu-cell-error]=\"\r\n                    rowStates.get(rowIndex) === 'error' && !loading()\r\n                  \"\r\n                  [class.fu-row-expanded]=\"expandIndex() === rowIndex\"\r\n                  [class.fu-cursor-pointer]=\"rowHoverEffect()\"\r\n                  [attr.data-row-index]=\"rowIndex\"\r\n                  [class]=\"resolvedRowClasses()[rowIndex]\"\r\n                  (animationend)=\"onEditAnimationEnd()\"\r\n                  (click)=\"onRowClick(row, $event)\"\r\n                >\r\n                  @if (\r\n                    (expandRowTemplate() && !isMobileScreen()) ||\r\n                    (expandRowTemplate() &&\r\n                      isMobileScreen() &&\r\n                      !responsiveConfig())\r\n                  ) {\r\n                    <td\r\n                      class=\"fu-expand-cell\"\r\n                      [style]=\"resolvedRowStyles()[rowIndex]\"\r\n                      [attr.data-expand]=\"expandIndex() === rowIndex\"\r\n                      (click)=\"toggleExpand(rowIndex, $event)\"\r\n                    >\r\n                      <span class=\"fu-icon\">\r\n                        <svg\r\n                          xmlns=\"http://www.w3.org/2000/svg\"\r\n                          width=\"24\"\r\n                          height=\"24\"\r\n                          viewBox=\"0 0 24 24\"\r\n                        >\r\n                          <path\r\n                            fill=\"currentColor\"\r\n                            d=\"M10 6L8.59 7.41L13.17 12l-4.58 4.59L10 18l6-6z\"\r\n                          />\r\n                        </svg>\r\n                      </span>\r\n                    </td>\r\n                  }\r\n                  <!--  -->\r\n                  @for (\r\n                    col of visibleColumns();\r\n                    let colIndex = $index;\r\n                    track colIndex\r\n                  ) {\r\n                    @let isMatch =\r\n                      activeMatchKey() === rowIndex + ':' + col.field();\r\n                    @let cellValue = col.accessor(row);\r\n\r\n                    @if (pendingDeleteRowIndex() === rowIndex && loading()) {\r\n                      <td>\r\n                        <div class=\"fu-skeleton-cell\"></div>\r\n                      </td>\r\n                    } @else {\r\n                      <td\r\n                        #contextTrigger=\"cdkContextMenuTriggerFor\"\r\n                        [cdkContextMenuTriggerFor]=\"cellContextMenu\"\r\n                        [cdkContextMenuTriggerData]=\"{\r\n                          value: cellValue,\r\n                          row,\r\n                          colIndex: colIndex,\r\n                          rowIndex: rowIndex,\r\n                          trigger: contextTrigger,\r\n                        }\"\r\n                        [cdkContextMenuDisabled]=\"!cellContextMenuTemplate()\"\r\n                        (cdkContextMenuOpened)=\"\r\n                          activeCell = col.field() + '-' + rowIndex\r\n                        \"\r\n                        (cdkContextMenuClosed)=\"activeCell = null\"\r\n                        [class.fu-context-open]=\"\r\n                          activeCell === col.field() + '-' + rowIndex\r\n                        \"\r\n                        [class.fu-cell-pending]=\"\r\n                          pendingSaveRowIndex() === rowIndex && loading()\r\n                        \"\r\n                        [class.fu-cell-editing]=\"editingRowIndex() === rowIndex\"\r\n                        [class.fu-cell-sorting]=\"\r\n                          col.isSortable() && col.sortDirection() !== null\r\n                        \"\r\n                        [class.fu-active-match]=\"isMatch\"\r\n                        [style]=\"\r\n                          col.isAction() ? null : resolvedRowStyles()[rowIndex]\r\n                        \"\r\n                      >\r\n                        <div class=\"fu-header-text\">\r\n                          {{ col.description() || col.header() }}\r\n                        </div>\r\n\r\n                        @if (col.columnCellTemplate()) {\r\n                          <ng-container\r\n                            [ngTemplateOutlet]=\"col.columnCellTemplate()!\"\r\n                            [ngTemplateOutletContext]=\"{\r\n                              $implicit: cellValue,\r\n                              row: row,\r\n                              index: rowIndex,\r\n                              searchTerm: searchTerm(),\r\n                              searchable: col.searchable(),\r\n                              activeMatch: isMatch,\r\n                            }\"\r\n                            }\r\n                          />\r\n                        } @else if (col.columnActionsTemplate()) {\r\n                          <ng-container\r\n                            [ngTemplateOutlet]=\"col.columnActionsTemplate()!\"\r\n                            [ngTemplateOutletContext]=\"{\r\n                              row: row,\r\n                              index: rowIndex,\r\n                              editing: editingRowIndex() === rowIndex,\r\n                              expanded: expandIndex() === rowIndex,\r\n                              startEdit: startEditRow.bind(this),\r\n                              saveEdit: saveEditRow.bind(this),\r\n                              cancelEdit: cancelEditRow.bind(this),\r\n                              toggleExpand: toggleExpand.bind(this),\r\n                              deleteRow: deleteRow.bind(this),\r\n                            }\"\r\n                            }\r\n                          />\r\n                        } @else {\r\n                          <fu-cell\r\n                            [id]=\"'cell-' + rowIndex + '-' + colIndex\"\r\n                            [type]=\"col.type()\"\r\n                            [searchTerm]=\"searchTerm()\"\r\n                            [editable]=\"col.editable()\"\r\n                            [searchable]=\"col.searchable()\"\r\n                            [value]=\"cellValue\"\r\n                            [activeMatch]=\"isMatch\"\r\n                            [editing]=\"editingRowIndex() === rowIndex\"\r\n                            (cellValueChange)=\"onCellChange(row, col, $event)\"\r\n                          />\r\n                        }\r\n                      </td>\r\n                    }\r\n                  }\r\n                </tr>\r\n              }\r\n\r\n              @if (\r\n                expandRowTemplate() && isMobileScreen() && responsiveConfig()\r\n              ) {\r\n                <td\r\n                  class=\"fu-expand-cell\"\r\n                  [style]=\"resolvedRowStyles()[rowIndex]\"\r\n                  [attr.data-expand]=\"expandIndex() === rowIndex\"\r\n                  (click)=\"toggleExpand(rowIndex, $event)\"\r\n                >\r\n                  <span class=\"fu-icon\">\r\n                    <svg\r\n                      xmlns=\"http://www.w3.org/2000/svg\"\r\n                      width=\"24\"\r\n                      height=\"24\"\r\n                      viewBox=\"0 0 24 24\"\r\n                    >\r\n                      <path\r\n                        fill=\"currentColor\"\r\n                        d=\"M10 6L8.59 7.41L13.17 12l-4.58 4.59L10 18l6-6z\"\r\n                      />\r\n                    </svg>\r\n                  </span>\r\n                </td>\r\n              }\r\n\r\n              @if (expandIndex() === rowIndex) {\r\n                <tr>\r\n                  <td [attr.colspan]=\"columns().length + 1\">\r\n                    <ng-container\r\n                      [ngTemplateOutlet]=\"expandRowTemplate()!\"\r\n                      [ngTemplateOutletContext]=\"{\r\n                        $implicit: row,\r\n                        index: rowIndex,\r\n                        searchTerm: searchTerm(),\r\n                      }\"\r\n                    />\r\n                  </td>\r\n                </tr>\r\n              }\r\n            } @empty {\r\n              <tr class=\"fu-no-data-row\">\r\n                <td [attr.colspan]=\"columns().length + 1\">\r\n                  <ng-container\r\n                    [ngTemplateOutlet]=\"noDataTemplate() ?? defaultNoData\"\r\n                  />\r\n                </td>\r\n              </tr>\r\n            }\r\n          }\r\n        </tbody>\r\n      </table>\r\n    </div>\r\n\r\n    @if (configPanel() || sidebarTemplate()) {\r\n      <div\r\n        class=\"fu-sidebar\"\r\n        [class.fu-open]=\"isSidebarOpen()\"\r\n        (fuClickOutside)=\"activeSidebarPanel.set(null)\"\r\n      >\r\n        @if (isSidebarOpen()) {\r\n          <!-- Sidebar content -->\r\n          <div class=\"fu-content\">\r\n            @if (isColumnsOpen()) {\r\n              <ng-container [ngTemplateOutlet]=\"defaultSidebar\" />\r\n            } @else if (isLayoutOpen()) {\r\n              <ng-container [ngTemplateOutlet]=\"configSidebar\" />\r\n            } @else if (isCustomOpen()) {\r\n              <ng-container [ngTemplateOutlet]=\"sidebarTemplate()!\" />\r\n            }\r\n          </div>\r\n        }\r\n\r\n        <div class=\"fu-handle\">\r\n          @if (configPanel()) {\r\n            <button\r\n              fuTButton\r\n              variant=\"icon\"\r\n              [severity]=\"isColumnsOpen() ? 'primary' : null\"\r\n              (click)=\"toggleColumnsPanel()\"\r\n            >\r\n              <svg\r\n                xmlns=\"http://www.w3.org/2000/svg\"\r\n                width=\"24\"\r\n                height=\"24\"\r\n                viewBox=\"0 0 24 24\"\r\n              >\r\n                <path\r\n                  fill=\"currentColor\"\r\n                  d=\"M3.25 3a.75.75 0 0 0 0 1.5h.5C4.44 4.5 5 5.06 5 5.75v12.5c0 .69-.56 1.25-1.25 1.25h-.5a.75.75 0 0 0 0 1.5h.5a2.75 2.75 0 0 0 2.75-2.75V5.75A2.75 2.75 0 0 0 3.75 3zm7.5 0A2.75 2.75 0 0 0 8 5.75v12.5A2.75 2.75 0 0 0 10.75 21h.415l.356-1.423l.02-.077h-.791c-.69 0-1.25-.56-1.25-1.25V5.75c0-.69.56-1.25 1.25-1.25h2.5c.69 0 1.25.56 1.25 1.25v10.105l1.5-1.5V5.75A2.75 2.75 0 0 0 13.25 3zM19 11.483q-.325.198-.607.48l-.893.892V5.75A2.75 2.75 0 0 1 20.25 3h.5a.75.75 0 0 1 0 1.5h-.5c-.69 0-1.25.56-1.25 1.25zm.1 1.186l-5.903 5.903a2.7 2.7 0 0 0-.706 1.247l-.458 1.831a1.087 1.087 0 0 0 1.319 1.318l1.83-.457a2.7 2.7 0 0 0 1.248-.707l5.902-5.902A2.286 2.286 0 0 0 19.1 12.67\"\r\n                />\r\n              </svg>\r\n            </button>\r\n            <button\r\n              fuTButton\r\n              variant=\"icon\"\r\n              [severity]=\"isLayoutOpen() ? 'primary' : null\"\r\n              (click)=\"toggleLayoutPanel()\"\r\n            >\r\n              <svg\r\n                xmlns=\"http://www.w3.org/2000/svg\"\r\n                width=\"24\"\r\n                height=\"24\"\r\n                viewBox=\"0 0 24 24\"\r\n              >\r\n                <path\r\n                  fill=\"currentColor\"\r\n                  d=\"M21 13.1c-.1 0-.3.1-.4.2l-1 1l2.1 2.1l1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8l-6.1 6V23h2.1l6.1-6.1zM21 3h-8v6h8zm-2 4h-4V5h4zm-6 11.06V11h8v.1c-.76 0-1.43.4-1.81.79L18.07 13H15v3.07zM11 3H3v10h8zm-2 8H5V5h4zm2 9.06V15H3v6h8zM9 19H5v-2h4z\"\r\n                />\r\n              </svg>\r\n            </button>\r\n          }\r\n          @if (sidebarTemplate()) {\r\n            <button\r\n              fuTButton\r\n              variant=\"icon\"\r\n              [severity]=\"isCustomOpen() ? 'primary' : null\"\r\n              (click)=\"toggleCustomPanel()\"\r\n            >\r\n              <svg\r\n                xmlns=\"http://www.w3.org/2000/svg\"\r\n                width=\"24\"\r\n                height=\"24\"\r\n                viewBox=\"0 0 24 24\"\r\n              >\r\n                <path\r\n                  fill=\"currentColor\"\r\n                  d=\"M12 16c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2M6 16c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m12 12c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2m0-6c1.1 0 2 .9 2 2s-.9 2-2 2s-2-.9-2-2s.9-2 2-2\"\r\n                />\r\n              </svg>\r\n            </button>\r\n          }\r\n        </div>\r\n      </div>\r\n    }\r\n  </div>\r\n\r\n  @if (paginator()) {\r\n    <div class=\"fu-paginator\">\r\n      <div class=\"fu-paginator-entries\">\r\n        {{ entriesLabel() }}\r\n      </div>\r\n\r\n      <button\r\n        fuTButton\r\n        variant=\"icon\"\r\n        (click)=\"prevPage()\"\r\n        [disabled]=\"pageIndex() === 0 || disablePaginator()\"\r\n      >\r\n        <svg\r\n          xmlns=\"http://www.w3.org/2000/svg\"\r\n          width=\"24\"\r\n          height=\"24\"\r\n          viewBox=\"0 0 24 24\"\r\n        >\r\n          <path\r\n            fill=\"none\"\r\n            stroke=\"currentColor\"\r\n            stroke-linecap=\"round\"\r\n            stroke-linejoin=\"round\"\r\n            stroke-width=\"1.5\"\r\n            d=\"m14 7l-5 5l5 5\"\r\n          />\r\n        </svg>\r\n      </button>\r\n\r\n      <div class=\"fu-page-info\">\r\n        {{ intl.pageLabel() }}\r\n\r\n        <input\r\n          class=\"fu-page-jump\"\r\n          #pageInput\r\n          [min]=\"1\"\r\n          [max]=\"totalPages()\"\r\n          [value]=\"pageIndex() + 1\"\r\n          (input)=\"adjustWidth(pageInput)\"\r\n          (change)=\"jumpToPage(pageInput)\"\r\n          [disabled]=\"totalPages() === 0\"\r\n          [style.width.px]=\"calculateWidth(pageInput.value)\"\r\n        />\r\n        <span [style.margin-left.px]=\"4\">/</span>\r\n        <span [style.margin-left.px]=\"4\">{{ totalPages() }}</span>\r\n      </div>\r\n\r\n      <button\r\n        fuTButton\r\n        variant=\"icon\"\r\n        (click)=\"nextPage()\"\r\n        [disabled]=\"pageIndex() >= totalPages() - 1 || disablePaginator()\"\r\n      >\r\n        <svg\r\n          xmlns=\"http://www.w3.org/2000/svg\"\r\n          width=\"24\"\r\n          height=\"24\"\r\n          viewBox=\"0 0 24 24\"\r\n        >\r\n          <path\r\n            fill=\"none\"\r\n            stroke=\"currentColor\"\r\n            stroke-linecap=\"round\"\r\n            stroke-linejoin=\"round\"\r\n            stroke-width=\"1.5\"\r\n            d=\"m10 17l5-5l-5-5\"\r\n          />\r\n        </svg>\r\n      </button>\r\n\r\n      <select [(ngModel)]=\"pageSize\" (ngModelChange)=\"onPageSizeChange($event)\">\r\n        @for (size of pageSizeOptions(); track size) {\r\n          <option class=\"fu-option\" [value]=\"size\">{{ size }}</option>\r\n        }\r\n      </select>\r\n    </div>\r\n  }\r\n</div>\r\n\r\n<ng-template\r\n  #cellContextMenu\r\n  let-value=\"value\"\r\n  let-row=\"row\"\r\n  let-colIndex=\"colIndex\"\r\n  let-rowIndex=\"rowIndex\"\r\n  let-trigger=\"trigger\"\r\n>\r\n  <div cdkMenu class=\"fu-context-menu\">\r\n    <ng-container\r\n      *ngTemplateOutlet=\"\r\n        cellContextMenuTemplate()!;\r\n        context: { value, row, colIndex, rowIndex, trigger }\r\n      \"\r\n    />\r\n  </div>\r\n</ng-template>\r\n\r\n<ng-template #initialLoadingTemplate>\r\n  @for (\r\n    i of [].constructor(skeletonRowCount());\r\n    let rowIndex = $index;\r\n    track rowIndex\r\n  ) {\r\n    <tr class=\"fu-skeleton-row\">\r\n      @for (\r\n        j of [].constructor(skeletonColumnCount());\r\n        let colIndex = $index;\r\n        track colIndex\r\n      ) {\r\n        <td>\r\n          <div class=\"fu-skeleton-cell\"></div>\r\n        </td>\r\n      }\r\n    </tr>\r\n  }\r\n</ng-template>\r\n\r\n<ng-template #loadingTemplate>\r\n  <tr class=\"fu-skeleton-row\">\r\n    @for (\r\n      j of [].constructor(skeletonColumnCount());\r\n      let colIndex = $index;\r\n      track colIndex\r\n    ) {\r\n      <td>\r\n        <div class=\"fu-skeleton-cell\"></div>\r\n      </td>\r\n    }\r\n  </tr>\r\n</ng-template>\r\n\r\n<ng-template #defaultSortIcon let-direction>\r\n  <span class=\"fu-sort-icon\">\r\n    @if (!direction) {\r\n      <svg\r\n        class=\"fu-sort-icon-default\"\r\n        xmlns=\"http://www.w3.org/2000/svg\"\r\n        width=\"16\"\r\n        height=\"16\"\r\n        viewBox=\"0 0 24 24\"\r\n      >\r\n        <path\r\n          fill=\"none\"\r\n          stroke=\"currentColor\"\r\n          stroke-linecap=\"round\"\r\n          stroke-linejoin=\"round\"\r\n          stroke-width=\"2\"\r\n          d=\"m3 9l4-4l4 4M7 5v14m14-4l-4 4l-4-4m4 4V5\"\r\n        />\r\n      </svg>\r\n    }\r\n\r\n    @if (direction === 'asc') {\r\n      <svg\r\n        class=\"fu-sort-icon-active\"\r\n        xmlns=\"http://www.w3.org/2000/svg\"\r\n        width=\"16\"\r\n        height=\"16\"\r\n        viewBox=\"0 0 24 24\"\r\n      >\r\n        <path\r\n          fill=\"none\"\r\n          stroke=\"currentColor\"\r\n          stroke-linecap=\"round\"\r\n          stroke-linejoin=\"round\"\r\n          stroke-width=\"2\"\r\n          d=\"M4 6h7m-7 6h7m-7 6h9m2-9l3-3l3 3m-3-3v12\"\r\n        />\r\n      </svg>\r\n    }\r\n\r\n    @if (direction === 'desc') {\r\n      <svg\r\n        class=\"fu-sort-icon-active\"\r\n        xmlns=\"http://www.w3.org/2000/svg\"\r\n        width=\"16\"\r\n        height=\"16\"\r\n        viewBox=\"0 0 24 24\"\r\n      >\r\n        <path\r\n          fill=\"none\"\r\n          stroke=\"currentColor\"\r\n          stroke-linecap=\"round\"\r\n          stroke-linejoin=\"round\"\r\n          stroke-width=\"2\"\r\n          d=\"M4 6h9m-9 6h7m-7 6h7m4-3l3 3l3-3m-3-9v12\"\r\n        />\r\n      </svg>\r\n    }\r\n  </span>\r\n</ng-template>\r\n\r\n<ng-template #defaultNoData>\r\n  <div class=\"fu-no-data-default\">{{ intl.noData() }}</div>\r\n</ng-template>\r\n\r\n<ng-template #configSidebar>\r\n  <div class=\"fu-config-sidebar\">\r\n    <div class=\"fu-config-item\">\r\n      <label for=\"responsive\">{{ intl.responsiveLabel() }}</label>\r\n      <input id=\"responsive\" type=\"checkbox\" [(ngModel)]=\"responsiveConfig\" />\r\n    </div>\r\n\r\n    <div class=\"fu-config-item\">\r\n      <label for=\"scrollable\">{{ intl.scrollableLabel() }}</label>\r\n      <input id=\"scrollable\" type=\"checkbox\" [(ngModel)]=\"scrollableConfig\" />\r\n    </div>\r\n\r\n    @if (scrollHeight()) {\r\n      <div class=\"fu-config-item\">\r\n        <label for=\"stickyHeader\">{{ intl.lockHeaderLabel() }}</label>\r\n        <input\r\n          id=\"stickyHeader\"\r\n          type=\"checkbox\"\r\n          [(ngModel)]=\"stickyHeaderConfig\"\r\n          [disabled]=\"!scrollableConfig()\"\r\n        />\r\n      </div>\r\n    }\r\n\r\n    <div class=\"fu-config-item\">\r\n      <label for=\"stickyFirstColumn\">{{ intl.lockLeftLabel() }}</label>\r\n      <input\r\n        id=\"stickyFirstColumn\"\r\n        type=\"checkbox\"\r\n        [(ngModel)]=\"stickyFirstColumnConfig\"\r\n        [disabled]=\"!scrollableConfig()\"\r\n      />\r\n    </div>\r\n\r\n    <div class=\"fu-config-item\">\r\n      <label for=\"stickyLastColumn\">{{ intl.lockRightLabel() }}</label>\r\n      <input\r\n        id=\"stickyLastColumn\"\r\n        type=\"checkbox\"\r\n        [(ngModel)]=\"stickyLastColumnConfig\"\r\n        [disabled]=\"!scrollableConfig()\"\r\n      />\r\n    </div>\r\n  </div>\r\n</ng-template>\r\n\r\n<ng-template #defaultSidebar>\r\n  <div class=\"fu-columns-panel\">\r\n    <div class=\"fu-column-search\">\r\n      <input\r\n        class=\"fu-column-search-input\"\r\n        type=\"text\"\r\n        [placeholder]=\"intl.searchPlaceholder()\"\r\n        [(ngModel)]=\"searchColTerm\"\r\n      />\r\n\r\n      <input\r\n        type=\"checkbox\"\r\n        [checked]=\"selectAllChecked()\"\r\n        [indeterminate]=\"selectAllIndeterminate()\"\r\n        (change)=\"toggleFilteredSelection($event)\"\r\n        [disabled]=\"filteredTotalCount() === 0\"\r\n        [style.marginRight.px]=\"8\"\r\n      />\r\n    </div>\r\n\r\n    <div\r\n      class=\"fu-drag-lock fu-drag-list\"\r\n      cdkDropList\r\n      cdkDropListOrientation=\"vertical\"\r\n      (cdkDropListDropped)=\"drop($event)\"\r\n    >\r\n      @for (col of filteredColumns(); track col.field(); let odd = $odd) {\r\n        <div\r\n          class=\"fu-column-item\"\r\n          cdkDrag\r\n          cdkDragLockAxis=\"y\"\r\n          cdkDragBoundary=\".fu-drag-lock\"\r\n          [cdkDragDisabled]=\"!col.reorderable()\"\r\n        >\r\n          <span\r\n            class=\"fu-drag-handle\"\r\n            cdkDragHandle\r\n            [style.color]=\"!col.reorderable() ? 'gray' : 'inherit'\"\r\n            [style.cursor]=\"!col.reorderable() ? 'not-allowed' : 'grab'\"\r\n            >\u2630</span\r\n          >\r\n\r\n          @if (col.description()) {\r\n            <div class=\"fu-column-item-label\">\r\n              <span class=\"fu-label\">{{ col.header() }}</span>\r\n              <span class=\"fu-sub-label\">{{ col.description() }}</span>\r\n            </div>\r\n          } @else {\r\n            <div class=\"fu-column-default\">\r\n              <span class=\"fu-label\" [style.min-height.px]=\"16\">{{\r\n                col.header()\r\n              }}</span>\r\n            </div>\r\n          }\r\n\r\n          <input\r\n            type=\"checkbox\"\r\n            [checked]=\"col.visible()\"\r\n            [disabled]=\"\r\n              !col.hideable() || (visibleCount() === 3 && col.visible())\r\n            \"\r\n            (change)=\"toggleVisibility(col)\"\r\n          />\r\n\r\n          <ng-template cdkDragPreview>\r\n            <div class=\"fu-drag-preview\">\r\n              <svg\r\n                class=\"fu-drag-icon\"\r\n                width=\"16px\"\r\n                height=\"16px\"\r\n                fill=\"currentColor\"\r\n                viewBox=\"0 0 25 25\"\r\n              >\r\n                <path\r\n                  d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\"\r\n                ></path>\r\n              </svg>\r\n              <div class=\"fu-drag-label\">{{ col.header() }}</div>\r\n            </div>\r\n          </ng-template>\r\n        </div>\r\n      }\r\n    </div>\r\n\r\n    <div class=\"fu-column-meta\">\r\n      {{ filteredVisibleCount() }} / {{ filteredTotalCount() }}\r\n      {{ intl.visible() }}\r\n    </div>\r\n  </div>\r\n</ng-template>\r\n", styles: [".fu-new-table-wrapper{--fu-table-bg: oklch(from var(--fu-surface) l c h);--fu-table-text: oklch(from var(--fu-text) l c h);--fu-table-text-secondary: oklch( from var(--fu-text) calc(l*.75) calc(c*.6) h );--fu-table-border: oklch(from var(--fu-border) l c h);--fu-table-input-bg: oklch(from var(--fu-surface) calc(l - .03) c h);--fu-table-header-bg: oklch(from var(--fu-surface) calc(l - .04) c h);--fu-table-header-text: oklch(from var(--fu-text) l c h);--fu-table-header-border: oklch(from var(--fu-border) calc(l - .02) c h);--fu-table-row-bg: oklch(from var(--fu-surface) l c h);--fu-table-row-hover-bg: oklch(from var(--fu-surface) calc(l - .035) c h);--fu-table-row-border: oklch(from var(--fu-border) l c h);--fu-table-row-striped-bg: oklch(from var(--fu-surface) calc(l - .02) c h);--fu-table-row-active-bg: oklch( from var(--fu-accent) calc(l + .3) calc(c/5) h );--fu-table-row-pending-bg: color-mix( in oklch, var(--fu-table-row-bg) 82%, oklch(from var(--fu-accent) calc(l + .06) calc(c*.08) h) 18% );--fu-table-sticky-shadow: color-mix( in oklch, oklch(from var(--fu-text) .2 0 0) 30%, transparent );--fu-table-sticky-bg: oklch(from var(--fu-surface) calc(l - .05) c h);--fu-table-sticky-border: oklch(from var(--fu-border) calc(l - .08) c h);--fu-skeleton-base: color-mix( in srgb, var(--fu-table-row-bg) 90%, var(--fu-text) 10% );--fu-skeleton-highlight: color-mix( in srgb, var(--fu-table-row-bg) 70%, var(--fu-text) 30% );--fu-table-cell-sorting-overlay: color-mix( in oklch, var(--fu-table-row-striped-bg) 76%, oklch(from var(--fu-accent) calc(l + .06) calc(c*.08) h) 24% );border:2px solid var(--fu-table-border);font-family:var(--fu-font-family);font-size:var(--fu-font-size)}.fu-table-scroll.fu-scrollable{width:100%;overflow-x:auto;overflow-y:auto}.fu-table-scroll{width:100%;overflow:hidden;min-height:255px}.fu-table{width:100%;border-collapse:separate;border-spacing:0;position:relative}.fu-table.fu-has-overlay:before{content:\"\";position:absolute;inset:0;background-color:oklch(from var(--fu-surface) calc(l - .1) c h/.1);z-index:5;pointer-events:none;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.fu-scrollable{overflow-x:auto;overflow-y:auto}.fu-table-scrollable{width:max-content;min-width:100%;table-layout:auto}.fu-sticky-header thead th{position:sticky;top:0;z-index:2;background:var(--fu-table-sticky-bg);border-bottom:1px solid var(--fu-table-sticky-border)}.fu-sticky-first th:first-child,.fu-sticky-first td:first-child{position:sticky;left:0;z-index:1;background:var(--fu-table-sticky-bg);border-right:1px solid var(--fu-table-sticky-border)}.fu-sticky-header.fu-sticky-first thead th:first-child{z-index:3}.fu-sticky-last th:last-child,.fu-sticky-last td:last-child{position:sticky;right:0;z-index:1;background:var(--fu-table-sticky-bg);border-left:1px solid var(--fu-table-sticky-border)}.fu-sticky-header.fu-sticky-last thead th:last-child{z-index:3}.fu-sticky-first td:first-child{box-shadow:4px 0 6px -2px var(--fu-table-sticky-shadow)}.fu-sticky-last td:last-child{box-shadow:-4px 0 6px -2px var(--fu-table-sticky-shadow)}.fu-sticky-header thead th{box-shadow:0 4px 6px -2px var(--fu-table-sticky-shadow)}tr{height:40px}tr.fu-cursor-pointer{cursor:pointer}th,td{padding:0 8px;background-color:var(--fu-table-bg);color:var(--fu-table-text);border-right:1px solid var(--fu-table-border);border-bottom:1px solid var(--fu-table-border);vertical-align:middle}th{text-align:left;vertical-align:middle}td .fu-icon{display:flex;justify-content:center;align-items:center;transition:transform .15s cubic-bezier(.4,0,.2,1);transform-origin:center}td[data-expand=true] .fu-icon{transform:rotate(90deg)}thead th{background-color:var(--fu-table-header-bg);border-top:2px solid var(--fu-table-border)}tr:nth-child(2n) td{background-color:var(--fu-table-row-striped-bg)}tbody tr:hover td{background-color:var(--fu-table-row-hover-bg)}th.fu-sortable{cursor:pointer;-webkit-user-select:none;user-select:none}th.fu-sortable:hover{background-color:var(--fu-table-row-hover-bg)}tbody td.fu-cell-sorting{position:relative;z-index:0}tbody td.fu-cell-sorting:before{content:\"\";position:absolute;inset:0;pointer-events:none;background:var(--fu-table-cell-sorting-overlay);opacity:.25;border-radius:0;z-index:-1}.fu-th-content{display:flex;align-items:center;gap:8px;min-width:0;position:relative}.fu-header-main{flex:1;min-width:0;display:inline-flex;align-items:center;gap:8px}.fu-header-txt{min-width:0;position:relative}.fu-header-txt.has-desc:before{content:\"(?)\";position:absolute;right:-7px;top:-7px;font-size:10px;color:var(--fu-accent)}.fu-header-addon{display:inline-flex;align-items:center;border-color:var(--fu-table-sticky-border)}.fu-paginator{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:8px 16px;font-size:14px;background-color:var(--fu-table-bg);color:var(--fu-table-text)}.fu-page-info{white-space:nowrap;color:var(--fu-table-text)}.fu-page-jump{padding:0 4px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}.fu-page-info input:focus{border-color:var(--fu-table-sticky-border)}.fu-paginator select{height:32px;padding:4px 8px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);cursor:pointer;color:var(--fu-table-text)}.fu-paginator select:focus{border-color:var(--fu-table-sticky-border);outline:none}.fu-search{display:flex;align-items:center;padding:8px 16px;background-color:var(--fu-table-bg);gap:16px}.fu-search input[type=search]{width:25%;max-width:100%;padding:6px 10px;font-size:14px;line-height:1.4;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;transition:border-color .15s,box-shadow .15s}.fu-search input[type=search]::placeholder{color:#999}.fu-search input[type=search]:focus{border-color:var(--fu-table-sticky-border)}.fu-table-toolbar{display:flex;align-items:center;padding:8px 16px;background-color:var(--fu-table-bg);gap:16px}tbody tr.fu-no-data-row td{text-align:center;padding:24px;background-color:var(--fu-table-bg);color:var(--fu-table-text);border-right-color:var(--fu-table-border);height:200px;pointer-events:none}.fu-no-data-default{font-style:italic}.fu-skeleton-row td{padding:10px 8px}.fu-skeleton-cell{height:18px;width:100%;border-radius:var(--fu-border-radius);background-image:linear-gradient(90deg,var(--fu-skeleton-base) 25%,var(--fu-skeleton-highlight) 37%,var(--fu-skeleton-base) 63%);background-size:400% 100%;animation:skeleton-loading 1.4s ease infinite}@media (prefers-reduced-motion: reduce){.fu-skeleton-cell{animation:none;opacity:.6}}@keyframes skeleton-loading{0%{background-position:100% 50%}to{background-position:0 50%}}tbody tr.fu-cell-error td{animation:flash-error 1.6s ease-out}@keyframes flash-error{0%{background-color:red}to{background-color:var(--fu-table-bg)}}tbody tr.fu-cell-success td{animation:flash-success 1.6s ease-out}@keyframes flash-success{0%{background-color:green}to{background-color:var(--fu-table-bg)}}tbody tr td.fu-cell-pending{pointer-events:none;animation:flash-pending 1.4s ease-in-out infinite}@keyframes flash-pending{0%,to{background-color:var(--fu-table-row-bg)}50%{background-color:var(--fu-table-row-pending-bg)}}.fu-table-layout{position:relative;background-color:var(--fu-table-bg)}.fu-table-layout.fu-with-sidebar{padding-right:43px}.fu-sidebar{position:absolute;right:0;bottom:0;top:0;width:41.5px;transition:width .25s ease;background-color:var(--fu-table-bg);border:2px solid var(--fu-table-border);border-right:none;overflow:hidden;display:grid;z-index:6}.fu-sidebar.fu-open{min-width:260px}.fu-handle{position:absolute;right:0;background-color:var(--fu-table-bg);height:100%;display:flex;flex-direction:column;align-items:center;gap:8px;padding:4px}.fu-content{border-right:2px solid var(--fu-table-border);position:absolute;height:100%;width:219px}.fu-columns-panel{display:flex;flex-direction:column;margin:4px 4px 0;position:absolute;height:100%}.fu-drag-list{overflow-y:auto}.fu-column-item{display:flex;align-items:center;gap:8px;padding:0 8px;margin-bottom:4px;background:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius)}.fu-column-item-label{display:flex;flex-direction:column;justify-content:center;flex:1;padding:2px 0;min-width:0;line-height:1.1;width:136px}.fu-sub-label{font-size:11px;color:gray;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-column-default{display:flex;align-items:center;flex:1;min-width:0;padding:6px 0}.fu-column-item:hover{background:var(--fu-table-row-hover-bg)}.fu-column-item .fu-drag-handle{cursor:grab;line-height:1}.fu-column-search{position:sticky;top:0;display:flex;background:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);margin-bottom:4px}.fu-column-search-input{padding:6px 8px;margin-right:8px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);outline:none;width:100%}.fu-column-meta{position:sticky;bottom:0;display:flex;align-items:center;font-size:12px;border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius);background-color:var(--fu-table-row-striped-bg);color:var(--fu-table-text);padding:4px 8px;margin-bottom:8px}.fu-config-item{background-color:var(--fu-table-header-bg);border:1px solid var(--fu-table-border);border-radius:var(--fu-border-radius)}.fu-config-item label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-header-text{display:none}@media (max-width: 900px){.fu-table--responsive.fu-table-scrollable{width:100%;min-width:100%;table-layout:fixed}.fu-table--responsive tr{display:flex;flex-wrap:wrap}.fu-table--responsive thead{display:none}.fu-table--responsive thead:has(tr .fu-sortable){display:flex}.fu-table--responsive thead tr{background-color:var(--fu-table-bg);border-bottom:2px solid var(--fu-table-border);border-right:1px solid var(--fu-table-border);width:100%;display:flex;gap:4px}.fu-table--responsive thead tr th{display:none}.fu-table--responsive thead tr .fu-sortable{padding:4px 8px;display:inline-flex;border-block:none;border-left:1px solid var(--fu-table-border);width:auto!important}.fu-table--responsive tbody{display:block}.fu-table--responsive tr{display:block;height:auto;margin-bottom:4px;border-top:2px solid var(--fu-table-border)}.fu-table--responsive tr.fu-row-expanded{margin-bottom:0}.fu-table--responsive th{display:block}.fu-table--responsive td{display:flex;align-items:center;justify-content:space-between;min-height:38px;border-bottom:1px solid var(--fu-table-border)}.fu-table--responsive .fu-header-text{display:block}.fu-search input[type=search]{flex:1}tbody tr.fu-no-data-row td{display:flex;justify-content:center;align-items:center}}.fu-outline-1{outline:1px solid var(--fu-table-border)}.fu-expand-cell{color:var(--fu-accent);cursor:pointer}.fu-search-nav{display:flex;gap:8px}.fu-match-counter{display:flex;align-items:center;margin-left:8px}.fu-expand-header{width:40px}.fu-header-addon{border-left:1px solid var(--fu-table-sticky-border);padding-left:8px;margin-left:8px}.fu-paginator-entries{margin-right:auto}.fu-sort-icon{display:flex;align-items:center;justify-content:center}.fu-sort-icon-default{color:gray}.fu-config-sidebar{display:flex;flex-direction:column;gap:4px;padding:4px}.fu-config-item{display:flex;gap:8px;justify-content:space-between;padding:8px;background-color:var(--fu-table-header-bg)}.fu-config-item:hover{background-color:var(--fu-table-row-hover-bg)}.fu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fu-drag-preview{display:flex;align-items:center;background:var(--fu-surface-muted);border:1px solid var(--fu-border);border-radius:var(--fu-border-radius);box-shadow:0 4px 6px -2px #00000059}.fu-drag-icon{margin:0 8px}.fu-drag-label{padding:6px 12px}.fu-context-menu{background:var(--fu-surface);border:1px solid var(--fu-border);border-radius:var(--fu-border-radius);box-shadow:0 3px 5px -1px #0003,0 6px 10px #00000024,0 1px 18px #0000001f;min-width:200px;max-width:280px;padding:8px 0}.fu-context-open{outline:2px solid var(--fu-accent, #1976d2);outline-offset:-2px}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--fu-table-bg);border-radius:10px}::-webkit-scrollbar-thumb{background:var(--fu-table-border);border-radius:10px}::-webkit-scrollbar-thumb:hover{background:#9ca3af}*{scrollbar-color:var(--fu-table-border) var(--fu-table-bg)}\n"] }]
        }], ctorParameters: () => [{ type: i0.Injector }], propDecorators: { onResize: [{
                type: HostListener,
                args: ['window:resize', ['$event']]
            }] } });

/**
 * Defines a custom cell template for a `fu-column`.
 *
 * The template context exposes:
 * - `value` – the current cell value
 * - `row` – the current row data
 * - `index` – row index
 * - `searchTerm` – current search term
 * - `activeMatch` – whether this cell matches the active search match
 *
 * ## Typing
 * To enable strong typing for `row`, provide the table data using `rowOf`.
 * This is used only for type inference and does not affect rendering.
 *
 * Usage:
 * ```html
 * <ng-template fuColumnCell let-value let-row="row" let-index="index">
 *   {{ value }}
 * </ng-template>
 * ```
 *
 * If `rowOf` is omitted, `row` will be typed as `any`.
 */
class FuColumnCellTemplateDirective {
    constructor() {
        /**
         * Provides typing context for the column cell template.
         * Used only for type inference – not consumed at runtime.
         */
        this.of = input(null, {
            alias: 'rowOf',
        });
    }
    static ngTemplateContextGuard(_dir, ctx) {
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuColumnCellTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: FuColumnCellTemplateDirective, isStandalone: true, selector: "[fuColumnCell]", inputs: { of: { classPropertyName: "of", publicName: "rowOf", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuColumnCellTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuColumnCell]',
                }]
        }] });

/**
 * Defines a custom header template for a `fu-column` header.
 *
 * Fully replaces default header content for a `fu-column` header.
 *
 * The template context exposes:
 * - `index` – current column index
 *
 * Usage:
 * ```html
 * <ng-template fuColumnHeader let-index="index">
 *   {{ index }}
 * </ng-template>
 * ```
 */
class FuColumnHeaderTemplateDirective {
    static ngTemplateContextGuard(_dir, ctx) {
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuColumnHeaderTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.6", type: FuColumnHeaderTemplateDirective, isStandalone: true, selector: "[fuColumnHeader]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuColumnHeaderTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuColumnHeader]',
                }]
        }] });

/**
 * Defines a custom header addon template for a `fu-column` header.
 *
 * Adds content to right side in default header for a `fu-column` header.
 *
 * The template context exposes:
 * - `index` – current column index
 *
 * Usage:
 * ```html
 * <ng-template fuColumnHeaderAddon let-index="index">
 *   {{ index }}
 * </ng-template>
 * ```
 */
class FuColumnHeaderAddonTemplateDirective {
    static ngTemplateContextGuard(_dir, ctx) {
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuColumnHeaderAddonTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.6", type: FuColumnHeaderAddonTemplateDirective, isStandalone: true, selector: "[fuColumnHeaderAddon]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuColumnHeaderAddonTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuColumnHeaderAddon]',
                }]
        }] });

/**
 * Defines a custom action template for a `fu-column`.
 *
 * This template is intended for rendering row-level actions
 * such as edit, save, cancel, or expand controls.
 *
 * The template context exposes:
 * - `row` – the current row data
 * - `index` – row index
 * - `editing` – whether the row is currently in edit mode
 * - `startEdit`, `saveEdit`, `cancelEdit` – row edit helpers
 * - `toggleExpand` – expands or collapses the row
 * - `deleteRow` – triggers onRowDelete event for the current row
 *
 * ## Event handling
 * If your table listens to row click events, interactive elements
 * inside this template should pass `$event` to helpers in order to
 * stop event propagation:
 *
 * ```html
 * <button (click)="startEdit(index, $event)">Edit</button>
 * ```
 *
 * ## Typing
 * To enable strong typing for `row`, provide the table data using `rowOf`.
 * This input is used only for type inference and does not affect rendering.
 *
 * ## Usage
 * ```html
 * <ng-template fuColumnActions let-index="index" let-startEdit="startEdit">
 *   <button (click)="startEdit(index, $event)">✏️</button>
 * </ng-template>
 * ```
 *
 *  * If `rowOf` is omitted, `row` will be typed as `any`.
 */
class FuColumnActionsTemplateDirective {
    constructor() {
        /**
         * Provides typing context for the column cell template.
         * Used only for type inference – not consumed at runtime.
         */
        this.of = input(null, {
            alias: 'rowOf',
        });
    }
    static ngTemplateContextGuard(_dir, ctx) {
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuColumnActionsTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: FuColumnActionsTemplateDirective, isStandalone: true, selector: "[fuColumnActions]", inputs: { of: { classPropertyName: "of", publicName: "rowOf", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuColumnActionsTemplateDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[fuColumnActions]',
                }]
        }] });

/**
 * Defines a column for use inside a `fu-table`.
 *
 * A `fu-column` describes how a single field of the row data is displayed,
 * sorted, edited, and configured.
 *
 * Columns can optionally provide custom templates for:
 * - header content
 * - header addon content
 * - data cell rendering
 * - row actions (edit, save, expand, etc.)
 *
 * Example:
 * ```html
 * <fu-table [data]="users">
 *   <fu-column field="name" header="Name" sortable editable />
 *
 *   <fu-column field="age" header="Age">
 *     <ng-template fuColumnCell let-value>
 *       {{ value }} years
 *     </ng-template>
 *   </fu-column>
 * </fu-table>
 * ```
 *
 * ## Visibility
 * The column visibility can be controlled in two ways:
 * - via the `visible` input on the column
 * - via `ColumnConfig` provided to `fu-table`
 *
 * If `ColumnConfig` is provided, it takes precedence over the column's
 * `visible` input.
 */
class FuColumnComponent {
    constructor(table) {
        /** Text displayed in the column header. */
        this.header = input('');
        /**
         * Optional descriptive text shown in the column configuration panel.
         * (drag & drop / visibility settings).
         *
         * Also used as tooltip text for the column header in the table.
         */
        this.description = input('');
        /**
         * Path to the value in the row object used by this column.
         *
         * Supports dot-notation for nested values (e.g. `address.city`).
         */
        this.field = input.required();
        /**
         * Control type used when the column is editable.
         *
         * If not provided, the control type is inferred from the cell value
         * using `typeof` (e.g. `string`, `number`, `boolean`).
         *
         * ⚠️ Note: Date values cannot be reliably inferred from the value.
         *
         * ⚠️ When editing date fields, it is recommended to explicitly set `type="date"`.
         *
         * The control type determines which editor is rendered for the cell.
         */
        this.type = input();
        /**
         * CSS width of the column (e.g. `120px`, `20%`, `auto`).
         * Defaults to `auto`.
         */
        this.width = input('auto');
        /**
         * Whether the column can be sorted.
         *
         * When enabled, clicking the column header toggles sort direction.
         *
         * Does not need to be set if `sortField` is provided.
         */
        this.sortable = input(false, {
            transform: booleanAttribute,
        });
        /**
         * Optional backend sort key.
         *
         * When provided, this value is emitted in sort queries instead of `field`.
         * Useful when the backend expects enum values, aliases, or different field names.
         *
         * If omitted, `field` is used.
         */
        this.sortField = input(null);
        /**
         * Whether cells in this column can be edited.
         *
         * Editing behavior depends on the configured control type and templates.
         */
        this.editable = input(false, {
            transform: booleanAttribute,
        });
        /**
         * Whether the column can be hidden via table configuration UI
         * (e.g. sidebar or column visibility controls).
         */
        this.hideable = input(true);
        /**
         * Whether the column can be reordered via drag-and-drop
         * or other column reordering mechanisms.
         */
        this.reorderable = input(true);
        /**
         * Whether the column is searchable for local filtering.
         *
         * When enabled, the table's search functionality includes this column
         * when filtering rows based on the search term.
         */
        this.searchable = input(true);
        /**
         * Controls whether the column is initially visible.
         *
         * Note:
         * If `ColumnConfig` is provided to `fu-table`, the visibility defined
         * there takes precedence over this value.
         */
        this.visible = model(true);
        /**
         * Marks the column as an action column.
         *
         * Action columns typically contain interactive elements such as buttons or links.
         *
         * These columns are excluded from row-level styling (e.g. rowClass, rowStyle).
         *
         * * Defaults to `false`.
         */
        this.isAction = input(false, {
            transform: booleanAttribute,
        });
        this.isSortable = computed(() => {
            return this.sortable() || this.sortField() !== null;
        });
        this.sortDirection = signal(null);
        this.columnCellTemplate = contentChild(FuColumnCellTemplateDirective, {
            read: TemplateRef,
        });
        this.columnHeaderAddonTemplate = contentChild(FuColumnHeaderAddonTemplateDirective, {
            read: TemplateRef,
        });
        this.columnHeaderTemplate = contentChild(FuColumnHeaderTemplateDirective, {
            read: TemplateRef,
        });
        this.columnActionsTemplate = contentChild(FuColumnActionsTemplateDirective, {
            read: TemplateRef,
        });
        table.registerColumn(this);
    }
    ngOnInit() {
        this.accessor = this.buildAccessor(this.field());
    }
    toggleSort() {
        const current = this.sortDirection();
        this.sortDirection.set(current === 'asc' ? 'desc' : current === 'desc' ? null : 'asc');
    }
    buildAccessor(path) {
        const keys = path.split('.');
        return (row) => {
            let v = row;
            for (const k of keys) {
                v = v?.[k];
                if (v == null)
                    return null;
            }
            return v;
        };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuColumnComponent, deps: [{ token: FuTableComponent }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.0.6", type: FuColumnComponent, isStandalone: true, selector: "fu-column", inputs: { header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, sortField: { classPropertyName: "sortField", publicName: "sortField", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, hideable: { classPropertyName: "hideable", publicName: "hideable", isSignal: true, isRequired: false, transformFunction: null }, reorderable: { classPropertyName: "reorderable", publicName: "reorderable", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, isAction: { classPropertyName: "isAction", publicName: "isAction", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange" }, queries: [{ propertyName: "columnCellTemplate", first: true, predicate: FuColumnCellTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "columnHeaderAddonTemplate", first: true, predicate: FuColumnHeaderAddonTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "columnHeaderTemplate", first: true, predicate: FuColumnHeaderTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "columnActionsTemplate", first: true, predicate: FuColumnActionsTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "\r\n", styles: [""] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuColumnComponent, decorators: [{
            type: Component,
            args: [{ selector: 'fu-column', imports: [], template: "\r\n" }]
        }], ctorParameters: () => [{ type: FuTableComponent }] });

class FuTableModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.6", ngImport: i0, type: FuTableModule, imports: [FuTableComponent,
            FuColumnComponent,
            FuColumnCellTemplateDirective,
            FuColumnActionsTemplateDirective,
            FuColumnHeaderTemplateDirective,
            FuColumnHeaderAddonTemplateDirective,
            FuTableCellContextMenuTemplateDirective,
            FuTableExpandRowTemplateDirective,
            FuTableNoDataTemplateDirective,
            FuTableSidebarTemplateDirective,
            FuTableToolbarTemplateDirective,
            FuTButtonDirective,
            FuHighlightDirective], exports: [FuTableComponent,
            FuColumnComponent,
            FuColumnCellTemplateDirective,
            FuColumnActionsTemplateDirective,
            FuColumnHeaderTemplateDirective,
            FuColumnHeaderAddonTemplateDirective,
            FuTableCellContextMenuTemplateDirective,
            FuTableExpandRowTemplateDirective,
            FuTableNoDataTemplateDirective,
            FuTableSidebarTemplateDirective,
            FuTableToolbarTemplateDirective,
            FuTButtonDirective,
            FuHighlightDirective] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableModule, imports: [FuTableComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuTableModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [],
                    imports: [
                        FuTableComponent,
                        FuColumnComponent,
                        FuColumnCellTemplateDirective,
                        FuColumnActionsTemplateDirective,
                        FuColumnHeaderTemplateDirective,
                        FuColumnHeaderAddonTemplateDirective,
                        FuTableCellContextMenuTemplateDirective,
                        FuTableExpandRowTemplateDirective,
                        FuTableNoDataTemplateDirective,
                        FuTableSidebarTemplateDirective,
                        FuTableToolbarTemplateDirective,
                        FuTButtonDirective,
                        FuHighlightDirective,
                    ],
                    exports: [
                        FuTableComponent,
                        FuColumnComponent,
                        FuColumnCellTemplateDirective,
                        FuColumnActionsTemplateDirective,
                        FuColumnHeaderTemplateDirective,
                        FuColumnHeaderAddonTemplateDirective,
                        FuTableCellContextMenuTemplateDirective,
                        FuTableExpandRowTemplateDirective,
                        FuTableNoDataTemplateDirective,
                        FuTableSidebarTemplateDirective,
                        FuTableToolbarTemplateDirective,
                        FuTButtonDirective,
                        FuHighlightDirective,
                    ],
                }]
        }] });

/**
 * Highlights occurrences of a search term inside a string by wrapping matches
 * in a `<mark>` element.
 *
 * This pipe is primarily intended for use with table cells and search results.
 * It returns an HTML string and is typically used together with `[innerHTML]`.
 *
 * ## Parameters
 * - `value` – the text value to highlight
 * - `term` – the search term to highlight
 * - `active` (optional) – whether the match should be marked as the active match
 *
 * If `term` is empty or `value` is `null`/`undefined`, the original value is
 * returned as a string.
 *
 * Special characters in the search term are safely escaped.
 *
 * ## Usage
 * ```html
 * <span
 *   [innerHTML]="value | fuHighlight : searchTerm : isActive"
 * ></span>
 * ```
 *
 * ## Styling
 * The pipe adds the following CSS classes:
 * - `search-highlight` – applied to all matches
 * - `search-highlight active` – applied when `active` is `true`
 *
 * Example:
 * ```css
 * .search-highlight {
 *   background-color: var(--fu-search-highlight-bg);
 * }
 *
 * .search-highlight.active {
 *   background-color: var(--fu-search-highlight-active-bg);
 * }
 * ```
 *
 * ## Notes
 * - This pipe returns **HTML**, not plain text.
 * - Always bind using `[innerHTML]`.
 * - The pipe is stateless and does not manage search state internally.
 */
class FuHighlightPipe {
    /**
     * Highlights occurrences of `term` in `value` by wrapping them in `<mark>`.
     *
     * @param value Text to transform
     * @param term Search term to highlight
     * @param active Whether the match is the active one
     * @returns HTML string with highlighted matches
     */
    transform(value, term, active = false) {
        if (!term || value == null) {
            return String(value ?? '');
        }
        const escaped = term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        const regex = new RegExp(`(${escaped})`, 'gi');
        return String(value).replace(regex, match => active
            ? `<mark class="search-highlight active">${match}</mark>`
            : `<mark class="search-highlight">${match}</mark>`);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuHighlightPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.6", ngImport: i0, type: FuHighlightPipe, isStandalone: true, name: "fuHighlight" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: FuHighlightPipe, decorators: [{
            type: Pipe,
            args: [{ name: 'fuHighlight' }]
        }] });

/**
 * Creates a row class resolver that maps a row's field value to a CSS class name.
 *
 * Use this helper to easily produce a function you can pass to the table's
 * `rowClass` input. The returned resolver reads the specified `field` from the
 * row object, stringifies it, looks it up in `map` and returns the matching
 * class name or the provided `fallback`.
 *
 * Notes:
 * - The function performs a direct property access: `(row as any)[field]`.
 * - Map keys are matched against the stringified field value (numbers/booleans
 *   are converted to strings).
 * - If the field is nested (e.g. `user.name`) use `rowClassByPath` instead.
 * - CSS classes returned by the resolver must be defined in the consumer
 *   application's styles — the library does not inject those rules.
 *
 * Example:
 * ```ts
 * // rows: Array<{ sex: 'male'|'female' }>
 * rowClass = rowClassByField('sex', {
 *   female: 'row-female',
 *   male: 'row-male'
 * }, '');
 * ```
 *
 * @param field Property name on the row objects to check
 * @param map Mapping from stringified field values to CSS class names
 * @param fallback Optional fallback class when no mapping matches (default: '')
 * @returns A function `(row: T) => string` that resolves the class name
 */
function rowClassByField(field, map, fallback = '') {
    return (row) => {
        const value = String(row[field]);
        return map[value] ?? fallback;
    };
}
/**
 * Creates a row class resolver that reads a nested field (dot-path) from a row
 * object and maps its stringified value to a CSS class name.
 *
 * This helper is useful when the value you want to base row styling on lives
 * on a nested property (for example `user.status` or `address.country.code`).
 * The `path` supports simple dot-notation and is resolved with a safe reduce
 * (it will tolerate missing intermediate objects).
 *
 * Behavior notes:
 * - The resolved field value is converted to a string and matched against the
 *   provided `map` keys.
 * - If no mapping matches, the `fallback` value is returned (defaults to `''`).
 * - The returned CSS class must be defined by the consumer application — the
 *   library does not provide styling for custom class names.
 *
 * Example (rows where `sex` is a nested property):
 * ```ts
 * // rows: Array<{ user: { sex: 'male'|'female' } }>
 * rowClass = rowClassByPath('user.sex', {
 *   female: 'row-female',
 *   male: 'row-male'
 * }, '');
 * ```
 *
 * @param path Dot-separated path to the property on the row objects
 * @param map Mapping from stringified values to CSS class names
 * @param fallback Optional fallback class when no mapping matches (default: '')
 * @returns A function `(row: T) => string` that resolves the class name
 */
function rowClassByPath(path, map, fallback = '') {
    return (row) => {
        const value = path.split('.').reduce((acc, key) => acc?.[key], row);
        return map[String(value)] ?? fallback;
    };
}
/**
 * Creates a strongly typed field path factory for a specific row type.
 *
 * This helper is used to create type-safe string paths that reference
 * properties of a data model (including nested properties), while
 * keeping the runtime value a simple string.
 *
 * It improves developer experience by:
 * - validating field paths at compile time
 * - preventing typos in nested property paths
 * - keeping IDE autocompletion and hover information clean
 *
 * ## Usage
 * ```ts
 * const fieldOf = fieldPathOf<Person>();
 *
 * const name = fieldOf('name');           // ✅ valid
 * const city = fieldOf('address.city');   // ✅ valid
 * const wrong = fieldOf('address.cito');  // ❌ compile-time error
 * ```
 *
 * The returned value is a string at runtime and can be safely used for:
 * - column definitions
 * - sorting and filtering
 * - backend queries
 *
 * @typeParam T The row data type used to validate field paths.
 */
function fieldPathOf() {
    return (path) => path;
}

/*
 * Public API Surface of ng-fusion-ui
 */

/**
 * Generated bundle index. Do not edit.
 */

export { BodyTemplateDirective, ButtonDirective, ButtonModule, DataTableModule, ExpandTemplateDirective, FuColumnActionsTemplateDirective, FuColumnCellTemplateDirective, FuColumnComponent, FuColumnHeaderAddonTemplateDirective, FuColumnHeaderTemplateDirective, FuHighlightDirective, FuHighlightPipe, FuTButtonDirective, FuTableCellContextMenuTemplateDirective, FuTableComponent, FuTableExpandRowTemplateDirective, FuTableIntlService, FuTableModule, FuTableNoDataTemplateDirective, FuTableSidebarTemplateDirective, FuTableToolbarTemplateDirective, HeaderTemplateDirective, HighlightDirective, IconComponent, IconModule, PopupTemplateDirective, TableComponent, TableFilterComponent, TableIntlService, TablePaginatorComponent, TbodyActionsComponent, TbodyCellComponent, TheadCellComponent, TreeComponent, TreeModule, fieldPathOf, rowClassByField, rowClassByPath };
//# sourceMappingURL=ng-fusion-ui.mjs.map