layout-tsi 0.0.5 → 21.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +32 -63
  2. package/fesm2022/layout-tsi.mjs +214 -221
  3. package/fesm2022/layout-tsi.mjs.map +1 -1
  4. package/package.json +10 -8
  5. package/types/layout-tsi.d.ts +579 -0
  6. package/index.d.ts +0 -5
  7. package/lib/models/general/app-tab.model.d.ts +0 -9
  8. package/lib/models/general/dashboard.model.d.ts +0 -15
  9. package/lib/models/general/route-info.model.d.ts +0 -16
  10. package/lib/models/general/session-data.model.d.ts +0 -8
  11. package/lib/service/detector.service.d.ts +0 -8
  12. package/lib/service/header-ui.service.d.ts +0 -9
  13. package/lib/service/menu.service.d.ts +0 -8
  14. package/lib/service/tabs.service.d.ts +0 -36
  15. package/lib/ui/bottom-navigation/bottom-navigation.component.d.ts +0 -31
  16. package/lib/ui/chatbot/chatbot.component.d.ts +0 -30
  17. package/lib/ui/chatbot/chatbot.model.d.ts +0 -28
  18. package/lib/ui/chatbot/chatbot.service.d.ts +0 -19
  19. package/lib/ui/dashboard/dashboard-chart-bars/dashboard-chart-bars.component.d.ts +0 -45
  20. package/lib/ui/dashboard/dashboard-chart-donut/dashboard-chart-donut.component.d.ts +0 -21
  21. package/lib/ui/dashboard/dashboard-view-switcher/dashboard-view-switcher.component.d.ts +0 -14
  22. package/lib/ui/dashboard/item-dashboard/item-dashboard.component.d.ts +0 -26
  23. package/lib/ui/dashboard/item-dashboard-group/item-dashboard-group.component.d.ts +0 -28
  24. package/lib/ui/full/full.component.d.ts +0 -48
  25. package/lib/ui/menu-item/menu-item.component.d.ts +0 -70
  26. package/lib/ui/not-found/not-found.component.d.ts +0 -7
  27. package/lib/ui/tab-bar/tab-bar.component.d.ts +0 -23
  28. package/lib/ui/vertical-header/vertical-header.component.d.ts +0 -96
  29. package/lib/utils/validaciones.d.ts +0 -1
  30. package/public-api.d.ts +0 -21
@@ -1,7 +1,7 @@
1
1
  import * as i1 from '@angular/common';
2
2
  import { NgClass, CommonModule, Location, NgStyle, KeyValuePipe, DecimalPipe } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { signal, Injectable, InjectionToken, inject, DestroyRef, Injector, computed, effect, input, ChangeDetectionStrategy, Component, output, HostListener, NgZone, ViewChild, reflectComponentType, ContentChild, viewChild } from '@angular/core';
4
+ import { signal, Injectable, InjectionToken, inject, DestroyRef, Injector, computed, effect, input, ChangeDetectionStrategy, Component, output, HostListener, ViewChild, reflectComponentType, ContentChild, viewChild } from '@angular/core';
5
5
  import * as i2 from '@angular/router';
6
6
  import { Router, NavigationEnd, RouterLink, ChildrenOutletContexts, RouterModule } from '@angular/router';
7
7
  import { takeUntilDestroyed, toObservable, toSignal } from '@angular/core/rxjs-interop';
@@ -9,7 +9,7 @@ import { Subject, combineLatest, EMPTY, filter as filter$1, map as map$1, startW
9
9
  import { filter, takeUntil, skip, debounceTime, map, distinctUntilChanged, switchMap, catchError } from 'rxjs/operators';
10
10
 
11
11
  class MenuService {
12
- _openMenus = signal(new Map());
12
+ _openMenus = signal(new Map(), ...(ngDevMode ? [{ debugName: "_openMenus" }] : /* istanbul ignore next */ []));
13
13
  openMenus = this._openMenus.asReadonly();
14
14
  setOpenMenu(level, id) {
15
15
  const currentMap = new Map(this._openMenus());
@@ -21,10 +21,10 @@ class MenuService {
21
21
  }
22
22
  this._openMenus.set(currentMap);
23
23
  }
24
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
25
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MenuService, providedIn: 'root' });
24
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: MenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
25
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: MenuService, providedIn: 'root' });
26
26
  }
27
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MenuService, decorators: [{
27
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: MenuService, decorators: [{
28
28
  type: Injectable,
29
29
  args: [{
30
30
  providedIn: 'root'
@@ -32,18 +32,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
32
32
  }] });
33
33
 
34
34
  class HeaderUiService {
35
- typeDocumento = signal(null);
36
- numintDocumento = signal(null);
35
+ typeDocumento = signal(null, ...(ngDevMode ? [{ debugName: "typeDocumento" }] : /* istanbul ignore next */ []));
36
+ numintDocumento = signal(null, ...(ngDevMode ? [{ debugName: "numintDocumento" }] : /* istanbul ignore next */ []));
37
37
  setTypeDocumento(value) {
38
38
  this.typeDocumento.set(value);
39
39
  }
40
40
  setNumintDocumento(value) {
41
41
  this.numintDocumento.set(value);
42
42
  }
43
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: HeaderUiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
44
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: HeaderUiService, providedIn: 'root' });
43
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HeaderUiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
44
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HeaderUiService, providedIn: 'root' });
45
45
  }
46
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: HeaderUiService, decorators: [{
46
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HeaderUiService, decorators: [{
47
47
  type: Injectable,
48
48
  args: [{
49
49
  providedIn: 'root'
@@ -62,15 +62,15 @@ class TabsService {
62
62
  syncProvider = inject(TABS_SYNC_PROVIDER, { optional: true });
63
63
  destroyRef = inject(DestroyRef);
64
64
  injector = inject(Injector);
65
- tabs = signal([]);
66
- activeId = signal(null);
67
- visible = signal(true);
65
+ tabs = signal([], ...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
66
+ activeId = signal(null, ...(ngDevMode ? [{ debugName: "activeId" }] : /* istanbul ignore next */ []));
67
+ visible = signal(true, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
68
68
  // Corta la carga/sincronización en curso cuando clear() destruye la sesión (logout).
69
69
  destroy$ = new Subject();
70
70
  sortedTabs = computed(() => {
71
71
  const ts = this.tabs();
72
72
  return [...ts.filter(t => t.pinned), ...ts.filter(t => !t.pinned)];
73
- });
73
+ }, ...(ngDevMode ? [{ debugName: "sortedTabs" }] : /* istanbul ignore next */ []));
74
74
  toggleVisible() { this.visible.update(v => !v); }
75
75
  constructor() {
76
76
  this.loadFromStorage();
@@ -182,16 +182,16 @@ class TabsService {
182
182
  event.stopPropagation();
183
183
  this.tabs.update(ts => ts.map(t => t.id === id ? { ...t, pinned: !t.pinned } : t));
184
184
  }
185
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TabsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
186
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TabsService, providedIn: 'root' });
185
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: TabsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
186
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: TabsService, providedIn: 'root' });
187
187
  }
188
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TabsService, decorators: [{
188
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: TabsService, decorators: [{
189
189
  type: Injectable,
190
190
  args: [{ providedIn: 'root' }]
191
191
  }], ctorParameters: () => [] });
192
192
 
193
- const activeFlyoutKey = signal(null);
194
- const activeTooltip = signal(null);
193
+ const activeFlyoutKey = signal(null, ...(ngDevMode ? [{ debugName: "activeFlyoutKey" }] : /* istanbul ignore next */ []));
194
+ const activeTooltip = signal(null, ...(ngDevMode ? [{ debugName: "activeTooltip" }] : /* istanbul ignore next */ []));
195
195
  const EXTRALINK_OPENER = new InjectionToken('EXTRALINK_OPENER');
196
196
  class MenuItemComponent {
197
197
  menuService = inject(MenuService);
@@ -199,27 +199,27 @@ class MenuItemComponent {
199
199
  tabsService = inject(TabsService);
200
200
  router = inject(Router);
201
201
  extralinkOpener = inject(EXTRALINK_OPENER, { optional: true });
202
- item = input.required();
203
- isSidebarOpen = input(true);
204
- isSidebarHovering = input(false);
205
- level = input(0);
206
- parentModuleName = input(null);
207
- accentColor = input('#398bf7');
202
+ item = input.required(...(ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []));
203
+ isSidebarOpen = input(true, ...(ngDevMode ? [{ debugName: "isSidebarOpen" }] : /* istanbul ignore next */ []));
204
+ isSidebarHovering = input(false, ...(ngDevMode ? [{ debugName: "isSidebarHovering" }] : /* istanbul ignore next */ []));
205
+ level = input(0, ...(ngDevMode ? [{ debugName: "level" }] : /* istanbul ignore next */ []));
206
+ parentModuleName = input(null, ...(ngDevMode ? [{ debugName: "parentModuleName" }] : /* istanbul ignore next */ []));
207
+ accentColor = input('#398bf7', ...(ngDevMode ? [{ debugName: "accentColor" }] : /* istanbul ignore next */ []));
208
208
  // Accesos/rol de la sesión: se reciben del consumidor (en vez de inyectar
209
209
  // SesionService acá) para que layout-tsi no dependa de core-tsi.
210
- accesos = input([]);
211
- rolId = input(null);
212
- open = signal(false);
213
- flyoutY = signal(0);
214
- expandedFlyoutChild = signal(null);
210
+ accesos = input([], ...(ngDevMode ? [{ debugName: "accesos" }] : /* istanbul ignore next */ []));
211
+ rolId = input(null, ...(ngDevMode ? [{ debugName: "rolId" }] : /* istanbul ignore next */ []));
212
+ open = signal(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
213
+ flyoutY = signal(0, ...(ngDevMode ? [{ debugName: "flyoutY" }] : /* istanbul ignore next */ []));
214
+ expandedFlyoutChild = signal(null, ...(ngDevMode ? [{ debugName: "expandedFlyoutChild" }] : /* istanbul ignore next */ []));
215
215
  flyoutTimer = null;
216
216
  tooltip = activeTooltip;
217
- showFlyout = computed(() => activeFlyoutKey() === this.getFlyoutKey() && this.isSidebarOpen() && window.innerWidth > 1191);
217
+ showFlyout = computed(() => activeFlyoutKey() === this.getFlyoutKey() && this.isSidebarOpen() && window.innerWidth > 1191, ...(ngDevMode ? [{ debugName: "showFlyout" }] : /* istanbul ignore next */ []));
218
218
  // El cierre tenía un delay de 80ms (debounce de onItemMouseLeave/onFlyoutMouseLeave)
219
219
  // seguido de un @if que lo desmontaba en seco, sin animación — eso es lo que se
220
220
  // sentía como "lag" (una pausa y después un salto). Ahora se anima la salida y
221
221
  // recién se desmonta cuando esa animación termina.
222
- flyoutRendered = signal(false);
222
+ flyoutRendered = signal(false, ...(ngDevMode ? [{ debugName: "flyoutRendered" }] : /* istanbul ignore next */ []));
223
223
  flyoutExitTimer = null;
224
224
  currentUrl = toSignal(this.router.events.pipe(filter$1((e) => e instanceof NavigationEnd), map$1(() => this.router.url), startWith(this.router.url)), { initialValue: this.router.url });
225
225
  // Una ruta con query param "project" (p. ej. tareas de un proyecto específico)
@@ -238,7 +238,7 @@ class MenuItemComponent {
238
238
  // tiene equivalente CSS puro (Angular removía el <ul> recién al terminar el
239
239
  // :leave) — acá se mantiene montado con "--closing" el tiempo de esa
240
240
  // animación y recién ahí se desmonta.
241
- submenuRendered = signal(false);
241
+ submenuRendered = signal(false, ...(ngDevMode ? [{ debugName: "submenuRendered" }] : /* istanbul ignore next */ []));
242
242
  submenuLeaveTimer = null;
243
243
  constructor() {
244
244
  effect(() => {
@@ -500,19 +500,19 @@ class MenuItemComponent {
500
500
  return null;
501
501
  return item.path;
502
502
  }
503
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
504
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: MenuItemComponent, isStandalone: true, selector: "app-menu-item", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, isSidebarOpen: { classPropertyName: "isSidebarOpen", publicName: "isSidebarOpen", isSignal: true, isRequired: false, transformFunction: null }, isSidebarHovering: { classPropertyName: "isSidebarHovering", publicName: "isSidebarHovering", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, parentModuleName: { classPropertyName: "parentModuleName", publicName: "parentModuleName", isSignal: true, isRequired: false, transformFunction: null }, accentColor: { classPropertyName: "accentColor", publicName: "accentColor", isSignal: true, isRequired: false, transformFunction: null }, accesos: { classPropertyName: "accesos", publicName: "accesos", isSignal: true, isRequired: false, transformFunction: null }, rolId: { classPropertyName: "rolId", publicName: "rolId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if(hasAccess()){\r\n<li (mouseenter)=\"onItemMouseEnter($event)\" (mouseleave)=\"onItemMouseLeave()\"\r\n (mouseover)=\"onItemMouseOver()\">\r\n <div class=\"d-flex align-items-center justify-content-between pt-2 pb-2 px-2 item-sidebar\" (click)=\"toggle()\"\r\n (mousedown)=\"onMiddleClick($event)\" (contextmenu)=\"onRightClick($event)\"\r\n [routerLink]=\"(!item().submenu?.length && item().path && !item().extralink) ? item().path : null\"\r\n [class.active-route]=\"esRutaActiva(item().path)\" [class.cursor-pointer]=\"item().submenu?.length == 0\"\r\n [class.cursor-drow]=\"item().submenu?.length > 0\">\r\n <span>\r\n @if (item().title) {\r\n <i [class]=\"(item().icon ? item().icon : '') + (isSidebarActuallyOpen ? ' me-1' : ' me-1 ms-2')\"></i>\r\n <span class=\"sidebar-text\" [class.sidebar-text--hidden]=\"!isSidebarActuallyOpen\">\r\n {{ item().title }}\r\n </span>\r\n }\r\n </span>\r\n @if (item().submenu?.length > 0) {\r\n <i class=\"fas sidebar-chevron\" [class.sidebar-chevron--hidden]=\"!isSidebarActuallyOpen\" [ngClass]=\"{\r\n 'fa-chevron-down': isOpen(),\r\n 'fa-chevron-right': !isOpen()\r\n }\"></i>\r\n }\r\n </div>\r\n @if (item().submenu?.length && isSidebarActuallyOpen && submenuRendered()) {\r\n <ul class=\"list-unstyled ms-3 submenu\" [class.submenu--closing]=\"!isOpen()\">\r\n @for (child of item().submenu; track $index) {\r\n <app-menu-item [item]=\"child\" [level]=\"level() + 1\" [isSidebarOpen]=\"!isSidebarActuallyOpen\" [parentModuleName]=\"parentModuleName()\" [accentColor]=\"accentColor()\" [accesos]=\"accesos()\" [rolId]=\"rolId()\" />\r\n }\r\n </ul>\r\n }\r\n\r\n @if (flyoutRendered()) {\r\n <div class=\"sidebar-flyout\" [class.sidebar-flyout--closing]=\"!showFlyout()\" [style.top.px]=\"flyoutY()\" [style.max-height]=\"'calc(100dvh - ' + flyoutY() + 'px - 8px)'\"\r\n [style.--flyout-accent]=\"accentColor()\" (mouseenter)=\"onFlyoutMouseEnter()\" (mouseleave)=\"onFlyoutMouseLeave()\">\r\n <div class=\"flyout-header\">\r\n <i [class]=\"(item().icon || '') + ' flyout-header-icon'\"></i>\r\n <span class=\"flyout-header-title\">{{ item().title }}</span>\r\n @if (codAcceso()) {\r\n <span class=\"flyout-header-acceso\">{{ codAcceso().split(': ')[1] }}</span>\r\n }\r\n </div>\r\n @if (item().submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-items\">\r\n @for (child of item().submenu; track $index) {\r\n @if (hasAccess(child)) {\r\n <li class=\"flyout-group\">\r\n <div class=\"flyout-item\" [class.flyout-item-has-children]=\"child.submenu?.length > 0\"\r\n [class.flyout-item-expanded]=\"isFlyoutChildExpanded(child)\" [routerLink]=\"manejarRuta(child)\"\r\n [class.flyout-item-active]=\"!child.submenu?.length && esRutaActiva(child.path)\"\r\n (click)=\"onFlyoutItemClick(child, $event)\" (mousedown)=\"onFlyoutItemMiddleClick($event, child)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, child)\" (mouseenter)=\"showChildTooltip($event, child)\"\r\n (mouseleave)=\"hideChildTooltip()\">\r\n @if (child.icon) {\r\n <i [class]=\"child.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ child.title }}</span>\r\n @if (child.submenu?.length > 0) {\r\n <i class=\"fas flyout-chevron\" [class.fa-chevron-down]=\"isFlyoutChildExpanded(child)\"\r\n [class.fa-chevron-right]=\"!isFlyoutChildExpanded(child)\"></i>\r\n }\r\n </div>\r\n\r\n @if (isFlyoutChildExpanded(child) && child.submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-subitems\">\r\n @for (grandchild of child.submenu; track $index) {\r\n @if (hasAccess(grandchild)) {\r\n <li class=\"flyout-subitem\" [routerLink]=\"manejarRuta(grandchild)\" [class.flyout-subitem-active]=\"esRutaActiva(grandchild.path)\"\r\n (click)=\"onFlyoutGrandchildClick(grandchild)\" (mousedown)=\"onFlyoutItemMiddleClick($event, grandchild)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, grandchild)\"\r\n (mouseenter)=\"showChildTooltip($event, grandchild)\" (mouseleave)=\"hideChildTooltip()\">\r\n @if (grandchild.icon) {\r\n <i [class]=\"grandchild.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ grandchild.title }}</span>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </div>\r\n }\r\n</li>\r\n}\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".active-route{color:var(--sidebar-active-text)!important;background:linear-gradient(90deg,#ffffff24,#ffffff0a)!important;border-left:3px solid var(--sidebar-accent, #c50048)!important;border-radius:0 8px 8px 0!important;box-shadow:inset 0 1px #ffffff0f!important}.cursor-drow{cursor:default}.submenu{transform-origin:top;animation:submenuIn .26s cubic-bezier(.4,0,.2,1) both}.submenu--closing{animation:submenuOut .22s cubic-bezier(.4,0,.2,1) both}@keyframes submenuIn{0%{opacity:0;transform:translateY(-8px) scaleY(.94)}to{opacity:1;transform:translateY(0) scaleY(1)}}@keyframes submenuOut{0%{opacity:1;transform:translateY(0) scaleY(1)}to{opacity:0;transform:translateY(-8px) scaleY(.94)}}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid var(--sidebar-accent, #c50048);display:flex;align-items:center;gap:5px;animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700;color:var(--sidebar-accent, #c50048)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--sidebar-accent, #c50048)}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.sidebar-text{display:inline-block;vertical-align:middle;white-space:normal;word-break:break-word;opacity:1;transform:translate(0);transition:opacity .15s ease .22s,transform .15s ease .22s}.sidebar-text--hidden{opacity:0;transform:translate(-4px);white-space:nowrap;max-width:0;overflow:hidden;transition:opacity .12s ease 0s,transform .12s ease 0s,max-width 0s linear .12s}.sidebar-chevron{opacity:1;transition:opacity .15s ease .22s}.sidebar-chevron--hidden{opacity:0;transition:opacity .12s ease 0s}.item-sidebar{color:var(--sidebar-text-color)!important;transition:all .2s ease;border-radius:8px}.item-sidebar>span:first-child{min-width:0;flex:1}.item-sidebar:hover{color:var(--sidebar-active-text)!important;background:#ffffff17!important;transform:translate(2px)}:host-context(.sidebar.open) .item-sidebar{border-radius:8px 0 0 8px;margin-right:-8px}:host-context(.sidebar.open) .item-sidebar:hover{transform:none}:host-context(.sidebar.open) .item-sidebar.active-route{border-radius:0!important;background:#ffffff24!important}.sidebar-flyout{position:fixed;left:70px;z-index:9999;min-width:220px;max-width:300px;overflow-y:auto;scrollbar-width:none;background:linear-gradient(160deg,var(--sidebar-gradient-start, #1a1a2e) 0%,var(--sidebar-bg, #16213e) 100%);border:1px solid rgba(255,255,255,.1);border-left:3px solid var(--flyout-accent, #c50048);border-radius:0 12px 12px;box-shadow:8px 6px 32px #0000008c,0 0 0 1px #ffffff0a;animation:flyout-slide-in .15s cubic-bezier(.25,.46,.45,.94);pointer-events:auto}.sidebar-flyout--closing{animation:flyout-slide-out .13s ease-in both}@keyframes flyout-slide-out{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-8px)}}.flyout-header{display:flex;align-items:center;gap:10px;padding:12px 16px 10px;border-bottom:1px solid rgba(255,255,255,.08);background:#ffffff0a}.flyout-header-icon{color:var(--flyout-accent, #c50048);font-size:14px;min-width:16px;text-align:center}.flyout-header-title{font-size:12px;font-weight:700;color:var(--sidebar-active-text, #fff);letter-spacing:.5px;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.flyout-header-acceso{font-size:10px;font-weight:700;font-family:monospace;color:var(--flyout-accent, #c50048);background:#ffffff12;border:1px solid rgba(255,255,255,.1);border-left:2px solid var(--flyout-accent, #c50048);padding:2px 7px;border-radius:4px;white-space:nowrap;flex-shrink:0}.flyout-items{padding:6px;margin:0}.flyout-item{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:8px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .7));font-size:13px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden;position:relative}.flyout-item:hover{background:#ffffff1a;color:var(--sidebar-active-text, #fff);transform:translate(3px)}.flyout-item-active{background:linear-gradient(90deg,#ffffff21,#ffffff08)!important;color:var(--sidebar-active-text, #fff)!important}.flyout-item-active:before{content:\"\";position:absolute;left:0;top:15%;height:70%;width:3px;background:var(--flyout-accent, #c50048);border-radius:0 2px 2px 0}.flyout-item-icon{font-size:12px;min-width:14px;text-align:center;color:inherit;opacity:.75}.flyout-item-label{flex:1;overflow:hidden;text-overflow:ellipsis}.flyout-chevron{font-size:10px;opacity:.5;margin-left:auto;flex-shrink:0;transition:transform .2s ease}.flyout-group{display:flex;flex-direction:column}.flyout-item-has-children{cursor:default}.flyout-item-expanded{background:#ffffff12!important;color:var(--sidebar-active-text, #fff)!important}.flyout-subitems{padding:2px 6px 2px 14px;border-left:2px solid rgba(255,255,255,.1);margin:0 6px 4px 20px}.flyout-subitem{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:6px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .65));font-size:12px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden}.flyout-subitem:hover{background:#ffffff17;color:var(--sidebar-active-text, #fff);transform:translate(2px)}.flyout-subitem-active{color:var(--sidebar-active-text, #fff)!important;position:relative}.flyout-subitem-active:before{content:\"\";position:absolute;left:-14px;top:20%;height:60%;width:2px;background:var(--flyout-accent, #c50048);border-radius:1px}@keyframes flyout-slide-in{0%{opacity:0;transform:translate(-10px)}to{opacity:1;transform:translate(0)}}\n"], dependencies: [{ kind: "component", type: MenuItemComponent, selector: "app-menu-item", inputs: ["item", "isSidebarOpen", "isSidebarHovering", "level", "parentModuleName", "accentColor", "accesos", "rolId"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
503
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: MenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
504
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: MenuItemComponent, isStandalone: true, selector: "app-menu-item", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, isSidebarOpen: { classPropertyName: "isSidebarOpen", publicName: "isSidebarOpen", isSignal: true, isRequired: false, transformFunction: null }, isSidebarHovering: { classPropertyName: "isSidebarHovering", publicName: "isSidebarHovering", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, parentModuleName: { classPropertyName: "parentModuleName", publicName: "parentModuleName", isSignal: true, isRequired: false, transformFunction: null }, accentColor: { classPropertyName: "accentColor", publicName: "accentColor", isSignal: true, isRequired: false, transformFunction: null }, accesos: { classPropertyName: "accesos", publicName: "accesos", isSignal: true, isRequired: false, transformFunction: null }, rolId: { classPropertyName: "rolId", publicName: "rolId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if(hasAccess()){\r\n<li (mouseenter)=\"onItemMouseEnter($event)\" (mouseleave)=\"onItemMouseLeave()\"\r\n (mouseover)=\"onItemMouseOver()\">\r\n <div class=\"d-flex align-items-center justify-content-between pt-2 pb-2 px-2 item-sidebar\" (click)=\"toggle()\"\r\n (mousedown)=\"onMiddleClick($event)\" (contextmenu)=\"onRightClick($event)\"\r\n [routerLink]=\"(!item().submenu?.length && item().path && !item().extralink) ? item().path : null\"\r\n [class.active-route]=\"esRutaActiva(item().path)\" [class.cursor-pointer]=\"item().submenu?.length == 0\"\r\n [class.cursor-drow]=\"item().submenu?.length > 0\">\r\n <span>\r\n @if (item().title) {\r\n <i [class]=\"(item().icon ? item().icon : '') + (isSidebarActuallyOpen ? ' me-1' : ' me-1 ms-2')\"></i>\r\n <span class=\"sidebar-text\" [class.sidebar-text--hidden]=\"!isSidebarActuallyOpen\">\r\n {{ item().title }}\r\n </span>\r\n }\r\n </span>\r\n @if (item().submenu?.length > 0) {\r\n <i class=\"fas sidebar-chevron\" [class.sidebar-chevron--hidden]=\"!isSidebarActuallyOpen\" [ngClass]=\"{\r\n 'fa-chevron-down': isOpen(),\r\n 'fa-chevron-right': !isOpen()\r\n }\"></i>\r\n }\r\n </div>\r\n @if (item().submenu?.length && isSidebarActuallyOpen && submenuRendered()) {\r\n <ul class=\"list-unstyled ms-3 submenu\" [class.submenu--closing]=\"!isOpen()\">\r\n @for (child of item().submenu; track $index) {\r\n <app-menu-item [item]=\"child\" [level]=\"level() + 1\" [isSidebarOpen]=\"!isSidebarActuallyOpen\" [parentModuleName]=\"parentModuleName()\" [accentColor]=\"accentColor()\" [accesos]=\"accesos()\" [rolId]=\"rolId()\" />\r\n }\r\n </ul>\r\n }\r\n\r\n @if (flyoutRendered()) {\r\n <div class=\"sidebar-flyout\" [class.sidebar-flyout--closing]=\"!showFlyout()\" [style.top.px]=\"flyoutY()\" [style.max-height]=\"'calc(100dvh - ' + flyoutY() + 'px - 8px)'\"\r\n [style.--flyout-accent]=\"accentColor()\" (mouseenter)=\"onFlyoutMouseEnter()\" (mouseleave)=\"onFlyoutMouseLeave()\">\r\n <div class=\"flyout-header\">\r\n <i [class]=\"(item().icon || '') + ' flyout-header-icon'\"></i>\r\n <span class=\"flyout-header-title\">{{ item().title }}</span>\r\n @if (codAcceso()) {\r\n <span class=\"flyout-header-acceso\">{{ codAcceso().split(': ')[1] }}</span>\r\n }\r\n </div>\r\n @if (item().submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-items\">\r\n @for (child of item().submenu; track $index) {\r\n @if (hasAccess(child)) {\r\n <li class=\"flyout-group\">\r\n <div class=\"flyout-item\" [class.flyout-item-has-children]=\"child.submenu?.length > 0\"\r\n [class.flyout-item-expanded]=\"isFlyoutChildExpanded(child)\" [routerLink]=\"manejarRuta(child)\"\r\n [class.flyout-item-active]=\"!child.submenu?.length && esRutaActiva(child.path)\"\r\n (click)=\"onFlyoutItemClick(child, $event)\" (mousedown)=\"onFlyoutItemMiddleClick($event, child)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, child)\" (mouseenter)=\"showChildTooltip($event, child)\"\r\n (mouseleave)=\"hideChildTooltip()\">\r\n @if (child.icon) {\r\n <i [class]=\"child.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ child.title }}</span>\r\n @if (child.submenu?.length > 0) {\r\n <i class=\"fas flyout-chevron\" [class.fa-chevron-down]=\"isFlyoutChildExpanded(child)\"\r\n [class.fa-chevron-right]=\"!isFlyoutChildExpanded(child)\"></i>\r\n }\r\n </div>\r\n\r\n @if (isFlyoutChildExpanded(child) && child.submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-subitems\">\r\n @for (grandchild of child.submenu; track $index) {\r\n @if (hasAccess(grandchild)) {\r\n <li class=\"flyout-subitem\" [routerLink]=\"manejarRuta(grandchild)\" [class.flyout-subitem-active]=\"esRutaActiva(grandchild.path)\"\r\n (click)=\"onFlyoutGrandchildClick(grandchild)\" (mousedown)=\"onFlyoutItemMiddleClick($event, grandchild)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, grandchild)\"\r\n (mouseenter)=\"showChildTooltip($event, grandchild)\" (mouseleave)=\"hideChildTooltip()\">\r\n @if (grandchild.icon) {\r\n <i [class]=\"grandchild.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ grandchild.title }}</span>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </div>\r\n }\r\n</li>\r\n}\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".active-route{color:var(--sidebar-active-text)!important;background:linear-gradient(90deg,#ffffff24,#ffffff0a)!important;border-left:3px solid var(--sidebar-accent, #c50048)!important;border-radius:0 8px 8px 0!important;box-shadow:inset 0 1px #ffffff0f!important}.cursor-drow{cursor:default}.submenu{transform-origin:top;animation:submenuIn .26s cubic-bezier(.4,0,.2,1) both}.submenu--closing{animation:submenuOut .22s cubic-bezier(.4,0,.2,1) both}@keyframes submenuIn{0%{opacity:0;transform:translateY(-8px) scaleY(.94)}to{opacity:1;transform:translateY(0) scaleY(1)}}@keyframes submenuOut{0%{opacity:1;transform:translateY(0) scaleY(1)}to{opacity:0;transform:translateY(-8px) scaleY(.94)}}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid var(--sidebar-accent, #c50048);display:flex;align-items:center;gap:5px}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700;color:var(--sidebar-accent, #c50048)}.acceso-tooltip-fixed{animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--sidebar-accent, #c50048)}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.sidebar-text{display:inline-block;vertical-align:middle;white-space:normal;word-break:break-word;opacity:1;transform:translate(0);transition:opacity .15s ease .22s,transform .15s ease .22s}.sidebar-text--hidden{opacity:0;transform:translate(-4px);white-space:nowrap;max-width:0;overflow:hidden;transition:opacity .12s ease 0s,transform .12s ease 0s,max-width 0s linear .12s}.sidebar-chevron{opacity:1;transition:opacity .15s ease .22s}.sidebar-chevron--hidden{opacity:0;transition:opacity .12s ease 0s}.item-sidebar{color:var(--sidebar-text-color)!important;transition:all .2s ease;border-radius:8px}.item-sidebar>span:first-child{min-width:0;flex:1}.item-sidebar:hover{color:var(--sidebar-active-text)!important;background:#ffffff17!important;transform:translate(2px)}:host-context(.sidebar.open) .item-sidebar{border-radius:8px 0 0 8px;margin-right:-8px}:host-context(.sidebar.open) .item-sidebar:hover{transform:none}:host-context(.sidebar.open) .item-sidebar.active-route{border-radius:0!important;background:#ffffff24!important}.sidebar-flyout{position:fixed;left:70px;z-index:9999;min-width:220px;max-width:300px;overflow-y:auto;scrollbar-width:none;background:linear-gradient(160deg,var(--sidebar-gradient-start, #1a1a2e) 0%,var(--sidebar-bg, #16213e) 100%);border:1px solid rgba(255,255,255,.1);border-left:3px solid var(--flyout-accent, #c50048);border-radius:0 12px 12px;box-shadow:8px 6px 32px #0000008c,0 0 0 1px #ffffff0a;animation:flyout-slide-in .15s cubic-bezier(.25,.46,.45,.94);pointer-events:auto}.sidebar-flyout--closing{animation:flyout-slide-out .13s ease-in both}@keyframes flyout-slide-out{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-8px)}}.flyout-header{display:flex;align-items:center;gap:10px;padding:12px 16px 10px;border-bottom:1px solid rgba(255,255,255,.08);background:#ffffff0a}.flyout-header-icon{color:var(--flyout-accent, #c50048);font-size:14px;min-width:16px;text-align:center}.flyout-header-title{font-size:12px;font-weight:700;color:var(--sidebar-active-text, #fff);letter-spacing:.5px;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.flyout-header-acceso{font-size:10px;font-weight:700;font-family:monospace;color:var(--flyout-accent, #c50048);background:#ffffff12;border:1px solid rgba(255,255,255,.1);border-left:2px solid var(--flyout-accent, #c50048);padding:2px 7px;border-radius:4px;white-space:nowrap;flex-shrink:0}.flyout-items{padding:6px;margin:0}.flyout-item{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:8px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .7));font-size:13px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden;position:relative}.flyout-item:hover{background:#ffffff1a;color:var(--sidebar-active-text, #fff);transform:translate(3px)}.flyout-item-active{background:linear-gradient(90deg,#ffffff21,#ffffff08)!important;color:var(--sidebar-active-text, #fff)!important}.flyout-item-active:before{content:\"\";position:absolute;left:0;top:15%;height:70%;width:3px;background:var(--flyout-accent, #c50048);border-radius:0 2px 2px 0}.flyout-item-icon{font-size:12px;min-width:14px;text-align:center;color:inherit;opacity:.75}.flyout-item-label{flex:1;overflow:hidden;text-overflow:ellipsis}.flyout-chevron{font-size:10px;opacity:.5;margin-left:auto;flex-shrink:0;transition:transform .2s ease}.flyout-group{display:flex;flex-direction:column}.flyout-item-has-children{cursor:default}.flyout-item-expanded{background:#ffffff12!important;color:var(--sidebar-active-text, #fff)!important}.flyout-subitems{padding:2px 6px 2px 14px;border-left:2px solid rgba(255,255,255,.1);margin:0 6px 4px 20px}.flyout-subitem{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:6px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .65));font-size:12px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden}.flyout-subitem:hover{background:#ffffff17;color:var(--sidebar-active-text, #fff);transform:translate(2px)}.flyout-subitem-active{color:var(--sidebar-active-text, #fff)!important;position:relative}.flyout-subitem-active:before{content:\"\";position:absolute;left:-14px;top:20%;height:60%;width:2px;background:var(--flyout-accent, #c50048);border-radius:1px}@keyframes flyout-slide-in{0%{opacity:0;transform:translate(-10px)}to{opacity:1;transform:translate(0)}}\n"], dependencies: [{ kind: "component", type: MenuItemComponent, selector: "app-menu-item", inputs: ["item", "isSidebarOpen", "isSidebarHovering", "level", "parentModuleName", "accentColor", "accesos", "rolId"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
505
505
  }
506
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MenuItemComponent, decorators: [{
506
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: MenuItemComponent, decorators: [{
507
507
  type: Component,
508
- args: [{ selector: 'app-menu-item', imports: [NgClass, RouterLink], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if(hasAccess()){\r\n<li (mouseenter)=\"onItemMouseEnter($event)\" (mouseleave)=\"onItemMouseLeave()\"\r\n (mouseover)=\"onItemMouseOver()\">\r\n <div class=\"d-flex align-items-center justify-content-between pt-2 pb-2 px-2 item-sidebar\" (click)=\"toggle()\"\r\n (mousedown)=\"onMiddleClick($event)\" (contextmenu)=\"onRightClick($event)\"\r\n [routerLink]=\"(!item().submenu?.length && item().path && !item().extralink) ? item().path : null\"\r\n [class.active-route]=\"esRutaActiva(item().path)\" [class.cursor-pointer]=\"item().submenu?.length == 0\"\r\n [class.cursor-drow]=\"item().submenu?.length > 0\">\r\n <span>\r\n @if (item().title) {\r\n <i [class]=\"(item().icon ? item().icon : '') + (isSidebarActuallyOpen ? ' me-1' : ' me-1 ms-2')\"></i>\r\n <span class=\"sidebar-text\" [class.sidebar-text--hidden]=\"!isSidebarActuallyOpen\">\r\n {{ item().title }}\r\n </span>\r\n }\r\n </span>\r\n @if (item().submenu?.length > 0) {\r\n <i class=\"fas sidebar-chevron\" [class.sidebar-chevron--hidden]=\"!isSidebarActuallyOpen\" [ngClass]=\"{\r\n 'fa-chevron-down': isOpen(),\r\n 'fa-chevron-right': !isOpen()\r\n }\"></i>\r\n }\r\n </div>\r\n @if (item().submenu?.length && isSidebarActuallyOpen && submenuRendered()) {\r\n <ul class=\"list-unstyled ms-3 submenu\" [class.submenu--closing]=\"!isOpen()\">\r\n @for (child of item().submenu; track $index) {\r\n <app-menu-item [item]=\"child\" [level]=\"level() + 1\" [isSidebarOpen]=\"!isSidebarActuallyOpen\" [parentModuleName]=\"parentModuleName()\" [accentColor]=\"accentColor()\" [accesos]=\"accesos()\" [rolId]=\"rolId()\" />\r\n }\r\n </ul>\r\n }\r\n\r\n @if (flyoutRendered()) {\r\n <div class=\"sidebar-flyout\" [class.sidebar-flyout--closing]=\"!showFlyout()\" [style.top.px]=\"flyoutY()\" [style.max-height]=\"'calc(100dvh - ' + flyoutY() + 'px - 8px)'\"\r\n [style.--flyout-accent]=\"accentColor()\" (mouseenter)=\"onFlyoutMouseEnter()\" (mouseleave)=\"onFlyoutMouseLeave()\">\r\n <div class=\"flyout-header\">\r\n <i [class]=\"(item().icon || '') + ' flyout-header-icon'\"></i>\r\n <span class=\"flyout-header-title\">{{ item().title }}</span>\r\n @if (codAcceso()) {\r\n <span class=\"flyout-header-acceso\">{{ codAcceso().split(': ')[1] }}</span>\r\n }\r\n </div>\r\n @if (item().submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-items\">\r\n @for (child of item().submenu; track $index) {\r\n @if (hasAccess(child)) {\r\n <li class=\"flyout-group\">\r\n <div class=\"flyout-item\" [class.flyout-item-has-children]=\"child.submenu?.length > 0\"\r\n [class.flyout-item-expanded]=\"isFlyoutChildExpanded(child)\" [routerLink]=\"manejarRuta(child)\"\r\n [class.flyout-item-active]=\"!child.submenu?.length && esRutaActiva(child.path)\"\r\n (click)=\"onFlyoutItemClick(child, $event)\" (mousedown)=\"onFlyoutItemMiddleClick($event, child)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, child)\" (mouseenter)=\"showChildTooltip($event, child)\"\r\n (mouseleave)=\"hideChildTooltip()\">\r\n @if (child.icon) {\r\n <i [class]=\"child.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ child.title }}</span>\r\n @if (child.submenu?.length > 0) {\r\n <i class=\"fas flyout-chevron\" [class.fa-chevron-down]=\"isFlyoutChildExpanded(child)\"\r\n [class.fa-chevron-right]=\"!isFlyoutChildExpanded(child)\"></i>\r\n }\r\n </div>\r\n\r\n @if (isFlyoutChildExpanded(child) && child.submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-subitems\">\r\n @for (grandchild of child.submenu; track $index) {\r\n @if (hasAccess(grandchild)) {\r\n <li class=\"flyout-subitem\" [routerLink]=\"manejarRuta(grandchild)\" [class.flyout-subitem-active]=\"esRutaActiva(grandchild.path)\"\r\n (click)=\"onFlyoutGrandchildClick(grandchild)\" (mousedown)=\"onFlyoutItemMiddleClick($event, grandchild)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, grandchild)\"\r\n (mouseenter)=\"showChildTooltip($event, grandchild)\" (mouseleave)=\"hideChildTooltip()\">\r\n @if (grandchild.icon) {\r\n <i [class]=\"grandchild.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ grandchild.title }}</span>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </div>\r\n }\r\n</li>\r\n}\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".active-route{color:var(--sidebar-active-text)!important;background:linear-gradient(90deg,#ffffff24,#ffffff0a)!important;border-left:3px solid var(--sidebar-accent, #c50048)!important;border-radius:0 8px 8px 0!important;box-shadow:inset 0 1px #ffffff0f!important}.cursor-drow{cursor:default}.submenu{transform-origin:top;animation:submenuIn .26s cubic-bezier(.4,0,.2,1) both}.submenu--closing{animation:submenuOut .22s cubic-bezier(.4,0,.2,1) both}@keyframes submenuIn{0%{opacity:0;transform:translateY(-8px) scaleY(.94)}to{opacity:1;transform:translateY(0) scaleY(1)}}@keyframes submenuOut{0%{opacity:1;transform:translateY(0) scaleY(1)}to{opacity:0;transform:translateY(-8px) scaleY(.94)}}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid var(--sidebar-accent, #c50048);display:flex;align-items:center;gap:5px;animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700;color:var(--sidebar-accent, #c50048)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--sidebar-accent, #c50048)}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.sidebar-text{display:inline-block;vertical-align:middle;white-space:normal;word-break:break-word;opacity:1;transform:translate(0);transition:opacity .15s ease .22s,transform .15s ease .22s}.sidebar-text--hidden{opacity:0;transform:translate(-4px);white-space:nowrap;max-width:0;overflow:hidden;transition:opacity .12s ease 0s,transform .12s ease 0s,max-width 0s linear .12s}.sidebar-chevron{opacity:1;transition:opacity .15s ease .22s}.sidebar-chevron--hidden{opacity:0;transition:opacity .12s ease 0s}.item-sidebar{color:var(--sidebar-text-color)!important;transition:all .2s ease;border-radius:8px}.item-sidebar>span:first-child{min-width:0;flex:1}.item-sidebar:hover{color:var(--sidebar-active-text)!important;background:#ffffff17!important;transform:translate(2px)}:host-context(.sidebar.open) .item-sidebar{border-radius:8px 0 0 8px;margin-right:-8px}:host-context(.sidebar.open) .item-sidebar:hover{transform:none}:host-context(.sidebar.open) .item-sidebar.active-route{border-radius:0!important;background:#ffffff24!important}.sidebar-flyout{position:fixed;left:70px;z-index:9999;min-width:220px;max-width:300px;overflow-y:auto;scrollbar-width:none;background:linear-gradient(160deg,var(--sidebar-gradient-start, #1a1a2e) 0%,var(--sidebar-bg, #16213e) 100%);border:1px solid rgba(255,255,255,.1);border-left:3px solid var(--flyout-accent, #c50048);border-radius:0 12px 12px;box-shadow:8px 6px 32px #0000008c,0 0 0 1px #ffffff0a;animation:flyout-slide-in .15s cubic-bezier(.25,.46,.45,.94);pointer-events:auto}.sidebar-flyout--closing{animation:flyout-slide-out .13s ease-in both}@keyframes flyout-slide-out{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-8px)}}.flyout-header{display:flex;align-items:center;gap:10px;padding:12px 16px 10px;border-bottom:1px solid rgba(255,255,255,.08);background:#ffffff0a}.flyout-header-icon{color:var(--flyout-accent, #c50048);font-size:14px;min-width:16px;text-align:center}.flyout-header-title{font-size:12px;font-weight:700;color:var(--sidebar-active-text, #fff);letter-spacing:.5px;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.flyout-header-acceso{font-size:10px;font-weight:700;font-family:monospace;color:var(--flyout-accent, #c50048);background:#ffffff12;border:1px solid rgba(255,255,255,.1);border-left:2px solid var(--flyout-accent, #c50048);padding:2px 7px;border-radius:4px;white-space:nowrap;flex-shrink:0}.flyout-items{padding:6px;margin:0}.flyout-item{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:8px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .7));font-size:13px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden;position:relative}.flyout-item:hover{background:#ffffff1a;color:var(--sidebar-active-text, #fff);transform:translate(3px)}.flyout-item-active{background:linear-gradient(90deg,#ffffff21,#ffffff08)!important;color:var(--sidebar-active-text, #fff)!important}.flyout-item-active:before{content:\"\";position:absolute;left:0;top:15%;height:70%;width:3px;background:var(--flyout-accent, #c50048);border-radius:0 2px 2px 0}.flyout-item-icon{font-size:12px;min-width:14px;text-align:center;color:inherit;opacity:.75}.flyout-item-label{flex:1;overflow:hidden;text-overflow:ellipsis}.flyout-chevron{font-size:10px;opacity:.5;margin-left:auto;flex-shrink:0;transition:transform .2s ease}.flyout-group{display:flex;flex-direction:column}.flyout-item-has-children{cursor:default}.flyout-item-expanded{background:#ffffff12!important;color:var(--sidebar-active-text, #fff)!important}.flyout-subitems{padding:2px 6px 2px 14px;border-left:2px solid rgba(255,255,255,.1);margin:0 6px 4px 20px}.flyout-subitem{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:6px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .65));font-size:12px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden}.flyout-subitem:hover{background:#ffffff17;color:var(--sidebar-active-text, #fff);transform:translate(2px)}.flyout-subitem-active{color:var(--sidebar-active-text, #fff)!important;position:relative}.flyout-subitem-active:before{content:\"\";position:absolute;left:-14px;top:20%;height:60%;width:2px;background:var(--flyout-accent, #c50048);border-radius:1px}@keyframes flyout-slide-in{0%{opacity:0;transform:translate(-10px)}to{opacity:1;transform:translate(0)}}\n"] }]
509
- }], ctorParameters: () => [] });
508
+ args: [{ selector: 'app-menu-item', imports: [NgClass, RouterLink], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if(hasAccess()){\r\n<li (mouseenter)=\"onItemMouseEnter($event)\" (mouseleave)=\"onItemMouseLeave()\"\r\n (mouseover)=\"onItemMouseOver()\">\r\n <div class=\"d-flex align-items-center justify-content-between pt-2 pb-2 px-2 item-sidebar\" (click)=\"toggle()\"\r\n (mousedown)=\"onMiddleClick($event)\" (contextmenu)=\"onRightClick($event)\"\r\n [routerLink]=\"(!item().submenu?.length && item().path && !item().extralink) ? item().path : null\"\r\n [class.active-route]=\"esRutaActiva(item().path)\" [class.cursor-pointer]=\"item().submenu?.length == 0\"\r\n [class.cursor-drow]=\"item().submenu?.length > 0\">\r\n <span>\r\n @if (item().title) {\r\n <i [class]=\"(item().icon ? item().icon : '') + (isSidebarActuallyOpen ? ' me-1' : ' me-1 ms-2')\"></i>\r\n <span class=\"sidebar-text\" [class.sidebar-text--hidden]=\"!isSidebarActuallyOpen\">\r\n {{ item().title }}\r\n </span>\r\n }\r\n </span>\r\n @if (item().submenu?.length > 0) {\r\n <i class=\"fas sidebar-chevron\" [class.sidebar-chevron--hidden]=\"!isSidebarActuallyOpen\" [ngClass]=\"{\r\n 'fa-chevron-down': isOpen(),\r\n 'fa-chevron-right': !isOpen()\r\n }\"></i>\r\n }\r\n </div>\r\n @if (item().submenu?.length && isSidebarActuallyOpen && submenuRendered()) {\r\n <ul class=\"list-unstyled ms-3 submenu\" [class.submenu--closing]=\"!isOpen()\">\r\n @for (child of item().submenu; track $index) {\r\n <app-menu-item [item]=\"child\" [level]=\"level() + 1\" [isSidebarOpen]=\"!isSidebarActuallyOpen\" [parentModuleName]=\"parentModuleName()\" [accentColor]=\"accentColor()\" [accesos]=\"accesos()\" [rolId]=\"rolId()\" />\r\n }\r\n </ul>\r\n }\r\n\r\n @if (flyoutRendered()) {\r\n <div class=\"sidebar-flyout\" [class.sidebar-flyout--closing]=\"!showFlyout()\" [style.top.px]=\"flyoutY()\" [style.max-height]=\"'calc(100dvh - ' + flyoutY() + 'px - 8px)'\"\r\n [style.--flyout-accent]=\"accentColor()\" (mouseenter)=\"onFlyoutMouseEnter()\" (mouseleave)=\"onFlyoutMouseLeave()\">\r\n <div class=\"flyout-header\">\r\n <i [class]=\"(item().icon || '') + ' flyout-header-icon'\"></i>\r\n <span class=\"flyout-header-title\">{{ item().title }}</span>\r\n @if (codAcceso()) {\r\n <span class=\"flyout-header-acceso\">{{ codAcceso().split(': ')[1] }}</span>\r\n }\r\n </div>\r\n @if (item().submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-items\">\r\n @for (child of item().submenu; track $index) {\r\n @if (hasAccess(child)) {\r\n <li class=\"flyout-group\">\r\n <div class=\"flyout-item\" [class.flyout-item-has-children]=\"child.submenu?.length > 0\"\r\n [class.flyout-item-expanded]=\"isFlyoutChildExpanded(child)\" [routerLink]=\"manejarRuta(child)\"\r\n [class.flyout-item-active]=\"!child.submenu?.length && esRutaActiva(child.path)\"\r\n (click)=\"onFlyoutItemClick(child, $event)\" (mousedown)=\"onFlyoutItemMiddleClick($event, child)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, child)\" (mouseenter)=\"showChildTooltip($event, child)\"\r\n (mouseleave)=\"hideChildTooltip()\">\r\n @if (child.icon) {\r\n <i [class]=\"child.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ child.title }}</span>\r\n @if (child.submenu?.length > 0) {\r\n <i class=\"fas flyout-chevron\" [class.fa-chevron-down]=\"isFlyoutChildExpanded(child)\"\r\n [class.fa-chevron-right]=\"!isFlyoutChildExpanded(child)\"></i>\r\n }\r\n </div>\r\n\r\n @if (isFlyoutChildExpanded(child) && child.submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-subitems\">\r\n @for (grandchild of child.submenu; track $index) {\r\n @if (hasAccess(grandchild)) {\r\n <li class=\"flyout-subitem\" [routerLink]=\"manejarRuta(grandchild)\" [class.flyout-subitem-active]=\"esRutaActiva(grandchild.path)\"\r\n (click)=\"onFlyoutGrandchildClick(grandchild)\" (mousedown)=\"onFlyoutItemMiddleClick($event, grandchild)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, grandchild)\"\r\n (mouseenter)=\"showChildTooltip($event, grandchild)\" (mouseleave)=\"hideChildTooltip()\">\r\n @if (grandchild.icon) {\r\n <i [class]=\"grandchild.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ grandchild.title }}</span>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </div>\r\n }\r\n</li>\r\n}\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".active-route{color:var(--sidebar-active-text)!important;background:linear-gradient(90deg,#ffffff24,#ffffff0a)!important;border-left:3px solid var(--sidebar-accent, #c50048)!important;border-radius:0 8px 8px 0!important;box-shadow:inset 0 1px #ffffff0f!important}.cursor-drow{cursor:default}.submenu{transform-origin:top;animation:submenuIn .26s cubic-bezier(.4,0,.2,1) both}.submenu--closing{animation:submenuOut .22s cubic-bezier(.4,0,.2,1) both}@keyframes submenuIn{0%{opacity:0;transform:translateY(-8px) scaleY(.94)}to{opacity:1;transform:translateY(0) scaleY(1)}}@keyframes submenuOut{0%{opacity:1;transform:translateY(0) scaleY(1)}to{opacity:0;transform:translateY(-8px) scaleY(.94)}}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid var(--sidebar-accent, #c50048);display:flex;align-items:center;gap:5px}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700;color:var(--sidebar-accent, #c50048)}.acceso-tooltip-fixed{animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--sidebar-accent, #c50048)}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.sidebar-text{display:inline-block;vertical-align:middle;white-space:normal;word-break:break-word;opacity:1;transform:translate(0);transition:opacity .15s ease .22s,transform .15s ease .22s}.sidebar-text--hidden{opacity:0;transform:translate(-4px);white-space:nowrap;max-width:0;overflow:hidden;transition:opacity .12s ease 0s,transform .12s ease 0s,max-width 0s linear .12s}.sidebar-chevron{opacity:1;transition:opacity .15s ease .22s}.sidebar-chevron--hidden{opacity:0;transition:opacity .12s ease 0s}.item-sidebar{color:var(--sidebar-text-color)!important;transition:all .2s ease;border-radius:8px}.item-sidebar>span:first-child{min-width:0;flex:1}.item-sidebar:hover{color:var(--sidebar-active-text)!important;background:#ffffff17!important;transform:translate(2px)}:host-context(.sidebar.open) .item-sidebar{border-radius:8px 0 0 8px;margin-right:-8px}:host-context(.sidebar.open) .item-sidebar:hover{transform:none}:host-context(.sidebar.open) .item-sidebar.active-route{border-radius:0!important;background:#ffffff24!important}.sidebar-flyout{position:fixed;left:70px;z-index:9999;min-width:220px;max-width:300px;overflow-y:auto;scrollbar-width:none;background:linear-gradient(160deg,var(--sidebar-gradient-start, #1a1a2e) 0%,var(--sidebar-bg, #16213e) 100%);border:1px solid rgba(255,255,255,.1);border-left:3px solid var(--flyout-accent, #c50048);border-radius:0 12px 12px;box-shadow:8px 6px 32px #0000008c,0 0 0 1px #ffffff0a;animation:flyout-slide-in .15s cubic-bezier(.25,.46,.45,.94);pointer-events:auto}.sidebar-flyout--closing{animation:flyout-slide-out .13s ease-in both}@keyframes flyout-slide-out{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-8px)}}.flyout-header{display:flex;align-items:center;gap:10px;padding:12px 16px 10px;border-bottom:1px solid rgba(255,255,255,.08);background:#ffffff0a}.flyout-header-icon{color:var(--flyout-accent, #c50048);font-size:14px;min-width:16px;text-align:center}.flyout-header-title{font-size:12px;font-weight:700;color:var(--sidebar-active-text, #fff);letter-spacing:.5px;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.flyout-header-acceso{font-size:10px;font-weight:700;font-family:monospace;color:var(--flyout-accent, #c50048);background:#ffffff12;border:1px solid rgba(255,255,255,.1);border-left:2px solid var(--flyout-accent, #c50048);padding:2px 7px;border-radius:4px;white-space:nowrap;flex-shrink:0}.flyout-items{padding:6px;margin:0}.flyout-item{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:8px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .7));font-size:13px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden;position:relative}.flyout-item:hover{background:#ffffff1a;color:var(--sidebar-active-text, #fff);transform:translate(3px)}.flyout-item-active{background:linear-gradient(90deg,#ffffff21,#ffffff08)!important;color:var(--sidebar-active-text, #fff)!important}.flyout-item-active:before{content:\"\";position:absolute;left:0;top:15%;height:70%;width:3px;background:var(--flyout-accent, #c50048);border-radius:0 2px 2px 0}.flyout-item-icon{font-size:12px;min-width:14px;text-align:center;color:inherit;opacity:.75}.flyout-item-label{flex:1;overflow:hidden;text-overflow:ellipsis}.flyout-chevron{font-size:10px;opacity:.5;margin-left:auto;flex-shrink:0;transition:transform .2s ease}.flyout-group{display:flex;flex-direction:column}.flyout-item-has-children{cursor:default}.flyout-item-expanded{background:#ffffff12!important;color:var(--sidebar-active-text, #fff)!important}.flyout-subitems{padding:2px 6px 2px 14px;border-left:2px solid rgba(255,255,255,.1);margin:0 6px 4px 20px}.flyout-subitem{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:6px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .65));font-size:12px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden}.flyout-subitem:hover{background:#ffffff17;color:var(--sidebar-active-text, #fff);transform:translate(2px)}.flyout-subitem-active{color:var(--sidebar-active-text, #fff)!important;position:relative}.flyout-subitem-active:before{content:\"\";position:absolute;left:-14px;top:20%;height:60%;width:2px;background:var(--flyout-accent, #c50048);border-radius:1px}@keyframes flyout-slide-in{0%{opacity:0;transform:translate(-10px)}to{opacity:1;transform:translate(0)}}\n"] }]
509
+ }], ctorParameters: () => [], propDecorators: { item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }], isSidebarOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isSidebarOpen", required: false }] }], isSidebarHovering: [{ type: i0.Input, args: [{ isSignal: true, alias: "isSidebarHovering", required: false }] }], level: [{ type: i0.Input, args: [{ isSignal: true, alias: "level", required: false }] }], parentModuleName: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentModuleName", required: false }] }], accentColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "accentColor", required: false }] }], accesos: [{ type: i0.Input, args: [{ isSignal: true, alias: "accesos", required: false }] }], rolId: [{ type: i0.Input, args: [{ isSignal: true, alias: "rolId", required: false }] }] } });
510
510
 
511
511
  class BottomNavigationComponent {
512
- menuItems = input([]);
513
- isVisible = input(true);
512
+ menuItems = input([], ...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
513
+ isVisible = input(true, ...(ngDevMode ? [{ debugName: "isVisible" }] : /* istanbul ignore next */ []));
514
514
  itemClick = output();
515
- activeDropdown = signal(null);
515
+ activeDropdown = signal(null, ...(ngDevMode ? [{ debugName: "activeDropdown" }] : /* istanbul ignore next */ []));
516
516
  onDocumentClick() {
517
517
  this.activeDropdown.set(null);
518
518
  }
@@ -542,13 +542,13 @@ class BottomNavigationComponent {
542
542
  subItem.action();
543
543
  }
544
544
  onDropdownClick(event) { event.stopPropagation(); }
545
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: BottomNavigationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
546
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: BottomNavigationComponent, isStandalone: true, selector: "app-bottom-navigation", inputs: { menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: false, transformFunction: null }, isVisible: { classPropertyName: "isVisible", publicName: "isVisible", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick" }, host: { listeners: { "document:click": "onDocumentClick()" } }, ngImport: i0, template: "<nav class=\"bottom-nav\" [class.visible]=\"isVisible()\">\r\n @for (item of menuItems(); track $index) {\r\n @if (item.type == 'dropdown') {\r\n <div class=\"bottom-nav-dropdown\">\r\n <button class=\"bottom-nav-item\" [class.active]=\"activeDropdown() === $index\"\r\n (click)=\"onItemClick($index, item, $event); toggleDropdown($index, $event)\">\r\n <i [class]=\"item.icon\"></i>\r\n <span>{{ item.label }}</span>\r\n </button>\r\n\r\n @if (activeDropdown() == $index) {\r\n <div class=\"dropdown-menu show\" (click)=\"onDropdownClick($event)\">\r\n @for (subItem of item.items; track subItem.label; let last = $last; let first = $first) {\r\n <button class=\"dropdown-item\"\r\n [ngClass]=\"{'border-top-radius': first, 'border-bottom-radius': last}\"\r\n (click)=\"onSubItemClick(subItem, $event)\">\r\n\r\n <i [class]=\"subItem.icon\" class=\"me-2\"></i>\r\n <span class=\"flex-grow-1\">{{ subItem.label }}</span>\r\n\r\n @if (subItem.value) {\r\n <span class=\"fw-semibold ms-2\">{{ subItem.value }}</span>\r\n }\r\n </button>\r\n\r\n }\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <button class=\"bottom-nav-item\" [class.active]=\"item.active\" (click)=\"onItemClick($index, item, $event)\">\r\n <i [class]=\"item.icon\"></i>\r\n <span>{{ item.label }}</span>\r\n </button>\r\n }\r\n }\r\n</nav>\r\n", styles: [".bottom-nav{position:fixed;bottom:0;left:0;right:0;background:var(--sidebar-bg, #ffffff);box-shadow:0 -2px 10px #0000001a;display:flex;justify-content:space-evenly;align-items:center;padding:8px 12px;z-index:1050;border-top:1px solid var(--font-border-input, #e0e0e0);transform:translateY(100%);transition:transform .3s cubic-bezier(.4,0,.2,1);height:60px}.bottom-nav.visible{transform:translateY(0)}@media(min-width:1192px){.bottom-nav{display:none}}.bottom-nav-item{display:flex;flex-direction:column;align-items:center;justify-content:center;background:none;border:none;padding:4px 2px;cursor:pointer;color:var(--sidebar-text-color, #666);transition:all .2s ease;border-radius:8px;flex:1;min-width:0;max-width:none;position:relative}.bottom-nav-item i{font-size:20px;margin-bottom:2px;transition:transform .2s cubic-bezier(.4,0,.2,1)}.bottom-nav-item span{font-size:11px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.bottom-nav-item:active{background:var(--bs-table-hover-bg, #f0f0f0);transform:scale(.95)}.bottom-nav-item.active{color:#398bf7}.bottom-nav-item.active i{transform:translateY(-2px)}.bottom-nav-dropdown{position:static;flex:1;display:flex;justify-content:center}.dropdown-menu{position:fixed;bottom:52px;left:50%;transform:translate(-50%) scale(.9);transform-origin:bottom center;background:var(--background-card, #ffffff);border:1px solid var(--border-color-modal, #dee2e6);border-radius:16px;padding:0;min-width:260px;max-width:90%;max-height:70vh;box-shadow:0 -4px 20px #00000026;z-index:1060;margin-bottom:10px;opacity:0;visibility:hidden;transition:all .25s cubic-bezier(.4,0,.2,1);pointer-events:none;overflow:hidden}.dropdown-menu.show{opacity:1;visibility:visible;transform:translate(-50%) scale(1);pointer-events:auto}.dropdown-menu .dropdown-item{display:flex;align-items:center;padding:14px 16px;font-size:10px;color:var(--text-color, #333);background:none;border:none;width:100%;text-align:left;border-bottom:1px solid var(--border-color-modal, #f0f0f0);opacity:0;transform:translateY(10px);animation:slideInItem .2s cubic-bezier(.4,0,.2,1) forwards;animation-delay:calc(.03s * var(--item-index, 0))}.dropdown-menu .dropdown-item:last-child{border-bottom:none}.dropdown-menu .dropdown-item i{width:24px;font-size:12px;transition:transform .2s ease}.dropdown-menu .dropdown-item:hover{background:var(--bs-table-hover-bg, #f8f9fa)}.dropdown-menu .dropdown-item:hover i{transform:scale(1.1)}.dropdown-menu .dropdown-item:active{background:var(--bs-table-hover-bg, #e9ecef);transform:scale(.98)}@keyframes slideInItem{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@media(max-width:480px){.bottom-nav-item span{font-size:10px}.bottom-nav-item i{font-size:18px}.dropdown-menu{min-width:220px}.dropdown-menu .dropdown-item{padding:12px 14px;font-size:10px}}@media(max-width:360px){.bottom-nav-item i{font-size:18px;margin-bottom:1px}.bottom-nav-item span{font-size:10px;font-weight:500}.dropdown-menu{min-width:200px}}.dropdown-overlay{position:fixed;inset:0;background:transparent;z-index:1055;display:none}.dropdown-overlay.active{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
545
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: BottomNavigationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
546
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: BottomNavigationComponent, isStandalone: true, selector: "app-bottom-navigation", inputs: { menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: false, transformFunction: null }, isVisible: { classPropertyName: "isVisible", publicName: "isVisible", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick" }, host: { listeners: { "document:click": "onDocumentClick()" } }, ngImport: i0, template: "<nav class=\"bottom-nav\" [class.visible]=\"isVisible()\">\r\n @for (item of menuItems(); track $index) {\r\n @if (item.type == 'dropdown') {\r\n <div class=\"bottom-nav-dropdown\">\r\n <button class=\"bottom-nav-item\" [class.active]=\"activeDropdown() === $index\"\r\n (click)=\"onItemClick($index, item, $event); toggleDropdown($index, $event)\">\r\n <i [class]=\"item.icon\"></i>\r\n <span>{{ item.label }}</span>\r\n </button>\r\n\r\n @if (activeDropdown() == $index) {\r\n <div class=\"dropdown-menu show\" (click)=\"onDropdownClick($event)\">\r\n @for (subItem of item.items; track subItem.label; let last = $last; let first = $first) {\r\n <button class=\"dropdown-item\"\r\n [ngClass]=\"{'border-top-radius': first, 'border-bottom-radius': last}\"\r\n (click)=\"onSubItemClick(subItem, $event)\">\r\n\r\n <i [class]=\"subItem.icon\" class=\"me-2\"></i>\r\n <span class=\"flex-grow-1\">{{ subItem.label }}</span>\r\n\r\n @if (subItem.value) {\r\n <span class=\"fw-semibold ms-2\">{{ subItem.value }}</span>\r\n }\r\n </button>\r\n\r\n }\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <button class=\"bottom-nav-item\" [class.active]=\"item.active\" (click)=\"onItemClick($index, item, $event)\">\r\n <i [class]=\"item.icon\"></i>\r\n <span>{{ item.label }}</span>\r\n </button>\r\n }\r\n }\r\n</nav>\r\n", styles: [".bottom-nav{position:fixed;bottom:0;left:0;right:0;background:var(--sidebar-bg, #ffffff);box-shadow:0 -2px 10px #0000001a;display:flex;justify-content:space-evenly;align-items:center;padding:8px 12px;z-index:1050;border-top:1px solid var(--font-border-input, #e0e0e0);transform:translateY(100%);transition:transform .3s cubic-bezier(.4,0,.2,1);height:60px}.bottom-nav.visible{transform:translateY(0)}@media(min-width:1192px){.bottom-nav{display:none}}.bottom-nav-item{display:flex;flex-direction:column;align-items:center;justify-content:center;background:none;border:none;padding:4px 2px;cursor:pointer;color:var(--sidebar-text-color, #666);transition:all .2s ease;border-radius:8px;flex:1;min-width:0;max-width:none;position:relative}.bottom-nav-item i{font-size:20px;margin-bottom:2px;transition:transform .2s cubic-bezier(.4,0,.2,1)}.bottom-nav-item span{font-size:11px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.bottom-nav-item:active{background:var(--bs-table-hover-bg, #f0f0f0);transform:scale(.95)}.bottom-nav-item.active{color:#398bf7}.bottom-nav-item.active i{transform:translateY(-2px)}.bottom-nav-dropdown{position:static;flex:1;display:flex;justify-content:center}.dropdown-menu{position:fixed;bottom:52px;left:50%;transform:translate(-50%) scale(.9);transform-origin:bottom center;background:var(--background-card, #ffffff);border:1px solid var(--border-color-modal, #dee2e6);border-radius:16px;padding:0;min-width:260px;max-width:90%;max-height:70vh;box-shadow:0 -4px 20px #00000026;z-index:1060;margin-bottom:10px;opacity:0;visibility:hidden;transition:all .25s cubic-bezier(.4,0,.2,1);pointer-events:none;overflow:hidden}.dropdown-menu.show{opacity:1;visibility:visible;transform:translate(-50%) scale(1);pointer-events:auto}.dropdown-menu .dropdown-item{display:flex;align-items:center;padding:14px 16px;font-size:10px;color:var(--text-color, #333);background:none;border:none;width:100%;text-align:left;border-bottom:1px solid var(--border-color-modal, #f0f0f0);opacity:0;transform:translateY(10px);animation:slideInItem .2s cubic-bezier(.4,0,.2,1) forwards;animation-delay:calc(.03s * var(--item-index, 0))}.dropdown-menu .dropdown-item:last-child{border-bottom:none}.dropdown-menu .dropdown-item i{width:24px;font-size:12px;transition:transform .2s ease}.dropdown-menu .dropdown-item:hover{background:var(--bs-table-hover-bg, #f8f9fa)}.dropdown-menu .dropdown-item:hover i{transform:scale(1.1)}.dropdown-menu .dropdown-item:active{background:var(--bs-table-hover-bg, #e9ecef);transform:scale(.98)}@keyframes slideInItem{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@media(max-width:480px){.bottom-nav-item span{font-size:10px}.bottom-nav-item i{font-size:18px}.dropdown-menu{min-width:220px}.dropdown-menu .dropdown-item{padding:12px 14px;font-size:10px}}@media(max-width:360px){.bottom-nav-item i{font-size:18px;margin-bottom:1px}.bottom-nav-item span{font-size:10px;font-weight:500}.dropdown-menu{min-width:200px}}.dropdown-overlay{position:fixed;inset:0;background:transparent;z-index:1055;display:none}.dropdown-overlay.active{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
547
547
  }
548
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: BottomNavigationComponent, decorators: [{
548
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: BottomNavigationComponent, decorators: [{
549
549
  type: Component,
550
550
  args: [{ selector: 'app-bottom-navigation', imports: [CommonModule], template: "<nav class=\"bottom-nav\" [class.visible]=\"isVisible()\">\r\n @for (item of menuItems(); track $index) {\r\n @if (item.type == 'dropdown') {\r\n <div class=\"bottom-nav-dropdown\">\r\n <button class=\"bottom-nav-item\" [class.active]=\"activeDropdown() === $index\"\r\n (click)=\"onItemClick($index, item, $event); toggleDropdown($index, $event)\">\r\n <i [class]=\"item.icon\"></i>\r\n <span>{{ item.label }}</span>\r\n </button>\r\n\r\n @if (activeDropdown() == $index) {\r\n <div class=\"dropdown-menu show\" (click)=\"onDropdownClick($event)\">\r\n @for (subItem of item.items; track subItem.label; let last = $last; let first = $first) {\r\n <button class=\"dropdown-item\"\r\n [ngClass]=\"{'border-top-radius': first, 'border-bottom-radius': last}\"\r\n (click)=\"onSubItemClick(subItem, $event)\">\r\n\r\n <i [class]=\"subItem.icon\" class=\"me-2\"></i>\r\n <span class=\"flex-grow-1\">{{ subItem.label }}</span>\r\n\r\n @if (subItem.value) {\r\n <span class=\"fw-semibold ms-2\">{{ subItem.value }}</span>\r\n }\r\n </button>\r\n\r\n }\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <button class=\"bottom-nav-item\" [class.active]=\"item.active\" (click)=\"onItemClick($index, item, $event)\">\r\n <i [class]=\"item.icon\"></i>\r\n <span>{{ item.label }}</span>\r\n </button>\r\n }\r\n }\r\n</nav>\r\n", styles: [".bottom-nav{position:fixed;bottom:0;left:0;right:0;background:var(--sidebar-bg, #ffffff);box-shadow:0 -2px 10px #0000001a;display:flex;justify-content:space-evenly;align-items:center;padding:8px 12px;z-index:1050;border-top:1px solid var(--font-border-input, #e0e0e0);transform:translateY(100%);transition:transform .3s cubic-bezier(.4,0,.2,1);height:60px}.bottom-nav.visible{transform:translateY(0)}@media(min-width:1192px){.bottom-nav{display:none}}.bottom-nav-item{display:flex;flex-direction:column;align-items:center;justify-content:center;background:none;border:none;padding:4px 2px;cursor:pointer;color:var(--sidebar-text-color, #666);transition:all .2s ease;border-radius:8px;flex:1;min-width:0;max-width:none;position:relative}.bottom-nav-item i{font-size:20px;margin-bottom:2px;transition:transform .2s cubic-bezier(.4,0,.2,1)}.bottom-nav-item span{font-size:11px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.bottom-nav-item:active{background:var(--bs-table-hover-bg, #f0f0f0);transform:scale(.95)}.bottom-nav-item.active{color:#398bf7}.bottom-nav-item.active i{transform:translateY(-2px)}.bottom-nav-dropdown{position:static;flex:1;display:flex;justify-content:center}.dropdown-menu{position:fixed;bottom:52px;left:50%;transform:translate(-50%) scale(.9);transform-origin:bottom center;background:var(--background-card, #ffffff);border:1px solid var(--border-color-modal, #dee2e6);border-radius:16px;padding:0;min-width:260px;max-width:90%;max-height:70vh;box-shadow:0 -4px 20px #00000026;z-index:1060;margin-bottom:10px;opacity:0;visibility:hidden;transition:all .25s cubic-bezier(.4,0,.2,1);pointer-events:none;overflow:hidden}.dropdown-menu.show{opacity:1;visibility:visible;transform:translate(-50%) scale(1);pointer-events:auto}.dropdown-menu .dropdown-item{display:flex;align-items:center;padding:14px 16px;font-size:10px;color:var(--text-color, #333);background:none;border:none;width:100%;text-align:left;border-bottom:1px solid var(--border-color-modal, #f0f0f0);opacity:0;transform:translateY(10px);animation:slideInItem .2s cubic-bezier(.4,0,.2,1) forwards;animation-delay:calc(.03s * var(--item-index, 0))}.dropdown-menu .dropdown-item:last-child{border-bottom:none}.dropdown-menu .dropdown-item i{width:24px;font-size:12px;transition:transform .2s ease}.dropdown-menu .dropdown-item:hover{background:var(--bs-table-hover-bg, #f8f9fa)}.dropdown-menu .dropdown-item:hover i{transform:scale(1.1)}.dropdown-menu .dropdown-item:active{background:var(--bs-table-hover-bg, #e9ecef);transform:scale(.98)}@keyframes slideInItem{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@media(max-width:480px){.bottom-nav-item span{font-size:10px}.bottom-nav-item i{font-size:18px}.dropdown-menu{min-width:220px}.dropdown-menu .dropdown-item{padding:12px 14px;font-size:10px}}@media(max-width:360px){.bottom-nav-item i{font-size:18px;margin-bottom:1px}.bottom-nav-item span{font-size:10px;font-weight:500}.dropdown-menu{min-width:200px}}.dropdown-overlay{position:fixed;inset:0;background:transparent;z-index:1055;display:none}.dropdown-overlay.active{display:block}\n"] }]
551
- }], propDecorators: { onDocumentClick: [{
551
+ }], propDecorators: { menuItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuItems", required: false }] }], isVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "isVisible", required: false }] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }], onDocumentClick: [{
552
552
  type: HostListener,
553
553
  args: ['document:click']
554
554
  }] } });
@@ -563,37 +563,36 @@ class VerticalHeaderComponent {
563
563
  // en vez de depender de un breakpoint fijo.
564
564
  static SEARCH_WIDTH = 280;
565
565
  static SEARCH_GAP = 16;
566
- searchCollapsed = signal(false);
566
+ searchCollapsed = signal(false, ...(ngDevMode ? [{ debugName: "searchCollapsed" }] : /* istanbul ignore next */ []));
567
567
  resizeObserver;
568
- ngZone = inject(NgZone);
569
568
  router = inject(Router);
570
569
  tabsService = inject(TabsService);
571
- actions = input([]);
570
+ actions = input([], ...(ngDevMode ? [{ debugName: "actions" }] : /* istanbul ignore next */ []));
572
571
  // Algunas apps solo muestran el buscador global a ciertos roles.
573
- showSearch = input(true);
572
+ showSearch = input(true, ...(ngDevMode ? [{ debugName: "showSearch" }] : /* istanbul ignore next */ []));
574
573
  themes = input([
575
574
  { id: 'light', icon: 'fa-sun', label: 'Claro' },
576
575
  { id: 'dark', icon: 'fa-moon', label: 'Oscuro' },
577
576
  { id: 'sky-blue', icon: 'fa-cloud', label: 'Sky Blue' },
578
577
  { id: 'system', icon: 'fa-desktop', label: 'Sistema' },
579
- ]);
580
- showThemeSwitcher = input(true);
581
- showTabs = input(true);
578
+ ], ...(ngDevMode ? [{ debugName: "themes" }] : /* istanbul ignore next */ []));
579
+ showThemeSwitcher = input(true, ...(ngDevMode ? [{ debugName: "showThemeSwitcher" }] : /* istanbul ignore next */ []));
580
+ showTabs = input(true, ...(ngDevMode ? [{ debugName: "showTabs" }] : /* istanbul ignore next */ []));
582
581
  // Notificaciones: estándar en todas las apps TSI, ícono y estilo fijos —
583
582
  // el consumidor solo decide si se muestra y provee el contador y el click.
584
- showNotifications = input(false);
585
- notificationsCount = input(0);
583
+ showNotifications = input(false, ...(ngDevMode ? [{ debugName: "showNotifications" }] : /* istanbul ignore next */ []));
584
+ notificationsCount = input(0, ...(ngDevMode ? [{ debugName: "notificationsCount" }] : /* istanbul ignore next */ []));
586
585
  notificationsClick = output();
587
586
  /** Opt-in: además de en el header, refleja las notificaciones en el bottom-nav (mobile). Por defecto no baja (igual que en consults). */
588
- notificationsInBottomNav = input(false);
587
+ notificationsInBottomNav = input(false, ...(ngDevMode ? [{ debugName: "notificationsInBottomNav" }] : /* istanbul ignore next */ []));
589
588
  // Soporte (chatbot): ídem, ícono y estilo fijos — el consumidor solo
590
589
  // decide si está disponible y controla su visibilidad.
591
- showChatbotToggle = input(false);
592
- chatbotVisible = input(false);
590
+ showChatbotToggle = input(false, ...(ngDevMode ? [{ debugName: "showChatbotToggle" }] : /* istanbul ignore next */ []));
591
+ chatbotVisible = input(false, ...(ngDevMode ? [{ debugName: "chatbotVisible" }] : /* istanbul ignore next */ []));
593
592
  chatbotVisibleChange = output();
594
593
  /** Opt-in: además de en el header, refleja el toggle de soporte en el bottom-nav (mobile). Por defecto no baja. */
595
- chatbotInBottomNav = input(false);
596
- currentTheme = input('light');
594
+ chatbotInBottomNav = input(false, ...(ngDevMode ? [{ debugName: "chatbotInBottomNav" }] : /* istanbul ignore next */ []));
595
+ currentTheme = input('light', ...(ngDevMode ? [{ debugName: "currentTheme" }] : /* istanbul ignore next */ []));
597
596
  themeChange = output();
598
597
  // Espejo de las acciones del header hacia el bottom-nav (mobile): mismo dato,
599
598
  // sin listas separadas — cada pieza (notificaciones, soporte, acciones) decide
@@ -631,32 +630,32 @@ class VerticalHeaderComponent {
631
630
  }
632
631
  }
633
632
  return items;
634
- });
635
- themeIcon = computed(() => this.themes().find(item => item.id === this.currentTheme())?.icon ?? 'fa-palette');
636
- themeLabel = computed(() => this.themes().find(item => item.id === this.currentTheme())?.label ?? 'Personalizado');
637
- versionApp = input('');
638
- accentColor = input('#398bf7');
639
- envClass = input('prod');
640
- produccion = input(false);
633
+ }, ...(ngDevMode ? [{ debugName: "bottomNavItems" }] : /* istanbul ignore next */ []));
634
+ themeIcon = computed(() => this.themes().find(item => item.id === this.currentTheme())?.icon ?? 'fa-palette', ...(ngDevMode ? [{ debugName: "themeIcon" }] : /* istanbul ignore next */ []));
635
+ themeLabel = computed(() => this.themes().find(item => item.id === this.currentTheme())?.label ?? 'Personalizado', ...(ngDevMode ? [{ debugName: "themeLabel" }] : /* istanbul ignore next */ []));
636
+ versionApp = input('', ...(ngDevMode ? [{ debugName: "versionApp" }] : /* istanbul ignore next */ []));
637
+ accentColor = input('#398bf7', ...(ngDevMode ? [{ debugName: "accentColor" }] : /* istanbul ignore next */ []));
638
+ envClass = input('prod', ...(ngDevMode ? [{ debugName: "envClass" }] : /* istanbul ignore next */ []));
639
+ produccion = input(false, ...(ngDevMode ? [{ debugName: "produccion" }] : /* istanbul ignore next */ []));
641
640
  emitirToogle = output();
642
- isScrolled = input(false);
643
- isSidebarOpen = input(false);
644
- nameProyecto = input('');
641
+ isScrolled = input(false, ...(ngDevMode ? [{ debugName: "isScrolled" }] : /* istanbul ignore next */ []));
642
+ isSidebarOpen = input(false, ...(ngDevMode ? [{ debugName: "isSidebarOpen" }] : /* istanbul ignore next */ []));
643
+ nameProyecto = input('', ...(ngDevMode ? [{ debugName: "nameProyecto" }] : /* istanbul ignore next */ []));
645
644
  searchComponents = output();
646
- showPanelControl = input(true);
645
+ showPanelControl = input(true, ...(ngDevMode ? [{ debugName: "showPanelControl" }] : /* istanbul ignore next */ []));
647
646
  panelControlClick = output();
648
647
  logout = output();
649
648
  // Datos de sesión: se reciben del consumidor (en vez de inyectar SesionService
650
649
  // acá) para que layout-tsi no dependa de core-tsi.
651
- userName = input('');
652
- empresaName = input('');
653
- tooltip = signal(null);
650
+ userName = input('', ...(ngDevMode ? [{ debugName: "userName" }] : /* istanbul ignore next */ []));
651
+ empresaName = input('', ...(ngDevMode ? [{ debugName: "empresaName" }] : /* istanbul ignore next */ []));
652
+ tooltip = signal(null, ...(ngDevMode ? [{ debugName: "tooltip" }] : /* istanbul ignore next */ []));
654
653
  // Reemplazan a ngbDropdown (sin @ng-bootstrap acá): un dropdown nativo por
655
654
  // click, reutilizando las clases de Bootstrap (dropdown/dropdown-menu/show)
656
655
  // que ya vienen estilizadas — así no hace falta reimplementar el CSS.
657
- openActionKey = signal(null);
658
- themeMenuOpen = signal(false);
659
- userMenuOpen = signal(false);
656
+ openActionKey = signal(null, ...(ngDevMode ? [{ debugName: "openActionKey" }] : /* istanbul ignore next */ []));
657
+ themeMenuOpen = signal(false, ...(ngDevMode ? [{ debugName: "themeMenuOpen" }] : /* istanbul ignore next */ []));
658
+ userMenuOpen = signal(false, ...(ngDevMode ? [{ debugName: "userMenuOpen" }] : /* istanbul ignore next */ []));
660
659
  onDocumentClick() {
661
660
  this.tooltip.set(null);
662
661
  this.closeAllMenus();
@@ -704,10 +703,7 @@ class VerticalHeaderComponent {
704
703
  // por igual — evita mezclar guards de rol/hasOpenModals en dos lugares.
705
704
  goToHome() { this.router.navigate(['/atajos']); }
706
705
  ngAfterViewInit() {
707
- // ResizeObserver corre fuera de la zona de Angular (no está parcheado por
708
- // zone.js), así que sin ngZone.run() el signal se actualiza pero la vista
709
- // no se refresca hasta que algo más dispare un ciclo de detección.
710
- this.resizeObserver = new ResizeObserver(() => this.ngZone.run(() => this.updateSearchCollapse()));
706
+ this.resizeObserver = new ResizeObserver(() => this.updateSearchCollapse());
711
707
  this.resizeObserver.observe(this.headerContainerRef.nativeElement);
712
708
  this.resizeObserver.observe(this.headerSideStartRef.nativeElement);
713
709
  this.resizeObserver.observe(this.headerSideEndRef.nativeElement);
@@ -738,10 +734,10 @@ class VerticalHeaderComponent {
738
734
  if (collides !== this.searchCollapsed())
739
735
  this.searchCollapsed.set(collides);
740
736
  }
741
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: VerticalHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
742
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: VerticalHeaderComponent, isStandalone: true, selector: "app-vertical-header", inputs: { actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, themes: { classPropertyName: "themes", publicName: "themes", isSignal: true, isRequired: false, transformFunction: null }, showThemeSwitcher: { classPropertyName: "showThemeSwitcher", publicName: "showThemeSwitcher", isSignal: true, isRequired: false, transformFunction: null }, showTabs: { classPropertyName: "showTabs", publicName: "showTabs", isSignal: true, isRequired: false, transformFunction: null }, showNotifications: { classPropertyName: "showNotifications", publicName: "showNotifications", isSignal: true, isRequired: false, transformFunction: null }, notificationsCount: { classPropertyName: "notificationsCount", publicName: "notificationsCount", isSignal: true, isRequired: false, transformFunction: null }, notificationsInBottomNav: { classPropertyName: "notificationsInBottomNav", publicName: "notificationsInBottomNav", isSignal: true, isRequired: false, transformFunction: null }, showChatbotToggle: { classPropertyName: "showChatbotToggle", publicName: "showChatbotToggle", isSignal: true, isRequired: false, transformFunction: null }, chatbotVisible: { classPropertyName: "chatbotVisible", publicName: "chatbotVisible", isSignal: true, isRequired: false, transformFunction: null }, chatbotInBottomNav: { classPropertyName: "chatbotInBottomNav", publicName: "chatbotInBottomNav", isSignal: true, isRequired: false, transformFunction: null }, currentTheme: { classPropertyName: "currentTheme", publicName: "currentTheme", isSignal: true, isRequired: false, transformFunction: null }, versionApp: { classPropertyName: "versionApp", publicName: "versionApp", isSignal: true, isRequired: false, transformFunction: null }, accentColor: { classPropertyName: "accentColor", publicName: "accentColor", isSignal: true, isRequired: false, transformFunction: null }, envClass: { classPropertyName: "envClass", publicName: "envClass", isSignal: true, isRequired: false, transformFunction: null }, produccion: { classPropertyName: "produccion", publicName: "produccion", isSignal: true, isRequired: false, transformFunction: null }, isScrolled: { classPropertyName: "isScrolled", publicName: "isScrolled", isSignal: true, isRequired: false, transformFunction: null }, isSidebarOpen: { classPropertyName: "isSidebarOpen", publicName: "isSidebarOpen", isSignal: true, isRequired: false, transformFunction: null }, nameProyecto: { classPropertyName: "nameProyecto", publicName: "nameProyecto", isSignal: true, isRequired: false, transformFunction: null }, showPanelControl: { classPropertyName: "showPanelControl", publicName: "showPanelControl", isSignal: true, isRequired: false, transformFunction: null }, userName: { classPropertyName: "userName", publicName: "userName", isSignal: true, isRequired: false, transformFunction: null }, empresaName: { classPropertyName: "empresaName", publicName: "empresaName", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { notificationsClick: "notificationsClick", chatbotVisibleChange: "chatbotVisibleChange", themeChange: "themeChange", emitirToogle: "emitirToogle", searchComponents: "searchComponents", panelControlClick: "panelControlClick", logout: "logout" }, host: { listeners: { "document:click": "onDocumentClick()" } }, viewQueries: [{ propertyName: "headerContainerRef", first: true, predicate: ["headerContainer"], descendants: true }, { propertyName: "headerSideStartRef", first: true, predicate: ["headerSideStart"], descendants: true }, { propertyName: "headerSideEndRef", first: true, predicate: ["headerSideEnd"], descendants: true }, { propertyName: "compactSearchWrapperRef", first: true, predicate: ["compactSearchWrapper"], descendants: true }], ngImport: i0, template: "<div #headerContainer class=\"d-flex header-container\" [ngClass]=\"envClass()\">\r\n <div class=\"first-header d-none d-md-flex\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" width=\"40px\" height=\"40px\" style=\"cursor:pointer\"\r\n (click)=\"goToHome()\" title=\"Ir a Home\">\r\n <span class=\"text-white empresa-nombre ps-2\" [title]=\"versionApp()\">{{empresaName()}}</span>\r\n </div>\r\n\r\n <div class=\"d-flex w-100 h-100 justify-content-between align-items-center pe-3 ps-0\">\r\n <div #headerSideStart class=\"d-flex align-items-center header-side\">\r\n <button class=\"btn text-white none-style sidebar-toggle-btn\" (click)=\"emitirToogle.emit()\">\r\n <i class=\"fa-solid fa-table-columns\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n <i class=\"fa-solid fa-chevron-left toggle-arrow\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n </button>\r\n <span class=\"text-white empresa-nombre d-inline d-md-none ps-2\">{{empresaName()}}</span>\r\n <span class=\"text-white fs-5 fw-normal d-none d-md-inline ps-2 text-nowrap\">{{nameProyecto()}}</span>\r\n @if (showTabs() && tabsService.tabs().length) {\r\n <button class=\"tabs-header-btn mx-2 d-none d-md-flex\"\r\n [class.tabs-header-btn--active]=\"tabsService.visible()\" (click)=\"tabsService.toggleVisible()\"\r\n [title]=\"tabsService.visible() ? 'Ocultar acceso r\u00E1pido' : 'Mostrar acceso r\u00E1pido'\">\r\n <i class=\"fas fa-layer-group\"></i>\r\n @if (!tabsService.visible()) {\r\n <span class=\"tabs-header-count\">{{ tabsService.tabs().length }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (showSearch()) {\r\n <button class=\"global-search-trigger d-none d-md-flex align-items-center\"\r\n [class.global-search-trigger--collapsed]=\"searchCollapsed()\" title=\"B\u00FAsqueda de p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">\r\n <i class=\"fas fa-search global-search-icon\"></i>\r\n <span class=\"global-search-placeholder\">Buscar p\u00E1ginas...</span>\r\n <kbd class=\"global-search-kbd\">F2</kbd>\r\n </button>\r\n }\r\n\r\n <div #headerSideEnd class=\"d-flex align-items-center header-side header-side--end\">\r\n\r\n <!-- Fallback del buscador centrado cuando no entra (colisi\u00F3n) o en mobile\r\n (el buscador centrado se oculta por completo por debajo de md): la\r\n p\u00EDldora de texto \"F2\", igual que antes. -->\r\n <div #compactSearchWrapper class=\"h-100 d-flex align-items-center\">\r\n @if (showSearch() && searchCollapsed()) {\r\n <button class=\"global-search-compact-pill\" title=\"Buscar p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">F2</button>\r\n }\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[extra-actions]\" />\r\n\r\n <!-- Acciones adicionales, definidas por el consumidor: siempre a la izquierda\r\n de los tres fijos (tema, notificaciones, soporte). Solo se ocultan en mobile\r\n las que adem\u00E1s se reflejan en el bottom-nav (showInBottomNav) \u2014 si una acci\u00F3n\r\n no baja al bottom-nav, se queda visible ac\u00E1 para no desaparecer del todo. -->\r\n @for (action of actions(); track action.label) {\r\n @if (!action.hidden) {\r\n @if (action.items?.length) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"openActionKey() === action.label\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"action.accion?.(); toggleActionMenu($event, action)\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"openActionKey() === action.label\">\r\n @for (opcion of action.items; track opcion.label; let last = $last) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4 d-flex align-items-center\"\r\n [ngClass]=\"{'divider-border': !last,'border-top-radius': $index == 0,'border-bottom-radius': last}\"\r\n (click)=\"runAction(opcion)\"\r\n (mouseenter)=\"showTooltip($event, opcion.title ?? '')\" (mouseleave)=\"hideTooltip()\">\r\n <i [class]=\"opcion.icon\" class=\"me-1\"></i> {{ opcion.label }}\r\n @if (opcion.value) {\r\n <span class=\"ms-auto ps-3 fw-6\">{{ opcion.value }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"h-100 d-flex align-items-center\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"action.accion?.()\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n @if (action.badge) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ action.badge }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n }\r\n }\r\n\r\n @if (showThemeSwitcher()) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"themeMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" (click)=\"toggleThemeMenu($event)\"\r\n [title]=\"'Tema: ' + themeLabel()\">\r\n <i class=\"fas text-white\" [ngClass]=\"themeIcon()\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"themeMenuOpen()\">\r\n @for (item of themes(); track item.id) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4 border-bottom-radius divider-border\"\r\n (click)=\"selectTheme(item.id)\">\r\n <i class=\"fas me-1\" [ngClass]=\"item.icon\"></i> {{ item.label }}\r\n @if (currentTheme() === item.id) {\r\n <i class=\"fas fa-check ms-auto text-success\"></i>\r\n }\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Notificaciones y soporte: \u00EDcono/estilo est\u00E1ndar, siempre visibles tambi\u00E9n en mobile -->\r\n @if (showNotifications()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" title=\"Notificaciones\"\r\n (click)=\"notificationsClick.emit()\">\r\n <i class=\"fas fa-bell text-white\"></i>\r\n @if (notificationsCount() > 0) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ notificationsCount() }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n\r\n @if (showChatbotToggle()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\"\r\n [title]=\"chatbotVisible() ? 'Ocultar soporte' : 'Mostrar soporte'\"\r\n (click)=\"chatbotVisibleChange.emit(!chatbotVisible())\">\r\n <i class=\"fas fa-robot text-white\"></i>\r\n </button>\r\n </div>\r\n }\r\n\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"userMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"border-0 bg-none\" (click)=\"toggleUserMenu($event)\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\" alt=\"\">\r\n </button>\r\n </div>\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0\" [class.show]=\"userMenuOpen()\">\r\n <div\r\n class=\"d-flex no-block align-items-center p-3 divider-border bg-gray-user-data border-top-radius\">\r\n <div class=\"d-flex align-items-center\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\">\r\n <div class=\"ms-2\">\r\n <p class=\"fs-7 my-0 py-0 fw-6\">{{userName()}}</p>\r\n @if (userName().startsWith('DESARROLLADOR')) {\r\n <span class=\"fs-7 fw-bold\">Desarrollador</span>\r\n } @else if (userName().startsWith('SOPORTE')) {\r\n <span class=\"fs-7 fw-bold\">Soporte</span>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n @if (showPanelControl()) {\r\n <button class=\"dropdown-item py-3 fs-7 fw-4\" (click)=\"userMenuOpen.set(false); panelControlClick.emit()\">\r\n Panel de control\r\n </button>\r\n }\r\n <button class=\"dropdown-item py-3 fs-7 fw-4 border-bottom-radius\" (click)=\"userMenuOpen.set(false); logout.emit()\"><i\r\n class=\"fas fa-power-off\"></i> Cerrar sesi\u00F3n</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\"\r\n [style.borderLeftColor]=\"accentColor()\" [style.--tooltip-accent]=\"accentColor()\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\" [style.color]=\"accentColor()\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".header-container{height:50px;display:flex;align-items:center;transition:position .5s ease-in-out,background-color .2s ease;padding:0;margin:0;position:relative;--header-accent: #398bf7;background:var(--header-accent);border-bottom:2px solid transparent}.header-container.dev{--header-accent: rgb(197, 0, 72)}.header-container.prod{--header-accent: #398bf7}.header-container.qa{--header-accent: #20c997}:host-context(.dark-mode) .header-container,:host-context(.sky-blue-mode) .header-container,:host-context(.high-contrast-green-mode) .header-container,:host-context(.purple-mode) .header-container{background:var(--header-bg);border-bottom-color:var(--header-accent)}.first-header{display:flex;align-items:center;gap:6px}.empresa-nombre{max-width:350px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:1.25;max-height:2.5em;max-width:100%}@media(max-width:575px){.empresa-nombre{display:none!important}.first-header{min-width:auto!important;padding:10px!important}}@media(min-width:576px)and (max-width:1180px){.first-header{padding:10px!important}}@media(min-width:1181px){.first-header{min-width:260px;width:260px;padding:15px}}.bg-gray-user-data{background:var(--background-btn-light)}.dropdown-menu{transform-origin:top;background-color:var(--background-card);border-color:var(--border-color-modal);color:var(--text-color)}.dropdown-menu-end{right:0!important;left:auto!important}.dropdown-item{color:var(--text-color)}.dropdown-item:hover,.dropdown-item:focus{background-color:var(--bs-table-hover-bg);color:var(--text-color)}.dropdown-menu.show{animation:dropdownMenuIn .24s cubic-bezier(.2,0,.2,1) both}@keyframes dropdownMenuIn{0%{opacity:0;transform:translateY(10px) scale(.9)}to{opacity:1;transform:translateY(0) scale(1)}}.dropdown-menu{width:300px!important;min-width:300px!important}.circle-icon{min-height:30px;min-width:30px;height:30px;width:30px;border-radius:100%;border:2px solid white}.none-style{background:none;border:none}.sidebar-toggle-btn{display:flex;align-items:center;gap:4px}.sidebar-toggle-btn i{transition:transform .25s cubic-bezier(.4,0,.2,1)}.sidebar-toggle-btn i.flipped{transform:scaleX(-1)}.sidebar-toggle-btn .toggle-arrow{font-size:9px;color:#fff}.z-index{z-index:1001}.option{position:relative;border-radius:50px;width:33px;height:100%;transition:background-color .3s ease}.option:hover,.dropdown.show .option{background-color:var(--bs-table-hover-bg)!important}.custom-dropdown.dropdown-menu{min-width:unset!important;width:auto!important}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid;display:flex;align-items:center;gap:5px;animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--tooltip-accent, #c50048)}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.btn-print{border:1px solid rgba(0,0,0,.5764705882)!important;width:33px;height:30px!important;border-radius:6px}.btn-print:hover{border:1px solid rgba(61,61,61,.5254901961)!important;background-color:#dadadaf8!important}.btn-search{width:40px;height:31px!important;border-radius:6px}.logo-btn{width:25px;height:25px;object-fit:contain}.btn-deudas{background:#fff;border-radius:20px;border:none;white-space:nowrap;flex-shrink:0}.btn-deudas.titilando{animation:bordeTitilante 1s infinite alternate}@keyframes bordeTitilante{0%{box-shadow:0 0 2px red}50%{box-shadow:0 0 5px red,0 0 5px #ff4d4d}to{box-shadow:0 0 2px red}}@media(max-width:1100px){.btn-deudas{width:31px;height:31px!important;border-radius:50px;padding:0;display:flex;align-items:center;justify-content:center;aspect-ratio:1/1}.btn-deudas .texto-deudas{display:none}.btn-deudas .logo-btn{width:20px;height:20px;margin:0}}@keyframes icon-rotate-pop{0%{transform:rotate(0) scale(1)}25%{transform:rotate(10deg) scale(1.05)}50%{transform:rotate(-10deg) scale(1.1)}75%{transform:rotate(10deg) scale(1.05)}to{transform:rotate(0) scale(1)}}.button-icon-hover{display:inline-block}.button-tilt-hover:hover .button-icon-hover{animation:icon-rotate-pop 1s ease-in-out infinite}.desktop-only{display:flex}@media(max-width:667px){.desktop-only{display:none!important}}.notification-btn{position:relative;border:none;background:none;padding:0;margin-right:8px;cursor:pointer;width:33px;height:32px;display:flex;align-items:center;justify-content:center}.notification-btn i{color:#fff}.notification-badge{position:absolute;top:-5px;right:-3px;color:#fff;font-size:11px;font-weight:600;border-radius:4px;min-width:18px;height:18px;display:flex;align-items:center;justify-content:center;padding:0 4px}.header-side{flex:0 1 auto;min-width:0}.header-side--end{justify-content:flex-end}.global-search-trigger{position:absolute;left:50%;transform:translate(-50%);z-index:2;align-self:center;flex-shrink:0;margin:0;gap:8px;height:31px;width:280px;padding:0 6px 0 12px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:12px;cursor:pointer;white-space:nowrap;transition:background .15s,border-color .15s,color .15s}.global-search-trigger:hover,.global-search-trigger:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.global-search-trigger .global-search-icon{font-size:12px;color:#ffffffbf}.global-search-trigger .global-search-placeholder{flex-grow:1;text-align:start}.global-search-trigger .global-search-kbd{font-size:10px;font-weight:600;line-height:1;padding:3px 5px;border-radius:4px;background:#fff3;border:1px solid rgba(255,255,255,.35);color:#fff}.global-search-trigger--collapsed{display:none!important}.global-search-compact-pill{display:flex;align-items:center;justify-content:center;height:31px;margin-right:8px;padding:0 9px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:11px;font-weight:700;cursor:pointer;transition:background .15s,border-color .15s,color .15s}.global-search-compact-pill:hover,.global-search-compact-pill:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.tabs-header-btn{display:flex;align-items:center;gap:4px;background:#ffffff1a;border:1px solid rgba(255,255,255,.15);color:#fff9;border-radius:20px;padding:3px 8px;font-size:11px;cursor:pointer;transition:background .15s,color .15s;white-space:nowrap}.tabs-header-btn:hover{background:#fff3;color:#fff}.tabs-header-btn--active{background:#ffffff2e;color:#fff;border-color:#ffffff4d}.tabs-header-btn i{font-size:12px}.tabs-header-count{font-weight:700;font-size:11px;background:#fff3;border-radius:10px;padding:0 5px;min-width:16px;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
737
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: VerticalHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
738
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: VerticalHeaderComponent, isStandalone: true, selector: "app-vertical-header", inputs: { actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, themes: { classPropertyName: "themes", publicName: "themes", isSignal: true, isRequired: false, transformFunction: null }, showThemeSwitcher: { classPropertyName: "showThemeSwitcher", publicName: "showThemeSwitcher", isSignal: true, isRequired: false, transformFunction: null }, showTabs: { classPropertyName: "showTabs", publicName: "showTabs", isSignal: true, isRequired: false, transformFunction: null }, showNotifications: { classPropertyName: "showNotifications", publicName: "showNotifications", isSignal: true, isRequired: false, transformFunction: null }, notificationsCount: { classPropertyName: "notificationsCount", publicName: "notificationsCount", isSignal: true, isRequired: false, transformFunction: null }, notificationsInBottomNav: { classPropertyName: "notificationsInBottomNav", publicName: "notificationsInBottomNav", isSignal: true, isRequired: false, transformFunction: null }, showChatbotToggle: { classPropertyName: "showChatbotToggle", publicName: "showChatbotToggle", isSignal: true, isRequired: false, transformFunction: null }, chatbotVisible: { classPropertyName: "chatbotVisible", publicName: "chatbotVisible", isSignal: true, isRequired: false, transformFunction: null }, chatbotInBottomNav: { classPropertyName: "chatbotInBottomNav", publicName: "chatbotInBottomNav", isSignal: true, isRequired: false, transformFunction: null }, currentTheme: { classPropertyName: "currentTheme", publicName: "currentTheme", isSignal: true, isRequired: false, transformFunction: null }, versionApp: { classPropertyName: "versionApp", publicName: "versionApp", isSignal: true, isRequired: false, transformFunction: null }, accentColor: { classPropertyName: "accentColor", publicName: "accentColor", isSignal: true, isRequired: false, transformFunction: null }, envClass: { classPropertyName: "envClass", publicName: "envClass", isSignal: true, isRequired: false, transformFunction: null }, produccion: { classPropertyName: "produccion", publicName: "produccion", isSignal: true, isRequired: false, transformFunction: null }, isScrolled: { classPropertyName: "isScrolled", publicName: "isScrolled", isSignal: true, isRequired: false, transformFunction: null }, isSidebarOpen: { classPropertyName: "isSidebarOpen", publicName: "isSidebarOpen", isSignal: true, isRequired: false, transformFunction: null }, nameProyecto: { classPropertyName: "nameProyecto", publicName: "nameProyecto", isSignal: true, isRequired: false, transformFunction: null }, showPanelControl: { classPropertyName: "showPanelControl", publicName: "showPanelControl", isSignal: true, isRequired: false, transformFunction: null }, userName: { classPropertyName: "userName", publicName: "userName", isSignal: true, isRequired: false, transformFunction: null }, empresaName: { classPropertyName: "empresaName", publicName: "empresaName", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { notificationsClick: "notificationsClick", chatbotVisibleChange: "chatbotVisibleChange", themeChange: "themeChange", emitirToogle: "emitirToogle", searchComponents: "searchComponents", panelControlClick: "panelControlClick", logout: "logout" }, host: { listeners: { "document:click": "onDocumentClick()" } }, viewQueries: [{ propertyName: "headerContainerRef", first: true, predicate: ["headerContainer"], descendants: true }, { propertyName: "headerSideStartRef", first: true, predicate: ["headerSideStart"], descendants: true }, { propertyName: "headerSideEndRef", first: true, predicate: ["headerSideEnd"], descendants: true }, { propertyName: "compactSearchWrapperRef", first: true, predicate: ["compactSearchWrapper"], descendants: true }], ngImport: i0, template: "<div #headerContainer class=\"d-flex header-container\" [ngClass]=\"envClass()\">\r\n <div class=\"first-header d-none d-md-flex\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" width=\"40px\" height=\"40px\" style=\"cursor:pointer\"\r\n (click)=\"goToHome()\" title=\"Ir a Home\">\r\n <span class=\"text-white empresa-nombre ps-2\" [title]=\"versionApp()\">{{empresaName()}}</span>\r\n </div>\r\n\r\n <div class=\"d-flex w-100 h-100 justify-content-between align-items-center pe-3 ps-0\">\r\n <div #headerSideStart class=\"d-flex align-items-center header-side\">\r\n <button class=\"btn text-white none-style sidebar-toggle-btn\" (click)=\"emitirToogle.emit()\">\r\n <i class=\"fa-solid fa-table-columns\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n <i class=\"fa-solid fa-chevron-left toggle-arrow\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n </button>\r\n <span class=\"text-white empresa-nombre d-inline d-md-none ps-2\">{{empresaName()}}</span>\r\n <span class=\"text-white fs-5 fw-normal d-none d-md-inline ps-2 text-nowrap\">{{nameProyecto()}}</span>\r\n @if (showTabs() && tabsService.tabs().length) {\r\n <button class=\"tabs-header-btn mx-2 d-none d-md-flex\"\r\n [class.tabs-header-btn--active]=\"tabsService.visible()\" (click)=\"tabsService.toggleVisible()\"\r\n [title]=\"tabsService.visible() ? 'Ocultar acceso r\u00E1pido' : 'Mostrar acceso r\u00E1pido'\">\r\n <i class=\"fas fa-layer-group\"></i>\r\n @if (!tabsService.visible()) {\r\n <span class=\"tabs-header-count\">{{ tabsService.tabs().length }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (showSearch()) {\r\n <button class=\"global-search-trigger d-none d-md-flex align-items-center\"\r\n [class.global-search-trigger--collapsed]=\"searchCollapsed()\" title=\"B\u00FAsqueda de p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">\r\n <i class=\"fas fa-search global-search-icon\"></i>\r\n <span class=\"global-search-placeholder\">Buscar p\u00E1ginas...</span>\r\n <kbd class=\"global-search-kbd\">F2</kbd>\r\n </button>\r\n }\r\n\r\n <div #headerSideEnd class=\"d-flex align-items-center header-side header-side--end\">\r\n\r\n <!-- Fallback del buscador centrado cuando no entra (colisi\u00F3n) o en mobile\r\n (el buscador centrado se oculta por completo por debajo de md): la\r\n p\u00EDldora de texto \"F2\", igual que antes. -->\r\n <div #compactSearchWrapper class=\"h-100 d-flex align-items-center\">\r\n @if (showSearch() && searchCollapsed()) {\r\n <button class=\"global-search-compact-pill\" title=\"Buscar p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">F2</button>\r\n }\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[extra-actions]\" />\r\n\r\n <!-- Acciones adicionales, definidas por el consumidor: siempre a la izquierda\r\n de los tres fijos (tema, notificaciones, soporte). Solo se ocultan en mobile\r\n las que adem\u00E1s se reflejan en el bottom-nav (showInBottomNav) \u2014 si una acci\u00F3n\r\n no baja al bottom-nav, se queda visible ac\u00E1 para no desaparecer del todo. -->\r\n @for (action of actions(); track action.label) {\r\n @if (!action.hidden) {\r\n @if (action.items?.length) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"openActionKey() === action.label\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"action.accion?.(); toggleActionMenu($event, action)\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"openActionKey() === action.label\">\r\n @for (opcion of action.items; track opcion.label; let last = $last) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4 d-flex align-items-center\"\r\n [ngClass]=\"{'divider-border': !last,'border-top-radius': $index == 0,'border-bottom-radius': last}\"\r\n (click)=\"runAction(opcion)\"\r\n (mouseenter)=\"showTooltip($event, opcion.title ?? '')\" (mouseleave)=\"hideTooltip()\">\r\n <i [class]=\"opcion.icon\" class=\"me-1\"></i> {{ opcion.label }}\r\n @if (opcion.value) {\r\n <span class=\"ms-auto ps-3 fw-6\">{{ opcion.value }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"h-100 d-flex align-items-center\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"action.accion?.()\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n @if (action.badge) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ action.badge }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n }\r\n }\r\n\r\n @if (showThemeSwitcher()) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"themeMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" (click)=\"toggleThemeMenu($event)\"\r\n [title]=\"'Tema: ' + themeLabel()\">\r\n <i class=\"fas text-white\" [ngClass]=\"themeIcon()\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"themeMenuOpen()\">\r\n @for (item of themes(); track item.id) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4 border-bottom-radius divider-border\"\r\n (click)=\"selectTheme(item.id)\">\r\n <i class=\"fas me-1\" [ngClass]=\"item.icon\"></i> {{ item.label }}\r\n @if (currentTheme() === item.id) {\r\n <i class=\"fas fa-check ms-auto text-success\"></i>\r\n }\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Notificaciones y soporte: \u00EDcono/estilo est\u00E1ndar, siempre visibles tambi\u00E9n en mobile -->\r\n @if (showNotifications()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" title=\"Notificaciones\"\r\n (click)=\"notificationsClick.emit()\">\r\n <i class=\"fas fa-bell text-white\"></i>\r\n @if (notificationsCount() > 0) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ notificationsCount() }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n\r\n @if (showChatbotToggle()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\"\r\n [title]=\"chatbotVisible() ? 'Ocultar soporte' : 'Mostrar soporte'\"\r\n (click)=\"chatbotVisibleChange.emit(!chatbotVisible())\">\r\n <i class=\"fas fa-robot text-white\"></i>\r\n </button>\r\n </div>\r\n }\r\n\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"userMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"border-0 bg-none\" (click)=\"toggleUserMenu($event)\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\" alt=\"\">\r\n </button>\r\n </div>\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0\" [class.show]=\"userMenuOpen()\">\r\n <div\r\n class=\"d-flex no-block align-items-center p-3 divider-border bg-gray-user-data border-top-radius\">\r\n <div class=\"d-flex align-items-center\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\">\r\n <div class=\"ms-2\">\r\n <p class=\"fs-7 my-0 py-0 fw-6\">{{userName()}}</p>\r\n @if (userName().startsWith('DESARROLLADOR')) {\r\n <span class=\"fs-7 fw-bold\">Desarrollador</span>\r\n } @else if (userName().startsWith('SOPORTE')) {\r\n <span class=\"fs-7 fw-bold\">Soporte</span>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n @if (showPanelControl()) {\r\n <button class=\"dropdown-item py-3 fs-7 fw-4\" (click)=\"userMenuOpen.set(false); panelControlClick.emit()\">\r\n Panel de control\r\n </button>\r\n }\r\n <button class=\"dropdown-item py-3 fs-7 fw-4 border-bottom-radius\" (click)=\"userMenuOpen.set(false); logout.emit()\"><i\r\n class=\"fas fa-power-off\"></i> Cerrar sesi\u00F3n</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\"\r\n [style.borderLeftColor]=\"accentColor()\" [style.--tooltip-accent]=\"accentColor()\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\" [style.color]=\"accentColor()\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".header-container{height:50px;display:flex;align-items:center;transition:position .5s ease-in-out,background-color .2s ease;padding:0;margin:0;position:relative;--header-accent: #398bf7;background:var(--header-accent);border-bottom:2px solid transparent}.header-container.dev{--header-accent: rgb(197, 0, 72)}.header-container.prod{--header-accent: #398bf7}.header-container.qa{--header-accent: #20c997}:host-context(.dark-mode) .header-container,:host-context(.sky-blue-mode) .header-container,:host-context(.high-contrast-green-mode) .header-container,:host-context(.purple-mode) .header-container{background:var(--header-bg);border-bottom-color:var(--header-accent)}.first-header{display:flex;align-items:center;gap:6px}.empresa-nombre{max-width:350px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:1.25;max-height:2.5em;max-width:100%}@media(max-width:575px){.empresa-nombre{display:none!important}.first-header{min-width:auto!important;padding:10px!important}}@media(min-width:576px)and (max-width:1180px){.first-header{padding:10px!important}}@media(min-width:1181px){.first-header{min-width:260px;width:260px;padding:15px}}.bg-gray-user-data{background:var(--background-btn-light)}.dropdown-menu{transform-origin:top;background-color:var(--background-card);border-color:var(--border-color-modal);color:var(--text-color)}.dropdown-menu-end{right:0!important;left:auto!important}.dropdown-item{color:var(--text-color)}.dropdown-item:hover,.dropdown-item:focus{background-color:var(--bs-table-hover-bg);color:var(--text-color)}.dropdown-menu.show{animation:dropdownMenuIn .24s cubic-bezier(.2,0,.2,1) both}@keyframes dropdownMenuIn{0%{opacity:0;transform:translateY(10px) scale(.9)}to{opacity:1;transform:translateY(0) scale(1)}}.dropdown-menu{width:300px!important;min-width:300px!important}.circle-icon{min-height:30px;min-width:30px;height:30px;width:30px;border-radius:100%;border:2px solid white}.none-style{background:none;border:none}.sidebar-toggle-btn{display:flex;align-items:center;gap:4px}.sidebar-toggle-btn i{transition:transform .25s cubic-bezier(.4,0,.2,1)}.sidebar-toggle-btn i.flipped{transform:scaleX(-1)}.sidebar-toggle-btn .toggle-arrow{font-size:9px;color:#fff}.z-index{z-index:1001}.option{position:relative;border-radius:50px;width:33px;height:100%;transition:background-color .3s ease}.option:hover,.dropdown.show .option{background-color:var(--bs-table-hover-bg)!important}.custom-dropdown.dropdown-menu{min-width:unset!important;width:auto!important}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid;display:flex;align-items:center;gap:5px;animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--tooltip-accent, #c50048)}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.btn-print{border:1px solid rgba(0,0,0,.5764705882)!important;width:33px;height:30px!important;border-radius:6px}.btn-print:hover{border:1px solid rgba(61,61,61,.5254901961)!important;background-color:#dadadaf8!important}.btn-search{width:40px;height:31px!important;border-radius:6px}.logo-btn{width:25px;height:25px;object-fit:contain}.btn-deudas{background:#fff;border-radius:20px;border:none;white-space:nowrap;flex-shrink:0}.btn-deudas.titilando{animation:bordeTitilante 1s infinite alternate}@keyframes bordeTitilante{0%{box-shadow:0 0 2px red}50%{box-shadow:0 0 5px red,0 0 5px #ff4d4d}to{box-shadow:0 0 2px red}}@media(max-width:1100px){.btn-deudas{width:31px;height:31px!important;border-radius:50px;padding:0;display:flex;align-items:center;justify-content:center;aspect-ratio:1/1}.btn-deudas .texto-deudas{display:none}.btn-deudas .logo-btn{width:20px;height:20px;margin:0}}@keyframes icon-rotate-pop{0%{transform:rotate(0) scale(1)}25%{transform:rotate(10deg) scale(1.05)}50%{transform:rotate(-10deg) scale(1.1)}75%{transform:rotate(10deg) scale(1.05)}to{transform:rotate(0) scale(1)}}.button-icon-hover{display:inline-block}.button-tilt-hover:hover .button-icon-hover{animation:icon-rotate-pop 1s ease-in-out infinite}.desktop-only{display:flex}@media(max-width:667px){.desktop-only{display:none!important}}.notification-btn{position:relative;border:none;background:none;padding:0;margin-right:8px;cursor:pointer;width:33px;height:32px;display:flex;align-items:center;justify-content:center}.notification-btn i{color:#fff}.notification-badge{position:absolute;top:-5px;right:-3px;color:#fff;font-size:11px;font-weight:600;border-radius:4px;min-width:18px;height:18px;display:flex;align-items:center;justify-content:center;padding:0 4px}.header-side{flex:0 1 auto;min-width:0}.header-side--end{justify-content:flex-end}.global-search-trigger{position:absolute;left:50%;transform:translate(-50%);z-index:2;align-self:center;flex-shrink:0;margin:0;gap:8px;height:31px;width:280px;padding:0 6px 0 12px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:12px;cursor:pointer;white-space:nowrap;transition:background .15s,border-color .15s,color .15s}.global-search-trigger:hover,.global-search-trigger:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.global-search-trigger .global-search-icon{font-size:12px;color:#ffffffbf}.global-search-trigger .global-search-placeholder{flex-grow:1;text-align:start}.global-search-trigger .global-search-kbd{font-size:10px;font-weight:600;line-height:1;padding:3px 5px;border-radius:4px;background:#fff3;border:1px solid rgba(255,255,255,.35);color:#fff}.global-search-trigger--collapsed{display:none!important}.global-search-compact-pill{display:flex;align-items:center;justify-content:center;height:31px;margin-right:8px;padding:0 9px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:11px;font-weight:700;cursor:pointer;transition:background .15s,border-color .15s,color .15s}.global-search-compact-pill:hover,.global-search-compact-pill:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.tabs-header-btn{display:flex;align-items:center;gap:4px;background:#ffffff1a;border:1px solid rgba(255,255,255,.15);color:#fff9;border-radius:20px;padding:3px 8px;font-size:11px;cursor:pointer;transition:background .15s,color .15s;white-space:nowrap}.tabs-header-btn:hover{background:#fff3;color:#fff}.tabs-header-btn--active{background:#ffffff2e;color:#fff;border-color:#ffffff4d}.tabs-header-btn i{font-size:12px}.tabs-header-count{font-weight:700;font-size:11px;background:#fff3;border-radius:10px;padding:0 5px;min-width:16px;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
743
739
  }
744
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: VerticalHeaderComponent, decorators: [{
740
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: VerticalHeaderComponent, decorators: [{
745
741
  type: Component,
746
742
  args: [{ selector: 'app-vertical-header', imports: [CommonModule], template: "<div #headerContainer class=\"d-flex header-container\" [ngClass]=\"envClass()\">\r\n <div class=\"first-header d-none d-md-flex\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" width=\"40px\" height=\"40px\" style=\"cursor:pointer\"\r\n (click)=\"goToHome()\" title=\"Ir a Home\">\r\n <span class=\"text-white empresa-nombre ps-2\" [title]=\"versionApp()\">{{empresaName()}}</span>\r\n </div>\r\n\r\n <div class=\"d-flex w-100 h-100 justify-content-between align-items-center pe-3 ps-0\">\r\n <div #headerSideStart class=\"d-flex align-items-center header-side\">\r\n <button class=\"btn text-white none-style sidebar-toggle-btn\" (click)=\"emitirToogle.emit()\">\r\n <i class=\"fa-solid fa-table-columns\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n <i class=\"fa-solid fa-chevron-left toggle-arrow\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n </button>\r\n <span class=\"text-white empresa-nombre d-inline d-md-none ps-2\">{{empresaName()}}</span>\r\n <span class=\"text-white fs-5 fw-normal d-none d-md-inline ps-2 text-nowrap\">{{nameProyecto()}}</span>\r\n @if (showTabs() && tabsService.tabs().length) {\r\n <button class=\"tabs-header-btn mx-2 d-none d-md-flex\"\r\n [class.tabs-header-btn--active]=\"tabsService.visible()\" (click)=\"tabsService.toggleVisible()\"\r\n [title]=\"tabsService.visible() ? 'Ocultar acceso r\u00E1pido' : 'Mostrar acceso r\u00E1pido'\">\r\n <i class=\"fas fa-layer-group\"></i>\r\n @if (!tabsService.visible()) {\r\n <span class=\"tabs-header-count\">{{ tabsService.tabs().length }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (showSearch()) {\r\n <button class=\"global-search-trigger d-none d-md-flex align-items-center\"\r\n [class.global-search-trigger--collapsed]=\"searchCollapsed()\" title=\"B\u00FAsqueda de p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">\r\n <i class=\"fas fa-search global-search-icon\"></i>\r\n <span class=\"global-search-placeholder\">Buscar p\u00E1ginas...</span>\r\n <kbd class=\"global-search-kbd\">F2</kbd>\r\n </button>\r\n }\r\n\r\n <div #headerSideEnd class=\"d-flex align-items-center header-side header-side--end\">\r\n\r\n <!-- Fallback del buscador centrado cuando no entra (colisi\u00F3n) o en mobile\r\n (el buscador centrado se oculta por completo por debajo de md): la\r\n p\u00EDldora de texto \"F2\", igual que antes. -->\r\n <div #compactSearchWrapper class=\"h-100 d-flex align-items-center\">\r\n @if (showSearch() && searchCollapsed()) {\r\n <button class=\"global-search-compact-pill\" title=\"Buscar p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">F2</button>\r\n }\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[extra-actions]\" />\r\n\r\n <!-- Acciones adicionales, definidas por el consumidor: siempre a la izquierda\r\n de los tres fijos (tema, notificaciones, soporte). Solo se ocultan en mobile\r\n las que adem\u00E1s se reflejan en el bottom-nav (showInBottomNav) \u2014 si una acci\u00F3n\r\n no baja al bottom-nav, se queda visible ac\u00E1 para no desaparecer del todo. -->\r\n @for (action of actions(); track action.label) {\r\n @if (!action.hidden) {\r\n @if (action.items?.length) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"openActionKey() === action.label\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"action.accion?.(); toggleActionMenu($event, action)\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"openActionKey() === action.label\">\r\n @for (opcion of action.items; track opcion.label; let last = $last) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4 d-flex align-items-center\"\r\n [ngClass]=\"{'divider-border': !last,'border-top-radius': $index == 0,'border-bottom-radius': last}\"\r\n (click)=\"runAction(opcion)\"\r\n (mouseenter)=\"showTooltip($event, opcion.title ?? '')\" (mouseleave)=\"hideTooltip()\">\r\n <i [class]=\"opcion.icon\" class=\"me-1\"></i> {{ opcion.label }}\r\n @if (opcion.value) {\r\n <span class=\"ms-auto ps-3 fw-6\">{{ opcion.value }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"h-100 d-flex align-items-center\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"action.accion?.()\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n @if (action.badge) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ action.badge }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n }\r\n }\r\n\r\n @if (showThemeSwitcher()) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"themeMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" (click)=\"toggleThemeMenu($event)\"\r\n [title]=\"'Tema: ' + themeLabel()\">\r\n <i class=\"fas text-white\" [ngClass]=\"themeIcon()\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"themeMenuOpen()\">\r\n @for (item of themes(); track item.id) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4 border-bottom-radius divider-border\"\r\n (click)=\"selectTheme(item.id)\">\r\n <i class=\"fas me-1\" [ngClass]=\"item.icon\"></i> {{ item.label }}\r\n @if (currentTheme() === item.id) {\r\n <i class=\"fas fa-check ms-auto text-success\"></i>\r\n }\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Notificaciones y soporte: \u00EDcono/estilo est\u00E1ndar, siempre visibles tambi\u00E9n en mobile -->\r\n @if (showNotifications()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" title=\"Notificaciones\"\r\n (click)=\"notificationsClick.emit()\">\r\n <i class=\"fas fa-bell text-white\"></i>\r\n @if (notificationsCount() > 0) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ notificationsCount() }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n\r\n @if (showChatbotToggle()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\"\r\n [title]=\"chatbotVisible() ? 'Ocultar soporte' : 'Mostrar soporte'\"\r\n (click)=\"chatbotVisibleChange.emit(!chatbotVisible())\">\r\n <i class=\"fas fa-robot text-white\"></i>\r\n </button>\r\n </div>\r\n }\r\n\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"userMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"border-0 bg-none\" (click)=\"toggleUserMenu($event)\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\" alt=\"\">\r\n </button>\r\n </div>\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0\" [class.show]=\"userMenuOpen()\">\r\n <div\r\n class=\"d-flex no-block align-items-center p-3 divider-border bg-gray-user-data border-top-radius\">\r\n <div class=\"d-flex align-items-center\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\">\r\n <div class=\"ms-2\">\r\n <p class=\"fs-7 my-0 py-0 fw-6\">{{userName()}}</p>\r\n @if (userName().startsWith('DESARROLLADOR')) {\r\n <span class=\"fs-7 fw-bold\">Desarrollador</span>\r\n } @else if (userName().startsWith('SOPORTE')) {\r\n <span class=\"fs-7 fw-bold\">Soporte</span>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n @if (showPanelControl()) {\r\n <button class=\"dropdown-item py-3 fs-7 fw-4\" (click)=\"userMenuOpen.set(false); panelControlClick.emit()\">\r\n Panel de control\r\n </button>\r\n }\r\n <button class=\"dropdown-item py-3 fs-7 fw-4 border-bottom-radius\" (click)=\"userMenuOpen.set(false); logout.emit()\"><i\r\n class=\"fas fa-power-off\"></i> Cerrar sesi\u00F3n</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\"\r\n [style.borderLeftColor]=\"accentColor()\" [style.--tooltip-accent]=\"accentColor()\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\" [style.color]=\"accentColor()\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".header-container{height:50px;display:flex;align-items:center;transition:position .5s ease-in-out,background-color .2s ease;padding:0;margin:0;position:relative;--header-accent: #398bf7;background:var(--header-accent);border-bottom:2px solid transparent}.header-container.dev{--header-accent: rgb(197, 0, 72)}.header-container.prod{--header-accent: #398bf7}.header-container.qa{--header-accent: #20c997}:host-context(.dark-mode) .header-container,:host-context(.sky-blue-mode) .header-container,:host-context(.high-contrast-green-mode) .header-container,:host-context(.purple-mode) .header-container{background:var(--header-bg);border-bottom-color:var(--header-accent)}.first-header{display:flex;align-items:center;gap:6px}.empresa-nombre{max-width:350px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:1.25;max-height:2.5em;max-width:100%}@media(max-width:575px){.empresa-nombre{display:none!important}.first-header{min-width:auto!important;padding:10px!important}}@media(min-width:576px)and (max-width:1180px){.first-header{padding:10px!important}}@media(min-width:1181px){.first-header{min-width:260px;width:260px;padding:15px}}.bg-gray-user-data{background:var(--background-btn-light)}.dropdown-menu{transform-origin:top;background-color:var(--background-card);border-color:var(--border-color-modal);color:var(--text-color)}.dropdown-menu-end{right:0!important;left:auto!important}.dropdown-item{color:var(--text-color)}.dropdown-item:hover,.dropdown-item:focus{background-color:var(--bs-table-hover-bg);color:var(--text-color)}.dropdown-menu.show{animation:dropdownMenuIn .24s cubic-bezier(.2,0,.2,1) both}@keyframes dropdownMenuIn{0%{opacity:0;transform:translateY(10px) scale(.9)}to{opacity:1;transform:translateY(0) scale(1)}}.dropdown-menu{width:300px!important;min-width:300px!important}.circle-icon{min-height:30px;min-width:30px;height:30px;width:30px;border-radius:100%;border:2px solid white}.none-style{background:none;border:none}.sidebar-toggle-btn{display:flex;align-items:center;gap:4px}.sidebar-toggle-btn i{transition:transform .25s cubic-bezier(.4,0,.2,1)}.sidebar-toggle-btn i.flipped{transform:scaleX(-1)}.sidebar-toggle-btn .toggle-arrow{font-size:9px;color:#fff}.z-index{z-index:1001}.option{position:relative;border-radius:50px;width:33px;height:100%;transition:background-color .3s ease}.option:hover,.dropdown.show .option{background-color:var(--bs-table-hover-bg)!important}.custom-dropdown.dropdown-menu{min-width:unset!important;width:auto!important}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid;display:flex;align-items:center;gap:5px;animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--tooltip-accent, #c50048)}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.btn-print{border:1px solid rgba(0,0,0,.5764705882)!important;width:33px;height:30px!important;border-radius:6px}.btn-print:hover{border:1px solid rgba(61,61,61,.5254901961)!important;background-color:#dadadaf8!important}.btn-search{width:40px;height:31px!important;border-radius:6px}.logo-btn{width:25px;height:25px;object-fit:contain}.btn-deudas{background:#fff;border-radius:20px;border:none;white-space:nowrap;flex-shrink:0}.btn-deudas.titilando{animation:bordeTitilante 1s infinite alternate}@keyframes bordeTitilante{0%{box-shadow:0 0 2px red}50%{box-shadow:0 0 5px red,0 0 5px #ff4d4d}to{box-shadow:0 0 2px red}}@media(max-width:1100px){.btn-deudas{width:31px;height:31px!important;border-radius:50px;padding:0;display:flex;align-items:center;justify-content:center;aspect-ratio:1/1}.btn-deudas .texto-deudas{display:none}.btn-deudas .logo-btn{width:20px;height:20px;margin:0}}@keyframes icon-rotate-pop{0%{transform:rotate(0) scale(1)}25%{transform:rotate(10deg) scale(1.05)}50%{transform:rotate(-10deg) scale(1.1)}75%{transform:rotate(10deg) scale(1.05)}to{transform:rotate(0) scale(1)}}.button-icon-hover{display:inline-block}.button-tilt-hover:hover .button-icon-hover{animation:icon-rotate-pop 1s ease-in-out infinite}.desktop-only{display:flex}@media(max-width:667px){.desktop-only{display:none!important}}.notification-btn{position:relative;border:none;background:none;padding:0;margin-right:8px;cursor:pointer;width:33px;height:32px;display:flex;align-items:center;justify-content:center}.notification-btn i{color:#fff}.notification-badge{position:absolute;top:-5px;right:-3px;color:#fff;font-size:11px;font-weight:600;border-radius:4px;min-width:18px;height:18px;display:flex;align-items:center;justify-content:center;padding:0 4px}.header-side{flex:0 1 auto;min-width:0}.header-side--end{justify-content:flex-end}.global-search-trigger{position:absolute;left:50%;transform:translate(-50%);z-index:2;align-self:center;flex-shrink:0;margin:0;gap:8px;height:31px;width:280px;padding:0 6px 0 12px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:12px;cursor:pointer;white-space:nowrap;transition:background .15s,border-color .15s,color .15s}.global-search-trigger:hover,.global-search-trigger:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.global-search-trigger .global-search-icon{font-size:12px;color:#ffffffbf}.global-search-trigger .global-search-placeholder{flex-grow:1;text-align:start}.global-search-trigger .global-search-kbd{font-size:10px;font-weight:600;line-height:1;padding:3px 5px;border-radius:4px;background:#fff3;border:1px solid rgba(255,255,255,.35);color:#fff}.global-search-trigger--collapsed{display:none!important}.global-search-compact-pill{display:flex;align-items:center;justify-content:center;height:31px;margin-right:8px;padding:0 9px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:11px;font-weight:700;cursor:pointer;transition:background .15s,border-color .15s,color .15s}.global-search-compact-pill:hover,.global-search-compact-pill:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.tabs-header-btn{display:flex;align-items:center;gap:4px;background:#ffffff1a;border:1px solid rgba(255,255,255,.15);color:#fff9;border-radius:20px;padding:3px 8px;font-size:11px;cursor:pointer;transition:background .15s,color .15s;white-space:nowrap}.tabs-header-btn:hover{background:#fff3;color:#fff}.tabs-header-btn--active{background:#ffffff2e;color:#fff;border-color:#ffffff4d}.tabs-header-btn i{font-size:12px}.tabs-header-count{font-weight:700;font-size:11px;background:#fff3;border-radius:10px;padding:0 5px;min-width:16px;text-align:center}\n"] }]
747
743
  }], propDecorators: { headerContainerRef: [{
@@ -756,7 +752,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
756
752
  }], compactSearchWrapperRef: [{
757
753
  type: ViewChild,
758
754
  args: ['compactSearchWrapper']
759
- }], onDocumentClick: [{
755
+ }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], showSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSearch", required: false }] }], themes: [{ type: i0.Input, args: [{ isSignal: true, alias: "themes", required: false }] }], showThemeSwitcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "showThemeSwitcher", required: false }] }], showTabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTabs", required: false }] }], showNotifications: [{ type: i0.Input, args: [{ isSignal: true, alias: "showNotifications", required: false }] }], notificationsCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "notificationsCount", required: false }] }], notificationsClick: [{ type: i0.Output, args: ["notificationsClick"] }], notificationsInBottomNav: [{ type: i0.Input, args: [{ isSignal: true, alias: "notificationsInBottomNav", required: false }] }], showChatbotToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showChatbotToggle", required: false }] }], chatbotVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "chatbotVisible", required: false }] }], chatbotVisibleChange: [{ type: i0.Output, args: ["chatbotVisibleChange"] }], chatbotInBottomNav: [{ type: i0.Input, args: [{ isSignal: true, alias: "chatbotInBottomNav", required: false }] }], currentTheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentTheme", required: false }] }], themeChange: [{ type: i0.Output, args: ["themeChange"] }], versionApp: [{ type: i0.Input, args: [{ isSignal: true, alias: "versionApp", required: false }] }], accentColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "accentColor", required: false }] }], envClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "envClass", required: false }] }], produccion: [{ type: i0.Input, args: [{ isSignal: true, alias: "produccion", required: false }] }], emitirToogle: [{ type: i0.Output, args: ["emitirToogle"] }], isScrolled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isScrolled", required: false }] }], isSidebarOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isSidebarOpen", required: false }] }], nameProyecto: [{ type: i0.Input, args: [{ isSignal: true, alias: "nameProyecto", required: false }] }], searchComponents: [{ type: i0.Output, args: ["searchComponents"] }], showPanelControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPanelControl", required: false }] }], panelControlClick: [{ type: i0.Output, args: ["panelControlClick"] }], logout: [{ type: i0.Output, args: ["logout"] }], userName: [{ type: i0.Input, args: [{ isSignal: true, alias: "userName", required: false }] }], empresaName: [{ type: i0.Input, args: [{ isSignal: true, alias: "empresaName", required: false }] }], onDocumentClick: [{
760
756
  type: HostListener,
761
757
  args: ['document:click']
762
758
  }] } });
@@ -778,8 +774,8 @@ class TabBarComponent {
778
774
  // tiene equivalente CSS puro porque Angular remueve el elemento del DOM al
779
775
  // instante — acá lo mantenemos montado con una clase "--leaving" el tiempo
780
776
  // que dura la animación de salida, y recién ahí lo desmontamos.
781
- shouldShow = computed(() => this.tabs.tabs().length > 0 && this.tabs.visible());
782
- rendered = signal(false);
777
+ shouldShow = computed(() => this.tabs.tabs().length > 0 && this.tabs.visible(), ...(ngDevMode ? [{ debugName: "shouldShow" }] : /* istanbul ignore next */ []));
778
+ rendered = signal(false, ...(ngDevMode ? [{ debugName: "rendered" }] : /* istanbul ignore next */ []));
783
779
  leaveTimer = null;
784
780
  constructor() {
785
781
  effect(() => {
@@ -797,11 +793,11 @@ class TabBarComponent {
797
793
  }
798
794
  // Se combina con los colores por defecto en vez de reemplazarlos: un proyecto solo
799
795
  // necesita pasar los módulos que quiera personalizar, el resto sigue con su color base.
800
- moduleColors = input({});
796
+ moduleColors = input({}, ...(ngDevMode ? [{ debugName: "moduleColors" }] : /* istanbul ignore next */ []));
801
797
  // Tooltip nativo al hover (sin ng-bootstrap): mismo patrón fixed-position
802
798
  // que ya usan menu-item/vertical-header en esta librería.
803
- hoveredTab = signal(null);
804
- tipPosition = signal({ x: 0, y: 0 });
799
+ hoveredTab = signal(null, ...(ngDevMode ? [{ debugName: "hoveredTab" }] : /* istanbul ignore next */ []));
800
+ tipPosition = signal({ x: 0, y: 0 }, ...(ngDevMode ? [{ debugName: "tipPosition" }] : /* istanbul ignore next */ []));
805
801
  hoverTimer = null;
806
802
  getModuleColor(tab) {
807
803
  const key = tab.moduleKey ?? tab.module ?? '';
@@ -829,26 +825,26 @@ class TabBarComponent {
829
825
  this.tabs.close(tab.id, event);
830
826
  }
831
827
  }
832
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TabBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
833
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: TabBarComponent, isStandalone: true, selector: "app-tab-bar", inputs: { moduleColors: { classPropertyName: "moduleColors", publicName: "moduleColors", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (rendered()) {\r\n<div class=\"tab-bar\" [class.tab-bar--leaving]=\"!shouldShow()\">\r\n <div class=\"tab-list\">\r\n @for (tab of tabs.sortedTabs(); track tab.id) {\r\n\r\n <div class=\"tab\" [class.tab--active]=\"tabs.activeId() === tab.id\" [class.tab--pinned]=\"tab.pinned\"\r\n [class.tab--with-module]=\"!!tab.module\" (mouseenter)=\"onTabMouseEnter($event, tab)\" (mouseleave)=\"onTabMouseLeave()\"\r\n (click)=\"tabs.activate(tab.id)\" (mousedown)=\"onTabMouseDown($event, tab)\">\r\n @if (tab.icon) {\r\n <i [class]=\"tab.icon + ' tab-icon'\"></i>\r\n }\r\n <div class=\"tab-body\">\r\n <span class=\"tab-title\">{{ tab.title }}</span>\r\n @if (tab.module) {\r\n <span class=\"tab-module\">\r\n <span class=\"tab-module-dot\" [style.background]=\"getModuleColor(tab)\"></span>\r\n {{ tab.module }}\r\n </span>\r\n }\r\n </div>\r\n <button class=\"tab-btn tab-pin\" [class.tab-pin--active]=\"tab.pinned\" (click)=\"tabs.togglePin(tab.id, $event)\"\r\n [title]=\"tab.pinned ? 'Desfijar' : 'Fijar'\">\r\n <i class=\"fas fa-thumbtack\"></i>\r\n </button>\r\n @if (!tab.pinned) {\r\n <button class=\"tab-btn tab-close\" (click)=\"tabs.close(tab.id, $event)\" title=\"Cerrar\">\r\n <i class=\"fas fa-times\"></i>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"tab-actions\">\r\n <button class=\"tab-close-all\" (click)=\"tabs.closeAll()\" title=\"Cerrar todas las pesta\u00F1as\">\r\n <i class=\"fas fa-times-circle\"></i>\r\n <span>Cerrar todo</span>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n@if (hoveredTab(); as tab) {\r\n<div class=\"tab-tip-fixed\" [style.left.px]=\"tipPosition().x\" [style.top.px]=\"tipPosition().y\">\r\n <span class=\"tab-tip-title\">{{ tab.title }}</span>\r\n @if (tab.module) {\r\n <span class=\"tab-tip-module\">\r\n <span class=\"tab-tip-dot\" [style.background]=\"getModuleColor(tab)\"></span>\r\n {{ tab.module }}\r\n </span>\r\n }\r\n</div>\r\n}\r\n}\r\n", styles: ["@media(max-width:767px){.tab-bar{display:none!important}}.tab-bar{display:flex;align-items:center;padding:4px 8px;background:var(--sidebar-bg, #0b1a3d);border-bottom:1px solid rgba(255,255,255,.1);min-height:38px;width:100%;flex-shrink:0;box-shadow:0 2px 8px #00000040;animation:tabBarSlideIn .22s cubic-bezier(.25,.46,.45,.94) both}.tab-bar--leaving{animation:tabBarSlideOut .16s ease-in both}@keyframes tabBarSlideIn{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes tabBarSlideOut{0%{transform:translateY(0);opacity:1}to{transform:translateY(-100%);opacity:0}}.tab-list{display:flex;align-items:stretch;gap:3px;flex:1;min-width:0;overflow-x:auto;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.15) transparent}.tab-list::-webkit-scrollbar{height:2px}.tab-list::-webkit-scrollbar-track{background:transparent}.tab-list::-webkit-scrollbar-thumb{background:#fff3;border-radius:2px}.tab{display:flex;align-items:center;gap:5px;padding:4px 8px;border-radius:5px;cursor:pointer;white-space:nowrap;font-size:12px;color:#ffffff8c;background:#ffffff0a;border:1px solid transparent;transition:background .15s,border-color .15s,color .15s;flex:1 1 0;min-width:60px;max-width:180px;overflow:hidden;-webkit-user-select:none;user-select:none}.tab--with-module{align-items:flex-start;padding-top:5px;padding-bottom:5px}.tab:hover{background:#ffffff17;color:#fffc}.tab:hover .tab-pin{opacity:.5}.tab--active{background:#398bf726;border-color:#398bf773;color:#93c5fd}.tab--pinned{border-color:#fbbf2459;background:#fbbf2412;flex:0 0 auto}.tab--pinned.tab--active{border-color:#398bf773;background:#398bf726}.tab-icon{font-size:11px;flex-shrink:0;margin-top:1px}.tab--with-module .tab-icon{margin-top:2px}.tab-body{display:flex;flex-direction:column;flex:1;min-width:0;gap:2px}.tab-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.2}.tab-module{display:flex;align-items:center;gap:4px;font-size:10.5px;color:#fff9;line-height:normal;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tab-module-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0;align-self:center;display:block}.tab-btn{background:none;border:none;padding:0 1px;cursor:pointer;color:inherit;font-size:9px;line-height:1;display:flex;align-items:center;flex-shrink:0}.tab-pin{opacity:0;transition:opacity .15s,color .15s,transform .2s;transform:rotate(45deg)}.tab-pin--active{opacity:1!important;color:#fbbf24;transform:rotate(0)}.tab-pin:hover{opacity:1!important}.tab-close{opacity:.4}.tab-close:hover{opacity:1}.tab-actions{display:flex;align-items:center;gap:4px;padding-left:8px;border-left:1px solid rgba(255,255,255,.08);margin-left:4px;flex-shrink:0}.tab-tip-fixed{position:fixed;z-index:99999;transform:translate(-50%);pointer-events:none;padding:6px 10px;border-radius:6px;background:#0f0f14;border:1px solid rgba(255,255,255,.07);white-space:nowrap;display:flex;flex-direction:column;gap:3px;animation:tabTipFadeIn .14s ease}.tab-tip-fixed:before{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border:5px solid transparent;border-bottom-color:#0f0f14}.tab-tip-title{font-size:11px;font-weight:600;color:#fff}.tab-tip-module{display:flex;align-items:center;gap:4px;font-size:10px;color:#ffffffa6}.tab-tip-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}@keyframes tabTipFadeIn{0%{opacity:0;transform:translate(-50%) translateY(-4px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.tab-close-all{display:flex;align-items:center;gap:5px;background:none;border:none;cursor:pointer;color:#fff6;font-size:11px;padding:3px 6px;border-radius:4px;white-space:nowrap;transition:color .15s,background .15s}.tab-close-all:hover{color:#f87171;background:#f871711a}.tab-close-all i{font-size:12px}\n"] });
828
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: TabBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
829
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: TabBarComponent, isStandalone: true, selector: "app-tab-bar", inputs: { moduleColors: { classPropertyName: "moduleColors", publicName: "moduleColors", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (rendered()) {\r\n<div class=\"tab-bar\" [class.tab-bar--leaving]=\"!shouldShow()\">\r\n <div class=\"tab-list\">\r\n @for (tab of tabs.sortedTabs(); track tab.id) {\r\n\r\n <div class=\"tab\" [class.tab--active]=\"tabs.activeId() === tab.id\" [class.tab--pinned]=\"tab.pinned\"\r\n [class.tab--with-module]=\"!!tab.module\" (mouseenter)=\"onTabMouseEnter($event, tab)\" (mouseleave)=\"onTabMouseLeave()\"\r\n (click)=\"tabs.activate(tab.id)\" (mousedown)=\"onTabMouseDown($event, tab)\">\r\n @if (tab.icon) {\r\n <i [class]=\"tab.icon + ' tab-icon'\"></i>\r\n }\r\n <div class=\"tab-body\">\r\n <span class=\"tab-title\">{{ tab.title }}</span>\r\n @if (tab.module) {\r\n <span class=\"tab-module\">\r\n <span class=\"tab-module-dot\" [style.background]=\"getModuleColor(tab)\"></span>\r\n {{ tab.module }}\r\n </span>\r\n }\r\n </div>\r\n <button class=\"tab-btn tab-pin\" [class.tab-pin--active]=\"tab.pinned\" (click)=\"tabs.togglePin(tab.id, $event)\"\r\n [title]=\"tab.pinned ? 'Desfijar' : 'Fijar'\">\r\n <i class=\"fas fa-thumbtack\"></i>\r\n </button>\r\n @if (!tab.pinned) {\r\n <button class=\"tab-btn tab-close\" (click)=\"tabs.close(tab.id, $event)\" title=\"Cerrar\">\r\n <i class=\"fas fa-times\"></i>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"tab-actions\">\r\n <button class=\"tab-close-all\" (click)=\"tabs.closeAll()\" title=\"Cerrar todas las pesta\u00F1as\">\r\n <i class=\"fas fa-times-circle\"></i>\r\n <span>Cerrar todo</span>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n@if (hoveredTab(); as tab) {\r\n<div class=\"tab-tip-fixed\" [style.left.px]=\"tipPosition().x\" [style.top.px]=\"tipPosition().y\">\r\n <span class=\"tab-tip-title\">{{ tab.title }}</span>\r\n @if (tab.module) {\r\n <span class=\"tab-tip-module\">\r\n <span class=\"tab-tip-dot\" [style.background]=\"getModuleColor(tab)\"></span>\r\n {{ tab.module }}\r\n </span>\r\n }\r\n</div>\r\n}\r\n}\r\n", styles: ["@media(max-width:767px){.tab-bar{display:none!important}}.tab-bar{display:flex;align-items:center;padding:4px 8px;background:var(--sidebar-bg, #0b1a3d);border-bottom:1px solid rgba(255,255,255,.1);min-height:38px;width:100%;flex-shrink:0;box-shadow:0 2px 8px #00000040;animation:tabBarSlideIn .22s cubic-bezier(.25,.46,.45,.94) both}.tab-bar--leaving{animation:tabBarSlideOut .16s ease-in both}@keyframes tabBarSlideIn{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes tabBarSlideOut{0%{transform:translateY(0);opacity:1}to{transform:translateY(-100%);opacity:0}}.tab-list{display:flex;align-items:stretch;gap:3px;flex:1;min-width:0;overflow-x:auto;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.15) transparent}.tab-list::-webkit-scrollbar{height:2px}.tab-list::-webkit-scrollbar-track{background:transparent}.tab-list::-webkit-scrollbar-thumb{background:#fff3;border-radius:2px}.tab{display:flex;align-items:center;gap:5px;padding:4px 8px;border-radius:5px;cursor:pointer;white-space:nowrap;font-size:12px;color:#ffffff8c;background:#ffffff0a;border:1px solid transparent;transition:background .15s,border-color .15s,color .15s;flex:1 1 0;min-width:60px;max-width:180px;overflow:hidden;-webkit-user-select:none;user-select:none}.tab--with-module{align-items:flex-start;padding-top:5px;padding-bottom:5px}.tab:hover{background:#ffffff17;color:#fffc}.tab:hover .tab-pin{opacity:.5}.tab--active{background:#398bf726;border-color:#398bf773;color:#93c5fd}.tab--pinned{border-color:#fbbf2459;background:#fbbf2412;flex:0 0 auto}.tab--pinned.tab--active{border-color:#398bf773;background:#398bf726}.tab-icon{font-size:11px;flex-shrink:0;margin-top:1px}.tab--with-module .tab-icon{margin-top:2px}.tab-body{display:flex;flex-direction:column;flex:1;min-width:0;gap:2px}.tab-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.2}.tab-module{display:flex;align-items:center;gap:4px;font-size:10.5px;color:#fff9;line-height:normal;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tab-module-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0;align-self:center;display:block}.tab-btn{background:none;border:none;padding:0 1px;cursor:pointer;color:inherit;font-size:9px;line-height:1;display:flex;align-items:center;flex-shrink:0}.tab-pin{opacity:0;transition:opacity .15s,color .15s,transform .2s;transform:rotate(45deg)}.tab-pin--active{opacity:1!important;color:#fbbf24;transform:rotate(0)}.tab-pin:hover{opacity:1!important}.tab-close{opacity:.4}.tab-close:hover{opacity:1}.tab-actions{display:flex;align-items:center;gap:4px;padding-left:8px;border-left:1px solid rgba(255,255,255,.08);margin-left:4px;flex-shrink:0}.tab-tip-fixed{position:fixed;z-index:99999;transform:translate(-50%);pointer-events:none;padding:6px 10px;border-radius:6px;background:#0f0f14;border:1px solid rgba(255,255,255,.07);white-space:nowrap;display:flex;flex-direction:column;gap:3px;animation:tabTipFadeIn .14s ease}.tab-tip-fixed:before{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border:5px solid transparent;border-bottom-color:#0f0f14}.tab-tip-title{font-size:11px;font-weight:600;color:#fff}.tab-tip-module{display:flex;align-items:center;gap:4px;font-size:10px;color:#ffffffa6}.tab-tip-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}@keyframes tabTipFadeIn{0%{opacity:0;transform:translate(-50%) translateY(-4px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.tab-close-all{display:flex;align-items:center;gap:5px;background:none;border:none;cursor:pointer;color:#fff6;font-size:11px;padding:3px 6px;border-radius:4px;white-space:nowrap;transition:color .15s,background .15s}.tab-close-all:hover{color:#f87171;background:#f871711a}.tab-close-all i{font-size:12px}\n"] });
834
830
  }
835
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TabBarComponent, decorators: [{
831
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: TabBarComponent, decorators: [{
836
832
  type: Component,
837
833
  args: [{ selector: 'app-tab-bar', imports: [], template: "@if (rendered()) {\r\n<div class=\"tab-bar\" [class.tab-bar--leaving]=\"!shouldShow()\">\r\n <div class=\"tab-list\">\r\n @for (tab of tabs.sortedTabs(); track tab.id) {\r\n\r\n <div class=\"tab\" [class.tab--active]=\"tabs.activeId() === tab.id\" [class.tab--pinned]=\"tab.pinned\"\r\n [class.tab--with-module]=\"!!tab.module\" (mouseenter)=\"onTabMouseEnter($event, tab)\" (mouseleave)=\"onTabMouseLeave()\"\r\n (click)=\"tabs.activate(tab.id)\" (mousedown)=\"onTabMouseDown($event, tab)\">\r\n @if (tab.icon) {\r\n <i [class]=\"tab.icon + ' tab-icon'\"></i>\r\n }\r\n <div class=\"tab-body\">\r\n <span class=\"tab-title\">{{ tab.title }}</span>\r\n @if (tab.module) {\r\n <span class=\"tab-module\">\r\n <span class=\"tab-module-dot\" [style.background]=\"getModuleColor(tab)\"></span>\r\n {{ tab.module }}\r\n </span>\r\n }\r\n </div>\r\n <button class=\"tab-btn tab-pin\" [class.tab-pin--active]=\"tab.pinned\" (click)=\"tabs.togglePin(tab.id, $event)\"\r\n [title]=\"tab.pinned ? 'Desfijar' : 'Fijar'\">\r\n <i class=\"fas fa-thumbtack\"></i>\r\n </button>\r\n @if (!tab.pinned) {\r\n <button class=\"tab-btn tab-close\" (click)=\"tabs.close(tab.id, $event)\" title=\"Cerrar\">\r\n <i class=\"fas fa-times\"></i>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"tab-actions\">\r\n <button class=\"tab-close-all\" (click)=\"tabs.closeAll()\" title=\"Cerrar todas las pesta\u00F1as\">\r\n <i class=\"fas fa-times-circle\"></i>\r\n <span>Cerrar todo</span>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n@if (hoveredTab(); as tab) {\r\n<div class=\"tab-tip-fixed\" [style.left.px]=\"tipPosition().x\" [style.top.px]=\"tipPosition().y\">\r\n <span class=\"tab-tip-title\">{{ tab.title }}</span>\r\n @if (tab.module) {\r\n <span class=\"tab-tip-module\">\r\n <span class=\"tab-tip-dot\" [style.background]=\"getModuleColor(tab)\"></span>\r\n {{ tab.module }}\r\n </span>\r\n }\r\n</div>\r\n}\r\n}\r\n", styles: ["@media(max-width:767px){.tab-bar{display:none!important}}.tab-bar{display:flex;align-items:center;padding:4px 8px;background:var(--sidebar-bg, #0b1a3d);border-bottom:1px solid rgba(255,255,255,.1);min-height:38px;width:100%;flex-shrink:0;box-shadow:0 2px 8px #00000040;animation:tabBarSlideIn .22s cubic-bezier(.25,.46,.45,.94) both}.tab-bar--leaving{animation:tabBarSlideOut .16s ease-in both}@keyframes tabBarSlideIn{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes tabBarSlideOut{0%{transform:translateY(0);opacity:1}to{transform:translateY(-100%);opacity:0}}.tab-list{display:flex;align-items:stretch;gap:3px;flex:1;min-width:0;overflow-x:auto;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.15) transparent}.tab-list::-webkit-scrollbar{height:2px}.tab-list::-webkit-scrollbar-track{background:transparent}.tab-list::-webkit-scrollbar-thumb{background:#fff3;border-radius:2px}.tab{display:flex;align-items:center;gap:5px;padding:4px 8px;border-radius:5px;cursor:pointer;white-space:nowrap;font-size:12px;color:#ffffff8c;background:#ffffff0a;border:1px solid transparent;transition:background .15s,border-color .15s,color .15s;flex:1 1 0;min-width:60px;max-width:180px;overflow:hidden;-webkit-user-select:none;user-select:none}.tab--with-module{align-items:flex-start;padding-top:5px;padding-bottom:5px}.tab:hover{background:#ffffff17;color:#fffc}.tab:hover .tab-pin{opacity:.5}.tab--active{background:#398bf726;border-color:#398bf773;color:#93c5fd}.tab--pinned{border-color:#fbbf2459;background:#fbbf2412;flex:0 0 auto}.tab--pinned.tab--active{border-color:#398bf773;background:#398bf726}.tab-icon{font-size:11px;flex-shrink:0;margin-top:1px}.tab--with-module .tab-icon{margin-top:2px}.tab-body{display:flex;flex-direction:column;flex:1;min-width:0;gap:2px}.tab-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.2}.tab-module{display:flex;align-items:center;gap:4px;font-size:10.5px;color:#fff9;line-height:normal;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tab-module-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0;align-self:center;display:block}.tab-btn{background:none;border:none;padding:0 1px;cursor:pointer;color:inherit;font-size:9px;line-height:1;display:flex;align-items:center;flex-shrink:0}.tab-pin{opacity:0;transition:opacity .15s,color .15s,transform .2s;transform:rotate(45deg)}.tab-pin--active{opacity:1!important;color:#fbbf24;transform:rotate(0)}.tab-pin:hover{opacity:1!important}.tab-close{opacity:.4}.tab-close:hover{opacity:1}.tab-actions{display:flex;align-items:center;gap:4px;padding-left:8px;border-left:1px solid rgba(255,255,255,.08);margin-left:4px;flex-shrink:0}.tab-tip-fixed{position:fixed;z-index:99999;transform:translate(-50%);pointer-events:none;padding:6px 10px;border-radius:6px;background:#0f0f14;border:1px solid rgba(255,255,255,.07);white-space:nowrap;display:flex;flex-direction:column;gap:3px;animation:tabTipFadeIn .14s ease}.tab-tip-fixed:before{content:\"\";position:absolute;bottom:100%;left:50%;transform:translate(-50%);border:5px solid transparent;border-bottom-color:#0f0f14}.tab-tip-title{font-size:11px;font-weight:600;color:#fff}.tab-tip-module{display:flex;align-items:center;gap:4px;font-size:10px;color:#ffffffa6}.tab-tip-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}@keyframes tabTipFadeIn{0%{opacity:0;transform:translate(-50%) translateY(-4px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.tab-close-all{display:flex;align-items:center;gap:5px;background:none;border:none;cursor:pointer;color:#fff6;font-size:11px;padding:3px 6px;border-radius:4px;white-space:nowrap;transition:color .15s,background .15s}.tab-close-all:hover{color:#f87171;background:#f871711a}.tab-close-all i{font-size:12px}\n"] }]
838
- }], ctorParameters: () => [] });
834
+ }], ctorParameters: () => [], propDecorators: { moduleColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "moduleColors", required: false }] }] } });
839
835
 
840
836
  class DetectorService {
841
- componenteActual = signal(null);
837
+ componenteActual = signal(null, ...(ngDevMode ? [{ debugName: "componenteActual" }] : /* istanbul ignore next */ []));
842
838
  setComponente(componente) {
843
839
  this.componenteActual.set(componente);
844
840
  }
845
841
  getComponente() {
846
842
  return this.componenteActual.asReadonly();
847
843
  }
848
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DetectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
849
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DetectorService, providedIn: 'root' });
844
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: DetectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
845
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: DetectorService, providedIn: 'root' });
850
846
  }
851
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DetectorService, decorators: [{
847
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: DetectorService, decorators: [{
852
848
  type: Injectable,
853
849
  args: [{
854
850
  providedIn: 'root'
@@ -860,35 +856,35 @@ class FullComponent {
860
856
  contexts = inject(ChildrenOutletContexts);
861
857
  router = inject(Router);
862
858
  tabsService = inject(TabsService);
863
- menuItems = input([]);
864
- nameProyecto = input('');
865
- accentColor = input('#398bf7');
866
- showTabs = input(true);
867
- tabModuleColors = input({});
859
+ menuItems = input([], ...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
860
+ nameProyecto = input('', ...(ngDevMode ? [{ debugName: "nameProyecto" }] : /* istanbul ignore next */ []));
861
+ accentColor = input('#398bf7', ...(ngDevMode ? [{ debugName: "accentColor" }] : /* istanbul ignore next */ []));
862
+ showTabs = input(true, ...(ngDevMode ? [{ debugName: "showTabs" }] : /* istanbul ignore next */ []));
863
+ tabModuleColors = input({}, ...(ngDevMode ? [{ debugName: "tabModuleColors" }] : /* istanbul ignore next */ []));
868
864
  currentYear = new Date().getFullYear();
869
865
  // El vertical-header se recibe proyectado (<ng-content select="[header]">), así
870
866
  // que no es un ViewChild del template propio de `full` sino contenido — por eso
871
867
  // ContentChild en vez de ViewChild (mismo mecanismo que usa consults con ViewChild
872
868
  // porque ahí el header vive directo en su propio template, no proyectado).
873
869
  // El bottom-nav SOLO sale de ahí — igual que en consults, sin lista aparte.
874
- verticalHeaderSignal = signal(null);
870
+ verticalHeaderSignal = signal(null, ...(ngDevMode ? [{ debugName: "verticalHeaderSignal" }] : /* istanbul ignore next */ []));
875
871
  set verticalHeaderRef(vh) {
876
872
  if (vh)
877
873
  this.verticalHeaderSignal.set(vh);
878
874
  }
879
- bottomMenuItems = computed(() => this.verticalHeaderSignal()?.bottomNavItems() ?? []);
880
- isSidebarOpen = signal(false);
881
- isSidebarHovering = signal(false);
882
- isScrolled = signal(false);
875
+ bottomMenuItems = computed(() => this.verticalHeaderSignal()?.bottomNavItems() ?? [], ...(ngDevMode ? [{ debugName: "bottomMenuItems" }] : /* istanbul ignore next */ []));
876
+ isSidebarOpen = signal(false, ...(ngDevMode ? [{ debugName: "isSidebarOpen" }] : /* istanbul ignore next */ []));
877
+ isSidebarHovering = signal(false, ...(ngDevMode ? [{ debugName: "isSidebarHovering" }] : /* istanbul ignore next */ []));
878
+ isScrolled = signal(false, ...(ngDevMode ? [{ debugName: "isScrolled" }] : /* istanbul ignore next */ []));
883
879
  isDesktop = window.innerWidth >= 1191;
884
- isMobileView = signal(window.innerWidth <= 667);
885
- sidebarWidth = signal(260);
880
+ isMobileView = signal(window.innerWidth <= 667, ...(ngDevMode ? [{ debugName: "isMobileView" }] : /* istanbul ignore next */ []));
881
+ sidebarWidth = signal(260, ...(ngDevMode ? [{ debugName: "sidebarWidth" }] : /* istanbul ignore next */ []));
886
882
  // Datos de sesión: se reciben del consumidor (en vez de inyectar SesionService
887
883
  // acá) para que layout-tsi no dependa de core-tsi. Es un solo objeto requerido
888
884
  // (input.required) en vez de 6 inputs sueltos, para que Angular tire error si
889
885
  // el consumidor se olvida de pasarlo, en vez de fallar en silencio con '' o [].
890
- sessionData = input.required();
891
- nombreSucursal = computed(() => this.sessionData().sucursales?.find(s => s.codsuc == this.sessionData().codsuc)?.sucursal ?? '');
886
+ sessionData = input.required(...(ngDevMode ? [{ debugName: "sessionData" }] : /* istanbul ignore next */ []));
887
+ nombreSucursal = computed(() => this.sessionData().sucursales?.find(s => s.codsuc == this.sessionData().codsuc)?.sucursal ?? '', ...(ngDevMode ? [{ debugName: "nombreSucursal" }] : /* istanbul ignore next */ []));
892
888
  cambiarSucursal() {
893
889
  this.router.navigateByUrl('seleccionar-sucursal');
894
890
  }
@@ -900,7 +896,7 @@ class FullComponent {
900
896
  // saca la clase y se vuelve a poner en el siguiente frame para forzar que
901
897
  // el @keyframes de entrada se reinicie (una clase ya puesta no reinicia su
902
898
  // animación si se la vuelve a poner sin sacarla antes).
903
- routeAnimating = signal(false);
899
+ routeAnimating = signal(false, ...(ngDevMode ? [{ debugName: "routeAnimating" }] : /* istanbul ignore next */ []));
904
900
  onRouteActivate() {
905
901
  this.routeAnimating.set(false);
906
902
  requestAnimationFrame(() => requestAnimationFrame(() => this.routeAnimating.set(true)));
@@ -982,17 +978,17 @@ class FullComponent {
982
978
  this.isSidebarHovering.set(false);
983
979
  }
984
980
  }
985
- showBottomNav = computed(() => this.isMobileView() && !this.isSidebarOpen() && this.bottomMenuItems().length > 0);
986
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FullComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
987
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: FullComponent, isStandalone: true, selector: "app-full", inputs: { menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: false, transformFunction: null }, nameProyecto: { classPropertyName: "nameProyecto", publicName: "nameProyecto", isSignal: true, isRequired: false, transformFunction: null }, accentColor: { classPropertyName: "accentColor", publicName: "accentColor", isSignal: true, isRequired: false, transformFunction: null }, showTabs: { classPropertyName: "showTabs", publicName: "showTabs", isSignal: true, isRequired: false, transformFunction: null }, tabModuleColors: { classPropertyName: "tabModuleColors", publicName: "tabModuleColors", isSignal: true, isRequired: false, transformFunction: null }, sessionData: { classPropertyName: "sessionData", publicName: "sessionData", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "window:resize": "onResize($event)", "document:click": "onClickOutside($event)" } }, queries: [{ propertyName: "verticalHeaderRef", first: true, predicate: VerticalHeaderComponent, descendants: true }], viewQueries: [{ propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true }, { propertyName: "sidebarRef", first: true, predicate: ["sidebar"], descendants: true }], ngImport: i0, template: "<ng-content select=\"[header]\" />\r\n\r\n<div [ngClass]=\"{'layout': true, 'open': isSidebarOpen()}\">\r\n <div #sidebar class=\"sidebar\" id=\"sidebar\" [ngClass]=\"isSidebarOpen() ? 'open' : ''\"\r\n (mouseenter)=\"onSidebarHoverEnter()\" (mouseleave)=\"onSidebarHoverLeave()\">\r\n <div class=\"sub-sidebar py-3\">\r\n <div class=\"user-profile\" [class.collapsed]=\"!isSidebarActuallyOpen\">\r\n <div class=\"user-info\" [class.user-info--hidden]=\"!isSidebarActuallyOpen\">\r\n <span class=\"fw-6 fs-7 truncate-text user-name\">{{ sessionData().nombreUser }}</span>\r\n <span class=\"truncate-text user-sucursal\">{{ nombreSucursal() }}</span>\r\n </div>\r\n @if (sessionData().sucursales.length > 1) {\r\n <button type=\"button\" class=\"btn-cambiar-sucursal\" title=\"Cambiar sucursal\" aria-label=\"Cambiar sucursal\"\r\n (click)=\"cambiarSucursal()\">\r\n <i class=\"fas fa-right-left\"></i>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"pt-3 px-2 list-menu-sidebar\">\r\n <ul class=\"list-unstyled\">\r\n @for (item of menuItems(); track $index) {\r\n <app-menu-item [item]=\"item\" [isSidebarOpen]=\"isSidebarOpen()\" [isSidebarHovering]=\"isSidebarHovering()\"\r\n [parentModuleName]=\"item.title\" [accentColor]=\"accentColor()\" [accesos]=\"sessionData().accesos\" [rolId]=\"sessionData().rolId\" />\r\n }\r\n </ul>\r\n </div>\r\n\r\n <div class=\"sidebar-footer text-center\" [class.sidebar-footer--hidden]=\"!isSidebarActuallyOpen\">\r\n <p> \u00A9 {{ currentYear }} Grupo TSI - {{ sessionData().idCia }} </p>\r\n </div>\r\n </div>\r\n\r\n <div #contentContainer class=\"content\" [class.has-bottom-nav]=\"showBottomNav()\"\r\n [ngStyle]=\"{'background-color': 'var(--background-color)'}\">\r\n @if (showTabs()) {\r\n <app-tab-bar [moduleColors]=\"tabModuleColors()\" />\r\n }\r\n <div class=\"content-scroll\">\r\n <div class=\"container-fluid\" [class.route-fade-in]=\"routeAnimating()\">\r\n <router-outlet (activate)=\"onRouteActivate()\" />\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (showBottomNav()) {\r\n<app-bottom-navigation [menuItems]=\"bottomMenuItems()\" [isVisible]=\"true\" />\r\n}\r\n<ng-content select=\"[chatbot]\" />\r\n", styles: [".hidden{display:none!important}.header-container{height:50px;background:#c50048;display:flex;justify-content:space-between;align-items:center}.header-sidebar{height:50px;background:#c50048;display:flex;align-items:center;justify-content:space-between;gap:5px}.sub-sidebar{border-bottom:1px solid rgba(255,255,255,.1);background:#ffffff08;min-width:0}.user-profile{display:flex;align-items:center;gap:10px;padding:0 12px;min-width:0;min-height:36px}.user-profile.collapsed{justify-content:center;padding:0;gap:0}.btn-cambiar-sucursal{flex:0 0 auto;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;font-size:12px;border:1px solid rgba(255,255,255,.15);border-radius:8px;background:#ffffff0f;color:var(--sidebar-active-text);cursor:pointer;transition:background .2s ease,border-color .2s ease,transform .15s ease}.btn-cambiar-sucursal:hover{background:#ffffff24;border-color:#ffffff4d}.btn-cambiar-sucursal:active{transform:scale(.94)}.btn-cambiar-sucursal:focus-visible{outline:2px solid var(--sidebar-accent, #c50048);outline-offset:2px}.user-avatar{width:38px;height:38px;min-width:38px;border-radius:50%;background:linear-gradient(135deg,var(--sidebar-accent, #c50048),color-mix(in srgb,var(--sidebar-accent, #c50048) 60%,white));color:#fff;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;letter-spacing:.5px;box-shadow:0 0 0 2px #ffffff1a,0 4px 12px #0006}.user-info{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;visibility:visible;opacity:1;transition:opacity .15s ease .22s,visibility 0s ease .22s}.user-info--hidden{visibility:hidden!important;opacity:0!important;max-height:0!important;flex:0 0 0!important;width:0!important;overflow:hidden!important;padding:0!important;margin:0!important;transition:opacity .08s ease 0s,visibility 0s ease .08s,max-height 0s ease .08s!important}.user-name{color:var(--sidebar-active-text)}.user-sucursal{font-size:11px;color:var(--sidebar-text-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.list-unstyled{font-size:13px;color:var(--sidebar-text-color)}.layout{display:grid;grid-template-columns:260px 1fr;height:calc(100dvh - 50px)}.sidebar{background:linear-gradient(160deg,var(--sidebar-gradient-start) 0%,var(--sidebar-bg) 100%)!important;box-shadow:4px 0 24px #00000059;border-right:1px solid rgba(255,255,255,.05);transition:transform .3s ease-in-out;width:260px;overflow:hidden;scrollbar-width:none;display:flex;flex-direction:column}.list-menu-sidebar{flex:1;overflow-y:auto;scrollbar-width:none;margin-bottom:0}.sidebar-footer{font-size:11px;color:var(--sidebar-text-color);padding:10px 12px;border-top:1px solid rgba(255,255,255,.08);margin-top:auto;width:100%;display:flex;align-items:center;justify-content:center;opacity:.65;visibility:visible;transition:opacity .15s ease .25s,visibility 0s ease .25s}.sidebar-footer--hidden{opacity:0;visibility:hidden;transition:opacity .1s ease 0s,visibility 0s ease .1s}.sidebar-footer p{margin:0}.content{display:flex;flex-direction:column;overflow:hidden;max-height:100%}.content-scroll{flex:1;overflow-x:auto;overflow-y:auto;min-height:0;--content-space: .75rem}.content-scroll .container-fluid{padding:var(--content-space)!important}.content-scroll .container-fluid.route-fade-in{animation:routeContentFadeIn .32s cubic-bezier(.4,0,.2,1)}@keyframes routeContentFadeIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@media(max-width:1191px){.layout{grid-template-columns:1fr}.sidebar{position:fixed;top:50px;left:0;width:260px;height:calc(100dvh - 50px);z-index:1000;transform:translate(-100%);scrollbar-width:none;display:flex;flex-direction:column;overflow:visible}.sidebar-footer{display:flex!important}.sidebar.open{transform:translate(0)}}@media(min-width:1192px){.layout{grid-template-columns:260px 1fr;transition:grid-template-columns .3s ease-in-out}.layout.open{grid-template-columns:70px 1fr}.sidebar{width:260px;max-width:260px;transition:width .3s ease-in-out,max-width .3s ease-in-out}.sidebar.open{width:70px;max-width:70px}}.truncate-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;width:100%}.tc-bubble-container{position:fixed;top:111px;right:30px;z-index:9999}.tc-bubble{background:#c50048;color:#fff;padding:10px 14px;border-radius:50px;cursor:pointer;display:flex;align-items:center;gap:8px;box-shadow:0 4px 12px #0003;transition:all .2s ease}.tc-bubble:hover{transform:scale(1.05)}.tc-label{font-size:13px;font-weight:600}.tc-dropdown{margin-top:10px;background:#fff;border-radius:12px;padding:10px;min-width:220px;box-shadow:0 6px 18px #00000026}.tc-item{display:flex;align-items:center;gap:8px;padding:6px 4px;font-size:13px}.tc-item i{color:#c50048}.tc-item .item-content{display:flex;justify-content:space-between;align-items:center;width:100%}.tc-item .item-label{color:#333;text-align:left}.tc-item .item-value{color:#333;text-align:right;font-weight:500;margin-left:16px}@media(max-width:700px){.tc-bubble-container{top:auto;bottom:55px;right:40px}}.mobile-view .content{min-height:calc(100dvh - 110px)}@media(max-width:1191px){.content.has-bottom-nav{padding-bottom:60px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i2.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: MenuItemComponent, selector: "app-menu-item", inputs: ["item", "isSidebarOpen", "isSidebarHovering", "level", "parentModuleName", "accentColor", "accesos", "rolId"] }, { kind: "component", type: BottomNavigationComponent, selector: "app-bottom-navigation", inputs: ["menuItems", "isVisible"], outputs: ["itemClick"] }, { kind: "component", type: TabBarComponent, selector: "app-tab-bar", inputs: ["moduleColors"] }] });
981
+ showBottomNav = computed(() => this.isMobileView() && !this.isSidebarOpen() && this.bottomMenuItems().length > 0, ...(ngDevMode ? [{ debugName: "showBottomNav" }] : /* istanbul ignore next */ []));
982
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: FullComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
983
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: FullComponent, isStandalone: true, selector: "app-full", inputs: { menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: false, transformFunction: null }, nameProyecto: { classPropertyName: "nameProyecto", publicName: "nameProyecto", isSignal: true, isRequired: false, transformFunction: null }, accentColor: { classPropertyName: "accentColor", publicName: "accentColor", isSignal: true, isRequired: false, transformFunction: null }, showTabs: { classPropertyName: "showTabs", publicName: "showTabs", isSignal: true, isRequired: false, transformFunction: null }, tabModuleColors: { classPropertyName: "tabModuleColors", publicName: "tabModuleColors", isSignal: true, isRequired: false, transformFunction: null }, sessionData: { classPropertyName: "sessionData", publicName: "sessionData", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "window:resize": "onResize($event)", "document:click": "onClickOutside($event)" } }, queries: [{ propertyName: "verticalHeaderRef", first: true, predicate: VerticalHeaderComponent, descendants: true }], viewQueries: [{ propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true }, { propertyName: "sidebarRef", first: true, predicate: ["sidebar"], descendants: true }], ngImport: i0, template: "<ng-content select=\"[header]\" />\r\n\r\n<div [ngClass]=\"{'layout': true, 'open': isSidebarOpen()}\">\r\n <div #sidebar class=\"sidebar\" id=\"sidebar\" [ngClass]=\"isSidebarOpen() ? 'open' : ''\"\r\n (mouseenter)=\"onSidebarHoverEnter()\" (mouseleave)=\"onSidebarHoverLeave()\">\r\n <div class=\"sub-sidebar py-3\">\r\n <div class=\"user-profile\" [class.collapsed]=\"!isSidebarActuallyOpen\">\r\n <div class=\"user-info\" [class.user-info--hidden]=\"!isSidebarActuallyOpen\">\r\n <span class=\"fw-6 fs-7 truncate-text user-name\">{{ sessionData().nombreUser }}</span>\r\n <span class=\"truncate-text user-sucursal\">{{ nombreSucursal() }}</span>\r\n </div>\r\n @if (sessionData().sucursales.length > 1) {\r\n <button type=\"button\" class=\"btn-cambiar-sucursal\" title=\"Cambiar sucursal\" aria-label=\"Cambiar sucursal\"\r\n (click)=\"cambiarSucursal()\">\r\n <i class=\"fas fa-right-left\"></i>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"pt-3 px-2 list-menu-sidebar\">\r\n <ul class=\"list-unstyled\">\r\n @for (item of menuItems(); track $index) {\r\n <app-menu-item [item]=\"item\" [isSidebarOpen]=\"isSidebarOpen()\" [isSidebarHovering]=\"isSidebarHovering()\"\r\n [parentModuleName]=\"item.title\" [accentColor]=\"accentColor()\" [accesos]=\"sessionData().accesos\" [rolId]=\"sessionData().rolId\" />\r\n }\r\n </ul>\r\n </div>\r\n\r\n <div class=\"sidebar-footer text-center\" [class.sidebar-footer--hidden]=\"!isSidebarActuallyOpen\">\r\n <p> \u00A9 {{ currentYear }} Grupo TSI - {{ sessionData().idCia }} </p>\r\n </div>\r\n </div>\r\n\r\n <div #contentContainer class=\"content\" [class.has-bottom-nav]=\"showBottomNav()\"\r\n [ngStyle]=\"{'background-color': 'var(--background-color)'}\">\r\n @if (showTabs()) {\r\n <app-tab-bar [moduleColors]=\"tabModuleColors()\" />\r\n }\r\n <div class=\"content-scroll\">\r\n <div class=\"container-fluid\" [class.route-fade-in]=\"routeAnimating()\">\r\n <router-outlet (activate)=\"onRouteActivate()\" />\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (showBottomNav()) {\r\n<app-bottom-navigation [menuItems]=\"bottomMenuItems()\" [isVisible]=\"true\" />\r\n}\r\n<ng-content select=\"[chatbot]\" />\r\n", styles: [".hidden{display:none!important}.header-container{height:50px;background:#c50048;display:flex;justify-content:space-between;align-items:center}.header-sidebar{height:50px;background:#c50048;display:flex;align-items:center;justify-content:space-between;gap:5px}.sub-sidebar{border-bottom:1px solid rgba(255,255,255,.1);background:#ffffff08;min-width:0}.user-profile{display:flex;align-items:center;gap:10px;padding:0 12px;min-width:0;min-height:36px}.user-profile.collapsed{justify-content:center;padding:0;gap:0}.btn-cambiar-sucursal{flex:0 0 auto;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;font-size:12px;border:1px solid rgba(255,255,255,.15);border-radius:8px;background:#ffffff0f;color:var(--sidebar-active-text);cursor:pointer;transition:background .2s ease,border-color .2s ease,transform .15s ease}.btn-cambiar-sucursal:hover{background:#ffffff24;border-color:#ffffff4d}.btn-cambiar-sucursal:active{transform:scale(.94)}.btn-cambiar-sucursal:focus-visible{outline:2px solid var(--sidebar-accent, #c50048);outline-offset:2px}.user-avatar{width:38px;height:38px;min-width:38px;border-radius:50%;background:linear-gradient(135deg,var(--sidebar-accent, #c50048),color-mix(in srgb,var(--sidebar-accent, #c50048) 60%,white));color:#fff;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;letter-spacing:.5px;box-shadow:0 0 0 2px #ffffff1a,0 4px 12px #0006}.user-info{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;visibility:visible;opacity:1;transition:opacity .15s ease .22s,visibility 0s ease .22s}.user-info--hidden{visibility:hidden!important;opacity:0!important;max-height:0!important;flex:0 0 0!important;width:0!important;overflow:hidden!important;padding:0!important;margin:0!important;transition:opacity .08s ease 0s,visibility 0s ease .08s,max-height 0s ease .08s!important}.user-name{color:var(--sidebar-active-text)}.user-sucursal{font-size:11px;color:var(--sidebar-text-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.list-unstyled{font-size:13px;color:var(--sidebar-text-color)}.layout{display:grid;grid-template-columns:260px 1fr;height:calc(100dvh - 50px)}.sidebar{background:linear-gradient(160deg,var(--sidebar-gradient-start) 0%,var(--sidebar-bg) 100%)!important;box-shadow:4px 0 24px #00000059;border-right:1px solid rgba(255,255,255,.05);transition:transform .3s ease-in-out;width:260px;overflow:hidden;scrollbar-width:none;display:flex;flex-direction:column}.list-menu-sidebar{flex:1;overflow-y:auto;scrollbar-width:none;margin-bottom:0}.sidebar-footer{font-size:11px;color:var(--sidebar-text-color);padding:10px 12px;border-top:1px solid rgba(255,255,255,.08);margin-top:auto;width:100%;display:flex;align-items:center;justify-content:center;opacity:.65;visibility:visible;transition:opacity .15s ease .25s,visibility 0s ease .25s}.sidebar-footer--hidden{opacity:0;visibility:hidden;transition:opacity .1s ease 0s,visibility 0s ease .1s}.sidebar-footer p{margin:0}.content{display:flex;flex-direction:column;overflow:hidden;max-height:100%}.content-scroll{flex:1;overflow-x:auto;overflow-y:auto;min-height:0;--content-space: .75rem}.content-scroll .container-fluid{padding:var(--content-space)!important}.content-scroll .container-fluid.route-fade-in{animation:routeContentFadeIn .32s cubic-bezier(.4,0,.2,1)}@keyframes routeContentFadeIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@media(max-width:1191px){.layout{grid-template-columns:1fr}.sidebar{position:fixed;top:50px;left:0;width:260px;height:calc(100dvh - 50px);z-index:1000;transform:translate(-100%);scrollbar-width:none;display:flex;flex-direction:column;overflow:visible}.sidebar-footer{display:flex!important}.sidebar.open{transform:translate(0)}}@media(min-width:1192px){.layout{grid-template-columns:260px 1fr;transition:grid-template-columns .3s ease-in-out}.layout.open{grid-template-columns:70px 1fr}.sidebar{width:260px;max-width:260px;transition:width .3s ease-in-out,max-width .3s ease-in-out}.sidebar.open{width:70px;max-width:70px}}.truncate-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;width:100%}.tc-bubble-container{position:fixed;top:111px;right:30px;z-index:9999}.tc-bubble{background:#c50048;color:#fff;padding:10px 14px;border-radius:50px;cursor:pointer;display:flex;align-items:center;gap:8px;box-shadow:0 4px 12px #0003;transition:all .2s ease}.tc-bubble:hover{transform:scale(1.05)}.tc-label{font-size:13px;font-weight:600}.tc-dropdown{margin-top:10px;background:#fff;border-radius:12px;padding:10px;min-width:220px;box-shadow:0 6px 18px #00000026}.tc-item{display:flex;align-items:center;gap:8px;padding:6px 4px;font-size:13px}.tc-item i{color:#c50048}.tc-item .item-content{display:flex;justify-content:space-between;align-items:center;width:100%}.tc-item .item-label{color:#333;text-align:left}.tc-item .item-value{color:#333;text-align:right;font-weight:500;margin-left:16px}@media(max-width:700px){.tc-bubble-container{top:auto;bottom:55px;right:40px}}.mobile-view .content{min-height:calc(100dvh - 110px)}@media(max-width:1191px){.content.has-bottom-nav{padding-bottom:60px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i2.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: MenuItemComponent, selector: "app-menu-item", inputs: ["item", "isSidebarOpen", "isSidebarHovering", "level", "parentModuleName", "accentColor", "accesos", "rolId"] }, { kind: "component", type: BottomNavigationComponent, selector: "app-bottom-navigation", inputs: ["menuItems", "isVisible"], outputs: ["itemClick"] }, { kind: "component", type: TabBarComponent, selector: "app-tab-bar", inputs: ["moduleColors"] }] });
988
984
  }
989
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FullComponent, decorators: [{
985
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: FullComponent, decorators: [{
990
986
  type: Component,
991
987
  args: [{ selector: 'app-full', imports: [CommonModule, RouterModule, MenuItemComponent, BottomNavigationComponent, TabBarComponent], template: "<ng-content select=\"[header]\" />\r\n\r\n<div [ngClass]=\"{'layout': true, 'open': isSidebarOpen()}\">\r\n <div #sidebar class=\"sidebar\" id=\"sidebar\" [ngClass]=\"isSidebarOpen() ? 'open' : ''\"\r\n (mouseenter)=\"onSidebarHoverEnter()\" (mouseleave)=\"onSidebarHoverLeave()\">\r\n <div class=\"sub-sidebar py-3\">\r\n <div class=\"user-profile\" [class.collapsed]=\"!isSidebarActuallyOpen\">\r\n <div class=\"user-info\" [class.user-info--hidden]=\"!isSidebarActuallyOpen\">\r\n <span class=\"fw-6 fs-7 truncate-text user-name\">{{ sessionData().nombreUser }}</span>\r\n <span class=\"truncate-text user-sucursal\">{{ nombreSucursal() }}</span>\r\n </div>\r\n @if (sessionData().sucursales.length > 1) {\r\n <button type=\"button\" class=\"btn-cambiar-sucursal\" title=\"Cambiar sucursal\" aria-label=\"Cambiar sucursal\"\r\n (click)=\"cambiarSucursal()\">\r\n <i class=\"fas fa-right-left\"></i>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"pt-3 px-2 list-menu-sidebar\">\r\n <ul class=\"list-unstyled\">\r\n @for (item of menuItems(); track $index) {\r\n <app-menu-item [item]=\"item\" [isSidebarOpen]=\"isSidebarOpen()\" [isSidebarHovering]=\"isSidebarHovering()\"\r\n [parentModuleName]=\"item.title\" [accentColor]=\"accentColor()\" [accesos]=\"sessionData().accesos\" [rolId]=\"sessionData().rolId\" />\r\n }\r\n </ul>\r\n </div>\r\n\r\n <div class=\"sidebar-footer text-center\" [class.sidebar-footer--hidden]=\"!isSidebarActuallyOpen\">\r\n <p> \u00A9 {{ currentYear }} Grupo TSI - {{ sessionData().idCia }} </p>\r\n </div>\r\n </div>\r\n\r\n <div #contentContainer class=\"content\" [class.has-bottom-nav]=\"showBottomNav()\"\r\n [ngStyle]=\"{'background-color': 'var(--background-color)'}\">\r\n @if (showTabs()) {\r\n <app-tab-bar [moduleColors]=\"tabModuleColors()\" />\r\n }\r\n <div class=\"content-scroll\">\r\n <div class=\"container-fluid\" [class.route-fade-in]=\"routeAnimating()\">\r\n <router-outlet (activate)=\"onRouteActivate()\" />\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (showBottomNav()) {\r\n<app-bottom-navigation [menuItems]=\"bottomMenuItems()\" [isVisible]=\"true\" />\r\n}\r\n<ng-content select=\"[chatbot]\" />\r\n", styles: [".hidden{display:none!important}.header-container{height:50px;background:#c50048;display:flex;justify-content:space-between;align-items:center}.header-sidebar{height:50px;background:#c50048;display:flex;align-items:center;justify-content:space-between;gap:5px}.sub-sidebar{border-bottom:1px solid rgba(255,255,255,.1);background:#ffffff08;min-width:0}.user-profile{display:flex;align-items:center;gap:10px;padding:0 12px;min-width:0;min-height:36px}.user-profile.collapsed{justify-content:center;padding:0;gap:0}.btn-cambiar-sucursal{flex:0 0 auto;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;font-size:12px;border:1px solid rgba(255,255,255,.15);border-radius:8px;background:#ffffff0f;color:var(--sidebar-active-text);cursor:pointer;transition:background .2s ease,border-color .2s ease,transform .15s ease}.btn-cambiar-sucursal:hover{background:#ffffff24;border-color:#ffffff4d}.btn-cambiar-sucursal:active{transform:scale(.94)}.btn-cambiar-sucursal:focus-visible{outline:2px solid var(--sidebar-accent, #c50048);outline-offset:2px}.user-avatar{width:38px;height:38px;min-width:38px;border-radius:50%;background:linear-gradient(135deg,var(--sidebar-accent, #c50048),color-mix(in srgb,var(--sidebar-accent, #c50048) 60%,white));color:#fff;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;letter-spacing:.5px;box-shadow:0 0 0 2px #ffffff1a,0 4px 12px #0006}.user-info{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;visibility:visible;opacity:1;transition:opacity .15s ease .22s,visibility 0s ease .22s}.user-info--hidden{visibility:hidden!important;opacity:0!important;max-height:0!important;flex:0 0 0!important;width:0!important;overflow:hidden!important;padding:0!important;margin:0!important;transition:opacity .08s ease 0s,visibility 0s ease .08s,max-height 0s ease .08s!important}.user-name{color:var(--sidebar-active-text)}.user-sucursal{font-size:11px;color:var(--sidebar-text-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.list-unstyled{font-size:13px;color:var(--sidebar-text-color)}.layout{display:grid;grid-template-columns:260px 1fr;height:calc(100dvh - 50px)}.sidebar{background:linear-gradient(160deg,var(--sidebar-gradient-start) 0%,var(--sidebar-bg) 100%)!important;box-shadow:4px 0 24px #00000059;border-right:1px solid rgba(255,255,255,.05);transition:transform .3s ease-in-out;width:260px;overflow:hidden;scrollbar-width:none;display:flex;flex-direction:column}.list-menu-sidebar{flex:1;overflow-y:auto;scrollbar-width:none;margin-bottom:0}.sidebar-footer{font-size:11px;color:var(--sidebar-text-color);padding:10px 12px;border-top:1px solid rgba(255,255,255,.08);margin-top:auto;width:100%;display:flex;align-items:center;justify-content:center;opacity:.65;visibility:visible;transition:opacity .15s ease .25s,visibility 0s ease .25s}.sidebar-footer--hidden{opacity:0;visibility:hidden;transition:opacity .1s ease 0s,visibility 0s ease .1s}.sidebar-footer p{margin:0}.content{display:flex;flex-direction:column;overflow:hidden;max-height:100%}.content-scroll{flex:1;overflow-x:auto;overflow-y:auto;min-height:0;--content-space: .75rem}.content-scroll .container-fluid{padding:var(--content-space)!important}.content-scroll .container-fluid.route-fade-in{animation:routeContentFadeIn .32s cubic-bezier(.4,0,.2,1)}@keyframes routeContentFadeIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@media(max-width:1191px){.layout{grid-template-columns:1fr}.sidebar{position:fixed;top:50px;left:0;width:260px;height:calc(100dvh - 50px);z-index:1000;transform:translate(-100%);scrollbar-width:none;display:flex;flex-direction:column;overflow:visible}.sidebar-footer{display:flex!important}.sidebar.open{transform:translate(0)}}@media(min-width:1192px){.layout{grid-template-columns:260px 1fr;transition:grid-template-columns .3s ease-in-out}.layout.open{grid-template-columns:70px 1fr}.sidebar{width:260px;max-width:260px;transition:width .3s ease-in-out,max-width .3s ease-in-out}.sidebar.open{width:70px;max-width:70px}}.truncate-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;width:100%}.tc-bubble-container{position:fixed;top:111px;right:30px;z-index:9999}.tc-bubble{background:#c50048;color:#fff;padding:10px 14px;border-radius:50px;cursor:pointer;display:flex;align-items:center;gap:8px;box-shadow:0 4px 12px #0003;transition:all .2s ease}.tc-bubble:hover{transform:scale(1.05)}.tc-label{font-size:13px;font-weight:600}.tc-dropdown{margin-top:10px;background:#fff;border-radius:12px;padding:10px;min-width:220px;box-shadow:0 6px 18px #00000026}.tc-item{display:flex;align-items:center;gap:8px;padding:6px 4px;font-size:13px}.tc-item i{color:#c50048}.tc-item .item-content{display:flex;justify-content:space-between;align-items:center;width:100%}.tc-item .item-label{color:#333;text-align:left}.tc-item .item-value{color:#333;text-align:right;font-weight:500;margin-left:16px}@media(max-width:700px){.tc-bubble-container{top:auto;bottom:55px;right:40px}}.mobile-view .content{min-height:calc(100dvh - 110px)}@media(max-width:1191px){.content.has-bottom-nav{padding-bottom:60px}}\n"] }]
992
- }], ctorParameters: () => [], propDecorators: { verticalHeaderRef: [{
988
+ }], ctorParameters: () => [], propDecorators: { menuItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuItems", required: false }] }], nameProyecto: [{ type: i0.Input, args: [{ isSignal: true, alias: "nameProyecto", required: false }] }], accentColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "accentColor", required: false }] }], showTabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTabs", required: false }] }], tabModuleColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabModuleColors", required: false }] }], verticalHeaderRef: [{
993
989
  type: ContentChild,
994
990
  args: [VerticalHeaderComponent]
995
- }], contentContainer: [{
991
+ }], sessionData: [{ type: i0.Input, args: [{ isSignal: true, alias: "sessionData", required: true }] }], contentContainer: [{
996
992
  type: ViewChild,
997
993
  args: ['contentContainer']
998
994
  }], sidebarRef: [{
@@ -1010,10 +1006,10 @@ const CHATBOT_CONFIG = new InjectionToken('CHATBOT_CONFIG');
1010
1006
 
1011
1007
  class ChatbotService {
1012
1008
  config = inject(CHATBOT_CONFIG);
1013
- messages = signal([]);
1014
- isTyping = signal(false);
1015
- isOpen = signal(false);
1016
- hasActiveConversation = computed(() => this.messages().length > 1);
1009
+ messages = signal([], ...(ngDevMode ? [{ debugName: "messages" }] : /* istanbul ignore next */ []));
1010
+ isTyping = signal(false, ...(ngDevMode ? [{ debugName: "isTyping" }] : /* istanbul ignore next */ []));
1011
+ isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
1012
+ hasActiveConversation = computed(() => this.messages().length > 1, ...(ngDevMode ? [{ debugName: "hasActiveConversation" }] : /* istanbul ignore next */ []));
1017
1013
  constructor() {
1018
1014
  this.init();
1019
1015
  }
@@ -1068,23 +1064,22 @@ class ChatbotService {
1068
1064
  restart() {
1069
1065
  this.init();
1070
1066
  }
1071
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: ChatbotService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1072
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: ChatbotService });
1067
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: ChatbotService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1068
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: ChatbotService });
1073
1069
  }
1074
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: ChatbotService, decorators: [{
1070
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: ChatbotService, decorators: [{
1075
1071
  type: Injectable
1076
1072
  }], ctorParameters: () => [] });
1077
1073
 
1078
1074
  class ChatbotComponent {
1079
1075
  service = inject(ChatbotService);
1080
1076
  config = inject(CHATBOT_CONFIG);
1081
- zone = inject(NgZone);
1082
- messagesEnd = viewChild('messagesEnd');
1083
- wrapper = viewChild('wrapper');
1084
- position = signal(null);
1085
- isDragging = signal(false);
1086
- openDir = signal('above');
1087
- openHDir = signal('right');
1077
+ messagesEnd = viewChild('messagesEnd', ...(ngDevMode ? [{ debugName: "messagesEnd" }] : /* istanbul ignore next */ []));
1078
+ wrapper = viewChild('wrapper', ...(ngDevMode ? [{ debugName: "wrapper" }] : /* istanbul ignore next */ []));
1079
+ position = signal(null, ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
1080
+ isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : /* istanbul ignore next */ []));
1081
+ openDir = signal('above', ...(ngDevMode ? [{ debugName: "openDir" }] : /* istanbul ignore next */ []));
1082
+ openHDir = signal('right', ...(ngDevMode ? [{ debugName: "openHDir" }] : /* istanbul ignore next */ []));
1088
1083
  dragOffset = { x: 0, y: 0 };
1089
1084
  hasDragged = false;
1090
1085
  constructor() {
@@ -1124,56 +1119,54 @@ class ChatbotComponent {
1124
1119
  if (!this.position())
1125
1120
  this.position.set({ x: rect.left, y: rect.top });
1126
1121
  this.isDragging.set(true);
1127
- this.zone.runOutsideAngular(() => {
1128
- document.addEventListener('mousemove', this.onDrag);
1129
- document.addEventListener('mouseup', this.stopDrag);
1130
- });
1122
+ document.addEventListener('mousemove', this.onDrag);
1123
+ document.addEventListener('mouseup', this.stopDrag);
1131
1124
  }
1132
1125
  onDrag = (event) => {
1133
1126
  this.hasDragged = true;
1134
1127
  const el = this.wrapper().nativeElement;
1135
1128
  const x = Math.max(0, Math.min(event.clientX - this.dragOffset.x, window.innerWidth - el.offsetWidth));
1136
1129
  const y = Math.max(0, Math.min(event.clientY - this.dragOffset.y, window.innerHeight - el.offsetHeight));
1137
- this.zone.run(() => this.position.set({ x, y }));
1130
+ this.position.set({ x, y });
1138
1131
  };
1139
1132
  stopDrag = () => {
1140
- this.zone.run(() => this.isDragging.set(false));
1133
+ this.isDragging.set(false);
1141
1134
  document.removeEventListener('mousemove', this.onDrag);
1142
1135
  document.removeEventListener('mouseup', this.stopDrag);
1143
1136
  };
1144
1137
  scrollToBottom() {
1145
1138
  this.messagesEnd()?.nativeElement.scrollIntoView({ behavior: 'smooth' });
1146
1139
  }
1147
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: ChatbotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1148
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: ChatbotComponent, isStandalone: true, selector: "app-chatbot", providers: [ChatbotService], viewQueries: [{ propertyName: "messagesEnd", first: true, predicate: ["messagesEnd"], descendants: true, isSignal: true }, { propertyName: "wrapper", first: true, predicate: ["wrapper"], descendants: true, isSignal: true }], ngImport: i0, template: "<div #wrapper class=\"chatbot-wrapper\"\r\n [class.chatbot-left]=\"config.position === 'bottom-left'\"\r\n [class.chatbot-dragging]=\"isDragging()\"\r\n [style.--chatbot-primary]=\"primaryColor\"\r\n [style.left.px]=\"position()?.x\"\r\n [style.top.px]=\"position()?.y\"\r\n [style.right]=\"position() ? 'auto' : null\"\r\n [style.bottom]=\"position() ? 'auto' : null\">\r\n\r\n @if (!service.isOpen()) {\r\n <span class=\"chatbot-beta\">Beta</span>\r\n }\r\n <button class=\"chatbot-fab\"\r\n [class.chatbot-fab--hidden]=\"service.isOpen()\"\r\n (mousedown)=\"startDrag($event)\"\r\n (click)=\"onFabClick()\"\r\n title=\"Abrir asistente\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"26\" height=\"26\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2M7.5 13A2.5 2.5 0 0 0 5 15.5 2.5 2.5 0 0 0 7.5 18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 7.5 13m9 0a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 16.5 13z\" />\r\n </svg>\r\n @if (service.hasActiveConversation()) {\r\n <span class=\"chatbot-badge\" title=\"Conversaci\u00F3n en progreso\"></span>\r\n }\r\n </button>\r\n\r\n @if (service.isOpen()) {\r\n <div class=\"chatbot-window\"\r\n [class.open-above]=\"openDir() === 'above'\"\r\n [class.open-below]=\"openDir() === 'below'\"\r\n [class.open-right]=\"openHDir() === 'right'\"\r\n [class.open-left]=\"openHDir() === 'left'\">\r\n\r\n <div class=\"chatbot-header\" (mousedown)=\"startDrag($event)\">\r\n <div class=\"chatbot-header-info\">\r\n <span class=\"chatbot-avatar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2M7.5 13A2.5 2.5 0 0 0 5 15.5 2.5 2.5 0 0 0 7.5 18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 7.5 13m9 0a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 16.5 13z\" />\r\n </svg>\r\n </span>\r\n <div>\r\n <div class=\"chatbot-name\">{{ config.botName || 'Asistente' }}</div>\r\n <div class=\"chatbot-status\">En l\u00EDnea</div>\r\n </div>\r\n </div>\r\n <div class=\"chatbot-header-actions\">\r\n <button class=\"chatbot-action-btn\" (click)=\"service.minimize()\" title=\"Minimizar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\r\n <path d=\"M2 8a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11A.5.5 0 0 1 2 8z\" />\r\n </svg>\r\n </button>\r\n <button class=\"chatbot-action-btn\" (click)=\"service.close()\" title=\"Cerrar y reiniciar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\r\n <path d=\"M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chatbot-body\">\r\n @for (msg of service.messages(); track $index; let i = $index) {\r\n <div class=\"chat-row\" [class.chat-row-user]=\"msg.from === 'user'\">\r\n @if (msg.from === 'bot') {\r\n <span class=\"bot-icon\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2M7.5 13A2.5 2.5 0 0 0 5 15.5 2.5 2.5 0 0 0 7.5 18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 7.5 13m9 0a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 16.5 13z\" />\r\n </svg>\r\n </span>\r\n }\r\n <div class=\"chat-col\">\r\n <div class=\"message-bubble\" [class.bubble-bot]=\"msg.from === 'bot'\" [class.bubble-user]=\"msg.from === 'user'\">\r\n {{ msg.text }}\r\n </div>\r\n @if (msg.options && msg.options.length > 0) {\r\n <div class=\"options-container\">\r\n @for (opt of msg.options; track $index) {\r\n <button class=\"option-btn\" [disabled]=\"msg.optionsDisabled\" (click)=\"selectOption(opt, i)\">\r\n {{ opt.label }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (service.isTyping()) {\r\n <div class=\"chat-row\">\r\n <span class=\"bot-icon\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2M7.5 13A2.5 2.5 0 0 0 5 15.5 2.5 2.5 0 0 0 7.5 18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 7.5 13m9 0a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 16.5 13z\" />\r\n </svg>\r\n </span>\r\n <div class=\"message-bubble bubble-bot typing-bubble\">\r\n <span class=\"dot\"></span><span class=\"dot\"></span><span class=\"dot\"></span>\r\n </div>\r\n </div>\r\n }\r\n <div #messagesEnd></div>\r\n </div>\r\n\r\n <div class=\"chatbot-footer\">\r\n <button class=\"restart-btn\" (click)=\"service.restart()\">\u21BA Reiniciar conversaci\u00F3n</button>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{--chatbot-primary: #c50048}.chatbot-wrapper{position:fixed;bottom:24px;right:24px;z-index:10000;font-family:Poppins,sans-serif;animation:chatbotFabIn .26s cubic-bezier(.2,0,.2,1) both}.chatbot-wrapper.chatbot-left{right:auto;left:24px}@keyframes chatbotFabIn{0%{opacity:0;transform:translateY(14px) scale(.85)}to{opacity:1;transform:translateY(0) scale(1)}}.chatbot-dragging{-webkit-user-select:none;user-select:none}.chatbot-dragging *{cursor:grabbing!important}.chatbot-beta{position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%);background:#0000008c;color:#ffffffd9;font-size:9px;font-weight:600;letter-spacing:.08em;padding:2px 6px;border-radius:4px;pointer-events:none;text-transform:uppercase;white-space:nowrap}.chatbot-fab{cursor:grab;position:relative;width:54px;height:54px;border-radius:50%;border:none;background:var(--chatbot-primary);color:#fff;cursor:pointer;box-shadow:0 4px 18px #0000004d;display:flex;align-items:center;justify-content:center;transition:transform .2s ease,box-shadow .2s ease}.chatbot-fab:hover{transform:scale(1.08);box-shadow:0 6px 22px #0006}.chatbot-badge{position:absolute;top:4px;right:4px;width:12px;height:12px;border-radius:50%;background:#facc15;border:2px solid #fff;animation:cbPulse 1.8s ease-in-out infinite}@keyframes cbPulse{0%,to{transform:scale(1);opacity:1}50%{transform:scale(1.3);opacity:.75}}.chatbot-fab--hidden{visibility:hidden;pointer-events:none}.chatbot-window{position:absolute;width:320px;max-height:490px;border-radius:16px;overflow:hidden;display:flex;flex-direction:column;box-shadow:0 8px 36px #00000038;background:var(--background-card, #ffffff);animation:cbSlideUp .22s ease}.chatbot-window.open-above{bottom:62px}.chatbot-window.open-below{top:62px}.chatbot-window.open-right{left:0}.chatbot-window.open-left{right:0}@keyframes cbSlideUp{0%{opacity:0;transform:translateY(14px)}to{opacity:1;transform:translateY(0)}}.chatbot-header{padding:12px 14px;background:var(--chatbot-primary);color:#fff;display:flex;align-items:center;justify-content:space-between;flex-shrink:0;cursor:grab}.chatbot-header-info{display:flex;align-items:center;gap:8px}.chatbot-avatar{font-size:20px;line-height:1}.chatbot-name{font-size:13px;font-weight:600}.chatbot-status{font-size:10px;opacity:.82}.chatbot-header-actions{display:flex;align-items:center;gap:2px}.chatbot-action-btn{background:none;border:none;color:#fff;cursor:pointer;padding:4px 6px;border-radius:4px;opacity:.75;display:flex;align-items:center;justify-content:center;transition:opacity .15s,background .15s}.chatbot-action-btn:hover{opacity:1;background:#ffffff2e}.chatbot-body{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px;background:var(--background-color, #f0f0f0)}.chat-row{display:flex;align-items:flex-start;gap:6px}.chat-row.chat-row-user{flex-direction:row-reverse}.bot-icon{font-size:16px;flex-shrink:0;margin-top:4px}.chat-col{display:flex;flex-direction:column;gap:4px;max-width:82%}.message-bubble{padding:8px 11px;border-radius:12px;font-size:11.5px;line-height:1.55;word-break:break-word}.message-bubble.bubble-bot{background:var(--background-card, #ffffff);color:var(--text-color, #1d1d1d);border-bottom-left-radius:4px;box-shadow:0 1px 4px #00000012}.message-bubble.bubble-user{background:var(--chatbot-primary);color:#fff;border-bottom-right-radius:4px;align-self:flex-end}.options-container{display:flex;flex-direction:column;gap:4px}.option-btn{background:var(--background-card, #ffffff);color:var(--chatbot-primary);border:1.5px solid var(--chatbot-primary);border-radius:8px;padding:5px 10px;font-size:11px;font-weight:600;cursor:pointer;text-align:left;transition:background .18s ease,color .18s ease}.option-btn:hover:not(:disabled){background:var(--chatbot-primary);color:#fff}.option-btn:disabled{opacity:.38;cursor:default}.typing-bubble{display:flex;gap:4px;align-items:center;padding:10px 14px!important}.dot{width:7px;height:7px;background:var(--placeholder-color, #aaa);border-radius:50%;animation:cbBounce 1.2s ease-in-out infinite}.dot:nth-child(2){animation-delay:.18s}.dot:nth-child(3){animation-delay:.36s}@keyframes cbBounce{0%,80%,to{transform:translateY(0)}40%{transform:translateY(-6px)}}.chatbot-footer{padding:7px 12px;background:var(--background-card, #ffffff);border-top:1px solid var(--border-color-modal, #e0e0e0);flex-shrink:0;display:flex;justify-content:center}.restart-btn{background:none;border:none;font-size:10.5px;color:var(--placeholder-color, #999);cursor:pointer;padding:3px 8px;border-radius:4px;transition:color .15s}.restart-btn:hover{color:var(--text-color, #333)}@media(max-width:768px){.chatbot-wrapper{display:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1140
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: ChatbotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1141
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: ChatbotComponent, isStandalone: true, selector: "app-chatbot", providers: [ChatbotService], viewQueries: [{ propertyName: "messagesEnd", first: true, predicate: ["messagesEnd"], descendants: true, isSignal: true }, { propertyName: "wrapper", first: true, predicate: ["wrapper"], descendants: true, isSignal: true }], ngImport: i0, template: "<div #wrapper class=\"chatbot-wrapper\"\r\n [class.chatbot-left]=\"config.position === 'bottom-left'\"\r\n [class.chatbot-dragging]=\"isDragging()\"\r\n [style.--chatbot-primary]=\"primaryColor\"\r\n [style.left.px]=\"position()?.x\"\r\n [style.top.px]=\"position()?.y\"\r\n [style.right]=\"position() ? 'auto' : null\"\r\n [style.bottom]=\"position() ? 'auto' : null\">\r\n\r\n @if (!service.isOpen()) {\r\n <span class=\"chatbot-beta\">Beta</span>\r\n }\r\n <button class=\"chatbot-fab\"\r\n [class.chatbot-fab--hidden]=\"service.isOpen()\"\r\n (mousedown)=\"startDrag($event)\"\r\n (click)=\"onFabClick()\"\r\n title=\"Abrir asistente\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"26\" height=\"26\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2M7.5 13A2.5 2.5 0 0 0 5 15.5 2.5 2.5 0 0 0 7.5 18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 7.5 13m9 0a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 16.5 13z\" />\r\n </svg>\r\n @if (service.hasActiveConversation()) {\r\n <span class=\"chatbot-badge\" title=\"Conversaci\u00F3n en progreso\"></span>\r\n }\r\n </button>\r\n\r\n @if (service.isOpen()) {\r\n <div class=\"chatbot-window\"\r\n [class.open-above]=\"openDir() === 'above'\"\r\n [class.open-below]=\"openDir() === 'below'\"\r\n [class.open-right]=\"openHDir() === 'right'\"\r\n [class.open-left]=\"openHDir() === 'left'\">\r\n\r\n <div class=\"chatbot-header\" (mousedown)=\"startDrag($event)\">\r\n <div class=\"chatbot-header-info\">\r\n <span class=\"chatbot-avatar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2M7.5 13A2.5 2.5 0 0 0 5 15.5 2.5 2.5 0 0 0 7.5 18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 7.5 13m9 0a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 16.5 13z\" />\r\n </svg>\r\n </span>\r\n <div>\r\n <div class=\"chatbot-name\">{{ config.botName || 'Asistente' }}</div>\r\n <div class=\"chatbot-status\">En l\u00EDnea</div>\r\n </div>\r\n </div>\r\n <div class=\"chatbot-header-actions\">\r\n <button class=\"chatbot-action-btn\" (click)=\"service.minimize()\" title=\"Minimizar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\r\n <path d=\"M2 8a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11A.5.5 0 0 1 2 8z\" />\r\n </svg>\r\n </button>\r\n <button class=\"chatbot-action-btn\" (click)=\"service.close()\" title=\"Cerrar y reiniciar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\r\n <path d=\"M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chatbot-body\">\r\n @for (msg of service.messages(); track $index; let i = $index) {\r\n <div class=\"chat-row\" [class.chat-row-user]=\"msg.from === 'user'\">\r\n @if (msg.from === 'bot') {\r\n <span class=\"bot-icon\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2M7.5 13A2.5 2.5 0 0 0 5 15.5 2.5 2.5 0 0 0 7.5 18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 7.5 13m9 0a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 16.5 13z\" />\r\n </svg>\r\n </span>\r\n }\r\n <div class=\"chat-col\">\r\n <div class=\"message-bubble\" [class.bubble-bot]=\"msg.from === 'bot'\" [class.bubble-user]=\"msg.from === 'user'\">\r\n {{ msg.text }}\r\n </div>\r\n @if (msg.options && msg.options.length > 0) {\r\n <div class=\"options-container\">\r\n @for (opt of msg.options; track $index) {\r\n <button class=\"option-btn\" [disabled]=\"msg.optionsDisabled\" (click)=\"selectOption(opt, i)\">\r\n {{ opt.label }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (service.isTyping()) {\r\n <div class=\"chat-row\">\r\n <span class=\"bot-icon\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2M7.5 13A2.5 2.5 0 0 0 5 15.5 2.5 2.5 0 0 0 7.5 18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 7.5 13m9 0a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 16.5 13z\" />\r\n </svg>\r\n </span>\r\n <div class=\"message-bubble bubble-bot typing-bubble\">\r\n <span class=\"dot\"></span><span class=\"dot\"></span><span class=\"dot\"></span>\r\n </div>\r\n </div>\r\n }\r\n <div #messagesEnd></div>\r\n </div>\r\n\r\n <div class=\"chatbot-footer\">\r\n <button class=\"restart-btn\" (click)=\"service.restart()\">\u21BA Reiniciar conversaci\u00F3n</button>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{--chatbot-primary: #c50048}.chatbot-wrapper{position:fixed;bottom:24px;right:24px;z-index:10000;font-family:Poppins,sans-serif;animation:chatbotFabIn .26s cubic-bezier(.2,0,.2,1) both}.chatbot-wrapper.chatbot-left{right:auto;left:24px}@keyframes chatbotFabIn{0%{opacity:0;transform:translateY(14px) scale(.85)}to{opacity:1;transform:translateY(0) scale(1)}}.chatbot-dragging{-webkit-user-select:none;user-select:none}.chatbot-dragging *{cursor:grabbing!important}.chatbot-beta{position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%);background:#0000008c;color:#ffffffd9;font-size:9px;font-weight:600;letter-spacing:.08em;padding:2px 6px;border-radius:4px;pointer-events:none;text-transform:uppercase;white-space:nowrap}.chatbot-fab{cursor:grab;position:relative;width:54px;height:54px;border-radius:50%;border:none;background:var(--chatbot-primary);color:#fff;cursor:pointer;box-shadow:0 4px 18px #0000004d;display:flex;align-items:center;justify-content:center;transition:transform .2s ease,box-shadow .2s ease}.chatbot-fab:hover{transform:scale(1.08);box-shadow:0 6px 22px #0006}.chatbot-badge{position:absolute;top:4px;right:4px;width:12px;height:12px;border-radius:50%;background:#facc15;border:2px solid #fff;animation:cbPulse 1.8s ease-in-out infinite}@keyframes cbPulse{0%,to{transform:scale(1);opacity:1}50%{transform:scale(1.3);opacity:.75}}.chatbot-fab--hidden{visibility:hidden;pointer-events:none}.chatbot-window{position:absolute;width:320px;max-height:490px;border-radius:16px;overflow:hidden;display:flex;flex-direction:column;box-shadow:0 8px 36px #00000038;background:var(--background-card, #ffffff);animation:cbSlideUp .22s ease}.chatbot-window.open-above{bottom:62px}.chatbot-window.open-below{top:62px}.chatbot-window.open-right{left:0}.chatbot-window.open-left{right:0}@keyframes cbSlideUp{0%{opacity:0;transform:translateY(14px)}to{opacity:1;transform:translateY(0)}}.chatbot-header{padding:12px 14px;background:var(--chatbot-primary);color:#fff;display:flex;align-items:center;justify-content:space-between;flex-shrink:0;cursor:grab}.chatbot-header-info{display:flex;align-items:center;gap:8px}.chatbot-avatar{font-size:20px;line-height:1}.chatbot-name{font-size:13px;font-weight:600}.chatbot-status{font-size:10px;opacity:.82}.chatbot-header-actions{display:flex;align-items:center;gap:2px}.chatbot-action-btn{background:none;border:none;color:#fff;cursor:pointer;padding:4px 6px;border-radius:4px;opacity:.75;display:flex;align-items:center;justify-content:center;transition:opacity .15s,background .15s}.chatbot-action-btn:hover{opacity:1;background:#ffffff2e}.chatbot-body{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px;background:var(--background-color, #f0f0f0)}.chat-row{display:flex;align-items:flex-start;gap:6px}.chat-row.chat-row-user{flex-direction:row-reverse}.bot-icon{font-size:16px;flex-shrink:0;margin-top:4px}.chat-col{display:flex;flex-direction:column;gap:4px;max-width:82%}.message-bubble{padding:8px 11px;border-radius:12px;font-size:11.5px;line-height:1.55;word-break:break-word}.message-bubble.bubble-bot{background:var(--background-card, #ffffff);color:var(--text-color, #1d1d1d);border-bottom-left-radius:4px;box-shadow:0 1px 4px #00000012}.message-bubble.bubble-user{background:var(--chatbot-primary);color:#fff;border-bottom-right-radius:4px;align-self:flex-end}.options-container{display:flex;flex-direction:column;gap:4px}.option-btn{background:var(--background-card, #ffffff);color:var(--chatbot-primary);border:1.5px solid var(--chatbot-primary);border-radius:8px;padding:5px 10px;font-size:11px;font-weight:600;cursor:pointer;text-align:left;transition:background .18s ease,color .18s ease}.option-btn:hover:not(:disabled){background:var(--chatbot-primary);color:#fff}.option-btn:disabled{opacity:.38;cursor:default}.typing-bubble{display:flex;gap:4px;align-items:center;padding:10px 14px!important}.dot{width:7px;height:7px;background:var(--placeholder-color, #aaa);border-radius:50%;animation:cbBounce 1.2s ease-in-out infinite}.dot:nth-child(2){animation-delay:.18s}.dot:nth-child(3){animation-delay:.36s}@keyframes cbBounce{0%,80%,to{transform:translateY(0)}40%{transform:translateY(-6px)}}.chatbot-footer{padding:7px 12px;background:var(--background-card, #ffffff);border-top:1px solid var(--border-color-modal, #e0e0e0);flex-shrink:0;display:flex;justify-content:center}.restart-btn{background:none;border:none;font-size:10.5px;color:var(--placeholder-color, #999);cursor:pointer;padding:3px 8px;border-radius:4px;transition:color .15s}.restart-btn:hover{color:var(--text-color, #333)}@media(max-width:768px){.chatbot-wrapper{display:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1149
1142
  }
1150
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: ChatbotComponent, decorators: [{
1143
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: ChatbotComponent, decorators: [{
1151
1144
  type: Component,
1152
1145
  args: [{ selector: 'app-chatbot', providers: [ChatbotService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #wrapper class=\"chatbot-wrapper\"\r\n [class.chatbot-left]=\"config.position === 'bottom-left'\"\r\n [class.chatbot-dragging]=\"isDragging()\"\r\n [style.--chatbot-primary]=\"primaryColor\"\r\n [style.left.px]=\"position()?.x\"\r\n [style.top.px]=\"position()?.y\"\r\n [style.right]=\"position() ? 'auto' : null\"\r\n [style.bottom]=\"position() ? 'auto' : null\">\r\n\r\n @if (!service.isOpen()) {\r\n <span class=\"chatbot-beta\">Beta</span>\r\n }\r\n <button class=\"chatbot-fab\"\r\n [class.chatbot-fab--hidden]=\"service.isOpen()\"\r\n (mousedown)=\"startDrag($event)\"\r\n (click)=\"onFabClick()\"\r\n title=\"Abrir asistente\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"26\" height=\"26\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2M7.5 13A2.5 2.5 0 0 0 5 15.5 2.5 2.5 0 0 0 7.5 18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 7.5 13m9 0a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 16.5 13z\" />\r\n </svg>\r\n @if (service.hasActiveConversation()) {\r\n <span class=\"chatbot-badge\" title=\"Conversaci\u00F3n en progreso\"></span>\r\n }\r\n </button>\r\n\r\n @if (service.isOpen()) {\r\n <div class=\"chatbot-window\"\r\n [class.open-above]=\"openDir() === 'above'\"\r\n [class.open-below]=\"openDir() === 'below'\"\r\n [class.open-right]=\"openHDir() === 'right'\"\r\n [class.open-left]=\"openHDir() === 'left'\">\r\n\r\n <div class=\"chatbot-header\" (mousedown)=\"startDrag($event)\">\r\n <div class=\"chatbot-header-info\">\r\n <span class=\"chatbot-avatar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2M7.5 13A2.5 2.5 0 0 0 5 15.5 2.5 2.5 0 0 0 7.5 18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 7.5 13m9 0a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 16.5 13z\" />\r\n </svg>\r\n </span>\r\n <div>\r\n <div class=\"chatbot-name\">{{ config.botName || 'Asistente' }}</div>\r\n <div class=\"chatbot-status\">En l\u00EDnea</div>\r\n </div>\r\n </div>\r\n <div class=\"chatbot-header-actions\">\r\n <button class=\"chatbot-action-btn\" (click)=\"service.minimize()\" title=\"Minimizar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\r\n <path d=\"M2 8a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11A.5.5 0 0 1 2 8z\" />\r\n </svg>\r\n </button>\r\n <button class=\"chatbot-action-btn\" (click)=\"service.close()\" title=\"Cerrar y reiniciar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"13\" height=\"13\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\r\n <path d=\"M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chatbot-body\">\r\n @for (msg of service.messages(); track $index; let i = $index) {\r\n <div class=\"chat-row\" [class.chat-row-user]=\"msg.from === 'user'\">\r\n @if (msg.from === 'bot') {\r\n <span class=\"bot-icon\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2M7.5 13A2.5 2.5 0 0 0 5 15.5 2.5 2.5 0 0 0 7.5 18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 7.5 13m9 0a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 16.5 13z\" />\r\n </svg>\r\n </span>\r\n }\r\n <div class=\"chat-col\">\r\n <div class=\"message-bubble\" [class.bubble-bot]=\"msg.from === 'bot'\" [class.bubble-user]=\"msg.from === 'user'\">\r\n {{ msg.text }}\r\n </div>\r\n @if (msg.options && msg.options.length > 0) {\r\n <div class=\"options-container\">\r\n @for (opt of msg.options; track $index) {\r\n <button class=\"option-btn\" [disabled]=\"msg.optionsDisabled\" (click)=\"selectOption(opt, i)\">\r\n {{ opt.label }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (service.isTyping()) {\r\n <div class=\"chat-row\">\r\n <span class=\"bot-icon\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2M7.5 13A2.5 2.5 0 0 0 5 15.5 2.5 2.5 0 0 0 7.5 18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 7.5 13m9 0a2.5 2.5 0 0 0-2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 16.5 13z\" />\r\n </svg>\r\n </span>\r\n <div class=\"message-bubble bubble-bot typing-bubble\">\r\n <span class=\"dot\"></span><span class=\"dot\"></span><span class=\"dot\"></span>\r\n </div>\r\n </div>\r\n }\r\n <div #messagesEnd></div>\r\n </div>\r\n\r\n <div class=\"chatbot-footer\">\r\n <button class=\"restart-btn\" (click)=\"service.restart()\">\u21BA Reiniciar conversaci\u00F3n</button>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{--chatbot-primary: #c50048}.chatbot-wrapper{position:fixed;bottom:24px;right:24px;z-index:10000;font-family:Poppins,sans-serif;animation:chatbotFabIn .26s cubic-bezier(.2,0,.2,1) both}.chatbot-wrapper.chatbot-left{right:auto;left:24px}@keyframes chatbotFabIn{0%{opacity:0;transform:translateY(14px) scale(.85)}to{opacity:1;transform:translateY(0) scale(1)}}.chatbot-dragging{-webkit-user-select:none;user-select:none}.chatbot-dragging *{cursor:grabbing!important}.chatbot-beta{position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%);background:#0000008c;color:#ffffffd9;font-size:9px;font-weight:600;letter-spacing:.08em;padding:2px 6px;border-radius:4px;pointer-events:none;text-transform:uppercase;white-space:nowrap}.chatbot-fab{cursor:grab;position:relative;width:54px;height:54px;border-radius:50%;border:none;background:var(--chatbot-primary);color:#fff;cursor:pointer;box-shadow:0 4px 18px #0000004d;display:flex;align-items:center;justify-content:center;transition:transform .2s ease,box-shadow .2s ease}.chatbot-fab:hover{transform:scale(1.08);box-shadow:0 6px 22px #0006}.chatbot-badge{position:absolute;top:4px;right:4px;width:12px;height:12px;border-radius:50%;background:#facc15;border:2px solid #fff;animation:cbPulse 1.8s ease-in-out infinite}@keyframes cbPulse{0%,to{transform:scale(1);opacity:1}50%{transform:scale(1.3);opacity:.75}}.chatbot-fab--hidden{visibility:hidden;pointer-events:none}.chatbot-window{position:absolute;width:320px;max-height:490px;border-radius:16px;overflow:hidden;display:flex;flex-direction:column;box-shadow:0 8px 36px #00000038;background:var(--background-card, #ffffff);animation:cbSlideUp .22s ease}.chatbot-window.open-above{bottom:62px}.chatbot-window.open-below{top:62px}.chatbot-window.open-right{left:0}.chatbot-window.open-left{right:0}@keyframes cbSlideUp{0%{opacity:0;transform:translateY(14px)}to{opacity:1;transform:translateY(0)}}.chatbot-header{padding:12px 14px;background:var(--chatbot-primary);color:#fff;display:flex;align-items:center;justify-content:space-between;flex-shrink:0;cursor:grab}.chatbot-header-info{display:flex;align-items:center;gap:8px}.chatbot-avatar{font-size:20px;line-height:1}.chatbot-name{font-size:13px;font-weight:600}.chatbot-status{font-size:10px;opacity:.82}.chatbot-header-actions{display:flex;align-items:center;gap:2px}.chatbot-action-btn{background:none;border:none;color:#fff;cursor:pointer;padding:4px 6px;border-radius:4px;opacity:.75;display:flex;align-items:center;justify-content:center;transition:opacity .15s,background .15s}.chatbot-action-btn:hover{opacity:1;background:#ffffff2e}.chatbot-body{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px;background:var(--background-color, #f0f0f0)}.chat-row{display:flex;align-items:flex-start;gap:6px}.chat-row.chat-row-user{flex-direction:row-reverse}.bot-icon{font-size:16px;flex-shrink:0;margin-top:4px}.chat-col{display:flex;flex-direction:column;gap:4px;max-width:82%}.message-bubble{padding:8px 11px;border-radius:12px;font-size:11.5px;line-height:1.55;word-break:break-word}.message-bubble.bubble-bot{background:var(--background-card, #ffffff);color:var(--text-color, #1d1d1d);border-bottom-left-radius:4px;box-shadow:0 1px 4px #00000012}.message-bubble.bubble-user{background:var(--chatbot-primary);color:#fff;border-bottom-right-radius:4px;align-self:flex-end}.options-container{display:flex;flex-direction:column;gap:4px}.option-btn{background:var(--background-card, #ffffff);color:var(--chatbot-primary);border:1.5px solid var(--chatbot-primary);border-radius:8px;padding:5px 10px;font-size:11px;font-weight:600;cursor:pointer;text-align:left;transition:background .18s ease,color .18s ease}.option-btn:hover:not(:disabled){background:var(--chatbot-primary);color:#fff}.option-btn:disabled{opacity:.38;cursor:default}.typing-bubble{display:flex;gap:4px;align-items:center;padding:10px 14px!important}.dot{width:7px;height:7px;background:var(--placeholder-color, #aaa);border-radius:50%;animation:cbBounce 1.2s ease-in-out infinite}.dot:nth-child(2){animation-delay:.18s}.dot:nth-child(3){animation-delay:.36s}@keyframes cbBounce{0%,80%,to{transform:translateY(0)}40%{transform:translateY(-6px)}}.chatbot-footer{padding:7px 12px;background:var(--background-card, #ffffff);border-top:1px solid var(--border-color-modal, #e0e0e0);flex-shrink:0;display:flex;justify-content:center}.restart-btn{background:none;border:none;font-size:10.5px;color:var(--placeholder-color, #999);cursor:pointer;padding:3px 8px;border-radius:4px;transition:color .15s}.restart-btn:hover{color:var(--text-color, #333)}@media(max-width:768px){.chatbot-wrapper{display:none}}\n"] }]
1153
- }], ctorParameters: () => [] });
1146
+ }], ctorParameters: () => [], propDecorators: { messagesEnd: [{ type: i0.ViewChild, args: ['messagesEnd', { isSignal: true }] }], wrapper: [{ type: i0.ViewChild, args: ['wrapper', { isSignal: true }] }] } });
1154
1147
 
1155
1148
  class NotFoundComponent {
1156
1149
  location = inject(Location);
1157
1150
  onBack() {
1158
1151
  this.location.back();
1159
1152
  }
1160
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: NotFoundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1161
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: NotFoundComponent, isStandalone: true, selector: "app-not-found", ngImport: i0, template: "<div class=\"nf-page d-flex align-items-center justify-content-center vh-100\">\r\n\r\n <!-- Blobs decorativos de fondo -->\r\n <div class=\"nf-blob nf-blob-1\"></div>\r\n <div class=\"nf-blob nf-blob-2\"></div>\r\n\r\n <div class=\"nf-card bg-white shadow-s text-center px-4 px-md-5 py-4 mx-3\">\r\n\r\n <!-- Ilustraci\u00F3n: ventana con 404 y lupa buscando -->\r\n <svg class=\"nf-illustration\" viewBox=\"0 0 520 340\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"P\u00E1gina no encontrada\">\r\n <defs>\r\n <linearGradient id=\"nfGrad\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\r\n <stop offset=\"0%\" style=\"stop-color: var(--sidebar-accent)\" />\r\n <stop offset=\"100%\" style=\"stop-color: var(--sidebar-accent); stop-opacity: 0.55\" />\r\n </linearGradient>\r\n </defs>\r\n\r\n <!-- \u00D3rbita punteada de fondo -->\r\n <circle class=\"nf-orbit\" cx=\"260\" cy=\"170\" r=\"150\"\r\n stroke=\"var(--font-border-input)\" stroke-width=\"1.5\"\r\n stroke-dasharray=\"6 10\" opacity=\"0.7\" />\r\n\r\n <!-- Decoraciones flotantes -->\r\n <g class=\"nf-spark nf-spark-1\" stroke=\"var(--sidebar-accent)\" stroke-width=\"3\" stroke-linecap=\"round\">\r\n <path d=\"M92 78 v20 M82 88 h20\" />\r\n </g>\r\n <g class=\"nf-spark nf-spark-2\" stroke=\"var(--placeholder-color)\" stroke-width=\"3\" stroke-linecap=\"round\">\r\n <path d=\"M448 220 v16 M440 228 h16\" />\r\n </g>\r\n <circle class=\"nf-spark nf-spark-3\" cx=\"430\" cy=\"70\" r=\"6\" fill=\"var(--sidebar-accent)\" opacity=\"0.7\" />\r\n <circle class=\"nf-spark nf-spark-1\" cx=\"70\" cy=\"230\" r=\"5\" fill=\"var(--placeholder-color)\" opacity=\"0.7\" />\r\n <path class=\"nf-spark nf-spark-2\" d=\"M120 300 q8 -10 16 0 q8 10 16 0\"\r\n stroke=\"var(--font-border-input)\" stroke-width=\"3\" stroke-linecap=\"round\" fill=\"none\" />\r\n\r\n <!-- Ventana de navegador -->\r\n <g class=\"nf-window\">\r\n <rect x=\"120\" y=\"60\" width=\"280\" height=\"200\" rx=\"16\"\r\n fill=\"var(--background-input)\" stroke=\"var(--font-border-input)\" stroke-width=\"2\" />\r\n <!-- Barra superior -->\r\n <line x1=\"120\" y1=\"98\" x2=\"400\" y2=\"98\" stroke=\"var(--font-border-input)\" stroke-width=\"2\" />\r\n <circle cx=\"144\" cy=\"79\" r=\"5\" fill=\"var(--sidebar-accent)\" />\r\n <circle cx=\"162\" cy=\"79\" r=\"5\" fill=\"var(--placeholder-color)\" opacity=\"0.8\" />\r\n <circle cx=\"180\" cy=\"79\" r=\"5\" fill=\"var(--font-border-input)\" />\r\n <!-- Barra de direcci\u00F3n -->\r\n <rect x=\"200\" y=\"71\" width=\"184\" height=\"16\" rx=\"8\" fill=\"var(--font-border-input)\" opacity=\"0.5\" />\r\n\r\n <!-- 404 dentro de la ventana -->\r\n <text x=\"260\" y=\"188\" text-anchor=\"middle\" class=\"nf-404-text\" fill=\"url(#nfGrad)\">404</text>\r\n\r\n <!-- L\u00EDneas de contenido (skeleton) -->\r\n <rect x=\"180\" y=\"212\" width=\"160\" height=\"9\" rx=\"4.5\" fill=\"var(--font-border-input)\" opacity=\"0.7\" />\r\n <rect x=\"205\" y=\"230\" width=\"110\" height=\"9\" rx=\"4.5\" fill=\"var(--font-border-input)\" opacity=\"0.45\" />\r\n </g>\r\n\r\n <!-- Lupa buscando -->\r\n <g class=\"nf-lens\">\r\n <circle cx=\"352\" cy=\"238\" r=\"46\" fill=\"var(--background-card)\" fill-opacity=\"0.55\"\r\n stroke=\"url(#nfGrad)\" stroke-width=\"8\" />\r\n <line x1=\"386\" y1=\"272\" x2=\"424\" y2=\"310\" stroke=\"url(#nfGrad)\" stroke-width=\"14\" stroke-linecap=\"round\" />\r\n <!-- Signo de interrogaci\u00F3n dentro de la lupa -->\r\n <path d=\"M340 224 q0 -14 13 -14 q13 0 13 12 q0 9 -10 13 q-3 1.5 -3 7\"\r\n stroke=\"var(--text-color)\" stroke-width=\"5\" stroke-linecap=\"round\" fill=\"none\" />\r\n <circle cx=\"353\" cy=\"256\" r=\"3.5\" fill=\"var(--text-color)\" />\r\n </g>\r\n </svg>\r\n\r\n <!-- Badge -->\r\n <span class=\"nf-badge fw-semibold\">ERROR 404</span>\r\n\r\n <h2 class=\"fw-semibold text-input mt-3\">P\u00E1gina no encontrada</h2>\r\n\r\n <p class=\"nf-desc fs-6 mt-2 mb-4 mx-auto\">\r\n Lo sentimos, la p\u00E1gina que buscas no existe o fue movida.\r\n Verifica la direcci\u00F3n o regresa al inicio.\r\n </p>\r\n\r\n <!-- Acciones -->\r\n <div class=\"d-flex gap-3 justify-content-center flex-wrap\">\r\n <button type=\"button\" (click)=\"onBack()\" class=\"btn nf-btn-primary px-4 py-2 shadow\">\r\n <i class=\"fa-solid fa-arrow-left me-2\"></i>Volver\r\n </button>\r\n <a routerLink=\"/\" class=\"btn nf-btn-ghost text-dark px-4 py-2\">\r\n <i class=\"fa-solid fa-house me-2\"></i>Ir al inicio\r\n </a>\r\n </div>\r\n\r\n </div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.nf-page{position:relative;overflow:hidden;background:var(--background-color)}.nf-blob{position:absolute;border-radius:50%;filter:blur(90px);opacity:.22;pointer-events:none;animation:nf-drift 12s ease-in-out infinite alternate}.nf-blob-1{width:420px;height:420px;top:-120px;left:-100px;background:var(--sidebar-accent)}.nf-blob-2{width:360px;height:360px;bottom:-100px;right:-80px;background:color-mix(in srgb,var(--sidebar-accent) 60%,var(--text-color));animation-delay:-6s}@keyframes nf-drift{0%{transform:translate(0) scale(1)}to{transform:translate(40px,30px) scale(1.12)}}.nf-card{position:relative;z-index:1;max-width:560px;width:100%;border-radius:1.5rem;border:1px solid var(--font-border-input);backdrop-filter:blur(var(--blur-modal))}.nf-illustration{width:100%;max-width:380px;height:auto;margin-bottom:.5rem}.nf-404-text{font-size:68px;font-weight:800;letter-spacing:4px}.nf-window{animation:nf-float 5s ease-in-out infinite}.nf-lens{transform-origin:370px 260px;animation:nf-search 4s ease-in-out infinite}@keyframes nf-float{0%,to{transform:translateY(0)}50%{transform:translateY(-8px)}}@keyframes nf-search{0%,to{transform:translate(0) rotate(0)}35%{transform:translate(-10px,-12px) rotate(-4deg)}70%{transform:translate(6px,-4px) rotate(3deg)}}.nf-orbit{transform-origin:260px 170px;animation:nf-spin 40s linear infinite}@keyframes nf-spin{to{transform:rotate(360deg)}}.nf-spark{animation:nf-twinkle 3s ease-in-out infinite}.nf-spark-2{animation-delay:-1s}.nf-spark-3{animation-delay:-2s}@keyframes nf-twinkle{0%,to{opacity:.9}50%{opacity:.25}}.nf-badge{display:inline-block;font-size:.75rem;letter-spacing:.15em;padding:.35rem .9rem;border-radius:999px;color:var(--sidebar-accent);background:color-mix(in srgb,var(--sidebar-accent) 12%,transparent);border:1px solid color-mix(in srgb,var(--sidebar-accent) 35%,transparent)}.nf-desc{color:var(--placeholder-color);max-width:380px}.nf-btn-primary{color:#fff;border:none;border-radius:.75rem;background:linear-gradient(135deg,var(--sidebar-accent),color-mix(in srgb,var(--sidebar-accent) 70%,#000));transition:transform .25s ease,box-shadow .25s ease}.nf-btn-primary:hover{color:#fff;transform:translateY(-2px);box-shadow:0 8px 20px color-mix(in srgb,var(--sidebar-accent) 40%,transparent)}.nf-btn-ghost{border-radius:.75rem;border:1px solid var(--font-border-input);background:transparent;transition:transform .25s ease,background .25s ease}.nf-btn-ghost:hover{transform:translateY(-2px);background:var(--background-btn-light);border-color:var(--font-border-input)}@media(prefers-reduced-motion:reduce){.nf-blob,.nf-window,.nf-lens,.nf-orbit,.nf-spark{animation:none}}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
1153
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: NotFoundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1154
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.24", type: NotFoundComponent, isStandalone: true, selector: "app-not-found", ngImport: i0, template: "<div class=\"nf-page d-flex align-items-center justify-content-center vh-100\">\r\n\r\n <!-- Blobs decorativos de fondo -->\r\n <div class=\"nf-blob nf-blob-1\"></div>\r\n <div class=\"nf-blob nf-blob-2\"></div>\r\n\r\n <div class=\"nf-card bg-white shadow-s text-center px-4 px-md-5 py-4 mx-3\">\r\n\r\n <!-- Ilustraci\u00F3n: ventana con 404 y lupa buscando -->\r\n <svg class=\"nf-illustration\" viewBox=\"0 0 520 340\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"P\u00E1gina no encontrada\">\r\n <defs>\r\n <linearGradient id=\"nfGrad\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\r\n <stop offset=\"0%\" style=\"stop-color: var(--sidebar-accent)\" />\r\n <stop offset=\"100%\" style=\"stop-color: var(--sidebar-accent); stop-opacity: 0.55\" />\r\n </linearGradient>\r\n </defs>\r\n\r\n <!-- \u00D3rbita punteada de fondo -->\r\n <circle class=\"nf-orbit\" cx=\"260\" cy=\"170\" r=\"150\"\r\n stroke=\"var(--font-border-input)\" stroke-width=\"1.5\"\r\n stroke-dasharray=\"6 10\" opacity=\"0.7\" />\r\n\r\n <!-- Decoraciones flotantes -->\r\n <g class=\"nf-spark nf-spark-1\" stroke=\"var(--sidebar-accent)\" stroke-width=\"3\" stroke-linecap=\"round\">\r\n <path d=\"M92 78 v20 M82 88 h20\" />\r\n </g>\r\n <g class=\"nf-spark nf-spark-2\" stroke=\"var(--placeholder-color)\" stroke-width=\"3\" stroke-linecap=\"round\">\r\n <path d=\"M448 220 v16 M440 228 h16\" />\r\n </g>\r\n <circle class=\"nf-spark nf-spark-3\" cx=\"430\" cy=\"70\" r=\"6\" fill=\"var(--sidebar-accent)\" opacity=\"0.7\" />\r\n <circle class=\"nf-spark nf-spark-1\" cx=\"70\" cy=\"230\" r=\"5\" fill=\"var(--placeholder-color)\" opacity=\"0.7\" />\r\n <path class=\"nf-spark nf-spark-2\" d=\"M120 300 q8 -10 16 0 q8 10 16 0\"\r\n stroke=\"var(--font-border-input)\" stroke-width=\"3\" stroke-linecap=\"round\" fill=\"none\" />\r\n\r\n <!-- Ventana de navegador -->\r\n <g class=\"nf-window\">\r\n <rect x=\"120\" y=\"60\" width=\"280\" height=\"200\" rx=\"16\"\r\n fill=\"var(--background-input)\" stroke=\"var(--font-border-input)\" stroke-width=\"2\" />\r\n <!-- Barra superior -->\r\n <line x1=\"120\" y1=\"98\" x2=\"400\" y2=\"98\" stroke=\"var(--font-border-input)\" stroke-width=\"2\" />\r\n <circle cx=\"144\" cy=\"79\" r=\"5\" fill=\"var(--sidebar-accent)\" />\r\n <circle cx=\"162\" cy=\"79\" r=\"5\" fill=\"var(--placeholder-color)\" opacity=\"0.8\" />\r\n <circle cx=\"180\" cy=\"79\" r=\"5\" fill=\"var(--font-border-input)\" />\r\n <!-- Barra de direcci\u00F3n -->\r\n <rect x=\"200\" y=\"71\" width=\"184\" height=\"16\" rx=\"8\" fill=\"var(--font-border-input)\" opacity=\"0.5\" />\r\n\r\n <!-- 404 dentro de la ventana -->\r\n <text x=\"260\" y=\"188\" text-anchor=\"middle\" class=\"nf-404-text\" fill=\"url(#nfGrad)\">404</text>\r\n\r\n <!-- L\u00EDneas de contenido (skeleton) -->\r\n <rect x=\"180\" y=\"212\" width=\"160\" height=\"9\" rx=\"4.5\" fill=\"var(--font-border-input)\" opacity=\"0.7\" />\r\n <rect x=\"205\" y=\"230\" width=\"110\" height=\"9\" rx=\"4.5\" fill=\"var(--font-border-input)\" opacity=\"0.45\" />\r\n </g>\r\n\r\n <!-- Lupa buscando -->\r\n <g class=\"nf-lens\">\r\n <circle cx=\"352\" cy=\"238\" r=\"46\" fill=\"var(--background-card)\" fill-opacity=\"0.55\"\r\n stroke=\"url(#nfGrad)\" stroke-width=\"8\" />\r\n <line x1=\"386\" y1=\"272\" x2=\"424\" y2=\"310\" stroke=\"url(#nfGrad)\" stroke-width=\"14\" stroke-linecap=\"round\" />\r\n <!-- Signo de interrogaci\u00F3n dentro de la lupa -->\r\n <path d=\"M340 224 q0 -14 13 -14 q13 0 13 12 q0 9 -10 13 q-3 1.5 -3 7\"\r\n stroke=\"var(--text-color)\" stroke-width=\"5\" stroke-linecap=\"round\" fill=\"none\" />\r\n <circle cx=\"353\" cy=\"256\" r=\"3.5\" fill=\"var(--text-color)\" />\r\n </g>\r\n </svg>\r\n\r\n <!-- Badge -->\r\n <span class=\"nf-badge fw-semibold\">ERROR 404</span>\r\n\r\n <h2 class=\"fw-semibold text-input mt-3\">P\u00E1gina no encontrada</h2>\r\n\r\n <p class=\"nf-desc fs-6 mt-2 mb-4 mx-auto\">\r\n Lo sentimos, la p\u00E1gina que buscas no existe o fue movida.\r\n Verifica la direcci\u00F3n o regresa al inicio.\r\n </p>\r\n\r\n <!-- Acciones -->\r\n <div class=\"d-flex gap-3 justify-content-center flex-wrap\">\r\n <button type=\"button\" (click)=\"onBack()\" class=\"btn nf-btn-primary px-4 py-2 shadow\">\r\n <i class=\"fa-solid fa-arrow-left me-2\"></i>Volver\r\n </button>\r\n <a routerLink=\"/\" class=\"btn nf-btn-ghost text-dark px-4 py-2\">\r\n <i class=\"fa-solid fa-house me-2\"></i>Ir al inicio\r\n </a>\r\n </div>\r\n\r\n </div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.nf-page{position:relative;overflow:hidden;background:var(--background-color)}.nf-blob{position:absolute;border-radius:50%;filter:blur(90px);opacity:.22;pointer-events:none;animation:nf-drift 12s ease-in-out infinite alternate}.nf-blob-1{width:420px;height:420px;top:-120px;left:-100px;background:var(--sidebar-accent)}.nf-blob-2{width:360px;height:360px;bottom:-100px;right:-80px;background:color-mix(in srgb,var(--sidebar-accent) 60%,var(--text-color));animation-delay:-6s}@keyframes nf-drift{0%{transform:translate(0) scale(1)}to{transform:translate(40px,30px) scale(1.12)}}.nf-card{position:relative;z-index:1;max-width:560px;width:100%;border-radius:1.5rem;border:1px solid var(--font-border-input);-webkit-backdrop-filter:blur(var(--blur-modal));backdrop-filter:blur(var(--blur-modal))}.nf-illustration{width:100%;max-width:380px;height:auto;margin-bottom:.5rem}.nf-404-text{font-size:68px;font-weight:800;letter-spacing:4px}.nf-window{animation:nf-float 5s ease-in-out infinite}.nf-lens{transform-origin:370px 260px;animation:nf-search 4s ease-in-out infinite}@keyframes nf-float{0%,to{transform:translateY(0)}50%{transform:translateY(-8px)}}@keyframes nf-search{0%,to{transform:translate(0) rotate(0)}35%{transform:translate(-10px,-12px) rotate(-4deg)}70%{transform:translate(6px,-4px) rotate(3deg)}}.nf-orbit{transform-origin:260px 170px;animation:nf-spin 40s linear infinite}@keyframes nf-spin{to{transform:rotate(360deg)}}.nf-spark{animation:nf-twinkle 3s ease-in-out infinite}.nf-spark-2{animation-delay:-1s}.nf-spark-3{animation-delay:-2s}@keyframes nf-twinkle{0%,to{opacity:.9}50%{opacity:.25}}.nf-badge{display:inline-block;font-size:.75rem;letter-spacing:.15em;padding:.35rem .9rem;border-radius:999px;color:var(--sidebar-accent);background:color-mix(in srgb,var(--sidebar-accent) 12%,transparent);border:1px solid color-mix(in srgb,var(--sidebar-accent) 35%,transparent)}.nf-desc{color:var(--placeholder-color);max-width:380px}.nf-btn-primary{color:#fff;border:none;border-radius:.75rem;background:linear-gradient(135deg,var(--sidebar-accent),color-mix(in srgb,var(--sidebar-accent) 70%,#000));transition:transform .25s ease,box-shadow .25s ease}.nf-btn-primary:hover{color:#fff;transform:translateY(-2px);box-shadow:0 8px 20px color-mix(in srgb,var(--sidebar-accent) 40%,transparent)}.nf-btn-ghost{border-radius:.75rem;border:1px solid var(--font-border-input);background:transparent;transition:transform .25s ease,background .25s ease}.nf-btn-ghost:hover{transform:translateY(-2px);background:var(--background-btn-light);border-color:var(--font-border-input)}@media(prefers-reduced-motion:reduce){.nf-blob,.nf-window,.nf-lens,.nf-orbit,.nf-spark{animation:none}}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
1162
1155
  }
1163
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: NotFoundComponent, decorators: [{
1156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: NotFoundComponent, decorators: [{
1164
1157
  type: Component,
1165
- args: [{ selector: 'app-not-found', imports: [RouterLink], template: "<div class=\"nf-page d-flex align-items-center justify-content-center vh-100\">\r\n\r\n <!-- Blobs decorativos de fondo -->\r\n <div class=\"nf-blob nf-blob-1\"></div>\r\n <div class=\"nf-blob nf-blob-2\"></div>\r\n\r\n <div class=\"nf-card bg-white shadow-s text-center px-4 px-md-5 py-4 mx-3\">\r\n\r\n <!-- Ilustraci\u00F3n: ventana con 404 y lupa buscando -->\r\n <svg class=\"nf-illustration\" viewBox=\"0 0 520 340\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"P\u00E1gina no encontrada\">\r\n <defs>\r\n <linearGradient id=\"nfGrad\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\r\n <stop offset=\"0%\" style=\"stop-color: var(--sidebar-accent)\" />\r\n <stop offset=\"100%\" style=\"stop-color: var(--sidebar-accent); stop-opacity: 0.55\" />\r\n </linearGradient>\r\n </defs>\r\n\r\n <!-- \u00D3rbita punteada de fondo -->\r\n <circle class=\"nf-orbit\" cx=\"260\" cy=\"170\" r=\"150\"\r\n stroke=\"var(--font-border-input)\" stroke-width=\"1.5\"\r\n stroke-dasharray=\"6 10\" opacity=\"0.7\" />\r\n\r\n <!-- Decoraciones flotantes -->\r\n <g class=\"nf-spark nf-spark-1\" stroke=\"var(--sidebar-accent)\" stroke-width=\"3\" stroke-linecap=\"round\">\r\n <path d=\"M92 78 v20 M82 88 h20\" />\r\n </g>\r\n <g class=\"nf-spark nf-spark-2\" stroke=\"var(--placeholder-color)\" stroke-width=\"3\" stroke-linecap=\"round\">\r\n <path d=\"M448 220 v16 M440 228 h16\" />\r\n </g>\r\n <circle class=\"nf-spark nf-spark-3\" cx=\"430\" cy=\"70\" r=\"6\" fill=\"var(--sidebar-accent)\" opacity=\"0.7\" />\r\n <circle class=\"nf-spark nf-spark-1\" cx=\"70\" cy=\"230\" r=\"5\" fill=\"var(--placeholder-color)\" opacity=\"0.7\" />\r\n <path class=\"nf-spark nf-spark-2\" d=\"M120 300 q8 -10 16 0 q8 10 16 0\"\r\n stroke=\"var(--font-border-input)\" stroke-width=\"3\" stroke-linecap=\"round\" fill=\"none\" />\r\n\r\n <!-- Ventana de navegador -->\r\n <g class=\"nf-window\">\r\n <rect x=\"120\" y=\"60\" width=\"280\" height=\"200\" rx=\"16\"\r\n fill=\"var(--background-input)\" stroke=\"var(--font-border-input)\" stroke-width=\"2\" />\r\n <!-- Barra superior -->\r\n <line x1=\"120\" y1=\"98\" x2=\"400\" y2=\"98\" stroke=\"var(--font-border-input)\" stroke-width=\"2\" />\r\n <circle cx=\"144\" cy=\"79\" r=\"5\" fill=\"var(--sidebar-accent)\" />\r\n <circle cx=\"162\" cy=\"79\" r=\"5\" fill=\"var(--placeholder-color)\" opacity=\"0.8\" />\r\n <circle cx=\"180\" cy=\"79\" r=\"5\" fill=\"var(--font-border-input)\" />\r\n <!-- Barra de direcci\u00F3n -->\r\n <rect x=\"200\" y=\"71\" width=\"184\" height=\"16\" rx=\"8\" fill=\"var(--font-border-input)\" opacity=\"0.5\" />\r\n\r\n <!-- 404 dentro de la ventana -->\r\n <text x=\"260\" y=\"188\" text-anchor=\"middle\" class=\"nf-404-text\" fill=\"url(#nfGrad)\">404</text>\r\n\r\n <!-- L\u00EDneas de contenido (skeleton) -->\r\n <rect x=\"180\" y=\"212\" width=\"160\" height=\"9\" rx=\"4.5\" fill=\"var(--font-border-input)\" opacity=\"0.7\" />\r\n <rect x=\"205\" y=\"230\" width=\"110\" height=\"9\" rx=\"4.5\" fill=\"var(--font-border-input)\" opacity=\"0.45\" />\r\n </g>\r\n\r\n <!-- Lupa buscando -->\r\n <g class=\"nf-lens\">\r\n <circle cx=\"352\" cy=\"238\" r=\"46\" fill=\"var(--background-card)\" fill-opacity=\"0.55\"\r\n stroke=\"url(#nfGrad)\" stroke-width=\"8\" />\r\n <line x1=\"386\" y1=\"272\" x2=\"424\" y2=\"310\" stroke=\"url(#nfGrad)\" stroke-width=\"14\" stroke-linecap=\"round\" />\r\n <!-- Signo de interrogaci\u00F3n dentro de la lupa -->\r\n <path d=\"M340 224 q0 -14 13 -14 q13 0 13 12 q0 9 -10 13 q-3 1.5 -3 7\"\r\n stroke=\"var(--text-color)\" stroke-width=\"5\" stroke-linecap=\"round\" fill=\"none\" />\r\n <circle cx=\"353\" cy=\"256\" r=\"3.5\" fill=\"var(--text-color)\" />\r\n </g>\r\n </svg>\r\n\r\n <!-- Badge -->\r\n <span class=\"nf-badge fw-semibold\">ERROR 404</span>\r\n\r\n <h2 class=\"fw-semibold text-input mt-3\">P\u00E1gina no encontrada</h2>\r\n\r\n <p class=\"nf-desc fs-6 mt-2 mb-4 mx-auto\">\r\n Lo sentimos, la p\u00E1gina que buscas no existe o fue movida.\r\n Verifica la direcci\u00F3n o regresa al inicio.\r\n </p>\r\n\r\n <!-- Acciones -->\r\n <div class=\"d-flex gap-3 justify-content-center flex-wrap\">\r\n <button type=\"button\" (click)=\"onBack()\" class=\"btn nf-btn-primary px-4 py-2 shadow\">\r\n <i class=\"fa-solid fa-arrow-left me-2\"></i>Volver\r\n </button>\r\n <a routerLink=\"/\" class=\"btn nf-btn-ghost text-dark px-4 py-2\">\r\n <i class=\"fa-solid fa-house me-2\"></i>Ir al inicio\r\n </a>\r\n </div>\r\n\r\n </div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.nf-page{position:relative;overflow:hidden;background:var(--background-color)}.nf-blob{position:absolute;border-radius:50%;filter:blur(90px);opacity:.22;pointer-events:none;animation:nf-drift 12s ease-in-out infinite alternate}.nf-blob-1{width:420px;height:420px;top:-120px;left:-100px;background:var(--sidebar-accent)}.nf-blob-2{width:360px;height:360px;bottom:-100px;right:-80px;background:color-mix(in srgb,var(--sidebar-accent) 60%,var(--text-color));animation-delay:-6s}@keyframes nf-drift{0%{transform:translate(0) scale(1)}to{transform:translate(40px,30px) scale(1.12)}}.nf-card{position:relative;z-index:1;max-width:560px;width:100%;border-radius:1.5rem;border:1px solid var(--font-border-input);backdrop-filter:blur(var(--blur-modal))}.nf-illustration{width:100%;max-width:380px;height:auto;margin-bottom:.5rem}.nf-404-text{font-size:68px;font-weight:800;letter-spacing:4px}.nf-window{animation:nf-float 5s ease-in-out infinite}.nf-lens{transform-origin:370px 260px;animation:nf-search 4s ease-in-out infinite}@keyframes nf-float{0%,to{transform:translateY(0)}50%{transform:translateY(-8px)}}@keyframes nf-search{0%,to{transform:translate(0) rotate(0)}35%{transform:translate(-10px,-12px) rotate(-4deg)}70%{transform:translate(6px,-4px) rotate(3deg)}}.nf-orbit{transform-origin:260px 170px;animation:nf-spin 40s linear infinite}@keyframes nf-spin{to{transform:rotate(360deg)}}.nf-spark{animation:nf-twinkle 3s ease-in-out infinite}.nf-spark-2{animation-delay:-1s}.nf-spark-3{animation-delay:-2s}@keyframes nf-twinkle{0%,to{opacity:.9}50%{opacity:.25}}.nf-badge{display:inline-block;font-size:.75rem;letter-spacing:.15em;padding:.35rem .9rem;border-radius:999px;color:var(--sidebar-accent);background:color-mix(in srgb,var(--sidebar-accent) 12%,transparent);border:1px solid color-mix(in srgb,var(--sidebar-accent) 35%,transparent)}.nf-desc{color:var(--placeholder-color);max-width:380px}.nf-btn-primary{color:#fff;border:none;border-radius:.75rem;background:linear-gradient(135deg,var(--sidebar-accent),color-mix(in srgb,var(--sidebar-accent) 70%,#000));transition:transform .25s ease,box-shadow .25s ease}.nf-btn-primary:hover{color:#fff;transform:translateY(-2px);box-shadow:0 8px 20px color-mix(in srgb,var(--sidebar-accent) 40%,transparent)}.nf-btn-ghost{border-radius:.75rem;border:1px solid var(--font-border-input);background:transparent;transition:transform .25s ease,background .25s ease}.nf-btn-ghost:hover{transform:translateY(-2px);background:var(--background-btn-light);border-color:var(--font-border-input)}@media(prefers-reduced-motion:reduce){.nf-blob,.nf-window,.nf-lens,.nf-orbit,.nf-spark{animation:none}}\n"] }]
1158
+ args: [{ selector: 'app-not-found', imports: [RouterLink], template: "<div class=\"nf-page d-flex align-items-center justify-content-center vh-100\">\r\n\r\n <!-- Blobs decorativos de fondo -->\r\n <div class=\"nf-blob nf-blob-1\"></div>\r\n <div class=\"nf-blob nf-blob-2\"></div>\r\n\r\n <div class=\"nf-card bg-white shadow-s text-center px-4 px-md-5 py-4 mx-3\">\r\n\r\n <!-- Ilustraci\u00F3n: ventana con 404 y lupa buscando -->\r\n <svg class=\"nf-illustration\" viewBox=\"0 0 520 340\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"P\u00E1gina no encontrada\">\r\n <defs>\r\n <linearGradient id=\"nfGrad\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\r\n <stop offset=\"0%\" style=\"stop-color: var(--sidebar-accent)\" />\r\n <stop offset=\"100%\" style=\"stop-color: var(--sidebar-accent); stop-opacity: 0.55\" />\r\n </linearGradient>\r\n </defs>\r\n\r\n <!-- \u00D3rbita punteada de fondo -->\r\n <circle class=\"nf-orbit\" cx=\"260\" cy=\"170\" r=\"150\"\r\n stroke=\"var(--font-border-input)\" stroke-width=\"1.5\"\r\n stroke-dasharray=\"6 10\" opacity=\"0.7\" />\r\n\r\n <!-- Decoraciones flotantes -->\r\n <g class=\"nf-spark nf-spark-1\" stroke=\"var(--sidebar-accent)\" stroke-width=\"3\" stroke-linecap=\"round\">\r\n <path d=\"M92 78 v20 M82 88 h20\" />\r\n </g>\r\n <g class=\"nf-spark nf-spark-2\" stroke=\"var(--placeholder-color)\" stroke-width=\"3\" stroke-linecap=\"round\">\r\n <path d=\"M448 220 v16 M440 228 h16\" />\r\n </g>\r\n <circle class=\"nf-spark nf-spark-3\" cx=\"430\" cy=\"70\" r=\"6\" fill=\"var(--sidebar-accent)\" opacity=\"0.7\" />\r\n <circle class=\"nf-spark nf-spark-1\" cx=\"70\" cy=\"230\" r=\"5\" fill=\"var(--placeholder-color)\" opacity=\"0.7\" />\r\n <path class=\"nf-spark nf-spark-2\" d=\"M120 300 q8 -10 16 0 q8 10 16 0\"\r\n stroke=\"var(--font-border-input)\" stroke-width=\"3\" stroke-linecap=\"round\" fill=\"none\" />\r\n\r\n <!-- Ventana de navegador -->\r\n <g class=\"nf-window\">\r\n <rect x=\"120\" y=\"60\" width=\"280\" height=\"200\" rx=\"16\"\r\n fill=\"var(--background-input)\" stroke=\"var(--font-border-input)\" stroke-width=\"2\" />\r\n <!-- Barra superior -->\r\n <line x1=\"120\" y1=\"98\" x2=\"400\" y2=\"98\" stroke=\"var(--font-border-input)\" stroke-width=\"2\" />\r\n <circle cx=\"144\" cy=\"79\" r=\"5\" fill=\"var(--sidebar-accent)\" />\r\n <circle cx=\"162\" cy=\"79\" r=\"5\" fill=\"var(--placeholder-color)\" opacity=\"0.8\" />\r\n <circle cx=\"180\" cy=\"79\" r=\"5\" fill=\"var(--font-border-input)\" />\r\n <!-- Barra de direcci\u00F3n -->\r\n <rect x=\"200\" y=\"71\" width=\"184\" height=\"16\" rx=\"8\" fill=\"var(--font-border-input)\" opacity=\"0.5\" />\r\n\r\n <!-- 404 dentro de la ventana -->\r\n <text x=\"260\" y=\"188\" text-anchor=\"middle\" class=\"nf-404-text\" fill=\"url(#nfGrad)\">404</text>\r\n\r\n <!-- L\u00EDneas de contenido (skeleton) -->\r\n <rect x=\"180\" y=\"212\" width=\"160\" height=\"9\" rx=\"4.5\" fill=\"var(--font-border-input)\" opacity=\"0.7\" />\r\n <rect x=\"205\" y=\"230\" width=\"110\" height=\"9\" rx=\"4.5\" fill=\"var(--font-border-input)\" opacity=\"0.45\" />\r\n </g>\r\n\r\n <!-- Lupa buscando -->\r\n <g class=\"nf-lens\">\r\n <circle cx=\"352\" cy=\"238\" r=\"46\" fill=\"var(--background-card)\" fill-opacity=\"0.55\"\r\n stroke=\"url(#nfGrad)\" stroke-width=\"8\" />\r\n <line x1=\"386\" y1=\"272\" x2=\"424\" y2=\"310\" stroke=\"url(#nfGrad)\" stroke-width=\"14\" stroke-linecap=\"round\" />\r\n <!-- Signo de interrogaci\u00F3n dentro de la lupa -->\r\n <path d=\"M340 224 q0 -14 13 -14 q13 0 13 12 q0 9 -10 13 q-3 1.5 -3 7\"\r\n stroke=\"var(--text-color)\" stroke-width=\"5\" stroke-linecap=\"round\" fill=\"none\" />\r\n <circle cx=\"353\" cy=\"256\" r=\"3.5\" fill=\"var(--text-color)\" />\r\n </g>\r\n </svg>\r\n\r\n <!-- Badge -->\r\n <span class=\"nf-badge fw-semibold\">ERROR 404</span>\r\n\r\n <h2 class=\"fw-semibold text-input mt-3\">P\u00E1gina no encontrada</h2>\r\n\r\n <p class=\"nf-desc fs-6 mt-2 mb-4 mx-auto\">\r\n Lo sentimos, la p\u00E1gina que buscas no existe o fue movida.\r\n Verifica la direcci\u00F3n o regresa al inicio.\r\n </p>\r\n\r\n <!-- Acciones -->\r\n <div class=\"d-flex gap-3 justify-content-center flex-wrap\">\r\n <button type=\"button\" (click)=\"onBack()\" class=\"btn nf-btn-primary px-4 py-2 shadow\">\r\n <i class=\"fa-solid fa-arrow-left me-2\"></i>Volver\r\n </button>\r\n <a routerLink=\"/\" class=\"btn nf-btn-ghost text-dark px-4 py-2\">\r\n <i class=\"fa-solid fa-house me-2\"></i>Ir al inicio\r\n </a>\r\n </div>\r\n\r\n </div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.nf-page{position:relative;overflow:hidden;background:var(--background-color)}.nf-blob{position:absolute;border-radius:50%;filter:blur(90px);opacity:.22;pointer-events:none;animation:nf-drift 12s ease-in-out infinite alternate}.nf-blob-1{width:420px;height:420px;top:-120px;left:-100px;background:var(--sidebar-accent)}.nf-blob-2{width:360px;height:360px;bottom:-100px;right:-80px;background:color-mix(in srgb,var(--sidebar-accent) 60%,var(--text-color));animation-delay:-6s}@keyframes nf-drift{0%{transform:translate(0) scale(1)}to{transform:translate(40px,30px) scale(1.12)}}.nf-card{position:relative;z-index:1;max-width:560px;width:100%;border-radius:1.5rem;border:1px solid var(--font-border-input);-webkit-backdrop-filter:blur(var(--blur-modal));backdrop-filter:blur(var(--blur-modal))}.nf-illustration{width:100%;max-width:380px;height:auto;margin-bottom:.5rem}.nf-404-text{font-size:68px;font-weight:800;letter-spacing:4px}.nf-window{animation:nf-float 5s ease-in-out infinite}.nf-lens{transform-origin:370px 260px;animation:nf-search 4s ease-in-out infinite}@keyframes nf-float{0%,to{transform:translateY(0)}50%{transform:translateY(-8px)}}@keyframes nf-search{0%,to{transform:translate(0) rotate(0)}35%{transform:translate(-10px,-12px) rotate(-4deg)}70%{transform:translate(6px,-4px) rotate(3deg)}}.nf-orbit{transform-origin:260px 170px;animation:nf-spin 40s linear infinite}@keyframes nf-spin{to{transform:rotate(360deg)}}.nf-spark{animation:nf-twinkle 3s ease-in-out infinite}.nf-spark-2{animation-delay:-1s}.nf-spark-3{animation-delay:-2s}@keyframes nf-twinkle{0%,to{opacity:.9}50%{opacity:.25}}.nf-badge{display:inline-block;font-size:.75rem;letter-spacing:.15em;padding:.35rem .9rem;border-radius:999px;color:var(--sidebar-accent);background:color-mix(in srgb,var(--sidebar-accent) 12%,transparent);border:1px solid color-mix(in srgb,var(--sidebar-accent) 35%,transparent)}.nf-desc{color:var(--placeholder-color);max-width:380px}.nf-btn-primary{color:#fff;border:none;border-radius:.75rem;background:linear-gradient(135deg,var(--sidebar-accent),color-mix(in srgb,var(--sidebar-accent) 70%,#000));transition:transform .25s ease,box-shadow .25s ease}.nf-btn-primary:hover{color:#fff;transform:translateY(-2px);box-shadow:0 8px 20px color-mix(in srgb,var(--sidebar-accent) 40%,transparent)}.nf-btn-ghost{border-radius:.75rem;border:1px solid var(--font-border-input);background:transparent;transition:transform .25s ease,background .25s ease}.nf-btn-ghost:hover{transform:translateY(-2px);background:var(--background-btn-light);border-color:var(--font-border-input)}@media(prefers-reduced-motion:reduce){.nf-blob,.nf-window,.nf-lens,.nf-orbit,.nf-spark{animation:none}}\n"] }]
1166
1159
  }] });
1167
1160
 
1168
1161
  class DashboardChartDonutComponent {
1169
- textClass = input('text-white');
1170
- complemento = input('');
1171
- data = input([]);
1172
- keyValue = input('value');
1173
- keyDescri = input('descri');
1174
- palette = input([]);
1162
+ textClass = input('text-white', ...(ngDevMode ? [{ debugName: "textClass" }] : /* istanbul ignore next */ []));
1163
+ complemento = input('', ...(ngDevMode ? [{ debugName: "complemento" }] : /* istanbul ignore next */ []));
1164
+ data = input([], ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
1165
+ keyValue = input('value', ...(ngDevMode ? [{ debugName: "keyValue" }] : /* istanbul ignore next */ []));
1166
+ keyDescri = input('descri', ...(ngDevMode ? [{ debugName: "keyDescri" }] : /* istanbul ignore next */ []));
1167
+ palette = input([], ...(ngDevMode ? [{ debugName: "palette" }] : /* istanbul ignore next */ []));
1175
1168
  clicked = output();
1176
- hoveredIndex = signal(-1);
1169
+ hoveredIndex = signal(-1, ...(ngDevMode ? [{ debugName: "hoveredIndex" }] : /* istanbul ignore next */ []));
1177
1170
  // ── Dona ──────────────────────────────────────────────────────────────────
1178
1171
  C = 2 * Math.PI * 70;
1179
1172
  GAP = 2;
@@ -1201,7 +1194,7 @@ class DashboardChartDonutComponent {
1201
1194
  item,
1202
1195
  };
1203
1196
  });
1204
- });
1197
+ }, ...(ngDevMode ? [{ debugName: "donutSegments" }] : /* istanbul ignore next */ []));
1205
1198
  centerDisplay = computed(() => {
1206
1199
  const idx = this.hoveredIndex();
1207
1200
  const segs = this.donutSegments();
@@ -1211,9 +1204,9 @@ class DashboardChartDonutComponent {
1211
1204
  }
1212
1205
  const total = segs.reduce((acc, s) => acc + s.value, 0);
1213
1206
  return { value: String(total), sub: 'Total' };
1214
- });
1215
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DashboardChartDonutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1216
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: DashboardChartDonutComponent, isStandalone: true, selector: "app-dashboard-chart-donut", inputs: { textClass: { classPropertyName: "textClass", publicName: "textClass", isSignal: true, isRequired: false, transformFunction: null }, complemento: { classPropertyName: "complemento", publicName: "complemento", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, keyValue: { classPropertyName: "keyValue", publicName: "keyValue", isSignal: true, isRequired: false, transformFunction: null }, keyDescri: { classPropertyName: "keyDescri", publicName: "keyDescri", isSignal: true, isRequired: false, transformFunction: null }, palette: { classPropertyName: "palette", publicName: "palette", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: `
1207
+ }, ...(ngDevMode ? [{ debugName: "centerDisplay" }] : /* istanbul ignore next */ []));
1208
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: DashboardChartDonutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1209
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: DashboardChartDonutComponent, isStandalone: true, selector: "app-dashboard-chart-donut", inputs: { textClass: { classPropertyName: "textClass", publicName: "textClass", isSignal: true, isRequired: false, transformFunction: null }, complemento: { classPropertyName: "complemento", publicName: "complemento", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, keyValue: { classPropertyName: "keyValue", publicName: "keyValue", isSignal: true, isRequired: false, transformFunction: null }, keyDescri: { classPropertyName: "keyDescri", publicName: "keyDescri", isSignal: true, isRequired: false, transformFunction: null }, palette: { classPropertyName: "palette", publicName: "palette", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: `
1217
1210
  <div class="d-flex flex-column align-items-center py-1 px-2">
1218
1211
 
1219
1212
  <!-- SVG ring -->
@@ -1273,7 +1266,7 @@ class DashboardChartDonutComponent {
1273
1266
  </div>
1274
1267
  `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
1275
1268
  }
1276
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DashboardChartDonutComponent, decorators: [{
1269
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: DashboardChartDonutComponent, decorators: [{
1277
1270
  type: Component,
1278
1271
  args: [{
1279
1272
  selector: 'app-dashboard-chart-donut',
@@ -1338,18 +1331,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
1338
1331
  </div>
1339
1332
  `
1340
1333
  }]
1341
- }] });
1334
+ }], propDecorators: { textClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "textClass", required: false }] }], complemento: [{ type: i0.Input, args: [{ isSignal: true, alias: "complemento", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], keyValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyValue", required: false }] }], keyDescri: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyDescri", required: false }] }], palette: [{ type: i0.Input, args: [{ isSignal: true, alias: "palette", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
1342
1335
 
1343
1336
  class DashboardChartBarsComponent {
1344
- data = input.required();
1345
- maxValue = input(null);
1346
- keyValue = input('value');
1347
- keyDescri = input('descri');
1348
- palette = input([]);
1349
- textClass = input('text-white');
1350
- complemento = input('');
1337
+ data = input.required(...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
1338
+ maxValue = input(null, ...(ngDevMode ? [{ debugName: "maxValue" }] : /* istanbul ignore next */ []));
1339
+ keyValue = input('value', ...(ngDevMode ? [{ debugName: "keyValue" }] : /* istanbul ignore next */ []));
1340
+ keyDescri = input('descri', ...(ngDevMode ? [{ debugName: "keyDescri" }] : /* istanbul ignore next */ []));
1341
+ palette = input([], ...(ngDevMode ? [{ debugName: "palette" }] : /* istanbul ignore next */ []));
1342
+ textClass = input('text-white', ...(ngDevMode ? [{ debugName: "textClass" }] : /* istanbul ignore next */ []));
1343
+ complemento = input('', ...(ngDevMode ? [{ debugName: "complemento" }] : /* istanbul ignore next */ []));
1351
1344
  clicked = output();
1352
- hoveredIndex = signal(-1);
1345
+ hoveredIndex = signal(-1, ...(ngDevMode ? [{ debugName: "hoveredIndex" }] : /* istanbul ignore next */ []));
1353
1346
  // ── Barras horizontales SVG ───────────────────────────────────────────────
1354
1347
  chartData = computed(() => {
1355
1348
  const data = this.data();
@@ -1384,9 +1377,9 @@ class DashboardChartBarsComponent {
1384
1377
  };
1385
1378
  });
1386
1379
  return { bars, xTicks, svgW: SVG_W, svgH, axisY, axisLft: LFT, svgRgt: SVG_W - RGT, svgTop: TOP };
1387
- });
1388
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DashboardChartBarsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1389
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: DashboardChartBarsComponent, isStandalone: true, selector: "app-dashboard-chart-bars", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, maxValue: { classPropertyName: "maxValue", publicName: "maxValue", isSignal: true, isRequired: false, transformFunction: null }, keyValue: { classPropertyName: "keyValue", publicName: "keyValue", isSignal: true, isRequired: false, transformFunction: null }, keyDescri: { classPropertyName: "keyDescri", publicName: "keyDescri", isSignal: true, isRequired: false, transformFunction: null }, palette: { classPropertyName: "palette", publicName: "palette", isSignal: true, isRequired: false, transformFunction: null }, textClass: { classPropertyName: "textClass", publicName: "textClass", isSignal: true, isRequired: false, transformFunction: null }, complemento: { classPropertyName: "complemento", publicName: "complemento", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: `
1380
+ }, ...(ngDevMode ? [{ debugName: "chartData" }] : /* istanbul ignore next */ []));
1381
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: DashboardChartBarsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1382
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: DashboardChartBarsComponent, isStandalone: true, selector: "app-dashboard-chart-bars", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, maxValue: { classPropertyName: "maxValue", publicName: "maxValue", isSignal: true, isRequired: false, transformFunction: null }, keyValue: { classPropertyName: "keyValue", publicName: "keyValue", isSignal: true, isRequired: false, transformFunction: null }, keyDescri: { classPropertyName: "keyDescri", publicName: "keyDescri", isSignal: true, isRequired: false, transformFunction: null }, palette: { classPropertyName: "palette", publicName: "palette", isSignal: true, isRequired: false, transformFunction: null }, textClass: { classPropertyName: "textClass", publicName: "textClass", isSignal: true, isRequired: false, transformFunction: null }, complemento: { classPropertyName: "complemento", publicName: "complemento", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: `
1390
1383
  <div class="d-flex flex-column align-items-center py-1 px-2">
1391
1384
 
1392
1385
  <!-- SVG: barras horizontales + ejes -->
@@ -1476,7 +1469,7 @@ class DashboardChartBarsComponent {
1476
1469
  </div>
1477
1470
  `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
1478
1471
  }
1479
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DashboardChartBarsComponent, decorators: [{
1472
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: DashboardChartBarsComponent, decorators: [{
1480
1473
  type: Component,
1481
1474
  args: [{
1482
1475
  selector: 'app-dashboard-chart-bars',
@@ -1571,28 +1564,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
1571
1564
  </div>
1572
1565
  `
1573
1566
  }]
1574
- }] });
1567
+ }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], maxValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxValue", required: false }] }], keyValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyValue", required: false }] }], keyDescri: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyDescri", required: false }] }], palette: [{ type: i0.Input, args: [{ isSignal: true, alias: "palette", required: false }] }], textClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "textClass", required: false }] }], complemento: [{ type: i0.Input, args: [{ isSignal: true, alias: "complemento", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
1575
1568
 
1576
1569
  class ItemDashboardComponent {
1577
- data = input([]);
1578
- titulo = input('');
1579
- textClass = input('text-white');
1580
- colorClass = input('');
1581
- keyValue = input('value');
1582
- keyDescri = input('descri');
1583
- complemento = input('');
1584
- isDesplegable = input(false);
1585
- isLoading = input(false);
1586
- viewMode = input('cards');
1587
- showContent = signal(false);
1570
+ data = input([], ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
1571
+ titulo = input('', ...(ngDevMode ? [{ debugName: "titulo" }] : /* istanbul ignore next */ []));
1572
+ textClass = input('text-white', ...(ngDevMode ? [{ debugName: "textClass" }] : /* istanbul ignore next */ []));
1573
+ colorClass = input('', ...(ngDevMode ? [{ debugName: "colorClass" }] : /* istanbul ignore next */ []));
1574
+ keyValue = input('value', ...(ngDevMode ? [{ debugName: "keyValue" }] : /* istanbul ignore next */ []));
1575
+ keyDescri = input('descri', ...(ngDevMode ? [{ debugName: "keyDescri" }] : /* istanbul ignore next */ []));
1576
+ complemento = input('', ...(ngDevMode ? [{ debugName: "complemento" }] : /* istanbul ignore next */ []));
1577
+ isDesplegable = input(false, ...(ngDevMode ? [{ debugName: "isDesplegable" }] : /* istanbul ignore next */ []));
1578
+ isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
1579
+ viewMode = input('cards', ...(ngDevMode ? [{ debugName: "viewMode" }] : /* istanbul ignore next */ []));
1580
+ showContent = signal(false, ...(ngDevMode ? [{ debugName: "showContent" }] : /* istanbul ignore next */ []));
1588
1581
  emit = output();
1589
1582
  emitContent = output();
1590
- filteredData = computed(() => this.data().filter(item => item[this.keyValue()] > 0));
1591
- totalItems = computed(() => this.filteredData().reduce((sum, item) => sum + (item[this.keyValue()] || 0), 0));
1583
+ filteredData = computed(() => this.data().filter(item => item[this.keyValue()] > 0), ...(ngDevMode ? [{ debugName: "filteredData" }] : /* istanbul ignore next */ []));
1584
+ totalItems = computed(() => this.filteredData().reduce((sum, item) => sum + (item[this.keyValue()] || 0), 0), ...(ngDevMode ? [{ debugName: "totalItems" }] : /* istanbul ignore next */ []));
1592
1585
  maxValue = computed(() => {
1593
1586
  const vals = this.filteredData().map(item => item[this.keyValue()] || 0);
1594
1587
  return vals.length > 0 ? Math.max(...vals) : 1;
1595
- });
1588
+ }, ...(ngDevMode ? [{ debugName: "maxValue" }] : /* istanbul ignore next */ []));
1596
1589
  // ── Paleta compartida entre dona y barras ──────────────────────────────────
1597
1590
  palette = [
1598
1591
  '#ffffff', '#48dae4', '#06d6a0', '#ff9f1c',
@@ -1612,29 +1605,29 @@ class ItemDashboardComponent {
1612
1605
  mover(item) {
1613
1606
  this.emit.emit(item);
1614
1607
  }
1615
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: ItemDashboardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1616
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: ItemDashboardComponent, isStandalone: true, selector: "app-item-dashboard", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, titulo: { classPropertyName: "titulo", publicName: "titulo", isSignal: true, isRequired: false, transformFunction: null }, textClass: { classPropertyName: "textClass", publicName: "textClass", isSignal: true, isRequired: false, transformFunction: null }, colorClass: { classPropertyName: "colorClass", publicName: "colorClass", isSignal: true, isRequired: false, transformFunction: null }, keyValue: { classPropertyName: "keyValue", publicName: "keyValue", isSignal: true, isRequired: false, transformFunction: null }, keyDescri: { classPropertyName: "keyDescri", publicName: "keyDescri", isSignal: true, isRequired: false, transformFunction: null }, complemento: { classPropertyName: "complemento", publicName: "complemento", isSignal: true, isRequired: false, transformFunction: null }, isDesplegable: { classPropertyName: "isDesplegable", publicName: "isDesplegable", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, viewMode: { classPropertyName: "viewMode", publicName: "viewMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { emit: "emit", emitContent: "emitContent" }, ngImport: i0, template: "<div class=\"iv2-card mb-2\" [ngClass]=\"colorClass() ? colorClass() : 'bg-danger'\">\r\n\r\n <!-- \u2500\u2500 HEADER \u2500\u2500 -->\r\n <div class=\"iv2-header\">\r\n\r\n <div class=\"iv2-icon-dot\"></div>\r\n\r\n <div class=\"iv2-title-wrap\">\r\n <h5 class=\"iv2-title\" [ngClass]=\"textClass()\">{{ titulo() }}</h5>\r\n\r\n @if (!isLoading() && totalItems() > 0) {\r\n <span class=\"iv2-total-badge\">{{ totalItems() }}</span>\r\n }\r\n </div>\r\n\r\n @if (isDesplegable()) {\r\n <button class=\"iv2-toggle-btn\" [ngClass]=\"textClass()\" (click)=\"toggleMostrar()\"\r\n [attr.aria-expanded]=\"showContent()\">\r\n <svg class=\"iv2-chevron\" [class.iv2-chevron--open]=\"showContent()\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- \u2500\u2500 CONTENIDO (expandible) \u2500\u2500 -->\r\n <div class=\"iv2-content\" [class.iv2-content--expanded]=\"showContent() || !isDesplegable()\">\r\n <div class=\"iv2-inner\">\r\n\r\n <!-- SKELETON -->\r\n @if (isLoading()) {\r\n <div class=\"iv2-skeleton\">\r\n <div class=\"iv2-sk-row\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n <div class=\"iv2-sk-row mt-2\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n </div>\r\n\r\n } @else {\r\n\r\n <!-- \u2550\u2550 CARDS \u2550\u2550 -->\r\n @if (viewMode() === 'cards') {\r\n @if (filteredData().length > 0) {\r\n <ul class=\"iv2-list\">\r\n @for (item of filteredData(); track $index) {\r\n <li class=\"iv2-item\" [class.iv2-item--clickable]=\"item[keyValue()] > 0\"\r\n (click)=\"mover(item)\">\r\n <div class=\"iv2-item-info\">\r\n <span class=\"iv2-item-label\" [ngClass]=\"textClass()\">{{ item[keyDescri()] }}</span>\r\n <div class=\"iv2-bar-track\">\r\n <div class=\"iv2-bar-fill\" [style.width.%]=\"getPercent(item)\"></div>\r\n </div>\r\n </div>\r\n <div class=\"iv2-item-right\">\r\n <span class=\"iv2-value-badge\">{{ complemento() }}{{ item[keyValue()] }}</span>\r\n </div>\r\n </li>\r\n }\r\n </ul>\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- \u2550\u2550 BARRAS \u2550\u2550 -->\r\n @if (viewMode() === 'bars') {\r\n @if (filteredData().length > 0) {\r\n <app-dashboard-chart-bars\r\n [data]=\"filteredData()\"\r\n [complemento]=\"complemento()\"\r\n [keyValue]=\"keyValue()\"\r\n [keyDescri]=\"keyDescri()\"\r\n [palette]=\"palette\"\r\n [maxValue]=\"maxValue()\"\r\n (clicked)=\"mover($event)\" />\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- \u2550\u2550 DONA \u2550\u2550 -->\r\n @if (viewMode() === 'donut') {\r\n @if (filteredData().length > 0) {\r\n <app-dashboard-chart-donut\r\n [data]=\"filteredData()\"\r\n [textClass]=\"textClass()\"\r\n [complemento]=\"complemento()\"\r\n [keyValue]=\"keyValue()\"\r\n [keyDescri]=\"keyDescri()\"\r\n [palette]=\"palette\"\r\n (clicked)=\"mover($event)\" />\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n }\r\n\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".iv2-card{border-radius:16px;border:1px solid rgba(255,255,255,.18);overflow:hidden;transition:transform .2s ease,box-shadow .2s ease}.iv2-card:hover{transform:translateY(-2px)}.bg-danger{background:linear-gradient(145deg,#ff4b2b,#dc3545)!important;box-shadow:0 8px 24px #dc354559;border-color:#ffffff26}.bg-success{background:linear-gradient(135deg,#2ecc71,#00cc6a)!important;box-shadow:0 8px 24px #15734759;border-color:#ffffff26}.bg-warning{background:linear-gradient(135deg,#f60,#fa9600)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.bg-info{background:linear-gradient(135deg,#4b84ff,#1b6ad8)!important;box-shadow:0 8px 24px #1b6ad859;border-color:#ffffff26}.bg-alert{background:linear-gradient(135deg,#ffc400,#fa0)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.iv2-header{display:flex;align-items:center;gap:10px;padding:14px 16px 12px}.iv2-icon-dot{width:8px;height:8px;border-radius:50%;background:#ffffff80;flex-shrink:0;animation:pulse-dot 2s ease-in-out infinite}@keyframes pulse-dot{0%,to{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.3)}}.iv2-title-wrap{flex:1;display:flex;align-items:center;gap:8px;min-width:0}.iv2-title{font-size:.82rem;font-weight:700;letter-spacing:.02em;margin:0;line-height:1.3;flex:1;min-width:0}.iv2-total-badge{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:22px;padding:0 7px;border-radius:999px;background:#ffffff40;color:#fff;font-size:.72rem;font-weight:700;letter-spacing:.01em;backdrop-filter:blur(4px);border:1px solid rgba(255,255,255,.35);flex-shrink:0;animation:badge-pop .3s cubic-bezier(.34,1.56,.64,1)}@keyframes badge-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}.iv2-toggle-btn{background:#ffffff26;border:1px solid rgba(255,255,255,.25);border-radius:8px;width:30px;height:30px;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .2s ease;padding:0}.iv2-toggle-btn:hover{background:#ffffff47}.iv2-chevron{width:16px;height:16px;transition:transform .3s cubic-bezier(.4,0,.2,1)}.iv2-chevron--open{transform:rotate(180deg)}.iv2-content{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4,0,.2,1),opacity .25s ease;opacity:0}.iv2-content--expanded{max-height:600px;opacity:1}.iv2-inner{background:#0000001f;backdrop-filter:blur(6px);border-top:1px solid rgba(255,255,255,.15);padding:4px 0 6px}.iv2-list{list-style:none;margin:0;padding:0}.iv2-item{display:flex;align-items:center;gap:10px;padding:9px 14px;border-top:1px solid rgba(255,255,255,.1);transition:background .18s ease}.iv2-item--clickable{cursor:pointer}.iv2-item--clickable:hover{background:#ffffff1f}.iv2-item--clickable:hover .iv2-arrow{opacity:1;transform:translate(3px)}.iv2-item:first-child{border-top:none}.iv2-item-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}.iv2-item-label{font-size:.78rem;font-weight:600;line-height:1.3;white-space:normal;word-break:break-word}.iv2-bar-track{height:3px;border-radius:99px;background:#fff3;overflow:hidden}.iv2-bar-fill{height:100%;border-radius:99px;background:#fff9;transition:width .6s cubic-bezier(.4,0,.2,1)}.iv2-item-right{display:flex;align-items:center;gap:6px;flex-shrink:0}.iv2-value-badge{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:26px;padding:0 9px;border-radius:999px;background:#ffffffe6;color:#333;font-size:.78rem;font-weight:700;letter-spacing:.01em;box-shadow:0 2px 6px #00000026}.iv2-arrow{width:14px;height:14px;opacity:.5;transition:opacity .18s ease,transform .18s ease}.iv2-empty{display:flex;flex-direction:column;align-items:center;padding:20px 16px 18px;gap:4px}.iv2-empty-icon{width:40px;height:40px;border-radius:50%;background:#fff3;border:1.5px solid rgba(255,255,255,.4);display:flex;align-items:center;justify-content:center;margin-bottom:6px}.iv2-empty-icon svg{width:20px;height:20px;color:#fff}.iv2-empty-title{font-size:.82rem;font-weight:700;margin:0;opacity:.95}.iv2-empty-sub{font-size:.72rem;margin:0;opacity:.65}.iv2-skeleton{padding:10px 14px 8px}.iv2-sk-row{display:flex;gap:12px;align-items:center}.iv2-sk-line{height:12px;border-radius:6px;background-size:200% 100%;animation:shimmer 1.5s infinite}.iv2-sk-line--long{flex:1}.iv2-sk-line--short{width:36px;flex-shrink:0}.bg-warning-line,.bg-alert-line{background:linear-gradient(90deg,#f9a825 25%,#fff59d,#f9a825 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-danger-line{background:linear-gradient(90deg,#c62828 25%,#ffcdd2,#c62828 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-info-line{background:linear-gradient(90deg,#1e88e5 25%,#90caf9,#1e88e5 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-success-line{background:linear-gradient(90deg,#2e7d32 25%,#a5d6a7,#2e7d32 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}@keyframes shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: DashboardChartDonutComponent, selector: "app-dashboard-chart-donut", inputs: ["textClass", "complemento", "data", "keyValue", "keyDescri", "palette"], outputs: ["clicked"] }, { kind: "component", type: DashboardChartBarsComponent, selector: "app-dashboard-chart-bars", inputs: ["data", "maxValue", "keyValue", "keyDescri", "palette", "textClass", "complemento"], outputs: ["clicked"] }] });
1608
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: ItemDashboardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1609
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: ItemDashboardComponent, isStandalone: true, selector: "app-item-dashboard", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, titulo: { classPropertyName: "titulo", publicName: "titulo", isSignal: true, isRequired: false, transformFunction: null }, textClass: { classPropertyName: "textClass", publicName: "textClass", isSignal: true, isRequired: false, transformFunction: null }, colorClass: { classPropertyName: "colorClass", publicName: "colorClass", isSignal: true, isRequired: false, transformFunction: null }, keyValue: { classPropertyName: "keyValue", publicName: "keyValue", isSignal: true, isRequired: false, transformFunction: null }, keyDescri: { classPropertyName: "keyDescri", publicName: "keyDescri", isSignal: true, isRequired: false, transformFunction: null }, complemento: { classPropertyName: "complemento", publicName: "complemento", isSignal: true, isRequired: false, transformFunction: null }, isDesplegable: { classPropertyName: "isDesplegable", publicName: "isDesplegable", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, viewMode: { classPropertyName: "viewMode", publicName: "viewMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { emit: "emit", emitContent: "emitContent" }, ngImport: i0, template: "<div class=\"iv2-card mb-2\" [ngClass]=\"colorClass() ? colorClass() : 'bg-danger'\">\r\n\r\n <!-- \u2500\u2500 HEADER \u2500\u2500 -->\r\n <div class=\"iv2-header\">\r\n\r\n <div class=\"iv2-icon-dot\"></div>\r\n\r\n <div class=\"iv2-title-wrap\">\r\n <h5 class=\"iv2-title\" [ngClass]=\"textClass()\">{{ titulo() }}</h5>\r\n\r\n @if (!isLoading() && totalItems() > 0) {\r\n <span class=\"iv2-total-badge\">{{ totalItems() }}</span>\r\n }\r\n </div>\r\n\r\n @if (isDesplegable()) {\r\n <button class=\"iv2-toggle-btn\" [ngClass]=\"textClass()\" (click)=\"toggleMostrar()\"\r\n [attr.aria-expanded]=\"showContent()\">\r\n <svg class=\"iv2-chevron\" [class.iv2-chevron--open]=\"showContent()\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- \u2500\u2500 CONTENIDO (expandible) \u2500\u2500 -->\r\n <div class=\"iv2-content\" [class.iv2-content--expanded]=\"showContent() || !isDesplegable()\">\r\n <div class=\"iv2-inner\">\r\n\r\n <!-- SKELETON -->\r\n @if (isLoading()) {\r\n <div class=\"iv2-skeleton\">\r\n <div class=\"iv2-sk-row\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n <div class=\"iv2-sk-row mt-2\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n </div>\r\n\r\n } @else {\r\n\r\n <!-- \u2550\u2550 CARDS \u2550\u2550 -->\r\n @if (viewMode() === 'cards') {\r\n @if (filteredData().length > 0) {\r\n <ul class=\"iv2-list\">\r\n @for (item of filteredData(); track $index) {\r\n <li class=\"iv2-item\" [class.iv2-item--clickable]=\"item[keyValue()] > 0\"\r\n (click)=\"mover(item)\">\r\n <div class=\"iv2-item-info\">\r\n <span class=\"iv2-item-label\" [ngClass]=\"textClass()\">{{ item[keyDescri()] }}</span>\r\n <div class=\"iv2-bar-track\">\r\n <div class=\"iv2-bar-fill\" [style.width.%]=\"getPercent(item)\"></div>\r\n </div>\r\n </div>\r\n <div class=\"iv2-item-right\">\r\n <span class=\"iv2-value-badge\">{{ complemento() }}{{ item[keyValue()] }}</span>\r\n </div>\r\n </li>\r\n }\r\n </ul>\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- \u2550\u2550 BARRAS \u2550\u2550 -->\r\n @if (viewMode() === 'bars') {\r\n @if (filteredData().length > 0) {\r\n <app-dashboard-chart-bars\r\n [data]=\"filteredData()\"\r\n [complemento]=\"complemento()\"\r\n [keyValue]=\"keyValue()\"\r\n [keyDescri]=\"keyDescri()\"\r\n [palette]=\"palette\"\r\n [maxValue]=\"maxValue()\"\r\n (clicked)=\"mover($event)\" />\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- \u2550\u2550 DONA \u2550\u2550 -->\r\n @if (viewMode() === 'donut') {\r\n @if (filteredData().length > 0) {\r\n <app-dashboard-chart-donut\r\n [data]=\"filteredData()\"\r\n [textClass]=\"textClass()\"\r\n [complemento]=\"complemento()\"\r\n [keyValue]=\"keyValue()\"\r\n [keyDescri]=\"keyDescri()\"\r\n [palette]=\"palette\"\r\n (clicked)=\"mover($event)\" />\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n }\r\n\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".iv2-card{border-radius:16px;border:1px solid rgba(255,255,255,.18);overflow:hidden;transition:transform .2s ease,box-shadow .2s ease}.iv2-card:hover{transform:translateY(-2px)}.bg-danger{background:linear-gradient(145deg,#ff4b2b,#dc3545)!important;box-shadow:0 8px 24px #dc354559;border-color:#ffffff26}.bg-success{background:linear-gradient(135deg,#2ecc71,#00cc6a)!important;box-shadow:0 8px 24px #15734759;border-color:#ffffff26}.bg-warning{background:linear-gradient(135deg,#f60,#fa9600)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.bg-info{background:linear-gradient(135deg,#4b84ff,#1b6ad8)!important;box-shadow:0 8px 24px #1b6ad859;border-color:#ffffff26}.bg-alert{background:linear-gradient(135deg,#ffc400,#fa0)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.iv2-header{display:flex;align-items:center;gap:10px;padding:14px 16px 12px}.iv2-icon-dot{width:8px;height:8px;border-radius:50%;background:#ffffff80;flex-shrink:0;animation:pulse-dot 2s ease-in-out infinite}@keyframes pulse-dot{0%,to{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.3)}}.iv2-title-wrap{flex:1;display:flex;align-items:center;gap:8px;min-width:0}.iv2-title{font-size:.82rem;font-weight:700;letter-spacing:.02em;margin:0;line-height:1.3;flex:1;min-width:0}.iv2-total-badge{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:22px;padding:0 7px;border-radius:999px;background:#ffffff40;color:#fff;font-size:.72rem;font-weight:700;letter-spacing:.01em;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border:1px solid rgba(255,255,255,.35);flex-shrink:0;animation:badge-pop .3s cubic-bezier(.34,1.56,.64,1)}@keyframes badge-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}.iv2-toggle-btn{background:#ffffff26;border:1px solid rgba(255,255,255,.25);border-radius:8px;width:30px;height:30px;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .2s ease;padding:0}.iv2-toggle-btn:hover{background:#ffffff47}.iv2-chevron{width:16px;height:16px;transition:transform .3s cubic-bezier(.4,0,.2,1)}.iv2-chevron--open{transform:rotate(180deg)}.iv2-content{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4,0,.2,1),opacity .25s ease;opacity:0}.iv2-content--expanded{max-height:600px;opacity:1}.iv2-inner{background:#0000001f;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border-top:1px solid rgba(255,255,255,.15);padding:4px 0 6px}.iv2-list{list-style:none;margin:0;padding:0}.iv2-item{display:flex;align-items:center;gap:10px;padding:9px 14px;border-top:1px solid rgba(255,255,255,.1);transition:background .18s ease}.iv2-item--clickable{cursor:pointer}.iv2-item--clickable:hover{background:#ffffff1f}.iv2-item--clickable:hover .iv2-arrow{opacity:1;transform:translate(3px)}.iv2-item:first-child{border-top:none}.iv2-item-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}.iv2-item-label{font-size:.78rem;font-weight:600;line-height:1.3;white-space:normal;word-break:break-word}.iv2-bar-track{height:3px;border-radius:99px;background:#fff3;overflow:hidden}.iv2-bar-fill{height:100%;border-radius:99px;background:#fff9;transition:width .6s cubic-bezier(.4,0,.2,1)}.iv2-item-right{display:flex;align-items:center;gap:6px;flex-shrink:0}.iv2-value-badge{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:26px;padding:0 9px;border-radius:999px;background:#ffffffe6;color:#333;font-size:.78rem;font-weight:700;letter-spacing:.01em;box-shadow:0 2px 6px #00000026}.iv2-arrow{width:14px;height:14px;opacity:.5;transition:opacity .18s ease,transform .18s ease}.iv2-empty{display:flex;flex-direction:column;align-items:center;padding:20px 16px 18px;gap:4px}.iv2-empty-icon{width:40px;height:40px;border-radius:50%;background:#fff3;border:1.5px solid rgba(255,255,255,.4);display:flex;align-items:center;justify-content:center;margin-bottom:6px}.iv2-empty-icon svg{width:20px;height:20px;color:#fff}.iv2-empty-title{font-size:.82rem;font-weight:700;margin:0;opacity:.95}.iv2-empty-sub{font-size:.72rem;margin:0;opacity:.65}.iv2-skeleton{padding:10px 14px 8px}.iv2-sk-row{display:flex;gap:12px;align-items:center}.iv2-sk-line{height:12px;border-radius:6px;background-size:200% 100%;animation:shimmer 1.5s infinite}.iv2-sk-line--long{flex:1}.iv2-sk-line--short{width:36px;flex-shrink:0}.bg-warning-line,.bg-alert-line{background:linear-gradient(90deg,#f9a825 25%,#fff59d,#f9a825 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-danger-line{background:linear-gradient(90deg,#c62828 25%,#ffcdd2,#c62828 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-info-line{background:linear-gradient(90deg,#1e88e5 25%,#90caf9,#1e88e5 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-success-line{background:linear-gradient(90deg,#2e7d32 25%,#a5d6a7,#2e7d32 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}@keyframes shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: DashboardChartDonutComponent, selector: "app-dashboard-chart-donut", inputs: ["textClass", "complemento", "data", "keyValue", "keyDescri", "palette"], outputs: ["clicked"] }, { kind: "component", type: DashboardChartBarsComponent, selector: "app-dashboard-chart-bars", inputs: ["data", "maxValue", "keyValue", "keyDescri", "palette", "textClass", "complemento"], outputs: ["clicked"] }] });
1617
1610
  }
1618
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: ItemDashboardComponent, decorators: [{
1611
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: ItemDashboardComponent, decorators: [{
1619
1612
  type: Component,
1620
- args: [{ selector: 'app-item-dashboard', imports: [NgClass, DashboardChartDonutComponent, DashboardChartBarsComponent], template: "<div class=\"iv2-card mb-2\" [ngClass]=\"colorClass() ? colorClass() : 'bg-danger'\">\r\n\r\n <!-- \u2500\u2500 HEADER \u2500\u2500 -->\r\n <div class=\"iv2-header\">\r\n\r\n <div class=\"iv2-icon-dot\"></div>\r\n\r\n <div class=\"iv2-title-wrap\">\r\n <h5 class=\"iv2-title\" [ngClass]=\"textClass()\">{{ titulo() }}</h5>\r\n\r\n @if (!isLoading() && totalItems() > 0) {\r\n <span class=\"iv2-total-badge\">{{ totalItems() }}</span>\r\n }\r\n </div>\r\n\r\n @if (isDesplegable()) {\r\n <button class=\"iv2-toggle-btn\" [ngClass]=\"textClass()\" (click)=\"toggleMostrar()\"\r\n [attr.aria-expanded]=\"showContent()\">\r\n <svg class=\"iv2-chevron\" [class.iv2-chevron--open]=\"showContent()\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- \u2500\u2500 CONTENIDO (expandible) \u2500\u2500 -->\r\n <div class=\"iv2-content\" [class.iv2-content--expanded]=\"showContent() || !isDesplegable()\">\r\n <div class=\"iv2-inner\">\r\n\r\n <!-- SKELETON -->\r\n @if (isLoading()) {\r\n <div class=\"iv2-skeleton\">\r\n <div class=\"iv2-sk-row\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n <div class=\"iv2-sk-row mt-2\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n </div>\r\n\r\n } @else {\r\n\r\n <!-- \u2550\u2550 CARDS \u2550\u2550 -->\r\n @if (viewMode() === 'cards') {\r\n @if (filteredData().length > 0) {\r\n <ul class=\"iv2-list\">\r\n @for (item of filteredData(); track $index) {\r\n <li class=\"iv2-item\" [class.iv2-item--clickable]=\"item[keyValue()] > 0\"\r\n (click)=\"mover(item)\">\r\n <div class=\"iv2-item-info\">\r\n <span class=\"iv2-item-label\" [ngClass]=\"textClass()\">{{ item[keyDescri()] }}</span>\r\n <div class=\"iv2-bar-track\">\r\n <div class=\"iv2-bar-fill\" [style.width.%]=\"getPercent(item)\"></div>\r\n </div>\r\n </div>\r\n <div class=\"iv2-item-right\">\r\n <span class=\"iv2-value-badge\">{{ complemento() }}{{ item[keyValue()] }}</span>\r\n </div>\r\n </li>\r\n }\r\n </ul>\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- \u2550\u2550 BARRAS \u2550\u2550 -->\r\n @if (viewMode() === 'bars') {\r\n @if (filteredData().length > 0) {\r\n <app-dashboard-chart-bars\r\n [data]=\"filteredData()\"\r\n [complemento]=\"complemento()\"\r\n [keyValue]=\"keyValue()\"\r\n [keyDescri]=\"keyDescri()\"\r\n [palette]=\"palette\"\r\n [maxValue]=\"maxValue()\"\r\n (clicked)=\"mover($event)\" />\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- \u2550\u2550 DONA \u2550\u2550 -->\r\n @if (viewMode() === 'donut') {\r\n @if (filteredData().length > 0) {\r\n <app-dashboard-chart-donut\r\n [data]=\"filteredData()\"\r\n [textClass]=\"textClass()\"\r\n [complemento]=\"complemento()\"\r\n [keyValue]=\"keyValue()\"\r\n [keyDescri]=\"keyDescri()\"\r\n [palette]=\"palette\"\r\n (clicked)=\"mover($event)\" />\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n }\r\n\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".iv2-card{border-radius:16px;border:1px solid rgba(255,255,255,.18);overflow:hidden;transition:transform .2s ease,box-shadow .2s ease}.iv2-card:hover{transform:translateY(-2px)}.bg-danger{background:linear-gradient(145deg,#ff4b2b,#dc3545)!important;box-shadow:0 8px 24px #dc354559;border-color:#ffffff26}.bg-success{background:linear-gradient(135deg,#2ecc71,#00cc6a)!important;box-shadow:0 8px 24px #15734759;border-color:#ffffff26}.bg-warning{background:linear-gradient(135deg,#f60,#fa9600)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.bg-info{background:linear-gradient(135deg,#4b84ff,#1b6ad8)!important;box-shadow:0 8px 24px #1b6ad859;border-color:#ffffff26}.bg-alert{background:linear-gradient(135deg,#ffc400,#fa0)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.iv2-header{display:flex;align-items:center;gap:10px;padding:14px 16px 12px}.iv2-icon-dot{width:8px;height:8px;border-radius:50%;background:#ffffff80;flex-shrink:0;animation:pulse-dot 2s ease-in-out infinite}@keyframes pulse-dot{0%,to{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.3)}}.iv2-title-wrap{flex:1;display:flex;align-items:center;gap:8px;min-width:0}.iv2-title{font-size:.82rem;font-weight:700;letter-spacing:.02em;margin:0;line-height:1.3;flex:1;min-width:0}.iv2-total-badge{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:22px;padding:0 7px;border-radius:999px;background:#ffffff40;color:#fff;font-size:.72rem;font-weight:700;letter-spacing:.01em;backdrop-filter:blur(4px);border:1px solid rgba(255,255,255,.35);flex-shrink:0;animation:badge-pop .3s cubic-bezier(.34,1.56,.64,1)}@keyframes badge-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}.iv2-toggle-btn{background:#ffffff26;border:1px solid rgba(255,255,255,.25);border-radius:8px;width:30px;height:30px;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .2s ease;padding:0}.iv2-toggle-btn:hover{background:#ffffff47}.iv2-chevron{width:16px;height:16px;transition:transform .3s cubic-bezier(.4,0,.2,1)}.iv2-chevron--open{transform:rotate(180deg)}.iv2-content{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4,0,.2,1),opacity .25s ease;opacity:0}.iv2-content--expanded{max-height:600px;opacity:1}.iv2-inner{background:#0000001f;backdrop-filter:blur(6px);border-top:1px solid rgba(255,255,255,.15);padding:4px 0 6px}.iv2-list{list-style:none;margin:0;padding:0}.iv2-item{display:flex;align-items:center;gap:10px;padding:9px 14px;border-top:1px solid rgba(255,255,255,.1);transition:background .18s ease}.iv2-item--clickable{cursor:pointer}.iv2-item--clickable:hover{background:#ffffff1f}.iv2-item--clickable:hover .iv2-arrow{opacity:1;transform:translate(3px)}.iv2-item:first-child{border-top:none}.iv2-item-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}.iv2-item-label{font-size:.78rem;font-weight:600;line-height:1.3;white-space:normal;word-break:break-word}.iv2-bar-track{height:3px;border-radius:99px;background:#fff3;overflow:hidden}.iv2-bar-fill{height:100%;border-radius:99px;background:#fff9;transition:width .6s cubic-bezier(.4,0,.2,1)}.iv2-item-right{display:flex;align-items:center;gap:6px;flex-shrink:0}.iv2-value-badge{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:26px;padding:0 9px;border-radius:999px;background:#ffffffe6;color:#333;font-size:.78rem;font-weight:700;letter-spacing:.01em;box-shadow:0 2px 6px #00000026}.iv2-arrow{width:14px;height:14px;opacity:.5;transition:opacity .18s ease,transform .18s ease}.iv2-empty{display:flex;flex-direction:column;align-items:center;padding:20px 16px 18px;gap:4px}.iv2-empty-icon{width:40px;height:40px;border-radius:50%;background:#fff3;border:1.5px solid rgba(255,255,255,.4);display:flex;align-items:center;justify-content:center;margin-bottom:6px}.iv2-empty-icon svg{width:20px;height:20px;color:#fff}.iv2-empty-title{font-size:.82rem;font-weight:700;margin:0;opacity:.95}.iv2-empty-sub{font-size:.72rem;margin:0;opacity:.65}.iv2-skeleton{padding:10px 14px 8px}.iv2-sk-row{display:flex;gap:12px;align-items:center}.iv2-sk-line{height:12px;border-radius:6px;background-size:200% 100%;animation:shimmer 1.5s infinite}.iv2-sk-line--long{flex:1}.iv2-sk-line--short{width:36px;flex-shrink:0}.bg-warning-line,.bg-alert-line{background:linear-gradient(90deg,#f9a825 25%,#fff59d,#f9a825 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-danger-line{background:linear-gradient(90deg,#c62828 25%,#ffcdd2,#c62828 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-info-line{background:linear-gradient(90deg,#1e88e5 25%,#90caf9,#1e88e5 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-success-line{background:linear-gradient(90deg,#2e7d32 25%,#a5d6a7,#2e7d32 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}@keyframes shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"] }]
1621
- }] });
1613
+ args: [{ selector: 'app-item-dashboard', imports: [NgClass, DashboardChartDonutComponent, DashboardChartBarsComponent], template: "<div class=\"iv2-card mb-2\" [ngClass]=\"colorClass() ? colorClass() : 'bg-danger'\">\r\n\r\n <!-- \u2500\u2500 HEADER \u2500\u2500 -->\r\n <div class=\"iv2-header\">\r\n\r\n <div class=\"iv2-icon-dot\"></div>\r\n\r\n <div class=\"iv2-title-wrap\">\r\n <h5 class=\"iv2-title\" [ngClass]=\"textClass()\">{{ titulo() }}</h5>\r\n\r\n @if (!isLoading() && totalItems() > 0) {\r\n <span class=\"iv2-total-badge\">{{ totalItems() }}</span>\r\n }\r\n </div>\r\n\r\n @if (isDesplegable()) {\r\n <button class=\"iv2-toggle-btn\" [ngClass]=\"textClass()\" (click)=\"toggleMostrar()\"\r\n [attr.aria-expanded]=\"showContent()\">\r\n <svg class=\"iv2-chevron\" [class.iv2-chevron--open]=\"showContent()\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- \u2500\u2500 CONTENIDO (expandible) \u2500\u2500 -->\r\n <div class=\"iv2-content\" [class.iv2-content--expanded]=\"showContent() || !isDesplegable()\">\r\n <div class=\"iv2-inner\">\r\n\r\n <!-- SKELETON -->\r\n @if (isLoading()) {\r\n <div class=\"iv2-skeleton\">\r\n <div class=\"iv2-sk-row\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n <div class=\"iv2-sk-row mt-2\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n </div>\r\n\r\n } @else {\r\n\r\n <!-- \u2550\u2550 CARDS \u2550\u2550 -->\r\n @if (viewMode() === 'cards') {\r\n @if (filteredData().length > 0) {\r\n <ul class=\"iv2-list\">\r\n @for (item of filteredData(); track $index) {\r\n <li class=\"iv2-item\" [class.iv2-item--clickable]=\"item[keyValue()] > 0\"\r\n (click)=\"mover(item)\">\r\n <div class=\"iv2-item-info\">\r\n <span class=\"iv2-item-label\" [ngClass]=\"textClass()\">{{ item[keyDescri()] }}</span>\r\n <div class=\"iv2-bar-track\">\r\n <div class=\"iv2-bar-fill\" [style.width.%]=\"getPercent(item)\"></div>\r\n </div>\r\n </div>\r\n <div class=\"iv2-item-right\">\r\n <span class=\"iv2-value-badge\">{{ complemento() }}{{ item[keyValue()] }}</span>\r\n </div>\r\n </li>\r\n }\r\n </ul>\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- \u2550\u2550 BARRAS \u2550\u2550 -->\r\n @if (viewMode() === 'bars') {\r\n @if (filteredData().length > 0) {\r\n <app-dashboard-chart-bars\r\n [data]=\"filteredData()\"\r\n [complemento]=\"complemento()\"\r\n [keyValue]=\"keyValue()\"\r\n [keyDescri]=\"keyDescri()\"\r\n [palette]=\"palette\"\r\n [maxValue]=\"maxValue()\"\r\n (clicked)=\"mover($event)\" />\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- \u2550\u2550 DONA \u2550\u2550 -->\r\n @if (viewMode() === 'donut') {\r\n @if (filteredData().length > 0) {\r\n <app-dashboard-chart-donut\r\n [data]=\"filteredData()\"\r\n [textClass]=\"textClass()\"\r\n [complemento]=\"complemento()\"\r\n [keyValue]=\"keyValue()\"\r\n [keyDescri]=\"keyDescri()\"\r\n [palette]=\"palette\"\r\n (clicked)=\"mover($event)\" />\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n }\r\n\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".iv2-card{border-radius:16px;border:1px solid rgba(255,255,255,.18);overflow:hidden;transition:transform .2s ease,box-shadow .2s ease}.iv2-card:hover{transform:translateY(-2px)}.bg-danger{background:linear-gradient(145deg,#ff4b2b,#dc3545)!important;box-shadow:0 8px 24px #dc354559;border-color:#ffffff26}.bg-success{background:linear-gradient(135deg,#2ecc71,#00cc6a)!important;box-shadow:0 8px 24px #15734759;border-color:#ffffff26}.bg-warning{background:linear-gradient(135deg,#f60,#fa9600)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.bg-info{background:linear-gradient(135deg,#4b84ff,#1b6ad8)!important;box-shadow:0 8px 24px #1b6ad859;border-color:#ffffff26}.bg-alert{background:linear-gradient(135deg,#ffc400,#fa0)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.iv2-header{display:flex;align-items:center;gap:10px;padding:14px 16px 12px}.iv2-icon-dot{width:8px;height:8px;border-radius:50%;background:#ffffff80;flex-shrink:0;animation:pulse-dot 2s ease-in-out infinite}@keyframes pulse-dot{0%,to{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.3)}}.iv2-title-wrap{flex:1;display:flex;align-items:center;gap:8px;min-width:0}.iv2-title{font-size:.82rem;font-weight:700;letter-spacing:.02em;margin:0;line-height:1.3;flex:1;min-width:0}.iv2-total-badge{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:22px;padding:0 7px;border-radius:999px;background:#ffffff40;color:#fff;font-size:.72rem;font-weight:700;letter-spacing:.01em;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border:1px solid rgba(255,255,255,.35);flex-shrink:0;animation:badge-pop .3s cubic-bezier(.34,1.56,.64,1)}@keyframes badge-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}.iv2-toggle-btn{background:#ffffff26;border:1px solid rgba(255,255,255,.25);border-radius:8px;width:30px;height:30px;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .2s ease;padding:0}.iv2-toggle-btn:hover{background:#ffffff47}.iv2-chevron{width:16px;height:16px;transition:transform .3s cubic-bezier(.4,0,.2,1)}.iv2-chevron--open{transform:rotate(180deg)}.iv2-content{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4,0,.2,1),opacity .25s ease;opacity:0}.iv2-content--expanded{max-height:600px;opacity:1}.iv2-inner{background:#0000001f;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border-top:1px solid rgba(255,255,255,.15);padding:4px 0 6px}.iv2-list{list-style:none;margin:0;padding:0}.iv2-item{display:flex;align-items:center;gap:10px;padding:9px 14px;border-top:1px solid rgba(255,255,255,.1);transition:background .18s ease}.iv2-item--clickable{cursor:pointer}.iv2-item--clickable:hover{background:#ffffff1f}.iv2-item--clickable:hover .iv2-arrow{opacity:1;transform:translate(3px)}.iv2-item:first-child{border-top:none}.iv2-item-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}.iv2-item-label{font-size:.78rem;font-weight:600;line-height:1.3;white-space:normal;word-break:break-word}.iv2-bar-track{height:3px;border-radius:99px;background:#fff3;overflow:hidden}.iv2-bar-fill{height:100%;border-radius:99px;background:#fff9;transition:width .6s cubic-bezier(.4,0,.2,1)}.iv2-item-right{display:flex;align-items:center;gap:6px;flex-shrink:0}.iv2-value-badge{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:26px;padding:0 9px;border-radius:999px;background:#ffffffe6;color:#333;font-size:.78rem;font-weight:700;letter-spacing:.01em;box-shadow:0 2px 6px #00000026}.iv2-arrow{width:14px;height:14px;opacity:.5;transition:opacity .18s ease,transform .18s ease}.iv2-empty{display:flex;flex-direction:column;align-items:center;padding:20px 16px 18px;gap:4px}.iv2-empty-icon{width:40px;height:40px;border-radius:50%;background:#fff3;border:1.5px solid rgba(255,255,255,.4);display:flex;align-items:center;justify-content:center;margin-bottom:6px}.iv2-empty-icon svg{width:20px;height:20px;color:#fff}.iv2-empty-title{font-size:.82rem;font-weight:700;margin:0;opacity:.95}.iv2-empty-sub{font-size:.72rem;margin:0;opacity:.65}.iv2-skeleton{padding:10px 14px 8px}.iv2-sk-row{display:flex;gap:12px;align-items:center}.iv2-sk-line{height:12px;border-radius:6px;background-size:200% 100%;animation:shimmer 1.5s infinite}.iv2-sk-line--long{flex:1}.iv2-sk-line--short{width:36px;flex-shrink:0}.bg-warning-line,.bg-alert-line{background:linear-gradient(90deg,#f9a825 25%,#fff59d,#f9a825 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-danger-line{background:linear-gradient(90deg,#c62828 25%,#ffcdd2,#c62828 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-info-line{background:linear-gradient(90deg,#1e88e5 25%,#90caf9,#1e88e5 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-success-line{background:linear-gradient(90deg,#2e7d32 25%,#a5d6a7,#2e7d32 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}@keyframes shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"] }]
1614
+ }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], titulo: [{ type: i0.Input, args: [{ isSignal: true, alias: "titulo", required: false }] }], textClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "textClass", required: false }] }], colorClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorClass", required: false }] }], keyValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyValue", required: false }] }], keyDescri: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyDescri", required: false }] }], complemento: [{ type: i0.Input, args: [{ isSignal: true, alias: "complemento", required: false }] }], isDesplegable: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDesplegable", required: false }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], viewMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewMode", required: false }] }], emit: [{ type: i0.Output, args: ["emit"] }], emitContent: [{ type: i0.Output, args: ["emitContent"] }] } });
1622
1615
 
1623
1616
  class ItemDashboardGroupComponent {
1624
- data = input([]);
1625
- titulo = input('');
1626
- textClass = input('text-white');
1627
- colorClass = input('');
1628
- keyValue = input('value');
1629
- keyDescri = input('descri');
1630
- complemento = input('');
1631
- isDesplegable = input(false);
1632
- isLoading = input(false);
1633
- viewMode = input('cards');
1634
- showContent = signal(false);
1617
+ data = input([], ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
1618
+ titulo = input('', ...(ngDevMode ? [{ debugName: "titulo" }] : /* istanbul ignore next */ []));
1619
+ textClass = input('text-white', ...(ngDevMode ? [{ debugName: "textClass" }] : /* istanbul ignore next */ []));
1620
+ colorClass = input('', ...(ngDevMode ? [{ debugName: "colorClass" }] : /* istanbul ignore next */ []));
1621
+ keyValue = input('value', ...(ngDevMode ? [{ debugName: "keyValue" }] : /* istanbul ignore next */ []));
1622
+ keyDescri = input('descri', ...(ngDevMode ? [{ debugName: "keyDescri" }] : /* istanbul ignore next */ []));
1623
+ complemento = input('', ...(ngDevMode ? [{ debugName: "complemento" }] : /* istanbul ignore next */ []));
1624
+ isDesplegable = input(false, ...(ngDevMode ? [{ debugName: "isDesplegable" }] : /* istanbul ignore next */ []));
1625
+ isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
1626
+ viewMode = input('cards', ...(ngDevMode ? [{ debugName: "viewMode" }] : /* istanbul ignore next */ []));
1627
+ showContent = signal(false, ...(ngDevMode ? [{ debugName: "showContent" }] : /* istanbul ignore next */ []));
1635
1628
  emit = output();
1636
1629
  emitContent = output();
1637
- dataGroup = computed(() => this.groupBy(this.data(), 'GROUP'));
1630
+ dataGroup = computed(() => this.groupBy(this.data(), 'GROUP'), ...(ngDevMode ? [{ debugName: "dataGroup" }] : /* istanbul ignore next */ []));
1638
1631
  filteredDataGroup = computed(() => {
1639
1632
  const grouped = this.dataGroup();
1640
1633
  const result = {};
@@ -1644,15 +1637,15 @@ class ItemDashboardGroupComponent {
1644
1637
  result[key] = items;
1645
1638
  }
1646
1639
  return result;
1647
- });
1648
- totalItems = computed(() => this.data().reduce((sum, item) => sum + (item[this.keyValue()] || 0), 0));
1640
+ }, ...(ngDevMode ? [{ debugName: "filteredDataGroup" }] : /* istanbul ignore next */ []));
1641
+ totalItems = computed(() => this.data().reduce((sum, item) => sum + (item[this.keyValue()] || 0), 0), ...(ngDevMode ? [{ debugName: "totalItems" }] : /* istanbul ignore next */ []));
1649
1642
  maxValue = computed(() => {
1650
1643
  const vals = this.data()
1651
1644
  .filter((item) => item[this.keyValue()] > 0)
1652
1645
  .map((item) => item[this.keyValue()] || 0);
1653
1646
  return vals.length > 0 ? Math.max(...vals) : 1;
1654
- });
1655
- hasData = computed(() => Object.keys(this.filteredDataGroup()).length > 0);
1647
+ }, ...(ngDevMode ? [{ debugName: "maxValue" }] : /* istanbul ignore next */ []));
1648
+ hasData = computed(() => Object.keys(this.filteredDataGroup()).length > 0, ...(ngDevMode ? [{ debugName: "hasData" }] : /* istanbul ignore next */ []));
1656
1649
  getPercent(item) {
1657
1650
  const max = this.maxValue();
1658
1651
  return max === 0 ? 0 : Math.round((item[this.keyValue()] / max) * 100);
@@ -1676,26 +1669,26 @@ class ItemDashboardGroupComponent {
1676
1669
  return acc;
1677
1670
  }, {});
1678
1671
  }
1679
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: ItemDashboardGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1680
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: ItemDashboardGroupComponent, isStandalone: true, selector: "app-item-dashboard-group", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, titulo: { classPropertyName: "titulo", publicName: "titulo", isSignal: true, isRequired: false, transformFunction: null }, textClass: { classPropertyName: "textClass", publicName: "textClass", isSignal: true, isRequired: false, transformFunction: null }, colorClass: { classPropertyName: "colorClass", publicName: "colorClass", isSignal: true, isRequired: false, transformFunction: null }, keyValue: { classPropertyName: "keyValue", publicName: "keyValue", isSignal: true, isRequired: false, transformFunction: null }, keyDescri: { classPropertyName: "keyDescri", publicName: "keyDescri", isSignal: true, isRequired: false, transformFunction: null }, complemento: { classPropertyName: "complemento", publicName: "complemento", isSignal: true, isRequired: false, transformFunction: null }, isDesplegable: { classPropertyName: "isDesplegable", publicName: "isDesplegable", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, viewMode: { classPropertyName: "viewMode", publicName: "viewMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { emit: "emit", emitContent: "emitContent" }, ngImport: i0, template: "<div class=\"iv2-card mb-2\" [ngClass]=\"colorClass() ? colorClass() : 'bg-danger'\">\r\n\r\n <!-- \u2500\u2500 HEADER \u2500\u2500 -->\r\n <div class=\"iv2-header\">\r\n\r\n <div class=\"iv2-icon-dot\"></div>\r\n\r\n <div class=\"iv2-title-wrap\">\r\n <h5 class=\"iv2-title\" [ngClass]=\"textClass()\">{{ titulo() }}</h5>\r\n </div>\r\n\r\n @if (isDesplegable()) {\r\n <button class=\"iv2-toggle-btn\" [ngClass]=\"textClass()\" (click)=\"toggleMostrar()\"\r\n [attr.aria-expanded]=\"showContent()\">\r\n <svg class=\"iv2-chevron\" [class.iv2-chevron--open]=\"showContent()\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- \u2500\u2500 CONTENIDO (expandible) \u2500\u2500 -->\r\n <div class=\"iv2-content\" [class.iv2-content--expanded]=\"showContent() || !isDesplegable()\">\r\n <div class=\"iv2-inner\">\r\n\r\n <!-- SKELETON -->\r\n @if (isLoading()) {\r\n <div class=\"iv2-skeleton\">\r\n <div class=\"iv2-sk-row\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n <div class=\"iv2-sk-row mt-2\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n <div class=\"iv2-sk-row mt-2\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n </div>\r\n\r\n } @else {\r\n\r\n <!-- \u2550\u2550 CARDS \u2550\u2550 -->\r\n @if (viewMode() === 'cards') {\r\n @if (hasData()) {\r\n <ul class=\"iv2-list\">\r\n @for (group of filteredDataGroup() | keyvalue; track group.key) {\r\n\r\n <li class=\"iv2-group-header\">\r\n <span class=\"iv2-group-label\" [ngClass]=\"textClass()\">{{ group.key }}</span>\r\n <div class=\"iv2-group-divider\"></div>\r\n </li>\r\n\r\n @for (item of group.value; track $index) {\r\n <li class=\"iv2-item\" [class.iv2-item--clickable]=\"item[keyValue()] > 0\"\r\n (click)=\"item[keyValue()] > 0 && mover(item)\">\r\n <div class=\"iv2-item-info\">\r\n <span class=\"iv2-item-label\" [ngClass]=\"textClass()\">{{ item[keyDescri()] }}</span>\r\n <div class=\"iv2-bar-track\">\r\n <div class=\"iv2-bar-fill\" [style.width.%]=\"getPercent(item)\"></div>\r\n </div>\r\n </div>\r\n <div class=\"iv2-item-right\">\r\n <span class=\"iv2-value-badge\">{{ complemento() }}{{ item[keyValue()] | number: '1.2-2' }}</span>\r\n </div>\r\n </li>\r\n }\r\n\r\n }\r\n </ul>\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- \u2550\u2550 BARRAS \u2550\u2550 -->\r\n @if (viewMode() === 'bars') {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">En implementaci\u00F3n</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Muy pronto</p>\r\n </div>\r\n }\r\n\r\n <!-- \u2550\u2550 DONA \u2550\u2550 -->\r\n @if (viewMode() === 'donut') {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">En implementaci\u00F3n</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Muy pronto</p>\r\n </div>\r\n }\r\n\r\n }\r\n\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".iv2-card{border-radius:16px;border:1px solid rgba(255,255,255,.18);overflow:hidden;transition:transform .2s ease,box-shadow .2s ease;animation:iv2CardSlideIn .22s cubic-bezier(.25,.46,.45,.94) both}.iv2-card:hover{transform:translateY(-2px)}@keyframes iv2CardSlideIn{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}.bg-danger{background:linear-gradient(145deg,#ff4b2b,#dc3545)!important;box-shadow:0 8px 24px #dc354559;border-color:#ffffff26}.bg-success{background:linear-gradient(135deg,#2ecc71,#00cc6a)!important;box-shadow:0 8px 24px #15734759;border-color:#ffffff26}.bg-warning{background:linear-gradient(135deg,#f60,#fa9600)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.bg-info{background:linear-gradient(135deg,#4b84ff,#1b6ad8)!important;box-shadow:0 8px 24px #1b6ad859;border-color:#ffffff26}.bg-alert{background:linear-gradient(135deg,#ffc400,#fa0)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.iv2-header{display:flex;align-items:center;gap:10px;padding:14px 16px 12px}.iv2-icon-dot{width:8px;height:8px;border-radius:50%;background:#ffffff80;flex-shrink:0;animation:pulse-dot 2s ease-in-out infinite}@keyframes pulse-dot{0%,to{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.3)}}.iv2-title-wrap{flex:1;display:flex;align-items:center;gap:8px;min-width:0}.iv2-title{font-size:.82rem;font-weight:700;letter-spacing:.02em;margin:0;line-height:1.3;flex:1;min-width:0}.iv2-total-badge{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:22px;padding:0 7px;border-radius:999px;background:#ffffff40;color:#fff;font-size:.72rem;font-weight:700;letter-spacing:.01em;backdrop-filter:blur(4px);border:1px solid rgba(255,255,255,.35);flex-shrink:0;animation:badge-pop .3s cubic-bezier(.34,1.56,.64,1)}@keyframes badge-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}.iv2-toggle-btn{background:#ffffff26;border:1px solid rgba(255,255,255,.25);border-radius:8px;width:30px;height:30px;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .2s ease;padding:0}.iv2-toggle-btn:hover{background:#ffffff47}.iv2-chevron{width:16px;height:16px;transition:transform .3s cubic-bezier(.4,0,.2,1)}.iv2-chevron--open{transform:rotate(180deg)}.iv2-content{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4,0,.2,1),opacity .25s ease;opacity:0}.iv2-content--expanded{max-height:1000px;opacity:1}.iv2-inner{background:#0000001f;backdrop-filter:blur(6px);border-top:1px solid rgba(255,255,255,.15);padding:4px 0 6px}.iv2-list{list-style:none;margin:0;padding:0}.iv2-group-header{display:flex;align-items:center;gap:8px;padding:10px 14px 6px}.iv2-group-label{font-size:.7rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;flex-shrink:0}.iv2-group-divider{flex:1;height:1px;background:#ffffff40}.iv2-item{display:flex;align-items:center;gap:10px;padding:9px 14px;border-top:1px solid rgba(255,255,255,.08);transition:background .2s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1)}.iv2-item--clickable{cursor:pointer}.iv2-item--clickable:hover{background:#ffffff1f}.iv2-item--clickable:active{transform:scale(.985);background:#ffffff2e}.iv2-item-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}.iv2-item-label{font-size:.78rem;font-weight:600;line-height:1.3;white-space:normal;word-break:break-word}.iv2-bar-track{height:3px;border-radius:99px;background:#fff3;overflow:hidden}.iv2-bar-fill{height:100%;border-radius:99px;background:#fff9;transition:width .6s cubic-bezier(.4,0,.2,1)}.iv2-item-right{display:flex;align-items:center;gap:6px;flex-shrink:0}.iv2-value-badge{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:26px;padding:0 9px;border-radius:999px;background:#ffffffe6;color:#333;font-size:.78rem;font-weight:700;letter-spacing:.01em;box-shadow:0 2px 6px #00000026}.iv2-empty{display:flex;flex-direction:column;align-items:center;padding:20px 16px 18px;gap:4px}.iv2-empty-icon{width:40px;height:40px;border-radius:50%;background:#fff3;border:1.5px solid rgba(255,255,255,.4);display:flex;align-items:center;justify-content:center;margin-bottom:6px}.iv2-empty-icon svg{width:20px;height:20px;color:#fff}.iv2-empty-title{font-size:.82rem;font-weight:700;margin:0;opacity:.95}.iv2-empty-sub{font-size:.72rem;margin:0;opacity:.65}.iv2-skeleton{padding:10px 14px 8px}.iv2-sk-row{display:flex;gap:12px;align-items:center}.iv2-sk-line{height:12px;border-radius:6px;background-size:200% 100%;animation:shimmer 1.5s infinite}.iv2-sk-line--long{flex:1}.iv2-sk-line--short{width:36px;flex-shrink:0}.bg-warning-line,.bg-alert-line{background:linear-gradient(90deg,#f9a825 25%,#fff59d,#f9a825 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-danger-line{background:linear-gradient(90deg,#c62828 25%,#ffcdd2,#c62828 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-info-line{background:linear-gradient(90deg,#1e88e5 25%,#90caf9,#1e88e5 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-success-line{background:linear-gradient(90deg,#2e7d32 25%,#a5d6a7,#2e7d32 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}@keyframes shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: DecimalPipe, name: "number" }] });
1672
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: ItemDashboardGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1673
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: ItemDashboardGroupComponent, isStandalone: true, selector: "app-item-dashboard-group", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, titulo: { classPropertyName: "titulo", publicName: "titulo", isSignal: true, isRequired: false, transformFunction: null }, textClass: { classPropertyName: "textClass", publicName: "textClass", isSignal: true, isRequired: false, transformFunction: null }, colorClass: { classPropertyName: "colorClass", publicName: "colorClass", isSignal: true, isRequired: false, transformFunction: null }, keyValue: { classPropertyName: "keyValue", publicName: "keyValue", isSignal: true, isRequired: false, transformFunction: null }, keyDescri: { classPropertyName: "keyDescri", publicName: "keyDescri", isSignal: true, isRequired: false, transformFunction: null }, complemento: { classPropertyName: "complemento", publicName: "complemento", isSignal: true, isRequired: false, transformFunction: null }, isDesplegable: { classPropertyName: "isDesplegable", publicName: "isDesplegable", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, viewMode: { classPropertyName: "viewMode", publicName: "viewMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { emit: "emit", emitContent: "emitContent" }, ngImport: i0, template: "<div class=\"iv2-card mb-2\" [ngClass]=\"colorClass() ? colorClass() : 'bg-danger'\">\r\n\r\n <!-- \u2500\u2500 HEADER \u2500\u2500 -->\r\n <div class=\"iv2-header\">\r\n\r\n <div class=\"iv2-icon-dot\"></div>\r\n\r\n <div class=\"iv2-title-wrap\">\r\n <h5 class=\"iv2-title\" [ngClass]=\"textClass()\">{{ titulo() }}</h5>\r\n </div>\r\n\r\n @if (isDesplegable()) {\r\n <button class=\"iv2-toggle-btn\" [ngClass]=\"textClass()\" (click)=\"toggleMostrar()\"\r\n [attr.aria-expanded]=\"showContent()\">\r\n <svg class=\"iv2-chevron\" [class.iv2-chevron--open]=\"showContent()\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- \u2500\u2500 CONTENIDO (expandible) \u2500\u2500 -->\r\n <div class=\"iv2-content\" [class.iv2-content--expanded]=\"showContent() || !isDesplegable()\">\r\n <div class=\"iv2-inner\">\r\n\r\n <!-- SKELETON -->\r\n @if (isLoading()) {\r\n <div class=\"iv2-skeleton\">\r\n <div class=\"iv2-sk-row\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n <div class=\"iv2-sk-row mt-2\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n <div class=\"iv2-sk-row mt-2\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n </div>\r\n\r\n } @else {\r\n\r\n <!-- \u2550\u2550 CARDS \u2550\u2550 -->\r\n @if (viewMode() === 'cards') {\r\n @if (hasData()) {\r\n <ul class=\"iv2-list\">\r\n @for (group of filteredDataGroup() | keyvalue; track group.key) {\r\n\r\n <li class=\"iv2-group-header\">\r\n <span class=\"iv2-group-label\" [ngClass]=\"textClass()\">{{ group.key }}</span>\r\n <div class=\"iv2-group-divider\"></div>\r\n </li>\r\n\r\n @for (item of group.value; track $index) {\r\n <li class=\"iv2-item\" [class.iv2-item--clickable]=\"item[keyValue()] > 0\"\r\n (click)=\"item[keyValue()] > 0 && mover(item)\">\r\n <div class=\"iv2-item-info\">\r\n <span class=\"iv2-item-label\" [ngClass]=\"textClass()\">{{ item[keyDescri()] }}</span>\r\n <div class=\"iv2-bar-track\">\r\n <div class=\"iv2-bar-fill\" [style.width.%]=\"getPercent(item)\"></div>\r\n </div>\r\n </div>\r\n <div class=\"iv2-item-right\">\r\n <span class=\"iv2-value-badge\">{{ complemento() }}{{ item[keyValue()] | number: '1.2-2' }}</span>\r\n </div>\r\n </li>\r\n }\r\n\r\n }\r\n </ul>\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- \u2550\u2550 BARRAS \u2550\u2550 -->\r\n @if (viewMode() === 'bars') {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">En implementaci\u00F3n</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Muy pronto</p>\r\n </div>\r\n }\r\n\r\n <!-- \u2550\u2550 DONA \u2550\u2550 -->\r\n @if (viewMode() === 'donut') {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">En implementaci\u00F3n</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Muy pronto</p>\r\n </div>\r\n }\r\n\r\n }\r\n\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".iv2-card{border-radius:16px;border:1px solid rgba(255,255,255,.18);overflow:hidden;transition:transform .2s ease,box-shadow .2s ease;animation:iv2CardSlideIn .22s cubic-bezier(.25,.46,.45,.94) both}.iv2-card:hover{transform:translateY(-2px)}@keyframes iv2CardSlideIn{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}.bg-danger{background:linear-gradient(145deg,#ff4b2b,#dc3545)!important;box-shadow:0 8px 24px #dc354559;border-color:#ffffff26}.bg-success{background:linear-gradient(135deg,#2ecc71,#00cc6a)!important;box-shadow:0 8px 24px #15734759;border-color:#ffffff26}.bg-warning{background:linear-gradient(135deg,#f60,#fa9600)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.bg-info{background:linear-gradient(135deg,#4b84ff,#1b6ad8)!important;box-shadow:0 8px 24px #1b6ad859;border-color:#ffffff26}.bg-alert{background:linear-gradient(135deg,#ffc400,#fa0)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.iv2-header{display:flex;align-items:center;gap:10px;padding:14px 16px 12px}.iv2-icon-dot{width:8px;height:8px;border-radius:50%;background:#ffffff80;flex-shrink:0;animation:pulse-dot 2s ease-in-out infinite}@keyframes pulse-dot{0%,to{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.3)}}.iv2-title-wrap{flex:1;display:flex;align-items:center;gap:8px;min-width:0}.iv2-title{font-size:.82rem;font-weight:700;letter-spacing:.02em;margin:0;line-height:1.3;flex:1;min-width:0}.iv2-total-badge{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:22px;padding:0 7px;border-radius:999px;background:#ffffff40;color:#fff;font-size:.72rem;font-weight:700;letter-spacing:.01em;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border:1px solid rgba(255,255,255,.35);flex-shrink:0;animation:badge-pop .3s cubic-bezier(.34,1.56,.64,1)}@keyframes badge-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}.iv2-toggle-btn{background:#ffffff26;border:1px solid rgba(255,255,255,.25);border-radius:8px;width:30px;height:30px;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .2s ease;padding:0}.iv2-toggle-btn:hover{background:#ffffff47}.iv2-chevron{width:16px;height:16px;transition:transform .3s cubic-bezier(.4,0,.2,1)}.iv2-chevron--open{transform:rotate(180deg)}.iv2-content{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4,0,.2,1),opacity .25s ease;opacity:0}.iv2-content--expanded{max-height:1000px;opacity:1}.iv2-inner{background:#0000001f;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border-top:1px solid rgba(255,255,255,.15);padding:4px 0 6px}.iv2-list{list-style:none;margin:0;padding:0}.iv2-group-header{display:flex;align-items:center;gap:8px;padding:10px 14px 6px}.iv2-group-label{font-size:.7rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;flex-shrink:0}.iv2-group-divider{flex:1;height:1px;background:#ffffff40}.iv2-item{display:flex;align-items:center;gap:10px;padding:9px 14px;border-top:1px solid rgba(255,255,255,.08);transition:background .2s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1)}.iv2-item--clickable{cursor:pointer}.iv2-item--clickable:hover{background:#ffffff1f}.iv2-item--clickable:active{transform:scale(.985);background:#ffffff2e}.iv2-item-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}.iv2-item-label{font-size:.78rem;font-weight:600;line-height:1.3;white-space:normal;word-break:break-word}.iv2-bar-track{height:3px;border-radius:99px;background:#fff3;overflow:hidden}.iv2-bar-fill{height:100%;border-radius:99px;background:#fff9;transition:width .6s cubic-bezier(.4,0,.2,1)}.iv2-item-right{display:flex;align-items:center;gap:6px;flex-shrink:0}.iv2-value-badge{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:26px;padding:0 9px;border-radius:999px;background:#ffffffe6;color:#333;font-size:.78rem;font-weight:700;letter-spacing:.01em;box-shadow:0 2px 6px #00000026}.iv2-empty{display:flex;flex-direction:column;align-items:center;padding:20px 16px 18px;gap:4px}.iv2-empty-icon{width:40px;height:40px;border-radius:50%;background:#fff3;border:1.5px solid rgba(255,255,255,.4);display:flex;align-items:center;justify-content:center;margin-bottom:6px}.iv2-empty-icon svg{width:20px;height:20px;color:#fff}.iv2-empty-title{font-size:.82rem;font-weight:700;margin:0;opacity:.95}.iv2-empty-sub{font-size:.72rem;margin:0;opacity:.65}.iv2-skeleton{padding:10px 14px 8px}.iv2-sk-row{display:flex;gap:12px;align-items:center}.iv2-sk-line{height:12px;border-radius:6px;background-size:200% 100%;animation:shimmer 1.5s infinite}.iv2-sk-line--long{flex:1}.iv2-sk-line--short{width:36px;flex-shrink:0}.bg-warning-line,.bg-alert-line{background:linear-gradient(90deg,#f9a825 25%,#fff59d,#f9a825 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-danger-line{background:linear-gradient(90deg,#c62828 25%,#ffcdd2,#c62828 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-info-line{background:linear-gradient(90deg,#1e88e5 25%,#90caf9,#1e88e5 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-success-line{background:linear-gradient(90deg,#2e7d32 25%,#a5d6a7,#2e7d32 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}@keyframes shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: DecimalPipe, name: "number" }] });
1681
1674
  }
1682
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: ItemDashboardGroupComponent, decorators: [{
1675
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: ItemDashboardGroupComponent, decorators: [{
1683
1676
  type: Component,
1684
- args: [{ selector: 'app-item-dashboard-group', imports: [NgClass, KeyValuePipe, DecimalPipe], template: "<div class=\"iv2-card mb-2\" [ngClass]=\"colorClass() ? colorClass() : 'bg-danger'\">\r\n\r\n <!-- \u2500\u2500 HEADER \u2500\u2500 -->\r\n <div class=\"iv2-header\">\r\n\r\n <div class=\"iv2-icon-dot\"></div>\r\n\r\n <div class=\"iv2-title-wrap\">\r\n <h5 class=\"iv2-title\" [ngClass]=\"textClass()\">{{ titulo() }}</h5>\r\n </div>\r\n\r\n @if (isDesplegable()) {\r\n <button class=\"iv2-toggle-btn\" [ngClass]=\"textClass()\" (click)=\"toggleMostrar()\"\r\n [attr.aria-expanded]=\"showContent()\">\r\n <svg class=\"iv2-chevron\" [class.iv2-chevron--open]=\"showContent()\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- \u2500\u2500 CONTENIDO (expandible) \u2500\u2500 -->\r\n <div class=\"iv2-content\" [class.iv2-content--expanded]=\"showContent() || !isDesplegable()\">\r\n <div class=\"iv2-inner\">\r\n\r\n <!-- SKELETON -->\r\n @if (isLoading()) {\r\n <div class=\"iv2-skeleton\">\r\n <div class=\"iv2-sk-row\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n <div class=\"iv2-sk-row mt-2\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n <div class=\"iv2-sk-row mt-2\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n </div>\r\n\r\n } @else {\r\n\r\n <!-- \u2550\u2550 CARDS \u2550\u2550 -->\r\n @if (viewMode() === 'cards') {\r\n @if (hasData()) {\r\n <ul class=\"iv2-list\">\r\n @for (group of filteredDataGroup() | keyvalue; track group.key) {\r\n\r\n <li class=\"iv2-group-header\">\r\n <span class=\"iv2-group-label\" [ngClass]=\"textClass()\">{{ group.key }}</span>\r\n <div class=\"iv2-group-divider\"></div>\r\n </li>\r\n\r\n @for (item of group.value; track $index) {\r\n <li class=\"iv2-item\" [class.iv2-item--clickable]=\"item[keyValue()] > 0\"\r\n (click)=\"item[keyValue()] > 0 && mover(item)\">\r\n <div class=\"iv2-item-info\">\r\n <span class=\"iv2-item-label\" [ngClass]=\"textClass()\">{{ item[keyDescri()] }}</span>\r\n <div class=\"iv2-bar-track\">\r\n <div class=\"iv2-bar-fill\" [style.width.%]=\"getPercent(item)\"></div>\r\n </div>\r\n </div>\r\n <div class=\"iv2-item-right\">\r\n <span class=\"iv2-value-badge\">{{ complemento() }}{{ item[keyValue()] | number: '1.2-2' }}</span>\r\n </div>\r\n </li>\r\n }\r\n\r\n }\r\n </ul>\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- \u2550\u2550 BARRAS \u2550\u2550 -->\r\n @if (viewMode() === 'bars') {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">En implementaci\u00F3n</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Muy pronto</p>\r\n </div>\r\n }\r\n\r\n <!-- \u2550\u2550 DONA \u2550\u2550 -->\r\n @if (viewMode() === 'donut') {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">En implementaci\u00F3n</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Muy pronto</p>\r\n </div>\r\n }\r\n\r\n }\r\n\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".iv2-card{border-radius:16px;border:1px solid rgba(255,255,255,.18);overflow:hidden;transition:transform .2s ease,box-shadow .2s ease;animation:iv2CardSlideIn .22s cubic-bezier(.25,.46,.45,.94) both}.iv2-card:hover{transform:translateY(-2px)}@keyframes iv2CardSlideIn{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}.bg-danger{background:linear-gradient(145deg,#ff4b2b,#dc3545)!important;box-shadow:0 8px 24px #dc354559;border-color:#ffffff26}.bg-success{background:linear-gradient(135deg,#2ecc71,#00cc6a)!important;box-shadow:0 8px 24px #15734759;border-color:#ffffff26}.bg-warning{background:linear-gradient(135deg,#f60,#fa9600)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.bg-info{background:linear-gradient(135deg,#4b84ff,#1b6ad8)!important;box-shadow:0 8px 24px #1b6ad859;border-color:#ffffff26}.bg-alert{background:linear-gradient(135deg,#ffc400,#fa0)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.iv2-header{display:flex;align-items:center;gap:10px;padding:14px 16px 12px}.iv2-icon-dot{width:8px;height:8px;border-radius:50%;background:#ffffff80;flex-shrink:0;animation:pulse-dot 2s ease-in-out infinite}@keyframes pulse-dot{0%,to{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.3)}}.iv2-title-wrap{flex:1;display:flex;align-items:center;gap:8px;min-width:0}.iv2-title{font-size:.82rem;font-weight:700;letter-spacing:.02em;margin:0;line-height:1.3;flex:1;min-width:0}.iv2-total-badge{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:22px;padding:0 7px;border-radius:999px;background:#ffffff40;color:#fff;font-size:.72rem;font-weight:700;letter-spacing:.01em;backdrop-filter:blur(4px);border:1px solid rgba(255,255,255,.35);flex-shrink:0;animation:badge-pop .3s cubic-bezier(.34,1.56,.64,1)}@keyframes badge-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}.iv2-toggle-btn{background:#ffffff26;border:1px solid rgba(255,255,255,.25);border-radius:8px;width:30px;height:30px;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .2s ease;padding:0}.iv2-toggle-btn:hover{background:#ffffff47}.iv2-chevron{width:16px;height:16px;transition:transform .3s cubic-bezier(.4,0,.2,1)}.iv2-chevron--open{transform:rotate(180deg)}.iv2-content{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4,0,.2,1),opacity .25s ease;opacity:0}.iv2-content--expanded{max-height:1000px;opacity:1}.iv2-inner{background:#0000001f;backdrop-filter:blur(6px);border-top:1px solid rgba(255,255,255,.15);padding:4px 0 6px}.iv2-list{list-style:none;margin:0;padding:0}.iv2-group-header{display:flex;align-items:center;gap:8px;padding:10px 14px 6px}.iv2-group-label{font-size:.7rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;flex-shrink:0}.iv2-group-divider{flex:1;height:1px;background:#ffffff40}.iv2-item{display:flex;align-items:center;gap:10px;padding:9px 14px;border-top:1px solid rgba(255,255,255,.08);transition:background .2s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1)}.iv2-item--clickable{cursor:pointer}.iv2-item--clickable:hover{background:#ffffff1f}.iv2-item--clickable:active{transform:scale(.985);background:#ffffff2e}.iv2-item-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}.iv2-item-label{font-size:.78rem;font-weight:600;line-height:1.3;white-space:normal;word-break:break-word}.iv2-bar-track{height:3px;border-radius:99px;background:#fff3;overflow:hidden}.iv2-bar-fill{height:100%;border-radius:99px;background:#fff9;transition:width .6s cubic-bezier(.4,0,.2,1)}.iv2-item-right{display:flex;align-items:center;gap:6px;flex-shrink:0}.iv2-value-badge{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:26px;padding:0 9px;border-radius:999px;background:#ffffffe6;color:#333;font-size:.78rem;font-weight:700;letter-spacing:.01em;box-shadow:0 2px 6px #00000026}.iv2-empty{display:flex;flex-direction:column;align-items:center;padding:20px 16px 18px;gap:4px}.iv2-empty-icon{width:40px;height:40px;border-radius:50%;background:#fff3;border:1.5px solid rgba(255,255,255,.4);display:flex;align-items:center;justify-content:center;margin-bottom:6px}.iv2-empty-icon svg{width:20px;height:20px;color:#fff}.iv2-empty-title{font-size:.82rem;font-weight:700;margin:0;opacity:.95}.iv2-empty-sub{font-size:.72rem;margin:0;opacity:.65}.iv2-skeleton{padding:10px 14px 8px}.iv2-sk-row{display:flex;gap:12px;align-items:center}.iv2-sk-line{height:12px;border-radius:6px;background-size:200% 100%;animation:shimmer 1.5s infinite}.iv2-sk-line--long{flex:1}.iv2-sk-line--short{width:36px;flex-shrink:0}.bg-warning-line,.bg-alert-line{background:linear-gradient(90deg,#f9a825 25%,#fff59d,#f9a825 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-danger-line{background:linear-gradient(90deg,#c62828 25%,#ffcdd2,#c62828 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-info-line{background:linear-gradient(90deg,#1e88e5 25%,#90caf9,#1e88e5 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-success-line{background:linear-gradient(90deg,#2e7d32 25%,#a5d6a7,#2e7d32 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}@keyframes shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"] }]
1685
- }] });
1677
+ args: [{ selector: 'app-item-dashboard-group', imports: [NgClass, KeyValuePipe, DecimalPipe], template: "<div class=\"iv2-card mb-2\" [ngClass]=\"colorClass() ? colorClass() : 'bg-danger'\">\r\n\r\n <!-- \u2500\u2500 HEADER \u2500\u2500 -->\r\n <div class=\"iv2-header\">\r\n\r\n <div class=\"iv2-icon-dot\"></div>\r\n\r\n <div class=\"iv2-title-wrap\">\r\n <h5 class=\"iv2-title\" [ngClass]=\"textClass()\">{{ titulo() }}</h5>\r\n </div>\r\n\r\n @if (isDesplegable()) {\r\n <button class=\"iv2-toggle-btn\" [ngClass]=\"textClass()\" (click)=\"toggleMostrar()\"\r\n [attr.aria-expanded]=\"showContent()\">\r\n <svg class=\"iv2-chevron\" [class.iv2-chevron--open]=\"showContent()\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- \u2500\u2500 CONTENIDO (expandible) \u2500\u2500 -->\r\n <div class=\"iv2-content\" [class.iv2-content--expanded]=\"showContent() || !isDesplegable()\">\r\n <div class=\"iv2-inner\">\r\n\r\n <!-- SKELETON -->\r\n @if (isLoading()) {\r\n <div class=\"iv2-skeleton\">\r\n <div class=\"iv2-sk-row\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n <div class=\"iv2-sk-row mt-2\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n <div class=\"iv2-sk-row mt-2\">\r\n <div class=\"iv2-sk-line iv2-sk-line--long\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n <div class=\"iv2-sk-line iv2-sk-line--short\" [ngClass]=\"colorClass() + '-line'\"></div>\r\n </div>\r\n </div>\r\n\r\n } @else {\r\n\r\n <!-- \u2550\u2550 CARDS \u2550\u2550 -->\r\n @if (viewMode() === 'cards') {\r\n @if (hasData()) {\r\n <ul class=\"iv2-list\">\r\n @for (group of filteredDataGroup() | keyvalue; track group.key) {\r\n\r\n <li class=\"iv2-group-header\">\r\n <span class=\"iv2-group-label\" [ngClass]=\"textClass()\">{{ group.key }}</span>\r\n <div class=\"iv2-group-divider\"></div>\r\n </li>\r\n\r\n @for (item of group.value; track $index) {\r\n <li class=\"iv2-item\" [class.iv2-item--clickable]=\"item[keyValue()] > 0\"\r\n (click)=\"item[keyValue()] > 0 && mover(item)\">\r\n <div class=\"iv2-item-info\">\r\n <span class=\"iv2-item-label\" [ngClass]=\"textClass()\">{{ item[keyDescri()] }}</span>\r\n <div class=\"iv2-bar-track\">\r\n <div class=\"iv2-bar-fill\" [style.width.%]=\"getPercent(item)\"></div>\r\n </div>\r\n </div>\r\n <div class=\"iv2-item-right\">\r\n <span class=\"iv2-value-badge\">{{ complemento() }}{{ item[keyValue()] | number: '1.2-2' }}</span>\r\n </div>\r\n </li>\r\n }\r\n\r\n }\r\n </ul>\r\n } @else {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">Todo al d\u00EDa</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Sin pendientes por el momento</p>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- \u2550\u2550 BARRAS \u2550\u2550 -->\r\n @if (viewMode() === 'bars') {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">En implementaci\u00F3n</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Muy pronto</p>\r\n </div>\r\n }\r\n\r\n <!-- \u2550\u2550 DONA \u2550\u2550 -->\r\n @if (viewMode() === 'donut') {\r\n <div class=\"iv2-empty\">\r\n <div class=\"iv2-empty-icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg></div>\r\n <p class=\"iv2-empty-title\" [ngClass]=\"textClass()\">En implementaci\u00F3n</p>\r\n <p class=\"iv2-empty-sub\" [ngClass]=\"textClass()\">Muy pronto</p>\r\n </div>\r\n }\r\n\r\n }\r\n\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".iv2-card{border-radius:16px;border:1px solid rgba(255,255,255,.18);overflow:hidden;transition:transform .2s ease,box-shadow .2s ease;animation:iv2CardSlideIn .22s cubic-bezier(.25,.46,.45,.94) both}.iv2-card:hover{transform:translateY(-2px)}@keyframes iv2CardSlideIn{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}.bg-danger{background:linear-gradient(145deg,#ff4b2b,#dc3545)!important;box-shadow:0 8px 24px #dc354559;border-color:#ffffff26}.bg-success{background:linear-gradient(135deg,#2ecc71,#00cc6a)!important;box-shadow:0 8px 24px #15734759;border-color:#ffffff26}.bg-warning{background:linear-gradient(135deg,#f60,#fa9600)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.bg-info{background:linear-gradient(135deg,#4b84ff,#1b6ad8)!important;box-shadow:0 8px 24px #1b6ad859;border-color:#ffffff26}.bg-alert{background:linear-gradient(135deg,#ffc400,#fa0)!important;box-shadow:0 8px 24px #ed8f0359;border-color:#ffffff26}.iv2-header{display:flex;align-items:center;gap:10px;padding:14px 16px 12px}.iv2-icon-dot{width:8px;height:8px;border-radius:50%;background:#ffffff80;flex-shrink:0;animation:pulse-dot 2s ease-in-out infinite}@keyframes pulse-dot{0%,to{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.3)}}.iv2-title-wrap{flex:1;display:flex;align-items:center;gap:8px;min-width:0}.iv2-title{font-size:.82rem;font-weight:700;letter-spacing:.02em;margin:0;line-height:1.3;flex:1;min-width:0}.iv2-total-badge{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:22px;padding:0 7px;border-radius:999px;background:#ffffff40;color:#fff;font-size:.72rem;font-weight:700;letter-spacing:.01em;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border:1px solid rgba(255,255,255,.35);flex-shrink:0;animation:badge-pop .3s cubic-bezier(.34,1.56,.64,1)}@keyframes badge-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}.iv2-toggle-btn{background:#ffffff26;border:1px solid rgba(255,255,255,.25);border-radius:8px;width:30px;height:30px;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .2s ease;padding:0}.iv2-toggle-btn:hover{background:#ffffff47}.iv2-chevron{width:16px;height:16px;transition:transform .3s cubic-bezier(.4,0,.2,1)}.iv2-chevron--open{transform:rotate(180deg)}.iv2-content{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4,0,.2,1),opacity .25s ease;opacity:0}.iv2-content--expanded{max-height:1000px;opacity:1}.iv2-inner{background:#0000001f;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border-top:1px solid rgba(255,255,255,.15);padding:4px 0 6px}.iv2-list{list-style:none;margin:0;padding:0}.iv2-group-header{display:flex;align-items:center;gap:8px;padding:10px 14px 6px}.iv2-group-label{font-size:.7rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;flex-shrink:0}.iv2-group-divider{flex:1;height:1px;background:#ffffff40}.iv2-item{display:flex;align-items:center;gap:10px;padding:9px 14px;border-top:1px solid rgba(255,255,255,.08);transition:background .2s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1)}.iv2-item--clickable{cursor:pointer}.iv2-item--clickable:hover{background:#ffffff1f}.iv2-item--clickable:active{transform:scale(.985);background:#ffffff2e}.iv2-item-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}.iv2-item-label{font-size:.78rem;font-weight:600;line-height:1.3;white-space:normal;word-break:break-word}.iv2-bar-track{height:3px;border-radius:99px;background:#fff3;overflow:hidden}.iv2-bar-fill{height:100%;border-radius:99px;background:#fff9;transition:width .6s cubic-bezier(.4,0,.2,1)}.iv2-item-right{display:flex;align-items:center;gap:6px;flex-shrink:0}.iv2-value-badge{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:26px;padding:0 9px;border-radius:999px;background:#ffffffe6;color:#333;font-size:.78rem;font-weight:700;letter-spacing:.01em;box-shadow:0 2px 6px #00000026}.iv2-empty{display:flex;flex-direction:column;align-items:center;padding:20px 16px 18px;gap:4px}.iv2-empty-icon{width:40px;height:40px;border-radius:50%;background:#fff3;border:1.5px solid rgba(255,255,255,.4);display:flex;align-items:center;justify-content:center;margin-bottom:6px}.iv2-empty-icon svg{width:20px;height:20px;color:#fff}.iv2-empty-title{font-size:.82rem;font-weight:700;margin:0;opacity:.95}.iv2-empty-sub{font-size:.72rem;margin:0;opacity:.65}.iv2-skeleton{padding:10px 14px 8px}.iv2-sk-row{display:flex;gap:12px;align-items:center}.iv2-sk-line{height:12px;border-radius:6px;background-size:200% 100%;animation:shimmer 1.5s infinite}.iv2-sk-line--long{flex:1}.iv2-sk-line--short{width:36px;flex-shrink:0}.bg-warning-line,.bg-alert-line{background:linear-gradient(90deg,#f9a825 25%,#fff59d,#f9a825 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-danger-line{background:linear-gradient(90deg,#c62828 25%,#ffcdd2,#c62828 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-info-line{background:linear-gradient(90deg,#1e88e5 25%,#90caf9,#1e88e5 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}.bg-success-line{background:linear-gradient(90deg,#2e7d32 25%,#a5d6a7,#2e7d32 75%);background-size:200% 100%;animation:shimmer 1.5s infinite}@keyframes shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"] }]
1678
+ }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], titulo: [{ type: i0.Input, args: [{ isSignal: true, alias: "titulo", required: false }] }], textClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "textClass", required: false }] }], colorClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorClass", required: false }] }], keyValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyValue", required: false }] }], keyDescri: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyDescri", required: false }] }], complemento: [{ type: i0.Input, args: [{ isSignal: true, alias: "complemento", required: false }] }], isDesplegable: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDesplegable", required: false }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], viewMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewMode", required: false }] }], emit: [{ type: i0.Output, args: ["emit"] }], emitContent: [{ type: i0.Output, args: ["emitContent"] }] } });
1686
1679
 
1687
1680
  // Duración de la animación de salida (@keyframes fabMiniOut en el scss): se
1688
1681
  // mantiene montado este tiempo antes de desmontarlo de verdad.
1689
1682
  const LEAVE_DURATION_MS = 150;
1690
1683
  class DashboardViewSwitcherComponent {
1691
- viewMode = input('cards');
1692
- accentColor = input('#398bf7');
1684
+ viewMode = input('cards', ...(ngDevMode ? [{ debugName: "viewMode" }] : /* istanbul ignore next */ []));
1685
+ accentColor = input('#398bf7', ...(ngDevMode ? [{ debugName: "accentColor" }] : /* istanbul ignore next */ []));
1693
1686
  viewModeChange = output();
1694
- fabOpen = signal(false);
1687
+ fabOpen = signal(false, ...(ngDevMode ? [{ debugName: "fabOpen" }] : /* istanbul ignore next */ []));
1695
1688
  // Reemplaza a @fabMenu (query + stagger, sin @angular/animations): el
1696
1689
  // stagger se logra con animation-delay por :nth-child en el scss, y la
1697
1690
  // salida se maneja igual que en tab-bar (mantener montado + clase "--closing").
1698
- fabRendered = signal(false);
1691
+ fabRendered = signal(false, ...(ngDevMode ? [{ debugName: "fabRendered" }] : /* istanbul ignore next */ []));
1699
1692
  closeTimer = null;
1700
1693
  constructor() {
1701
1694
  effect(() => {
@@ -1715,13 +1708,13 @@ class DashboardViewSwitcherComponent {
1715
1708
  this.viewModeChange.emit(mode);
1716
1709
  this.fabOpen.set(false);
1717
1710
  }
1718
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DashboardViewSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1719
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: DashboardViewSwitcherComponent, isStandalone: true, selector: "app-dashboard-view-switcher", inputs: { viewMode: { classPropertyName: "viewMode", publicName: "viewMode", isSignal: true, isRequired: false, transformFunction: null }, accentColor: { classPropertyName: "accentColor", publicName: "accentColor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { viewModeChange: "viewModeChange" }, ngImport: i0, template: "<div class=\"view-fab\" [style.--fab-main-from]=\"accentColor()\" [style.--fab-main-to]=\"accentColor()\"\r\n [style.--fab-active-bg]=\"accentColor()\" [style.--fab-mini-hover-border]=\"accentColor()\"\r\n [style.--fab-mini-hover-color]=\"accentColor()\" (mouseenter)=\"fabOpen.set(true)\" (mouseleave)=\"fabOpen.set(false)\">\r\n @if (fabRendered()) {\r\n <div class=\"fab-menu\" [class.fab-menu--closing]=\"!fabOpen()\">\r\n\r\n <div class=\"fab-mini-wrap\">\r\n <span class=\"fab-tooltip\">Dona</span>\r\n <button class=\"fab-mini\" [class.active]=\"viewMode() === 'donut'\" (click)=\"setView('donut')\"\r\n title=\"Vista de dona\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\r\n <circle cx=\"12\" cy=\"12\" r=\"4\"></circle>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fab-mini-wrap\">\r\n <span class=\"fab-tooltip\">Barras</span>\r\n <button class=\"fab-mini\" [class.active]=\"viewMode() === 'bars'\" (click)=\"setView('bars')\"\r\n title=\"Vista de barras\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"2\" y=\"13\" width=\"5\" height=\"9\" rx=\"1\"></rect>\r\n <rect x=\"9\" y=\"7\" width=\"5\" height=\"15\" rx=\"1\"></rect>\r\n <rect x=\"16\" y=\"3\" width=\"5\" height=\"19\" rx=\"1\"></rect>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fab-mini-wrap\">\r\n <span class=\"fab-tooltip\">Tarjetas</span>\r\n <button class=\"fab-mini\" [class.active]=\"viewMode() === 'cards'\" (click)=\"setView('cards')\"\r\n title=\"Vista de tarjetas\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </div>\r\n }\r\n\r\n <button class=\"fab-main\" [class.is-open]=\"fabOpen()\" (click)=\"fabOpen.set(!fabOpen())\" title=\"Cambiar vista\">\r\n @switch (viewMode()) {\r\n @case ('cards') {\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n </svg>\r\n }\r\n @case ('bars') {\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"2\" y=\"13\" width=\"5\" height=\"9\" rx=\"1\"></rect>\r\n <rect x=\"9\" y=\"7\" width=\"5\" height=\"15\" rx=\"1\"></rect>\r\n <rect x=\"16\" y=\"3\" width=\"5\" height=\"19\" rx=\"1\"></rect>\r\n </svg>\r\n }\r\n @case ('donut') {\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\r\n <circle cx=\"12\" cy=\"12\" r=\"4\"></circle>\r\n </svg>\r\n }\r\n }\r\n </button>\r\n</div>\r\n", styles: [":host{--fab-mini-bg: #ffffff;--fab-mini-border: #e2e8f0;--fab-mini-color: #64748b;--fab-mini-shadow: rgba(0, 0, 0, .12);--fab-mini-hover-border: #4678e5;--fab-mini-hover-color: #4678e5;--fab-tooltip-bg: rgba(15, 23, 42, .82);--fab-tooltip-color: #ffffff;--fab-main-from: #002fff;--fab-main-to: #3a88ed;--fab-main-shadow: rgba(70, 134, 229, .55);--fab-main-hover-shadow: rgba(70, 139, 229, .7);--fab-active-bg: #0957ff;--fab-active-shadow: rgba(70, 152, 229, .45)}:host-context([data-bs-theme=dark]),:host-context(.dark-mode),:host-context(.theme-dark){--fab-mini-bg: #1e293b;--fab-mini-border: #334155;--fab-mini-color: #94a3b8;--fab-mini-shadow: rgba(0, 0, 0, .35);--fab-mini-hover-border: #60a5fa;--fab-mini-hover-color: #60a5fa;--fab-tooltip-bg: rgba(248, 250, 252, .92);--fab-tooltip-color: #0f172a}.view-fab{position:fixed;bottom:24px;right:24px;z-index:999;display:flex;flex-direction:column-reverse;align-items:center;gap:.55rem}.fab-main{width:54px;height:54px;border-radius:50%;border:none;background:linear-gradient(135deg,var(--fab-main-from) 0%,var(--fab-main-to) 100%);color:#fff;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 18px var(--fab-main-shadow);cursor:pointer;transition:transform .25s cubic-bezier(.34,1.56,.64,1),box-shadow .25s ease}.fab-main svg{transition:transform .35s ease}.fab-main:hover{transform:scale(1.1);box-shadow:0 6px 24px var(--fab-main-hover-shadow)}.fab-main.is-open{box-shadow:0 6px 24px var(--fab-main-hover-shadow)}.fab-mini{width:44px;height:44px;border-radius:50%;border:2px solid var(--fab-mini-border);background:var(--fab-mini-bg);color:var(--fab-mini-color);display:flex;align-items:center;justify-content:center;box-shadow:0 2px 10px var(--fab-mini-shadow);cursor:pointer;transition:background .2s ease,border-color .2s ease,color .2s ease,transform .2s cubic-bezier(.34,1.56,.64,1),box-shadow .2s ease}.fab-mini:hover{transform:scale(1.12);border-color:var(--fab-mini-hover-border);color:var(--fab-mini-hover-color)}.fab-mini.active{background:var(--fab-active-bg);border-color:var(--fab-active-bg);color:#fff;box-shadow:0 3px 12px var(--fab-active-shadow);transform:scale(1.08)}.fab-tooltip{position:absolute;right:calc(100% + 10px);top:50%;transform:translateY(-50%);font-size:.7rem;font-weight:600;background:var(--fab-tooltip-bg);backdrop-filter:blur(4px);color:var(--fab-tooltip-color);padding:3px 8px;border-radius:6px;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .15s ease}.fab-menu{display:flex;flex-direction:column;align-items:center;gap:.55rem}.fab-mini-wrap{position:relative;display:flex;align-items:center;animation:fabMiniIn .22s cubic-bezier(.34,1.56,.64,1) both}.fab-mini-wrap:nth-child(1){animation-delay:0ms}.fab-mini-wrap:nth-child(2){animation-delay:55ms}.fab-mini-wrap:nth-child(3){animation-delay:.11s}.fab-mini-wrap:hover .fab-tooltip{opacity:1}.fab-menu--closing .fab-mini-wrap{animation:fabMiniOut .15s ease-in both;animation-delay:0ms}@keyframes fabMiniIn{0%{opacity:0;transform:translateY(12px) scale(.75)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes fabMiniOut{0%{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(10px) scale(.8)}}\n"] });
1711
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: DashboardViewSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1712
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: DashboardViewSwitcherComponent, isStandalone: true, selector: "app-dashboard-view-switcher", inputs: { viewMode: { classPropertyName: "viewMode", publicName: "viewMode", isSignal: true, isRequired: false, transformFunction: null }, accentColor: { classPropertyName: "accentColor", publicName: "accentColor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { viewModeChange: "viewModeChange" }, ngImport: i0, template: "<div class=\"view-fab\" [style.--fab-main-from]=\"accentColor()\" [style.--fab-main-to]=\"accentColor()\"\r\n [style.--fab-active-bg]=\"accentColor()\" [style.--fab-mini-hover-border]=\"accentColor()\"\r\n [style.--fab-mini-hover-color]=\"accentColor()\" (mouseenter)=\"fabOpen.set(true)\" (mouseleave)=\"fabOpen.set(false)\">\r\n @if (fabRendered()) {\r\n <div class=\"fab-menu\" [class.fab-menu--closing]=\"!fabOpen()\">\r\n\r\n <div class=\"fab-mini-wrap\">\r\n <span class=\"fab-tooltip\">Dona</span>\r\n <button class=\"fab-mini\" [class.active]=\"viewMode() === 'donut'\" (click)=\"setView('donut')\"\r\n title=\"Vista de dona\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\r\n <circle cx=\"12\" cy=\"12\" r=\"4\"></circle>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fab-mini-wrap\">\r\n <span class=\"fab-tooltip\">Barras</span>\r\n <button class=\"fab-mini\" [class.active]=\"viewMode() === 'bars'\" (click)=\"setView('bars')\"\r\n title=\"Vista de barras\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"2\" y=\"13\" width=\"5\" height=\"9\" rx=\"1\"></rect>\r\n <rect x=\"9\" y=\"7\" width=\"5\" height=\"15\" rx=\"1\"></rect>\r\n <rect x=\"16\" y=\"3\" width=\"5\" height=\"19\" rx=\"1\"></rect>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fab-mini-wrap\">\r\n <span class=\"fab-tooltip\">Tarjetas</span>\r\n <button class=\"fab-mini\" [class.active]=\"viewMode() === 'cards'\" (click)=\"setView('cards')\"\r\n title=\"Vista de tarjetas\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </div>\r\n }\r\n\r\n <button class=\"fab-main\" [class.is-open]=\"fabOpen()\" (click)=\"fabOpen.set(!fabOpen())\" title=\"Cambiar vista\">\r\n @switch (viewMode()) {\r\n @case ('cards') {\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n </svg>\r\n }\r\n @case ('bars') {\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"2\" y=\"13\" width=\"5\" height=\"9\" rx=\"1\"></rect>\r\n <rect x=\"9\" y=\"7\" width=\"5\" height=\"15\" rx=\"1\"></rect>\r\n <rect x=\"16\" y=\"3\" width=\"5\" height=\"19\" rx=\"1\"></rect>\r\n </svg>\r\n }\r\n @case ('donut') {\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\r\n <circle cx=\"12\" cy=\"12\" r=\"4\"></circle>\r\n </svg>\r\n }\r\n }\r\n </button>\r\n</div>\r\n", styles: [":host{--fab-mini-bg: #ffffff;--fab-mini-border: #e2e8f0;--fab-mini-color: #64748b;--fab-mini-shadow: rgba(0, 0, 0, .12);--fab-mini-hover-border: #4678e5;--fab-mini-hover-color: #4678e5;--fab-tooltip-bg: rgba(15, 23, 42, .82);--fab-tooltip-color: #ffffff;--fab-main-from: #002fff;--fab-main-to: #3a88ed;--fab-main-shadow: rgba(70, 134, 229, .55);--fab-main-hover-shadow: rgba(70, 139, 229, .7);--fab-active-bg: #0957ff;--fab-active-shadow: rgba(70, 152, 229, .45)}:host-context([data-bs-theme=dark]),:host-context(.dark-mode),:host-context(.theme-dark){--fab-mini-bg: #1e293b;--fab-mini-border: #334155;--fab-mini-color: #94a3b8;--fab-mini-shadow: rgba(0, 0, 0, .35);--fab-mini-hover-border: #60a5fa;--fab-mini-hover-color: #60a5fa;--fab-tooltip-bg: rgba(248, 250, 252, .92);--fab-tooltip-color: #0f172a}.view-fab{position:fixed;bottom:24px;right:24px;z-index:999;display:flex;flex-direction:column-reverse;align-items:center;gap:.55rem}.fab-main{width:54px;height:54px;border-radius:50%;border:none;background:linear-gradient(135deg,var(--fab-main-from) 0%,var(--fab-main-to) 100%);color:#fff;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 18px var(--fab-main-shadow);cursor:pointer;transition:transform .25s cubic-bezier(.34,1.56,.64,1),box-shadow .25s ease}.fab-main svg{transition:transform .35s ease}.fab-main:hover{transform:scale(1.1);box-shadow:0 6px 24px var(--fab-main-hover-shadow)}.fab-main.is-open{box-shadow:0 6px 24px var(--fab-main-hover-shadow)}.fab-mini{width:44px;height:44px;border-radius:50%;border:2px solid var(--fab-mini-border);background:var(--fab-mini-bg);color:var(--fab-mini-color);display:flex;align-items:center;justify-content:center;box-shadow:0 2px 10px var(--fab-mini-shadow);cursor:pointer;transition:background .2s ease,border-color .2s ease,color .2s ease,transform .2s cubic-bezier(.34,1.56,.64,1),box-shadow .2s ease}.fab-mini:hover{transform:scale(1.12);border-color:var(--fab-mini-hover-border);color:var(--fab-mini-hover-color)}.fab-mini.active{background:var(--fab-active-bg);border-color:var(--fab-active-bg);color:#fff;box-shadow:0 3px 12px var(--fab-active-shadow);transform:scale(1.08)}.fab-tooltip{position:absolute;right:calc(100% + 10px);top:50%;transform:translateY(-50%);font-size:.7rem;font-weight:600;background:var(--fab-tooltip-bg);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);color:var(--fab-tooltip-color);padding:3px 8px;border-radius:6px;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .15s ease}.fab-menu{display:flex;flex-direction:column;align-items:center;gap:.55rem}.fab-mini-wrap{position:relative;display:flex;align-items:center;animation:fabMiniIn .22s cubic-bezier(.34,1.56,.64,1) both}.fab-mini-wrap:nth-child(1){animation-delay:0ms}.fab-mini-wrap:nth-child(2){animation-delay:55ms}.fab-mini-wrap:nth-child(3){animation-delay:.11s}.fab-mini-wrap:hover .fab-tooltip{opacity:1}.fab-menu--closing .fab-mini-wrap{animation:fabMiniOut .15s ease-in both;animation-delay:0ms}@keyframes fabMiniIn{0%{opacity:0;transform:translateY(12px) scale(.75)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes fabMiniOut{0%{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(10px) scale(.8)}}\n"] });
1720
1713
  }
1721
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: DashboardViewSwitcherComponent, decorators: [{
1714
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: DashboardViewSwitcherComponent, decorators: [{
1722
1715
  type: Component,
1723
- args: [{ selector: 'app-dashboard-view-switcher', imports: [], template: "<div class=\"view-fab\" [style.--fab-main-from]=\"accentColor()\" [style.--fab-main-to]=\"accentColor()\"\r\n [style.--fab-active-bg]=\"accentColor()\" [style.--fab-mini-hover-border]=\"accentColor()\"\r\n [style.--fab-mini-hover-color]=\"accentColor()\" (mouseenter)=\"fabOpen.set(true)\" (mouseleave)=\"fabOpen.set(false)\">\r\n @if (fabRendered()) {\r\n <div class=\"fab-menu\" [class.fab-menu--closing]=\"!fabOpen()\">\r\n\r\n <div class=\"fab-mini-wrap\">\r\n <span class=\"fab-tooltip\">Dona</span>\r\n <button class=\"fab-mini\" [class.active]=\"viewMode() === 'donut'\" (click)=\"setView('donut')\"\r\n title=\"Vista de dona\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\r\n <circle cx=\"12\" cy=\"12\" r=\"4\"></circle>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fab-mini-wrap\">\r\n <span class=\"fab-tooltip\">Barras</span>\r\n <button class=\"fab-mini\" [class.active]=\"viewMode() === 'bars'\" (click)=\"setView('bars')\"\r\n title=\"Vista de barras\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"2\" y=\"13\" width=\"5\" height=\"9\" rx=\"1\"></rect>\r\n <rect x=\"9\" y=\"7\" width=\"5\" height=\"15\" rx=\"1\"></rect>\r\n <rect x=\"16\" y=\"3\" width=\"5\" height=\"19\" rx=\"1\"></rect>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fab-mini-wrap\">\r\n <span class=\"fab-tooltip\">Tarjetas</span>\r\n <button class=\"fab-mini\" [class.active]=\"viewMode() === 'cards'\" (click)=\"setView('cards')\"\r\n title=\"Vista de tarjetas\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </div>\r\n }\r\n\r\n <button class=\"fab-main\" [class.is-open]=\"fabOpen()\" (click)=\"fabOpen.set(!fabOpen())\" title=\"Cambiar vista\">\r\n @switch (viewMode()) {\r\n @case ('cards') {\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n </svg>\r\n }\r\n @case ('bars') {\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"2\" y=\"13\" width=\"5\" height=\"9\" rx=\"1\"></rect>\r\n <rect x=\"9\" y=\"7\" width=\"5\" height=\"15\" rx=\"1\"></rect>\r\n <rect x=\"16\" y=\"3\" width=\"5\" height=\"19\" rx=\"1\"></rect>\r\n </svg>\r\n }\r\n @case ('donut') {\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\r\n <circle cx=\"12\" cy=\"12\" r=\"4\"></circle>\r\n </svg>\r\n }\r\n }\r\n </button>\r\n</div>\r\n", styles: [":host{--fab-mini-bg: #ffffff;--fab-mini-border: #e2e8f0;--fab-mini-color: #64748b;--fab-mini-shadow: rgba(0, 0, 0, .12);--fab-mini-hover-border: #4678e5;--fab-mini-hover-color: #4678e5;--fab-tooltip-bg: rgba(15, 23, 42, .82);--fab-tooltip-color: #ffffff;--fab-main-from: #002fff;--fab-main-to: #3a88ed;--fab-main-shadow: rgba(70, 134, 229, .55);--fab-main-hover-shadow: rgba(70, 139, 229, .7);--fab-active-bg: #0957ff;--fab-active-shadow: rgba(70, 152, 229, .45)}:host-context([data-bs-theme=dark]),:host-context(.dark-mode),:host-context(.theme-dark){--fab-mini-bg: #1e293b;--fab-mini-border: #334155;--fab-mini-color: #94a3b8;--fab-mini-shadow: rgba(0, 0, 0, .35);--fab-mini-hover-border: #60a5fa;--fab-mini-hover-color: #60a5fa;--fab-tooltip-bg: rgba(248, 250, 252, .92);--fab-tooltip-color: #0f172a}.view-fab{position:fixed;bottom:24px;right:24px;z-index:999;display:flex;flex-direction:column-reverse;align-items:center;gap:.55rem}.fab-main{width:54px;height:54px;border-radius:50%;border:none;background:linear-gradient(135deg,var(--fab-main-from) 0%,var(--fab-main-to) 100%);color:#fff;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 18px var(--fab-main-shadow);cursor:pointer;transition:transform .25s cubic-bezier(.34,1.56,.64,1),box-shadow .25s ease}.fab-main svg{transition:transform .35s ease}.fab-main:hover{transform:scale(1.1);box-shadow:0 6px 24px var(--fab-main-hover-shadow)}.fab-main.is-open{box-shadow:0 6px 24px var(--fab-main-hover-shadow)}.fab-mini{width:44px;height:44px;border-radius:50%;border:2px solid var(--fab-mini-border);background:var(--fab-mini-bg);color:var(--fab-mini-color);display:flex;align-items:center;justify-content:center;box-shadow:0 2px 10px var(--fab-mini-shadow);cursor:pointer;transition:background .2s ease,border-color .2s ease,color .2s ease,transform .2s cubic-bezier(.34,1.56,.64,1),box-shadow .2s ease}.fab-mini:hover{transform:scale(1.12);border-color:var(--fab-mini-hover-border);color:var(--fab-mini-hover-color)}.fab-mini.active{background:var(--fab-active-bg);border-color:var(--fab-active-bg);color:#fff;box-shadow:0 3px 12px var(--fab-active-shadow);transform:scale(1.08)}.fab-tooltip{position:absolute;right:calc(100% + 10px);top:50%;transform:translateY(-50%);font-size:.7rem;font-weight:600;background:var(--fab-tooltip-bg);backdrop-filter:blur(4px);color:var(--fab-tooltip-color);padding:3px 8px;border-radius:6px;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .15s ease}.fab-menu{display:flex;flex-direction:column;align-items:center;gap:.55rem}.fab-mini-wrap{position:relative;display:flex;align-items:center;animation:fabMiniIn .22s cubic-bezier(.34,1.56,.64,1) both}.fab-mini-wrap:nth-child(1){animation-delay:0ms}.fab-mini-wrap:nth-child(2){animation-delay:55ms}.fab-mini-wrap:nth-child(3){animation-delay:.11s}.fab-mini-wrap:hover .fab-tooltip{opacity:1}.fab-menu--closing .fab-mini-wrap{animation:fabMiniOut .15s ease-in both;animation-delay:0ms}@keyframes fabMiniIn{0%{opacity:0;transform:translateY(12px) scale(.75)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes fabMiniOut{0%{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(10px) scale(.8)}}\n"] }]
1724
- }], ctorParameters: () => [] });
1716
+ args: [{ selector: 'app-dashboard-view-switcher', imports: [], template: "<div class=\"view-fab\" [style.--fab-main-from]=\"accentColor()\" [style.--fab-main-to]=\"accentColor()\"\r\n [style.--fab-active-bg]=\"accentColor()\" [style.--fab-mini-hover-border]=\"accentColor()\"\r\n [style.--fab-mini-hover-color]=\"accentColor()\" (mouseenter)=\"fabOpen.set(true)\" (mouseleave)=\"fabOpen.set(false)\">\r\n @if (fabRendered()) {\r\n <div class=\"fab-menu\" [class.fab-menu--closing]=\"!fabOpen()\">\r\n\r\n <div class=\"fab-mini-wrap\">\r\n <span class=\"fab-tooltip\">Dona</span>\r\n <button class=\"fab-mini\" [class.active]=\"viewMode() === 'donut'\" (click)=\"setView('donut')\"\r\n title=\"Vista de dona\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\r\n <circle cx=\"12\" cy=\"12\" r=\"4\"></circle>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fab-mini-wrap\">\r\n <span class=\"fab-tooltip\">Barras</span>\r\n <button class=\"fab-mini\" [class.active]=\"viewMode() === 'bars'\" (click)=\"setView('bars')\"\r\n title=\"Vista de barras\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"2\" y=\"13\" width=\"5\" height=\"9\" rx=\"1\"></rect>\r\n <rect x=\"9\" y=\"7\" width=\"5\" height=\"15\" rx=\"1\"></rect>\r\n <rect x=\"16\" y=\"3\" width=\"5\" height=\"19\" rx=\"1\"></rect>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"fab-mini-wrap\">\r\n <span class=\"fab-tooltip\">Tarjetas</span>\r\n <button class=\"fab-mini\" [class.active]=\"viewMode() === 'cards'\" (click)=\"setView('cards')\"\r\n title=\"Vista de tarjetas\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n </div>\r\n }\r\n\r\n <button class=\"fab-main\" [class.is-open]=\"fabOpen()\" (click)=\"fabOpen.set(!fabOpen())\" title=\"Cambiar vista\">\r\n @switch (viewMode()) {\r\n @case ('cards') {\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect>\r\n </svg>\r\n }\r\n @case ('bars') {\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"2\" y=\"13\" width=\"5\" height=\"9\" rx=\"1\"></rect>\r\n <rect x=\"9\" y=\"7\" width=\"5\" height=\"15\" rx=\"1\"></rect>\r\n <rect x=\"16\" y=\"3\" width=\"5\" height=\"19\" rx=\"1\"></rect>\r\n </svg>\r\n }\r\n @case ('donut') {\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\r\n <circle cx=\"12\" cy=\"12\" r=\"4\"></circle>\r\n </svg>\r\n }\r\n }\r\n </button>\r\n</div>\r\n", styles: [":host{--fab-mini-bg: #ffffff;--fab-mini-border: #e2e8f0;--fab-mini-color: #64748b;--fab-mini-shadow: rgba(0, 0, 0, .12);--fab-mini-hover-border: #4678e5;--fab-mini-hover-color: #4678e5;--fab-tooltip-bg: rgba(15, 23, 42, .82);--fab-tooltip-color: #ffffff;--fab-main-from: #002fff;--fab-main-to: #3a88ed;--fab-main-shadow: rgba(70, 134, 229, .55);--fab-main-hover-shadow: rgba(70, 139, 229, .7);--fab-active-bg: #0957ff;--fab-active-shadow: rgba(70, 152, 229, .45)}:host-context([data-bs-theme=dark]),:host-context(.dark-mode),:host-context(.theme-dark){--fab-mini-bg: #1e293b;--fab-mini-border: #334155;--fab-mini-color: #94a3b8;--fab-mini-shadow: rgba(0, 0, 0, .35);--fab-mini-hover-border: #60a5fa;--fab-mini-hover-color: #60a5fa;--fab-tooltip-bg: rgba(248, 250, 252, .92);--fab-tooltip-color: #0f172a}.view-fab{position:fixed;bottom:24px;right:24px;z-index:999;display:flex;flex-direction:column-reverse;align-items:center;gap:.55rem}.fab-main{width:54px;height:54px;border-radius:50%;border:none;background:linear-gradient(135deg,var(--fab-main-from) 0%,var(--fab-main-to) 100%);color:#fff;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 18px var(--fab-main-shadow);cursor:pointer;transition:transform .25s cubic-bezier(.34,1.56,.64,1),box-shadow .25s ease}.fab-main svg{transition:transform .35s ease}.fab-main:hover{transform:scale(1.1);box-shadow:0 6px 24px var(--fab-main-hover-shadow)}.fab-main.is-open{box-shadow:0 6px 24px var(--fab-main-hover-shadow)}.fab-mini{width:44px;height:44px;border-radius:50%;border:2px solid var(--fab-mini-border);background:var(--fab-mini-bg);color:var(--fab-mini-color);display:flex;align-items:center;justify-content:center;box-shadow:0 2px 10px var(--fab-mini-shadow);cursor:pointer;transition:background .2s ease,border-color .2s ease,color .2s ease,transform .2s cubic-bezier(.34,1.56,.64,1),box-shadow .2s ease}.fab-mini:hover{transform:scale(1.12);border-color:var(--fab-mini-hover-border);color:var(--fab-mini-hover-color)}.fab-mini.active{background:var(--fab-active-bg);border-color:var(--fab-active-bg);color:#fff;box-shadow:0 3px 12px var(--fab-active-shadow);transform:scale(1.08)}.fab-tooltip{position:absolute;right:calc(100% + 10px);top:50%;transform:translateY(-50%);font-size:.7rem;font-weight:600;background:var(--fab-tooltip-bg);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);color:var(--fab-tooltip-color);padding:3px 8px;border-radius:6px;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .15s ease}.fab-menu{display:flex;flex-direction:column;align-items:center;gap:.55rem}.fab-mini-wrap{position:relative;display:flex;align-items:center;animation:fabMiniIn .22s cubic-bezier(.34,1.56,.64,1) both}.fab-mini-wrap:nth-child(1){animation-delay:0ms}.fab-mini-wrap:nth-child(2){animation-delay:55ms}.fab-mini-wrap:nth-child(3){animation-delay:.11s}.fab-mini-wrap:hover .fab-tooltip{opacity:1}.fab-menu--closing .fab-mini-wrap{animation:fabMiniOut .15s ease-in both;animation-delay:0ms}@keyframes fabMiniIn{0%{opacity:0;transform:translateY(12px) scale(.75)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes fabMiniOut{0%{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(10px) scale(.8)}}\n"] }]
1717
+ }], ctorParameters: () => [], propDecorators: { viewMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewMode", required: false }] }], accentColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "accentColor", required: false }] }], viewModeChange: [{ type: i0.Output, args: ["viewModeChange"] }] } });
1725
1718
 
1726
1719
  /*
1727
1720
  * Public API Surface of layout-tsi