@kaufmann-lab/ui 0.1.0 → 0.1.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"kaufmann-lab-ui.mjs","sources":["../../../projects/ui/src/lib/icon/icon-sprite.ts","../../../projects/ui/src/lib/icon/Icon.ts","../../../projects/ui/src/lib/action-tile/ActionTile.ts","../../../projects/ui/src/lib/admin-badge/AdminBadge.ts","../../../projects/ui/src/lib/button/button.ts","../../../projects/ui/src/lib/alert/Alert.ts","../../../projects/ui/src/lib/avatar/Avatar.ts","../../../projects/ui/src/lib/badge/Badge.ts","../../../projects/ui/src/lib/breadcrumb/Breadcrumb.ts","../../../projects/ui/src/lib/card/Card.ts","../../../projects/ui/src/lib/carousel/Carousel.ts","../../../projects/ui/src/lib/checkbox/Checkbox.ts","../../../projects/ui/src/lib/chip/Chip.ts","../../../projects/ui/src/lib/field-label/FieldLabel.ts","../../../projects/ui/src/lib/select/Select.ts","../../../projects/ui/src/lib/company-selector/CompanySelector.ts","../../../projects/ui/src/lib/content-slot/ContentSlot.ts","../../../projects/ui/src/lib/empty-state/EmptyState.ts","../../../projects/ui/src/lib/skeleton/Skeleton.ts","../../../projects/ui/src/lib/spinner/Spinner.ts","../../../projects/ui/src/lib/content-state/ContentState.ts","../../../projects/ui/src/lib/data-table/DataTable.ts","../../../projects/ui/src/lib/feature-card/FeatureCard.ts","../../../projects/ui/src/lib/field/Field.ts","../../../projects/ui/src/lib/filter-chips/FilterChips.ts","../../../projects/ui/src/lib/folder-tabs/FolderTabs.ts","../../../projects/ui/src/lib/input/Input.ts","../../../projects/ui/src/lib/metric-card/MetricCard.ts","../../../projects/ui/src/lib/modal/Modal.ts","../../../projects/ui/src/lib/multi-select/MultiSelect.ts","../../../projects/ui/src/lib/page-header/PageHeader.ts","../../../projects/ui/src/lib/pagination/Pagination.ts","../../../projects/ui/src/lib/panel/Panel.ts","../../../projects/ui/src/lib/portal-header/PortalHeader.ts","../../../projects/ui/src/lib/reserve-block/ReserveBlock.ts","../../../projects/ui/src/lib/section-header/SectionHeader.ts","../../../projects/ui/src/lib/segmented/Segmented.ts","../../../projects/ui/src/lib/select-menu/SelectMenu.ts","../../../projects/ui/src/lib/stat-tile/StatTile.ts","../../../projects/ui/src/lib/status-pill/StatusPill.ts","../../../projects/ui/src/lib/tabs/Tabs.ts","../../../projects/ui/src/lib/toast/Toast.ts","../../../projects/ui/src/lib/vehicle-header/VehicleHeader.ts","../../../projects/ui/src/lib/view-toggle/ViewToggle.ts","../../../projects/ui/src/public-api.ts","../../../projects/ui/src/kaufmann-lab-ui.ts"],"sourcesContent":["/**\n * Sprite SVG con los 59 íconos de trazo del design system (página 5:\n * \"Set de 59 iconos de trazo (1.9px, grilla 24×24)\"). Cada ícono es un\n * `<symbol>` con su nombre real de la spec como id (`kf-icon-check`,\n * `kf-icon-alert-triangle`, etc.) — `Icon` lo referencia con `<use>`.\n *\n * Los paths vienen de Lucide (https://lucide.dev, licencia ISC), la\n * librería de iconos de trazo cuyo set de nombres coincide exactamente con\n * el que pide el design system (chevron-right, alert-triangle, bar-chart…).\n * Se embeben acá en vez de agregar `lucide` como dependencia del paquete\n * para no sumar peso/versión externa a algo que consumen todos los\n * frontends del ecosistema — son 59 <path>/<circle>/<rect> estáticos, no\n * lógica que necesite actualizarse seguido.\n *\n * Mapeo de 4 nombres de la spec que no existen tal cual en Lucide (renombres\n * entre versiones de esa librería, o conceptos vecinos):\n * tool -> wrench\n * sort -> arrow-up-down (control de orden bidireccional simple)\n * cart -> shopping-cart\n * chevron-left-bar -> panel-left (icono de \"colapsar panel lateral\")\n *\n * Se inyecta UNA sola vez en el DOM (ver `Icon`), sin importar cuántos\n * `<kf-icon>` distintos haya en la página — todos referencian el mismo\n * sprite vía `<use href=\"#kf-icon-...\">`.\n */\nexport const KF_ICON_SPRITE = `<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none\">\n <symbol id=\"kf-icon-activity\" viewBox=\"0 0 24 24\">\n <path d=\"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2\" />\n </symbol>\n <symbol id=\"kf-icon-alert-circle\" viewBox=\"0 0 24 24\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" x2=\"12\" y1=\"8\" y2=\"12\" />\n <line x1=\"12\" x2=\"12.01\" y1=\"16\" y2=\"16\" />\n </symbol>\n <symbol id=\"kf-icon-alert-octagon\" viewBox=\"0 0 24 24\">\n <path d=\"M12 16h.01\" />\n <path d=\"M12 8v4\" />\n <path d=\"M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z\" />\n </symbol>\n <symbol id=\"kf-icon-alert-triangle\" viewBox=\"0 0 24 24\">\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </symbol>\n <symbol id=\"kf-icon-award\" viewBox=\"0 0 24 24\">\n <path d=\"m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526\" />\n <circle cx=\"12\" cy=\"8\" r=\"6\" />\n </symbol>\n <symbol id=\"kf-icon-bar-chart\" viewBox=\"0 0 24 24\">\n <path d=\"M5 21v-6\" />\n <path d=\"M12 21V9\" />\n <path d=\"M19 21V3\" />\n </symbol>\n <symbol id=\"kf-icon-bell\" viewBox=\"0 0 24 24\">\n <path d=\"M10.268 21a2 2 0 0 0 3.464 0\" />\n <path d=\"M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326\" />\n </symbol>\n <symbol id=\"kf-icon-bus\" viewBox=\"0 0 24 24\">\n <path d=\"M8 6v6\" />\n <path d=\"M15 6v6\" />\n <path d=\"M2 12h19.6\" />\n <path d=\"M18 18h3s.5-1.7.8-2.8c.1-.4.2-.8.2-1.2 0-.4-.1-.8-.2-1.2l-1.4-5C20.1 6.8 19.1 6 18 6H4a2 2 0 0 0-2 2v10h3\" />\n <circle cx=\"7\" cy=\"18\" r=\"2\" />\n <path d=\"M9 18h5\" />\n <circle cx=\"16\" cy=\"18\" r=\"2\" />\n </symbol>\n <symbol id=\"kf-icon-calculator\" viewBox=\"0 0 24 24\">\n <rect width=\"16\" height=\"20\" x=\"4\" y=\"2\" rx=\"2\" />\n <line x1=\"8\" x2=\"16\" y1=\"6\" y2=\"6\" />\n <line x1=\"16\" x2=\"16\" y1=\"14\" y2=\"18\" />\n <path d=\"M16 10h.01\" />\n <path d=\"M12 10h.01\" />\n <path d=\"M8 10h.01\" />\n <path d=\"M12 14h.01\" />\n <path d=\"M8 14h.01\" />\n <path d=\"M12 18h.01\" />\n <path d=\"M8 18h.01\" />\n </symbol>\n <symbol id=\"kf-icon-calendar\" viewBox=\"0 0 24 24\">\n <path d=\"M8 2v3\" />\n <path d=\"M16 2v3\" />\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <path d=\"M3 9h18\" />\n </symbol>\n <symbol id=\"kf-icon-car\" viewBox=\"0 0 24 24\">\n <path d=\"M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2\" />\n <circle cx=\"7\" cy=\"17\" r=\"2\" />\n <path d=\"M9 17h6\" />\n <circle cx=\"17\" cy=\"17\" r=\"2\" />\n </symbol>\n <symbol id=\"kf-icon-cart\" viewBox=\"0 0 24 24\">\n <circle cx=\"8\" cy=\"21\" r=\"1\" />\n <circle cx=\"19\" cy=\"21\" r=\"1\" />\n <path d=\"M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12\" />\n </symbol>\n <symbol id=\"kf-icon-check\" viewBox=\"0 0 24 24\">\n <path d=\"M20 6 9 17l-5-5\" />\n </symbol>\n <symbol id=\"kf-icon-check-circle\" viewBox=\"0 0 24 24\">\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n </symbol>\n <symbol id=\"kf-icon-check-square\" viewBox=\"0 0 24 24\">\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"m9 12 2 2 4-4\" />\n </symbol>\n <symbol id=\"kf-icon-chevron-down\" viewBox=\"0 0 24 24\">\n <path d=\"m6 9 6 6 6-6\" />\n </symbol>\n <symbol id=\"kf-icon-chevron-left\" viewBox=\"0 0 24 24\">\n <path d=\"m15 18-6-6 6-6\" />\n </symbol>\n <symbol id=\"kf-icon-chevron-left-bar\" viewBox=\"0 0 24 24\">\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n </symbol>\n <symbol id=\"kf-icon-chevron-right\" viewBox=\"0 0 24 24\">\n <path d=\"m9 18 6-6-6-6\" />\n </symbol>\n <symbol id=\"kf-icon-clipboard\" viewBox=\"0 0 24 24\">\n <rect width=\"8\" height=\"4\" x=\"8\" y=\"2\" rx=\"1\" ry=\"1\" />\n <path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\" />\n </symbol>\n <symbol id=\"kf-icon-clock\" viewBox=\"0 0 24 24\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 6v6l4 2\" />\n </symbol>\n <symbol id=\"kf-icon-credit-card\" viewBox=\"0 0 24 24\">\n <rect width=\"20\" height=\"14\" x=\"2\" y=\"5\" rx=\"2\" />\n <line x1=\"2\" x2=\"22\" y1=\"10\" y2=\"10\" />\n </symbol>\n <symbol id=\"kf-icon-download\" viewBox=\"0 0 24 24\">\n <path d=\"M12 15V3\" />\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <path d=\"m7 10 5 5 5-5\" />\n </symbol>\n <symbol id=\"kf-icon-edit\" viewBox=\"0 0 24 24\">\n <path d=\"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\" />\n <path d=\"m15 5 4 4\" />\n </symbol>\n <symbol id=\"kf-icon-external-link\" viewBox=\"0 0 24 24\">\n <path d=\"M15 3h6v6\" />\n <path d=\"M10 14 21 3\" />\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n </symbol>\n <symbol id=\"kf-icon-eye\" viewBox=\"0 0 24 24\">\n <path d=\"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </symbol>\n <symbol id=\"kf-icon-file\" viewBox=\"0 0 24 24\">\n <path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\" />\n <path d=\"M14 2v5a1 1 0 0 0 1 1h5\" />\n </symbol>\n <symbol id=\"kf-icon-filter\" viewBox=\"0 0 24 24\">\n <path d=\"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z\" />\n </symbol>\n <symbol id=\"kf-icon-gauge\" viewBox=\"0 0 24 24\">\n <path d=\"m12 14 4-4\" />\n <path d=\"M3.34 19a10 10 0 1 1 17.32 0\" />\n </symbol>\n <symbol id=\"kf-icon-gift\" viewBox=\"0 0 24 24\">\n <path d=\"M12 7v14\" />\n <path d=\"M20 11v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8\" />\n <path d=\"M7.5 7a1 1 0 0 1 0-5A4.8 8 0 0 1 12 7a4.8 8 0 0 1 4.5-5 1 1 0 0 1 0 5\" />\n <rect x=\"3\" y=\"7\" width=\"18\" height=\"4\" rx=\"1\" />\n </symbol>\n <symbol id=\"kf-icon-grid\" viewBox=\"0 0 24 24\">\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M3 9h18\" />\n <path d=\"M3 15h18\" />\n <path d=\"M9 3v18\" />\n <path d=\"M15 3v18\" />\n </symbol>\n <symbol id=\"kf-icon-history\" viewBox=\"0 0 24 24\">\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n <path d=\"M12 7v5l4 2\" />\n </symbol>\n <symbol id=\"kf-icon-inbox\" viewBox=\"0 0 24 24\">\n <polyline points=\"22 12 16 12 14 15 10 15 8 12 2 12\" />\n <path d=\"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\" />\n </symbol>\n <symbol id=\"kf-icon-layers\" viewBox=\"0 0 24 24\">\n <path d=\"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z\" />\n <path d=\"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12\" />\n <path d=\"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17\" />\n </symbol>\n <symbol id=\"kf-icon-list\" viewBox=\"0 0 24 24\">\n <path d=\"M3 5h.01\" />\n <path d=\"M3 12h.01\" />\n <path d=\"M3 19h.01\" />\n <path d=\"M8 5h13\" />\n <path d=\"M8 12h13\" />\n <path d=\"M8 19h13\" />\n </symbol>\n <symbol id=\"kf-icon-map\" viewBox=\"0 0 24 24\">\n <path d=\"M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z\" />\n <path d=\"M15 5.764v15\" />\n <path d=\"M9 3.236v15\" />\n </symbol>\n <symbol id=\"kf-icon-map-pin\" viewBox=\"0 0 24 24\">\n <path d=\"M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0\" />\n <circle cx=\"12\" cy=\"10\" r=\"3\" />\n </symbol>\n <symbol id=\"kf-icon-menu\" viewBox=\"0 0 24 24\">\n <path d=\"M4 5h16\" />\n <path d=\"M4 12h16\" />\n <path d=\"M4 19h16\" />\n </symbol>\n <symbol id=\"kf-icon-mic\" viewBox=\"0 0 24 24\">\n <path d=\"M12 19v3\" />\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" />\n <rect x=\"9\" y=\"2\" width=\"6\" height=\"13\" rx=\"3\" />\n </symbol>\n <symbol id=\"kf-icon-mic-off\" viewBox=\"0 0 24 24\">\n <path d=\"M12 19v3\" />\n <path d=\"M15 9.34V5a3 3 0 0 0-5.68-1.33\" />\n <path d=\"M16.95 16.95A7 7 0 0 1 5 12v-2\" />\n <path d=\"M18.89 13.23A7 7 0 0 0 19 12v-2\" />\n <path d=\"m2 2 20 20\" />\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12\" />\n </symbol>\n <symbol id=\"kf-icon-more-vertical\" viewBox=\"0 0 24 24\">\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\n </symbol>\n <symbol id=\"kf-icon-pause\" viewBox=\"0 0 24 24\">\n <rect x=\"14\" y=\"3\" width=\"5\" height=\"18\" rx=\"1\" />\n <rect x=\"5\" y=\"3\" width=\"5\" height=\"18\" rx=\"1\" />\n </symbol>\n <symbol id=\"kf-icon-phone\" viewBox=\"0 0 24 24\">\n <path d=\"M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384\" />\n </symbol>\n <symbol id=\"kf-icon-play\" viewBox=\"0 0 24 24\">\n <path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\" />\n </symbol>\n <symbol id=\"kf-icon-plus\" viewBox=\"0 0 24 24\">\n <path d=\"M5 12h14\" />\n <path d=\"M12 5v14\" />\n </symbol>\n <symbol id=\"kf-icon-search\" viewBox=\"0 0 24 24\">\n <path d=\"m21 21-4.34-4.34\" />\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n </symbol>\n <symbol id=\"kf-icon-settings\" viewBox=\"0 0 24 24\">\n <path d=\"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </symbol>\n <symbol id=\"kf-icon-shield-check\" viewBox=\"0 0 24 24\">\n <path d=\"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\" />\n <path d=\"m9 12 2 2 4-4\" />\n </symbol>\n <symbol id=\"kf-icon-sort\" viewBox=\"0 0 24 24\">\n <path d=\"m21 16-4 4-4-4\" />\n <path d=\"M17 20V4\" />\n <path d=\"m3 8 4-4 4 4\" />\n <path d=\"M7 4v16\" />\n </symbol>\n <symbol id=\"kf-icon-star\" viewBox=\"0 0 24 24\">\n <path d=\"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\" />\n </symbol>\n <symbol id=\"kf-icon-ticket\" viewBox=\"0 0 24 24\">\n <path d=\"M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z\" />\n <path d=\"M13 5v2\" />\n <path d=\"M13 17v2\" />\n <path d=\"M13 11v2\" />\n </symbol>\n <symbol id=\"kf-icon-tool\" viewBox=\"0 0 24 24\">\n <path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z\" />\n </symbol>\n <symbol id=\"kf-icon-trash\" viewBox=\"0 0 24 24\">\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\" />\n <path d=\"M3 6h18\" />\n <path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </symbol>\n <symbol id=\"kf-icon-truck\" viewBox=\"0 0 24 24\">\n <path d=\"M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2\" />\n <path d=\"M15 18H9\" />\n <path d=\"M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14\" />\n <circle cx=\"17\" cy=\"18\" r=\"2\" />\n <circle cx=\"7\" cy=\"18\" r=\"2\" />\n </symbol>\n <symbol id=\"kf-icon-upload-cloud\" viewBox=\"0 0 24 24\">\n <path d=\"M12 13v8\" />\n <path d=\"M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242\" />\n <path d=\"m8 17 4-4 4 4\" />\n </symbol>\n <symbol id=\"kf-icon-user\" viewBox=\"0 0 24 24\">\n <path d=\"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\" />\n <circle cx=\"12\" cy=\"7\" r=\"4\" />\n </symbol>\n <symbol id=\"kf-icon-user-search\" viewBox=\"0 0 24 24\">\n <circle cx=\"10\" cy=\"7\" r=\"4\" />\n <path d=\"M10.3 15H7a4 4 0 0 0-4 4v2\" />\n <circle cx=\"17\" cy=\"17\" r=\"3\" />\n <path d=\"m21 21-1.9-1.9\" />\n </symbol>\n <symbol id=\"kf-icon-video\" viewBox=\"0 0 24 24\">\n <path d=\"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5\" />\n <rect x=\"2\" y=\"6\" width=\"14\" height=\"12\" rx=\"2\" />\n </symbol>\n <symbol id=\"kf-icon-x\" viewBox=\"0 0 24 24\">\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </symbol>\n</svg>`;\n","import { DOCUMENT } from '@angular/common';\nimport { Component, computed, effect, inject, input } from '@angular/core';\nimport { KF_ICON_SPRITE } from './icon-sprite';\n\n/** Nombre de cada uno de los 59 íconos del design system (página 5). */\nexport type IconName =\n | 'activity'\n | 'alert-circle'\n | 'alert-octagon'\n | 'alert-triangle'\n | 'award'\n | 'bar-chart'\n | 'bell'\n | 'bus'\n | 'calculator'\n | 'calendar'\n | 'car'\n | 'cart'\n | 'check'\n | 'check-circle'\n | 'check-square'\n | 'chevron-down'\n | 'chevron-left'\n | 'chevron-left-bar'\n | 'chevron-right'\n | 'clipboard'\n | 'clock'\n | 'credit-card'\n | 'download'\n | 'edit'\n | 'external-link'\n | 'eye'\n | 'file'\n | 'filter'\n | 'gauge'\n | 'gift'\n | 'grid'\n | 'history'\n | 'inbox'\n | 'layers'\n | 'list'\n | 'map'\n | 'map-pin'\n | 'menu'\n | 'mic'\n | 'mic-off'\n | 'more-vertical'\n | 'pause'\n | 'phone'\n | 'play'\n | 'plus'\n | 'search'\n | 'settings'\n | 'shield-check'\n | 'sort'\n | 'star'\n | 'ticket'\n | 'tool'\n | 'trash'\n | 'truck'\n | 'upload-cloud'\n | 'user'\n | 'user-search'\n | 'video'\n | 'x';\n\nexport type IconSize = 'sm' | 'md' | 'lg';\n\n/** Marca el sprite ya inyectado, para no depender de una bandera de módulo\n * — una bandera compartida entre instancias de test (o entre múltiples\n * `TestBed` en la misma suite) daría falsos negativos: el primer test que\n * corre \"gasta\" la bandera y todos los siguientes creerían que el sprite\n * nunca se inyecta. Comprobar el propio DOM es la fuente de verdad real. */\nconst SPRITE_ROOT_ID = 'kf-icon-sprite-root';\n\n/**\n * Ícono de trazo del design system — 59 glyphs (página 5), grilla 24×24,\n * grosor de trazo 1.9px. Referencia un sprite SVG embebido (ver\n * `icon-sprite.ts`) vía `<use>`, así que no hay peso de red adicional por\n * cada instancia: el sprite se inyecta al DOM una única vez, la primera\n * vez que se renderiza cualquier `<kf-icon>` de toda la aplicación.\n *\n * El tamaño se controla con `size` (página 6: \"el tamaño se controla con la\n * prop size\"): `sm` (16px), `md` (20px, default) o `lg` (24px). El color\n * sigue siempre `currentColor` — se hereda del texto del elemento\n * contenedor, nunca se fija en el propio ícono.\n *\n * <kf-icon name=\"alert-triangle\" size=\"sm\" />\n * <kf-button icon=\"calendar\">Reservar hora</kf-button> <!-- ver Button -->\n */\n@Component({\n selector: 'kf-icon',\n template: `\n <svg [attr.aria-hidden]=\"true\" focusable=\"false\">\n <use [attr.href]=\"'#kf-icon-' + name()\" />\n </svg>\n `,\n styles: `\n :host {\n display: inline-flex;\n flex: none;\n line-height: 0;\n }\n svg {\n width: var(--kf-icon-size, 20px);\n height: var(--kf-icon-size, 20px);\n fill: none;\n stroke: currentColor;\n stroke-width: 1.9;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n `,\n host: {\n '[style.--kf-icon-size]': 'pixelSize()',\n },\n})\nexport class Icon {\n readonly name = input.required<IconName>();\n readonly size = input<IconSize>('md');\n\n private readonly document = inject(DOCUMENT);\n\n protected readonly pixelSize = computed(() => {\n const bySize: Record<IconSize, string> = { sm: '16px', md: '20px', lg: '24px' };\n return bySize[this.size()];\n });\n\n constructor() {\n effect(() => {\n if (this.document.getElementById(SPRITE_ROOT_ID)) {\n return;\n }\n const container = this.document.createElement('div');\n container.innerHTML = KF_ICON_SPRITE;\n const sprite = container.firstElementChild;\n if (sprite) {\n sprite.id = SPRITE_ROOT_ID;\n this.document.body.prepend(sprite);\n }\n });\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Dos variantes del mismo concepto — acceso rápido a una sección (página\n * 35): \"Tile de acceso destacado\" (`variant=\"tile\"`, default) es un bloque\n * centrado con ícono grande arriba y título abajo, pensado para una\n * cuadrícula de accesos (ej. \"Todos los certificados\"). \"Fila de documento\"\n * (`variant=\"row\"`) es horizontal, con ícono a la izquierda y\n * título+descripción a la derecha, pensada para listas verticales dentro de\n * un `kf-panel` (ej. \"Pagos\" / \"Revisa tu estado de cuenta y realiza pagos.\").\n *\n * <kf-action-tile icon=\"shield-check\" title=\"Todos los certificados\" />\n * <kf-action-tile variant=\"row\" icon=\"download\" title=\"Pagos\"\n * description=\"Revisa tu estado de cuenta y realiza pagos.\" />\n */\n@Component({\n selector: 'kf-action-tile',\n imports: [Icon],\n template: `\n <span class=\"kf-action-tile__icon\">\n <kf-icon [name]=\"icon()\" [size]=\"variant() === 'row' ? 'md' : 'lg'\" />\n </span>\n <span class=\"kf-action-tile__text\">\n <span class=\"kf-action-tile__title\">{{ title() }}</span>\n @if (description()) {\n <span class=\"kf-action-tile__description\">{{ description() }}</span>\n }\n </span>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n :host(:hover) {\n border-color: var(--kf-color-border-strong);\n box-shadow: var(--kf-shadow-xs);\n }\n :host(.kf-action-tile--tile) {\n flex-direction: column;\n text-align: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-lg);\n }\n .kf-action-tile__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n :host(.kf-action-tile--row) .kf-action-tile__icon {\n width: 2.25rem;\n height: 2.25rem;\n background: var(--kf-color-secondary-soft);\n color: var(--kf-color-secondary);\n }\n :host(.kf-action-tile--tile) .kf-action-tile__icon {\n width: 2.75rem;\n height: 2.75rem;\n }\n .kf-action-tile__text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n }\n .kf-action-tile__title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-action-tile__description {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n `,\n host: {\n '[class.kf-action-tile--tile]': \"variant() === 'tile'\",\n '[class.kf-action-tile--row]': \"variant() === 'row'\",\n },\n})\nexport class ActionTile {\n readonly variant = input<'tile' | 'row'>('tile');\n readonly icon = input.required<IconName>();\n readonly title = input.required<string>();\n readonly description = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Marca la barra superior como chrome exclusivo de administradores (página\n * 18) — acento ámbar para diferenciar contexto privilegiado del resto del\n * portal. Dos variantes: etiqueta aislada (pill), o `inline` para usarse\n * dentro de la franja de `kf-portal-header` (fondo oscuro, texto ámbar).\n *\n * <kf-admin-badge />\n * <kf-admin-badge inline />\n */\n@Component({\n selector: 'kf-admin-badge',\n imports: [Icon],\n template: `\n <kf-icon name=\"shield-check\" size=\"sm\" />\n <span>Vista administrador</span>\n `,\n styles: `\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-warning-soft);\n border: 1px solid var(--kf-color-warning);\n color: var(--kf-color-warning-strong);\n font-size: 0.75rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n line-height: 1;\n }\n :host(.kf-admin-badge--inline) {\n background: transparent;\n border-color: rgba(226, 185, 59, 0.5);\n color: var(--kf-color-warning);\n }\n `,\n host: {\n '[class.kf-admin-badge--inline]': 'inline()',\n },\n})\nexport class AdminBadge {\n /** Para usarse dentro de una superficie oscura (ej. la franja de `kf-portal-header`). */\n readonly inline = input(false, { transform: booleanAttribute });\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Wraps a native `<button>`, so keyboard handling, focus and form submission\n * keep working. The cost of the wrapper is forwarding `disabled` and `type` by\n * hand: as attributes on a custom element they have no native effect.\n *\n * Five variants (page 9 of the design system): `primary` (main action, blue),\n * `secondary` (service actions, orange), `ghost` (low-emphasis, no fill),\n * `outline` (medium-emphasis, bordered) and `danger` (destructive\n * confirmations — red, see the Confirmation Modal pattern on page 30). Three\n * sizes (`sm`/`md`/`lg`). `icon` renders a leading glyph (`kf-icon`) before\n * the projected label; `block` stretches the button to the full width of its\n * container.\n *\n * `(click)` is not forwarded — it bubbles from the inner button to the host.\n *\n * <kf-button (click)=\"save()\">Save</kf-button>\n * <kf-button variant=\"ghost\" disabled>Cancel</kf-button>\n * <kf-button variant=\"danger\" (click)=\"remove()\">Delete</kf-button>\n * <kf-button size=\"sm\" icon=\"calendar\" block>Reservar hora</kf-button>\n */\n@Component({\n selector: 'kf-button',\n imports: [Icon],\n template: `\n <button\n [type]=\"type()\"\n [disabled]=\"disabled()\"\n [class.kf-button--secondary]=\"variant() === 'secondary'\"\n [class.kf-button--ghost]=\"variant() === 'ghost'\"\n [class.kf-button--outline]=\"variant() === 'outline'\"\n [class.kf-button--danger]=\"variant() === 'danger'\"\n [class.kf-button--sm]=\"size() === 'sm'\"\n [class.kf-button--lg]=\"size() === 'lg'\"\n >\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-button__icon\" [name]=\"iconName\" [size]=\"size() === 'lg' ? 'md' : 'sm'\" />\n }\n <ng-content />\n </button>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n :host([block]) {\n display: block;\n }\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--kf-space-xs);\n width: 100%;\n font: inherit;\n font-weight: 600;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid var(--kf-color-primary);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n cursor: pointer;\n transition:\n background 0.14s,\n border-color 0.14s,\n color 0.14s;\n }\n button:hover:not(:disabled) {\n background: var(--kf-color-primary-hover);\n border-color: var(--kf-color-primary-hover);\n }\n button:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n /* Secondary — naranja, para acciones de servicio (agendar, mantención). */\n button.kf-button--secondary {\n border-color: var(--kf-color-secondary);\n background: var(--kf-color-secondary);\n }\n button.kf-button--secondary:hover:not(:disabled) {\n background: var(--kf-color-secondary-hover);\n border-color: var(--kf-color-secondary-hover);\n }\n\n /* Ghost — sin relleno, para acciones secundarias junto a un primary. */\n button.kf-button--ghost {\n background: transparent;\n border-color: transparent;\n color: var(--kf-color-primary);\n }\n button.kf-button--ghost:hover:not(:disabled) {\n background: var(--kf-color-primary-soft);\n }\n\n /* Outline — énfasis medio: borde visible, sin relleno (ej. \"Llamar\" en Vehicle Header). */\n button.kf-button--outline {\n background: transparent;\n border-color: var(--kf-color-border-strong);\n color: var(--kf-color-text);\n }\n button.kf-button--outline:hover:not(:disabled) {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-text-muted);\n }\n\n /* Danger — rojo, para confirmaciones destructivas (cancelar, eliminar). */\n button.kf-button--danger {\n border-color: var(--kf-color-error);\n background: var(--kf-color-error);\n }\n button.kf-button--danger:hover:not(:disabled) {\n background: var(--kf-color-error-hover);\n border-color: var(--kf-color-error-hover);\n }\n\n /* Tamaños — el tamaño por defecto (md) usa el padding base de arriba. */\n button.kf-button--sm {\n padding: 6px var(--kf-space-sm);\n font-size: 0.85rem;\n }\n button.kf-button--lg {\n padding: var(--kf-space-sm) var(--kf-space-lg);\n font-size: 1.05rem;\n }\n `,\n host: {\n '[attr.block]': \"block() ? '' : null\",\n },\n})\nexport class Button {\n readonly variant = input<'primary' | 'secondary' | 'ghost' | 'outline' | 'danger'>('primary');\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Matches the native default: submits when inside a `<form>`. */\n readonly type = input<'button' | 'submit' | 'reset'>('submit');\n /** Leading icon, rendered via `kf-icon` before the projected label. */\n readonly icon = input<IconName>();\n /** Stretches the button to the full width of its container. */\n readonly block = input(false, { transform: booleanAttribute });\n}\n","import { booleanAttribute, Component, computed, input, model } from '@angular/core';\n\nexport type AlertTone = 'info' | 'ok' | 'warn' | 'error';\n\n/**\n * Banner contextual que vive dentro del flujo: validaciones, avisos de\n * vencimiento, confirmaciones. Persiste hasta que se descarta o hasta que la\n * condición que lo causó desaparece — para feedback efímero está el toast.\n *\n * `open` es two-way: el botón de cerrar lo pone en `false` y el componente\n * deja de renderizar. El consumidor puede volver a abrirlo poniéndolo en\n * `true` (ej. cuando la validación falla otra vez).\n *\n * ponytail: los glifos van inline en vez de venir de un componente Icon —\n * son 4 paths fijos, uno por tono, y no existe todavía `kf-icon` en la\n * librería. Cuando exista, se reemplaza este `@switch` por `<kf-icon>`.\n *\n * <kf-alert tone=\"warn\" title=\"SOAT por vencer\">Vence el 15/08.</kf-alert>\n * <kf-alert tone=\"ok\" [(open)]=\"saved\" dismissible>Pago registrado.</kf-alert>\n */\n@Component({\n selector: 'kf-alert',\n template: `\n @if (open()) {\n <div class=\"kf-alert\" [class]=\"'kf-alert--' + tone()\" [attr.role]=\"ariaRole()\">\n <svg class=\"kf-alert__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n @switch (tone()) {\n @case ('ok') {\n <path d=\"M21 12a9 9 0 1 1-4.2-7.6\" />\n <path d=\"M9 11.5l3 3 8.5-8.5\" />\n }\n @case ('warn') {\n <path d=\"M12 4l9 16H3z\" />\n <path d=\"M12 10v4\" />\n <path d=\"M12 17.5h.01\" />\n }\n @case ('error') {\n <path d=\"M8 3h8l5 5v8l-5 5H8l-5-5V8z\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n }\n </svg>\n <div class=\"kf-alert__body\">\n @if (title()) {\n <p class=\"kf-alert__title\">{{ title() }}</p>\n }\n <div class=\"kf-alert__message\"><ng-content /></div>\n </div>\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"kf-alert__close\"\n aria-label=\"Cerrar aviso\"\n (click)=\"open.set(false)\"\n >\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M6 6l12 12M18 6L6 18\" />\n </svg>\n </button>\n }\n </div>\n }\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-alert {\n display: flex;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid transparent;\n border-radius: var(--kf-radius-sm);\n font-size: 0.9rem;\n }\n .kf-alert--info {\n background: var(--kf-color-info-soft);\n border-color: var(--kf-color-info);\n color: var(--kf-color-info-strong);\n }\n .kf-alert--ok {\n background: var(--kf-color-success-soft);\n border-color: var(--kf-color-success);\n color: var(--kf-color-success-strong);\n }\n .kf-alert--warn {\n background: var(--kf-color-warning-soft);\n border-color: var(--kf-color-warning);\n color: var(--kf-color-warning-strong);\n }\n .kf-alert--error {\n background: var(--kf-color-error-soft);\n border-color: var(--kf-color-error);\n color: var(--kf-color-error-strong);\n }\n .kf-alert__icon,\n .kf-alert__close svg {\n flex: none;\n width: 1.15em;\n height: 1.15em;\n fill: none;\n stroke: currentColor;\n stroke-width: 1.9;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n .kf-alert__body {\n flex: 1;\n min-width: 0;\n }\n .kf-alert__title {\n margin: 0;\n font-family: var(--kf-font-title);\n font-weight: 700;\n }\n .kf-alert__message {\n color: inherit;\n }\n .kf-alert__close {\n flex: none;\n display: inline-flex;\n padding: 2px;\n border: none;\n background: transparent;\n color: inherit;\n border-radius: var(--kf-radius-xs);\n cursor: pointer;\n opacity: 0.7;\n }\n .kf-alert__close:hover {\n opacity: 1;\n }\n .kf-alert__close:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n `,\n})\nexport class Alert {\n readonly tone = input<AlertTone>('info');\n /** Línea en negrita arriba del mensaje. Vacío deja solo el contenido proyectado. */\n readonly title = input('');\n readonly dismissible = input(false, { transform: booleanAttribute });\n /** Visibilidad, two-way: `[(open)]=\"hasError\"`. */\n readonly open = model(true);\n\n /**\n * `alert` interrumpe al lector de pantalla; se reserva para error/warn.\n * Los avisos informativos se anuncian sin cortar lo que se esté leyendo.\n */\n protected readonly ariaRole = computed(() =>\n this.tone() === 'error' || this.tone() === 'warn' ? 'alert' : 'status',\n );\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport { booleanAttribute, Component, computed, input } from '@angular/core';\n\n/**\n * Avatar de usuario: muestra una foto (`src`) o, si no hay foto, las\n * iniciales (`initials`) sobre un fondo con gradiente de marca. `round`\n * controla la forma: circular (por defecto) o cuadrada con radio.\n *\n * Con `pill`, el avatar se envuelve en una pastilla azul con un chevron a la\n * derecha — la \"pill de usuario (header)\" de la página 18 del design system,\n * usada en la barra de sesión del Portal Header.\n *\n * <kf-avatar initials=\"JD\" />\n * <kf-avatar src=\"https://…/foto.jpg\" [round]=\"false\" />\n * <kf-avatar initials=\"TS\" pill />\n *\n * Pendiente: si en el futuro se agrega un ícono de fallback (persona\n * genérica) para cuando no hay ni `src` ni `initials`, depende del\n * componente Icon / sprite SVG que todavía no existe en esta librería.\n */\n@Component({\n selector: 'kf-avatar',\n imports: [NgTemplateOutlet],\n template: `\n <ng-template #avatarCircle>\n <span class=\"kf-avatar\" [class.kf-avatar--square]=\"!round()\">\n @if (src()) {\n <img class=\"kf-avatar__image\" [src]=\"src()\" [alt]=\"initials() || ''\" />\n } @else {\n <span class=\"kf-avatar__initials\">{{ displayInitials() }}</span>\n }\n </span>\n </ng-template>\n\n @if (pill()) {\n <span class=\"kf-avatar-pill\">\n <ng-container [ngTemplateOutlet]=\"avatarCircle\" />\n <span class=\"kf-avatar-pill__caret\" aria-hidden=\"true\"></span>\n </span>\n } @else {\n <ng-container [ngTemplateOutlet]=\"avatarCircle\" />\n }\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-avatar {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: 40px;\n block-size: 40px;\n overflow: hidden;\n border-radius: var(--kf-radius-pill);\n background: linear-gradient(135deg, var(--kf-color-primary), var(--kf-color-primary-active));\n color: var(--kf-color-white);\n font: inherit;\n font-size: 0.875rem;\n font-weight: 600;\n line-height: 1;\n user-select: none;\n flex: none;\n }\n .kf-avatar--square {\n border-radius: var(--kf-radius-sm);\n }\n .kf-avatar__image {\n inline-size: 100%;\n block-size: 100%;\n object-fit: cover;\n }\n .kf-avatar__initials {\n text-transform: uppercase;\n }\n\n /* Pill de usuario (header) — envuelve el avatar en una pastilla azul con chevron. */\n .kf-avatar-pill {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: 4px var(--kf-space-sm) 4px 4px;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-primary);\n cursor: pointer;\n }\n .kf-avatar-pill .kf-avatar {\n inline-size: 32px;\n block-size: 32px;\n background: rgba(255, 255, 255, 0.18);\n }\n .kf-avatar-pill__caret {\n flex: none;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-white);\n border-bottom: 2px solid var(--kf-color-white);\n transform: rotate(45deg);\n margin-top: -4px;\n }\n `,\n})\nexport class Avatar {\n readonly initials = input<string>();\n readonly src = input<string>();\n readonly round = input(true);\n /** Envuelve el avatar en la pastilla de sesión del header, con chevron. */\n readonly pill = input(false, { transform: booleanAttribute });\n\n /** Limita a 2 caracteres para que quepan cómodos dentro del círculo. */\n readonly displayInitials = computed(() => (this.initials() ?? '').slice(0, 2));\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Pill chica de fondo suave (soft) para un conteo, tag o estado liviano\n * puntual (no un proceso en vivo — para eso existe `kf-status-pill`, que usa\n * borde en vez de relleno). El color de fondo/texto/punto depende de `tone`.\n *\n * El PDF (página 10) fija seis tonos con fondo soft y texto del tono fuerte\n * — nunca fondo saturado con texto blanco, que es más apto para un botón\n * que para una etiqueta de lectura rápida en una lista densa.\n *\n * <kf-badge tone=\"ok\" dot>Al día</kf-badge>\n * <kf-badge tone=\"error\">3</kf-badge>\n *\n * Mapeo de `tone` a los seis conceptos de la página 10 y sus tokens\n * semánticos en projects/ui/src/tokens/base.css:\n * neutral -> Neutral (border/text-muted), info -> Información (info-soft/-strong),\n * ok -> Activo (success-soft/-strong), warn -> Pendiente (warning-soft/-strong),\n * error -> Vencido (error-soft/-strong), service -> Servicio (secondary-soft,\n * no existe un `-strong` para secondary todavía — usa el color base).\n */\n@Component({\n selector: 'kf-badge',\n template: `\n <span class=\"kf-badge\" [class]=\"'kf-badge--' + tone()\">\n @if (dot()) {\n <span class=\"kf-badge__dot\"></span>\n }\n <ng-content />\n </span>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-badge {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n font: inherit;\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1;\n white-space: nowrap;\n background: var(--kf-color-border);\n color: var(--kf-color-text-muted);\n }\n .kf-badge__dot {\n inline-size: 6px;\n block-size: 6px;\n border-radius: var(--kf-radius-pill);\n flex: none;\n background: currentColor;\n }\n .kf-badge--neutral {\n background: var(--kf-color-border);\n color: var(--kf-color-text-muted);\n }\n .kf-badge--ok {\n background: var(--kf-color-success-soft);\n color: var(--kf-color-success-strong);\n }\n .kf-badge--warn {\n background: var(--kf-color-warning-soft);\n color: var(--kf-color-warning-strong);\n }\n .kf-badge--error {\n background: var(--kf-color-error-soft);\n color: var(--kf-color-error-strong);\n }\n .kf-badge--info {\n background: var(--kf-color-info-soft);\n color: var(--kf-color-info-strong);\n }\n .kf-badge--service {\n background: var(--kf-color-secondary-soft);\n color: var(--kf-color-secondary-strong);\n }\n `,\n})\nexport class Badge {\n readonly tone = input<'neutral' | 'ok' | 'warn' | 'error' | 'info' | 'service'>('neutral');\n readonly dot = input(false, { transform: booleanAttribute });\n}\n","import { Component, computed, input, output } from '@angular/core';\n\nexport interface BreadcrumbItem {\n label: string;\n /** Destino del link. Sin `href` el nivel se rinde como texto plano. */\n href?: string;\n}\n\n/**\n * Ruta de navegación de las vistas internas. El último nivel es la página\n * actual: nunca es link y lleva `aria-current=\"page\"`, aunque traiga `href`.\n *\n * Se rinde como `<nav><ol>` — es una lista ordenada de ancestros, y eso es lo\n * que los lectores de pantalla anuncian (\"navegación, lista de 3 elementos\").\n *\n * Para apps con router: escuchar `itemClick` y llamar\n * `event.preventDefault()` antes de `router.navigate(...)`. El `href` se\n * mantiene igual para que click-medio, \"abrir en pestaña nueva\" y el hover\n * de la barra de estado sigan funcionando.\n *\n * <kf-breadcrumb [items]=\"[{ label: 'Inicio', href: '/' }, { label: 'Mis vehículos' }]\" />\n */\n@Component({\n selector: 'kf-breadcrumb',\n template: `\n <nav class=\"kf-breadcrumb\" aria-label=\"Ruta de navegación\">\n <ol class=\"kf-breadcrumb__list\">\n @for (item of items(); track $index; let i = $index) {\n <li class=\"kf-breadcrumb__item\">\n @if (i > 0) {\n <svg\n class=\"kf-breadcrumb__separator\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M9 6l6 6-6 6\" />\n </svg>\n }\n @if (item.href && i !== lastIndex()) {\n <a\n class=\"kf-breadcrumb__link\"\n [href]=\"item.href\"\n (click)=\"itemClick.emit({ item, index: i, event: $event })\"\n >\n {{ item.label }}\n </a>\n } @else {\n <span\n class=\"kf-breadcrumb__current\"\n [attr.aria-current]=\"i === lastIndex() ? 'page' : null\"\n >\n {{ item.label }}\n </span>\n }\n </li>\n }\n </ol>\n </nav>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n font-size: 0.875rem;\n }\n .kf-breadcrumb__list {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--kf-space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n .kf-breadcrumb__item {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n min-width: 0;\n }\n .kf-breadcrumb__separator {\n flex: none;\n width: 1em;\n height: 1em;\n fill: none;\n stroke: var(--kf-color-border-strong);\n stroke-width: 1.9;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n .kf-breadcrumb__link {\n color: var(--kf-color-primary);\n text-decoration: none;\n border-radius: var(--kf-radius-xs);\n transition: color 0.14s;\n }\n .kf-breadcrumb__link:hover {\n text-decoration: underline;\n }\n .kf-breadcrumb__link:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-breadcrumb__current {\n color: var(--kf-color-text-muted);\n overflow-wrap: anywhere;\n }\n `,\n})\nexport class Breadcrumb {\n readonly items = input.required<BreadcrumbItem[]>();\n\n /**\n * Click en un nivel con `href`. Incluye el `MouseEvent` para que un\n * consumidor con router pueda cortar la navegación nativa.\n *\n * ponytail: no dependemos de `@angular/router` acá — sería un peer dep\n * nuevo en la librería para lo que el consumidor resuelve en una línea.\n */\n readonly itemClick = output<{ item: BreadcrumbItem; index: number; event: MouseEvent }>();\n\n protected readonly lastIndex = computed(() => this.items().length - 1);\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Contenedor base con esquinas redondeadas y sombra sutil — la base visual\n * de paneles, tarjetas de métrica, tablas y bloques de contenido de todo el\n * portal (ver página 14 del design system).\n *\n * Piensa este componente como el \"cimiento\": no impone estructura interna\n * más allá de dos slots opcionales alrededor del contenido libre —\n * `[media]` para una imagen/ícono destacado arriba, y `[actions]` para una\n * fila de botones al pie, separada por una línea. El contenido por defecto\n * (sin selector) queda en el medio, sin ningún layout forzado, para que\n * cualquier composición (una métrica, una lista, un formulario) pueda vivir\n * dentro sin pelear con estilos propios del `Card`.\n *\n * <kf-card>Contenido simple</kf-card>\n * <kf-card flush>Sin sombra — para superficies ya delimitadas por otra card</kf-card>\n * <kf-card>\n * <img kf-card-media src=\"...\" alt=\"\" />\n * <h3>Título</h3>\n * <p>Descripción</p>\n * <div kf-card-actions>\n * <kf-button variant=\"ghost\">Cancelar</kf-button>\n * <kf-button>Guardar</kf-button>\n * </div>\n * </kf-card>\n */\n@Component({\n selector: 'kf-card',\n template: `\n <ng-content select=\"[kf-card-media]\" />\n <div class=\"kf-card__body\">\n <ng-content />\n </div>\n <ng-content select=\"[kf-card-actions]\" />\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-xs);\n overflow: hidden;\n }\n :host.kf-card--flush {\n box-shadow: none;\n }\n .kf-card__body {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n flex: 1 1 auto;\n }\n ::ng-deep [kf-card-media] {\n display: block;\n inline-size: 100%;\n block-size: auto;\n object-fit: cover;\n }\n ::ng-deep [kf-card-actions] {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-top: 1px solid var(--kf-color-border);\n }\n `,\n host: {\n '[class.kf-card--flush]': 'flush()',\n },\n})\nexport class Card {\n /** Quita la sombra — para cards anidadas dentro de otra superficie ya elevada. */\n readonly flush = input(false, { transform: booleanAttribute });\n}\n","import {\n AfterContentInit,\n Component,\n DestroyRef,\n contentChildren,\n inject,\n input,\n numberAttribute,\n output,\n signal,\n} from '@angular/core';\n\n/**\n * Slide individual de un `kf-carousel`. Es un contenedor mínimo: solo existe\n * para que el carrusel pueda detectar, vía `contentChildren`, cuántos slides\n * se proyectaron y en qué orden — el contenido real es responsabilidad total\n * de quien lo consume.\n *\n * <kf-carousel-slide>...</kf-carousel-slide>\n */\n@Component({\n selector: 'kf-carousel-slide',\n template: `<ng-content />`,\n styles: `\n :host {\n display: block;\n flex: 0 0 100%;\n width: 100%;\n }\n `,\n})\nexport class CarouselSlide {}\n\n/**\n * Carrusel de slides con flechas, dots y autoplay opcional.\n *\n * La spec original de React recibe `slides` como un array de nodos React.\n * En Angular eso no tiene equivalente directo: en vez de forzar un array de\n * datos crudos, cada slide se proyecta como contenido declarativo mediante\n * un `kf-carousel-slide` hijo, y el carrusel los detecta con\n * `contentChildren(CarouselSlide)`. Esto evita depender de un renderer de\n * nodos y deja que cada slide use plantillas Angular normales (bindings,\n * `@if`, `@for`, etc.) tal como se espera en este ecosistema.\n *\n * <kf-carousel [autoplay]=\"true\" [interval]=\"4000\" (indexChange)=\"onIndex($event)\">\n * <kf-carousel-slide>...</kf-carousel-slide>\n * <kf-carousel-slide>...</kf-carousel-slide>\n * </kf-carousel>\n */\n@Component({\n selector: 'kf-carousel',\n template: `\n <div\n class=\"kf-carousel\"\n (mouseenter)=\"pauseAutoplay()\"\n (mouseleave)=\"resumeAutoplay()\"\n (focusin)=\"pauseAutoplay()\"\n (focusout)=\"resumeAutoplay()\"\n >\n <div class=\"kf-carousel__viewport\">\n <div\n class=\"kf-carousel__track\"\n [style.transform]=\"'translateX(-' + activeIndex() * 100 + '%)'\"\n >\n <ng-content />\n </div>\n </div>\n\n @if (slides().length > 1) {\n <button\n type=\"button\"\n class=\"kf-carousel__arrow kf-carousel__arrow--prev\"\n aria-label=\"Slide anterior\"\n (click)=\"previous()\"\n >\n ‹\n </button>\n <button\n type=\"button\"\n class=\"kf-carousel__arrow kf-carousel__arrow--next\"\n aria-label=\"Slide siguiente\"\n (click)=\"next()\"\n >\n ›\n </button>\n\n <div class=\"kf-carousel__dots\" role=\"tablist\">\n @for (slide of slides(); track slide; let i = $index) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"kf-carousel__dot\"\n [class.kf-carousel__dot--active]=\"i === activeIndex()\"\n [attr.aria-selected]=\"i === activeIndex()\"\n [attr.aria-label]=\"'Ir al slide ' + (i + 1)\"\n (click)=\"goTo(i)\"\n ></button>\n }\n </div>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-carousel {\n position: relative;\n }\n .kf-carousel__viewport {\n overflow: hidden;\n border-radius: var(--kf-radius-md);\n }\n .kf-carousel__track {\n display: flex;\n transition: transform 0.32s ease;\n }\n .kf-carousel__arrow {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 2.25rem;\n height: 2.25rem;\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-white);\n color: var(--kf-color-ink);\n font-size: 1.25rem;\n line-height: 1;\n cursor: pointer;\n box-shadow: var(--kf-shadow-sm);\n transition:\n background 0.14s,\n border-color 0.14s;\n }\n .kf-carousel__arrow:hover {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border-strong);\n }\n .kf-carousel__arrow:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-carousel__arrow--prev {\n left: var(--kf-space-sm);\n }\n .kf-carousel__arrow--next {\n right: var(--kf-space-sm);\n }\n .kf-carousel__dots {\n display: flex;\n justify-content: center;\n gap: var(--kf-space-xs);\n margin-top: var(--kf-space-sm);\n }\n .kf-carousel__dot {\n width: 0.5rem;\n height: 0.5rem;\n padding: 0;\n border: none;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-border-strong);\n cursor: pointer;\n transition: background 0.14s;\n }\n .kf-carousel__dot:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-carousel__dot--active {\n background: var(--kf-color-primary);\n }\n `,\n})\nexport class Carousel implements AfterContentInit {\n readonly autoplay = input(false);\n readonly interval = input(5000, { transform: numberAttribute });\n readonly indexChange = output<number>();\n\n readonly slides = contentChildren(CarouselSlide);\n\n private readonly activeIndexSignal = signal(0);\n readonly activeIndex = this.activeIndexSignal.asReadonly();\n\n private readonly destroyRef = inject(DestroyRef);\n private timer: ReturnType<typeof setInterval> | null = null;\n private autoplayPaused = false;\n\n ngAfterContentInit(): void {\n this.startAutoplay();\n this.destroyRef.onDestroy(() => this.stopAutoplay());\n }\n\n next(): void {\n const total = this.slides().length;\n if (total === 0) {\n return;\n }\n this.goTo((this.activeIndexSignal() + 1) % total);\n }\n\n previous(): void {\n const total = this.slides().length;\n if (total === 0) {\n return;\n }\n this.goTo((this.activeIndexSignal() - 1 + total) % total);\n }\n\n goTo(index: number): void {\n if (index === this.activeIndexSignal()) {\n return;\n }\n this.activeIndexSignal.set(index);\n this.indexChange.emit(index);\n }\n\n pauseAutoplay(): void {\n this.autoplayPaused = true;\n }\n\n resumeAutoplay(): void {\n this.autoplayPaused = false;\n }\n\n private startAutoplay(): void {\n if (!this.autoplay() || this.slides().length <= 1) {\n return;\n }\n this.timer = setInterval(() => {\n if (!this.autoplayPaused) {\n this.next();\n }\n }, this.interval());\n }\n\n private stopAutoplay(): void {\n if (this.timer !== null) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n}\n","import {\n booleanAttribute,\n Component,\n effect,\n ElementRef,\n forwardRef,\n input,\n output,\n viewChild,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\n/**\n * Checkbox accesible con soporte de estado \"indeterminate\".\n *\n * `indeterminate` no existe como atributo HTML: el navegador solo lo expone\n * como propiedad del elemento nativo, así que se aplica a mano sobre el\n * `<input>` interno vía `viewChild` + `effect` cada vez que cambia el input.\n *\n * Implementa `ControlValueAccessor` para poder usarse con `formControlName` /\n * `ngModel` igual que un checkbox nativo. En ese modo, `writeValue` controla\n * el DOM directamente y el input `checked` (pensado para binding manual sin\n * forms) queda en su valor por defecto — igual que `disabled` combina el\n * input signal con `setDisabledState` en el resto de la librería.\n *\n * <kf-checkbox label=\"Aceptar términos\" [(checked)]=\"accepted\" />\n * <kf-checkbox label=\"Seleccionar todo\" [indeterminate]=\"isPartial()\" />\n * <kf-checkbox label=\"Notificaciones\" formControlName=\"notifications\" />\n */\n@Component({\n selector: 'kf-checkbox',\n template: `\n <label class=\"kf-checkbox\" [class.kf-checkbox--disabled]=\"disabled()\">\n <input\n #inputRef\n type=\"checkbox\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n (change)=\"onChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span class=\"kf-checkbox__box\"></span>\n @if (label()) {\n <span class=\"kf-checkbox__label\">{{ label() }}</span>\n }\n </label>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-checkbox {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-sm);\n cursor: pointer;\n font: inherit;\n font-family: var(--kf-font-body);\n color: var(--kf-color-text);\n }\n .kf-checkbox--disabled {\n cursor: not-allowed;\n color: var(--kf-color-text-muted);\n }\n .kf-checkbox input {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n .kf-checkbox__box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--kf-space-md);\n height: var(--kf-space-md);\n border: 1px solid var(--kf-color-border-strong);\n border-radius: var(--kf-radius-xs);\n background: var(--kf-color-white);\n transition:\n background 0.14s,\n border-color 0.14s;\n }\n .kf-checkbox input:checked + .kf-checkbox__box,\n .kf-checkbox input:indeterminate + .kf-checkbox__box {\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n }\n .kf-checkbox input:checked + .kf-checkbox__box::after {\n content: '';\n width: 4px;\n height: 8px;\n border: solid var(--kf-color-white);\n border-width: 0 2px 2px 0;\n transform: rotate(45deg) translate(-1px, -1px);\n }\n .kf-checkbox input:indeterminate + .kf-checkbox__box::after {\n content: '';\n width: 8px;\n height: 2px;\n background: var(--kf-color-white);\n border-radius: var(--kf-radius-xs);\n }\n .kf-checkbox input:focus-visible + .kf-checkbox__box {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-checkbox--disabled .kf-checkbox__box {\n opacity: 0.5;\n }\n .kf-checkbox__label {\n user-select: none;\n }\n `,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Checkbox),\n multi: true,\n },\n ],\n})\nexport class Checkbox implements ControlValueAccessor {\n readonly label = input<string>();\n readonly checked = input(false, { transform: booleanAttribute });\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly indeterminate = input(false, { transform: booleanAttribute });\n\n readonly checkedChange = output<boolean>();\n\n private readonly inputRef = viewChild.required<ElementRef<HTMLInputElement>>('inputRef');\n\n /** Callbacks registrados por Forms; no-op hasta que registerOnChange/Touched las reemplacen. */\n private onChangeFn: (value: boolean) => void = () => {};\n private onTouchedFn: () => void = () => {};\n\n constructor() {\n // El estado \"indeterminate\" no tiene atributo HTML: hay que empujarlo\n // como propiedad DOM cada vez que cambia el input, incluyendo el\n // valor inicial del primer render.\n effect(() => {\n this.inputRef().nativeElement.indeterminate = this.indeterminate();\n });\n }\n\n onChange(event: Event): void {\n const value = (event.target as HTMLInputElement).checked;\n this.checkedChange.emit(value);\n this.onChangeFn(value);\n }\n\n onTouched(): void {\n this.onTouchedFn();\n }\n\n writeValue(value: boolean): void {\n this.inputRef().nativeElement.checked = !!value;\n }\n\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChangeFn = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouchedFn = fn;\n }\n\n setDisabledState?(isDisabled: boolean): void {\n this.inputRef().nativeElement.disabled = isDisabled;\n }\n}\n","import { Component, input } from '@angular/core';\n\n/**\n * Chip de fondo suave con un punto líder que indica estado. Pensado\n * principalmente para celdas de tabla (estado de fila), pero utilizable\n * en cualquier lugar donde se necesite una etiqueta de estado compacta.\n *\n * <kf-chip tone=\"warn\">Pendiente</kf-chip>\n * <kf-chip tone=\"ok\">Aprobado</kf-chip>\n *\n * Nota: la spec original define la unión de tonos como \"ok\" | \"warn\" |\n * \"error\" | \"neutral\". Internamente se mapean a los tokens semánticos de\n * projects/ui/src/tokens/base.css: ok -> success, warn -> warning,\n * error -> error, neutral -> surface/border/text-muted (no existe un\n * token \"neutral\" dedicado en base.css, así que se arma con los tokens\n * de superficie/borde/texto-muted más cercanos).\n */\n@Component({\n selector: 'kf-chip',\n template: `\n <span\n class=\"kf-chip__dot\"\n [class.kf-chip__dot--ok]=\"tone() === 'ok'\"\n [class.kf-chip__dot--warn]=\"tone() === 'warn'\"\n [class.kf-chip__dot--error]=\"tone() === 'error'\"\n [class.kf-chip__dot--neutral]=\"tone() === 'neutral'\"\n ></span>\n <span class=\"kf-chip__label\"><ng-content /></span>\n `,\n styles: `\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n border: 1px solid transparent;\n font: inherit;\n font-size: 0.875em;\n line-height: 1;\n color: var(--kf-color-text);\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border);\n white-space: nowrap;\n }\n :host(.kf-chip--ok) {\n background: var(--kf-color-success-soft);\n border-color: var(--kf-color-success-soft);\n color: var(--kf-color-text);\n }\n :host(.kf-chip--warn) {\n background: var(--kf-color-warning-soft);\n border-color: var(--kf-color-warning-soft);\n color: var(--kf-color-text);\n }\n :host(.kf-chip--error) {\n background: var(--kf-color-error-soft);\n border-color: var(--kf-color-error-soft);\n color: var(--kf-color-text);\n }\n :host(.kf-chip--neutral) {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border);\n color: var(--kf-color-text);\n }\n .kf-chip__dot {\n inline-size: 0.5em;\n block-size: 0.5em;\n border-radius: var(--kf-radius-pill);\n flex: none;\n background: var(--kf-color-text-muted);\n }\n .kf-chip__label {\n display: inline-block;\n }\n .kf-chip__dot--ok {\n background: var(--kf-color-success);\n }\n .kf-chip__dot--warn {\n background: var(--kf-color-warning);\n }\n .kf-chip__dot--error {\n background: var(--kf-color-error);\n }\n .kf-chip__dot--neutral {\n background: var(--kf-color-text-muted);\n }\n `,\n host: {\n '[class.kf-chip--ok]': \"tone() === 'ok'\",\n '[class.kf-chip--warn]': \"tone() === 'warn'\",\n '[class.kf-chip--error]': \"tone() === 'error'\",\n '[class.kf-chip--neutral]': \"tone() === 'neutral'\",\n },\n})\nexport class Chip {\n readonly tone = input<'ok' | 'warn' | 'error' | 'neutral'>('neutral');\n}\n","import { Component, input } from '@angular/core';\n\n/**\n * Label superior compartido por todos los campos de formulario del design\n * system (páginas 11-12: Text Field, Select, Multiselect) — uppercase,\n * chico, gris, con letter-spacing amplio. El PDF fija un único tratamiento\n * (\"PATENTE O VIN\", \"SUCURSAL\", \"SUCURSALES\" usan exactamente el mismo\n * estilo), así que este componente es la única fuente de verdad: antes vivía\n * copiado por separado en `Input`, `Select`, `SelectMenu` y `MultiSelect`,\n * y dos de esas copias ya habían divergido del estilo real del PDF.\n *\n * No reemplaza al `<label>` nativo — lo envuelve, para no perder la\n * asociación de accesibilidad `for`/`id` con el control real.\n *\n * <kf-field-label [for]=\"inputId\">Patente o VIN</kf-field-label>\n */\n@Component({\n selector: 'kf-field-label',\n template: ` <label class=\"kf-field-label\" [for]=\"for()\"><ng-content /></label> `,\n styles: `\n :host {\n display: contents;\n }\n .kf-field-label {\n font-family: var(--kf-font-title);\n font-size: 0.75rem;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class FieldLabel {\n /** `id` del control asociado — se refleja como `for` en el `<label>` interno. */\n readonly for = input<string>();\n}\n","import {\n Component,\n ElementRef,\n HostListener,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { FieldLabel } from '../field-label/FieldLabel';\n\n/** Normalized shape used internally once `options` (string[] or object[]) is resolved. */\ninterface SelectOption {\n value: string;\n label: string;\n}\n\nlet nextId = 0;\n\n/**\n * Dropdown de selección simple con panel propio — NUNCA usa el `<select>`\n * nativo del navegador. Un `<select>` real siempre delega el popup de\n * opciones al sistema operativo, y ningún CSS puede controlar cómo se ve\n * ese popup (ver el mismo problema ya resuelto en `SelectMenu`, del que\n * este componente reutiliza el patrón completo: trigger + panel flotante\n * propio, cerrado con click-afuera y Escape).\n *\n * Pensado para sets simples y cortos. Para listas más ricas o con más\n * opciones, es el mismo componente que `SelectMenu` — la diferencia es\n * solo de estilo (label uppercase, fondo gris que pasa a blanco al foco,\n * a tono con `Input`) y que acepta `options` como `string[]` además de\n * `{ value, label }[]`.\n *\n * <kf-select label=\"Sede\" [options]=\"['Lima', 'Arequipa', 'Trujillo']\" placeholder=\"Selecciona…\" />\n * <kf-select [options]=\"[{ value: 'pe', label: 'Perú' }]\" (valueChange)=\"onCountry($event)\" />\n */\n@Component({\n selector: 'kf-select',\n imports: [FieldLabel],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n }\n <button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-select__trigger\"\n [class.kf-select__trigger--disabled]=\"disabled()\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n >\n <span class=\"kf-select__value\" [class.kf-select__value--placeholder]=\"!selectedOption()\">\n {{ selectedOption()?.label ?? placeholder() }}\n </span>\n <span\n class=\"kf-select__caret\"\n [class.kf-select__caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n </button>\n @if (isOpen()) {\n <ul\n class=\"kf-select__panel\"\n [id]=\"listboxId\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @for (option of normalizedOptions(); track option.value) {\n <li\n class=\"kf-select__option\"\n [class.kf-select__option--selected]=\"option.value === value()\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"option.value === value()\"\n (click)=\"select(option)\"\n (keydown.enter)=\"select(option)\"\n (keydown.space)=\"$event.preventDefault(); select(option)\"\n >\n {{ option.label }}\n </li>\n } @empty {\n <li class=\"kf-select__empty\">Sin opciones disponibles</li>\n }\n </ul>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n position: relative;\n font-family: var(--kf-font-body);\n }\n .kf-select__trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n width: 100%;\n font: inherit;\n color: var(--kf-color-text);\n padding: var(--kf-space-sm) var(--kf-space-md);\n /* Mismo fondo blanco que kf-select-menu: ambos aparecen lado a lado\n en un mismo formulario (ej. Sede + País), y el gris de kf-input no\n se distingue como \"campo de texto\" en un trigger de panel — solo\n se ve como una inconsistencia de color entre dos selects. */\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-select__trigger:hover:not(:disabled) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-select__trigger:focus-visible {\n outline: none;\n border-color: var(--kf-color-primary);\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-select__trigger--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-select__value {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .kf-select__value--placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-select__caret {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-text-muted);\n border-bottom: 2px solid var(--kf-color-text-muted);\n transform: rotate(45deg);\n transition: transform 0.14s;\n margin-top: -4px;\n }\n .kf-select__caret--open {\n transform: rotate(-135deg);\n margin-top: 4px;\n }\n .kf-select__panel {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 10;\n margin: var(--kf-space-xs) 0 0;\n padding: var(--kf-space-xs) 0;\n list-style: none;\n max-height: 240px;\n overflow-y: auto;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-md);\n }\n .kf-select__option {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-select__option:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-select__option--selected {\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n font-weight: 600;\n }\n .kf-select__empty {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class Select {\n readonly label = input<string>();\n readonly options = input.required<string[] | SelectOption[]>();\n readonly value = input<string>();\n readonly placeholder = input<string>('Seleccionar');\n readonly disabled = input(false, { transform: booleanAttribute });\n\n readonly valueChange = output<string>();\n\n private readonly instanceId = `kf-select-${nextId++}`;\n readonly triggerId = `${this.instanceId}-trigger`;\n readonly listboxId = `${this.instanceId}-listbox`;\n\n readonly isOpen = signal(false);\n\n /** Resolves the union (`string[] | { value; label }[]`) into a single shape for the template. */\n readonly normalizedOptions = computed<SelectOption[]>(() =>\n this.options().map((option) =>\n typeof option === 'string' ? { value: option, label: option } : option,\n ),\n );\n\n readonly selectedOption = computed(() =>\n this.normalizedOptions().find((option) => option.value === this.value()),\n );\n\n private readonly host = inject(ElementRef<HTMLElement>);\n\n toggle(): void {\n if (this.disabled()) {\n return;\n }\n this.isOpen.update((open) => !open);\n }\n\n select(option: SelectOption): void {\n this.isOpen.set(false);\n if (option.value !== this.value()) {\n this.valueChange.emit(option.value);\n }\n }\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(event: MouseEvent): void {\n if (this.isOpen() && !this.host.nativeElement.contains(event.target as Node)) {\n this.isOpen.set(false);\n }\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n this.isOpen.set(false);\n }\n}\n","import { Component, input, output } from '@angular/core';\nimport { Select } from '../select/Select';\n\n/** Metadato clave mostrado junto al selector (RUC, identificación, sucursal). */\nexport interface CompanySelectorMeta {\n label: string;\n value: string;\n}\n\n/**\n * Conmutador de empresa activa con metadatos clave (página 32) — encabeza\n * la pantalla de inicio del portal. Compone `kf-select` para el propio\n * selector (mismo panel propio, sin `<select>` nativo) y proyecta hasta 3\n * pares label/valor (RUC, Identificación, Sucursal en el ejemplo del PDF).\n *\n * <kf-company-selector\n * label=\"Selecciona empresa\"\n * [companies]=\"['TRANSPORTES DEL SUR S.A.C.', 'ANDES MAQ LTDA.']\"\n * [value]=\"activeCompany()\"\n * (valueChange)=\"activeCompany.set($event)\"\n * [meta]=\"[\n * { label: 'RUC', value: '20448712359' },\n * { label: 'Identificación', value: '0004002232' },\n * { label: 'Sucursal', value: 'Sucursal Norte' },\n * ]\"\n * />\n */\n@Component({\n selector: 'kf-company-selector',\n imports: [Select],\n template: `\n <kf-select\n class=\"kf-company-selector__select\"\n [label]=\"label()\"\n [options]=\"companies()\"\n [value]=\"value()\"\n (valueChange)=\"valueChange.emit($event)\"\n />\n @if (meta().length) {\n <div class=\"kf-company-selector__meta\">\n @for (item of meta(); track item.label) {\n <div class=\"kf-company-selector__meta-item\">\n <span class=\"kf-company-selector__meta-label\">{{ item.label }}</span>\n <span class=\"kf-company-selector__meta-value\">{{ item.value }}</span>\n </div>\n }\n </div>\n }\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-lg);\n flex-wrap: wrap;\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-company-selector__select {\n flex: 1 1 260px;\n min-width: 0;\n }\n .kf-company-selector__meta {\n display: flex;\n gap: var(--kf-space-lg);\n flex-wrap: wrap;\n }\n .kf-company-selector__meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n .kf-company-selector__meta-label {\n font-family: var(--kf-font-title);\n font-size: 0.72rem;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--kf-color-text-muted);\n }\n .kf-company-selector__meta-value {\n font-family: var(--kf-font-mono);\n font-size: 0.875rem;\n color: var(--kf-color-ink);\n }\n `,\n})\nexport class CompanySelector {\n readonly label = input('Selecciona empresa');\n readonly companies = input.required<string[]>();\n readonly value = input<string>();\n readonly meta = input<CompanySelectorMeta[]>([]);\n\n readonly valueChange = output<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Marcador genérico para contenido aún por definir (página 38) — comunica\n * \"contenido disponible para uso\" sin parecer un error, a diferencia de\n * `kf-empty-state` (que comunica ausencia real de datos del usuario).\n * Pensado para secciones del portal que un negocio todavía no completó.\n *\n * `compact` reduce el tamaño de la imagen placeholder y omite el badge de\n * pie (segunda variante de la página 38, sin la etiqueta \"Contenido\n * disponible para uso\" al final).\n *\n * <kf-content-slot title=\"Contenido disponible\"\n * description=\"Espacio reservado para contenido de Divemotor Perú. Disponible para uso.\" />\n * <kf-content-slot compact icon=\"star\" title=\"Contenido disponible\"\n * description=\"Espacio reservado para contenido de Divemotor Perú.\" />\n */\n@Component({\n selector: 'kf-content-slot',\n imports: [Icon],\n template: `\n <div class=\"kf-content-slot__media\">\n <kf-icon [name]=\"icon()\" [size]=\"compact() ? 'md' : 'lg'\" />\n </div>\n <span class=\"kf-content-slot__title\">{{ title() }}</span>\n @if (description()) {\n <p class=\"kf-content-slot__description\">{{ description() }}</p>\n }\n @if (!compact()) {\n <span class=\"kf-content-slot__footer\">Contenido disponible para uso</span>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-content-slot__media {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 96px;\n margin-bottom: var(--kf-space-xs);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-surface);\n color: var(--kf-color-border-strong);\n }\n :host(.kf-content-slot--compact) .kf-content-slot__media {\n height: 56px;\n }\n .kf-content-slot__title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-content-slot__description {\n margin: 0;\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-content-slot__footer {\n align-self: flex-start;\n margin-top: var(--kf-space-xs);\n padding: 2px var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-surface);\n color: var(--kf-color-text-muted);\n font-size: 0.72rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n `,\n host: {\n '[class.kf-content-slot--compact]': 'compact()',\n },\n})\nexport class ContentSlot {\n readonly title = input('Contenido disponible');\n readonly description = input<string>();\n readonly icon = input<IconName>('layers');\n readonly compact = input(false, { transform: booleanAttribute });\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Placeholder para una sección sin contenido. Dos tonos, con anatomía\n * distinta (páginas 27-28 del design system, que los trata como piezas\n * separadas — \"Error State\" no es una variante de color de \"Empty State\",\n * es un estado semánticamente distinto):\n *\n * - `neutral` (default): \"cero resultados\" — cuadro con borde punteado\n * discreto, para listas vacías o búsquedas sin coincidencias. No es un\n * error, es la ausencia normal de datos.\n * - `error`: fallo real de carga — sin borde punteado, con un ícono de\n * alerta más prominente y texto en el tono de error. Pensado para usarse\n * junto a un botón \"Reintentar\" en el slot por defecto.\n *\n * <kf-empty-state>No se encontraron resultados.</kf-empty-state>\n * <kf-empty-state icon=\"search\">Sin coincidencias para tu búsqueda.</kf-empty-state>\n * <kf-empty-state tone=\"error\" icon=\"alert-triangle\">\n * No pudimos cargar tus vehículos\n * <kf-button (click)=\"retry()\">Reintentar</kf-button>\n * </kf-empty-state>\n */\n@Component({\n selector: 'kf-empty-state',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <span class=\"kf-empty-state__icon\">\n <kf-icon [name]=\"iconName\" [size]=\"tone() === 'error' ? 'lg' : 'md'\" />\n </span>\n }\n <div class=\"kf-empty-state__content\">\n <ng-content />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-xl);\n border: 1px dashed var(--kf-color-border-strong);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-surface);\n color: var(--kf-color-text-muted);\n font: inherit;\n text-align: center;\n }\n :host(.kf-empty-state--error) {\n border: none;\n background: var(--kf-color-error-soft);\n }\n .kf-empty-state__content {\n color: var(--kf-color-text-muted);\n font-family: var(--kf-font-body);\n }\n :host(.kf-empty-state--error) .kf-empty-state__content {\n color: var(--kf-color-error-strong);\n }\n `,\n host: {\n '[class.kf-empty-state--error]': \"tone() === 'error'\",\n },\n})\nexport class EmptyState {\n readonly icon = input<IconName | undefined>(undefined);\n /** `neutral` (default): cero resultados. `error`: fallo real de carga. */\n readonly tone = input<'neutral' | 'error'>('neutral');\n}\n","import { Component, input } from '@angular/core';\n\n/** Forma del placeholder. */\nexport type SkeletonVariant = 'text' | 'circle' | 'rect';\n\n/**\n * Bloque placeholder con shimmer para contenido que todavía carga: una línea\n * de texto, un avatar o un área de card/imagen, según `variant`.\n *\n * Es decorativo (`aria-hidden`): quien lo usa debería marcar el contenedor con\n * `aria-busy=\"true\"` mientras carga, así el lector de pantalla anuncia el\n * estado una vez en vez de leer N placeholders vacíos.\n *\n * `circle` usa `aspect-ratio`, así que alcanza con darle `width`.\n *\n * <kf-skeleton />\n * <kf-skeleton variant=\"circle\" width=\"40px\" />\n * <kf-skeleton variant=\"rect\" width=\"100%\" height=\"120px\" />\n */\n@Component({\n selector: 'kf-skeleton',\n template: `\n <span\n class=\"kf-skeleton\"\n [class]=\"'kf-skeleton--' + variant()\"\n aria-hidden=\"true\"\n [style.width]=\"width()\"\n [style.height]=\"height() || null\"\n ></span>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-skeleton {\n display: block;\n background: linear-gradient(\n 90deg,\n var(--kf-color-border) 25%,\n var(--kf-color-surface) 37%,\n var(--kf-color-border) 63%\n );\n background-size: 400% 100%;\n animation: kf-skeleton-shimmer 1.4s ease infinite;\n }\n .kf-skeleton--text {\n height: 14px;\n border-radius: var(--kf-radius-xs);\n }\n .kf-skeleton--rect {\n height: 80px;\n border-radius: var(--kf-radius-sm);\n }\n .kf-skeleton--circle {\n aspect-ratio: 1 / 1;\n border-radius: var(--kf-radius-pill);\n }\n @keyframes kf-skeleton-shimmer {\n from {\n background-position: 100% 0;\n }\n to {\n background-position: 0 0;\n }\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-skeleton {\n animation: none;\n background: var(--kf-color-border);\n }\n }\n `,\n})\nexport class Skeleton {\n readonly variant = input<SkeletonVariant>('text');\n /** Ancho CSS. Default `'100%'`. */\n readonly width = input('100%');\n /** Alto CSS. Vacío deja el alto/aspect-ratio propio de la variante. */\n readonly height = input('');\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\nexport type SpinnerSize = 'sm' | 'md' | 'lg';\n\n/**\n * Indicador de carga indeterminado: inline, dentro de un botón, o como único\n * contenido de una sección mientras llega la data.\n *\n * Cuando se conoce la forma del contenido que viene, preferir `kf-skeleton`\n * (dibuja la silueta). El spinner es para \"algo está pasando\" sin forma\n * conocida — guardar, enviar, reintentar.\n *\n * Lleva `role=\"status\"`, así que el lector de pantalla anuncia el `label`\n * cuando aparece. Sin `label` cae en un texto accesible por defecto.\n *\n * <kf-spinner />\n * <kf-spinner size=\"sm\" label=\"Cargando…\" />\n * <kf-spinner onDark />\n */\n@Component({\n selector: 'kf-spinner',\n template: `\n <span class=\"kf-spinner\" [class.kf-spinner--on-dark]=\"onDark()\" role=\"status\">\n <span class=\"kf-spinner__ring\" [class]=\"'kf-spinner__ring--' + size()\"></span>\n @if (label()) {\n <span class=\"kf-spinner__label\">{{ label() }}</span>\n } @else {\n <span class=\"kf-spinner__sr\">Cargando</span>\n }\n </span>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-spinner {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-sm);\n font-family: var(--kf-font-body);\n }\n .kf-spinner__ring {\n display: inline-block;\n flex: none;\n border-radius: var(--kf-radius-pill);\n border: 2px solid var(--kf-color-border);\n border-top-color: var(--kf-color-primary);\n animation: kf-spinner-turn 0.7s linear infinite;\n }\n .kf-spinner__ring--sm {\n width: 16px;\n height: 16px;\n }\n .kf-spinner__ring--md {\n width: 24px;\n height: 24px;\n border-width: 3px;\n }\n .kf-spinner__ring--lg {\n width: 32px;\n height: 32px;\n border-width: 3px;\n }\n .kf-spinner__label {\n font-size: 0.875rem;\n color: var(--kf-color-text-muted);\n }\n /* Sobre superficies oscuras (carousel, feature card, barra de admin). */\n .kf-spinner--on-dark .kf-spinner__ring {\n border-color: rgba(255, 255, 255, 0.28);\n border-top-color: var(--kf-color-white);\n }\n .kf-spinner--on-dark .kf-spinner__label {\n color: var(--kf-color-white);\n }\n @keyframes kf-spinner-turn {\n to {\n transform: rotate(360deg);\n }\n }\n .kf-spinner__sr {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-spinner__ring {\n animation-duration: 2s;\n }\n }\n `,\n})\nexport class Spinner {\n readonly size = input<SpinnerSize>('md');\n /** Texto al lado del anillo. Vacío deja solo el anillo (y el texto para lectores). */\n readonly label = input('');\n /** Invierte los colores para fondos oscuros. */\n readonly onDark = input(false, { transform: booleanAttribute });\n}\n","import { Component, input } from '@angular/core';\nimport { EmptyState } from '../empty-state/EmptyState';\nimport { Skeleton } from '../skeleton/Skeleton';\nimport { Spinner } from '../spinner/Spinner';\n\n/** En qué estado está la sección. */\nexport type ContentStateKind = 'ready' | 'loading' | 'empty' | 'error';\n\n/** Cómo se dibuja `loading`. Default `'skeleton'`. */\nexport type ContentStateLoad = 'skeleton' | 'spinner';\n\n/**\n * Wrapper de los cuatro estados que toda sección tiene: cargando, con datos,\n * vacía y con error. Un componente en vez de tres `@if` sueltos, porque es\n * siempre el mismo slot el que va rotando entre los cuatro.\n *\n * Con `state=\"ready\"` proyecta el contenido real y desaparece; en los otros\n * tres dibuja el placeholder correspondiente y el contenido no se instancia.\n * No inventa visuales propios: `loading` usa `kf-skeleton` (o `kf-spinner` con\n * `load=\"spinner\"`), y `empty`/`error` usan `kf-empty-state`.\n *\n * Las acciones (reintentar, crear) van en el slot `actions` — se ignoran\n * mientras carga, porque no hay nada que reintentar todavía.\n *\n * <kf-content-state [state]=\"state()\" title=\"No pudimos cargar tus vehículos\"\n * subtitle=\"Revisá tu conexión e intentá de nuevo.\">\n * <kf-button actions (click)=\"retry()\">Reintentar</kf-button>\n * <kf-data-table [columns]=\"cols\" [rows]=\"rows()\" />\n * </kf-content-state>\n */\n@Component({\n selector: 'kf-content-state',\n imports: [EmptyState, Skeleton, Spinner],\n template: `\n @switch (state()) {\n @case ('ready') {\n <ng-content />\n }\n @case ('loading') {\n <div class=\"kf-content-state__loading\" aria-busy=\"true\">\n @if (load() === 'spinner') {\n <kf-spinner [label]=\"loadingLabel()\" />\n } @else {\n <kf-skeleton />\n <kf-skeleton width=\"80%\" />\n <kf-skeleton width=\"60%\" />\n }\n </div>\n }\n @default {\n <kf-empty-state [tone]=\"state() === 'error' ? 'error' : 'neutral'\">\n @if (title()) {\n <p class=\"kf-content-state__title\">{{ title() }}</p>\n }\n @if (subtitle()) {\n <p class=\"kf-content-state__subtitle\">{{ subtitle() }}</p>\n }\n <div class=\"kf-content-state__actions\"><ng-content select=\"[actions]\" /></div>\n </kf-empty-state>\n }\n }\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-content-state__loading {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-sm);\n }\n .kf-content-state__title {\n margin: 0;\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-content-state__subtitle {\n margin: 0;\n color: var(--kf-color-text-muted);\n }\n .kf-content-state__actions:empty {\n display: none;\n }\n .kf-content-state__actions {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n gap: var(--kf-space-sm);\n margin-top: var(--kf-space-sm);\n }\n `,\n})\nexport class ContentState {\n readonly state = input.required<ContentStateKind>();\n /** Forma del estado de carga: silueta (default) o spinner. */\n readonly load = input<ContentStateLoad>('skeleton');\n /** Título de `empty`/`error`. Ignorado mientras carga. */\n readonly title = input('');\n readonly subtitle = input('');\n /** Texto al lado del spinner cuando `load=\"spinner\"`. */\n readonly loadingLabel = input('Cargando…');\n}\n","import { Component, computed, input, output, signal, TemplateRef } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\n\n/**\n * Zona que ocupa la columna en la vista de cards. La vista de tabla ignora\n * esto (salvo `media`, que igual se rinde como thumbnail en vez de imprimir\n * la URL):\n * - `media`: thumbnail a la izquierda del encabezado; el valor de la celda se\n * usa como `src` salvo que la columna traiga su `cellTemplates`.\n * - `title`: título del encabezado (ej. la patente/unidad).\n * - `status`: chip/estado al lado del título.\n * - `field` (default): par label/valor en el cuerpo.\n * - `action`: va al pie, separado del cuerpo por una línea.\n */\nexport type DataTableCardRole = 'media' | 'title' | 'status' | 'field' | 'action';\n\nexport interface DataTableColumn {\n key: string;\n label: string;\n right?: boolean;\n className?: string;\n cardRole?: DataTableCardRole;\n}\n\n/** Vistas disponibles cuando `cardable` está activo. */\nexport type DataTableView = 'table' | 'cards';\n\n/**\n * Tabla estandarizada con soporte opcional de toggle tabla/cards.\n *\n * El \"render\" custom por columna de la spec original (una función que\n * devuelve JSX) se resuelve acá de dos formas, de la más simple a la más\n * flexible:\n * - `render`: función `(row) => string` para el caso típico de mostrar un\n * valor derivado/formateado de la fila como texto plano.\n * - `cellTemplates`: mapa `key -> TemplateRef` para cuando un consumidor\n * necesita marcado real dentro de una celda (badges, links, botones). Se\n * proyecta con `ngTemplateOutlet` y recibe `{ $implicit: row, index }`.\n * Se eligió esta combinación en vez de content-projection por columna\n * (ng-content con selector) porque las columnas son dinámicas (vienen de\n * `columns()`), y `ngTemplateOutlet` es el mecanismo estándar de Angular\n * para \"insertar esta plantilla por cada fila de este array\".\n *\n * En la vista de cards, `cardRole` por columna reparte el contenido en zonas\n * — encabezado (thumbnail + título + estado), cuerpo (pares label/valor) y\n * pie separado por una línea para las acciones. Sin `cardRole`, todas las\n * columnas caen en el cuerpo, igual que antes.\n *\n * El modo `cards` no depende de un componente ViewToggle separado: expone\n * un control de segmentos mínimo inline (mismo patrón visual que\n * kf-segmented) para no acoplarse a un componente que otro agente puede\n * estar construyendo en paralelo — ver nota en el resumen de la tarea.\n *\n * <kf-data-table [columns]=\"columns\" [rows]=\"rows\" (rowClick)=\"onRowClick($event)\">\n * <kf-empty-state empty>No hay resultados para mostrar.</kf-empty-state>\n * </kf-data-table>\n *\n * <kf-data-table [columns]=\"columns\" [rows]=\"rows\" [cardable]=\"true\" defaultView=\"cards\" />\n *\n * El slot `[footer]` (página 15: \"slot de pie para paginación\") va siempre\n * al final, en ambas vistas, separado por una línea — pensado para proyectar\n * `<kf-pagination>`, que sigue siendo un componente independiente.\n *\n * <kf-data-table [columns]=\"columns\" [rows]=\"rows\">\n * <kf-pagination footer [page]=\"page()\" [total]=\"total()\" (pageChange)=\"page.set($event)\" />\n * </kf-data-table>\n */\n@Component({\n selector: 'kf-data-table',\n imports: [NgTemplateOutlet],\n template: `\n <div class=\"kf-data-table\" [class.kf-data-table--flush]=\"flush()\">\n @if (cardable()) {\n <div class=\"kf-data-table__toolbar\">\n <div class=\"kf-data-table__view-toggle\" role=\"group\" aria-label=\"Cambiar vista\">\n <button\n type=\"button\"\n class=\"kf-data-table__view-option\"\n [class.kf-data-table__view-option--active]=\"view() === 'table'\"\n [attr.aria-pressed]=\"view() === 'table'\"\n (click)=\"setView('table')\"\n >\n Tabla\n </button>\n <button\n type=\"button\"\n class=\"kf-data-table__view-option\"\n [class.kf-data-table__view-option--active]=\"view() === 'cards'\"\n [attr.aria-pressed]=\"view() === 'cards'\"\n (click)=\"setView('cards')\"\n >\n Tarjetas\n </button>\n </div>\n </div>\n }\n\n @if (rows().length === 0) {\n <div class=\"kf-data-table__empty\">\n <ng-content select=\"[empty]\" />\n </div>\n } @else if (view() === 'table') {\n <div class=\"kf-data-table__scroll\">\n <table class=\"kf-data-table__table\">\n <thead>\n <tr>\n @for (column of columns(); track column.key) {\n <th [class]=\"column.className\" [class.kf-data-table__cell--right]=\"column.right\">\n {{ column.label }}\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track trackRow(row, $index); let i = $index) {\n <tr\n class=\"kf-data-table__row\"\n tabindex=\"0\"\n (click)=\"onRowClick(row, i)\"\n (keydown.enter)=\"onRowClick(row, i)\"\n >\n @for (column of columns(); track column.key) {\n <td\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"column.right\"\n >\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else if (column.cardRole === 'media') {\n <img class=\"kf-data-table__thumb\" [src]=\"cellValue(row, column)\" alt=\"\" />\n } @else {\n {{ cellValue(row, column) }}\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n } @else {\n <div class=\"kf-data-table__cards\">\n @for (row of rows(); track trackRow(row, $index); let i = $index) {\n <div\n class=\"kf-data-table__card\"\n [class.kf-data-table__card--interactive]=\"cardInteractive()\"\n [attr.role]=\"cardInteractive() ? 'button' : null\"\n [attr.tabindex]=\"cardInteractive() ? 0 : null\"\n (click)=\"cardInteractive() && onRowClick(row, i)\"\n (keydown.enter)=\"cardInteractive() && onRowClick(row, i)\"\n >\n @if (cardMediaColumn() || cardTitleColumn() || cardStatusColumns().length) {\n <div class=\"kf-data-table__card-header\">\n @if (cardMediaColumn(); as media) {\n <div class=\"kf-data-table__card-media\">\n @if (cellTemplates()?.[media.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n <img [src]=\"cellValue(row, media)\" alt=\"\" />\n }\n </div>\n }\n <div class=\"kf-data-table__card-heading\">\n @if (cardTitleColumn(); as title) {\n <span class=\"kf-data-table__card-title\">\n @if (cellTemplates()?.[title.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, title) }}\n }\n </span>\n }\n @if (cardStatusColumns().length) {\n <span class=\"kf-data-table__card-statuses\">\n @for (column of cardStatusColumns(); track column.key) {\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n }\n </span>\n }\n </div>\n </div>\n }\n\n @if (cardFieldColumns().length) {\n <div class=\"kf-data-table__card-fields\">\n @for (column of cardFieldColumns(); track column.key) {\n <div class=\"kf-data-table__card-field\">\n <span class=\"kf-data-table__card-label\">{{ column.label }}</span>\n <span class=\"kf-data-table__card-value\">\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n </span>\n </div>\n }\n </div>\n }\n\n @if (cardActionColumns().length) {\n <div class=\"kf-data-table__card-actions\">\n @for (column of cardActionColumns(); track column.key) {\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (rows().length > 0) {\n <div class=\"kf-data-table__footer\">\n <ng-content select=\"[footer]\" />\n </div>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-data-table {\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-sm);\n overflow: hidden;\n }\n .kf-data-table--flush {\n border: none;\n box-shadow: none;\n border-radius: 0;\n }\n .kf-data-table__toolbar {\n display: flex;\n justify-content: flex-end;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-bottom: 1px solid var(--kf-color-border);\n }\n .kf-data-table__view-toggle {\n display: inline-flex;\n gap: 2px;\n padding: 2px;\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n }\n .kf-data-table__view-option {\n font: inherit;\n font-size: 0.875em;\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border: none;\n background: transparent;\n color: var(--kf-color-text-muted);\n border-radius: var(--kf-radius-xs);\n cursor: pointer;\n transition:\n background 0.14s,\n color 0.14s;\n }\n .kf-data-table__view-option:hover:not(.kf-data-table__view-option--active) {\n color: var(--kf-color-text);\n }\n .kf-data-table__view-option--active {\n background: var(--kf-color-white);\n color: var(--kf-color-ink);\n box-shadow: var(--kf-shadow-xs);\n }\n .kf-data-table__view-option:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n\n .kf-data-table__scroll {\n overflow-x: auto;\n }\n .kf-data-table__table {\n width: 100%;\n border-collapse: collapse;\n text-align: left;\n }\n .kf-data-table__table th,\n .kf-data-table__table td {\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-bottom: 1px solid var(--kf-color-border);\n white-space: nowrap;\n }\n .kf-data-table__table th {\n font-family: var(--kf-font-title);\n font-size: 0.8125em;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n color: var(--kf-color-text-muted);\n background: var(--kf-color-surface);\n }\n .kf-data-table__table td {\n color: var(--kf-color-text);\n }\n .kf-data-table__table tbody tr:last-child td {\n border-bottom: none;\n }\n .kf-data-table__row {\n cursor: pointer;\n transition: background 0.14s;\n }\n .kf-data-table__row:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-data-table__cell--right {\n text-align: right;\n }\n\n .kf-data-table__empty {\n padding: var(--kf-space-md);\n }\n\n .kf-data-table__footer {\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-top: 1px solid var(--kf-color-border);\n }\n .kf-data-table__footer:empty {\n display: none;\n }\n\n .kf-data-table__cards {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));\n gap: var(--kf-space-md);\n padding: var(--kf-space-md);\n }\n .kf-data-table__card {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n overflow: hidden;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-data-table__card--interactive {\n cursor: pointer;\n }\n .kf-data-table__card:hover {\n border-color: var(--kf-color-border-strong);\n box-shadow: var(--kf-shadow-xs);\n }\n .kf-data-table__card--interactive:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n\n .kf-data-table__card-header {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-md);\n }\n .kf-data-table__card-media {\n flex: none;\n }\n .kf-data-table__card-media img,\n .kf-data-table__thumb {\n display: block;\n width: 48px;\n height: 48px;\n border-radius: var(--kf-radius-xs);\n object-fit: cover;\n background: var(--kf-color-surface);\n }\n .kf-data-table__card-heading {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n min-width: 0;\n }\n .kf-data-table__card-title {\n font-family: var(--kf-font-title);\n font-weight: 600;\n color: var(--kf-color-ink);\n overflow-wrap: anywhere;\n }\n .kf-data-table__card-statuses,\n .kf-data-table__card-actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kf-space-xs);\n }\n\n .kf-data-table__card-fields {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n }\n /* El encabezado ya aportó el padding de arriba. */\n .kf-data-table__card-header + .kf-data-table__card-fields {\n padding-top: 0;\n }\n .kf-data-table__card-field {\n display: flex;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n }\n .kf-data-table__card-actions {\n justify-content: flex-end;\n margin-top: auto;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-top: 1px solid var(--kf-color-border);\n background: var(--kf-color-surface);\n }\n\n .kf-data-table__thumb {\n width: 32px;\n height: 32px;\n }\n .kf-data-table__card-label {\n font-family: var(--kf-font-title);\n font-size: 0.8125em;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n color: var(--kf-color-text-muted);\n }\n .kf-data-table__card-value {\n color: var(--kf-color-text);\n text-align: right;\n }\n `,\n})\nexport class DataTable<T = unknown> {\n readonly columns = input.required<DataTableColumn[]>();\n readonly rows = input.required<T[]>();\n /** Default: índice de la fila dentro de `rows`. */\n readonly rowKey = input<(row: T, index: number) => string | number>();\n /** Sin borde/sombra de card — para tablas anidadas dentro de otra card. */\n readonly flush = input(false);\n /** Habilita el toggle de vista tabla/cards. */\n readonly cardable = input(false);\n readonly defaultView = input<DataTableView>('table');\n /**\n * Formateo simple de celda como texto: `(row) => string`. Para marcado\n * real (badges, links, botones) usar `cellTemplates`.\n */\n readonly render = input<(row: T) => string>();\n /** Mapa `columnKey -> TemplateRef` para celdas con contenido custom. */\n readonly cellTemplates = input<\n Record<string, TemplateRef<{ $implicit: T; index: number }>> | undefined\n >();\n\n readonly rowClick = output<{ row: T; index: number }>();\n\n private readonly internalView = signal<DataTableView | null>(null);\n\n /** Vista activa: la elegida por el usuario, o `defaultView` si no tocó el toggle. */\n readonly view = computed<DataTableView>(() => this.internalView() ?? this.defaultView());\n\n /** Primera columna de cada rol único; el resto se ignora en el encabezado. */\n readonly cardMediaColumn = computed(() => this.columns().find((c) => c.cardRole === 'media'));\n readonly cardTitleColumn = computed(() => this.columns().find((c) => c.cardRole === 'title'));\n readonly cardStatusColumns = computed(() =>\n this.columns().filter((c) => c.cardRole === 'status'),\n );\n readonly cardActionColumns = computed(() =>\n this.columns().filter((c) => c.cardRole === 'action'),\n );\n readonly cardFieldColumns = computed(() =>\n this.columns().filter((c) => !c.cardRole || c.cardRole === 'field'),\n );\n\n /**\n * La card entera es clickeable solo si no tiene acciones propias: un\n * `role=\"button\"` con botones adentro es inválido y deja el foco ambiguo.\n * Con columnas `action`, la interacción la manejan esos botones.\n */\n readonly cardInteractive = computed(() => this.cardActionColumns().length === 0);\n\n setView(next: DataTableView): void {\n this.internalView.set(next);\n }\n\n trackRow(row: T, index: number): string | number {\n const keyFn = this.rowKey();\n return keyFn ? keyFn(row, index) : index;\n }\n\n cellValue(row: T, column: DataTableColumn): string {\n const renderFn = this.render();\n if (renderFn) {\n return renderFn(row);\n }\n const value = (row as Record<string, unknown>)[column.key];\n return value === null || value === undefined ? '' : String(value);\n }\n\n onRowClick(row: T, index: number): void {\n this.rowClick.emit({ row, index });\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Bloque promocional sobre fondo oscuro de marca (página 37) — campañas,\n * accesos directos o el portal de autoatención. Usa `--kf-color-tertiary-deep`\n * como base del degradado, el mismo azul profundo que el slide destacado de\n * `kf-carousel` y la barra de `kf-portal-header`.\n *\n * <kf-feature-card badge=\"Autoatención\" badgeIcon=\"tool\" title=\"Portal de Autoatención\"\n * description=\"Con tu patente o VIN accede a soluciones para tu vehículo: mantenciones, repuestos y conectividad en un solo lugar.\"\n * actionLabel=\"Ir al portal\" actionHref=\"/autoatencion\" />\n */\n@Component({\n selector: 'kf-feature-card',\n imports: [Icon],\n template: `\n @if (badge()) {\n <span class=\"kf-feature-card__badge\">\n @if (badgeIcon(); as iconName) {\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n }\n {{ badge() }}\n </span>\n }\n <span class=\"kf-feature-card__title\">{{ title() }}</span>\n @if (description()) {\n <p class=\"kf-feature-card__description\">{{ description() }}</p>\n }\n @if (actionLabel()) {\n <a class=\"kf-feature-card__action\" [href]=\"actionHref() || '#'\">\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n {{ actionLabel() }}\n </a>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-lg);\n border-radius: var(--kf-radius-md);\n background: linear-gradient(\n 135deg,\n var(--kf-color-primary-active) 0%,\n var(--kf-color-tertiary-deep) 100%\n );\n color: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-feature-card__badge {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n background: rgba(255, 255, 255, 0.12);\n border: 1px solid rgba(255, 255, 255, 0.24);\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n }\n .kf-feature-card__title {\n font-family: var(--kf-font-title);\n font-size: 1.375rem;\n font-weight: 700;\n line-height: 1.2;\n }\n .kf-feature-card__description {\n margin: 0;\n max-width: 48ch;\n color: rgba(255, 255, 255, 0.8);\n font-size: 0.9375rem;\n }\n .kf-feature-card__action {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n margin-top: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-md);\n border-radius: var(--kf-radius-sm);\n background: rgba(255, 255, 255, 0.14);\n color: var(--kf-color-white);\n font-size: 0.875rem;\n font-weight: 600;\n text-decoration: none;\n transition: background 0.14s;\n }\n .kf-feature-card__action:hover {\n background: rgba(255, 255, 255, 0.22);\n }\n `,\n})\nexport class FeatureCard {\n readonly badge = input<string>();\n readonly badgeIcon = input<IconName>();\n readonly title = input.required<string>();\n readonly description = input<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Chip de solo-lectura inline (label/valor) dentro de una caja bordeada.\n * Se usa en barras de filtro y filas de resumen para mostrar información,\n * NO para entrada de datos — para eso existe `Input`.\n *\n * El valor admite dos formas, igual que en el design system de referencia:\n * - `value` (string): caso simple, ej. `[value]=\"'Jul 2026'\"`.\n * - contenido proyectado (`<ng-content>`): cuando se necesita algo más rico\n * que un string (un badge, texto con formato, etc.).\n * `value` tiene prioridad cuando está definido; si no se pasa `value`, se\n * renderiza el contenido proyectado y, si tampoco hay contenido, `placeholder`.\n *\n * <kf-field icon=\"calendar\" label=\"Periodo\" value=\"Jul 2026\" [select]=\"true\" />\n * <kf-field label=\"Sucursal\"><strong>Casa Central</strong></kf-field>\n */\n@Component({\n selector: 'kf-field',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-field__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n @if (label()) {\n <span class=\"kf-field__label\">{{ label() }}</span>\n }\n <span class=\"kf-field__value\">\n @if (value()) {\n {{ value() }}\n } @else {\n <ng-content></ng-content>\n @if (isPlaceholderVisible()) {\n <span class=\"kf-field__placeholder\">{{ placeholder() }}</span>\n }\n }\n </span>\n @if (select()) {\n <kf-icon class=\"kf-field__chevron\" name=\"chevron-down\" size=\"sm\" />\n }\n `,\n styles: `\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-surface);\n font: inherit;\n font-family: var(--kf-font-body);\n color: var(--kf-color-text);\n line-height: 1.2;\n }\n :host(.kf-field--select) {\n cursor: pointer;\n }\n :host(.kf-field--select:hover) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-field__icon {\n color: var(--kf-color-text-muted);\n }\n .kf-field__label {\n color: var(--kf-color-text-muted);\n white-space: nowrap;\n }\n .kf-field__value {\n font-weight: 500;\n color: var(--kf-color-ink);\n white-space: nowrap;\n }\n .kf-field__placeholder {\n color: var(--kf-color-text-muted);\n font-weight: 400;\n }\n .kf-field__chevron {\n color: var(--kf-color-text-muted);\n }\n `,\n host: {\n '[class.kf-field--select]': 'select()',\n '[attr.style]': 'style() || null',\n },\n})\nexport class Field {\n readonly label = input<string>();\n readonly value = input<string>();\n readonly icon = input<IconName>();\n readonly placeholder = input<string>();\n readonly select = input(false, { transform: booleanAttribute });\n /** Estilos inline opcionales aplicados directamente al host. */\n readonly style = input<string>();\n\n /**\n * El placeholder solo tiene sentido cuando no hay `value` ni contenido\n * proyectado. Angular no expone de forma simple si `<ng-content>` recibió\n * hijos reales, así que la regla adoptada es puramente declarativa: se\n * muestra el placeholder cuando hay texto de placeholder y no hay `value`\n * (ver comentario de clase sobre la prioridad value > proyectado > placeholder).\n */\n protected isPlaceholderVisible(): boolean {\n return !this.value() && !!this.placeholder();\n }\n}\n","import { Component, computed, input, output } from '@angular/core';\n\n/** Forma normalizada interna de cada opción, ya resuelta a value/label. */\ninterface FilterChipOption {\n value: string;\n label: string;\n}\n\n/**\n * Fila de chips tipo \"pill\" para filtros de una sola selección.\n *\n * Cada opción puede pasarse como string simple (se usa como value y label\n * a la vez) o como objeto { value, label } cuando el texto mostrado difiere\n * del valor interno.\n *\n * El chip activo se resalta con el color \"ink\" oscuro (--kf-color-ink), no\n * con el color primario de marca: así lo define el sistema de diseño de\n * referencia para este componente en particular.\n *\n * <kf-filter-chips [options]=\"['Todos', 'Activos', 'Archivados']\"\n * [value]=\"filtro\"\n * (valueChange)=\"filtro = $event\" />\n *\n * <kf-filter-chips [options]=\"[{ value: 'all', label: 'Todos' }]\"\n * [value]=\"filtro\"\n * (valueChange)=\"filtro = $event\" />\n */\n@Component({\n selector: 'kf-filter-chips',\n template: `\n <div class=\"kf-filter-chips\" role=\"group\">\n @for (option of normalizedOptions(); track option.value) {\n <button\n type=\"button\"\n class=\"kf-filter-chips__chip\"\n [class.kf-filter-chips__chip--active]=\"option.value === value()\"\n [attr.aria-pressed]=\"option.value === value()\"\n (click)=\"select(option.value)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-filter-chips {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kf-space-xs);\n }\n .kf-filter-chips__chip {\n font: inherit;\n padding: var(--kf-space-xs) var(--kf-space-md);\n border-radius: var(--kf-radius-pill);\n border: 1px solid var(--kf-color-border);\n background: var(--kf-color-surface);\n color: var(--kf-color-text);\n cursor: pointer;\n transition:\n background 0.14s,\n border-color 0.14s,\n color 0.14s;\n }\n .kf-filter-chips__chip:hover:not(.kf-filter-chips__chip--active) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-filter-chips__chip:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-filter-chips__chip--active {\n background: var(--kf-color-ink);\n border-color: var(--kf-color-ink);\n color: var(--kf-color-white);\n }\n `,\n})\nexport class FilterChips {\n readonly options = input.required<(string | { value: string; label: string })[]>();\n readonly value = input<string>('');\n\n readonly valueChange = output<string>();\n\n /** Normaliza cada opción string/objeto a la forma { value, label }. */\n readonly normalizedOptions = computed<FilterChipOption[]>(() =>\n this.options().map((option) =>\n typeof option === 'string' ? { value: option, label: option } : option,\n ),\n );\n\n select(value: string): void {\n if (value === this.value()) {\n return;\n }\n this.valueChange.emit(value);\n }\n}\n","import { Component, input, output } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\nexport interface FolderTabOption {\n value: string;\n label: string;\n icon?: IconName;\n}\n\n/**\n * Tabs con forma de \"carpeta\": el borde superior queda redondeado y el borde\n * inferior de la pestaña activa se funde visualmente con el panel de\n * contenido que va debajo (misma superficie, sin línea divisoria).\n *\n * Al cambiar de pestaña, la que se activa se \"abre\": gira sobre su borde\n * inferior (hinge 3D) y sube con un pequeño rebote. Es CSS solo: la clase\n * `--active` se mueve de un botón a otro, y eso vuelve a disparar el keyframe\n * sin tocar JS.\n *\n * El consumidor es responsable de renderizar el panel de contenido debajo;\n * este componente solo resuelve la fila de pestañas y emite `valueChange`.\n *\n * <kf-folder-tabs [options]=\"tabs\" [value]=\"active\" (valueChange)=\"active = $event\" />\n */\n@Component({\n selector: 'kf-folder-tabs',\n imports: [Icon],\n template: `\n <div class=\"kf-folder-tabs\" role=\"tablist\">\n @for (option of options(); track option.value) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"kf-folder-tabs__tab\"\n [class.kf-folder-tabs__tab--active]=\"option.value === value()\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.tabindex]=\"option.value === value() ? 0 : -1\"\n [id]=\"'kf-folder-tab-' + option.value\"\n [attr.aria-controls]=\"'kf-folder-panel-' + option.value\"\n (click)=\"select(option.value)\"\n (keydown)=\"onKeydown($event, option.value)\"\n >\n @if (option.icon; as iconName) {\n <kf-icon class=\"kf-folder-tabs__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <span class=\"kf-folder-tabs__label\">{{ option.label }}</span>\n </button>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-folder-tabs {\n display: flex;\n align-items: flex-end;\n gap: var(--kf-space-xs);\n /* Da profundidad al hinge: las pestañas giran sobre su borde inferior. */\n perspective: 900px;\n }\n .kf-folder-tabs__tab {\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n font: inherit;\n font-size: 0.9rem;\n color: var(--kf-color-text-muted);\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-bottom-color: var(--kf-color-border-strong);\n border-radius: var(--kf-radius-sm) var(--kf-radius-sm) 0 0;\n padding: var(--kf-space-sm) var(--kf-space-md);\n cursor: pointer;\n transform-origin: bottom center;\n /* Inactiva: hundida en la pila, un pelo más chica. */\n transform: translateY(5px) scale(0.985);\n transition:\n background 0.14s,\n color 0.14s,\n border-color 0.14s,\n transform 0.22s cubic-bezier(0.32, 0.72, 0, 1);\n }\n .kf-folder-tabs__tab:hover:not(.kf-folder-tabs__tab--active) {\n color: var(--kf-color-text);\n background: var(--kf-color-white);\n transform: translateY(2px) scale(0.99);\n }\n .kf-folder-tabs__tab:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n z-index: 1;\n }\n .kf-folder-tabs__tab--active {\n z-index: 1;\n color: var(--kf-color-primary);\n font-weight: 700;\n background: var(--kf-color-white);\n border-color: var(--kf-color-border);\n /* Marca el color del tema abajo (página 19 del design system) — no se\n funde con el panel: el borde queda visible y grueso, mismo trato\n que el subrayado de kf-tabs. */\n border-bottom: 2px solid var(--kf-color-primary);\n /* Sombra hacia arriba: la pestaña quedó por delante del resto. */\n box-shadow: 0 -6px 14px -10px rgba(16, 24, 40, 0.4);\n transform: translateY(1px);\n animation: kf-folder-tabs-pull 0.34s cubic-bezier(0.22, 1.2, 0.36, 1) both;\n }\n @keyframes kf-folder-tabs-pull {\n 0% {\n transform: translateY(7px) rotateX(-24deg) scale(0.95);\n }\n 60% {\n transform: translateY(-2px) rotateX(3deg) scale(1.02);\n }\n 100% {\n transform: translateY(1px) rotateX(0) scale(1);\n }\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-folder-tabs__tab,\n .kf-folder-tabs__tab--active {\n animation: none;\n transition:\n background 0.14s,\n color 0.14s,\n border-color 0.14s;\n }\n }\n `,\n})\nexport class FolderTabs {\n readonly options = input.required<FolderTabOption[]>();\n readonly value = input.required<string>();\n readonly valueChange = output<string>();\n\n select(value: string): void {\n if (value === this.value()) {\n return;\n }\n this.valueChange.emit(value);\n }\n\n /** Navegación estándar de ARIA tabs: flechas mueven el foco y activan la pestaña. */\n onKeydown(event: KeyboardEvent, currentValue: string): void {\n const items = this.options();\n const currentIndex = items.findIndex((option) => option.value === currentValue);\n\n let nextIndex: number;\n switch (event.key) {\n case 'ArrowRight':\n nextIndex = (currentIndex + 1) % items.length;\n break;\n case 'ArrowLeft':\n nextIndex = (currentIndex - 1 + items.length) % items.length;\n break;\n case 'Home':\n nextIndex = 0;\n break;\n case 'End':\n nextIndex = items.length - 1;\n break;\n default:\n return;\n }\n\n event.preventDefault();\n const nextOption = items[nextIndex];\n this.select(nextOption.value);\n\n const host = (event.currentTarget as HTMLElement).parentElement;\n const nextId = `kf-folder-tab-${nextOption.value}`;\n const nextButton = Array.from(host?.querySelectorAll<HTMLButtonElement>('button') ?? []).find(\n (button) => button.id === nextId,\n );\n nextButton?.focus();\n }\n}\n","import {\n AfterViewInit,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n forwardRef,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { FieldLabel } from '../field-label/FieldLabel';\n\n/**\n * Input de formulario apilado: label arriba (en mayúsculas vía CSS), campo con\n * fondo gris que pasa a blanco con anillo de foco azul al enfocar.\n *\n * Implementa ControlValueAccessor, así que funciona con [(ngModel)] y con\n * Reactive Forms (formControl / formControlName), no es solo un wrapper visual.\n *\n * <kf-input label=\"Placa\" icon=\"car\" placeholder=\"ABC-123\" hint=\"Formato: 3 letras + 3 números\" />\n * <input kf-input formControlName=\"email\" type=\"email\" />\n *\n * Nota sobre \"icon\": todavía no existe un componente Icon / sprite SVG en esta\n * librería. El prop se acepta igual para no romper el contrato de la spec,\n * pero por ahora solo reserva el espacio visual (placeholder vacío) — no\n * renderiza ningún glyph real.\n */\n@Component({\n selector: 'kf-input',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FormsModule, FieldLabel],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Input),\n multi: true,\n },\n ],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"inputId\">{{ label() }}</kf-field-label>\n }\n <div\n class=\"kf-input__field\"\n [class.kf-input__field--disabled]=\"isDisabled()\"\n [class.kf-input__field--focused]=\"focused()\"\n >\n @if (icon()) {\n <!-- Pendiente: falta componente Icon / sprite SVG. Se reserva el\n espacio pero no se renderiza ningún glyph todavía. -->\n <span class=\"kf-input__icon\" aria-hidden=\"true\"></span>\n }\n <input\n #nativeInput\n [id]=\"inputId\"\n class=\"kf-input__control\"\n [type]=\"type()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-describedby]=\"hint() ? hintId : null\"\n [value]=\"value()\"\n (input)=\"onInput(nativeInput.value)\"\n (blur)=\"onBlur()\"\n (focus)=\"focused.set(true)\"\n />\n @if (suffix()) {\n <span class=\"kf-input__suffix\">{{ suffix() }}</span>\n }\n </div>\n @if (hint()) {\n <span class=\"kf-input__hint\" [id]=\"hintId\">{{ hint() }}</span>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n font-family: var(--kf-font-body);\n }\n .kf-input__field {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: 0 var(--kf-space-sm);\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n transition:\n background 0.14s,\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-input__field--focused {\n background: var(--kf-color-white);\n border-color: var(--kf-color-primary);\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-input__field--disabled {\n opacity: 0.5;\n }\n .kf-input__icon {\n width: 1rem;\n height: 1rem;\n flex: none;\n }\n .kf-input__control {\n flex: 1;\n min-width: 0;\n border: none;\n outline: none;\n background: transparent;\n font: inherit;\n color: var(--kf-color-text);\n padding: var(--kf-space-sm) 0;\n }\n .kf-input__control::placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-input__control:disabled {\n cursor: not-allowed;\n }\n .kf-input__suffix {\n flex: none;\n color: var(--kf-color-text-muted);\n font-size: 0.875rem;\n }\n .kf-input__hint {\n font-size: 0.75rem;\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class Input implements ControlValueAccessor, AfterViewInit {\n private static nextId = 0;\n\n private readonly nativeInput = viewChild.required<ElementRef<HTMLInputElement>>('nativeInput');\n\n readonly label = input<string>();\n /** Nombre de ícono líder. Ver nota de clase: sin componente Icon todavía. */\n readonly icon = input<string>();\n readonly suffix = input<string>();\n readonly hint = input<string>();\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly type = input<string>('text');\n readonly placeholder = input<string>('');\n\n protected readonly inputId = `kf-input-${Input.nextId++}`;\n protected readonly hintId = `${this.inputId}-hint`;\n\n protected readonly value = signal('');\n protected readonly focused = signal(false);\n /** Deshabilitado por Reactive Forms (formControl.disable()). */\n private readonly disabledByForm = signal(false);\n /** Disabled real: por input() directo o por el FormControl asociado. */\n protected readonly isDisabled = computed(() => this.disabled() || this.disabledByForm());\n\n private onChange: (value: string) => void = () => {};\n private onTouched: () => void = () => {};\n\n ngAfterViewInit(): void {\n // El binding declarativo [value]=\"value()\" no siempre re-sincroniza la\n // propiedad DOM del <input> cuando el valor llega por writeValue() antes\n // de que la vista termine de inicializarse — se refuerza escribiendo la\n // propiedad DOM directamente para que el primer valor de un formulario\n // ya cargado (ngModel/formControl con valor inicial) se refleje siempre.\n this.nativeInput().nativeElement.value = this.value();\n }\n\n writeValue(value: string): void {\n const nextValue = value ?? '';\n this.value.set(nextValue);\n // Mismo motivo que en ngAfterViewInit: escritura directa a la propiedad\n // DOM además del binding declarativo, para que cambios de valor\n // posteriores (ej. patchValue de un FormControl) siempre lleguen al\n // input nativo sin depender del timing de detección de cambios.\n const el = this.nativeInput?.();\n if (el) {\n el.nativeElement.value = nextValue;\n }\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabledByForm.set(isDisabled);\n }\n\n protected onInput(rawValue: string): void {\n this.value.set(rawValue);\n this.onChange(rawValue);\n }\n\n protected onBlur(): void {\n this.focused.set(false);\n this.onTouched();\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Card } from '../card/Card';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Card de estadística/KPI: label, valor grande, ícono opcional en la esquina\n * superior derecha, badge de esquina opcional (pegado al valor) y una nota\n * al pie. Pensada para tableros de resumen (ej. \"11 Tickets abiertos\").\n *\n * Compone sobre `kf-card` en vez de duplicar su estilo de contenedor — así\n * el look de \"card\" (radio, sombra, borde) tiene una única fuente de verdad\n * en toda la librería, tal como pide el design system (página 14: \"Card...\n * es la base de paneles, tarjetas de métrica, tablas...\").\n *\n * <kf-metric-card label=\"Tickets abiertos\" value=\"11\" icon=\"ticket\" foot=\"+2 hoy\" />\n * <kf-metric-card label=\"Tasa de resolución\" value=\"94%\" badge=\"+2%\" value-color=\"var(--kf-color-success)\" />\n */\n@Component({\n selector: 'kf-metric-card',\n imports: [Card, Icon],\n template: `\n <kf-card>\n <div class=\"kf-metric-card__head\">\n <span class=\"kf-metric-card__label\">{{ label() }}</span>\n @if (icon(); as iconName) {\n <span class=\"kf-metric-card__icon\">\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n </span>\n }\n </div>\n <div class=\"kf-metric-card__value-row\">\n <div class=\"kf-metric-card__value\" [style.color]=\"valueColor()\">\n {{ value() }}\n @if (unit()) {\n <span class=\"kf-metric-card__unit\">{{ unit() }}</span>\n }\n </div>\n @if (badge()) {\n <span class=\"kf-metric-card__badge\">{{ badge() }}</span>\n }\n </div>\n @if (foot()) {\n <div class=\"kf-metric-card__foot\">{{ foot() }}</div>\n }\n </kf-card>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-metric-card__head {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--kf-space-xs);\n }\n .kf-metric-card__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n flex: none;\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n .kf-metric-card__label {\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--kf-color-text-muted);\n }\n .kf-metric-card__value-row {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n }\n .kf-metric-card__value {\n font-family: var(--kf-font-title);\n font-weight: 700;\n font-size: 1.6rem;\n line-height: 1.1;\n color: var(--kf-color-ink);\n }\n .kf-metric-card__unit {\n font-size: 0.85rem;\n font-weight: 500;\n color: var(--kf-color-text-muted);\n margin-left: var(--kf-space-xs);\n }\n .kf-metric-card__badge {\n font-size: 0.72rem;\n font-weight: 700;\n padding: 2px var(--kf-space-xs);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-success-soft);\n color: var(--kf-color-success-strong);\n }\n .kf-metric-card__foot {\n font-size: 0.78rem;\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class MetricCard {\n readonly label = input.required<string>();\n readonly value = input.required<string | number>();\n readonly unit = input<string>();\n /** Ícono en la esquina superior derecha, renderizado vía `kf-icon`. */\n readonly icon = input<IconName>();\n readonly foot = input<string>();\n /** Tinte opcional para el valor grande (ej. un color semántico de estado). */\n readonly valueColor = input<string>();\n /** Badge de esquina opcional, pegado al valor (ej. \"+2%\"). */\n readonly badge = input<string>();\n}\n","import { DOCUMENT } from '@angular/common';\nimport {\n booleanAttribute,\n Component,\n DestroyRef,\n ElementRef,\n HostListener,\n afterRenderEffect,\n inject,\n input,\n model,\n viewChild,\n} from '@angular/core';\n\nlet modalId = 0;\n\n/**\n * Diálogo centrado sobre un backdrop: confirmaciones destructivas, formularios\n * cortos, decisiones que bloquean el flujo.\n *\n * Se apoya en el `<dialog>` nativo (`showModal()`), así que el atrapado de\n * foco, el backdrop, el orden en el top-layer y el cierre con `Escape` los\n * resuelve el navegador — no hay trampa de foco escrita a mano acá. Lo único\n * que se agrega es el lock de scroll del body, que `<dialog>` no hace.\n *\n * `open` es two-way. Con `dismissible` en `false` (ej. mientras una acción\n * destructiva está en vuelo) se cancelan `Escape` y el clic en el backdrop:\n * solo cierra el consumidor poniendo `open` en `false`.\n *\n * Las acciones van en el slot `footer`.\n *\n * <kf-modal [(open)]=\"confirmOpen\" title=\"Eliminar unidad\">\n * <p>Esta acción no se puede deshacer.</p>\n * <div footer>\n * <kf-button variant=\"ghost\" (click)=\"confirmOpen.set(false)\">Cancelar</kf-button>\n * <kf-button (click)=\"remove()\">Eliminar</kf-button>\n * </div>\n * </kf-modal>\n */\n@Component({\n selector: 'kf-modal',\n template: `\n <dialog\n #dialog\n class=\"kf-modal\"\n [attr.aria-labelledby]=\"title() ? titleId : null\"\n (cancel)=\"onCancel($event)\"\n (close)=\"open.set(false)\"\n >\n @if (open()) {\n <div class=\"kf-modal__panel\">\n <div class=\"kf-modal__head\">\n @if (title()) {\n <h2 class=\"kf-modal__title\" [id]=\"titleId\">{{ title() }}</h2>\n }\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"kf-modal__close\"\n aria-label=\"Cerrar diálogo\"\n (click)=\"open.set(false)\"\n >\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M6 6l12 12M18 6L6 18\" />\n </svg>\n </button>\n }\n </div>\n <div class=\"kf-modal__body\"><ng-content /></div>\n <div class=\"kf-modal__footer\"><ng-content select=\"[footer]\" /></div>\n </div>\n }\n </dialog>\n `,\n styles: `\n .kf-modal {\n width: min(480px, calc(100vw - 2 * var(--kf-space-md)));\n max-height: calc(100vh - 2 * var(--kf-space-xl));\n padding: 0;\n border: none;\n background: transparent;\n overflow: visible;\n font-family: var(--kf-font-body);\n }\n .kf-modal::backdrop {\n background: rgba(23, 29, 37, 0.45);\n }\n .kf-modal__panel {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-md);\n padding: var(--kf-space-lg);\n background: var(--kf-color-white);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-lg);\n }\n .kf-modal__head {\n display: flex;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n }\n .kf-modal__title {\n flex: 1;\n margin: 0;\n font-family: var(--kf-font-title);\n font-size: 1.375rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-modal__close {\n flex: none;\n display: inline-flex;\n padding: 2px;\n border: none;\n background: transparent;\n color: var(--kf-color-text-muted);\n border-radius: var(--kf-radius-xs);\n cursor: pointer;\n }\n .kf-modal__close svg {\n width: 1.25em;\n height: 1.25em;\n fill: none;\n stroke: currentColor;\n stroke-width: 1.9;\n stroke-linecap: round;\n }\n .kf-modal__close:hover {\n color: var(--kf-color-ink);\n }\n .kf-modal__close:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-modal__body {\n color: var(--kf-color-text);\n overflow-y: auto;\n }\n .kf-modal__footer:empty {\n display: none;\n }\n .kf-modal__footer {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class Modal {\n readonly title = input('');\n /** Visibilidad, two-way: `[(open)]=\"confirmOpen\"`. */\n readonly open = model(false);\n /** Permite cerrar con el botón, `Escape` o clic en el backdrop. */\n readonly dismissible = input(true, { transform: booleanAttribute });\n\n protected readonly titleId = `kf-modal-title-${modalId++}`;\n\n private readonly dialog = viewChild<ElementRef<HTMLDialogElement>>('dialog');\n private readonly document = inject(DOCUMENT);\n\n constructor() {\n afterRenderEffect(() => {\n const el = this.dialog()?.nativeElement;\n if (!el) {\n return;\n }\n if (this.open() && !el.open) {\n // ponytail: `showModal` no existe en jsdom (tests) ni en entornos sin\n // top-layer; el atributo `open` lo deja visible, aunque no modal.\n if (typeof el.showModal === 'function') {\n el.showModal();\n } else {\n el.open = true;\n }\n } else if (!this.open() && el.open) {\n if (typeof el.close === 'function') {\n el.close();\n } else {\n el.open = false;\n }\n }\n // `<dialog>` inertiza el resto de la página pero no frena su scroll.\n this.document.body.style.overflow = this.open() ? 'hidden' : '';\n });\n\n inject(DestroyRef).onDestroy(() => {\n this.document.body.style.overflow = '';\n });\n }\n\n /** `Escape` dispara `cancel`; cancelarlo lo deja abierto. */\n protected onCancel(event: Event): void {\n if (!this.dismissible()) {\n event.preventDefault();\n }\n }\n\n /**\n * Clic en el backdrop. Un clic en la zona del backdrop tiene como `target` al\n * propio `<dialog>` (el contenido vive en el panel de adentro), así que basta\n * comparar contra él — no hace falta cortar la propagación en el panel.\n *\n * Va como HostListener y no como binding en el template porque un `(click)`\n * sobre el `<dialog>` dispara las reglas a11y de click-sin-teclado; acá el\n * equivalente de teclado es `Escape`, que el `<dialog>` nativo ya maneja.\n */\n @HostListener('click', ['$event'])\n protected onHostClick(event: MouseEvent): void {\n if (this.dismissible() && event.target === this.dialog()?.nativeElement) {\n this.open.set(false);\n }\n }\n}\n","import {\n Component,\n ElementRef,\n HostListener,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { FieldLabel } from '../field-label/FieldLabel';\n\nexport interface MultiSelectOption {\n value: string;\n label: string;\n}\n\nlet nextId = 0;\n\n/**\n * Dropdown de selección múltiple con checkboxes internos, siguiendo el mismo\n * patrón de panel flotante que `SelectMenu` (panel con `position: absolute`\n * sobre el host, sin Angular CDK Overlay, que no es dependencia del proyecto).\n * Se abre y cierra por click en el disparador, y se cierra al hacer click\n * afuera o al presionar Escape.\n *\n * A diferencia de `SelectMenu`, el disparador no muestra un único valor sino\n * los nombres seleccionados junto a un badge circular con el conteo (página\n * 12: \"Sucursal Norte, Lima Centro\" + badge \"2\"), y cada opción del panel se\n * marca/desmarca con un checkbox sin cerrar el panel. Incluye una opción\n * \"Todas\" al inicio de la lista, con estado `indeterminate` cuando hay\n * selección parcial — el mismo patrón de \"seleccionar todos\" de `Checkbox`.\n *\n * <kf-multi-select\n * label=\"Sucursales\"\n * [options]=\"branches\"\n * [values]=\"selectedBranches()\"\n * (valuesChange)=\"selectedBranches.set($event)\"\n * />\n *\n * Pendiente: el prop `icon` de otros componentes del design system requiere\n * un componente Icon / sprite SVG que esta librería todavía no tiene — este\n * componente no usa iconos, así que no aplica acá.\n */\n@Component({\n selector: 'kf-multi-select',\n imports: [FieldLabel],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n }\n <button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-multi-select__trigger\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n >\n <span\n class=\"kf-multi-select__value\"\n [class.kf-multi-select__value--placeholder]=\"selectedCount() === 0\"\n >\n {{ summaryText() }}\n </span>\n @if (selectedCount() > 0) {\n <span class=\"kf-multi-select__count\">{{ selectedCount() }}</span>\n }\n <span\n class=\"kf-multi-select__caret\"\n [class.kf-multi-select__caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n </button>\n @if (isOpen()) {\n <ul\n class=\"kf-multi-select__panel\"\n [id]=\"listboxId\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @if (options().length > 0) {\n <li\n class=\"kf-multi-select__option\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"allSelected()\"\n (click)=\"toggleAll()\"\n (keydown.enter)=\"toggleAll()\"\n (keydown.space)=\"$event.preventDefault(); toggleAll()\"\n >\n <span\n class=\"kf-multi-select__checkbox\"\n [class.kf-multi-select__checkbox--checked]=\"allSelected()\"\n [class.kf-multi-select__checkbox--indeterminate]=\"isPartiallySelected()\"\n ></span>\n <span class=\"kf-multi-select__option-label\">Todas</span>\n </li>\n }\n @for (option of options(); track option.value) {\n <li\n class=\"kf-multi-select__option\"\n [class.kf-multi-select__option--selected]=\"isSelected(option.value)\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"isSelected(option.value)\"\n (click)=\"toggleOption(option.value)\"\n (keydown.enter)=\"toggleOption(option.value)\"\n (keydown.space)=\"$event.preventDefault(); toggleOption(option.value)\"\n >\n <span\n class=\"kf-multi-select__checkbox\"\n [class.kf-multi-select__checkbox--checked]=\"isSelected(option.value)\"\n ></span>\n <span class=\"kf-multi-select__option-label\">{{ option.label }}</span>\n </li>\n } @empty {\n <li class=\"kf-multi-select__empty\">Sin opciones disponibles</li>\n }\n </ul>\n }\n `,\n styles: `\n :host {\n display: inline-flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n position: relative;\n font: inherit;\n min-width: 200px;\n }\n .kf-multi-select__trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n width: 100%;\n font: inherit;\n font-family: var(--kf-font-body);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n color: var(--kf-color-text);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-multi-select__trigger:hover:not(:disabled) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-multi-select__trigger:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-multi-select__trigger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-multi-select__value {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n text-align: left;\n }\n .kf-multi-select__value--placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-multi-select__count {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 1.25rem;\n height: 1.25rem;\n padding: 0 5px;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n font-size: 0.72rem;\n font-weight: 700;\n }\n .kf-multi-select__caret {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-text-muted);\n border-bottom: 2px solid var(--kf-color-text-muted);\n transform: rotate(45deg);\n transition: transform 0.14s;\n margin-top: -4px;\n }\n .kf-multi-select__caret--open {\n transform: rotate(-135deg);\n margin-top: 4px;\n }\n .kf-multi-select__panel {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 10;\n margin: var(--kf-space-xs) 0 0;\n padding: var(--kf-space-xs) 0;\n list-style: none;\n max-height: 240px;\n overflow-y: auto;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-md);\n }\n .kf-multi-select__option {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-multi-select__option:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-multi-select__option--selected {\n color: var(--kf-color-primary);\n font-weight: 600;\n }\n .kf-multi-select__checkbox {\n display: inline-flex;\n flex-shrink: 0;\n width: var(--kf-space-md);\n height: var(--kf-space-md);\n border: 1px solid var(--kf-color-border-strong);\n border-radius: var(--kf-radius-xs);\n background: var(--kf-color-white);\n transition:\n background 0.14s,\n border-color 0.14s;\n position: relative;\n }\n .kf-multi-select__checkbox--checked {\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n }\n .kf-multi-select__checkbox--checked::after {\n content: '';\n position: absolute;\n left: 4px;\n top: 1px;\n width: 4px;\n height: 8px;\n border: solid var(--kf-color-white);\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n /* \"Todas\" con selección parcial: barra horizontal, mismo patrón que Checkbox. */\n .kf-multi-select__checkbox--indeterminate {\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n }\n .kf-multi-select__checkbox--indeterminate::after {\n content: '';\n position: absolute;\n left: 3px;\n top: 6px;\n width: 8px;\n height: 2px;\n background: var(--kf-color-white);\n border: none;\n transform: none;\n }\n .kf-multi-select__option-label {\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-multi-select__empty {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class MultiSelect {\n readonly label = input<string>();\n readonly options = input<MultiSelectOption[]>([]);\n readonly values = input<string[]>([]);\n readonly placeholder = input<string>('Seleccionar');\n readonly disabled = input(false, { transform: booleanAttribute });\n\n readonly valuesChange = output<string[]>();\n\n private readonly instanceId = `kf-multi-select-${nextId++}`;\n readonly triggerId = `${this.instanceId}-trigger`;\n readonly listboxId = `${this.instanceId}-listbox`;\n\n readonly isOpen = signal(false);\n\n readonly selectedCount = computed(() => this.values().length);\n\n readonly allSelected = computed(\n () => this.options().length > 0 && this.values().length === this.options().length,\n );\n\n readonly isPartiallySelected = computed(() => this.values().length > 0 && !this.allSelected());\n\n /**\n * Texto del disparador: placeholder si no hay selección, o los nombres\n * seleccionados unidos por coma (el conteo va aparte, en el badge). Con\n * muchas opciones el `text-overflow: ellipsis` del `.kf-multi-select__value`\n * corta el texto — el badge de conteo siempre queda visible al lado.\n */\n readonly summaryText = computed(() => {\n const count = this.selectedCount();\n if (count === 0) {\n return this.placeholder();\n }\n const selectedLabels = this.values()\n .map((value) => this.options().find((option) => option.value === value)?.label)\n .filter((label): label is string => Boolean(label));\n return selectedLabels.join(', ');\n });\n\n private readonly host = inject(ElementRef<HTMLElement>);\n\n isSelected(value: string): boolean {\n return this.values().includes(value);\n }\n\n toggle(): void {\n if (this.disabled()) {\n return;\n }\n this.isOpen.update((open) => !open);\n }\n\n toggleOption(value: string): void {\n const current = this.values();\n const next = current.includes(value)\n ? current.filter((selectedValue) => selectedValue !== value)\n : [...current, value];\n this.valuesChange.emit(next);\n }\n\n /** Alterna entre \"todas seleccionadas\" y \"ninguna seleccionada\". */\n toggleAll(): void {\n this.valuesChange.emit(this.allSelected() ? [] : this.options().map((option) => option.value));\n }\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(event: MouseEvent): void {\n if (this.isOpen() && !this.host.nativeElement.contains(event.target as Node)) {\n this.isOpen.set(false);\n }\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n this.isOpen.set(false);\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Bloque de título al tope de una página: chip de ícono opcional, título (h1),\n * subtítulo opcional y un área de acciones opcional proyectada vía\n * `<ng-content select=\"[actions]\">`, para no acoplar el componente a un set\n * fijo de botones.\n *\n * <kf-page-header title=\"Vehículos\" subtitle=\"Gestión de la flota activa\">\n * <button actions>Nuevo vehículo</button>\n * </kf-page-header>\n *\n * <kf-page-header icon=\"settings\" title=\"Configuración\" />\n */\n@Component({\n selector: 'kf-page-header',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <span class=\"kf-page-header__icon\">\n <kf-icon [name]=\"iconName\" size=\"lg\" />\n </span>\n }\n\n <div class=\"kf-page-header__heading\">\n <h1 class=\"kf-page-header__title\">{{ title() }}</h1>\n @if (subtitle()) {\n <p class=\"kf-page-header__subtitle\">{{ subtitle() }}</p>\n }\n </div>\n\n <div class=\"kf-page-header__actions\">\n <ng-content select=\"[actions]\" />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-md);\n font-family: var(--kf-font-body);\n }\n .kf-page-header__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n /* El chip necesita bastante más aire que el ícono (24px \"lg\") que\n contiene — con --kf-space-xl (32px) quedaban casi pegados. */\n width: 48px;\n height: 48px;\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n .kf-page-header__heading {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n flex: 1 1 auto;\n min-width: 0;\n }\n .kf-page-header__title {\n margin: 0;\n font-family: var(--kf-font-title);\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1.2;\n color: var(--kf-color-ink);\n }\n .kf-page-header__subtitle {\n margin: 0;\n font-size: 0.9375rem;\n color: var(--kf-color-text-muted);\n }\n .kf-page-header__actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class PageHeader {\n readonly icon = input<IconName | undefined>(undefined);\n readonly title = input.required<string>();\n readonly subtitle = input<string | undefined>(undefined);\n}\n","import { Component, computed, input, output } from '@angular/core';\n\n/** Un número de página clickeable o un separador \"…\" no interactivo. */\nexport type PaginationItem = { type: 'page'; page: number } | { type: 'ellipsis' };\n\nconst SIBLINGS = 1;\n\n/**\n * Paginador numerado con elipsis + prev/next.\n *\n * Algoritmo de elipsis estándar: siempre se muestran la primera página, la\n * última, la página actual y un par de vecinas alrededor de la actual; el\n * resto de los huecos se colapsa en un separador \"…\". Cuando el hueco entre\n * dos números visibles es de exactamente una página, se muestra ese número\n * en vez de un \"…\" (no tiene sentido colapsar un solo elemento).\n *\n * El contenido proyectado (`<ng-content>`) es para el texto informativo\n * opcional (ej. \"21–40 de 273\"), a la izquierda de los controles.\n *\n * <kf-pagination [page]=\"page\" [pages]=\"totalPages\" (pageChange)=\"page = $event\">\n * 21–40 de 273\n * </kf-pagination>\n */\n@Component({\n selector: 'kf-pagination',\n template: `\n <div class=\"kf-pagination\">\n <div class=\"kf-pagination__info\">\n <ng-content />\n </div>\n <nav class=\"kf-pagination__nav\" aria-label=\"Paginación\">\n <button\n type=\"button\"\n class=\"kf-pagination__control\"\n [disabled]=\"page() <= 1\"\n aria-label=\"Página anterior\"\n (click)=\"goTo(page() - 1)\"\n >\n ‹\n </button>\n\n @for (item of items(); track $index) {\n @if (item.type === 'page') {\n <button\n type=\"button\"\n class=\"kf-pagination__page\"\n [class.kf-pagination__page--active]=\"item.page === page()\"\n [attr.aria-current]=\"item.page === page() ? 'page' : null\"\n [attr.aria-label]=\"'Ir a la página ' + item.page\"\n (click)=\"goTo(item.page)\"\n >\n {{ item.page }}\n </button>\n } @else {\n <span class=\"kf-pagination__ellipsis\" aria-hidden=\"true\">…</span>\n }\n }\n\n <button\n type=\"button\"\n class=\"kf-pagination__control\"\n [disabled]=\"page() >= pages()\"\n aria-label=\"Página siguiente\"\n (click)=\"goTo(page() + 1)\"\n >\n ›\n </button>\n </nav>\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-pagination {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-md);\n flex-wrap: wrap;\n }\n .kf-pagination__info {\n font-size: 0.85rem;\n color: var(--kf-color-text-muted);\n }\n .kf-pagination__info:empty {\n display: none;\n }\n .kf-pagination__nav {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n }\n .kf-pagination__control,\n .kf-pagination__page {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 2rem;\n height: 2rem;\n padding: 0 var(--kf-space-xs);\n font: inherit;\n font-size: 0.85rem;\n color: var(--kf-color-text);\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n cursor: pointer;\n transition:\n background 0.14s,\n border-color 0.14s,\n color 0.14s;\n }\n .kf-pagination__control:hover:not(:disabled),\n .kf-pagination__page:hover:not(.kf-pagination__page--active) {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border-strong);\n }\n .kf-pagination__control:focus-visible,\n .kf-pagination__page:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-pagination__control:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-pagination__page--active {\n color: var(--kf-color-white);\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n cursor: default;\n }\n .kf-pagination__ellipsis {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 2rem;\n height: 2rem;\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class Pagination {\n readonly page = input(1);\n readonly pages = input(1);\n readonly pageChange = output<number>();\n\n /** Lista de números de página y separadores a renderizar, ya resuelta por el algoritmo de elipsis. */\n readonly items = computed<PaginationItem[]>(() =>\n buildPaginationItems(this.page(), this.pages()),\n );\n\n goTo(target: number): void {\n const clamped = Math.min(Math.max(target, 1), this.pages());\n if (clamped === this.page()) {\n return;\n }\n this.pageChange.emit(clamped);\n }\n}\n\n/**\n * Construye la lista de items visibles con el algoritmo de elipsis estándar:\n * primera página, última página, actual ± `SIBLINGS`, y un \"…\" por cada hueco\n * mayor a una página entre esos bloques.\n */\nfunction buildPaginationItems(current: number, total: number): PaginationItem[] {\n const totalPages = Math.max(total, 1);\n const safeCurrent = Math.min(Math.max(current, 1), totalPages);\n\n const visible = new Set<number>([1, totalPages, safeCurrent]);\n for (let offset = 1; offset <= SIBLINGS; offset++) {\n visible.add(safeCurrent - offset);\n visible.add(safeCurrent + offset);\n }\n\n const sortedPages = [...visible].filter((p) => p >= 1 && p <= totalPages).sort((a, b) => a - b);\n\n const items: PaginationItem[] = [];\n for (let i = 0; i < sortedPages.length; i++) {\n const pageNumber = sortedPages[i];\n if (i > 0) {\n const gap = pageNumber - sortedPages[i - 1];\n if (gap === 2) {\n // Hueco de una sola página: mostrarla en vez de colapsarla en \"…\".\n items.push({ type: 'page', page: pageNumber - 1 });\n } else if (gap > 2) {\n items.push({ type: 'ellipsis' });\n }\n }\n items.push({ type: 'page', page: pageNumber });\n }\n\n return items;\n}\n","import { Component, input } from '@angular/core';\nimport { Card } from '../card/Card';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Tarjeta contenedora con título, enlace de acción opcional a la derecha, y\n * cuerpo con contenido libre — página 33: \"Base de la mayoría de bloques del\n * portal\". Compone sobre `kf-card` para compartir la misma superficie\n * (radio, sombra, borde) que el resto de la librería.\n *\n * <kf-panel title=\"Mis documentos por pagar\" actionLabel=\"Ir a pagos\" actionHref=\"/pagos\">\n * <kf-action-tile-row icon=\"download\" title=\"Pagos\" description=\"Revisa tu estado de cuenta y realiza pagos.\" />\n * </kf-panel>\n */\n@Component({\n selector: 'kf-panel',\n imports: [Card, Icon],\n template: `\n <kf-card>\n <div class=\"kf-panel__head\">\n <span class=\"kf-panel__title\">{{ title() }}</span>\n @if (actionLabel()) {\n <a class=\"kf-panel__action\" [href]=\"actionHref() || '#'\">\n {{ actionLabel() }}\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n </div>\n <div class=\"kf-panel__body\">\n <ng-content />\n </div>\n </kf-card>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-panel__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n margin-bottom: var(--kf-space-sm);\n }\n .kf-panel__title {\n font-family: var(--kf-font-title);\n font-size: 1.05rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-panel__action {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n flex: none;\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n .kf-panel__action:hover {\n text-decoration: underline;\n }\n .kf-panel__body {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class Panel {\n readonly title = input.required<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import { Component, booleanAttribute, input, output } from '@angular/core';\nimport { AdminBadge } from '../admin-badge/AdminBadge';\nimport { Avatar } from '../avatar/Avatar';\n\n/** Un ítem de navegación de la barra de marca. */\nexport interface PortalHeaderNavItem {\n label: string;\n href: string;\n active?: boolean;\n}\n\n/** Una acción de la franja de administrador (ej. \"Consultar deuda clientes\"). */\nexport interface PortalHeaderAdminAction {\n label: string;\n href: string;\n}\n\n/**\n * Cabecera completa del portal (página 31) — franja de administrador\n * (acento ámbar, solo admins), barra de marca con logo, navegación y\n * pastilla de sesión. Compone `kf-admin-badge` para la franja y `kf-avatar\n * pill` para la sesión, en vez de reimplementar ambos.\n *\n * Es distinto de `kf-page-header`/`kf-page-head` (título de una vista\n * interna) — este es el chrome global del portal, se monta una sola vez.\n *\n * <kf-portal-header\n * [isAdmin]=\"true\"\n * [adminActions]=\"[{ label: 'Consultar deuda clientes', href: '/deuda' }, { label: 'Cambiar DNI', href: '/dni' }]\"\n * [navItems]=\"[{ label: 'Home', href: '/', active: true }, { label: 'Vehículos', href: '/vehiculos' }]\"\n * userInitials=\"TS\"\n * />\n */\n@Component({\n selector: 'kf-portal-header',\n imports: [AdminBadge, Avatar],\n template: `\n @if (isAdmin()) {\n <div class=\"kf-portal-header__admin-bar\">\n <kf-admin-badge inline />\n <div class=\"kf-portal-header__admin-actions\">\n @for (action of adminActions(); track action.label) {\n <a class=\"kf-portal-header__admin-action\" [href]=\"action.href\">{{ action.label }}</a>\n }\n </div>\n </div>\n }\n <div class=\"kf-portal-header__brand-bar\">\n <span class=\"kf-portal-header__logo\">{{ brand() }}</span>\n <nav class=\"kf-portal-header__nav\">\n @for (item of navItems(); track item.label) {\n <a\n class=\"kf-portal-header__nav-item\"\n [class.kf-portal-header__nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n >\n {{ item.label }}\n </a>\n }\n </nav>\n <button type=\"button\" class=\"kf-portal-header__session\" (click)=\"sessionClick.emit()\">\n <kf-avatar [initials]=\"userInitials()\" pill />\n </button>\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-portal-header__admin-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-md);\n padding: var(--kf-space-xs) var(--kf-space-lg);\n background: var(--kf-color-tertiary-deep);\n }\n .kf-portal-header__admin-actions {\n display: flex;\n gap: var(--kf-space-md);\n }\n .kf-portal-header__admin-action {\n font-size: 0.8125rem;\n font-weight: 600;\n color: rgba(255, 255, 255, 0.85);\n text-decoration: none;\n }\n .kf-portal-header__admin-action:hover {\n color: var(--kf-color-white);\n }\n .kf-portal-header__brand-bar {\n display: flex;\n align-items: center;\n gap: var(--kf-space-lg);\n padding: var(--kf-space-sm) var(--kf-space-lg);\n background: var(--kf-color-tertiary-deep);\n border-top: 1px solid rgba(255, 255, 255, 0.1);\n }\n .kf-portal-header__logo {\n font-family: var(--kf-font-title);\n font-size: 1.25rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n color: var(--kf-color-white);\n text-transform: uppercase;\n }\n .kf-portal-header__nav {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n flex: 1 1 auto;\n }\n .kf-portal-header__nav-item {\n padding: var(--kf-space-xs) var(--kf-space-md);\n border-radius: var(--kf-radius-sm);\n color: rgba(255, 255, 255, 0.75);\n font-size: 0.875rem;\n font-weight: 600;\n text-decoration: none;\n transition:\n background 0.14s,\n color 0.14s;\n }\n .kf-portal-header__nav-item:hover {\n color: var(--kf-color-white);\n }\n .kf-portal-header__nav-item--active {\n background: var(--kf-color-white);\n color: var(--kf-color-ink);\n }\n .kf-portal-header__session {\n flex: none;\n border: none;\n background: transparent;\n padding: 0;\n cursor: pointer;\n }\n `,\n})\nexport class PortalHeader {\n readonly brand = input('DIVEMOTOR');\n readonly isAdmin = input(false, { transform: booleanAttribute });\n readonly adminActions = input<PortalHeaderAdminAction[]>([]);\n readonly navItems = input<PortalHeaderNavItem[]>([]);\n readonly userInitials = input.required<string>();\n\n readonly sessionClick = output<void>();\n}\n","import { Component, input } from '@angular/core';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Estado vacío de reservas en taller con llamada a agendar (página 36):\n * barra de estado vacío arriba (\"No tienes reservas de taller\"), panel de\n * invitación al medio (ícono en círculo azul, título, descripción, link) y\n * una fila de dos acciones al pie — un slot `[actions]` proyectado, para no\n * acoplar el componente a botones fijos.\n *\n * Distinto de `kf-empty-state` genérico: este combina la barra + la\n * invitación + las acciones como un bloque compuesto propio del dominio\n * \"taller\", no un placeholder de una sola pieza.\n *\n * <kf-reserve-block emptyLabel=\"No tienes reservas de taller\"\n * title=\"¿Necesitas mantención?\" description=\"Tenemos la mejor red de talleres.\"\n * actionLabel=\"Agenda tu reserva aquí\" actionHref=\"/taller/agendar\">\n * <kf-button actions icon=\"calendar\">Reservar hora</kf-button>\n * <kf-button actions variant=\"outline\" icon=\"list\">Ver agenda</kf-button>\n * </kf-reserve-block>\n */\n@Component({\n selector: 'kf-reserve-block',\n imports: [Icon],\n template: `\n <div class=\"kf-reserve-block__empty\">\n <kf-icon name=\"calendar\" size=\"sm\" />\n <span>{{ emptyLabel() }}</span>\n </div>\n <div class=\"kf-reserve-block__invite\">\n <span class=\"kf-reserve-block__invite-icon\">\n <kf-icon name=\"tool\" size=\"md\" />\n </span>\n <div class=\"kf-reserve-block__invite-text\">\n <span class=\"kf-reserve-block__invite-title\">{{ title() }}</span>\n @if (description()) {\n <span class=\"kf-reserve-block__invite-description\">{{ description() }}</span>\n }\n @if (actionLabel()) {\n <a class=\"kf-reserve-block__invite-action\" [href]=\"actionHref() || '#'\">\n {{ actionLabel() }}\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n </div>\n </div>\n <div class=\"kf-reserve-block__actions\">\n <ng-content select=\"[actions]\" />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-reserve-block__empty {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding-bottom: var(--kf-space-sm);\n border-bottom: 1px solid var(--kf-color-border);\n color: var(--kf-color-text-muted);\n font-size: 0.875rem;\n }\n .kf-reserve-block__invite {\n display: flex;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n }\n .kf-reserve-block__invite-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: 2.25rem;\n height: 2.25rem;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n }\n .kf-reserve-block__invite-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n }\n .kf-reserve-block__invite-title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-reserve-block__invite-description {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-reserve-block__invite-action {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n margin-top: var(--kf-space-xs);\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n .kf-reserve-block__invite-action:hover {\n text-decoration: underline;\n }\n .kf-reserve-block__actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class ReserveBlock {\n readonly emptyLabel = input('No tienes reservas de taller');\n readonly title = input.required<string>();\n readonly description = input<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Título de sub-sección con chip de ícono, pensado para anidarse dentro de\n * cards o paneles (a diferencia de `PageHeader`, que encabeza una página\n * completa). Un área de acciones opcional se proyecta vía\n * `<ng-content select=\"[actions]\">` para no acoplar el componente a un set\n * fijo de botones.\n *\n * `size=\"sm\"` reduce tipografía y espaciado para usarse dentro de cards ya\n * compactas. `solid` rellena el chip de ícono con el color primario sólido\n * en vez del tratamiento \"soft\" (fondo tenue) — pensado para superficies que\n * ya tienen un tinte de color propio, donde el chip \"soft\" perdería contraste.\n *\n * <kf-section-header icon=\"settings\" title=\"Preferencias\"\n * subtitle=\"Configuración general de la cuenta\">\n * <button actions>Editar</button>\n * </kf-section-header>\n *\n * <kf-section-header title=\"Detalle\" size=\"sm\" [solid]=\"true\" />\n */\n@Component({\n selector: 'kf-section-header',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <span class=\"kf-section-header__icon\" [class.kf-section-header__icon--solid]=\"solid()\">\n <kf-icon [name]=\"iconName\" [size]=\"size() === 'sm' ? 'sm' : 'md'\" />\n </span>\n }\n\n <span class=\"kf-section-header__text\">\n <span class=\"kf-section-header__title\">{{ title() }}</span>\n @if (subtitle()) {\n <span class=\"kf-section-header__subtitle\">{{ subtitle() }}</span>\n }\n </span>\n\n <span class=\"kf-section-header__actions\">\n <ng-content select=\"[actions]\" />\n </span>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n font-family: var(--kf-font-body);\n }\n :host(.kf-section-header--sm) {\n gap: var(--kf-space-xs);\n }\n .kf-section-header__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n inline-size: 2.5rem;\n block-size: 2.5rem;\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n :host(.kf-section-header--sm) .kf-section-header__icon {\n inline-size: 1.75rem;\n block-size: 1.75rem;\n border-radius: var(--kf-radius-xs);\n }\n .kf-section-header__icon--solid {\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n }\n .kf-section-header__text {\n display: flex;\n flex-direction: column;\n min-width: 0;\n flex: 1 1 auto;\n }\n .kf-section-header__title {\n font-family: var(--kf-font-title);\n font-size: 1rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n line-height: 1.3;\n }\n :host(.kf-section-header--sm) .kf-section-header__title {\n font-size: 0.875rem;\n }\n .kf-section-header__subtitle {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n line-height: 1.3;\n }\n :host(.kf-section-header--sm) .kf-section-header__subtitle {\n font-size: 0.75rem;\n }\n .kf-section-header__actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n `,\n host: {\n '[class.kf-section-header--sm]': \"size() === 'sm'\",\n },\n})\nexport class SectionHeader {\n readonly icon = input<IconName>();\n readonly title = input.required<string>();\n readonly subtitle = input<string>();\n readonly size = input<'sm'>();\n readonly solid = input(false, { transform: booleanAttribute });\n}\n","import { Component, computed, input, output } from '@angular/core';\n\nexport interface SegmentedOption {\n value: string;\n label: string;\n}\n\n/**\n * Control de segmentos relleno, tipo \"iOS segmented control\": 2-3 opciones\n * con un thumb que se desliza detrás de la opción activa.\n *\n * La posición del thumb se resuelve con una variable CSS (--kf-segmented-index)\n * y `transform: translateX()`, así la transición queda a cargo de CSS puro\n * (mismo criterio que Tabs), sin medir el DOM desde TypeScript.\n *\n * <kf-segmented [options]=\"options\" [value]=\"value\" (valueChange)=\"onChange($event)\" />\n */\n@Component({\n selector: 'kf-segmented',\n template: `\n <div class=\"kf-segmented__track\" [style.--kf-segmented-count]=\"options().length\">\n <div\n class=\"kf-segmented__thumb\"\n [style.--kf-segmented-index]=\"selectedIndex()\"\n [style.visibility]=\"selectedIndex() === -1 ? 'hidden' : 'visible'\"\n ></div>\n @for (option of options(); track option.value) {\n <button\n type=\"button\"\n class=\"kf-segmented__option\"\n [class.kf-segmented__option--active]=\"option.value === value()\"\n [attr.aria-pressed]=\"option.value === value()\"\n (click)=\"select(option.value)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-segmented__track {\n position: relative;\n display: grid;\n grid-template-columns: repeat(var(--kf-segmented-count), 1fr);\n gap: 2px;\n padding: 2px;\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n }\n .kf-segmented__thumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: calc((100% - 4px) / var(--kf-segmented-count));\n height: calc(100% - 4px);\n background: var(--kf-color-white);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-xs);\n transform: translateX(calc(var(--kf-segmented-index, 0) * 100%));\n transition: transform 0.2s ease;\n }\n .kf-segmented__option {\n position: relative;\n z-index: 1;\n font: inherit;\n padding: var(--kf-space-xs) var(--kf-space-md);\n border: none;\n background: transparent;\n color: var(--kf-color-text-muted);\n border-radius: var(--kf-radius-sm);\n cursor: pointer;\n transition: color 0.14s;\n }\n .kf-segmented__option:hover:not(.kf-segmented__option--active) {\n color: var(--kf-color-text);\n }\n .kf-segmented__option--active {\n color: var(--kf-color-ink);\n }\n .kf-segmented__option:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n `,\n})\nexport class Segmented {\n readonly options = input.required<SegmentedOption[]>();\n readonly value = input.required<string>();\n readonly valueChange = output<string>();\n\n /** Índice de la opción activa; -1 si `value` no matchea ninguna opción. */\n readonly selectedIndex = computed(() =>\n this.options().findIndex((option) => option.value === this.value()),\n );\n\n select(nextValue: string): void {\n if (nextValue === this.value()) {\n return;\n }\n this.valueChange.emit(nextValue);\n }\n}\n","import {\n Component,\n ElementRef,\n HostListener,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { FieldLabel } from '../field-label/FieldLabel';\n\nexport interface SelectMenuOption {\n value: string;\n label: string;\n}\n\nlet nextId = 0;\n\n/**\n * Dropdown de selección simple pero con panel propio (no usa `<select>` nativo),\n * para cuando se necesita más control visual que un `<select>` estándar permite.\n *\n * El panel flotante se implementa con `position: absolute` sobre el host\n * (sin Angular CDK Overlay, que no es dependencia del proyecto). Se abre y\n * cierra por click en el disparador, y se cierra al hacer click afuera o al\n * presionar Escape.\n *\n * <kf-select-menu\n * label=\"País\"\n * [options]=\"countries\"\n * [value]=\"selectedCountry()\"\n * (valueChange)=\"selectedCountry.set($event)\"\n * />\n *\n * Pendiente: el prop `icon` de otros componentes del design system requiere\n * un componente Icon / sprite SVG que esta librería todavía no tiene — este\n * componente no usa iconos, así que no aplica acá.\n */\n@Component({\n selector: 'kf-select-menu',\n imports: [FieldLabel],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n }\n <button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-select-menu__trigger\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n >\n <span\n class=\"kf-select-menu__value\"\n [class.kf-select-menu__value--placeholder]=\"!selectedOption()\"\n >\n {{ selectedOption()?.label ?? placeholder() }}\n </span>\n <span\n class=\"kf-select-menu__caret\"\n [class.kf-select-menu__caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n </button>\n @if (isOpen()) {\n <ul\n class=\"kf-select-menu__panel\"\n [id]=\"listboxId\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @for (option of options(); track option.value) {\n <li\n class=\"kf-select-menu__option\"\n [class.kf-select-menu__option--selected]=\"option.value === value()\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"option.value === value()\"\n (click)=\"select(option)\"\n (keydown.enter)=\"select(option)\"\n (keydown.space)=\"$event.preventDefault(); select(option)\"\n >\n {{ option.label }}\n </li>\n } @empty {\n <li class=\"kf-select-menu__empty\">Sin opciones disponibles</li>\n }\n </ul>\n }\n `,\n styles: `\n :host {\n display: inline-flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n position: relative;\n font: inherit;\n min-width: 200px;\n }\n .kf-select-menu__trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n width: 100%;\n font: inherit;\n font-family: var(--kf-font-body);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n color: var(--kf-color-text);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-select-menu__trigger:hover:not(:disabled) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-select-menu__trigger:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-select-menu__trigger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-select-menu__value {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .kf-select-menu__value--placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-select-menu__caret {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-text-muted);\n border-bottom: 2px solid var(--kf-color-text-muted);\n transform: rotate(45deg);\n transition: transform 0.14s;\n margin-top: -4px;\n }\n .kf-select-menu__caret--open {\n transform: rotate(-135deg);\n margin-top: 4px;\n }\n .kf-select-menu__panel {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 10;\n margin: var(--kf-space-xs) 0 0;\n padding: var(--kf-space-xs) 0;\n list-style: none;\n max-height: 240px;\n overflow-y: auto;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-md);\n }\n .kf-select-menu__option {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-select-menu__option:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-select-menu__option--selected {\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n font-weight: 600;\n }\n .kf-select-menu__empty {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class SelectMenu {\n readonly label = input<string>();\n readonly options = input<SelectMenuOption[]>([]);\n readonly value = input<string>();\n readonly placeholder = input<string>('Seleccionar');\n readonly disabled = input(false, { transform: booleanAttribute });\n\n readonly valueChange = output<string>();\n\n private readonly instanceId = `kf-select-menu-${nextId++}`;\n readonly triggerId = `${this.instanceId}-trigger`;\n readonly listboxId = `${this.instanceId}-listbox`;\n\n readonly isOpen = signal(false);\n\n readonly selectedOption = computed(() =>\n this.options().find((option) => option.value === this.value()),\n );\n\n private readonly host = inject(ElementRef<HTMLElement>);\n\n toggle(): void {\n if (this.disabled()) {\n return;\n }\n this.isOpen.update((open) => !open);\n }\n\n select(option: SelectMenuOption): void {\n this.isOpen.set(false);\n if (option.value !== this.value()) {\n this.valueChange.emit(option.value);\n }\n }\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(event: MouseEvent): void {\n if (this.isOpen() && !this.host.nativeElement.contains(event.target as Node)) {\n this.isOpen.set(false);\n }\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n this.isOpen.set(false);\n }\n}\n","import { Component, booleanAttribute, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Indicador numérico compacto (página 34): label + valor grande, con un\n * ícono a la derecha del label — más chico y sin badge de esquina que\n * `kf-metric-card`, pensado para grillas densas de KPIs simples (\"Total\n * vehículos: 4\", \"En taller: 1\"), no para dashboards con tendencia.\n *\n * Con `cta` en vez de `value`, se convierte en la variante de llamada a la\n * acción: un bloque de fondo suave con título, descripción y un link — sin\n * número, para promover el siguiente paso (ej. \"¿Necesitas mantención?\").\n *\n * <kf-stat-tile label=\"Total vehículos\" value=\"4\" icon=\"car\" />\n * <kf-stat-tile cta title=\"¿Necesitas mantención?\"\n * description=\"Tenemos la mejor red de talleres.\"\n * actionLabel=\"Agenda aquí\" actionHref=\"/taller/agendar\" />\n */\n@Component({\n selector: 'kf-stat-tile',\n imports: [Icon],\n template: `\n @if (cta()) {\n <span class=\"kf-stat-tile__cta-title\">{{ title() }}</span>\n @if (description()) {\n <span class=\"kf-stat-tile__cta-description\">{{ description() }}</span>\n }\n @if (actionLabel()) {\n <a class=\"kf-stat-tile__cta-action\" [href]=\"actionHref() || '#'\">\n {{ actionLabel() }}\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n } @else {\n <div class=\"kf-stat-tile__head\">\n <span class=\"kf-stat-tile__label\">{{ label() }}</span>\n @if (icon(); as iconName) {\n <span class=\"kf-stat-tile__icon\">\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n </span>\n }\n </div>\n <span class=\"kf-stat-tile__value\">{{ value() }}</span>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n }\n :host(.kf-stat-tile--cta) {\n background: var(--kf-color-surface);\n gap: 2px;\n }\n .kf-stat-tile__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-xs);\n }\n .kf-stat-tile__label {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-stat-tile__icon {\n display: inline-flex;\n color: var(--kf-color-primary);\n }\n .kf-stat-tile__value {\n font-family: var(--kf-font-title);\n font-size: 1.5rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-stat-tile__cta-title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-stat-tile__cta-description {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-stat-tile__cta-action {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n margin-top: var(--kf-space-xs);\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n .kf-stat-tile__cta-action:hover {\n text-decoration: underline;\n }\n `,\n host: {\n '[class.kf-stat-tile--cta]': 'cta()',\n },\n})\nexport class StatTile {\n readonly cta = input(false, { transform: booleanAttribute });\n // Variante numérica\n readonly label = input<string>();\n readonly value = input<string | number>();\n readonly icon = input<IconName>();\n // Variante CTA\n readonly title = input<string>();\n readonly description = input<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Pill con borde, en mayúsculas y con letter-spacing, pensada para indicadores\n * de estado únicos y prominentes (ej. \"ESTADO TÉCNICO\"). El fondo es siempre\n * transparente; el color de borde/texto/punto depende de `tone`.\n *\n * <kf-status-pill tone=\"ok\">Operativo</kf-status-pill>\n * <kf-status-pill tone=\"error\" dot>Fuera de servicio</kf-status-pill>\n */\n@Component({\n selector: 'kf-status-pill',\n template: `\n <span class=\"kf-status-pill\" [class]=\"'kf-status-pill--' + tone()\">\n @if (dot()) {\n <span class=\"kf-status-pill__dot\"></span>\n }\n <ng-content />\n </span>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-status-pill {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border: 1px solid currentColor;\n border-radius: var(--kf-radius-pill);\n background: transparent;\n font: inherit;\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n white-space: nowrap;\n }\n .kf-status-pill__dot {\n width: 6px;\n height: 6px;\n border-radius: var(--kf-radius-pill);\n background: currentColor;\n flex-shrink: 0;\n }\n .kf-status-pill--blue {\n color: var(--kf-color-info);\n }\n .kf-status-pill--ok {\n color: var(--kf-color-success);\n }\n .kf-status-pill--warn {\n color: var(--kf-color-warning);\n }\n .kf-status-pill--error {\n color: var(--kf-color-error);\n }\n `,\n})\nexport class StatusPill {\n readonly tone = input<'blue' | 'ok' | 'warn' | 'error'>('blue');\n readonly dot = input(false, { transform: booleanAttribute });\n}\n","import {\n Component,\n DestroyRef,\n ElementRef,\n afterNextRender,\n afterRenderEffect,\n computed,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\nexport interface TabOption {\n value: string;\n label: string;\n icon?: IconName;\n}\n\n/**\n * Barra de tabs subrayada: un único indicador se desliza horizontalmente hasta\n * la pestaña activa. Como las pestañas tienen ancho de contenido (labels de\n * largo distinto), la posición no se puede resolver con CSS puro: se mide el\n * `offsetLeft`/`offsetWidth` de la pestaña activa después de cada render y la\n * transición del `transform`/`width` queda a cargo de CSS.\n *\n * <kf-tabs [options]=\"tabs\" [value]=\"active\" (valueChange)=\"active = $event\" />\n */\n@Component({\n selector: 'kf-tabs',\n imports: [Icon],\n template: `\n <div class=\"kf-tabs\" role=\"tablist\" #track>\n @for (option of options(); track option.value) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"kf-tabs__tab\"\n [class.kf-tabs__tab--active]=\"option.value === value()\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.tabindex]=\"option.value === value() ? 0 : -1\"\n [id]=\"'kf-tab-' + option.value\"\n [attr.aria-controls]=\"'kf-tabpanel-' + option.value\"\n (click)=\"select(option.value)\"\n (keydown)=\"onKeydown($event, option.value)\"\n >\n @if (option.icon; as iconName) {\n <kf-icon class=\"kf-tabs__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <span class=\"kf-tabs__label\">{{ option.label }}</span>\n </button>\n }\n <span\n class=\"kf-tabs__indicator\"\n aria-hidden=\"true\"\n [style.transform]=\"indicatorTransform()\"\n [style.width.px]=\"indicatorWidth()\"\n [style.opacity]=\"indicatorWidth() ? 1 : 0\"\n ></span>\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-tabs {\n position: relative;\n display: flex;\n align-items: stretch;\n gap: var(--kf-space-md);\n border-bottom: 1px solid var(--kf-color-border);\n }\n .kf-tabs__tab {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n font: inherit;\n font-size: 0.9rem;\n color: var(--kf-color-text-muted);\n background: transparent;\n border: none;\n /* Sin padding horizontal propio: el espaciado entre tabs lo da el\n gap del contenedor — con ambos sumando (como antes) el conjunto\n quedaba más separado que en el PDF, que muestra las pestañas casi\n pegadas entre sí. El padding vertical se mantiene por área de click. */\n padding: var(--kf-space-sm) 0;\n cursor: pointer;\n transition: color 0.14s;\n }\n .kf-tabs__tab:hover:not(.kf-tabs__tab--active) {\n color: var(--kf-color-text);\n }\n .kf-tabs__tab:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n border-radius: var(--kf-radius-xs);\n }\n .kf-tabs__tab--active {\n color: var(--kf-color-primary);\n font-size: 1rem;\n font-weight: 700;\n }\n .kf-tabs__indicator {\n position: absolute;\n bottom: -1px;\n left: 0;\n height: 2px;\n background: var(--kf-color-primary);\n border-radius: 2px 2px 0 0;\n pointer-events: none;\n transition:\n transform 0.28s cubic-bezier(0.32, 0.72, 0, 1),\n width 0.28s cubic-bezier(0.32, 0.72, 0, 1),\n opacity 0.14s;\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-tabs__indicator {\n transition: opacity 0.14s;\n }\n }\n `,\n})\nexport class Tabs {\n readonly options = input.required<TabOption[]>();\n readonly value = input.required<string>();\n readonly valueChange = output<string>();\n\n private readonly track = viewChild.required<ElementRef<HTMLElement>>('track');\n private readonly destroyRef = inject(DestroyRef);\n\n /** Geometría de la pestaña activa; `null` mientras no haya una medición válida. */\n private readonly activeRect = signal<{ x: number; width: number } | null>(null);\n\n protected readonly indicatorTransform = computed(\n () => `translateX(${this.activeRect()?.x ?? 0}px)`,\n );\n protected readonly indicatorWidth = computed(() => this.activeRect()?.width ?? 0);\n\n constructor() {\n // Cada cambio de `value`/`options` re-mide después de que el DOM ya se actualizó.\n afterRenderEffect(() => {\n this.value();\n this.options();\n this.measure();\n });\n\n afterNextRender(() => {\n // El ancho de la pestaña activa cambia con el layout (resize, fuentes que\n // cargan tarde), y sin esto el indicador queda desfasado del texto.\n const observer = new ResizeObserver(() => this.measure());\n observer.observe(this.track().nativeElement);\n this.destroyRef.onDestroy(() => observer.disconnect());\n });\n }\n\n private measure(): void {\n const active = this.track().nativeElement.querySelector<HTMLElement>('.kf-tabs__tab--active');\n this.activeRect.set(active ? { x: active.offsetLeft, width: active.offsetWidth } : null);\n }\n\n select(value: string): void {\n if (value === this.value()) {\n return;\n }\n this.valueChange.emit(value);\n }\n\n /** Navegación estándar de ARIA tabs: flechas mueven el foco y activan la pestaña. */\n onKeydown(event: KeyboardEvent, currentValue: string): void {\n const items = this.options();\n const currentIndex = items.findIndex((option) => option.value === currentValue);\n\n let nextIndex: number;\n switch (event.key) {\n case 'ArrowRight':\n nextIndex = (currentIndex + 1) % items.length;\n break;\n case 'ArrowLeft':\n nextIndex = (currentIndex - 1 + items.length) % items.length;\n break;\n case 'Home':\n nextIndex = 0;\n break;\n case 'End':\n nextIndex = items.length - 1;\n break;\n default:\n return;\n }\n\n event.preventDefault();\n const nextOption = items[nextIndex];\n this.select(nextOption.value);\n\n const host = (event.currentTarget as HTMLElement).parentElement;\n const nextId = `kf-tab-${nextOption.value}`;\n const nextButton = Array.from(host?.querySelectorAll<HTMLButtonElement>('button') ?? []).find(\n (button) => button.id === nextId,\n );\n nextButton?.focus();\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n Injectable,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Visual tone of a toast. Maps to the state tokens in\n * projects/ui/src/tokens/base.css. `loading` has no auto-dismiss and shows an\n * indeterminate bar instead of a countdown — pair it with\n * {@link ToastService.promise}. It reuses the `info` tokens, the closest\n * semantic role to \"work in progress\".\n */\nexport type ToastTone = 'success' | 'error' | 'warning' | 'info' | 'loading';\n\n/** Fixed icon per tone (page 20 of the design system) — not configurable per call. */\nconst TOAST_ICON: Record<ToastTone, IconName> = {\n success: 'check-circle',\n error: 'alert-circle',\n warning: 'alert-triangle',\n info: 'bell',\n loading: 'bell',\n};\n\n/** Options for {@link ToastService.show}. */\nexport interface ToastOptions {\n /** Color tone. Defaults to `'info'`. */\n tone?: ToastTone;\n /** Milliseconds before auto-dismiss. Ignored when `tone` is `'loading'`. Defaults to `2800`. */\n duration?: number;\n}\n\n/** Messages for each leg of {@link ToastService.promise}. */\nexport interface ToastPromiseMessages<T = unknown> {\n loading?: string;\n success?: string | ((value: T) => string);\n error?: string | ((error: unknown) => string);\n}\n\n/** The single active toast, as rendered by `kf-toast-host`. */\nexport interface ToastState {\n id: number;\n message: string;\n tone: ToastTone;\n duration: number;\n leaving: boolean;\n}\n\nconst DEFAULT_DURATION_MS = 2800;\nconst EXIT_ANIMATION_MS = 200;\n\n/**\n * Shows one toast at a time — a new `show()` call replaces whatever is\n * currently up (this mirrors a global status line, not a notification stack).\n *\n * Angular has no global function that can mount UI on its own, so the\n * imperative `showToast(...)` of the reference design system becomes a\n * root-provided service holding signal state: `ToastService.show(...)` sets\n * the active toast and `ToastHost` (standalone, mounted once in the app\n * shell) renders it.\n *\n * @example\n * ```ts\n * // app.ts\n * imports: [ToastHost]\n * template: `<kf-toast-host />`\n *\n * // anywhere else\n * private readonly toast = inject(ToastService);\n * this.toast.show('Vehículo guardado', { tone: 'success' });\n *\n * // chains a `loading` toast into the promise's outcome:\n * this.toast.promise(this.api.save(vehicle), {\n * loading: 'Guardando…',\n * success: 'Vehículo guardado',\n * error: 'No se pudo guardar',\n * });\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class ToastService {\n private readonly _current = signal<ToastState | null>(null);\n private nextId = 0;\n private dismissTimer?: ReturnType<typeof setTimeout>;\n private removeTimer?: ReturnType<typeof setTimeout>;\n\n /** The single active toast, or `null`. */\n readonly current = this._current.asReadonly();\n\n /** Shows a toast, replacing whatever is currently shown. Returns its id. */\n show(message: string, options: ToastOptions = {}): number {\n const id = this.nextId++;\n const tone = options.tone ?? 'info';\n const duration = options.duration ?? DEFAULT_DURATION_MS;\n clearTimeout(this.dismissTimer);\n clearTimeout(this.removeTimer);\n this._current.set({ id, message, tone, duration, leaving: false });\n if (tone !== 'loading') {\n this.dismissTimer = setTimeout(() => this.dismiss(id), duration);\n }\n return id;\n }\n\n /**\n * Starts the exit animation, then removes the toast. No-op when `id` is no\n * longer the active toast, so a stale timer never kills a newer toast.\n */\n dismiss(id?: number): void {\n const toast = this._current();\n if (!toast || toast.leaving || (id !== undefined && toast.id !== id)) return;\n clearTimeout(this.dismissTimer);\n this._current.set({ ...toast, leaving: true });\n this.removeTimer = setTimeout(() => {\n if (this._current()?.id === toast.id) this._current.set(null);\n }, EXIT_ANIMATION_MS);\n }\n\n /**\n * Shows a `loading` toast, then swaps it for a `success`/`error` toast once\n * `work` settles. Re-throws `work`'s rejection so callers can still react to\n * the failure.\n */\n promise<T>(work: Promise<T>, messages: ToastPromiseMessages<T> = {}): Promise<T> {\n this.show(messages.loading ?? 'Procesando…', { tone: 'loading' });\n return work.then(\n (value) => {\n const msg = messages.success ?? 'Listo';\n this.show(typeof msg === 'function' ? msg(value) : msg, { tone: 'success' });\n return value;\n },\n (error) => {\n const msg = messages.error ?? 'Ocurrió un error';\n this.show(typeof msg === 'function' ? msg(error) : msg, { tone: 'error' });\n throw error;\n },\n );\n }\n}\n\n/**\n * Renders whatever `ToastService` currently holds, fixed bottom-right. Mount\n * one instance in the app shell (e.g. next to the router outlet); it takes no\n * inputs and re-renders itself from the service state.\n *\n * <kf-toast-host />\n */\n@Component({\n selector: 'kf-toast-host',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [Icon],\n template: `\n @for (t of toastList(); track t.id) {\n <div\n class=\"kf-toast kf-toast--{{ t.tone }}\"\n [class.kf-toast--leaving]=\"t.leaving\"\n role=\"status\"\n [attr.aria-live]=\"t.tone === 'error' ? 'assertive' : 'polite'\"\n >\n <kf-icon class=\"kf-toast__icon\" [name]=\"toastIcon(t.tone)\" size=\"sm\" />\n <span class=\"kf-toast__message\">{{ t.message }}</span>\n <button type=\"button\" class=\"kf-toast__dismiss\" aria-label=\"Cerrar\" (click)=\"dismiss(t.id)\">\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n <span class=\"kf-toast__bar\" [style.--kf-toast-dur]=\"t.duration + 'ms'\"></span>\n </div>\n }\n `,\n styles: `\n @keyframes kf-toast-in {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n }\n @keyframes kf-toast-bar {\n from {\n transform: scaleX(1);\n }\n to {\n transform: scaleX(0);\n }\n }\n @keyframes kf-toast-indeterminate {\n 0% {\n left: -40%;\n width: 40%;\n }\n 50% {\n left: 30%;\n width: 55%;\n }\n 100% {\n left: 100%;\n width: 40%;\n }\n }\n\n .kf-toast {\n /* Per-tone accent, overridden by the tone classes below. */\n --kf-toast-accent: var(--kf-color-info);\n\n position: fixed;\n inset-block-end: var(--kf-space-lg);\n inset-inline-end: var(--kf-space-lg);\n z-index: 1100;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n max-inline-size: 360px;\n padding: var(--kf-space-sm) var(--kf-space-sm) var(--kf-space-sm) var(--kf-space-md);\n border-radius: var(--kf-radius-md);\n border-left: 4px solid var(--kf-toast-accent);\n background: var(--kf-color-ink);\n color: var(--kf-color-white);\n box-shadow: var(--kf-shadow-lg);\n font-family: var(--kf-font-body);\n font-size: 0.875rem;\n font-weight: 600;\n line-height: 1.4;\n overflow: hidden;\n animation: kf-toast-in 0.25s ease forwards;\n transition:\n transform 0.2s ease,\n opacity 0.2s ease;\n }\n .kf-toast--leaving {\n transform: translateY(20px);\n opacity: 0;\n }\n .kf-toast--success {\n --kf-toast-accent: var(--kf-color-success);\n }\n .kf-toast--error {\n --kf-toast-accent: var(--kf-color-error);\n }\n .kf-toast--warning {\n --kf-toast-accent: var(--kf-color-warning);\n }\n .kf-toast--info,\n .kf-toast--loading {\n --kf-toast-accent: var(--kf-color-info);\n }\n\n .kf-toast__icon {\n flex: none;\n color: var(--kf-toast-accent);\n }\n .kf-toast__message {\n flex: 1;\n }\n .kf-toast__dismiss {\n flex: none;\n display: grid;\n place-items: center;\n inline-size: 24px;\n block-size: 24px;\n padding: 0;\n border: none;\n border-radius: var(--kf-radius-xs);\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1;\n cursor: pointer;\n opacity: 0.6;\n }\n .kf-toast__dismiss:hover {\n opacity: 1;\n }\n\n .kf-toast__bar {\n position: absolute;\n inset-block-end: 0;\n left: 0;\n block-size: 3px;\n inline-size: 100%;\n background: var(--kf-toast-accent);\n opacity: 0.7;\n transform-origin: left;\n animation: kf-toast-bar var(--kf-toast-dur, 2800ms) linear forwards;\n }\n .kf-toast--loading .kf-toast__bar {\n left: -40%;\n inline-size: 40%;\n opacity: 0.6;\n animation: kf-toast-indeterminate 1.4s ease-in-out infinite;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .kf-toast,\n .kf-toast__bar,\n .kf-toast--loading .kf-toast__bar {\n animation: none;\n }\n .kf-toast {\n transition: none;\n }\n }\n `,\n})\nexport class ToastHost {\n private readonly toastService = inject(ToastService);\n\n /** 0-or-1 wrapper so `@for track t.id` remounts the node on every new toast, restarting its animations. */\n protected readonly toastList = computed<ToastState[]>(() => {\n const toast = this.toastService.current();\n return toast ? [toast] : [];\n });\n\n protected toastIcon(tone: ToastTone): IconName {\n return TOAST_ICON[tone];\n }\n\n protected dismiss(id: number): void {\n this.toastService.dismiss(id);\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Estado puntual mostrado junto a la identidad del vehículo (ej. \"En ruta\",\n * \"Mantenimiento\", \"Fuera de servicio\"). `tone` define el color semántico:\n * \"crit\" no tiene token propio en base.css, se mapea a var(--kf-color-error).\n */\nexport interface VehicleHeaderStatus {\n label: string;\n tone?: 'ok' | 'warn' | 'crit';\n icon?: IconName;\n}\n\n/**\n * Header de identidad de un vehículo de flota: unidad (patente/id), modelo\n * (como badge, no texto plano — página 24: \"ABC-123\" junto a un badge\n * \"TITAN 4X2\"), VIN en fuente mono y un estado opcional. Un área de acciones\n * opcional se proyecta vía `<ng-content select=\"[actions]\">` para no acoplar\n * el componente a un set fijo de botones — el patrón real de la spec es\n * `kf-button variant=\"outline\"` (ej. \"Llamar\", con ícono) + un `primary`\n * (ej. \"Crear Ticket\", con ícono \"+\"):\n *\n * <kf-vehicle-header unit=\"AB123CD\" model=\"Sprinter 415\" vin=\"9BW...\"\n * [status]=\"{ label: 'En ruta', tone: 'ok' }\">\n * <kf-button actions variant=\"outline\" icon=\"phone\">Llamar</kf-button>\n * <kf-button actions icon=\"plus\">Crear Ticket</kf-button>\n * </kf-vehicle-header>\n */\n@Component({\n selector: 'kf-vehicle-header',\n imports: [Icon],\n template: `\n <div class=\"kf-vehicle-header__identity\">\n <span class=\"kf-vehicle-header__unit\">{{ unit() }}</span>\n @if (model()) {\n <span class=\"kf-vehicle-header__model\">{{ model() }}</span>\n }\n @if (vin()) {\n <span class=\"kf-vehicle-header__vin\">VIN: {{ vin() }}</span>\n }\n </div>\n\n @if (status(); as currentStatus) {\n <span\n class=\"kf-vehicle-header__status\"\n [class]=\"'kf-vehicle-header__status--' + (currentStatus.tone ?? 'ok')\"\n >\n @if (currentStatus.icon; as iconName) {\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n }\n {{ currentStatus.label }}\n </span>\n }\n\n <div class=\"kf-vehicle-header__actions\">\n <ng-content select=\"[actions]\" />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-md);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-surface);\n font-family: var(--kf-font-body);\n }\n .kf-vehicle-header__identity {\n display: flex;\n align-items: baseline;\n flex-wrap: wrap;\n gap: var(--kf-space-sm);\n flex: 1 1 auto;\n min-width: 0;\n }\n .kf-vehicle-header__unit {\n font-family: var(--kf-font-title);\n font-size: 1.125rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-vehicle-header__model {\n padding: 2px var(--kf-space-sm);\n border-radius: var(--kf-radius-xs);\n background: var(--kf-color-border);\n color: var(--kf-color-text-muted);\n font-size: 0.75rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n }\n .kf-vehicle-header__vin {\n font-family: var(--kf-font-mono);\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-vehicle-header__status {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1;\n white-space: nowrap;\n }\n .kf-vehicle-header__status--ok {\n background: var(--kf-color-success-soft);\n color: var(--kf-color-success);\n }\n .kf-vehicle-header__status--warn {\n background: var(--kf-color-warning-soft);\n color: var(--kf-color-warning);\n }\n .kf-vehicle-header__status--crit {\n background: var(--kf-color-error-soft);\n color: var(--kf-color-error);\n }\n .kf-vehicle-header__actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class VehicleHeader {\n readonly unit = input.required<string>();\n readonly model = input<string>();\n readonly vin = input<string>();\n readonly status = input<VehicleHeaderStatus>();\n}\n","import { Component, input, output } from '@angular/core';\n\nexport type ViewToggleOption = 'table' | 'cards';\n\n/**\n * Switch de dos posiciones para alternar entre vista de tabla y vista de\n * tarjetas. Pensado para usarse dentro de DataTable, pero es standalone e\n * independiente: no asume nada sobre el componente que lo contiene.\n *\n * Se implementa como un grupo de radio (role=\"radiogroup\") en vez de dos\n * botones sueltos: semánticamente es una única selección excluyente entre\n * dos estados, no dos acciones independientes. Esto también habilita\n * navegación con flechas izquierda/derecha, igual que un <input type=\"radio\">\n * nativo agrupado.\n *\n * <kf-view-toggle [view]=\"view\" (viewChange)=\"view = $event\" />\n */\n@Component({\n selector: 'kf-view-toggle',\n template: `\n <div class=\"kf-view-toggle\" role=\"radiogroup\" aria-label=\"Alternar tipo de vista\">\n <button\n type=\"button\"\n role=\"radio\"\n class=\"kf-view-toggle__option\"\n [class.kf-view-toggle__option--active]=\"view() === 'table'\"\n [attr.aria-checked]=\"view() === 'table'\"\n [attr.tabindex]=\"view() === 'table' ? 0 : -1\"\n (click)=\"select('table')\"\n (keydown)=\"onKeydown($event)\"\n >\n Tabla\n </button>\n <button\n type=\"button\"\n role=\"radio\"\n class=\"kf-view-toggle__option\"\n [class.kf-view-toggle__option--active]=\"view() === 'cards'\"\n [attr.aria-checked]=\"view() === 'cards'\"\n [attr.tabindex]=\"view() === 'cards' ? 0 : -1\"\n (click)=\"select('cards')\"\n (keydown)=\"onKeydown($event)\"\n >\n Tarjetas\n </button>\n </div>\n `,\n styles: `\n :host {\n display: inline-block;\n font-family: var(--kf-font-body);\n }\n .kf-view-toggle {\n display: inline-flex;\n align-items: stretch;\n gap: 2px;\n padding: 2px;\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n }\n .kf-view-toggle__option {\n font: inherit;\n font-size: 0.85rem;\n line-height: 1;\n color: var(--kf-color-text-muted);\n background: transparent;\n border: none;\n border-radius: var(--kf-radius-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n cursor: pointer;\n transition:\n background 0.14s,\n color 0.14s,\n box-shadow 0.14s;\n }\n .kf-view-toggle__option:hover:not(.kf-view-toggle__option--active) {\n color: var(--kf-color-text);\n }\n .kf-view-toggle__option:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-view-toggle__option--active {\n color: var(--kf-color-ink);\n background: var(--kf-color-white);\n box-shadow: var(--kf-shadow-xs);\n }\n `,\n})\nexport class ViewToggle {\n readonly view = input.required<ViewToggleOption>();\n readonly viewChange = output<ViewToggleOption>();\n\n select(next: ViewToggleOption): void {\n if (next === this.view()) {\n return;\n }\n this.viewChange.emit(next);\n }\n\n /** Navegación estándar de ARIA radiogroup: flechas mueven foco y seleccionan. */\n onKeydown(event: KeyboardEvent): void {\n if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') {\n return;\n }\n\n event.preventDefault();\n const next: ViewToggleOption = this.view() === 'table' ? 'cards' : 'table';\n this.select(next);\n\n const current = event.currentTarget as HTMLElement;\n const buttons =\n current.parentElement?.querySelectorAll<HTMLButtonElement>('.kf-view-toggle__option');\n const nextButton = Array.from(buttons ?? []).find((button) => button !== current);\n nextButton?.focus();\n }\n}\n","/*\n * Public API Surface of ui\n */\n\nexport * from './lib/action-tile/ActionTile';\nexport * from './lib/admin-badge/AdminBadge';\nexport * from './lib/button/button';\nexport * from './lib/alert/Alert';\nexport * from './lib/avatar/Avatar';\nexport * from './lib/badge/Badge';\nexport * from './lib/breadcrumb/Breadcrumb';\nexport * from './lib/card/Card';\nexport * from './lib/carousel/Carousel';\nexport * from './lib/checkbox/Checkbox';\nexport * from './lib/chip/Chip';\nexport * from './lib/company-selector/CompanySelector';\nexport * from './lib/content-slot/ContentSlot';\nexport * from './lib/content-state/ContentState';\nexport * from './lib/data-table/DataTable';\nexport * from './lib/empty-state/EmptyState';\nexport * from './lib/feature-card/FeatureCard';\nexport * from './lib/field/Field';\nexport * from './lib/field-label/FieldLabel';\nexport * from './lib/filter-chips/FilterChips';\nexport * from './lib/folder-tabs/FolderTabs';\nexport * from './lib/icon/Icon';\nexport * from './lib/input/Input';\nexport * from './lib/metric-card/MetricCard';\nexport * from './lib/modal/Modal';\nexport * from './lib/multi-select/MultiSelect';\nexport * from './lib/page-header/PageHeader';\nexport * from './lib/pagination/Pagination';\nexport * from './lib/panel/Panel';\nexport * from './lib/portal-header/PortalHeader';\nexport * from './lib/reserve-block/ReserveBlock';\nexport * from './lib/section-header/SectionHeader';\nexport * from './lib/segmented/Segmented';\nexport * from './lib/select/Select';\nexport * from './lib/select-menu/SelectMenu';\nexport * from './lib/skeleton/Skeleton';\nexport * from './lib/spinner/Spinner';\nexport * from './lib/stat-tile/StatTile';\nexport * from './lib/status-pill/StatusPill';\nexport * from './lib/tabs/Tabs';\nexport * from './lib/toast/Toast';\nexport * from './lib/vehicle-header/VehicleHeader';\nexport * from './lib/view-toggle/ViewToggle';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["nextId"],"mappings":";;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;AACI,MAAM,cAAc,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyRvB;;AC9OP;;;;AAI4E;AAC5E,MAAM,cAAc,GAAG,qBAAqB;AAE5C;;;;;;;;;;;;;;AAcG;MA4BU,IAAI,CAAA;IACN,IAAI,GAAG,KAAK,CAAC,QAAQ;6EAAY;IACjC,IAAI,GAAG,KAAK,CAAW,IAAI;6EAAC;AAEpB,IAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;AAEzB,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAK;AAC3C,QAAA,MAAM,MAAM,GAA6B,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE;AAC/E,QAAA,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;kFAAC;AAEF,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,MAAK;YACV,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE;gBAChD;YACF;YACA,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;AACpD,YAAA,SAAS,CAAC,SAAS,GAAG,cAAc;AACpC,YAAA,MAAM,MAAM,GAAG,SAAS,CAAC,iBAAiB;YAC1C,IAAI,MAAM,EAAE;AACV,gBAAA,MAAM,CAAC,EAAE,GAAG,cAAc;gBAC1B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YACpC;AACF,QAAA,CAAC,CAAC;IACJ;uGAxBW,IAAI,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAJ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,IAAI,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,sBAAA,EAAA,aAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAzBL;;;;AAIT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,qNAAA,CAAA,EAAA,CAAA;;2FAqBU,IAAI,EAAA,UAAA,EAAA,CAAA;kBA3BhB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,SAAS,EAAA,QAAA,EACT;;;;GAIT,EAAA,IAAA,EAiBK;AACJ,wBAAA,wBAAwB,EAAE,aAAa;AACxC,qBAAA,EAAA,MAAA,EAAA,CAAA,qNAAA,CAAA,EAAA;;;AChHH;;;;;;;;;;;;AAYG;MA+EU,UAAU,CAAA;IACZ,OAAO,GAAG,KAAK,CAAiB,MAAM;gFAAC;IACvC,IAAI,GAAG,KAAK,CAAC,QAAQ;6EAAY;IACjC,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAU;AAChC,IAAA,WAAW,GAAG,KAAK;+FAAU;uGAJ3B,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,4BAAA,EAAA,sBAAA,EAAA,2BAAA,EAAA,qBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA3EX;;;;;;;;;;AAUT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,ioCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAXS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FA4EH,UAAU,EAAA,UAAA,EAAA,CAAA;kBA9EtB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,OAAA,EACjB,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;;GAUT,EAAA,IAAA,EA4DK;AACJ,wBAAA,8BAA8B,EAAE,sBAAsB;AACtD,wBAAA,6BAA6B,EAAE,qBAAqB;AACrD,qBAAA,EAAA,MAAA,EAAA,CAAA,ioCAAA,CAAA,EAAA;;;ACzFH;;;;;;;;AAQG;MAkCU,UAAU,CAAA;;IAEZ,MAAM,GAAG,KAAK,CAAC,KAAK,8EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;uGAFpD,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,8BAAA,EAAA,UAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA9BX;;;AAGT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,wdAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAJS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FA+BH,UAAU,EAAA,UAAA,EAAA,CAAA;kBAjCtB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,OAAA,EACjB,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;GAGT,EAAA,IAAA,EAuBK;AACJ,wBAAA,gCAAgC,EAAE,UAAU;AAC7C,qBAAA,EAAA,MAAA,EAAA,CAAA,wdAAA,CAAA,EAAA;;;ACxCH;;;;;;;;;;;;;;;;;;;AAmBG;MAmHU,MAAM,CAAA;IACR,OAAO,GAAG,KAAK,CAA2D,SAAS;gFAAC;IACpF,IAAI,GAAG,KAAK,CAAqB,IAAI;6EAAC;IACtC,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;;IAExD,IAAI,GAAG,KAAK,CAAgC,QAAQ;6EAAC;;AAErD,IAAA,IAAI,GAAG,KAAK;wFAAY;;IAExB,KAAK,GAAG,KAAK,CAAC,KAAK,6EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;uGATnD,MAAM,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAN,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAM,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,YAAA,EAAA,qBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA/GP;;;;;;;;;;;;;;;;AAgBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,mrDAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAjBS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAgHH,MAAM,EAAA,UAAA,EAAA,CAAA;kBAlHlB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,WAAW,EAAA,OAAA,EACZ,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;;;;;;;;GAgBT,EAAA,IAAA,EA2FK;AACJ,wBAAA,cAAc,EAAE,qBAAqB;AACtC,qBAAA,EAAA,MAAA,EAAA,CAAA,mrDAAA,CAAA,EAAA;;;ACnIH;;;;;;;;;;;;;;;AAeG;MA+HU,KAAK,CAAA;IACP,IAAI,GAAG,KAAK,CAAY,MAAM;6EAAC;;IAE/B,KAAK,GAAG,KAAK,CAAC,EAAE;8EAAC;IACjB,WAAW,GAAG,KAAK,CAAC,KAAK,mFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;;IAE3D,IAAI,GAAG,KAAK,CAAC,IAAI;6EAAC;AAE3B;;;AAGG;IACgB,QAAQ,GAAG,QAAQ,CAAC,MACrC,IAAI,CAAC,IAAI,EAAE,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,MAAM,GAAG,OAAO,GAAG,QAAQ;iFACvE;uGAdU,KAAK,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAL,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAK,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,IAAA,EAAA,YAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA5HN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,4zCAAA,CAAA,EAAA,CAAA;;2FA8EU,KAAK,EAAA,UAAA,EAAA,CAAA;kBA9HjB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,UAAU,EAAA,QAAA,EACV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,4zCAAA,CAAA,EAAA;;;ACjEH;;;;;;;;;;;;;;;;AAgBG;MAoFU,MAAM,CAAA;AACR,IAAA,QAAQ,GAAG,KAAK;4FAAU;AAC1B,IAAA,GAAG,GAAG,KAAK;uFAAU;IACrB,KAAK,GAAG,KAAK,CAAC,IAAI;8EAAC;;IAEnB,IAAI,GAAG,KAAK,CAAC,KAAK,4EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;;IAGpD,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;wFAAC;uGARnE,MAAM,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAN,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAM,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAhFP;;;;;;;;;;;;;;;;;;;AAmBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,kjCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EApBS,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,kBAAA,EAAA,0BAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAiFf,MAAM,EAAA,UAAA,EAAA,CAAA;kBAnFlB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,WAAW,EAAA,OAAA,EACZ,CAAC,gBAAgB,CAAC,EAAA,QAAA,EACjB;;;;;;;;;;;;;;;;;;;AAmBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,kjCAAA,CAAA,EAAA;;;ACxCH;;;;;;;;;;;;;;;;;;AAkBG;MA8DU,KAAK,CAAA;IACP,IAAI,GAAG,KAAK,CAA2D,SAAS;6EAAC;IACjF,GAAG,GAAG,KAAK,CAAC,KAAK,2EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;uGAFjD,KAAK,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAL,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAK,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA3DN;;;;;;;AAOT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,k+BAAA,CAAA,EAAA,CAAA;;2FAoDU,KAAK,EAAA,UAAA,EAAA,CAAA;kBA7DjB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,UAAU,EAAA,QAAA,EACV;;;;;;;AAOT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,k+BAAA,CAAA,EAAA;;;ACtBH;;;;;;;;;;;;;AAaG;MAyFU,UAAU,CAAA;IACZ,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAoB;AAEnD;;;;;;AAMG;IACM,SAAS,GAAG,MAAM,EAA8D;AAEtE,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,GAAG,CAAC;kFAAC;uGAZ3D,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAtFX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,kyBAAA,CAAA,EAAA,CAAA;;2FAmDU,UAAU,EAAA,UAAA,EAAA,CAAA;kBAxFtB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,eAAe,EAAA,QAAA,EACf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,kyBAAA,CAAA,EAAA;;;ACzDH;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;MAiDU,IAAI,CAAA;;IAEN,KAAK,GAAG,KAAK,CAAC,KAAK,6EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;uGAFnD,IAAI,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAJ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,IAAI,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,sBAAA,EAAA,SAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA9CL;;;;;;AAMT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,8nBAAA,CAAA,EAAA,CAAA;;2FAwCU,IAAI,EAAA,UAAA,EAAA,CAAA;kBAhDhB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,SAAS,EAAA,QAAA,EACT;;;;;;GAMT,EAAA,IAAA,EAoCK;AACJ,wBAAA,wBAAwB,EAAE,SAAS;AACpC,qBAAA,EAAA,MAAA,EAAA,CAAA,8nBAAA,CAAA,EAAA;;;AC7DH;;;;;;;AAOG;MAYU,aAAa,CAAA;uGAAb,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,aAAa,6EATd,CAAA,cAAA,CAAgB,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,iDAAA,CAAA,EAAA,CAAA;;2FASf,aAAa,EAAA,UAAA,EAAA,CAAA;kBAXzB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mBAAmB,YACnB,CAAA,cAAA,CAAgB,EAAA,MAAA,EAAA,CAAA,iDAAA,CAAA,EAAA;;AAW5B;;;;;;;;;;;;;;;AAeG;MAkIU,QAAQ,CAAA;IACV,QAAQ,GAAG,KAAK,CAAC,KAAK;iFAAC;IACvB,QAAQ,GAAG,KAAK,CAAC,IAAI,gFAAI,SAAS,EAAE,eAAe,EAAA,CAAG;IACtD,WAAW,GAAG,MAAM,EAAU;IAE9B,MAAM,GAAG,eAAe,CAAC,aAAa;+EAAC;IAE/B,iBAAiB,GAAG,MAAM,CAAC,CAAC;0FAAC;AACrC,IAAA,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,EAAE;AAEzC,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACxC,KAAK,GAA0C,IAAI;IACnD,cAAc,GAAG,KAAK;IAE9B,kBAAkB,GAAA;QAChB,IAAI,CAAC,aAAa,EAAE;AACpB,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IACtD;IAEA,IAAI,GAAA;QACF,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM;AAClC,QAAA,IAAI,KAAK,KAAK,CAAC,EAAE;YACf;QACF;AACA,QAAA,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,CAAC,IAAI,KAAK,CAAC;IACnD;IAEA,QAAQ,GAAA;QACN,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM;AAClC,QAAA,IAAI,KAAK,KAAK,CAAC,EAAE;YACf;QACF;AACA,QAAA,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,CAAC,GAAG,KAAK,IAAI,KAAK,CAAC;IAC3D;AAEA,IAAA,IAAI,CAAC,KAAa,EAAA;AAChB,QAAA,IAAI,KAAK,KAAK,IAAI,CAAC,iBAAiB,EAAE,EAAE;YACtC;QACF;AACA,QAAA,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC;AACjC,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9B;IAEA,aAAa,GAAA;AACX,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI;IAC5B;IAEA,cAAc,GAAA;AACZ,QAAA,IAAI,CAAC,cAAc,GAAG,KAAK;IAC7B;IAEQ,aAAa,GAAA;AACnB,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE;YACjD;QACF;AACA,QAAA,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,MAAK;AAC5B,YAAA,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;gBACxB,IAAI,CAAC,IAAI,EAAE;YACb;AACF,QAAA,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;IACrB;IAEQ,YAAY,GAAA;AAClB,QAAA,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE;AACvB,YAAA,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;AACzB,YAAA,IAAI,CAAC,KAAK,GAAG,IAAI;QACnB;IACF;uGAnEW,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAR,QAAQ,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,OAAA,EAAA,CAAA,EAAA,YAAA,EAAA,QAAA,EAAA,SAAA,EAKe,aAAa,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EApIrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,o1CAAA,CAAA,EAAA,CAAA;;2FA6EU,QAAQ,EAAA,UAAA,EAAA,CAAA;kBAjIpB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,aAAa,EAAA,QAAA,EACb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,o1CAAA,CAAA,EAAA;yVAkFiC,aAAa,CAAA,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AC3KjD;;;;;;;;;;;;;;;;AAgBG;MAoGU,QAAQ,CAAA;AACV,IAAA,KAAK,GAAG,KAAK;yFAAU;IACvB,OAAO,GAAG,KAAK,CAAC,KAAK,+EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;IACvD,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;IACxD,aAAa,GAAG,KAAK,CAAC,KAAK,qFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;IAE7D,aAAa,GAAG,MAAM,EAAW;AAEzB,IAAA,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAA+B,UAAU;iFAAC;;AAGhF,IAAA,UAAU,GAA6B,MAAK,EAAE,CAAC;AAC/C,IAAA,WAAW,GAAe,MAAK,EAAE,CAAC;AAE1C,IAAA,WAAA,GAAA;;;;QAIE,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,QAAQ,EAAE,CAAC,aAAa,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE;AACpE,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,QAAQ,CAAC,KAAY,EAAA;AACnB,QAAA,MAAM,KAAK,GAAI,KAAK,CAAC,MAA2B,CAAC,OAAO;AACxD,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;AAC9B,QAAA,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;IACxB;IAEA,SAAS,GAAA;QACP,IAAI,CAAC,WAAW,EAAE;IACpB;AAEA,IAAA,UAAU,CAAC,KAAc,EAAA;QACvB,IAAI,CAAC,QAAQ,EAAE,CAAC,aAAa,CAAC,OAAO,GAAG,CAAC,CAAC,KAAK;IACjD;AAEA,IAAA,gBAAgB,CAAC,EAA4B,EAAA;AAC3C,QAAA,IAAI,CAAC,UAAU,GAAG,EAAE;IACtB;AAEA,IAAA,iBAAiB,CAAC,EAAc,EAAA;AAC9B,QAAA,IAAI,CAAC,WAAW,GAAG,EAAE;IACvB;AAEA,IAAA,gBAAgB,CAAE,UAAmB,EAAA;QACnC,IAAI,CAAC,QAAQ,EAAE,CAAC,aAAa,CAAC,QAAQ,GAAG,UAAU;IACrD;uGA/CW,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAR,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,QAAQ,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,aAAA,EAAA,eAAA,EAAA,EAAA,SAAA,EARR;AACT,YAAA;AACE,gBAAA,OAAO,EAAE,iBAAiB;AAC1B,gBAAA,WAAW,EAAE,UAAU,CAAC,MAAM,QAAQ,CAAC;AACvC,gBAAA,KAAK,EAAE,IAAI;AACZ,aAAA;SACF,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,UAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,UAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA/FS;;;;;;;;;;;;;;;AAeT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,m6CAAA,CAAA,EAAA,CAAA;;2FAkFU,QAAQ,EAAA,UAAA,EAAA,CAAA;kBAnGpB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,aAAa,EAAA,QAAA,EACb;;;;;;;;;;;;;;;GAeT,EAAA,SAAA,EA0EU;AACT,wBAAA;AACE,4BAAA,OAAO,EAAE,iBAAiB;AAC1B,4BAAA,WAAW,EAAE,UAAU,CAAC,cAAc,CAAC;AACvC,4BAAA,KAAK,EAAE,IAAI;AACZ,yBAAA;AACF,qBAAA,EAAA,MAAA,EAAA,CAAA,m6CAAA,CAAA,EAAA;iiBAU4E,UAAU,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;ACtIzF;;;;;;;;;;;;;;AAcG;MA+EU,IAAI,CAAA;IACN,IAAI,GAAG,KAAK,CAAsC,SAAS;6EAAC;uGAD1D,IAAI,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAJ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,IAAI,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,mBAAA,EAAA,iBAAA,EAAA,qBAAA,EAAA,mBAAA,EAAA,sBAAA,EAAA,oBAAA,EAAA,wBAAA,EAAA,sBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA5EL;;;;;;;;;AAST,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,8tCAAA,CAAA,EAAA,CAAA;;2FAmEU,IAAI,EAAA,UAAA,EAAA,CAAA;kBA9EhB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,SAAS,EAAA,QAAA,EACT;;;;;;;;;GAST,EAAA,IAAA,EA4DK;AACJ,wBAAA,qBAAqB,EAAE,iBAAiB;AACxC,wBAAA,uBAAuB,EAAE,mBAAmB;AAC5C,wBAAA,wBAAwB,EAAE,oBAAoB;AAC9C,wBAAA,0BAA0B,EAAE,sBAAsB;AACnD,qBAAA,EAAA,MAAA,EAAA,CAAA,8tCAAA,CAAA,EAAA;;;AC3FH;;;;;;;;;;;;;AAaG;MAkBU,UAAU,CAAA;;AAEZ,IAAA,GAAG,GAAG,KAAK;uFAAU;uGAFnB,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,wMAfX,CAAA,oEAAA,CAAsE,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,4LAAA,CAAA,EAAA,CAAA;;2FAerE,UAAU,EAAA,UAAA,EAAA,CAAA;kBAjBtB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,YAChB,CAAA,oEAAA,CAAsE,EAAA,MAAA,EAAA,CAAA,4LAAA,CAAA,EAAA;;;ACClF,IAAIA,QAAM,GAAG,CAAC;AAEd;;;;;;;;;;;;;;;;AAgBG;MA4JU,MAAM,CAAA;AACR,IAAA,KAAK,GAAG,KAAK;yFAAU;IACvB,OAAO,GAAG,KAAK,CAAC,QAAQ;gFAA6B;AACrD,IAAA,KAAK,GAAG,KAAK;yFAAU;IACvB,WAAW,GAAG,KAAK,CAAS,aAAa;oFAAC;IAC1C,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;IAExD,WAAW,GAAG,MAAM,EAAU;AAEtB,IAAA,UAAU,GAAG,CAAA,UAAA,EAAaA,QAAM,EAAE,EAAE;AAC5C,IAAA,SAAS,GAAG,CAAA,EAAG,IAAI,CAAC,UAAU,UAAU;AACxC,IAAA,SAAS,GAAG,CAAA,EAAG,IAAI,CAAC,UAAU,UAAU;IAExC,MAAM,GAAG,MAAM,CAAC,KAAK;+EAAC;;AAGtB,IAAA,iBAAiB,GAAG,QAAQ,CAAiB,MACpD,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,KACxB,OAAO,MAAM,KAAK,QAAQ,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CACvE;0FACF;IAEQ,cAAc,GAAG,QAAQ,CAAC,MACjC,IAAI,CAAC,iBAAiB,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;uFACzE;AAEgB,IAAA,IAAI,GAAG,MAAM,EAAC,UAAuB,EAAC;IAEvD,MAAM,GAAA;AACJ,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE;YACnB;QACF;AACA,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC;IACrC;AAEA,IAAA,MAAM,CAAC,MAAoB,EAAA;AACzB,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;QACtB,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE;YACjC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QACrC;IACF;AAGA,IAAA,eAAe,CAAC,KAAiB,EAAA;AAC/B,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAc,CAAC,EAAE;AAC5E,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;QACxB;IACF;IAGA,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;IACxB;uGApDW,MAAM,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAN,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAM,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,gBAAA,EAAA,yBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAxJP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,64DAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAnDS,UAAU,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,KAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAyJT,MAAM,EAAA,UAAA,EAAA,CAAA;kBA3JlB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,WAAW,EAAA,OAAA,EACZ,CAAC,UAAU,CAAC,EAAA,QAAA,EACX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,64DAAA,CAAA,EAAA;;sBAgJA,YAAY;uBAAC,gBAAgB,EAAE,CAAC,QAAQ,CAAC;;sBAOzC,YAAY;uBAAC,yBAAyB;;;ACzOzC;;;;;;;;;;;;;;;;;AAiBG;MAgEU,eAAe,CAAA;IACjB,KAAK,GAAG,KAAK,CAAC,oBAAoB;8EAAC;IACnC,SAAS,GAAG,KAAK,CAAC,QAAQ;kFAAY;AACtC,IAAA,KAAK,GAAG,KAAK;yFAAU;IACvB,IAAI,GAAG,KAAK,CAAwB,EAAE;6EAAC;IAEvC,WAAW,GAAG,MAAM,EAAU;uGAN5B,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAf,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAe,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA5DhB;;;;;;;;;;;;;;;;;;AAkBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,suBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAnBS,MAAM,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,EAAA,OAAA,EAAA,aAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,aAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FA6DL,eAAe,EAAA,UAAA,EAAA,CAAA;kBA/D3B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,qBAAqB,EAAA,OAAA,EACtB,CAAC,MAAM,CAAC,EAAA,QAAA,EACP;;;;;;;;;;;;;;;;;;AAkBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,suBAAA,CAAA,EAAA;;;AC7CH;;;;;;;;;;;;;;AAcG;MAmEU,WAAW,CAAA;IACb,KAAK,GAAG,KAAK,CAAC,sBAAsB;8EAAC;AACrC,IAAA,WAAW,GAAG,KAAK;+FAAU;IAC7B,IAAI,GAAG,KAAK,CAAW,QAAQ;6EAAC;IAChC,OAAO,GAAG,KAAK,CAAC,KAAK,+EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;uGAJrD,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAX,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,gCAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA/DZ;;;;;;;;;;;AAWT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,q/BAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAZS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAgEH,WAAW,EAAA,UAAA,EAAA,CAAA;kBAlEvB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,iBAAiB,EAAA,OAAA,EAClB,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;;;GAWT,EAAA,IAAA,EAgDK;AACJ,wBAAA,kCAAkC,EAAE,WAAW;AAChD,qBAAA,EAAA,MAAA,EAAA,CAAA,q/BAAA,CAAA,EAAA;;;AC/EH;;;;;;;;;;;;;;;;;;;AAmBG;MA6CU,UAAU,CAAA;IACZ,IAAI,GAAG,KAAK,CAAuB,SAAS;6EAAC;;IAE7C,IAAI,GAAG,KAAK,CAAsB,SAAS;6EAAC;uGAH1C,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,6BAAA,EAAA,oBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAzCX;;;;;;;;;AAST,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,kkBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAVS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FA0CH,UAAU,EAAA,UAAA,EAAA,CAAA;kBA5CtB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,OAAA,EACjB,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;GAST,EAAA,IAAA,EA4BK;AACJ,wBAAA,+BAA+B,EAAE,oBAAoB;AACtD,qBAAA,EAAA,MAAA,EAAA,CAAA,kkBAAA,CAAA,EAAA;;;AC5DH;;;;;;;;;;;;;AAaG;MAuDU,QAAQ,CAAA;IACV,OAAO,GAAG,KAAK,CAAkB,MAAM;gFAAC;;IAExC,KAAK,GAAG,KAAK,CAAC,MAAM;8EAAC;;IAErB,MAAM,GAAG,KAAK,CAAC,EAAE;+EAAC;uGALhB,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAR,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,QAAQ,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EApDT;;;;;;;;AAQT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,8nBAAA,CAAA,EAAA,CAAA;;2FA4CU,QAAQ,EAAA,UAAA,EAAA,CAAA;kBAtDpB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,aAAa,EAAA,QAAA,EACb;;;;;;;;AAQT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,8nBAAA,CAAA,EAAA;;;ACzBH;;;;;;;;;;;;;;AAcG;MA6EU,OAAO,CAAA;IACT,IAAI,GAAG,KAAK,CAAc,IAAI;6EAAC;;IAE/B,KAAK,GAAG,KAAK,CAAC,EAAE;8EAAC;;IAEjB,MAAM,GAAG,KAAK,CAAC,KAAK,8EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;uGALpD,OAAO,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAP,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,OAAO,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA1ER;;;;;;;;;AAST,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,2+BAAA,CAAA,EAAA,CAAA;;2FAiEU,OAAO,EAAA,UAAA,EAAA,CAAA;kBA5EnB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,YAAY,EAAA,QAAA,EACZ;;;;;;;;;AAST,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,2+BAAA,CAAA,EAAA;;;ACnBH;;;;;;;;;;;;;;;;;;AAkBG;MAiEU,YAAY,CAAA;IACd,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAoB;;IAE1C,IAAI,GAAG,KAAK,CAAmB,UAAU;6EAAC;;IAE1C,KAAK,GAAG,KAAK,CAAC,EAAE;8EAAC;IACjB,QAAQ,GAAG,KAAK,CAAC,EAAE;iFAAC;;IAEpB,YAAY,GAAG,KAAK,CAAC,WAAW;qFAAC;uGAR/B,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAZ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAY,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA7Db;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,ifAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EA7BS,UAAU,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,QAAQ,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,OAAO,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,QAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FA8D5B,YAAY,EAAA,UAAA,EAAA,CAAA;kBAhExB,SAAS;+BACE,kBAAkB,EAAA,OAAA,EACnB,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAA,QAAA,EAC9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,ifAAA,CAAA,EAAA;;;AClCH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCG;MAwYU,SAAS,CAAA;IACX,OAAO,GAAG,KAAK,CAAC,QAAQ;gFAAqB;IAC7C,IAAI,GAAG,KAAK,CAAC,QAAQ;6EAAO;;AAE5B,IAAA,MAAM,GAAG,KAAK;0FAA8C;;IAE5D,KAAK,GAAG,KAAK,CAAC,KAAK;8EAAC;;IAEpB,QAAQ,GAAG,KAAK,CAAC,KAAK;iFAAC;IACvB,WAAW,GAAG,KAAK,CAAgB,OAAO;oFAAC;AACpD;;;AAGG;AACM,IAAA,MAAM,GAAG,KAAK;0FAAsB;;AAEpC,IAAA,aAAa,GAAG,KAAK;iGAE3B;IAEM,QAAQ,GAAG,MAAM,EAA6B;IAEtC,YAAY,GAAG,MAAM,CAAuB,IAAI;qFAAC;;AAGzD,IAAA,IAAI,GAAG,QAAQ,CAAgB,MAAM,IAAI,CAAC,YAAY,EAAE,IAAI,IAAI,CAAC,WAAW,EAAE;6EAAC;;IAG/E,eAAe,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC;wFAAC;IACpF,eAAe,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC;wFAAC;IACpF,iBAAiB,GAAG,QAAQ,CAAC,MACpC,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC;0FACtD;IACQ,iBAAiB,GAAG,QAAQ,CAAC,MACpC,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC;0FACtD;AACQ,IAAA,gBAAgB,GAAG,QAAQ,CAAC,MACnC,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC;yFACpE;AAED;;;;AAIG;AACM,IAAA,eAAe,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC,MAAM,KAAK,CAAC;wFAAC;AAEhF,IAAA,OAAO,CAAC,IAAmB,EAAA;AACzB,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;IAC7B;IAEA,QAAQ,CAAC,GAAM,EAAE,KAAa,EAAA;AAC5B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE;AAC3B,QAAA,OAAO,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,KAAK;IAC1C;IAEA,SAAS,CAAC,GAAM,EAAE,MAAuB,EAAA;AACvC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE;QAC9B,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,QAAQ,CAAC,GAAG,CAAC;QACtB;QACA,MAAM,KAAK,GAAI,GAA+B,CAAC,MAAM,CAAC,GAAG,CAAC;AAC1D,QAAA,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC;IACnE;IAEA,UAAU,CAAC,GAAM,EAAE,KAAa,EAAA;QAC9B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IACpC;uGAnEW,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAT,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,SAAS,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EApYV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8KT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,yiIAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EA/KS,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,kBAAA,EAAA,0BAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAqYf,SAAS,EAAA,UAAA,EAAA,CAAA;kBAvYrB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,eAAe,EAAA,OAAA,EAChB,CAAC,gBAAgB,CAAC,EAAA,QAAA,EACjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8KT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,yiIAAA,CAAA,EAAA;;;ACjPH;;;;;;;;;AASG;MAoFU,WAAW,CAAA;AACb,IAAA,KAAK,GAAG,KAAK;yFAAU;AACvB,IAAA,SAAS,GAAG,KAAK;6FAAY;IAC7B,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAU;AAChC,IAAA,WAAW,GAAG,KAAK;+FAAU;AAC7B,IAAA,WAAW,GAAG,KAAK;+FAAU;AAC7B,IAAA,UAAU,GAAG,KAAK;8FAAU;uGAN1B,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAX,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAhFZ;;;;;;;;;;;;;;;;;;;AAmBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,4qCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EApBS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAiFH,WAAW,EAAA,UAAA,EAAA,CAAA;kBAnFvB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,iBAAiB,EAAA,OAAA,EAClB,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;;;;;;;;;;;AAmBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,4qCAAA,CAAA,EAAA;;;AChCH;;;;;;;;;;;;;;AAcG;MAsEU,KAAK,CAAA;AACP,IAAA,KAAK,GAAG,KAAK;yFAAU;AACvB,IAAA,KAAK,GAAG,KAAK;yFAAU;AACvB,IAAA,IAAI,GAAG,KAAK;wFAAY;AACxB,IAAA,WAAW,GAAG,KAAK;+FAAU;IAC7B,MAAM,GAAG,KAAK,CAAC,KAAK,8EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;;AAEtD,IAAA,KAAK,GAAG,KAAK;yFAAU;AAEhC;;;;;;AAMG;IACO,oBAAoB,GAAA;AAC5B,QAAA,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE;IAC9C;uGAlBW,KAAK,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAL,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAK,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,wBAAA,EAAA,UAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAlEN;;;;;;;;;;;;;;;;;;;;AAoBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,6uBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EArBS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAmEH,KAAK,EAAA,UAAA,EAAA,CAAA;kBArEjB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,UAAU,EAAA,OAAA,EACX,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;;;;;;;;;;;;GAoBT,EAAA,IAAA,EAyCK;AACJ,wBAAA,0BAA0B,EAAE,UAAU;AACtC,wBAAA,cAAc,EAAE,iBAAiB;AAClC,qBAAA,EAAA,MAAA,EAAA,CAAA,6uBAAA,CAAA,EAAA;;;AC7EH;;;;;;;;;;;;;;;;;;AAkBG;MAsDU,WAAW,CAAA;IACb,OAAO,GAAG,KAAK,CAAC,QAAQ;gFAAiD;IACzE,KAAK,GAAG,KAAK,CAAS,EAAE;8EAAC;IAEzB,WAAW,GAAG,MAAM,EAAU;;AAG9B,IAAA,iBAAiB,GAAG,QAAQ,CAAqB,MACxD,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,KACxB,OAAO,MAAM,KAAK,QAAQ,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CACvE;0FACF;AAED,IAAA,MAAM,CAAC,KAAa,EAAA;AAClB,QAAA,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE;YAC1B;QACF;AACA,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9B;uGAlBW,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAX,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAnDZ;;;;;;;;;;;;;;AAcT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,0rBAAA,CAAA,EAAA,CAAA;;2FAqCU,WAAW,EAAA,UAAA,EAAA,CAAA;kBArDvB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,iBAAiB,EAAA,QAAA,EACjB;;;;;;;;;;;;;;AAcT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,0rBAAA,CAAA,EAAA;;;AClCH;;;;;;;;;;;;;;AAcG;MA8GU,UAAU,CAAA;IACZ,OAAO,GAAG,KAAK,CAAC,QAAQ;gFAAqB;IAC7C,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAU;IAChC,WAAW,GAAG,MAAM,EAAU;AAEvC,IAAA,MAAM,CAAC,KAAa,EAAA;AAClB,QAAA,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE;YAC1B;QACF;AACA,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9B;;IAGA,SAAS,CAAC,KAAoB,EAAE,YAAoB,EAAA;AAClD,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE;AAC5B,QAAA,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,KAAK,YAAY,CAAC;AAE/E,QAAA,IAAI,SAAiB;AACrB,QAAA,QAAQ,KAAK,CAAC,GAAG;AACf,YAAA,KAAK,YAAY;gBACf,SAAS,GAAG,CAAC,YAAY,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM;gBAC7C;AACF,YAAA,KAAK,WAAW;AACd,gBAAA,SAAS,GAAG,CAAC,YAAY,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM;gBAC5D;AACF,YAAA,KAAK,MAAM;gBACT,SAAS,GAAG,CAAC;gBACb;AACF,YAAA,KAAK,KAAK;AACR,gBAAA,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC;gBAC5B;AACF,YAAA;gBACE;;QAGJ,KAAK,CAAC,cAAc,EAAE;AACtB,QAAA,MAAM,UAAU,GAAG,KAAK,CAAC,SAAS,CAAC;AACnC,QAAA,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;AAE7B,QAAA,MAAM,IAAI,GAAI,KAAK,CAAC,aAA6B,CAAC,aAAa;AAC/D,QAAA,MAAM,MAAM,GAAG,CAAA,cAAA,EAAiB,UAAU,CAAC,KAAK,EAAE;AAClD,QAAA,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAoB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAC3F,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,KAAK,MAAM,CACjC;QACD,UAAU,EAAE,KAAK,EAAE;IACrB;uGA7CW,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA1GX;;;;;;;;;;;;;;;;;;;;;;AAsBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,2nDAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAvBS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FA2GH,UAAU,EAAA,UAAA,EAAA,CAAA;kBA7GtB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,OAAA,EACjB,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;;;;;;;;;;;;;;AAsBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,2nDAAA,CAAA,EAAA;;;AClCH;;;;;;;;;;;;;;AAcG;MA2GU,KAAK,CAAA;AACR,IAAA,OAAO,MAAM,GAAG,CAAC;AAER,IAAA,WAAW,GAAG,SAAS,CAAC,QAAQ,CAA+B,aAAa;oFAAC;AAErF,IAAA,KAAK,GAAG,KAAK;yFAAU;;AAEvB,IAAA,IAAI,GAAG,KAAK;wFAAU;AACtB,IAAA,MAAM,GAAG,KAAK;0FAAU;AACxB,IAAA,IAAI,GAAG,KAAK;wFAAU;IACtB,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;IACxD,IAAI,GAAG,KAAK,CAAS,MAAM;6EAAC;IAC5B,WAAW,GAAG,KAAK,CAAS,EAAE;oFAAC;AAErB,IAAA,OAAO,GAAG,CAAA,SAAA,EAAY,KAAK,CAAC,MAAM,EAAE,EAAE;AACtC,IAAA,MAAM,GAAG,CAAA,EAAG,IAAI,CAAC,OAAO,OAAO;IAE/B,KAAK,GAAG,MAAM,CAAC,EAAE;8EAAC;IAClB,OAAO,GAAG,MAAM,CAAC,KAAK;gFAAC;;IAEzB,cAAc,GAAG,MAAM,CAAC,KAAK;uFAAC;;AAE5B,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,cAAc,EAAE;mFAAC;AAEhF,IAAA,QAAQ,GAA4B,MAAK,EAAE,CAAC;AAC5C,IAAA,SAAS,GAAe,MAAK,EAAE,CAAC;IAExC,eAAe,GAAA;;;;;;AAMb,QAAA,IAAI,CAAC,WAAW,EAAE,CAAC,aAAa,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;IACvD;AAEA,IAAA,UAAU,CAAC,KAAa,EAAA;AACtB,QAAA,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;AAC7B,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;;;;;AAKzB,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,IAAI;QAC/B,IAAI,EAAE,EAAE;AACN,YAAA,EAAE,CAAC,aAAa,CAAC,KAAK,GAAG,SAAS;QACpC;IACF;AAEA,IAAA,gBAAgB,CAAC,EAA2B,EAAA;AAC1C,QAAA,IAAI,CAAC,QAAQ,GAAG,EAAE;IACpB;AAEA,IAAA,iBAAiB,CAAC,EAAc,EAAA;AAC9B,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;IACrB;AAEA,IAAA,gBAAgB,CAAC,UAAmB,EAAA;AAClC,QAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC;IACrC;AAEU,IAAA,OAAO,CAAC,QAAgB,EAAA;AAChC,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;AACxB,QAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACzB;IAEU,MAAM,GAAA;AACd,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;QACvB,IAAI,CAAC,SAAS,EAAE;IAClB;uGArEW,KAAK,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAL,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAK,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,SAAA,EAtGL;AACT,YAAA;AACE,gBAAA,OAAO,EAAE,iBAAiB;AAC1B,gBAAA,WAAW,EAAE,UAAU,CAAC,MAAM,KAAK,CAAC;AACpC,gBAAA,KAAK,EAAE,IAAI;AACZ,aAAA;SACF,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,aAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,aAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EACS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCT,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,w+BAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EA1CS,WAAW,+BAAE,UAAU,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,KAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAuGtB,KAAK,EAAA,UAAA,EAAA,CAAA;kBA1GjB,SAAS;+BACE,UAAU,EAAA,eAAA,EACH,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC,CAAC,WAAW,EAAE,UAAU,CAAC,EAAA,SAAA,EACvB;AACT,wBAAA;AACE,4BAAA,OAAO,EAAE,iBAAiB;AAC1B,4BAAA,WAAW,EAAE,UAAU,CAAC,WAAW,CAAC;AACpC,4BAAA,KAAK,EAAE,IAAI;AACZ,yBAAA;qBACF,EAAA,QAAA,EACS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,w+BAAA,CAAA,EAAA;yEAgE+E,aAAa,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,KAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,OAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,IAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,QAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,IAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,QAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,IAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;ACvI/F;;;;;;;;;;;;AAYG;MA0FU,UAAU,CAAA;IACZ,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAU;IAChC,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAmB;AACzC,IAAA,IAAI,GAAG,KAAK;wFAAU;;AAEtB,IAAA,IAAI,GAAG,KAAK;wFAAY;AACxB,IAAA,IAAI,GAAG,KAAK;wFAAU;;AAEtB,IAAA,UAAU,GAAG,KAAK;8FAAU;;AAE5B,IAAA,KAAK,GAAG,KAAK;yFAAU;uGAVrB,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAtFX;;;;;;;;;;;;;;;;;;;;;;;;;GAyBT,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,6kCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EA1BS,IAAI,uEAAE,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAuFT,UAAU,EAAA,UAAA,EAAA,CAAA;kBAzFtB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,WACjB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAA,QAAA,EACX;;;;;;;;;;;;;;;;;;;;;;;;;AAyBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,6kCAAA,CAAA,EAAA;;;AC/BH,IAAI,OAAO,GAAG,CAAC;AAEf;;;;;;;;;;;;;;;;;;;;;;AAsBG;MA+GU,KAAK,CAAA;IACP,KAAK,GAAG,KAAK,CAAC,EAAE;8EAAC;;IAEjB,IAAI,GAAG,KAAK,CAAC,KAAK;6EAAC;;IAEnB,WAAW,GAAG,KAAK,CAAC,IAAI,mFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;AAEhD,IAAA,OAAO,GAAG,CAAA,eAAA,EAAkB,OAAO,EAAE,EAAE;IAEzC,MAAM,GAAG,SAAS,CAAgC,QAAQ;+EAAC;AAC3D,IAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;AAE5C,IAAA,WAAA,GAAA;QACE,iBAAiB,CAAC,MAAK;YACrB,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa;YACvC,IAAI,CAAC,EAAE,EAAE;gBACP;YACF;YACA,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE;;;AAG3B,gBAAA,IAAI,OAAO,EAAE,CAAC,SAAS,KAAK,UAAU,EAAE;oBACtC,EAAE,CAAC,SAAS,EAAE;gBAChB;qBAAO;AACL,oBAAA,EAAE,CAAC,IAAI,GAAG,IAAI;gBAChB;YACF;iBAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE;AAClC,gBAAA,IAAI,OAAO,EAAE,CAAC,KAAK,KAAK,UAAU,EAAE;oBAClC,EAAE,CAAC,KAAK,EAAE;gBACZ;qBAAO;AACL,oBAAA,EAAE,CAAC,IAAI,GAAG,KAAK;gBACjB;YACF;;YAEA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,QAAQ,GAAG,EAAE;AACjE,QAAA,CAAC,CAAC;AAEF,QAAA,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,MAAK;YAChC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE;AACxC,QAAA,CAAC,CAAC;IACJ;;AAGU,IAAA,QAAQ,CAAC,KAAY,EAAA;AAC7B,QAAA,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE;YACvB,KAAK,CAAC,cAAc,EAAE;QACxB;IACF;AAEA;;;;;;;;AAQG;AAEO,IAAA,WAAW,CAAC,KAAiB,EAAA;AACrC,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE;AACvE,YAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;QACtB;IACF;uGA/DW,KAAK,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAL,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAK,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,IAAA,EAAA,YAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,qBAAA,EAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,QAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,QAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA5GN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,8uCAAA,CAAA,EAAA,CAAA;;2FA4EU,KAAK,EAAA,UAAA,EAAA,CAAA;kBA9GjB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,UAAU,EAAA,QAAA,EACV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,8uCAAA,CAAA,EAAA;iaAqFkE,QAAQ,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA;sBAiD1E,YAAY;uBAAC,OAAO,EAAE,CAAC,QAAQ,CAAC;;;AC7LnC,IAAIA,QAAM,GAAG,CAAC;AAEd;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;MAuPU,WAAW,CAAA;AACb,IAAA,KAAK,GAAG,KAAK;yFAAU;IACvB,OAAO,GAAG,KAAK,CAAsB,EAAE;gFAAC;IACxC,MAAM,GAAG,KAAK,CAAW,EAAE;+EAAC;IAC5B,WAAW,GAAG,KAAK,CAAS,aAAa;oFAAC;IAC1C,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;IAExD,YAAY,GAAG,MAAM,EAAY;AAEzB,IAAA,UAAU,GAAG,CAAA,gBAAA,EAAmBA,QAAM,EAAE,EAAE;AAClD,IAAA,SAAS,GAAG,CAAA,EAAG,IAAI,CAAC,UAAU,UAAU;AACxC,IAAA,SAAS,GAAG,CAAA,EAAG,IAAI,CAAC,UAAU,UAAU;IAExC,MAAM,GAAG,MAAM,CAAC,KAAK;+EAAC;IAEtB,aAAa,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM;sFAAC;IAEpD,WAAW,GAAG,QAAQ,CAC7B,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM;oFAClF;AAEQ,IAAA,mBAAmB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;4FAAC;AAE9F;;;;;AAKG;AACM,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;AACnC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE;AAClC,QAAA,IAAI,KAAK,KAAK,CAAC,EAAE;AACf,YAAA,OAAO,IAAI,CAAC,WAAW,EAAE;QAC3B;AACA,QAAA,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM;aAC/B,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,KAAK;aAC7E,MAAM,CAAC,CAAC,KAAK,KAAsB,OAAO,CAAC,KAAK,CAAC,CAAC;AACrD,QAAA,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;IAClC,CAAC;oFAAC;AAEe,IAAA,IAAI,GAAG,MAAM,EAAC,UAAuB,EAAC;AAEvD,IAAA,UAAU,CAAC,KAAa,EAAA;QACtB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;IACtC;IAEA,MAAM,GAAA;AACJ,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE;YACnB;QACF;AACA,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC;IACrC;AAEA,IAAA,YAAY,CAAC,KAAa,EAAA;AACxB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE;AAC7B,QAAA,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK;AACjC,cAAE,OAAO,CAAC,MAAM,CAAC,CAAC,aAAa,KAAK,aAAa,KAAK,KAAK;AAC3D,cAAE,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC;AACvB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;IAC9B;;IAGA,SAAS,GAAA;AACP,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC;IAChG;AAGA,IAAA,eAAe,CAAC,KAAiB,EAAA;AAC/B,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAc,CAAC,EAAE;AAC5E,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;QACxB;IACF;IAGA,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;IACxB;uGA5EW,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAX,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,YAAA,EAAA,cAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,gBAAA,EAAA,yBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAnPZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8ET,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,2sGAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EA/ES,UAAU,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,KAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAoPT,WAAW,EAAA,UAAA,EAAA,CAAA;kBAtPvB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,iBAAiB,EAAA,OAAA,EAClB,CAAC,UAAU,CAAC,EAAA,QAAA,EACX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8ET,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,2sGAAA,CAAA,EAAA;;sBAuOA,YAAY;uBAAC,gBAAgB,EAAE,CAAC,QAAQ,CAAC;;sBAOzC,YAAY;uBAAC,yBAAyB;;;ACzWzC;;;;;;;;;;;AAWG;MAsEU,UAAU,CAAA;IACZ,IAAI,GAAG,KAAK,CAAuB,SAAS;6EAAC;IAC7C,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAU;IAChC,QAAQ,GAAG,KAAK,CAAqB,SAAS;iFAAC;uGAH7C,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAlEX;;;;;;;;;;;;;;;;;AAiBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,wuBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAlBS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAmEH,UAAU,EAAA,UAAA,EAAA,CAAA;kBArEtB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,OAAA,EACjB,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;;;;;;;;;AAiBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,wuBAAA,CAAA,EAAA;;;AC9BH,MAAM,QAAQ,GAAG,CAAC;AAElB;;;;;;;;;;;;;;;AAeG;MA0HU,UAAU,CAAA;IACZ,IAAI,GAAG,KAAK,CAAC,CAAC;6EAAC;IACf,KAAK,GAAG,KAAK,CAAC,CAAC;8EAAC;IAChB,UAAU,GAAG,MAAM,EAAU;;AAG7B,IAAA,KAAK,GAAG,QAAQ,CAAmB,MAC1C,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;8EAChD;AAED,IAAA,IAAI,CAAC,MAAc,EAAA;QACjB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;AAC3D,QAAA,IAAI,OAAO,KAAK,IAAI,CAAC,IAAI,EAAE,EAAE;YAC3B;QACF;AACA,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC;IAC/B;uGAhBW,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,UAAA,EAAA,YAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAvHX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,q4CAAA,CAAA,EAAA,CAAA;;2FA2EU,UAAU,EAAA,UAAA,EAAA,CAAA;kBAzHtB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,eAAe,EAAA,QAAA,EACf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,q4CAAA,CAAA,EAAA;;AA8FH;;;;AAIG;AACH,SAAS,oBAAoB,CAAC,OAAe,EAAE,KAAa,EAAA;IAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;AACrC,IAAA,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC;AAE9D,IAAA,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,CAAC,CAAC,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AAC7D,IAAA,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,QAAQ,EAAE,MAAM,EAAE,EAAE;AACjD,QAAA,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,MAAM,CAAC;AACjC,QAAA,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,MAAM,CAAC;IACnC;AAEA,IAAA,MAAM,WAAW,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAE/F,MAAM,KAAK,GAAqB,EAAE;AAClC,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAC3C,QAAA,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC;AACjC,QAAA,IAAI,CAAC,GAAG,CAAC,EAAE;YACT,MAAM,GAAG,GAAG,UAAU,GAAG,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC;AAC3C,YAAA,IAAI,GAAG,KAAK,CAAC,EAAE;;AAEb,gBAAA,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,CAAC,EAAE,CAAC;YACpD;AAAO,iBAAA,IAAI,GAAG,GAAG,CAAC,EAAE;gBAClB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;YAClC;QACF;AACA,QAAA,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAChD;AAEA,IAAA,OAAO,KAAK;AACd;;AChMA;;;;;;;;;AASG;MAyDU,KAAK,CAAA;IACP,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAU;AAChC,IAAA,WAAW,GAAG,KAAK;+FAAU;AAC7B,IAAA,UAAU,GAAG,KAAK;8FAAU;uGAH1B,KAAK,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAL,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAK,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EArDN;;;;;;;;;;;;;;;GAeT,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,yiBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAhBS,IAAI,uEAAE,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAsDT,KAAK,EAAA,UAAA,EAAA,CAAA;kBAxDjB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,UAAU,WACX,CAAC,IAAI,EAAE,IAAI,CAAC,EAAA,QAAA,EACX;;;;;;;;;;;;;;;AAeT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,yiBAAA,CAAA,EAAA;;;ACfH;;;;;;;;;;;;;;;AAeG;MA4GU,YAAY,CAAA;IACd,KAAK,GAAG,KAAK,CAAC,WAAW;8EAAC;IAC1B,OAAO,GAAG,KAAK,CAAC,KAAK,+EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;IACvD,YAAY,GAAG,KAAK,CAA4B,EAAE;qFAAC;IACnD,QAAQ,GAAG,KAAK,CAAwB,EAAE;iFAAC;IAC3C,YAAY,GAAG,KAAK,CAAC,QAAQ;qFAAU;IAEvC,YAAY,GAAG,MAAM,EAAQ;uGAP3B,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAZ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAY,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,YAAA,EAAA,cAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAxGb;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BT,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,65CAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EA7BS,UAAU,+EAAE,MAAM,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,KAAA,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAyGjB,YAAY,EAAA,UAAA,EAAA,CAAA;kBA3GxB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,kBAAkB,WACnB,CAAC,UAAU,EAAE,MAAM,CAAC,EAAA,QAAA,EACnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,65CAAA,CAAA,EAAA;;;AC7DH;;;;;;;;;;;;;;;;;AAiBG;MAwGU,YAAY,CAAA;IACd,UAAU,GAAG,KAAK,CAAC,8BAA8B;mFAAC;IAClD,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAU;AAChC,IAAA,WAAW,GAAG,KAAK;+FAAU;AAC7B,IAAA,WAAW,GAAG,KAAK;+FAAU;AAC7B,IAAA,UAAU,GAAG,KAAK;8FAAU;uGAL1B,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAZ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAY,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EApGb;;;;;;;;;;;;;;;;;;;;;;;;;AAyBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,68CAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EA1BS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAqGH,YAAY,EAAA,UAAA,EAAA,CAAA;kBAvGxB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,kBAAkB,EAAA,OAAA,EACnB,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;;;;;;;;;;;;;;;;;AAyBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,68CAAA,CAAA,EAAA;;;AC9CH;;;;;;;;;;;;;;;;;;AAkBG;MAuFU,aAAa,CAAA;AACf,IAAA,IAAI,GAAG,KAAK;wFAAY;IACxB,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAU;AAChC,IAAA,QAAQ,GAAG,KAAK;4FAAU;AAC1B,IAAA,IAAI,GAAG,KAAK;wFAAQ;IACpB,KAAK,GAAG,KAAK,CAAC,KAAK,6EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;uGALnD,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,6BAAA,EAAA,iBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAnFd;;;;;;;;;;;;;;;;;AAiBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,ipCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAlBS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAoFH,aAAa,EAAA,UAAA,EAAA,CAAA;kBAtFzB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mBAAmB,EAAA,OAAA,EACpB,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;;;;;;;;;GAiBT,EAAA,IAAA,EA8DK;AACJ,wBAAA,+BAA+B,EAAE,iBAAiB;AACnD,qBAAA,EAAA,MAAA,EAAA,CAAA,ipCAAA,CAAA,EAAA;;;ACnGH;;;;;;;;;AASG;MAyEU,SAAS,CAAA;IACX,OAAO,GAAG,KAAK,CAAC,QAAQ;gFAAqB;IAC7C,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAU;IAChC,WAAW,GAAG,MAAM,EAAU;;IAG9B,aAAa,GAAG,QAAQ,CAAC,MAChC,IAAI,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;sFACpE;AAED,IAAA,MAAM,CAAC,SAAiB,EAAA;AACtB,QAAA,IAAI,SAAS,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE;YAC9B;QACF;AACA,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC;IAClC;uGAfW,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAT,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,SAAS,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAtEV;;;;;;;;;;;;;;;;;;;AAmBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,ijCAAA,CAAA,EAAA,CAAA;;2FAmDU,SAAS,EAAA,UAAA,EAAA,CAAA;kBAxErB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,cAAc,EAAA,QAAA,EACd;;;;;;;;;;;;;;;;;;;AAmBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,ijCAAA,CAAA,EAAA;;;ACpBH,IAAI,MAAM,GAAG,CAAC;AAEd;;;;;;;;;;;;;;;;;;;AAmBG;MA2JU,UAAU,CAAA;AACZ,IAAA,KAAK,GAAG,KAAK;yFAAU;IACvB,OAAO,GAAG,KAAK,CAAqB,EAAE;gFAAC;AACvC,IAAA,KAAK,GAAG,KAAK;yFAAU;IACvB,WAAW,GAAG,KAAK,CAAS,aAAa;oFAAC;IAC1C,QAAQ,GAAG,KAAK,CAAC,KAAK,gFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;IAExD,WAAW,GAAG,MAAM,EAAU;AAEtB,IAAA,UAAU,GAAG,CAAA,eAAA,EAAkB,MAAM,EAAE,EAAE;AACjD,IAAA,SAAS,GAAG,CAAA,EAAG,IAAI,CAAC,UAAU,UAAU;AACxC,IAAA,SAAS,GAAG,CAAA,EAAG,IAAI,CAAC,UAAU,UAAU;IAExC,MAAM,GAAG,MAAM,CAAC,KAAK;+EAAC;IAEtB,cAAc,GAAG,QAAQ,CAAC,MACjC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;uFAC/D;AAEgB,IAAA,IAAI,GAAG,MAAM,EAAC,UAAuB,EAAC;IAEvD,MAAM,GAAA;AACJ,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE;YACnB;QACF;AACA,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC;IACrC;AAEA,IAAA,MAAM,CAAC,MAAwB,EAAA;AAC7B,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;QACtB,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE;YACjC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QACrC;IACF;AAGA,IAAA,eAAe,CAAC,KAAiB,EAAA;AAC/B,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAc,CAAC,EAAE;AAC5E,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;QACxB;IACF;IAGA,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;IACxB;uGA7CW,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,gBAAA,EAAA,yBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAvJX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,48DAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EArDS,UAAU,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,KAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAwJT,UAAU,EAAA,UAAA,EAAA,CAAA;kBA1JtB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,OAAA,EACjB,CAAC,UAAU,CAAC,EAAA,QAAA,EACX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,48DAAA,CAAA,EAAA;;sBAsIA,YAAY;uBAAC,gBAAgB,EAAE,CAAC,QAAQ,CAAC;;sBAOzC,YAAY;uBAAC,yBAAyB;;;ACzOzC;;;;;;;;;;;;;;AAcG;MAyFU,QAAQ,CAAA;IACV,GAAG,GAAG,KAAK,CAAC,KAAK,2EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;;AAEnD,IAAA,KAAK,GAAG,KAAK;yFAAU;AACvB,IAAA,KAAK,GAAG,KAAK;yFAAmB;AAChC,IAAA,IAAI,GAAG,KAAK;wFAAY;;AAExB,IAAA,KAAK,GAAG,KAAK;yFAAU;AACvB,IAAA,WAAW,GAAG,KAAK;+FAAU;AAC7B,IAAA,WAAW,GAAG,KAAK;+FAAU;AAC7B,IAAA,UAAU,GAAG,KAAK;8FAAU;uGAV1B,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAR,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,QAAQ,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,yBAAA,EAAA,OAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EArFT;;;;;;;;;;;;;;;;;;;;;;;AAuBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,siCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAxBS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAsFH,QAAQ,EAAA,UAAA,EAAA,CAAA;kBAxFpB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,cAAc,EAAA,OAAA,EACf,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;;;;;;;;;;;;;;;GAuBT,EAAA,IAAA,EA0DK;AACJ,wBAAA,2BAA2B,EAAE,OAAO;AACrC,qBAAA,EAAA,MAAA,EAAA,CAAA,siCAAA,CAAA,EAAA;;;ACtGH;;;;;;;AAOG;MAoDU,UAAU,CAAA;IACZ,IAAI,GAAG,KAAK,CAAmC,MAAM;6EAAC;IACtD,GAAG,GAAG,KAAK,CAAC,KAAK,2EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;uGAFjD,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAjDX;;;;;;;AAOT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,+qBAAA,CAAA,EAAA,CAAA;;2FA0CU,UAAU,EAAA,UAAA,EAAA,CAAA;kBAnDtB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,QAAA,EAChB;;;;;;;AAOT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,+qBAAA,CAAA,EAAA;;;ACEH;;;;;;;;AAQG;MAgGU,IAAI,CAAA;IACN,OAAO,GAAG,KAAK,CAAC,QAAQ;gFAAe;IACvC,KAAK,GAAG,KAAK,CAAC,QAAQ;8EAAU;IAChC,WAAW,GAAG,MAAM,EAAU;AAEtB,IAAA,KAAK,GAAG,SAAS,CAAC,QAAQ,CAA0B,OAAO;8EAAC;AAC5D,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;;IAG/B,UAAU,GAAG,MAAM,CAAsC,IAAI;mFAAC;AAE5D,IAAA,kBAAkB,GAAG,QAAQ,CAC9C,MAAM,CAAA,WAAA,EAAc,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,CAAA,GAAA,CAAK;2FACnD;AACkB,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,IAAI,CAAC;uFAAC;AAEjF,IAAA,WAAA,GAAA;;QAEE,iBAAiB,CAAC,MAAK;YACrB,IAAI,CAAC,KAAK,EAAE;YACZ,IAAI,CAAC,OAAO,EAAE;YACd,IAAI,CAAC,OAAO,EAAE;AAChB,QAAA,CAAC,CAAC;QAEF,eAAe,CAAC,MAAK;;;AAGnB,YAAA,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACzD,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,aAAa,CAAC;AAC5C,YAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC;AACxD,QAAA,CAAC,CAAC;IACJ;IAEQ,OAAO,GAAA;AACb,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,aAAa,CAAC,aAAa,CAAc,uBAAuB,CAAC;QAC7F,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC;IAC1F;AAEA,IAAA,MAAM,CAAC,KAAa,EAAA;AAClB,QAAA,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE;YAC1B;QACF;AACA,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9B;;IAGA,SAAS,CAAC,KAAoB,EAAE,YAAoB,EAAA;AAClD,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE;AAC5B,QAAA,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,KAAK,YAAY,CAAC;AAE/E,QAAA,IAAI,SAAiB;AACrB,QAAA,QAAQ,KAAK,CAAC,GAAG;AACf,YAAA,KAAK,YAAY;gBACf,SAAS,GAAG,CAAC,YAAY,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM;gBAC7C;AACF,YAAA,KAAK,WAAW;AACd,gBAAA,SAAS,GAAG,CAAC,YAAY,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM;gBAC5D;AACF,YAAA,KAAK,MAAM;gBACT,SAAS,GAAG,CAAC;gBACb;AACF,YAAA,KAAK,KAAK;AACR,gBAAA,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC;gBAC5B;AACF,YAAA;gBACE;;QAGJ,KAAK,CAAC,cAAc,EAAE;AACtB,QAAA,MAAM,UAAU,GAAG,KAAK,CAAC,SAAS,CAAC;AACnC,QAAA,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;AAE7B,QAAA,MAAM,IAAI,GAAI,KAAK,CAAC,aAA6B,CAAC,aAAa;AAC/D,QAAA,MAAM,MAAM,GAAG,CAAA,OAAA,EAAU,UAAU,CAAC,KAAK,EAAE;AAC3C,QAAA,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAoB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAC3F,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,KAAK,MAAM,CACjC;QACD,UAAU,EAAE,KAAK,EAAE;IACrB;uGA9EW,IAAI,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAJ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,IAAI,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,OAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,OAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA5FL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,igCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EA9BS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FA6FH,IAAI,EAAA,UAAA,EAAA,CAAA;kBA/FhB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,SAAS,EAAA,OAAA,EACV,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,igCAAA,CAAA,EAAA;8UAoEoE,OAAO,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AC/G9E;AACA,MAAM,UAAU,GAAgC;AAC9C,IAAA,OAAO,EAAE,cAAc;AACvB,IAAA,KAAK,EAAE,cAAc;AACrB,IAAA,OAAO,EAAE,gBAAgB;AACzB,IAAA,IAAI,EAAE,MAAM;AACZ,IAAA,OAAO,EAAE,MAAM;CAChB;AA0BD,MAAM,mBAAmB,GAAG,IAAI;AAChC,MAAM,iBAAiB,GAAG,GAAG;AAE7B;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;MAEU,YAAY,CAAA;IACN,QAAQ,GAAG,MAAM,CAAoB,IAAI;iFAAC;IACnD,MAAM,GAAG,CAAC;AACV,IAAA,YAAY;AACZ,IAAA,WAAW;;AAGV,IAAA,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE;;AAG7C,IAAA,IAAI,CAAC,OAAe,EAAE,OAAA,GAAwB,EAAE,EAAA;AAC9C,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE;AACxB,QAAA,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM;AACnC,QAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,mBAAmB;AACxD,QAAA,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,QAAA,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC;AAC9B,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAClE,QAAA,IAAI,IAAI,KAAK,SAAS,EAAE;AACtB,YAAA,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC;QAClE;AACA,QAAA,OAAO,EAAE;IACX;AAEA;;;AAGG;AACH,IAAA,OAAO,CAAC,EAAW,EAAA;AACjB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC7B,QAAA,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE,KAAK,SAAS,IAAI,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;YAAE;AACtE,QAAA,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC9C,QAAA,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,MAAK;YACjC,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,KAAK,CAAC,EAAE;AAAE,gBAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;QAC/D,CAAC,EAAE,iBAAiB,CAAC;IACvB;AAEA;;;;AAIG;AACH,IAAA,OAAO,CAAI,IAAgB,EAAE,QAAA,GAAoC,EAAE,EAAA;AACjE,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,aAAa,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AACjE,QAAA,OAAO,IAAI,CAAC,IAAI,CACd,CAAC,KAAK,KAAI;AACR,YAAA,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,IAAI,OAAO;YACvC,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC5E,YAAA,OAAO,KAAK;AACd,QAAA,CAAC,EACD,CAAC,KAAK,KAAI;AACR,YAAA,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,IAAI,kBAAkB;YAChD,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC1E,YAAA,MAAM,KAAK;AACb,QAAA,CAAC,CACF;IACH;uGAxDW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAZ,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,YAAY,cADC,MAAM,EAAA,CAAA;;2FACnB,YAAY,EAAA,UAAA,EAAA,CAAA;kBADxB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;AA4DlC;;;;;;AAMG;MA+JU,SAAS,CAAA;AACH,IAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;;AAGjC,IAAA,SAAS,GAAG,QAAQ,CAAe,MAAK;QACzD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE;QACzC,OAAO,KAAK,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE;IAC7B,CAAC;kFAAC;AAEQ,IAAA,SAAS,CAAC,IAAe,EAAA;AACjC,QAAA,OAAO,UAAU,CAAC,IAAI,CAAC;IACzB;AAEU,IAAA,OAAO,CAAC,EAAU,EAAA;AAC1B,QAAA,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;IAC/B;uGAfW,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAT,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,SAAS,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA1JV;;;;;;;;;;;;;;;;AAgBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,yjEAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAjBS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FA2JH,SAAS,EAAA,UAAA,EAAA,CAAA;kBA9JrB,SAAS;+BACE,eAAe,EAAA,eAAA,EACR,uBAAuB,CAAC,MAAM,WACtC,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;;;;;;;;AAgBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,yjEAAA,CAAA,EAAA;;;AC5JH;;;;;;;;;;;;;;AAcG;MAuGU,aAAa,CAAA;IACf,IAAI,GAAG,KAAK,CAAC,QAAQ;6EAAU;AAC/B,IAAA,KAAK,GAAG,KAAK;yFAAU;AACvB,IAAA,GAAG,GAAG,KAAK;uFAAU;AACrB,IAAA,MAAM,GAAG,KAAK;0FAAuB;uGAJnC,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAnGd;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,27CAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EA3BS,IAAI,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAoGH,aAAa,EAAA,UAAA,EAAA,CAAA;kBAtGzB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mBAAmB,EAAA,OAAA,EACpB,CAAC,IAAI,CAAC,EAAA,QAAA,EACL;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,27CAAA,CAAA,EAAA;;;ACtDH;;;;;;;;;;;;AAYG;MA0EU,UAAU,CAAA;IACZ,IAAI,GAAG,KAAK,CAAC,QAAQ;6EAAoB;IACzC,UAAU,GAAG,MAAM,EAAoB;AAEhD,IAAA,MAAM,CAAC,IAAsB,EAAA;AAC3B,QAAA,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,EAAE;YACxB;QACF;AACA,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;IAC5B;;AAGA,IAAA,SAAS,CAAC,KAAoB,EAAA;AAC5B,QAAA,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,YAAY,EAAE;YAC3D;QACF;QAEA,KAAK,CAAC,cAAc,EAAE;AACtB,QAAA,MAAM,IAAI,GAAqB,IAAI,CAAC,IAAI,EAAE,KAAK,OAAO,GAAG,OAAO,GAAG,OAAO;AAC1E,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;AAEjB,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,aAA4B;QAClD,MAAM,OAAO,GACX,OAAO,CAAC,aAAa,EAAE,gBAAgB,CAAoB,yBAAyB,CAAC;QACvF,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,KAAK,OAAO,CAAC;QACjF,UAAU,EAAE,KAAK,EAAE;IACrB;uGA1BW,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,UAAA,EAAA,YAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAvEX;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,k0BAAA,CAAA,EAAA,CAAA;;2FA4CU,UAAU,EAAA,UAAA,EAAA,CAAA;kBAzEtB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,QAAA,EAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,k0BAAA,CAAA,EAAA;;;AC9CH;;AAEG;;ACFH;;AAEG;;;;"}
1
+ {"version":3,"file":"kaufmann-lab-ui.mjs","sources":["../../../projects/ui/src/lib/icon/icon-sprite.ts","../../../projects/ui/src/lib/icon/Icon.ts","../../../projects/ui/src/lib/action-tile/ActionTile.ts","../../../projects/ui/src/lib/admin-badge/AdminBadge.ts","../../../projects/ui/src/lib/button/button.ts","../../../projects/ui/src/lib/alert/Alert.ts","../../../projects/ui/src/lib/avatar/Avatar.ts","../../../projects/ui/src/lib/badge/Badge.ts","../../../projects/ui/src/lib/breadcrumb/Breadcrumb.ts","../../../projects/ui/src/lib/card/Card.ts","../../../projects/ui/src/lib/carousel/Carousel.ts","../../../projects/ui/src/lib/checkbox/Checkbox.ts","../../../projects/ui/src/lib/chip/Chip.ts","../../../projects/ui/src/lib/field-label/FieldLabel.ts","../../../projects/ui/src/lib/select/Select.ts","../../../projects/ui/src/lib/company-selector/CompanySelector.ts","../../../projects/ui/src/lib/content-slot/ContentSlot.ts","../../../projects/ui/src/lib/empty-state/EmptyState.ts","../../../projects/ui/src/lib/skeleton/Skeleton.ts","../../../projects/ui/src/lib/spinner/Spinner.ts","../../../projects/ui/src/lib/content-state/ContentState.ts","../../../projects/ui/src/lib/data-table/DataTable.ts","../../../projects/ui/src/lib/feature-card/FeatureCard.ts","../../../projects/ui/src/lib/field/Field.ts","../../../projects/ui/src/lib/filter-chips/FilterChips.ts","../../../projects/ui/src/lib/folder-tabs/FolderTabs.ts","../../../projects/ui/src/lib/input/Input.ts","../../../projects/ui/src/lib/metric-card/MetricCard.ts","../../../projects/ui/src/lib/modal/Modal.ts","../../../projects/ui/src/lib/multi-select/MultiSelect.ts","../../../projects/ui/src/lib/page-header/PageHeader.ts","../../../projects/ui/src/lib/pagination/Pagination.ts","../../../projects/ui/src/lib/panel/Panel.ts","../../../projects/ui/src/lib/portal-header/PortalHeader.ts","../../../projects/ui/src/lib/reserve-block/ReserveBlock.ts","../../../projects/ui/src/lib/section-header/SectionHeader.ts","../../../projects/ui/src/lib/segmented/Segmented.ts","../../../projects/ui/src/lib/select-menu/SelectMenu.ts","../../../projects/ui/src/lib/stat-tile/StatTile.ts","../../../projects/ui/src/lib/status-pill/StatusPill.ts","../../../projects/ui/src/lib/tabs/Tabs.ts","../../../projects/ui/src/lib/toast/Toast.ts","../../../projects/ui/src/lib/vehicle-header/VehicleHeader.ts","../../../projects/ui/src/lib/view-toggle/ViewToggle.ts","../../../projects/ui/src/public-api.ts","../../../projects/ui/src/kaufmann-lab-ui.ts"],"sourcesContent":["/**\n * Sprite SVG con los 59 íconos de trazo del design system (página 5:\n * \"Set de 59 iconos de trazo (1.9px, grilla 24×24)\"). Cada ícono es un\n * `<symbol>` con su nombre real de la spec como id (`kf-icon-check`,\n * `kf-icon-alert-triangle`, etc.) — `Icon` lo referencia con `<use>`.\n *\n * Los paths vienen de Lucide (https://lucide.dev, licencia ISC), la\n * librería de iconos de trazo cuyo set de nombres coincide exactamente con\n * el que pide el design system (chevron-right, alert-triangle, bar-chart…).\n * Se embeben acá en vez de agregar `lucide` como dependencia del paquete\n * para no sumar peso/versión externa a algo que consumen todos los\n * frontends del ecosistema — son 59 <path>/<circle>/<rect> estáticos, no\n * lógica que necesite actualizarse seguido.\n *\n * Mapeo de 4 nombres de la spec que no existen tal cual en Lucide (renombres\n * entre versiones de esa librería, o conceptos vecinos):\n * tool -> wrench\n * sort -> arrow-up-down (control de orden bidireccional simple)\n * cart -> shopping-cart\n * chevron-left-bar -> panel-left (icono de \"colapsar panel lateral\")\n *\n * Se inyecta UNA sola vez en el DOM (ver `Icon`), sin importar cuántos\n * `<kf-icon>` distintos haya en la página — todos referencian el mismo\n * sprite vía `<use href=\"#kf-icon-...\">`.\n */\nexport const KF_ICON_SPRITE = `<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none\">\n <symbol id=\"kf-icon-activity\" viewBox=\"0 0 24 24\">\n <path d=\"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2\" />\n </symbol>\n <symbol id=\"kf-icon-alert-circle\" viewBox=\"0 0 24 24\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" x2=\"12\" y1=\"8\" y2=\"12\" />\n <line x1=\"12\" x2=\"12.01\" y1=\"16\" y2=\"16\" />\n </symbol>\n <symbol id=\"kf-icon-alert-octagon\" viewBox=\"0 0 24 24\">\n <path d=\"M12 16h.01\" />\n <path d=\"M12 8v4\" />\n <path d=\"M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z\" />\n </symbol>\n <symbol id=\"kf-icon-alert-triangle\" viewBox=\"0 0 24 24\">\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </symbol>\n <symbol id=\"kf-icon-award\" viewBox=\"0 0 24 24\">\n <path d=\"m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526\" />\n <circle cx=\"12\" cy=\"8\" r=\"6\" />\n </symbol>\n <symbol id=\"kf-icon-bar-chart\" viewBox=\"0 0 24 24\">\n <path d=\"M5 21v-6\" />\n <path d=\"M12 21V9\" />\n <path d=\"M19 21V3\" />\n </symbol>\n <symbol id=\"kf-icon-bell\" viewBox=\"0 0 24 24\">\n <path d=\"M10.268 21a2 2 0 0 0 3.464 0\" />\n <path d=\"M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326\" />\n </symbol>\n <symbol id=\"kf-icon-bus\" viewBox=\"0 0 24 24\">\n <path d=\"M8 6v6\" />\n <path d=\"M15 6v6\" />\n <path d=\"M2 12h19.6\" />\n <path d=\"M18 18h3s.5-1.7.8-2.8c.1-.4.2-.8.2-1.2 0-.4-.1-.8-.2-1.2l-1.4-5C20.1 6.8 19.1 6 18 6H4a2 2 0 0 0-2 2v10h3\" />\n <circle cx=\"7\" cy=\"18\" r=\"2\" />\n <path d=\"M9 18h5\" />\n <circle cx=\"16\" cy=\"18\" r=\"2\" />\n </symbol>\n <symbol id=\"kf-icon-calculator\" viewBox=\"0 0 24 24\">\n <rect width=\"16\" height=\"20\" x=\"4\" y=\"2\" rx=\"2\" />\n <line x1=\"8\" x2=\"16\" y1=\"6\" y2=\"6\" />\n <line x1=\"16\" x2=\"16\" y1=\"14\" y2=\"18\" />\n <path d=\"M16 10h.01\" />\n <path d=\"M12 10h.01\" />\n <path d=\"M8 10h.01\" />\n <path d=\"M12 14h.01\" />\n <path d=\"M8 14h.01\" />\n <path d=\"M12 18h.01\" />\n <path d=\"M8 18h.01\" />\n </symbol>\n <symbol id=\"kf-icon-calendar\" viewBox=\"0 0 24 24\">\n <path d=\"M8 2v3\" />\n <path d=\"M16 2v3\" />\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <path d=\"M3 9h18\" />\n </symbol>\n <symbol id=\"kf-icon-car\" viewBox=\"0 0 24 24\">\n <path d=\"M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2\" />\n <circle cx=\"7\" cy=\"17\" r=\"2\" />\n <path d=\"M9 17h6\" />\n <circle cx=\"17\" cy=\"17\" r=\"2\" />\n </symbol>\n <symbol id=\"kf-icon-cart\" viewBox=\"0 0 24 24\">\n <circle cx=\"8\" cy=\"21\" r=\"1\" />\n <circle cx=\"19\" cy=\"21\" r=\"1\" />\n <path d=\"M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12\" />\n </symbol>\n <symbol id=\"kf-icon-check\" viewBox=\"0 0 24 24\">\n <path d=\"M20 6 9 17l-5-5\" />\n </symbol>\n <symbol id=\"kf-icon-check-circle\" viewBox=\"0 0 24 24\">\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n </symbol>\n <symbol id=\"kf-icon-check-square\" viewBox=\"0 0 24 24\">\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"m9 12 2 2 4-4\" />\n </symbol>\n <symbol id=\"kf-icon-chevron-down\" viewBox=\"0 0 24 24\">\n <path d=\"m6 9 6 6 6-6\" />\n </symbol>\n <symbol id=\"kf-icon-chevron-left\" viewBox=\"0 0 24 24\">\n <path d=\"m15 18-6-6 6-6\" />\n </symbol>\n <symbol id=\"kf-icon-chevron-left-bar\" viewBox=\"0 0 24 24\">\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n </symbol>\n <symbol id=\"kf-icon-chevron-right\" viewBox=\"0 0 24 24\">\n <path d=\"m9 18 6-6-6-6\" />\n </symbol>\n <symbol id=\"kf-icon-clipboard\" viewBox=\"0 0 24 24\">\n <rect width=\"8\" height=\"4\" x=\"8\" y=\"2\" rx=\"1\" ry=\"1\" />\n <path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\" />\n </symbol>\n <symbol id=\"kf-icon-clock\" viewBox=\"0 0 24 24\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 6v6l4 2\" />\n </symbol>\n <symbol id=\"kf-icon-credit-card\" viewBox=\"0 0 24 24\">\n <rect width=\"20\" height=\"14\" x=\"2\" y=\"5\" rx=\"2\" />\n <line x1=\"2\" x2=\"22\" y1=\"10\" y2=\"10\" />\n </symbol>\n <symbol id=\"kf-icon-download\" viewBox=\"0 0 24 24\">\n <path d=\"M12 15V3\" />\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <path d=\"m7 10 5 5 5-5\" />\n </symbol>\n <symbol id=\"kf-icon-edit\" viewBox=\"0 0 24 24\">\n <path d=\"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\" />\n <path d=\"m15 5 4 4\" />\n </symbol>\n <symbol id=\"kf-icon-external-link\" viewBox=\"0 0 24 24\">\n <path d=\"M15 3h6v6\" />\n <path d=\"M10 14 21 3\" />\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n </symbol>\n <symbol id=\"kf-icon-eye\" viewBox=\"0 0 24 24\">\n <path d=\"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </symbol>\n <symbol id=\"kf-icon-eye-off\" viewBox=\"0 0 24 24\">\n <path d=\"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\" />\n <path d=\"M14.084 14.158a3 3 0 0 1-4.242-4.242\" />\n <path d=\"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\" />\n <path d=\"m2 2 20 20\" />\n </symbol>\n <symbol id=\"kf-icon-file\" viewBox=\"0 0 24 24\">\n <path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\" />\n <path d=\"M14 2v5a1 1 0 0 0 1 1h5\" />\n </symbol>\n <symbol id=\"kf-icon-filter\" viewBox=\"0 0 24 24\">\n <path d=\"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z\" />\n </symbol>\n <symbol id=\"kf-icon-gauge\" viewBox=\"0 0 24 24\">\n <path d=\"m12 14 4-4\" />\n <path d=\"M3.34 19a10 10 0 1 1 17.32 0\" />\n </symbol>\n <symbol id=\"kf-icon-gift\" viewBox=\"0 0 24 24\">\n <path d=\"M12 7v14\" />\n <path d=\"M20 11v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8\" />\n <path d=\"M7.5 7a1 1 0 0 1 0-5A4.8 8 0 0 1 12 7a4.8 8 0 0 1 4.5-5 1 1 0 0 1 0 5\" />\n <rect x=\"3\" y=\"7\" width=\"18\" height=\"4\" rx=\"1\" />\n </symbol>\n <symbol id=\"kf-icon-grid\" viewBox=\"0 0 24 24\">\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M3 9h18\" />\n <path d=\"M3 15h18\" />\n <path d=\"M9 3v18\" />\n <path d=\"M15 3v18\" />\n </symbol>\n <symbol id=\"kf-icon-history\" viewBox=\"0 0 24 24\">\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n <path d=\"M12 7v5l4 2\" />\n </symbol>\n <symbol id=\"kf-icon-inbox\" viewBox=\"0 0 24 24\">\n <polyline points=\"22 12 16 12 14 15 10 15 8 12 2 12\" />\n <path d=\"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\" />\n </symbol>\n <symbol id=\"kf-icon-layers\" viewBox=\"0 0 24 24\">\n <path d=\"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z\" />\n <path d=\"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12\" />\n <path d=\"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17\" />\n </symbol>\n <symbol id=\"kf-icon-list\" viewBox=\"0 0 24 24\">\n <path d=\"M3 5h.01\" />\n <path d=\"M3 12h.01\" />\n <path d=\"M3 19h.01\" />\n <path d=\"M8 5h13\" />\n <path d=\"M8 12h13\" />\n <path d=\"M8 19h13\" />\n </symbol>\n <symbol id=\"kf-icon-map\" viewBox=\"0 0 24 24\">\n <path d=\"M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z\" />\n <path d=\"M15 5.764v15\" />\n <path d=\"M9 3.236v15\" />\n </symbol>\n <symbol id=\"kf-icon-map-pin\" viewBox=\"0 0 24 24\">\n <path d=\"M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0\" />\n <circle cx=\"12\" cy=\"10\" r=\"3\" />\n </symbol>\n <symbol id=\"kf-icon-menu\" viewBox=\"0 0 24 24\">\n <path d=\"M4 5h16\" />\n <path d=\"M4 12h16\" />\n <path d=\"M4 19h16\" />\n </symbol>\n <symbol id=\"kf-icon-mic\" viewBox=\"0 0 24 24\">\n <path d=\"M12 19v3\" />\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" />\n <rect x=\"9\" y=\"2\" width=\"6\" height=\"13\" rx=\"3\" />\n </symbol>\n <symbol id=\"kf-icon-mic-off\" viewBox=\"0 0 24 24\">\n <path d=\"M12 19v3\" />\n <path d=\"M15 9.34V5a3 3 0 0 0-5.68-1.33\" />\n <path d=\"M16.95 16.95A7 7 0 0 1 5 12v-2\" />\n <path d=\"M18.89 13.23A7 7 0 0 0 19 12v-2\" />\n <path d=\"m2 2 20 20\" />\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12\" />\n </symbol>\n <symbol id=\"kf-icon-more-vertical\" viewBox=\"0 0 24 24\">\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\n </symbol>\n <symbol id=\"kf-icon-pause\" viewBox=\"0 0 24 24\">\n <rect x=\"14\" y=\"3\" width=\"5\" height=\"18\" rx=\"1\" />\n <rect x=\"5\" y=\"3\" width=\"5\" height=\"18\" rx=\"1\" />\n </symbol>\n <symbol id=\"kf-icon-phone\" viewBox=\"0 0 24 24\">\n <path d=\"M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384\" />\n </symbol>\n <symbol id=\"kf-icon-play\" viewBox=\"0 0 24 24\">\n <path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\" />\n </symbol>\n <symbol id=\"kf-icon-plus\" viewBox=\"0 0 24 24\">\n <path d=\"M5 12h14\" />\n <path d=\"M12 5v14\" />\n </symbol>\n <symbol id=\"kf-icon-search\" viewBox=\"0 0 24 24\">\n <path d=\"m21 21-4.34-4.34\" />\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n </symbol>\n <symbol id=\"kf-icon-settings\" viewBox=\"0 0 24 24\">\n <path d=\"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </symbol>\n <symbol id=\"kf-icon-shield-check\" viewBox=\"0 0 24 24\">\n <path d=\"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\" />\n <path d=\"m9 12 2 2 4-4\" />\n </symbol>\n <symbol id=\"kf-icon-sort\" viewBox=\"0 0 24 24\">\n <path d=\"m21 16-4 4-4-4\" />\n <path d=\"M17 20V4\" />\n <path d=\"m3 8 4-4 4 4\" />\n <path d=\"M7 4v16\" />\n </symbol>\n <symbol id=\"kf-icon-star\" viewBox=\"0 0 24 24\">\n <path d=\"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\" />\n </symbol>\n <symbol id=\"kf-icon-ticket\" viewBox=\"0 0 24 24\">\n <path d=\"M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z\" />\n <path d=\"M13 5v2\" />\n <path d=\"M13 17v2\" />\n <path d=\"M13 11v2\" />\n </symbol>\n <symbol id=\"kf-icon-tool\" viewBox=\"0 0 24 24\">\n <path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z\" />\n </symbol>\n <symbol id=\"kf-icon-trash\" viewBox=\"0 0 24 24\">\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\" />\n <path d=\"M3 6h18\" />\n <path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </symbol>\n <symbol id=\"kf-icon-truck\" viewBox=\"0 0 24 24\">\n <path d=\"M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2\" />\n <path d=\"M15 18H9\" />\n <path d=\"M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14\" />\n <circle cx=\"17\" cy=\"18\" r=\"2\" />\n <circle cx=\"7\" cy=\"18\" r=\"2\" />\n </symbol>\n <symbol id=\"kf-icon-upload-cloud\" viewBox=\"0 0 24 24\">\n <path d=\"M12 13v8\" />\n <path d=\"M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242\" />\n <path d=\"m8 17 4-4 4 4\" />\n </symbol>\n <symbol id=\"kf-icon-user\" viewBox=\"0 0 24 24\">\n <path d=\"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\" />\n <circle cx=\"12\" cy=\"7\" r=\"4\" />\n </symbol>\n <symbol id=\"kf-icon-user-search\" viewBox=\"0 0 24 24\">\n <circle cx=\"10\" cy=\"7\" r=\"4\" />\n <path d=\"M10.3 15H7a4 4 0 0 0-4 4v2\" />\n <circle cx=\"17\" cy=\"17\" r=\"3\" />\n <path d=\"m21 21-1.9-1.9\" />\n </symbol>\n <symbol id=\"kf-icon-video\" viewBox=\"0 0 24 24\">\n <path d=\"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5\" />\n <rect x=\"2\" y=\"6\" width=\"14\" height=\"12\" rx=\"2\" />\n </symbol>\n <symbol id=\"kf-icon-x\" viewBox=\"0 0 24 24\">\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </symbol>\n</svg>`;\n","import { DOCUMENT } from '@angular/common';\nimport { Component, computed, effect, inject, input } from '@angular/core';\nimport { KF_ICON_SPRITE } from './icon-sprite';\n\n/**\n * Nombre de cada ícono del design system. Página 5 del PDF fija un set de\n * 59; `eye-off` es una extensión propia por fuera de ese set, agregada para\n * el toggle de mostrar/ocultar contraseña de `Input` — no hay un ícono de\n * \"ojo tachado\" en la spec original porque esa interacción no estaba\n * contemplada ahí.\n */\nexport type IconName =\n | 'activity'\n | 'alert-circle'\n | 'alert-octagon'\n | 'alert-triangle'\n | 'award'\n | 'bar-chart'\n | 'bell'\n | 'bus'\n | 'calculator'\n | 'calendar'\n | 'car'\n | 'cart'\n | 'check'\n | 'check-circle'\n | 'check-square'\n | 'chevron-down'\n | 'chevron-left'\n | 'chevron-left-bar'\n | 'chevron-right'\n | 'clipboard'\n | 'clock'\n | 'credit-card'\n | 'download'\n | 'edit'\n | 'external-link'\n | 'eye'\n | 'eye-off'\n | 'file'\n | 'filter'\n | 'gauge'\n | 'gift'\n | 'grid'\n | 'history'\n | 'inbox'\n | 'layers'\n | 'list'\n | 'map'\n | 'map-pin'\n | 'menu'\n | 'mic'\n | 'mic-off'\n | 'more-vertical'\n | 'pause'\n | 'phone'\n | 'play'\n | 'plus'\n | 'search'\n | 'settings'\n | 'shield-check'\n | 'sort'\n | 'star'\n | 'ticket'\n | 'tool'\n | 'trash'\n | 'truck'\n | 'upload-cloud'\n | 'user'\n | 'user-search'\n | 'video'\n | 'x';\n\nexport type IconSize = 'sm' | 'md' | 'lg';\n\n/** Marca el sprite ya inyectado, para no depender de una bandera de módulo\n * — una bandera compartida entre instancias de test (o entre múltiples\n * `TestBed` en la misma suite) daría falsos negativos: el primer test que\n * corre \"gasta\" la bandera y todos los siguientes creerían que el sprite\n * nunca se inyecta. Comprobar el propio DOM es la fuente de verdad real. */\nconst SPRITE_ROOT_ID = 'kf-icon-sprite-root';\n\n/**\n * Ícono de trazo del design system — 59 glyphs (página 5), grilla 24×24,\n * grosor de trazo 1.9px. Referencia un sprite SVG embebido (ver\n * `icon-sprite.ts`) vía `<use>`, así que no hay peso de red adicional por\n * cada instancia: el sprite se inyecta al DOM una única vez, la primera\n * vez que se renderiza cualquier `<kf-icon>` de toda la aplicación.\n *\n * El tamaño se controla con `size` (página 6: \"el tamaño se controla con la\n * prop size\"): `sm` (16px), `md` (20px, default) o `lg` (24px). El color\n * sigue siempre `currentColor` — se hereda del texto del elemento\n * contenedor, nunca se fija en el propio ícono.\n *\n * <kf-icon name=\"alert-triangle\" size=\"sm\" />\n * <kf-button icon=\"calendar\">Reservar hora</kf-button> <!-- ver Button -->\n */\n@Component({\n selector: 'kf-icon',\n template: `\n <svg [attr.aria-hidden]=\"true\" focusable=\"false\">\n <use [attr.href]=\"'#kf-icon-' + name()\" />\n </svg>\n `,\n styles: `\n :host {\n display: inline-flex;\n flex: none;\n line-height: 0;\n }\n svg {\n width: var(--kf-icon-size, 20px);\n height: var(--kf-icon-size, 20px);\n fill: none;\n stroke: currentColor;\n stroke-width: 1.9;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n `,\n host: {\n '[style.--kf-icon-size]': 'pixelSize()',\n },\n})\nexport class Icon {\n readonly name = input.required<IconName>();\n readonly size = input<IconSize>('md');\n\n private readonly document = inject(DOCUMENT);\n\n protected readonly pixelSize = computed(() => {\n const bySize: Record<IconSize, string> = { sm: '16px', md: '20px', lg: '24px' };\n return bySize[this.size()];\n });\n\n constructor() {\n effect(() => {\n if (this.document.getElementById(SPRITE_ROOT_ID)) {\n return;\n }\n const container = this.document.createElement('div');\n container.innerHTML = KF_ICON_SPRITE;\n const sprite = container.firstElementChild;\n if (sprite) {\n sprite.id = SPRITE_ROOT_ID;\n this.document.body.prepend(sprite);\n }\n });\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Dos variantes del mismo concepto — acceso rápido a una sección (página\n * 35): \"Tile de acceso destacado\" (`variant=\"tile\"`, default) es un bloque\n * centrado con ícono grande arriba y título abajo, pensado para una\n * cuadrícula de accesos (ej. \"Todos los certificados\"). \"Fila de documento\"\n * (`variant=\"row\"`) es horizontal, con ícono a la izquierda y\n * título+descripción a la derecha, pensada para listas verticales dentro de\n * un `kf-panel` (ej. \"Pagos\" / \"Revisa tu estado de cuenta y realiza pagos.\").\n *\n * <kf-action-tile icon=\"shield-check\" title=\"Todos los certificados\" />\n * <kf-action-tile variant=\"row\" icon=\"download\" title=\"Pagos\"\n * description=\"Revisa tu estado de cuenta y realiza pagos.\" />\n */\n@Component({\n selector: 'kf-action-tile',\n imports: [Icon],\n template: `\n <span class=\"kf-action-tile__icon\">\n <kf-icon [name]=\"icon()\" [size]=\"variant() === 'row' ? 'md' : 'lg'\" />\n </span>\n <span class=\"kf-action-tile__text\">\n <span class=\"kf-action-tile__title\">{{ title() }}</span>\n @if (description()) {\n <span class=\"kf-action-tile__description\">{{ description() }}</span>\n }\n </span>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n :host(:hover) {\n border-color: var(--kf-color-border-strong);\n box-shadow: var(--kf-shadow-xs);\n }\n :host(.kf-action-tile--tile) {\n flex-direction: column;\n text-align: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-lg);\n }\n .kf-action-tile__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n :host(.kf-action-tile--row) .kf-action-tile__icon {\n width: 2.25rem;\n height: 2.25rem;\n background: var(--kf-color-secondary-soft);\n color: var(--kf-color-secondary);\n }\n :host(.kf-action-tile--tile) .kf-action-tile__icon {\n width: 2.75rem;\n height: 2.75rem;\n }\n .kf-action-tile__text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n }\n .kf-action-tile__title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-action-tile__description {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n `,\n host: {\n '[class.kf-action-tile--tile]': \"variant() === 'tile'\",\n '[class.kf-action-tile--row]': \"variant() === 'row'\",\n },\n})\nexport class ActionTile {\n readonly variant = input<'tile' | 'row'>('tile');\n readonly icon = input.required<IconName>();\n readonly title = input.required<string>();\n readonly description = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Marca la barra superior como chrome exclusivo de administradores (página\n * 18) — acento ámbar para diferenciar contexto privilegiado del resto del\n * portal. Dos variantes: etiqueta aislada (pill), o `inline` para usarse\n * dentro de la franja de `kf-portal-header` (fondo oscuro, texto ámbar).\n *\n * <kf-admin-badge />\n * <kf-admin-badge inline />\n */\n@Component({\n selector: 'kf-admin-badge',\n imports: [Icon],\n template: `\n <kf-icon name=\"shield-check\" size=\"sm\" />\n <span>Vista administrador</span>\n `,\n styles: `\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-warning-soft);\n border: 1px solid var(--kf-color-warning);\n color: var(--kf-color-warning-strong);\n font-size: 0.75rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n line-height: 1;\n }\n :host(.kf-admin-badge--inline) {\n background: transparent;\n border-color: rgba(226, 185, 59, 0.5);\n color: var(--kf-color-warning);\n }\n `,\n host: {\n '[class.kf-admin-badge--inline]': 'inline()',\n },\n})\nexport class AdminBadge {\n /** Para usarse dentro de una superficie oscura (ej. la franja de `kf-portal-header`). */\n readonly inline = input(false, { transform: booleanAttribute });\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Wraps a native `<button>`, so keyboard handling, focus and form submission\n * keep working. The cost of the wrapper is forwarding `disabled` and `type` by\n * hand: as attributes on a custom element they have no native effect.\n *\n * Five variants (page 9 of the design system): `primary` (main action, blue),\n * `secondary` (service actions, orange), `ghost` (low-emphasis, no fill),\n * `outline` (medium-emphasis, bordered) and `danger` (destructive\n * confirmations — red, see the Confirmation Modal pattern on page 30). Three\n * sizes (`sm`/`md`/`lg`). `icon` renders a leading glyph (`kf-icon`) before\n * the projected label; `block` stretches the button to the full width of its\n * container.\n *\n * `(click)` is not forwarded — it bubbles from the inner button to the host.\n *\n * <kf-button (click)=\"save()\">Save</kf-button>\n * <kf-button variant=\"ghost\" disabled>Cancel</kf-button>\n * <kf-button variant=\"danger\" (click)=\"remove()\">Delete</kf-button>\n * <kf-button size=\"sm\" icon=\"calendar\" block>Reservar hora</kf-button>\n */\n@Component({\n selector: 'kf-button',\n imports: [Icon],\n template: `\n <button\n [type]=\"type()\"\n [disabled]=\"disabled()\"\n [class.kf-button--secondary]=\"variant() === 'secondary'\"\n [class.kf-button--ghost]=\"variant() === 'ghost'\"\n [class.kf-button--outline]=\"variant() === 'outline'\"\n [class.kf-button--danger]=\"variant() === 'danger'\"\n [class.kf-button--sm]=\"size() === 'sm'\"\n [class.kf-button--lg]=\"size() === 'lg'\"\n >\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-button__icon\" [name]=\"iconName\" [size]=\"size() === 'lg' ? 'md' : 'sm'\" />\n }\n <ng-content />\n </button>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n :host([block]) {\n display: block;\n }\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--kf-space-xs);\n width: 100%;\n font: inherit;\n font-weight: 600;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid var(--kf-color-primary);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n cursor: pointer;\n transition:\n background 0.14s,\n border-color 0.14s,\n color 0.14s;\n }\n button:hover:not(:disabled) {\n background: var(--kf-color-primary-hover);\n border-color: var(--kf-color-primary-hover);\n }\n button:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n /* Secondary — naranja, para acciones de servicio (agendar, mantención). */\n button.kf-button--secondary {\n border-color: var(--kf-color-secondary);\n background: var(--kf-color-secondary);\n }\n button.kf-button--secondary:hover:not(:disabled) {\n background: var(--kf-color-secondary-hover);\n border-color: var(--kf-color-secondary-hover);\n }\n\n /* Ghost — sin relleno, para acciones secundarias junto a un primary. */\n button.kf-button--ghost {\n background: transparent;\n border-color: transparent;\n color: var(--kf-color-primary);\n }\n button.kf-button--ghost:hover:not(:disabled) {\n background: var(--kf-color-primary-soft);\n }\n\n /* Outline — énfasis medio: borde visible, sin relleno (ej. \"Llamar\" en Vehicle Header). */\n button.kf-button--outline {\n background: transparent;\n border-color: var(--kf-color-border-strong);\n color: var(--kf-color-text);\n }\n button.kf-button--outline:hover:not(:disabled) {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-text-muted);\n }\n\n /* Danger — rojo, para confirmaciones destructivas (cancelar, eliminar). */\n button.kf-button--danger {\n border-color: var(--kf-color-error);\n background: var(--kf-color-error);\n }\n button.kf-button--danger:hover:not(:disabled) {\n background: var(--kf-color-error-hover);\n border-color: var(--kf-color-error-hover);\n }\n\n /* Tamaños — el tamaño por defecto (md) usa el padding base de arriba. */\n button.kf-button--sm {\n padding: 6px var(--kf-space-sm);\n font-size: 0.85rem;\n }\n button.kf-button--lg {\n padding: var(--kf-space-sm) var(--kf-space-lg);\n font-size: 1.05rem;\n }\n `,\n host: {\n '[attr.block]': \"block() ? '' : null\",\n },\n})\nexport class Button {\n readonly variant = input<'primary' | 'secondary' | 'ghost' | 'outline' | 'danger'>('primary');\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Matches the native default: submits when inside a `<form>`. */\n readonly type = input<'button' | 'submit' | 'reset'>('submit');\n /** Leading icon, rendered via `kf-icon` before the projected label. */\n readonly icon = input<IconName>();\n /** Stretches the button to the full width of its container. */\n readonly block = input(false, { transform: booleanAttribute });\n}\n","import { booleanAttribute, Component, computed, input, model } from '@angular/core';\n\nexport type AlertTone = 'info' | 'ok' | 'warn' | 'error';\n\n/**\n * Banner contextual que vive dentro del flujo: validaciones, avisos de\n * vencimiento, confirmaciones. Persiste hasta que se descarta o hasta que la\n * condición que lo causó desaparece — para feedback efímero está el toast.\n *\n * `open` es two-way: el botón de cerrar lo pone en `false` y el componente\n * deja de renderizar. El consumidor puede volver a abrirlo poniéndolo en\n * `true` (ej. cuando la validación falla otra vez).\n *\n * ponytail: los glifos van inline en vez de venir de un componente Icon —\n * son 4 paths fijos, uno por tono, y no existe todavía `kf-icon` en la\n * librería. Cuando exista, se reemplaza este `@switch` por `<kf-icon>`.\n *\n * <kf-alert tone=\"warn\" title=\"SOAT por vencer\">Vence el 15/08.</kf-alert>\n * <kf-alert tone=\"ok\" [(open)]=\"saved\" dismissible>Pago registrado.</kf-alert>\n */\n@Component({\n selector: 'kf-alert',\n template: `\n @if (open()) {\n <div class=\"kf-alert\" [class]=\"'kf-alert--' + tone()\" [attr.role]=\"ariaRole()\">\n <svg class=\"kf-alert__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n @switch (tone()) {\n @case ('ok') {\n <path d=\"M21 12a9 9 0 1 1-4.2-7.6\" />\n <path d=\"M9 11.5l3 3 8.5-8.5\" />\n }\n @case ('warn') {\n <path d=\"M12 4l9 16H3z\" />\n <path d=\"M12 10v4\" />\n <path d=\"M12 17.5h.01\" />\n }\n @case ('error') {\n <path d=\"M8 3h8l5 5v8l-5 5H8l-5-5V8z\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n }\n </svg>\n <div class=\"kf-alert__body\">\n @if (title()) {\n <p class=\"kf-alert__title\">{{ title() }}</p>\n }\n <div class=\"kf-alert__message\"><ng-content /></div>\n </div>\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"kf-alert__close\"\n aria-label=\"Cerrar aviso\"\n (click)=\"open.set(false)\"\n >\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M6 6l12 12M18 6L6 18\" />\n </svg>\n </button>\n }\n </div>\n }\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-alert {\n display: flex;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid transparent;\n border-radius: var(--kf-radius-sm);\n font-size: 0.9rem;\n }\n .kf-alert--info {\n background: var(--kf-color-info-soft);\n border-color: var(--kf-color-info);\n color: var(--kf-color-info-strong);\n }\n .kf-alert--ok {\n background: var(--kf-color-success-soft);\n border-color: var(--kf-color-success);\n color: var(--kf-color-success-strong);\n }\n .kf-alert--warn {\n background: var(--kf-color-warning-soft);\n border-color: var(--kf-color-warning);\n color: var(--kf-color-warning-strong);\n }\n .kf-alert--error {\n background: var(--kf-color-error-soft);\n border-color: var(--kf-color-error);\n color: var(--kf-color-error-strong);\n }\n .kf-alert__icon,\n .kf-alert__close svg {\n flex: none;\n width: 1.15em;\n height: 1.15em;\n fill: none;\n stroke: currentColor;\n stroke-width: 1.9;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n .kf-alert__body {\n flex: 1;\n min-width: 0;\n }\n .kf-alert__title {\n margin: 0;\n font-family: var(--kf-font-title);\n font-weight: 700;\n }\n .kf-alert__message {\n color: inherit;\n }\n .kf-alert__close {\n flex: none;\n display: inline-flex;\n padding: 2px;\n border: none;\n background: transparent;\n color: inherit;\n border-radius: var(--kf-radius-xs);\n cursor: pointer;\n opacity: 0.7;\n }\n .kf-alert__close:hover {\n opacity: 1;\n }\n .kf-alert__close:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n `,\n})\nexport class Alert {\n readonly tone = input<AlertTone>('info');\n /** Línea en negrita arriba del mensaje. Vacío deja solo el contenido proyectado. */\n readonly title = input('');\n readonly dismissible = input(false, { transform: booleanAttribute });\n /** Visibilidad, two-way: `[(open)]=\"hasError\"`. */\n readonly open = model(true);\n\n /**\n * `alert` interrumpe al lector de pantalla; se reserva para error/warn.\n * Los avisos informativos se anuncian sin cortar lo que se esté leyendo.\n */\n protected readonly ariaRole = computed(() =>\n this.tone() === 'error' || this.tone() === 'warn' ? 'alert' : 'status',\n );\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport { booleanAttribute, Component, computed, input } from '@angular/core';\n\n/**\n * Avatar de usuario: muestra una foto (`src`) o, si no hay foto, las\n * iniciales (`initials`) sobre un fondo con gradiente de marca. `round`\n * controla la forma: circular (por defecto) o cuadrada con radio.\n *\n * Con `pill`, el avatar se envuelve en una pastilla azul con un chevron a la\n * derecha — la \"pill de usuario (header)\" de la página 18 del design system,\n * usada en la barra de sesión del Portal Header.\n *\n * <kf-avatar initials=\"JD\" />\n * <kf-avatar src=\"https://…/foto.jpg\" [round]=\"false\" />\n * <kf-avatar initials=\"TS\" pill />\n *\n * Pendiente: si en el futuro se agrega un ícono de fallback (persona\n * genérica) para cuando no hay ni `src` ni `initials`, depende del\n * componente Icon / sprite SVG que todavía no existe en esta librería.\n */\n@Component({\n selector: 'kf-avatar',\n imports: [NgTemplateOutlet],\n template: `\n <ng-template #avatarCircle>\n <span class=\"kf-avatar\" [class.kf-avatar--square]=\"!round()\">\n @if (src()) {\n <img class=\"kf-avatar__image\" [src]=\"src()\" [alt]=\"initials() || ''\" />\n } @else {\n <span class=\"kf-avatar__initials\">{{ displayInitials() }}</span>\n }\n </span>\n </ng-template>\n\n @if (pill()) {\n <span class=\"kf-avatar-pill\">\n <ng-container [ngTemplateOutlet]=\"avatarCircle\" />\n <span class=\"kf-avatar-pill__caret\" aria-hidden=\"true\"></span>\n </span>\n } @else {\n <ng-container [ngTemplateOutlet]=\"avatarCircle\" />\n }\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-avatar {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: 40px;\n block-size: 40px;\n overflow: hidden;\n border-radius: var(--kf-radius-pill);\n background: linear-gradient(135deg, var(--kf-color-primary), var(--kf-color-primary-active));\n color: var(--kf-color-white);\n font: inherit;\n font-size: 0.875rem;\n font-weight: 600;\n line-height: 1;\n user-select: none;\n flex: none;\n }\n .kf-avatar--square {\n border-radius: var(--kf-radius-sm);\n }\n .kf-avatar__image {\n inline-size: 100%;\n block-size: 100%;\n object-fit: cover;\n }\n .kf-avatar__initials {\n text-transform: uppercase;\n }\n\n /* Pill de usuario (header) — envuelve el avatar en una pastilla azul con chevron. */\n .kf-avatar-pill {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: 4px var(--kf-space-sm) 4px 4px;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-primary);\n cursor: pointer;\n }\n .kf-avatar-pill .kf-avatar {\n inline-size: 32px;\n block-size: 32px;\n background: rgba(255, 255, 255, 0.18);\n }\n .kf-avatar-pill__caret {\n flex: none;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-white);\n border-bottom: 2px solid var(--kf-color-white);\n transform: rotate(45deg);\n margin-top: -4px;\n }\n `,\n})\nexport class Avatar {\n readonly initials = input<string>();\n readonly src = input<string>();\n readonly round = input(true);\n /** Envuelve el avatar en la pastilla de sesión del header, con chevron. */\n readonly pill = input(false, { transform: booleanAttribute });\n\n /** Limita a 2 caracteres para que quepan cómodos dentro del círculo. */\n readonly displayInitials = computed(() => (this.initials() ?? '').slice(0, 2));\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Pill chica de fondo suave (soft) para un conteo, tag o estado liviano\n * puntual (no un proceso en vivo — para eso existe `kf-status-pill`, que usa\n * borde en vez de relleno). El color de fondo/texto/punto depende de `tone`.\n *\n * El PDF (página 10) fija seis tonos con fondo soft y texto del tono fuerte\n * — nunca fondo saturado con texto blanco, que es más apto para un botón\n * que para una etiqueta de lectura rápida en una lista densa.\n *\n * <kf-badge tone=\"ok\" dot>Al día</kf-badge>\n * <kf-badge tone=\"error\">3</kf-badge>\n *\n * Mapeo de `tone` a los seis conceptos de la página 10 y sus tokens\n * semánticos en projects/ui/src/tokens/base.css:\n * neutral -> Neutral (border/text-muted), info -> Información (info-soft/-strong),\n * ok -> Activo (success-soft/-strong), warn -> Pendiente (warning-soft/-strong),\n * error -> Vencido (error-soft/-strong), service -> Servicio (secondary-soft,\n * no existe un `-strong` para secondary todavía — usa el color base).\n */\n@Component({\n selector: 'kf-badge',\n template: `\n <span class=\"kf-badge\" [class]=\"'kf-badge--' + tone()\">\n @if (dot()) {\n <span class=\"kf-badge__dot\"></span>\n }\n <ng-content />\n </span>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-badge {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n font: inherit;\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1;\n white-space: nowrap;\n background: var(--kf-color-border);\n color: var(--kf-color-text-muted);\n }\n .kf-badge__dot {\n inline-size: 6px;\n block-size: 6px;\n border-radius: var(--kf-radius-pill);\n flex: none;\n background: currentColor;\n }\n .kf-badge--neutral {\n background: var(--kf-color-border);\n color: var(--kf-color-text-muted);\n }\n .kf-badge--ok {\n background: var(--kf-color-success-soft);\n color: var(--kf-color-success-strong);\n }\n .kf-badge--warn {\n background: var(--kf-color-warning-soft);\n color: var(--kf-color-warning-strong);\n }\n .kf-badge--error {\n background: var(--kf-color-error-soft);\n color: var(--kf-color-error-strong);\n }\n .kf-badge--info {\n background: var(--kf-color-info-soft);\n color: var(--kf-color-info-strong);\n }\n .kf-badge--service {\n background: var(--kf-color-secondary-soft);\n color: var(--kf-color-secondary-strong);\n }\n `,\n})\nexport class Badge {\n readonly tone = input<'neutral' | 'ok' | 'warn' | 'error' | 'info' | 'service'>('neutral');\n readonly dot = input(false, { transform: booleanAttribute });\n}\n","import { Component, computed, input, output } from '@angular/core';\n\nexport interface BreadcrumbItem {\n label: string;\n /** Destino del link. Sin `href` el nivel se rinde como texto plano. */\n href?: string;\n}\n\n/**\n * Ruta de navegación de las vistas internas. El último nivel es la página\n * actual: nunca es link y lleva `aria-current=\"page\"`, aunque traiga `href`.\n *\n * Se rinde como `<nav><ol>` — es una lista ordenada de ancestros, y eso es lo\n * que los lectores de pantalla anuncian (\"navegación, lista de 3 elementos\").\n *\n * Para apps con router: escuchar `itemClick` y llamar\n * `event.preventDefault()` antes de `router.navigate(...)`. El `href` se\n * mantiene igual para que click-medio, \"abrir en pestaña nueva\" y el hover\n * de la barra de estado sigan funcionando.\n *\n * <kf-breadcrumb [items]=\"[{ label: 'Inicio', href: '/' }, { label: 'Mis vehículos' }]\" />\n */\n@Component({\n selector: 'kf-breadcrumb',\n template: `\n <nav class=\"kf-breadcrumb\" aria-label=\"Ruta de navegación\">\n <ol class=\"kf-breadcrumb__list\">\n @for (item of items(); track $index; let i = $index) {\n <li class=\"kf-breadcrumb__item\">\n @if (i > 0) {\n <svg\n class=\"kf-breadcrumb__separator\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M9 6l6 6-6 6\" />\n </svg>\n }\n @if (item.href && i !== lastIndex()) {\n <a\n class=\"kf-breadcrumb__link\"\n [href]=\"item.href\"\n (click)=\"itemClick.emit({ item, index: i, event: $event })\"\n >\n {{ item.label }}\n </a>\n } @else {\n <span\n class=\"kf-breadcrumb__current\"\n [attr.aria-current]=\"i === lastIndex() ? 'page' : null\"\n >\n {{ item.label }}\n </span>\n }\n </li>\n }\n </ol>\n </nav>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n font-size: 0.875rem;\n }\n .kf-breadcrumb__list {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--kf-space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n .kf-breadcrumb__item {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n min-width: 0;\n }\n .kf-breadcrumb__separator {\n flex: none;\n width: 1em;\n height: 1em;\n fill: none;\n stroke: var(--kf-color-border-strong);\n stroke-width: 1.9;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n .kf-breadcrumb__link {\n color: var(--kf-color-primary);\n text-decoration: none;\n border-radius: var(--kf-radius-xs);\n transition: color 0.14s;\n }\n .kf-breadcrumb__link:hover {\n text-decoration: underline;\n }\n .kf-breadcrumb__link:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-breadcrumb__current {\n color: var(--kf-color-text-muted);\n overflow-wrap: anywhere;\n }\n `,\n})\nexport class Breadcrumb {\n readonly items = input.required<BreadcrumbItem[]>();\n\n /**\n * Click en un nivel con `href`. Incluye el `MouseEvent` para que un\n * consumidor con router pueda cortar la navegación nativa.\n *\n * ponytail: no dependemos de `@angular/router` acá — sería un peer dep\n * nuevo en la librería para lo que el consumidor resuelve en una línea.\n */\n readonly itemClick = output<{ item: BreadcrumbItem; index: number; event: MouseEvent }>();\n\n protected readonly lastIndex = computed(() => this.items().length - 1);\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Contenedor base con esquinas redondeadas y sombra sutil — la base visual\n * de paneles, tarjetas de métrica, tablas y bloques de contenido de todo el\n * portal (ver página 14 del design system).\n *\n * Piensa este componente como el \"cimiento\": no impone estructura interna\n * más allá de dos slots opcionales alrededor del contenido libre —\n * `[media]` para una imagen/ícono destacado arriba, y `[actions]` para una\n * fila de botones al pie, separada por una línea. El contenido por defecto\n * (sin selector) queda en el medio, sin ningún layout forzado, para que\n * cualquier composición (una métrica, una lista, un formulario) pueda vivir\n * dentro sin pelear con estilos propios del `Card`.\n *\n * <kf-card>Contenido simple</kf-card>\n * <kf-card flush>Sin sombra — para superficies ya delimitadas por otra card</kf-card>\n * <kf-card>\n * <img kf-card-media src=\"...\" alt=\"\" />\n * <h3>Título</h3>\n * <p>Descripción</p>\n * <div kf-card-actions>\n * <kf-button variant=\"ghost\">Cancelar</kf-button>\n * <kf-button>Guardar</kf-button>\n * </div>\n * </kf-card>\n */\n@Component({\n selector: 'kf-card',\n template: `\n <ng-content select=\"[kf-card-media]\" />\n <div class=\"kf-card__body\">\n <ng-content />\n </div>\n <ng-content select=\"[kf-card-actions]\" />\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-xs);\n overflow: hidden;\n }\n :host.kf-card--flush {\n box-shadow: none;\n }\n .kf-card__body {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n flex: 1 1 auto;\n }\n ::ng-deep [kf-card-media] {\n display: block;\n inline-size: 100%;\n block-size: auto;\n object-fit: cover;\n }\n ::ng-deep [kf-card-actions] {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-top: 1px solid var(--kf-color-border);\n }\n `,\n host: {\n '[class.kf-card--flush]': 'flush()',\n },\n})\nexport class Card {\n /** Quita la sombra — para cards anidadas dentro de otra superficie ya elevada. */\n readonly flush = input(false, { transform: booleanAttribute });\n}\n","import {\n AfterContentInit,\n Component,\n DestroyRef,\n contentChildren,\n inject,\n input,\n numberAttribute,\n output,\n signal,\n} from '@angular/core';\n\n/**\n * Slide individual de un `kf-carousel`. Es un contenedor mínimo: solo existe\n * para que el carrusel pueda detectar, vía `contentChildren`, cuántos slides\n * se proyectaron y en qué orden — el contenido real es responsabilidad total\n * de quien lo consume.\n *\n * <kf-carousel-slide>...</kf-carousel-slide>\n */\n@Component({\n selector: 'kf-carousel-slide',\n template: `<ng-content />`,\n styles: `\n :host {\n display: block;\n flex: 0 0 100%;\n width: 100%;\n }\n `,\n})\nexport class CarouselSlide {}\n\n/**\n * Carrusel de slides con flechas, dots y autoplay opcional.\n *\n * La spec original de React recibe `slides` como un array de nodos React.\n * En Angular eso no tiene equivalente directo: en vez de forzar un array de\n * datos crudos, cada slide se proyecta como contenido declarativo mediante\n * un `kf-carousel-slide` hijo, y el carrusel los detecta con\n * `contentChildren(CarouselSlide)`. Esto evita depender de un renderer de\n * nodos y deja que cada slide use plantillas Angular normales (bindings,\n * `@if`, `@for`, etc.) tal como se espera en este ecosistema.\n *\n * <kf-carousel [autoplay]=\"true\" [interval]=\"4000\" (indexChange)=\"onIndex($event)\">\n * <kf-carousel-slide>...</kf-carousel-slide>\n * <kf-carousel-slide>...</kf-carousel-slide>\n * </kf-carousel>\n */\n@Component({\n selector: 'kf-carousel',\n template: `\n <div\n class=\"kf-carousel\"\n (mouseenter)=\"pauseAutoplay()\"\n (mouseleave)=\"resumeAutoplay()\"\n (focusin)=\"pauseAutoplay()\"\n (focusout)=\"resumeAutoplay()\"\n >\n <div class=\"kf-carousel__viewport\">\n <div\n class=\"kf-carousel__track\"\n [style.transform]=\"'translateX(-' + activeIndex() * 100 + '%)'\"\n >\n <ng-content />\n </div>\n </div>\n\n @if (slides().length > 1) {\n <button\n type=\"button\"\n class=\"kf-carousel__arrow kf-carousel__arrow--prev\"\n aria-label=\"Slide anterior\"\n (click)=\"previous()\"\n >\n ‹\n </button>\n <button\n type=\"button\"\n class=\"kf-carousel__arrow kf-carousel__arrow--next\"\n aria-label=\"Slide siguiente\"\n (click)=\"next()\"\n >\n ›\n </button>\n\n <div class=\"kf-carousel__dots\" role=\"tablist\">\n @for (slide of slides(); track slide; let i = $index) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"kf-carousel__dot\"\n [class.kf-carousel__dot--active]=\"i === activeIndex()\"\n [attr.aria-selected]=\"i === activeIndex()\"\n [attr.aria-label]=\"'Ir al slide ' + (i + 1)\"\n (click)=\"goTo(i)\"\n ></button>\n }\n </div>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-carousel {\n position: relative;\n }\n .kf-carousel__viewport {\n overflow: hidden;\n border-radius: var(--kf-radius-md);\n }\n .kf-carousel__track {\n display: flex;\n transition: transform 0.32s ease;\n }\n .kf-carousel__arrow {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 2.25rem;\n height: 2.25rem;\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-white);\n color: var(--kf-color-ink);\n font-size: 1.25rem;\n line-height: 1;\n cursor: pointer;\n box-shadow: var(--kf-shadow-sm);\n transition:\n background 0.14s,\n border-color 0.14s;\n }\n .kf-carousel__arrow:hover {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border-strong);\n }\n .kf-carousel__arrow:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-carousel__arrow--prev {\n left: var(--kf-space-sm);\n }\n .kf-carousel__arrow--next {\n right: var(--kf-space-sm);\n }\n .kf-carousel__dots {\n display: flex;\n justify-content: center;\n gap: var(--kf-space-xs);\n margin-top: var(--kf-space-sm);\n }\n .kf-carousel__dot {\n width: 0.5rem;\n height: 0.5rem;\n padding: 0;\n border: none;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-border-strong);\n cursor: pointer;\n transition: background 0.14s;\n }\n .kf-carousel__dot:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-carousel__dot--active {\n background: var(--kf-color-primary);\n }\n `,\n})\nexport class Carousel implements AfterContentInit {\n readonly autoplay = input(false);\n readonly interval = input(5000, { transform: numberAttribute });\n readonly indexChange = output<number>();\n\n readonly slides = contentChildren(CarouselSlide);\n\n private readonly activeIndexSignal = signal(0);\n readonly activeIndex = this.activeIndexSignal.asReadonly();\n\n private readonly destroyRef = inject(DestroyRef);\n private timer: ReturnType<typeof setInterval> | null = null;\n private autoplayPaused = false;\n\n ngAfterContentInit(): void {\n this.startAutoplay();\n this.destroyRef.onDestroy(() => this.stopAutoplay());\n }\n\n next(): void {\n const total = this.slides().length;\n if (total === 0) {\n return;\n }\n this.goTo((this.activeIndexSignal() + 1) % total);\n }\n\n previous(): void {\n const total = this.slides().length;\n if (total === 0) {\n return;\n }\n this.goTo((this.activeIndexSignal() - 1 + total) % total);\n }\n\n goTo(index: number): void {\n if (index === this.activeIndexSignal()) {\n return;\n }\n this.activeIndexSignal.set(index);\n this.indexChange.emit(index);\n }\n\n pauseAutoplay(): void {\n this.autoplayPaused = true;\n }\n\n resumeAutoplay(): void {\n this.autoplayPaused = false;\n }\n\n private startAutoplay(): void {\n if (!this.autoplay() || this.slides().length <= 1) {\n return;\n }\n this.timer = setInterval(() => {\n if (!this.autoplayPaused) {\n this.next();\n }\n }, this.interval());\n }\n\n private stopAutoplay(): void {\n if (this.timer !== null) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n}\n","import {\n booleanAttribute,\n Component,\n effect,\n ElementRef,\n forwardRef,\n input,\n output,\n viewChild,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\n/**\n * Checkbox accesible con soporte de estado \"indeterminate\".\n *\n * `indeterminate` no existe como atributo HTML: el navegador solo lo expone\n * como propiedad del elemento nativo, así que se aplica a mano sobre el\n * `<input>` interno vía `viewChild` + `effect` cada vez que cambia el input.\n *\n * Implementa `ControlValueAccessor` para poder usarse con `formControlName` /\n * `ngModel` igual que un checkbox nativo. En ese modo, `writeValue` controla\n * el DOM directamente y el input `checked` (pensado para binding manual sin\n * forms) queda en su valor por defecto — igual que `disabled` combina el\n * input signal con `setDisabledState` en el resto de la librería.\n *\n * `invalid` pinta el recuadro en rojo y setea `aria-invalid` en el `<input>`\n * nativo — mismo mecanismo que `Input.invalid`, para el caso típico de un\n * checkbox obligatorio (ej. \"Acepto términos y condiciones\") sin marcar.\n *\n * <kf-checkbox label=\"Aceptar términos\" [(checked)]=\"accepted\" />\n * <kf-checkbox label=\"Seleccionar todo\" [indeterminate]=\"isPartial()\" />\n * <kf-checkbox label=\"Notificaciones\" formControlName=\"notifications\" />\n * <kf-checkbox label=\"Acepto los términos y condiciones\" [invalid]=\"submitted() && !accepted()\" />\n */\n@Component({\n selector: 'kf-checkbox',\n template: `\n <label class=\"kf-checkbox\" [class.kf-checkbox--disabled]=\"disabled()\">\n <input\n #inputRef\n type=\"checkbox\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n (change)=\"onChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span class=\"kf-checkbox__box\" [class.kf-checkbox__box--invalid]=\"invalid()\"></span>\n @if (label()) {\n <span class=\"kf-checkbox__label\">{{ label() }}</span>\n }\n </label>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-checkbox {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-sm);\n cursor: pointer;\n font: inherit;\n font-family: var(--kf-font-body);\n color: var(--kf-color-text);\n }\n .kf-checkbox--disabled {\n cursor: not-allowed;\n color: var(--kf-color-text-muted);\n }\n .kf-checkbox input {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n .kf-checkbox__box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--kf-space-md);\n height: var(--kf-space-md);\n border: 1px solid var(--kf-color-border-strong);\n border-radius: var(--kf-radius-xs);\n background: var(--kf-color-white);\n transition:\n background 0.14s,\n border-color 0.14s;\n }\n .kf-checkbox input:checked + .kf-checkbox__box,\n .kf-checkbox input:indeterminate + .kf-checkbox__box {\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n }\n .kf-checkbox input:checked + .kf-checkbox__box::after {\n content: '';\n width: 4px;\n height: 8px;\n border: solid var(--kf-color-white);\n border-width: 0 2px 2px 0;\n transform: rotate(45deg) translate(-1px, -1px);\n }\n .kf-checkbox input:indeterminate + .kf-checkbox__box::after {\n content: '';\n width: 8px;\n height: 2px;\n background: var(--kf-color-white);\n border-radius: var(--kf-radius-xs);\n }\n .kf-checkbox input:focus-visible + .kf-checkbox__box {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-checkbox__box--invalid {\n border-color: var(--kf-color-error);\n }\n .kf-checkbox--disabled .kf-checkbox__box {\n opacity: 0.5;\n }\n .kf-checkbox__label {\n user-select: none;\n }\n `,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Checkbox),\n multi: true,\n },\n ],\n})\nexport class Checkbox implements ControlValueAccessor {\n readonly label = input<string>();\n readonly checked = input(false, { transform: booleanAttribute });\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly indeterminate = input(false, { transform: booleanAttribute });\n /** Recuadro en rojo + aria-invalid — ej. checkbox obligatorio sin marcar. */\n readonly invalid = input(false, { transform: booleanAttribute });\n\n readonly checkedChange = output<boolean>();\n\n private readonly inputRef = viewChild.required<ElementRef<HTMLInputElement>>('inputRef');\n\n /** Callbacks registrados por Forms; no-op hasta que registerOnChange/Touched las reemplacen. */\n private onChangeFn: (value: boolean) => void = () => {};\n private onTouchedFn: () => void = () => {};\n\n constructor() {\n // El estado \"indeterminate\" no tiene atributo HTML: hay que empujarlo\n // como propiedad DOM cada vez que cambia el input, incluyendo el\n // valor inicial del primer render.\n effect(() => {\n this.inputRef().nativeElement.indeterminate = this.indeterminate();\n });\n }\n\n onChange(event: Event): void {\n const value = (event.target as HTMLInputElement).checked;\n this.checkedChange.emit(value);\n this.onChangeFn(value);\n }\n\n onTouched(): void {\n this.onTouchedFn();\n }\n\n writeValue(value: boolean): void {\n this.inputRef().nativeElement.checked = !!value;\n }\n\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChangeFn = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouchedFn = fn;\n }\n\n setDisabledState?(isDisabled: boolean): void {\n this.inputRef().nativeElement.disabled = isDisabled;\n }\n}\n","import { Component, input } from '@angular/core';\n\n/**\n * Chip de fondo suave con un punto líder que indica estado. Pensado\n * principalmente para celdas de tabla (estado de fila), pero utilizable\n * en cualquier lugar donde se necesite una etiqueta de estado compacta.\n *\n * <kf-chip tone=\"warn\">Pendiente</kf-chip>\n * <kf-chip tone=\"ok\">Aprobado</kf-chip>\n *\n * Nota: la spec original define la unión de tonos como \"ok\" | \"warn\" |\n * \"error\" | \"neutral\". Internamente se mapean a los tokens semánticos de\n * projects/ui/src/tokens/base.css: ok -> success, warn -> warning,\n * error -> error, neutral -> surface/border/text-muted (no existe un\n * token \"neutral\" dedicado en base.css, así que se arma con los tokens\n * de superficie/borde/texto-muted más cercanos).\n */\n@Component({\n selector: 'kf-chip',\n template: `\n <span\n class=\"kf-chip__dot\"\n [class.kf-chip__dot--ok]=\"tone() === 'ok'\"\n [class.kf-chip__dot--warn]=\"tone() === 'warn'\"\n [class.kf-chip__dot--error]=\"tone() === 'error'\"\n [class.kf-chip__dot--neutral]=\"tone() === 'neutral'\"\n ></span>\n <span class=\"kf-chip__label\"><ng-content /></span>\n `,\n styles: `\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n border: 1px solid transparent;\n font: inherit;\n font-size: 0.875em;\n line-height: 1;\n color: var(--kf-color-text);\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border);\n white-space: nowrap;\n }\n :host(.kf-chip--ok) {\n background: var(--kf-color-success-soft);\n border-color: var(--kf-color-success-soft);\n color: var(--kf-color-text);\n }\n :host(.kf-chip--warn) {\n background: var(--kf-color-warning-soft);\n border-color: var(--kf-color-warning-soft);\n color: var(--kf-color-text);\n }\n :host(.kf-chip--error) {\n background: var(--kf-color-error-soft);\n border-color: var(--kf-color-error-soft);\n color: var(--kf-color-text);\n }\n :host(.kf-chip--neutral) {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border);\n color: var(--kf-color-text);\n }\n .kf-chip__dot {\n inline-size: 0.5em;\n block-size: 0.5em;\n border-radius: var(--kf-radius-pill);\n flex: none;\n background: var(--kf-color-text-muted);\n }\n .kf-chip__label {\n display: inline-block;\n }\n .kf-chip__dot--ok {\n background: var(--kf-color-success);\n }\n .kf-chip__dot--warn {\n background: var(--kf-color-warning);\n }\n .kf-chip__dot--error {\n background: var(--kf-color-error);\n }\n .kf-chip__dot--neutral {\n background: var(--kf-color-text-muted);\n }\n `,\n host: {\n '[class.kf-chip--ok]': \"tone() === 'ok'\",\n '[class.kf-chip--warn]': \"tone() === 'warn'\",\n '[class.kf-chip--error]': \"tone() === 'error'\",\n '[class.kf-chip--neutral]': \"tone() === 'neutral'\",\n },\n})\nexport class Chip {\n readonly tone = input<'ok' | 'warn' | 'error' | 'neutral'>('neutral');\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Label superior compartido por todos los campos de formulario del design\n * system (páginas 11-12: Text Field, Select, Multiselect) — uppercase,\n * chico, gris, con letter-spacing amplio. El PDF fija un único tratamiento\n * (\"PATENTE O VIN\", \"SUCURSAL\", \"SUCURSALES\" usan exactamente el mismo\n * estilo), así que este componente es la única fuente de verdad: antes vivía\n * copiado por separado en `Input`, `Select`, `SelectMenu` y `MultiSelect`,\n * y dos de esas copias ya habían divergido del estilo real del PDF.\n *\n * No reemplaza al `<label>` nativo — lo envuelve, para no perder la\n * asociación de accesibilidad `for`/`id` con el control real.\n *\n * `required` agrega un asterisco visual en el tono de error, separado del\n * texto por un espacio y marcado `aria-hidden` — el estado obligatorio real\n * para lectores de pantalla lo comunica el propio control (`aria-required`\n * / `required` en el `<input>`/`<select>` asociado), no este label.\n *\n * <kf-field-label [for]=\"inputId\">Patente o VIN</kf-field-label>\n * <kf-field-label [for]=\"inputId\" required>Correo electrónico</kf-field-label>\n */\n@Component({\n selector: 'kf-field-label',\n template: `\n <label class=\"kf-field-label\" [for]=\"for()\">\n <ng-content />\n @if (required()) {\n <span class=\"kf-field-label__required\" aria-hidden=\"true\">*</span>\n }\n </label>\n `,\n styles: `\n :host {\n display: contents;\n }\n .kf-field-label {\n font-family: var(--kf-font-title);\n font-size: 0.75rem;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--kf-color-text-muted);\n }\n .kf-field-label__required {\n color: var(--kf-color-error);\n margin-inline-start: 2px;\n }\n `,\n})\nexport class FieldLabel {\n /** `id` del control asociado — se refleja como `for` en el `<label>` interno. */\n readonly for = input<string>();\n /** Muestra un asterisco visual indicando que el campo es obligatorio. */\n readonly required = input(false, { transform: booleanAttribute });\n}\n","import {\n Component,\n ElementRef,\n HostListener,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { FieldLabel } from '../field-label/FieldLabel';\n\n/** Normalized shape used internally once `options` (string[] or object[]) is resolved. */\ninterface SelectOption {\n value: string;\n label: string;\n}\n\nlet nextId = 0;\n\n/**\n * Dropdown de selección simple con panel propio — NUNCA usa el `<select>`\n * nativo del navegador. Un `<select>` real siempre delega el popup de\n * opciones al sistema operativo, y ningún CSS puede controlar cómo se ve\n * ese popup (ver el mismo problema ya resuelto en `SelectMenu`, del que\n * este componente reutiliza el patrón completo: trigger + panel flotante\n * propio, cerrado con click-afuera y Escape).\n *\n * Pensado para sets simples y cortos. Para listas más ricas o con más\n * opciones, es el mismo componente que `SelectMenu` — la diferencia es\n * solo de estilo (label uppercase, fondo gris que pasa a blanco al foco,\n * a tono con `Input`) y que acepta `options` como `string[]` además de\n * `{ value, label }[]`.\n *\n * <kf-select label=\"Sede\" [options]=\"['Lima', 'Arequipa', 'Trujillo']\" placeholder=\"Selecciona…\" />\n * <kf-select [options]=\"[{ value: 'pe', label: 'Perú' }]\" (valueChange)=\"onCountry($event)\" />\n */\n@Component({\n selector: 'kf-select',\n imports: [FieldLabel],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n }\n <button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-select__trigger\"\n [class.kf-select__trigger--disabled]=\"disabled()\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n >\n <span class=\"kf-select__value\" [class.kf-select__value--placeholder]=\"!selectedOption()\">\n {{ selectedOption()?.label ?? placeholder() }}\n </span>\n <span\n class=\"kf-select__caret\"\n [class.kf-select__caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n </button>\n @if (isOpen()) {\n <ul\n class=\"kf-select__panel\"\n [id]=\"listboxId\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @for (option of normalizedOptions(); track option.value) {\n <li\n class=\"kf-select__option\"\n [class.kf-select__option--selected]=\"option.value === value()\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"option.value === value()\"\n (click)=\"select(option)\"\n (keydown.enter)=\"select(option)\"\n (keydown.space)=\"$event.preventDefault(); select(option)\"\n >\n {{ option.label }}\n </li>\n } @empty {\n <li class=\"kf-select__empty\">Sin opciones disponibles</li>\n }\n </ul>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n position: relative;\n font-family: var(--kf-font-body);\n }\n .kf-select__trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n width: 100%;\n font: inherit;\n color: var(--kf-color-text);\n padding: var(--kf-space-sm) var(--kf-space-md);\n /* Mismo fondo blanco que kf-select-menu: ambos aparecen lado a lado\n en un mismo formulario (ej. Sede + País), y el gris de kf-input no\n se distingue como \"campo de texto\" en un trigger de panel — solo\n se ve como una inconsistencia de color entre dos selects. */\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-select__trigger:hover:not(:disabled) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-select__trigger:focus-visible {\n outline: none;\n border-color: var(--kf-color-primary);\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-select__trigger--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-select__value {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .kf-select__value--placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-select__caret {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-text-muted);\n border-bottom: 2px solid var(--kf-color-text-muted);\n transform: rotate(45deg);\n transition: transform 0.14s;\n margin-top: -4px;\n }\n .kf-select__caret--open {\n transform: rotate(-135deg);\n margin-top: 4px;\n }\n .kf-select__panel {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 10;\n margin: var(--kf-space-xs) 0 0;\n padding: var(--kf-space-xs) 0;\n list-style: none;\n max-height: 240px;\n overflow-y: auto;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-md);\n }\n .kf-select__option {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-select__option:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-select__option--selected {\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n font-weight: 600;\n }\n .kf-select__empty {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class Select {\n readonly label = input<string>();\n readonly options = input.required<string[] | SelectOption[]>();\n readonly value = input<string>();\n readonly placeholder = input<string>('Seleccionar');\n readonly disabled = input(false, { transform: booleanAttribute });\n\n readonly valueChange = output<string>();\n\n private readonly instanceId = `kf-select-${nextId++}`;\n readonly triggerId = `${this.instanceId}-trigger`;\n readonly listboxId = `${this.instanceId}-listbox`;\n\n readonly isOpen = signal(false);\n\n /** Resolves the union (`string[] | { value; label }[]`) into a single shape for the template. */\n readonly normalizedOptions = computed<SelectOption[]>(() =>\n this.options().map((option) =>\n typeof option === 'string' ? { value: option, label: option } : option,\n ),\n );\n\n readonly selectedOption = computed(() =>\n this.normalizedOptions().find((option) => option.value === this.value()),\n );\n\n private readonly host = inject(ElementRef<HTMLElement>);\n\n toggle(): void {\n if (this.disabled()) {\n return;\n }\n this.isOpen.update((open) => !open);\n }\n\n select(option: SelectOption): void {\n this.isOpen.set(false);\n if (option.value !== this.value()) {\n this.valueChange.emit(option.value);\n }\n }\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(event: MouseEvent): void {\n if (this.isOpen() && !this.host.nativeElement.contains(event.target as Node)) {\n this.isOpen.set(false);\n }\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n this.isOpen.set(false);\n }\n}\n","import { Component, input, output } from '@angular/core';\nimport { Select } from '../select/Select';\n\n/** Metadato clave mostrado junto al selector (RUC, identificación, sucursal). */\nexport interface CompanySelectorMeta {\n label: string;\n value: string;\n}\n\n/**\n * Conmutador de empresa activa con metadatos clave (página 32) — encabeza\n * la pantalla de inicio del portal. Compone `kf-select` para el propio\n * selector (mismo panel propio, sin `<select>` nativo) y proyecta hasta 3\n * pares label/valor (RUC, Identificación, Sucursal en el ejemplo del PDF).\n *\n * <kf-company-selector\n * label=\"Selecciona empresa\"\n * [companies]=\"['TRANSPORTES DEL SUR S.A.C.', 'ANDES MAQ LTDA.']\"\n * [value]=\"activeCompany()\"\n * (valueChange)=\"activeCompany.set($event)\"\n * [meta]=\"[\n * { label: 'RUC', value: '20448712359' },\n * { label: 'Identificación', value: '0004002232' },\n * { label: 'Sucursal', value: 'Sucursal Norte' },\n * ]\"\n * />\n */\n@Component({\n selector: 'kf-company-selector',\n imports: [Select],\n template: `\n <kf-select\n class=\"kf-company-selector__select\"\n [label]=\"label()\"\n [options]=\"companies()\"\n [value]=\"value()\"\n (valueChange)=\"valueChange.emit($event)\"\n />\n @if (meta().length) {\n <div class=\"kf-company-selector__meta\">\n @for (item of meta(); track item.label) {\n <div class=\"kf-company-selector__meta-item\">\n <span class=\"kf-company-selector__meta-label\">{{ item.label }}</span>\n <span class=\"kf-company-selector__meta-value\">{{ item.value }}</span>\n </div>\n }\n </div>\n }\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-lg);\n flex-wrap: wrap;\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-company-selector__select {\n flex: 1 1 260px;\n min-width: 0;\n }\n .kf-company-selector__meta {\n display: flex;\n gap: var(--kf-space-lg);\n flex-wrap: wrap;\n }\n .kf-company-selector__meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n .kf-company-selector__meta-label {\n font-family: var(--kf-font-title);\n font-size: 0.72rem;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--kf-color-text-muted);\n }\n .kf-company-selector__meta-value {\n font-family: var(--kf-font-mono);\n font-size: 0.875rem;\n color: var(--kf-color-ink);\n }\n `,\n})\nexport class CompanySelector {\n readonly label = input('Selecciona empresa');\n readonly companies = input.required<string[]>();\n readonly value = input<string>();\n readonly meta = input<CompanySelectorMeta[]>([]);\n\n readonly valueChange = output<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Marcador genérico para contenido aún por definir (página 38) — comunica\n * \"contenido disponible para uso\" sin parecer un error, a diferencia de\n * `kf-empty-state` (que comunica ausencia real de datos del usuario).\n * Pensado para secciones del portal que un negocio todavía no completó.\n *\n * `compact` reduce el tamaño de la imagen placeholder y omite el badge de\n * pie (segunda variante de la página 38, sin la etiqueta \"Contenido\n * disponible para uso\" al final).\n *\n * <kf-content-slot title=\"Contenido disponible\"\n * description=\"Espacio reservado para contenido de Divemotor Perú. Disponible para uso.\" />\n * <kf-content-slot compact icon=\"star\" title=\"Contenido disponible\"\n * description=\"Espacio reservado para contenido de Divemotor Perú.\" />\n */\n@Component({\n selector: 'kf-content-slot',\n imports: [Icon],\n template: `\n <div class=\"kf-content-slot__media\">\n <kf-icon [name]=\"icon()\" [size]=\"compact() ? 'md' : 'lg'\" />\n </div>\n <span class=\"kf-content-slot__title\">{{ title() }}</span>\n @if (description()) {\n <p class=\"kf-content-slot__description\">{{ description() }}</p>\n }\n @if (!compact()) {\n <span class=\"kf-content-slot__footer\">Contenido disponible para uso</span>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-content-slot__media {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 96px;\n margin-bottom: var(--kf-space-xs);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-surface);\n color: var(--kf-color-border-strong);\n }\n :host(.kf-content-slot--compact) .kf-content-slot__media {\n height: 56px;\n }\n .kf-content-slot__title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-content-slot__description {\n margin: 0;\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-content-slot__footer {\n align-self: flex-start;\n margin-top: var(--kf-space-xs);\n padding: 2px var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-surface);\n color: var(--kf-color-text-muted);\n font-size: 0.72rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n `,\n host: {\n '[class.kf-content-slot--compact]': 'compact()',\n },\n})\nexport class ContentSlot {\n readonly title = input('Contenido disponible');\n readonly description = input<string>();\n readonly icon = input<IconName>('layers');\n readonly compact = input(false, { transform: booleanAttribute });\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Placeholder para una sección sin contenido. Dos tonos, con anatomía\n * distinta (páginas 27-28 del design system, que los trata como piezas\n * separadas — \"Error State\" no es una variante de color de \"Empty State\",\n * es un estado semánticamente distinto):\n *\n * - `neutral` (default): \"cero resultados\" — cuadro con borde punteado\n * discreto, para listas vacías o búsquedas sin coincidencias. No es un\n * error, es la ausencia normal de datos.\n * - `error`: fallo real de carga — sin borde punteado, con un ícono de\n * alerta más prominente y texto en el tono de error. Pensado para usarse\n * junto a un botón \"Reintentar\" en el slot por defecto.\n *\n * <kf-empty-state>No se encontraron resultados.</kf-empty-state>\n * <kf-empty-state icon=\"search\">Sin coincidencias para tu búsqueda.</kf-empty-state>\n * <kf-empty-state tone=\"error\" icon=\"alert-triangle\">\n * No pudimos cargar tus vehículos\n * <kf-button (click)=\"retry()\">Reintentar</kf-button>\n * </kf-empty-state>\n */\n@Component({\n selector: 'kf-empty-state',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <span class=\"kf-empty-state__icon\">\n <kf-icon [name]=\"iconName\" [size]=\"tone() === 'error' ? 'lg' : 'md'\" />\n </span>\n }\n <div class=\"kf-empty-state__content\">\n <ng-content />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-xl);\n border: 1px dashed var(--kf-color-border-strong);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-surface);\n color: var(--kf-color-text-muted);\n font: inherit;\n text-align: center;\n }\n :host(.kf-empty-state--error) {\n border: none;\n background: var(--kf-color-error-soft);\n }\n .kf-empty-state__content {\n color: var(--kf-color-text-muted);\n font-family: var(--kf-font-body);\n }\n :host(.kf-empty-state--error) .kf-empty-state__content {\n color: var(--kf-color-error-strong);\n }\n `,\n host: {\n '[class.kf-empty-state--error]': \"tone() === 'error'\",\n },\n})\nexport class EmptyState {\n readonly icon = input<IconName | undefined>(undefined);\n /** `neutral` (default): cero resultados. `error`: fallo real de carga. */\n readonly tone = input<'neutral' | 'error'>('neutral');\n}\n","import { Component, input } from '@angular/core';\n\n/** Forma del placeholder. */\nexport type SkeletonVariant = 'text' | 'circle' | 'rect';\n\n/**\n * Bloque placeholder con shimmer para contenido que todavía carga: una línea\n * de texto, un avatar o un área de card/imagen, según `variant`.\n *\n * Es decorativo (`aria-hidden`): quien lo usa debería marcar el contenedor con\n * `aria-busy=\"true\"` mientras carga, así el lector de pantalla anuncia el\n * estado una vez en vez de leer N placeholders vacíos.\n *\n * `circle` usa `aspect-ratio`, así que alcanza con darle `width`.\n *\n * <kf-skeleton />\n * <kf-skeleton variant=\"circle\" width=\"40px\" />\n * <kf-skeleton variant=\"rect\" width=\"100%\" height=\"120px\" />\n */\n@Component({\n selector: 'kf-skeleton',\n template: `\n <span\n class=\"kf-skeleton\"\n [class]=\"'kf-skeleton--' + variant()\"\n aria-hidden=\"true\"\n [style.width]=\"width()\"\n [style.height]=\"height() || null\"\n ></span>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-skeleton {\n display: block;\n background: linear-gradient(\n 90deg,\n var(--kf-color-border) 25%,\n var(--kf-color-surface) 37%,\n var(--kf-color-border) 63%\n );\n background-size: 400% 100%;\n animation: kf-skeleton-shimmer 1.4s ease infinite;\n }\n .kf-skeleton--text {\n height: 14px;\n border-radius: var(--kf-radius-xs);\n }\n .kf-skeleton--rect {\n height: 80px;\n border-radius: var(--kf-radius-sm);\n }\n .kf-skeleton--circle {\n aspect-ratio: 1 / 1;\n border-radius: var(--kf-radius-pill);\n }\n @keyframes kf-skeleton-shimmer {\n from {\n background-position: 100% 0;\n }\n to {\n background-position: 0 0;\n }\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-skeleton {\n animation: none;\n background: var(--kf-color-border);\n }\n }\n `,\n})\nexport class Skeleton {\n readonly variant = input<SkeletonVariant>('text');\n /** Ancho CSS. Default `'100%'`. */\n readonly width = input('100%');\n /** Alto CSS. Vacío deja el alto/aspect-ratio propio de la variante. */\n readonly height = input('');\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\nexport type SpinnerSize = 'sm' | 'md' | 'lg';\n\n/**\n * Indicador de carga indeterminado: inline, dentro de un botón, o como único\n * contenido de una sección mientras llega la data.\n *\n * Cuando se conoce la forma del contenido que viene, preferir `kf-skeleton`\n * (dibuja la silueta). El spinner es para \"algo está pasando\" sin forma\n * conocida — guardar, enviar, reintentar.\n *\n * Lleva `role=\"status\"`, así que el lector de pantalla anuncia el `label`\n * cuando aparece. Sin `label` cae en un texto accesible por defecto.\n *\n * <kf-spinner />\n * <kf-spinner size=\"sm\" label=\"Cargando…\" />\n * <kf-spinner onDark />\n */\n@Component({\n selector: 'kf-spinner',\n template: `\n <span class=\"kf-spinner\" [class.kf-spinner--on-dark]=\"onDark()\" role=\"status\">\n <span class=\"kf-spinner__ring\" [class]=\"'kf-spinner__ring--' + size()\"></span>\n @if (label()) {\n <span class=\"kf-spinner__label\">{{ label() }}</span>\n } @else {\n <span class=\"kf-spinner__sr\">Cargando</span>\n }\n </span>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-spinner {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-sm);\n font-family: var(--kf-font-body);\n }\n .kf-spinner__ring {\n display: inline-block;\n flex: none;\n border-radius: var(--kf-radius-pill);\n border: 2px solid var(--kf-color-border);\n border-top-color: var(--kf-color-primary);\n animation: kf-spinner-turn 0.7s linear infinite;\n }\n .kf-spinner__ring--sm {\n width: 16px;\n height: 16px;\n }\n .kf-spinner__ring--md {\n width: 24px;\n height: 24px;\n border-width: 3px;\n }\n .kf-spinner__ring--lg {\n width: 32px;\n height: 32px;\n border-width: 3px;\n }\n .kf-spinner__label {\n font-size: 0.875rem;\n color: var(--kf-color-text-muted);\n }\n /* Sobre superficies oscuras (carousel, feature card, barra de admin). */\n .kf-spinner--on-dark .kf-spinner__ring {\n border-color: rgba(255, 255, 255, 0.28);\n border-top-color: var(--kf-color-white);\n }\n .kf-spinner--on-dark .kf-spinner__label {\n color: var(--kf-color-white);\n }\n @keyframes kf-spinner-turn {\n to {\n transform: rotate(360deg);\n }\n }\n .kf-spinner__sr {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-spinner__ring {\n animation-duration: 2s;\n }\n }\n `,\n})\nexport class Spinner {\n readonly size = input<SpinnerSize>('md');\n /** Texto al lado del anillo. Vacío deja solo el anillo (y el texto para lectores). */\n readonly label = input('');\n /** Invierte los colores para fondos oscuros. */\n readonly onDark = input(false, { transform: booleanAttribute });\n}\n","import { Component, input } from '@angular/core';\nimport { EmptyState } from '../empty-state/EmptyState';\nimport { Skeleton } from '../skeleton/Skeleton';\nimport { Spinner } from '../spinner/Spinner';\n\n/** En qué estado está la sección. */\nexport type ContentStateKind = 'ready' | 'loading' | 'empty' | 'error';\n\n/** Cómo se dibuja `loading`. Default `'skeleton'`. */\nexport type ContentStateLoad = 'skeleton' | 'spinner';\n\n/**\n * Wrapper de los cuatro estados que toda sección tiene: cargando, con datos,\n * vacía y con error. Un componente en vez de tres `@if` sueltos, porque es\n * siempre el mismo slot el que va rotando entre los cuatro.\n *\n * Con `state=\"ready\"` proyecta el contenido real y desaparece; en los otros\n * tres dibuja el placeholder correspondiente y el contenido no se instancia.\n * No inventa visuales propios: `loading` usa `kf-skeleton` (o `kf-spinner` con\n * `load=\"spinner\"`), y `empty`/`error` usan `kf-empty-state`.\n *\n * Las acciones (reintentar, crear) van en el slot `actions` — se ignoran\n * mientras carga, porque no hay nada que reintentar todavía.\n *\n * <kf-content-state [state]=\"state()\" title=\"No pudimos cargar tus vehículos\"\n * subtitle=\"Revisá tu conexión e intentá de nuevo.\">\n * <kf-button actions (click)=\"retry()\">Reintentar</kf-button>\n * <kf-data-table [columns]=\"cols\" [rows]=\"rows()\" />\n * </kf-content-state>\n */\n@Component({\n selector: 'kf-content-state',\n imports: [EmptyState, Skeleton, Spinner],\n template: `\n @switch (state()) {\n @case ('ready') {\n <ng-content />\n }\n @case ('loading') {\n <div class=\"kf-content-state__loading\" aria-busy=\"true\">\n @if (load() === 'spinner') {\n <kf-spinner [label]=\"loadingLabel()\" />\n } @else {\n <kf-skeleton />\n <kf-skeleton width=\"80%\" />\n <kf-skeleton width=\"60%\" />\n }\n </div>\n }\n @default {\n <kf-empty-state [tone]=\"state() === 'error' ? 'error' : 'neutral'\">\n @if (title()) {\n <p class=\"kf-content-state__title\">{{ title() }}</p>\n }\n @if (subtitle()) {\n <p class=\"kf-content-state__subtitle\">{{ subtitle() }}</p>\n }\n <div class=\"kf-content-state__actions\"><ng-content select=\"[actions]\" /></div>\n </kf-empty-state>\n }\n }\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-content-state__loading {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-sm);\n }\n .kf-content-state__title {\n margin: 0;\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-content-state__subtitle {\n margin: 0;\n color: var(--kf-color-text-muted);\n }\n .kf-content-state__actions:empty {\n display: none;\n }\n .kf-content-state__actions {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n gap: var(--kf-space-sm);\n margin-top: var(--kf-space-sm);\n }\n `,\n})\nexport class ContentState {\n readonly state = input.required<ContentStateKind>();\n /** Forma del estado de carga: silueta (default) o spinner. */\n readonly load = input<ContentStateLoad>('skeleton');\n /** Título de `empty`/`error`. Ignorado mientras carga. */\n readonly title = input('');\n readonly subtitle = input('');\n /** Texto al lado del spinner cuando `load=\"spinner\"`. */\n readonly loadingLabel = input('Cargando…');\n}\n","import { Component, computed, input, output, signal, TemplateRef } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\n\n/**\n * Zona que ocupa la columna en la vista de cards. La vista de tabla ignora\n * esto (salvo `media`, que igual se rinde como thumbnail en vez de imprimir\n * la URL):\n * - `media`: thumbnail a la izquierda del encabezado; el valor de la celda se\n * usa como `src` salvo que la columna traiga su `cellTemplates`.\n * - `title`: título del encabezado (ej. la patente/unidad).\n * - `status`: chip/estado al lado del título.\n * - `field` (default): par label/valor en el cuerpo.\n * - `action`: va al pie, separado del cuerpo por una línea.\n */\nexport type DataTableCardRole = 'media' | 'title' | 'status' | 'field' | 'action';\n\nexport interface DataTableColumn {\n key: string;\n label: string;\n right?: boolean;\n className?: string;\n cardRole?: DataTableCardRole;\n}\n\n/** Vistas disponibles cuando `cardable` está activo. */\nexport type DataTableView = 'table' | 'cards';\n\n/**\n * Tabla estandarizada con soporte opcional de toggle tabla/cards.\n *\n * El \"render\" custom por columna de la spec original (una función que\n * devuelve JSX) se resuelve acá de dos formas, de la más simple a la más\n * flexible:\n * - `render`: función `(row) => string` para el caso típico de mostrar un\n * valor derivado/formateado de la fila como texto plano.\n * - `cellTemplates`: mapa `key -> TemplateRef` para cuando un consumidor\n * necesita marcado real dentro de una celda (badges, links, botones). Se\n * proyecta con `ngTemplateOutlet` y recibe `{ $implicit: row, index }`.\n * Se eligió esta combinación en vez de content-projection por columna\n * (ng-content con selector) porque las columnas son dinámicas (vienen de\n * `columns()`), y `ngTemplateOutlet` es el mecanismo estándar de Angular\n * para \"insertar esta plantilla por cada fila de este array\".\n *\n * En la vista de cards, `cardRole` por columna reparte el contenido en zonas\n * — encabezado (thumbnail + título + estado), cuerpo (pares label/valor) y\n * pie separado por una línea para las acciones. Sin `cardRole`, todas las\n * columnas caen en el cuerpo, igual que antes.\n *\n * El modo `cards` no depende de un componente ViewToggle separado: expone\n * un control de segmentos mínimo inline (mismo patrón visual que\n * kf-segmented) para no acoplarse a un componente que otro agente puede\n * estar construyendo en paralelo — ver nota en el resumen de la tarea.\n *\n * <kf-data-table [columns]=\"columns\" [rows]=\"rows\" (rowClick)=\"onRowClick($event)\">\n * <kf-empty-state empty>No hay resultados para mostrar.</kf-empty-state>\n * </kf-data-table>\n *\n * <kf-data-table [columns]=\"columns\" [rows]=\"rows\" [cardable]=\"true\" defaultView=\"cards\" />\n *\n * El slot `[footer]` (página 15: \"slot de pie para paginación\") va siempre\n * al final, en ambas vistas, separado por una línea — pensado para proyectar\n * `<kf-pagination>`, que sigue siendo un componente independiente.\n *\n * <kf-data-table [columns]=\"columns\" [rows]=\"rows\">\n * <kf-pagination footer [page]=\"page()\" [total]=\"total()\" (pageChange)=\"page.set($event)\" />\n * </kf-data-table>\n */\n@Component({\n selector: 'kf-data-table',\n imports: [NgTemplateOutlet],\n template: `\n <div class=\"kf-data-table\" [class.kf-data-table--flush]=\"flush()\">\n @if (cardable()) {\n <div class=\"kf-data-table__toolbar\">\n <div class=\"kf-data-table__view-toggle\" role=\"group\" aria-label=\"Cambiar vista\">\n <button\n type=\"button\"\n class=\"kf-data-table__view-option\"\n [class.kf-data-table__view-option--active]=\"view() === 'table'\"\n [attr.aria-pressed]=\"view() === 'table'\"\n (click)=\"setView('table')\"\n >\n Tabla\n </button>\n <button\n type=\"button\"\n class=\"kf-data-table__view-option\"\n [class.kf-data-table__view-option--active]=\"view() === 'cards'\"\n [attr.aria-pressed]=\"view() === 'cards'\"\n (click)=\"setView('cards')\"\n >\n Tarjetas\n </button>\n </div>\n </div>\n }\n\n @if (rows().length === 0) {\n <div class=\"kf-data-table__empty\">\n <ng-content select=\"[empty]\" />\n </div>\n } @else if (view() === 'table') {\n <div class=\"kf-data-table__scroll\">\n <table class=\"kf-data-table__table\">\n <thead>\n <tr>\n @for (column of columns(); track column.key) {\n <th [class]=\"column.className\" [class.kf-data-table__cell--right]=\"column.right\">\n {{ column.label }}\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track trackRow(row, $index); let i = $index) {\n <tr\n class=\"kf-data-table__row\"\n tabindex=\"0\"\n (click)=\"onRowClick(row, i)\"\n (keydown.enter)=\"onRowClick(row, i)\"\n >\n @for (column of columns(); track column.key) {\n <td\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"column.right\"\n >\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else if (column.cardRole === 'media') {\n <img class=\"kf-data-table__thumb\" [src]=\"cellValue(row, column)\" alt=\"\" />\n } @else {\n {{ cellValue(row, column) }}\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n } @else {\n <div class=\"kf-data-table__cards\">\n @for (row of rows(); track trackRow(row, $index); let i = $index) {\n <div\n class=\"kf-data-table__card\"\n [class.kf-data-table__card--interactive]=\"cardInteractive()\"\n [attr.role]=\"cardInteractive() ? 'button' : null\"\n [attr.tabindex]=\"cardInteractive() ? 0 : null\"\n (click)=\"cardInteractive() && onRowClick(row, i)\"\n (keydown.enter)=\"cardInteractive() && onRowClick(row, i)\"\n >\n @if (cardMediaColumn() || cardTitleColumn() || cardStatusColumns().length) {\n <div class=\"kf-data-table__card-header\">\n @if (cardMediaColumn(); as media) {\n <div class=\"kf-data-table__card-media\">\n @if (cellTemplates()?.[media.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n <img [src]=\"cellValue(row, media)\" alt=\"\" />\n }\n </div>\n }\n <div class=\"kf-data-table__card-heading\">\n @if (cardTitleColumn(); as title) {\n <span class=\"kf-data-table__card-title\">\n @if (cellTemplates()?.[title.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, title) }}\n }\n </span>\n }\n @if (cardStatusColumns().length) {\n <span class=\"kf-data-table__card-statuses\">\n @for (column of cardStatusColumns(); track column.key) {\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n }\n </span>\n }\n </div>\n </div>\n }\n\n @if (cardFieldColumns().length) {\n <div class=\"kf-data-table__card-fields\">\n @for (column of cardFieldColumns(); track column.key) {\n <div class=\"kf-data-table__card-field\">\n <span class=\"kf-data-table__card-label\">{{ column.label }}</span>\n <span class=\"kf-data-table__card-value\">\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n </span>\n </div>\n }\n </div>\n }\n\n @if (cardActionColumns().length) {\n <div class=\"kf-data-table__card-actions\">\n @for (column of cardActionColumns(); track column.key) {\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (rows().length > 0) {\n <div class=\"kf-data-table__footer\">\n <ng-content select=\"[footer]\" />\n </div>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-data-table {\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-sm);\n overflow: hidden;\n }\n .kf-data-table--flush {\n border: none;\n box-shadow: none;\n border-radius: 0;\n }\n .kf-data-table__toolbar {\n display: flex;\n justify-content: flex-end;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-bottom: 1px solid var(--kf-color-border);\n }\n .kf-data-table__view-toggle {\n display: inline-flex;\n gap: 2px;\n padding: 2px;\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n }\n .kf-data-table__view-option {\n font: inherit;\n font-size: 0.875em;\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border: none;\n background: transparent;\n color: var(--kf-color-text-muted);\n border-radius: var(--kf-radius-xs);\n cursor: pointer;\n transition:\n background 0.14s,\n color 0.14s;\n }\n .kf-data-table__view-option:hover:not(.kf-data-table__view-option--active) {\n color: var(--kf-color-text);\n }\n .kf-data-table__view-option--active {\n background: var(--kf-color-white);\n color: var(--kf-color-ink);\n box-shadow: var(--kf-shadow-xs);\n }\n .kf-data-table__view-option:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n\n .kf-data-table__scroll {\n overflow-x: auto;\n }\n .kf-data-table__table {\n width: 100%;\n border-collapse: collapse;\n text-align: left;\n }\n .kf-data-table__table th,\n .kf-data-table__table td {\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-bottom: 1px solid var(--kf-color-border);\n white-space: nowrap;\n }\n .kf-data-table__table th {\n font-family: var(--kf-font-title);\n font-size: 0.8125em;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n color: var(--kf-color-text-muted);\n background: var(--kf-color-surface);\n }\n .kf-data-table__table td {\n color: var(--kf-color-text);\n }\n .kf-data-table__table tbody tr:last-child td {\n border-bottom: none;\n }\n .kf-data-table__row {\n cursor: pointer;\n transition: background 0.14s;\n }\n .kf-data-table__row:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-data-table__cell--right {\n text-align: right;\n }\n\n .kf-data-table__empty {\n padding: var(--kf-space-md);\n }\n\n .kf-data-table__footer {\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-top: 1px solid var(--kf-color-border);\n }\n .kf-data-table__footer:empty {\n display: none;\n }\n\n .kf-data-table__cards {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));\n gap: var(--kf-space-md);\n padding: var(--kf-space-md);\n }\n .kf-data-table__card {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n overflow: hidden;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-data-table__card--interactive {\n cursor: pointer;\n }\n .kf-data-table__card:hover {\n border-color: var(--kf-color-border-strong);\n box-shadow: var(--kf-shadow-xs);\n }\n .kf-data-table__card--interactive:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n\n .kf-data-table__card-header {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-md);\n }\n .kf-data-table__card-media {\n flex: none;\n }\n .kf-data-table__card-media img,\n .kf-data-table__thumb {\n display: block;\n width: 48px;\n height: 48px;\n border-radius: var(--kf-radius-xs);\n object-fit: cover;\n background: var(--kf-color-surface);\n }\n .kf-data-table__card-heading {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n min-width: 0;\n }\n .kf-data-table__card-title {\n font-family: var(--kf-font-title);\n font-weight: 600;\n color: var(--kf-color-ink);\n overflow-wrap: anywhere;\n }\n .kf-data-table__card-statuses,\n .kf-data-table__card-actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kf-space-xs);\n }\n\n .kf-data-table__card-fields {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n }\n /* El encabezado ya aportó el padding de arriba. */\n .kf-data-table__card-header + .kf-data-table__card-fields {\n padding-top: 0;\n }\n .kf-data-table__card-field {\n display: flex;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n }\n .kf-data-table__card-actions {\n justify-content: flex-end;\n margin-top: auto;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-top: 1px solid var(--kf-color-border);\n background: var(--kf-color-surface);\n }\n\n .kf-data-table__thumb {\n width: 32px;\n height: 32px;\n }\n .kf-data-table__card-label {\n font-family: var(--kf-font-title);\n font-size: 0.8125em;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n color: var(--kf-color-text-muted);\n }\n .kf-data-table__card-value {\n color: var(--kf-color-text);\n text-align: right;\n }\n `,\n})\nexport class DataTable<T = unknown> {\n readonly columns = input.required<DataTableColumn[]>();\n readonly rows = input.required<T[]>();\n /** Default: índice de la fila dentro de `rows`. */\n readonly rowKey = input<(row: T, index: number) => string | number>();\n /** Sin borde/sombra de card — para tablas anidadas dentro de otra card. */\n readonly flush = input(false);\n /** Habilita el toggle de vista tabla/cards. */\n readonly cardable = input(false);\n readonly defaultView = input<DataTableView>('table');\n /**\n * Formateo simple de celda como texto: `(row) => string`. Para marcado\n * real (badges, links, botones) usar `cellTemplates`.\n */\n readonly render = input<(row: T) => string>();\n /** Mapa `columnKey -> TemplateRef` para celdas con contenido custom. */\n readonly cellTemplates = input<\n Record<string, TemplateRef<{ $implicit: T; index: number }>> | undefined\n >();\n\n readonly rowClick = output<{ row: T; index: number }>();\n\n private readonly internalView = signal<DataTableView | null>(null);\n\n /** Vista activa: la elegida por el usuario, o `defaultView` si no tocó el toggle. */\n readonly view = computed<DataTableView>(() => this.internalView() ?? this.defaultView());\n\n /** Primera columna de cada rol único; el resto se ignora en el encabezado. */\n readonly cardMediaColumn = computed(() => this.columns().find((c) => c.cardRole === 'media'));\n readonly cardTitleColumn = computed(() => this.columns().find((c) => c.cardRole === 'title'));\n readonly cardStatusColumns = computed(() =>\n this.columns().filter((c) => c.cardRole === 'status'),\n );\n readonly cardActionColumns = computed(() =>\n this.columns().filter((c) => c.cardRole === 'action'),\n );\n readonly cardFieldColumns = computed(() =>\n this.columns().filter((c) => !c.cardRole || c.cardRole === 'field'),\n );\n\n /**\n * La card entera es clickeable solo si no tiene acciones propias: un\n * `role=\"button\"` con botones adentro es inválido y deja el foco ambiguo.\n * Con columnas `action`, la interacción la manejan esos botones.\n */\n readonly cardInteractive = computed(() => this.cardActionColumns().length === 0);\n\n setView(next: DataTableView): void {\n this.internalView.set(next);\n }\n\n trackRow(row: T, index: number): string | number {\n const keyFn = this.rowKey();\n return keyFn ? keyFn(row, index) : index;\n }\n\n cellValue(row: T, column: DataTableColumn): string {\n const renderFn = this.render();\n if (renderFn) {\n return renderFn(row);\n }\n const value = (row as Record<string, unknown>)[column.key];\n return value === null || value === undefined ? '' : String(value);\n }\n\n onRowClick(row: T, index: number): void {\n this.rowClick.emit({ row, index });\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Bloque promocional sobre fondo oscuro de marca (página 37) — campañas,\n * accesos directos o el portal de autoatención. Usa `--kf-color-tertiary-deep`\n * como base del degradado, el mismo azul profundo que el slide destacado de\n * `kf-carousel` y la barra de `kf-portal-header`.\n *\n * <kf-feature-card badge=\"Autoatención\" badgeIcon=\"tool\" title=\"Portal de Autoatención\"\n * description=\"Con tu patente o VIN accede a soluciones para tu vehículo: mantenciones, repuestos y conectividad en un solo lugar.\"\n * actionLabel=\"Ir al portal\" actionHref=\"/autoatencion\" />\n */\n@Component({\n selector: 'kf-feature-card',\n imports: [Icon],\n template: `\n @if (badge()) {\n <span class=\"kf-feature-card__badge\">\n @if (badgeIcon(); as iconName) {\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n }\n {{ badge() }}\n </span>\n }\n <span class=\"kf-feature-card__title\">{{ title() }}</span>\n @if (description()) {\n <p class=\"kf-feature-card__description\">{{ description() }}</p>\n }\n @if (actionLabel()) {\n <a class=\"kf-feature-card__action\" [href]=\"actionHref() || '#'\">\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n {{ actionLabel() }}\n </a>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-lg);\n border-radius: var(--kf-radius-md);\n background: linear-gradient(\n 135deg,\n var(--kf-color-primary-active) 0%,\n var(--kf-color-tertiary-deep) 100%\n );\n color: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-feature-card__badge {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n background: rgba(255, 255, 255, 0.12);\n border: 1px solid rgba(255, 255, 255, 0.24);\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n }\n .kf-feature-card__title {\n font-family: var(--kf-font-title);\n font-size: 1.375rem;\n font-weight: 700;\n line-height: 1.2;\n }\n .kf-feature-card__description {\n margin: 0;\n max-width: 48ch;\n color: rgba(255, 255, 255, 0.8);\n font-size: 0.9375rem;\n }\n .kf-feature-card__action {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n margin-top: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-md);\n border-radius: var(--kf-radius-sm);\n background: rgba(255, 255, 255, 0.14);\n color: var(--kf-color-white);\n font-size: 0.875rem;\n font-weight: 600;\n text-decoration: none;\n transition: background 0.14s;\n }\n .kf-feature-card__action:hover {\n background: rgba(255, 255, 255, 0.22);\n }\n `,\n})\nexport class FeatureCard {\n readonly badge = input<string>();\n readonly badgeIcon = input<IconName>();\n readonly title = input.required<string>();\n readonly description = input<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Chip de solo-lectura inline (label/valor) dentro de una caja bordeada.\n * Se usa en barras de filtro y filas de resumen para mostrar información,\n * NO para entrada de datos — para eso existe `Input`.\n *\n * El valor admite dos formas, igual que en el design system de referencia:\n * - `value` (string): caso simple, ej. `[value]=\"'Jul 2026'\"`.\n * - contenido proyectado (`<ng-content>`): cuando se necesita algo más rico\n * que un string (un badge, texto con formato, etc.).\n * `value` tiene prioridad cuando está definido; si no se pasa `value`, se\n * renderiza el contenido proyectado y, si tampoco hay contenido, `placeholder`.\n *\n * <kf-field icon=\"calendar\" label=\"Periodo\" value=\"Jul 2026\" [select]=\"true\" />\n * <kf-field label=\"Sucursal\"><strong>Casa Central</strong></kf-field>\n */\n@Component({\n selector: 'kf-field',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-field__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n @if (label()) {\n <span class=\"kf-field__label\">{{ label() }}</span>\n }\n <span class=\"kf-field__value\">\n @if (value()) {\n {{ value() }}\n } @else {\n <ng-content></ng-content>\n @if (isPlaceholderVisible()) {\n <span class=\"kf-field__placeholder\">{{ placeholder() }}</span>\n }\n }\n </span>\n @if (select()) {\n <kf-icon class=\"kf-field__chevron\" name=\"chevron-down\" size=\"sm\" />\n }\n `,\n styles: `\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-surface);\n font: inherit;\n font-family: var(--kf-font-body);\n color: var(--kf-color-text);\n line-height: 1.2;\n }\n :host(.kf-field--select) {\n cursor: pointer;\n }\n :host(.kf-field--select:hover) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-field__icon {\n color: var(--kf-color-text-muted);\n }\n .kf-field__label {\n color: var(--kf-color-text-muted);\n white-space: nowrap;\n }\n .kf-field__value {\n font-weight: 500;\n color: var(--kf-color-ink);\n white-space: nowrap;\n }\n .kf-field__placeholder {\n color: var(--kf-color-text-muted);\n font-weight: 400;\n }\n .kf-field__chevron {\n color: var(--kf-color-text-muted);\n }\n `,\n host: {\n '[class.kf-field--select]': 'select()',\n '[attr.style]': 'style() || null',\n },\n})\nexport class Field {\n readonly label = input<string>();\n readonly value = input<string>();\n readonly icon = input<IconName>();\n readonly placeholder = input<string>();\n readonly select = input(false, { transform: booleanAttribute });\n /** Estilos inline opcionales aplicados directamente al host. */\n readonly style = input<string>();\n\n /**\n * El placeholder solo tiene sentido cuando no hay `value` ni contenido\n * proyectado. Angular no expone de forma simple si `<ng-content>` recibió\n * hijos reales, así que la regla adoptada es puramente declarativa: se\n * muestra el placeholder cuando hay texto de placeholder y no hay `value`\n * (ver comentario de clase sobre la prioridad value > proyectado > placeholder).\n */\n protected isPlaceholderVisible(): boolean {\n return !this.value() && !!this.placeholder();\n }\n}\n","import { Component, computed, input, output } from '@angular/core';\n\n/** Forma normalizada interna de cada opción, ya resuelta a value/label. */\ninterface FilterChipOption {\n value: string;\n label: string;\n}\n\n/**\n * Fila de chips tipo \"pill\" para filtros de una sola selección.\n *\n * Cada opción puede pasarse como string simple (se usa como value y label\n * a la vez) o como objeto { value, label } cuando el texto mostrado difiere\n * del valor interno.\n *\n * El chip activo se resalta con el color \"ink\" oscuro (--kf-color-ink), no\n * con el color primario de marca: así lo define el sistema de diseño de\n * referencia para este componente en particular.\n *\n * <kf-filter-chips [options]=\"['Todos', 'Activos', 'Archivados']\"\n * [value]=\"filtro\"\n * (valueChange)=\"filtro = $event\" />\n *\n * <kf-filter-chips [options]=\"[{ value: 'all', label: 'Todos' }]\"\n * [value]=\"filtro\"\n * (valueChange)=\"filtro = $event\" />\n */\n@Component({\n selector: 'kf-filter-chips',\n template: `\n <div class=\"kf-filter-chips\" role=\"group\">\n @for (option of normalizedOptions(); track option.value) {\n <button\n type=\"button\"\n class=\"kf-filter-chips__chip\"\n [class.kf-filter-chips__chip--active]=\"option.value === value()\"\n [attr.aria-pressed]=\"option.value === value()\"\n (click)=\"select(option.value)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-filter-chips {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kf-space-xs);\n }\n .kf-filter-chips__chip {\n font: inherit;\n padding: var(--kf-space-xs) var(--kf-space-md);\n border-radius: var(--kf-radius-pill);\n border: 1px solid var(--kf-color-border);\n background: var(--kf-color-surface);\n color: var(--kf-color-text);\n cursor: pointer;\n transition:\n background 0.14s,\n border-color 0.14s,\n color 0.14s;\n }\n .kf-filter-chips__chip:hover:not(.kf-filter-chips__chip--active) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-filter-chips__chip:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-filter-chips__chip--active {\n background: var(--kf-color-ink);\n border-color: var(--kf-color-ink);\n color: var(--kf-color-white);\n }\n `,\n})\nexport class FilterChips {\n readonly options = input.required<(string | { value: string; label: string })[]>();\n readonly value = input<string>('');\n\n readonly valueChange = output<string>();\n\n /** Normaliza cada opción string/objeto a la forma { value, label }. */\n readonly normalizedOptions = computed<FilterChipOption[]>(() =>\n this.options().map((option) =>\n typeof option === 'string' ? { value: option, label: option } : option,\n ),\n );\n\n select(value: string): void {\n if (value === this.value()) {\n return;\n }\n this.valueChange.emit(value);\n }\n}\n","import { Component, input, output } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\nexport interface FolderTabOption {\n value: string;\n label: string;\n icon?: IconName;\n}\n\n/**\n * Tabs con forma de \"carpeta\": el borde superior queda redondeado y el borde\n * inferior de la pestaña activa se funde visualmente con el panel de\n * contenido que va debajo (misma superficie, sin línea divisoria).\n *\n * Al cambiar de pestaña, la que se activa se \"abre\": gira sobre su borde\n * inferior (hinge 3D) y sube con un pequeño rebote. Es CSS solo: la clase\n * `--active` se mueve de un botón a otro, y eso vuelve a disparar el keyframe\n * sin tocar JS.\n *\n * El consumidor es responsable de renderizar el panel de contenido debajo;\n * este componente solo resuelve la fila de pestañas y emite `valueChange`.\n *\n * <kf-folder-tabs [options]=\"tabs\" [value]=\"active\" (valueChange)=\"active = $event\" />\n */\n@Component({\n selector: 'kf-folder-tabs',\n imports: [Icon],\n template: `\n <div class=\"kf-folder-tabs\" role=\"tablist\">\n @for (option of options(); track option.value) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"kf-folder-tabs__tab\"\n [class.kf-folder-tabs__tab--active]=\"option.value === value()\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.tabindex]=\"option.value === value() ? 0 : -1\"\n [id]=\"'kf-folder-tab-' + option.value\"\n [attr.aria-controls]=\"'kf-folder-panel-' + option.value\"\n (click)=\"select(option.value)\"\n (keydown)=\"onKeydown($event, option.value)\"\n >\n @if (option.icon; as iconName) {\n <kf-icon class=\"kf-folder-tabs__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <span class=\"kf-folder-tabs__label\">{{ option.label }}</span>\n </button>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-folder-tabs {\n display: flex;\n align-items: flex-end;\n gap: var(--kf-space-xs);\n /* Da profundidad al hinge: las pestañas giran sobre su borde inferior. */\n perspective: 900px;\n }\n .kf-folder-tabs__tab {\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n font: inherit;\n font-size: 0.9rem;\n color: var(--kf-color-text-muted);\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-bottom-color: var(--kf-color-border-strong);\n border-radius: var(--kf-radius-sm) var(--kf-radius-sm) 0 0;\n padding: var(--kf-space-sm) var(--kf-space-md);\n cursor: pointer;\n transform-origin: bottom center;\n /* Inactiva: hundida en la pila, un pelo más chica. */\n transform: translateY(5px) scale(0.985);\n transition:\n background 0.14s,\n color 0.14s,\n border-color 0.14s,\n transform 0.22s cubic-bezier(0.32, 0.72, 0, 1);\n }\n .kf-folder-tabs__tab:hover:not(.kf-folder-tabs__tab--active) {\n color: var(--kf-color-text);\n background: var(--kf-color-white);\n transform: translateY(2px) scale(0.99);\n }\n .kf-folder-tabs__tab:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n z-index: 1;\n }\n .kf-folder-tabs__tab--active {\n z-index: 1;\n color: var(--kf-color-primary);\n font-weight: 700;\n background: var(--kf-color-white);\n border-color: var(--kf-color-border);\n /* Marca el color del tema abajo (página 19 del design system) — no se\n funde con el panel: el borde queda visible y grueso, mismo trato\n que el subrayado de kf-tabs. */\n border-bottom: 2px solid var(--kf-color-primary);\n /* Sombra hacia arriba: la pestaña quedó por delante del resto. */\n box-shadow: 0 -6px 14px -10px rgba(16, 24, 40, 0.4);\n transform: translateY(1px);\n animation: kf-folder-tabs-pull 0.34s cubic-bezier(0.22, 1.2, 0.36, 1) both;\n }\n @keyframes kf-folder-tabs-pull {\n 0% {\n transform: translateY(7px) rotateX(-24deg) scale(0.95);\n }\n 60% {\n transform: translateY(-2px) rotateX(3deg) scale(1.02);\n }\n 100% {\n transform: translateY(1px) rotateX(0) scale(1);\n }\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-folder-tabs__tab,\n .kf-folder-tabs__tab--active {\n animation: none;\n transition:\n background 0.14s,\n color 0.14s,\n border-color 0.14s;\n }\n }\n `,\n})\nexport class FolderTabs {\n readonly options = input.required<FolderTabOption[]>();\n readonly value = input.required<string>();\n readonly valueChange = output<string>();\n\n select(value: string): void {\n if (value === this.value()) {\n return;\n }\n this.valueChange.emit(value);\n }\n\n /** Navegación estándar de ARIA tabs: flechas mueven el foco y activan la pestaña. */\n onKeydown(event: KeyboardEvent, currentValue: string): void {\n const items = this.options();\n const currentIndex = items.findIndex((option) => option.value === currentValue);\n\n let nextIndex: number;\n switch (event.key) {\n case 'ArrowRight':\n nextIndex = (currentIndex + 1) % items.length;\n break;\n case 'ArrowLeft':\n nextIndex = (currentIndex - 1 + items.length) % items.length;\n break;\n case 'Home':\n nextIndex = 0;\n break;\n case 'End':\n nextIndex = items.length - 1;\n break;\n default:\n return;\n }\n\n event.preventDefault();\n const nextOption = items[nextIndex];\n this.select(nextOption.value);\n\n const host = (event.currentTarget as HTMLElement).parentElement;\n const nextId = `kf-folder-tab-${nextOption.value}`;\n const nextButton = Array.from(host?.querySelectorAll<HTMLButtonElement>('button') ?? []).find(\n (button) => button.id === nextId,\n );\n nextButton?.focus();\n }\n}\n","import {\n AfterViewInit,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n forwardRef,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { FieldLabel } from '../field-label/FieldLabel';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Input de formulario apilado: label arriba (en mayúsculas vía CSS), campo con\n * fondo gris que pasa a blanco con anillo de foco azul al enfocar.\n *\n * Implementa ControlValueAccessor, así que funciona con [(ngModel)] y con\n * Reactive Forms (formControl / formControlName), no es solo un wrapper visual.\n *\n * <kf-input label=\"Placa\" icon=\"car\" placeholder=\"ABC-123\" hint=\"Formato: 3 letras + 3 números\" />\n * <input kf-input formControlName=\"email\" type=\"email\" />\n *\n * `invalid` + `errorMessage` cubren el estado de error: con `invalid` el\n * borde pasa a rojo (`--kf-color-error`) y se setea `aria-invalid=\"true\"` en\n * el `<input>` nativo; `errorMessage` reemplaza el `hint` neutro por un\n * mensaje en rojo con `role=\"alert\"`, para que un lector de pantalla lo\n * anuncie apenas aparece (a diferencia de `hint`, que es solo informativo y\n * nunca interrumpe). Si se pasan ambos, `errorMessage` tiene prioridad\n * visual sobre `hint` — no tiene sentido mostrar los dos a la vez.\n *\n * <kf-input label=\"Correo\" formControlName=\"email\"\n * [invalid]=\"email.invalid && email.touched\"\n * [errorMessage]=\"email.touched && email.hasError('required') ? 'Ingresa tu correo.' : undefined\" />\n *\n * `toggleable` solo tiene efecto cuando `type=\"password\"`: agrega un botón\n * de ojo al final del campo que alterna la visibilidad del valor tipeado\n * (cambia el `type` real del `<input>` nativo entre `password` y `text`,\n * nunca expone el valor en el DOM de otra forma). El botón es `type=\"button\"`\n * — nunca dispara submit del form contenedor — y anuncia su acción con\n * `aria-label` dinámico y `aria-pressed`, ya que es un toggle, no un botón\n * de una sola acción.\n *\n * <kf-input type=\"password\" label=\"Contraseña\" toggleable formControlName=\"password\" />\n */\n@Component({\n selector: 'kf-input',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FormsModule, FieldLabel, Icon],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Input),\n multi: true,\n },\n ],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"inputId\" [required]=\"required()\">{{ label() }}</kf-field-label>\n }\n <div\n class=\"kf-input__field\"\n [class.kf-input__field--disabled]=\"isDisabled()\"\n [class.kf-input__field--focused]=\"focused()\"\n [class.kf-input__field--invalid]=\"invalid()\"\n >\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-input__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <input\n #nativeInput\n [id]=\"inputId\"\n class=\"kf-input__control\"\n [type]=\"effectiveType()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : hint() ? hintId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [value]=\"value()\"\n (input)=\"onInput(nativeInput.value)\"\n (blur)=\"onBlur()\"\n (focus)=\"focused.set(true)\"\n />\n @if (showPasswordToggle()) {\n <button\n type=\"button\"\n class=\"kf-input__toggle\"\n [attr.aria-label]=\"passwordVisible() ? 'Ocultar contraseña' : 'Mostrar contraseña'\"\n [attr.aria-pressed]=\"passwordVisible()\"\n (click)=\"onTogglePasswordVisibility()\"\n >\n <kf-icon [name]=\"passwordVisible() ? 'eye-off' : 'eye'\" size=\"sm\" />\n </button>\n } @else if (suffix()) {\n <span class=\"kf-input__suffix\">{{ suffix() }}</span>\n }\n </div>\n @if (errorMessage(); as message) {\n <span class=\"kf-input__error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n } @else if (hint()) {\n <span class=\"kf-input__hint\" [id]=\"hintId\">{{ hint() }}</span>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n font-family: var(--kf-font-body);\n }\n .kf-input__field {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: 0 var(--kf-space-sm);\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n transition:\n background 0.14s,\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-input__field--focused {\n background: var(--kf-color-white);\n border-color: var(--kf-color-primary);\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-input__field--invalid {\n border-color: var(--kf-color-error);\n }\n .kf-input__field--invalid.kf-input__field--focused {\n box-shadow: 0 0 0 3px rgba(235, 87, 87, 0.22);\n }\n .kf-input__field--disabled {\n opacity: 0.5;\n }\n .kf-input__icon {\n color: var(--kf-color-text-muted);\n }\n .kf-input__field--invalid .kf-input__icon {\n color: var(--kf-color-error);\n }\n .kf-input__control {\n flex: 1;\n min-width: 0;\n border: none;\n outline: none;\n background: transparent;\n font: inherit;\n color: var(--kf-color-text);\n padding: var(--kf-space-sm) 0;\n }\n .kf-input__control::placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-input__control:disabled {\n cursor: not-allowed;\n }\n .kf-input__suffix {\n flex: none;\n color: var(--kf-color-text-muted);\n font-size: 0.875rem;\n }\n .kf-input__toggle {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n padding: var(--kf-space-xs);\n margin: 0 calc(var(--kf-space-xs) * -1);\n color: var(--kf-color-text-muted);\n cursor: pointer;\n border-radius: var(--kf-radius-xs);\n transition: color 0.14s;\n }\n .kf-input__toggle:hover {\n color: var(--kf-color-text);\n }\n .kf-input__toggle:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-input__hint {\n font-size: 0.75rem;\n color: var(--kf-color-text-muted);\n }\n .kf-input__error {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--kf-color-error-strong);\n }\n `,\n})\nexport class Input implements ControlValueAccessor, AfterViewInit {\n private static nextId = 0;\n\n private readonly nativeInput = viewChild.required<ElementRef<HTMLInputElement>>('nativeInput');\n\n readonly label = input<string>();\n /** Marca el label con un asterisco visual — no aplica `required` al `<input>` nativo por sí solo. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Ícono líder, renderizado vía `kf-icon`. */\n readonly icon = input<IconName>();\n readonly suffix = input<string>();\n readonly hint = input<string>();\n /** Borde y aria-invalid en rojo. Ver `errorMessage` para el mensaje asociado. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Mensaje de error con `role=\"alert\"` — reemplaza a `hint` mientras esté presente. */\n readonly errorMessage = input<string>();\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly type = input<string>('text');\n readonly placeholder = input<string>('');\n /** Agrega el botón de mostrar/ocultar — sin efecto si `type` no es `\"password\"`. */\n readonly toggleable = input(false, { transform: booleanAttribute });\n\n protected readonly inputId = `kf-input-${Input.nextId++}`;\n protected readonly hintId = `${this.inputId}-hint`;\n protected readonly errorId = `${this.inputId}-error`;\n\n protected readonly value = signal('');\n protected readonly focused = signal(false);\n /** Deshabilitado por Reactive Forms (formControl.disable()). */\n private readonly disabledByForm = signal(false);\n /** Disabled real: por input() directo o por el FormControl asociado. */\n protected readonly isDisabled = computed(() => this.disabled() || this.disabledByForm());\n\n /** Estado interno del toggle — irrelevante si `showPasswordToggle()` es false. */\n protected readonly passwordVisible = signal(false);\n /** El botón solo tiene sentido si el campo realmente es de contraseña. */\n protected readonly showPasswordToggle = computed(\n () => this.toggleable() && this.type() === 'password',\n );\n /**\n * `type` real que recibe el `<input>` nativo: igual a `type()` salvo\n * cuando el toggle está activo y visible, donde pasa a `text` para\n * mostrar el valor en claro sin cambiar `type()` en sí (evita que un\n * consumidor que lee `type()` desde afuera vea un valor inconsistente).\n */\n protected readonly effectiveType = computed(() =>\n this.showPasswordToggle() && this.passwordVisible() ? 'text' : this.type(),\n );\n\n private onChange: (value: string) => void = () => {};\n private onTouched: () => void = () => {};\n\n ngAfterViewInit(): void {\n // El binding declarativo [value]=\"value()\" no siempre re-sincroniza la\n // propiedad DOM del <input> cuando el valor llega por writeValue() antes\n // de que la vista termine de inicializarse — se refuerza escribiendo la\n // propiedad DOM directamente para que el primer valor de un formulario\n // ya cargado (ngModel/formControl con valor inicial) se refleje siempre.\n this.nativeInput().nativeElement.value = this.value();\n }\n\n writeValue(value: string): void {\n const nextValue = value ?? '';\n this.value.set(nextValue);\n // Mismo motivo que en ngAfterViewInit: escritura directa a la propiedad\n // DOM además del binding declarativo, para que cambios de valor\n // posteriores (ej. patchValue de un FormControl) siempre lleguen al\n // input nativo sin depender del timing de detección de cambios.\n const el = this.nativeInput?.();\n if (el) {\n el.nativeElement.value = nextValue;\n }\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabledByForm.set(isDisabled);\n }\n\n protected onInput(rawValue: string): void {\n this.value.set(rawValue);\n this.onChange(rawValue);\n }\n\n protected onBlur(): void {\n this.focused.set(false);\n this.onTouched();\n }\n\n /**\n * Alterna la visibilidad del valor. No dispara `onBlur`/pierde el foco:\n * el botón vive dentro del mismo `.kf-input__field`, así que un click acá\n * no debe tratarse como si el usuario hubiese abandonado el campo.\n */\n protected onTogglePasswordVisibility(): void {\n this.passwordVisible.update((visible) => !visible);\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Card } from '../card/Card';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Card de estadística/KPI: label, valor grande, ícono opcional en la esquina\n * superior derecha, badge de esquina opcional (pegado al valor) y una nota\n * al pie. Pensada para tableros de resumen (ej. \"11 Tickets abiertos\").\n *\n * Compone sobre `kf-card` en vez de duplicar su estilo de contenedor — así\n * el look de \"card\" (radio, sombra, borde) tiene una única fuente de verdad\n * en toda la librería, tal como pide el design system (página 14: \"Card...\n * es la base de paneles, tarjetas de métrica, tablas...\").\n *\n * <kf-metric-card label=\"Tickets abiertos\" value=\"11\" icon=\"ticket\" foot=\"+2 hoy\" />\n * <kf-metric-card label=\"Tasa de resolución\" value=\"94%\" badge=\"+2%\" value-color=\"var(--kf-color-success)\" />\n */\n@Component({\n selector: 'kf-metric-card',\n imports: [Card, Icon],\n template: `\n <kf-card>\n <div class=\"kf-metric-card__head\">\n <span class=\"kf-metric-card__label\">{{ label() }}</span>\n @if (icon(); as iconName) {\n <span class=\"kf-metric-card__icon\">\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n </span>\n }\n </div>\n <div class=\"kf-metric-card__value-row\">\n <div class=\"kf-metric-card__value\" [style.color]=\"valueColor()\">\n {{ value() }}\n @if (unit()) {\n <span class=\"kf-metric-card__unit\">{{ unit() }}</span>\n }\n </div>\n @if (badge()) {\n <span class=\"kf-metric-card__badge\">{{ badge() }}</span>\n }\n </div>\n @if (foot()) {\n <div class=\"kf-metric-card__foot\">{{ foot() }}</div>\n }\n </kf-card>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-metric-card__head {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--kf-space-xs);\n }\n .kf-metric-card__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n flex: none;\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n .kf-metric-card__label {\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--kf-color-text-muted);\n }\n .kf-metric-card__value-row {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n }\n .kf-metric-card__value {\n font-family: var(--kf-font-title);\n font-weight: 700;\n font-size: 1.6rem;\n line-height: 1.1;\n color: var(--kf-color-ink);\n }\n .kf-metric-card__unit {\n font-size: 0.85rem;\n font-weight: 500;\n color: var(--kf-color-text-muted);\n margin-left: var(--kf-space-xs);\n }\n .kf-metric-card__badge {\n font-size: 0.72rem;\n font-weight: 700;\n padding: 2px var(--kf-space-xs);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-success-soft);\n color: var(--kf-color-success-strong);\n }\n .kf-metric-card__foot {\n font-size: 0.78rem;\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class MetricCard {\n readonly label = input.required<string>();\n readonly value = input.required<string | number>();\n readonly unit = input<string>();\n /** Ícono en la esquina superior derecha, renderizado vía `kf-icon`. */\n readonly icon = input<IconName>();\n readonly foot = input<string>();\n /** Tinte opcional para el valor grande (ej. un color semántico de estado). */\n readonly valueColor = input<string>();\n /** Badge de esquina opcional, pegado al valor (ej. \"+2%\"). */\n readonly badge = input<string>();\n}\n","import { DOCUMENT } from '@angular/common';\nimport {\n booleanAttribute,\n Component,\n DestroyRef,\n ElementRef,\n HostListener,\n afterRenderEffect,\n inject,\n input,\n model,\n viewChild,\n} from '@angular/core';\n\nlet modalId = 0;\n\n/**\n * Diálogo centrado sobre un backdrop: confirmaciones destructivas, formularios\n * cortos, decisiones que bloquean el flujo.\n *\n * Se apoya en el `<dialog>` nativo (`showModal()`), así que el atrapado de\n * foco, el backdrop, el orden en el top-layer y el cierre con `Escape` los\n * resuelve el navegador — no hay trampa de foco escrita a mano acá. Lo único\n * que se agrega es el lock de scroll del body, que `<dialog>` no hace.\n *\n * `open` es two-way. Con `dismissible` en `false` (ej. mientras una acción\n * destructiva está en vuelo) se cancelan `Escape` y el clic en el backdrop:\n * solo cierra el consumidor poniendo `open` en `false`.\n *\n * Las acciones van en el slot `footer`.\n *\n * <kf-modal [(open)]=\"confirmOpen\" title=\"Eliminar unidad\">\n * <p>Esta acción no se puede deshacer.</p>\n * <div footer>\n * <kf-button variant=\"ghost\" (click)=\"confirmOpen.set(false)\">Cancelar</kf-button>\n * <kf-button (click)=\"remove()\">Eliminar</kf-button>\n * </div>\n * </kf-modal>\n */\n@Component({\n selector: 'kf-modal',\n template: `\n <dialog\n #dialog\n class=\"kf-modal\"\n [attr.aria-labelledby]=\"title() ? titleId : null\"\n (cancel)=\"onCancel($event)\"\n (close)=\"open.set(false)\"\n >\n @if (open()) {\n <div class=\"kf-modal__panel\">\n <div class=\"kf-modal__head\">\n @if (title()) {\n <h2 class=\"kf-modal__title\" [id]=\"titleId\">{{ title() }}</h2>\n }\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"kf-modal__close\"\n aria-label=\"Cerrar diálogo\"\n (click)=\"open.set(false)\"\n >\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M6 6l12 12M18 6L6 18\" />\n </svg>\n </button>\n }\n </div>\n <div class=\"kf-modal__body\"><ng-content /></div>\n <div class=\"kf-modal__footer\"><ng-content select=\"[footer]\" /></div>\n </div>\n }\n </dialog>\n `,\n styles: `\n .kf-modal {\n width: min(480px, calc(100vw - 2 * var(--kf-space-md)));\n max-height: calc(100vh - 2 * var(--kf-space-xl));\n padding: 0;\n border: none;\n background: transparent;\n overflow: visible;\n font-family: var(--kf-font-body);\n }\n .kf-modal::backdrop {\n background: rgba(23, 29, 37, 0.45);\n }\n .kf-modal__panel {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-md);\n padding: var(--kf-space-lg);\n background: var(--kf-color-white);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-lg);\n }\n .kf-modal__head {\n display: flex;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n }\n .kf-modal__title {\n flex: 1;\n margin: 0;\n font-family: var(--kf-font-title);\n font-size: 1.375rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-modal__close {\n flex: none;\n display: inline-flex;\n padding: 2px;\n border: none;\n background: transparent;\n color: var(--kf-color-text-muted);\n border-radius: var(--kf-radius-xs);\n cursor: pointer;\n }\n .kf-modal__close svg {\n width: 1.25em;\n height: 1.25em;\n fill: none;\n stroke: currentColor;\n stroke-width: 1.9;\n stroke-linecap: round;\n }\n .kf-modal__close:hover {\n color: var(--kf-color-ink);\n }\n .kf-modal__close:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-modal__body {\n color: var(--kf-color-text);\n overflow-y: auto;\n }\n .kf-modal__footer:empty {\n display: none;\n }\n .kf-modal__footer {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class Modal {\n readonly title = input('');\n /** Visibilidad, two-way: `[(open)]=\"confirmOpen\"`. */\n readonly open = model(false);\n /** Permite cerrar con el botón, `Escape` o clic en el backdrop. */\n readonly dismissible = input(true, { transform: booleanAttribute });\n\n protected readonly titleId = `kf-modal-title-${modalId++}`;\n\n private readonly dialog = viewChild<ElementRef<HTMLDialogElement>>('dialog');\n private readonly document = inject(DOCUMENT);\n\n constructor() {\n afterRenderEffect(() => {\n const el = this.dialog()?.nativeElement;\n if (!el) {\n return;\n }\n if (this.open() && !el.open) {\n // ponytail: `showModal` no existe en jsdom (tests) ni en entornos sin\n // top-layer; el atributo `open` lo deja visible, aunque no modal.\n if (typeof el.showModal === 'function') {\n el.showModal();\n } else {\n el.open = true;\n }\n } else if (!this.open() && el.open) {\n if (typeof el.close === 'function') {\n el.close();\n } else {\n el.open = false;\n }\n }\n // `<dialog>` inertiza el resto de la página pero no frena su scroll.\n this.document.body.style.overflow = this.open() ? 'hidden' : '';\n });\n\n inject(DestroyRef).onDestroy(() => {\n this.document.body.style.overflow = '';\n });\n }\n\n /** `Escape` dispara `cancel`; cancelarlo lo deja abierto. */\n protected onCancel(event: Event): void {\n if (!this.dismissible()) {\n event.preventDefault();\n }\n }\n\n /**\n * Clic en el backdrop. Un clic en la zona del backdrop tiene como `target` al\n * propio `<dialog>` (el contenido vive en el panel de adentro), así que basta\n * comparar contra él — no hace falta cortar la propagación en el panel.\n *\n * Va como HostListener y no como binding en el template porque un `(click)`\n * sobre el `<dialog>` dispara las reglas a11y de click-sin-teclado; acá el\n * equivalente de teclado es `Escape`, que el `<dialog>` nativo ya maneja.\n */\n @HostListener('click', ['$event'])\n protected onHostClick(event: MouseEvent): void {\n if (this.dismissible() && event.target === this.dialog()?.nativeElement) {\n this.open.set(false);\n }\n }\n}\n","import {\n Component,\n ElementRef,\n HostListener,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { FieldLabel } from '../field-label/FieldLabel';\n\nexport interface MultiSelectOption {\n value: string;\n label: string;\n}\n\nlet nextId = 0;\n\n/**\n * Dropdown de selección múltiple con checkboxes internos, siguiendo el mismo\n * patrón de panel flotante que `SelectMenu` (panel con `position: absolute`\n * sobre el host, sin Angular CDK Overlay, que no es dependencia del proyecto).\n * Se abre y cierra por click en el disparador, y se cierra al hacer click\n * afuera o al presionar Escape.\n *\n * A diferencia de `SelectMenu`, el disparador no muestra un único valor sino\n * los nombres seleccionados junto a un badge circular con el conteo (página\n * 12: \"Sucursal Norte, Lima Centro\" + badge \"2\"), y cada opción del panel se\n * marca/desmarca con un checkbox sin cerrar el panel. Incluye una opción\n * \"Todas\" al inicio de la lista, con estado `indeterminate` cuando hay\n * selección parcial — el mismo patrón de \"seleccionar todos\" de `Checkbox`.\n *\n * <kf-multi-select\n * label=\"Sucursales\"\n * [options]=\"branches\"\n * [values]=\"selectedBranches()\"\n * (valuesChange)=\"selectedBranches.set($event)\"\n * />\n *\n * Pendiente: el prop `icon` de otros componentes del design system requiere\n * un componente Icon / sprite SVG que esta librería todavía no tiene — este\n * componente no usa iconos, así que no aplica acá.\n */\n@Component({\n selector: 'kf-multi-select',\n imports: [FieldLabel],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n }\n <button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-multi-select__trigger\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n >\n <span\n class=\"kf-multi-select__value\"\n [class.kf-multi-select__value--placeholder]=\"selectedCount() === 0\"\n >\n {{ summaryText() }}\n </span>\n @if (selectedCount() > 0) {\n <span class=\"kf-multi-select__count\">{{ selectedCount() }}</span>\n }\n <span\n class=\"kf-multi-select__caret\"\n [class.kf-multi-select__caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n </button>\n @if (isOpen()) {\n <ul\n class=\"kf-multi-select__panel\"\n [id]=\"listboxId\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @if (options().length > 0) {\n <li\n class=\"kf-multi-select__option\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"allSelected()\"\n (click)=\"toggleAll()\"\n (keydown.enter)=\"toggleAll()\"\n (keydown.space)=\"$event.preventDefault(); toggleAll()\"\n >\n <span\n class=\"kf-multi-select__checkbox\"\n [class.kf-multi-select__checkbox--checked]=\"allSelected()\"\n [class.kf-multi-select__checkbox--indeterminate]=\"isPartiallySelected()\"\n ></span>\n <span class=\"kf-multi-select__option-label\">Todas</span>\n </li>\n }\n @for (option of options(); track option.value) {\n <li\n class=\"kf-multi-select__option\"\n [class.kf-multi-select__option--selected]=\"isSelected(option.value)\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"isSelected(option.value)\"\n (click)=\"toggleOption(option.value)\"\n (keydown.enter)=\"toggleOption(option.value)\"\n (keydown.space)=\"$event.preventDefault(); toggleOption(option.value)\"\n >\n <span\n class=\"kf-multi-select__checkbox\"\n [class.kf-multi-select__checkbox--checked]=\"isSelected(option.value)\"\n ></span>\n <span class=\"kf-multi-select__option-label\">{{ option.label }}</span>\n </li>\n } @empty {\n <li class=\"kf-multi-select__empty\">Sin opciones disponibles</li>\n }\n </ul>\n }\n `,\n styles: `\n :host {\n display: inline-flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n position: relative;\n font: inherit;\n min-width: 200px;\n }\n .kf-multi-select__trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n width: 100%;\n font: inherit;\n font-family: var(--kf-font-body);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n color: var(--kf-color-text);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-multi-select__trigger:hover:not(:disabled) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-multi-select__trigger:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-multi-select__trigger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-multi-select__value {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n text-align: left;\n }\n .kf-multi-select__value--placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-multi-select__count {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 1.25rem;\n height: 1.25rem;\n padding: 0 5px;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n font-size: 0.72rem;\n font-weight: 700;\n }\n .kf-multi-select__caret {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-text-muted);\n border-bottom: 2px solid var(--kf-color-text-muted);\n transform: rotate(45deg);\n transition: transform 0.14s;\n margin-top: -4px;\n }\n .kf-multi-select__caret--open {\n transform: rotate(-135deg);\n margin-top: 4px;\n }\n .kf-multi-select__panel {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 10;\n margin: var(--kf-space-xs) 0 0;\n padding: var(--kf-space-xs) 0;\n list-style: none;\n max-height: 240px;\n overflow-y: auto;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-md);\n }\n .kf-multi-select__option {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-multi-select__option:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-multi-select__option--selected {\n color: var(--kf-color-primary);\n font-weight: 600;\n }\n .kf-multi-select__checkbox {\n display: inline-flex;\n flex-shrink: 0;\n width: var(--kf-space-md);\n height: var(--kf-space-md);\n border: 1px solid var(--kf-color-border-strong);\n border-radius: var(--kf-radius-xs);\n background: var(--kf-color-white);\n transition:\n background 0.14s,\n border-color 0.14s;\n position: relative;\n }\n .kf-multi-select__checkbox--checked {\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n }\n .kf-multi-select__checkbox--checked::after {\n content: '';\n position: absolute;\n left: 4px;\n top: 1px;\n width: 4px;\n height: 8px;\n border: solid var(--kf-color-white);\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n /* \"Todas\" con selección parcial: barra horizontal, mismo patrón que Checkbox. */\n .kf-multi-select__checkbox--indeterminate {\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n }\n .kf-multi-select__checkbox--indeterminate::after {\n content: '';\n position: absolute;\n left: 3px;\n top: 6px;\n width: 8px;\n height: 2px;\n background: var(--kf-color-white);\n border: none;\n transform: none;\n }\n .kf-multi-select__option-label {\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-multi-select__empty {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class MultiSelect {\n readonly label = input<string>();\n readonly options = input<MultiSelectOption[]>([]);\n readonly values = input<string[]>([]);\n readonly placeholder = input<string>('Seleccionar');\n readonly disabled = input(false, { transform: booleanAttribute });\n\n readonly valuesChange = output<string[]>();\n\n private readonly instanceId = `kf-multi-select-${nextId++}`;\n readonly triggerId = `${this.instanceId}-trigger`;\n readonly listboxId = `${this.instanceId}-listbox`;\n\n readonly isOpen = signal(false);\n\n readonly selectedCount = computed(() => this.values().length);\n\n readonly allSelected = computed(\n () => this.options().length > 0 && this.values().length === this.options().length,\n );\n\n readonly isPartiallySelected = computed(() => this.values().length > 0 && !this.allSelected());\n\n /**\n * Texto del disparador: placeholder si no hay selección, o los nombres\n * seleccionados unidos por coma (el conteo va aparte, en el badge). Con\n * muchas opciones el `text-overflow: ellipsis` del `.kf-multi-select__value`\n * corta el texto — el badge de conteo siempre queda visible al lado.\n */\n readonly summaryText = computed(() => {\n const count = this.selectedCount();\n if (count === 0) {\n return this.placeholder();\n }\n const selectedLabels = this.values()\n .map((value) => this.options().find((option) => option.value === value)?.label)\n .filter((label): label is string => Boolean(label));\n return selectedLabels.join(', ');\n });\n\n private readonly host = inject(ElementRef<HTMLElement>);\n\n isSelected(value: string): boolean {\n return this.values().includes(value);\n }\n\n toggle(): void {\n if (this.disabled()) {\n return;\n }\n this.isOpen.update((open) => !open);\n }\n\n toggleOption(value: string): void {\n const current = this.values();\n const next = current.includes(value)\n ? current.filter((selectedValue) => selectedValue !== value)\n : [...current, value];\n this.valuesChange.emit(next);\n }\n\n /** Alterna entre \"todas seleccionadas\" y \"ninguna seleccionada\". */\n toggleAll(): void {\n this.valuesChange.emit(this.allSelected() ? [] : this.options().map((option) => option.value));\n }\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(event: MouseEvent): void {\n if (this.isOpen() && !this.host.nativeElement.contains(event.target as Node)) {\n this.isOpen.set(false);\n }\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n this.isOpen.set(false);\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Bloque de título al tope de una página: chip de ícono opcional, título (h1),\n * subtítulo opcional y un área de acciones opcional proyectada vía\n * `<ng-content select=\"[actions]\">`, para no acoplar el componente a un set\n * fijo de botones.\n *\n * <kf-page-header title=\"Vehículos\" subtitle=\"Gestión de la flota activa\">\n * <button actions>Nuevo vehículo</button>\n * </kf-page-header>\n *\n * <kf-page-header icon=\"settings\" title=\"Configuración\" />\n */\n@Component({\n selector: 'kf-page-header',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <span class=\"kf-page-header__icon\">\n <kf-icon [name]=\"iconName\" size=\"lg\" />\n </span>\n }\n\n <div class=\"kf-page-header__heading\">\n <h1 class=\"kf-page-header__title\">{{ title() }}</h1>\n @if (subtitle()) {\n <p class=\"kf-page-header__subtitle\">{{ subtitle() }}</p>\n }\n </div>\n\n <div class=\"kf-page-header__actions\">\n <ng-content select=\"[actions]\" />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-md);\n font-family: var(--kf-font-body);\n }\n .kf-page-header__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n /* El chip necesita bastante más aire que el ícono (24px \"lg\") que\n contiene — con --kf-space-xl (32px) quedaban casi pegados. */\n width: 48px;\n height: 48px;\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n .kf-page-header__heading {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n flex: 1 1 auto;\n min-width: 0;\n }\n .kf-page-header__title {\n margin: 0;\n font-family: var(--kf-font-title);\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1.2;\n color: var(--kf-color-ink);\n }\n .kf-page-header__subtitle {\n margin: 0;\n font-size: 0.9375rem;\n color: var(--kf-color-text-muted);\n }\n .kf-page-header__actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class PageHeader {\n readonly icon = input<IconName | undefined>(undefined);\n readonly title = input.required<string>();\n readonly subtitle = input<string | undefined>(undefined);\n}\n","import { Component, computed, input, output } from '@angular/core';\n\n/** Un número de página clickeable o un separador \"…\" no interactivo. */\nexport type PaginationItem = { type: 'page'; page: number } | { type: 'ellipsis' };\n\nconst SIBLINGS = 1;\n\n/**\n * Paginador numerado con elipsis + prev/next.\n *\n * Algoritmo de elipsis estándar: siempre se muestran la primera página, la\n * última, la página actual y un par de vecinas alrededor de la actual; el\n * resto de los huecos se colapsa en un separador \"…\". Cuando el hueco entre\n * dos números visibles es de exactamente una página, se muestra ese número\n * en vez de un \"…\" (no tiene sentido colapsar un solo elemento).\n *\n * El contenido proyectado (`<ng-content>`) es para el texto informativo\n * opcional (ej. \"21–40 de 273\"), a la izquierda de los controles.\n *\n * <kf-pagination [page]=\"page\" [pages]=\"totalPages\" (pageChange)=\"page = $event\">\n * 21–40 de 273\n * </kf-pagination>\n */\n@Component({\n selector: 'kf-pagination',\n template: `\n <div class=\"kf-pagination\">\n <div class=\"kf-pagination__info\">\n <ng-content />\n </div>\n <nav class=\"kf-pagination__nav\" aria-label=\"Paginación\">\n <button\n type=\"button\"\n class=\"kf-pagination__control\"\n [disabled]=\"page() <= 1\"\n aria-label=\"Página anterior\"\n (click)=\"goTo(page() - 1)\"\n >\n ‹\n </button>\n\n @for (item of items(); track $index) {\n @if (item.type === 'page') {\n <button\n type=\"button\"\n class=\"kf-pagination__page\"\n [class.kf-pagination__page--active]=\"item.page === page()\"\n [attr.aria-current]=\"item.page === page() ? 'page' : null\"\n [attr.aria-label]=\"'Ir a la página ' + item.page\"\n (click)=\"goTo(item.page)\"\n >\n {{ item.page }}\n </button>\n } @else {\n <span class=\"kf-pagination__ellipsis\" aria-hidden=\"true\">…</span>\n }\n }\n\n <button\n type=\"button\"\n class=\"kf-pagination__control\"\n [disabled]=\"page() >= pages()\"\n aria-label=\"Página siguiente\"\n (click)=\"goTo(page() + 1)\"\n >\n ›\n </button>\n </nav>\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-pagination {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-md);\n flex-wrap: wrap;\n }\n .kf-pagination__info {\n font-size: 0.85rem;\n color: var(--kf-color-text-muted);\n }\n .kf-pagination__info:empty {\n display: none;\n }\n .kf-pagination__nav {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n }\n .kf-pagination__control,\n .kf-pagination__page {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 2rem;\n height: 2rem;\n padding: 0 var(--kf-space-xs);\n font: inherit;\n font-size: 0.85rem;\n color: var(--kf-color-text);\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n cursor: pointer;\n transition:\n background 0.14s,\n border-color 0.14s,\n color 0.14s;\n }\n .kf-pagination__control:hover:not(:disabled),\n .kf-pagination__page:hover:not(.kf-pagination__page--active) {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border-strong);\n }\n .kf-pagination__control:focus-visible,\n .kf-pagination__page:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-pagination__control:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-pagination__page--active {\n color: var(--kf-color-white);\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n cursor: default;\n }\n .kf-pagination__ellipsis {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 2rem;\n height: 2rem;\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class Pagination {\n readonly page = input(1);\n readonly pages = input(1);\n readonly pageChange = output<number>();\n\n /** Lista de números de página y separadores a renderizar, ya resuelta por el algoritmo de elipsis. */\n readonly items = computed<PaginationItem[]>(() =>\n buildPaginationItems(this.page(), this.pages()),\n );\n\n goTo(target: number): void {\n const clamped = Math.min(Math.max(target, 1), this.pages());\n if (clamped === this.page()) {\n return;\n }\n this.pageChange.emit(clamped);\n }\n}\n\n/**\n * Construye la lista de items visibles con el algoritmo de elipsis estándar:\n * primera página, última página, actual ± `SIBLINGS`, y un \"…\" por cada hueco\n * mayor a una página entre esos bloques.\n */\nfunction buildPaginationItems(current: number, total: number): PaginationItem[] {\n const totalPages = Math.max(total, 1);\n const safeCurrent = Math.min(Math.max(current, 1), totalPages);\n\n const visible = new Set<number>([1, totalPages, safeCurrent]);\n for (let offset = 1; offset <= SIBLINGS; offset++) {\n visible.add(safeCurrent - offset);\n visible.add(safeCurrent + offset);\n }\n\n const sortedPages = [...visible].filter((p) => p >= 1 && p <= totalPages).sort((a, b) => a - b);\n\n const items: PaginationItem[] = [];\n for (let i = 0; i < sortedPages.length; i++) {\n const pageNumber = sortedPages[i];\n if (i > 0) {\n const gap = pageNumber - sortedPages[i - 1];\n if (gap === 2) {\n // Hueco de una sola página: mostrarla en vez de colapsarla en \"…\".\n items.push({ type: 'page', page: pageNumber - 1 });\n } else if (gap > 2) {\n items.push({ type: 'ellipsis' });\n }\n }\n items.push({ type: 'page', page: pageNumber });\n }\n\n return items;\n}\n","import { Component, input } from '@angular/core';\nimport { Card } from '../card/Card';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Tarjeta contenedora con título, enlace de acción opcional a la derecha, y\n * cuerpo con contenido libre — página 33: \"Base de la mayoría de bloques del\n * portal\". Compone sobre `kf-card` para compartir la misma superficie\n * (radio, sombra, borde) que el resto de la librería.\n *\n * <kf-panel title=\"Mis documentos por pagar\" actionLabel=\"Ir a pagos\" actionHref=\"/pagos\">\n * <kf-action-tile-row icon=\"download\" title=\"Pagos\" description=\"Revisa tu estado de cuenta y realiza pagos.\" />\n * </kf-panel>\n */\n@Component({\n selector: 'kf-panel',\n imports: [Card, Icon],\n template: `\n <kf-card>\n <div class=\"kf-panel__head\">\n <span class=\"kf-panel__title\">{{ title() }}</span>\n @if (actionLabel()) {\n <a class=\"kf-panel__action\" [href]=\"actionHref() || '#'\">\n {{ actionLabel() }}\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n </div>\n <div class=\"kf-panel__body\">\n <ng-content />\n </div>\n </kf-card>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-panel__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n margin-bottom: var(--kf-space-sm);\n }\n .kf-panel__title {\n font-family: var(--kf-font-title);\n font-size: 1.05rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-panel__action {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n flex: none;\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n .kf-panel__action:hover {\n text-decoration: underline;\n }\n .kf-panel__body {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class Panel {\n readonly title = input.required<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import { Component, booleanAttribute, input, output } from '@angular/core';\nimport { AdminBadge } from '../admin-badge/AdminBadge';\nimport { Avatar } from '../avatar/Avatar';\n\n/** Un ítem de navegación de la barra de marca. */\nexport interface PortalHeaderNavItem {\n label: string;\n href: string;\n active?: boolean;\n}\n\n/** Una acción de la franja de administrador (ej. \"Consultar deuda clientes\"). */\nexport interface PortalHeaderAdminAction {\n label: string;\n href: string;\n}\n\n/**\n * Cabecera completa del portal (página 31) — franja de administrador\n * (acento ámbar, solo admins), barra de marca con logo, navegación y\n * pastilla de sesión. Compone `kf-admin-badge` para la franja y `kf-avatar\n * pill` para la sesión, en vez de reimplementar ambos.\n *\n * Es distinto de `kf-page-header`/`kf-page-head` (título de una vista\n * interna) — este es el chrome global del portal, se monta una sola vez.\n *\n * <kf-portal-header\n * [isAdmin]=\"true\"\n * [adminActions]=\"[{ label: 'Consultar deuda clientes', href: '/deuda' }, { label: 'Cambiar DNI', href: '/dni' }]\"\n * [navItems]=\"[{ label: 'Home', href: '/', active: true }, { label: 'Vehículos', href: '/vehiculos' }]\"\n * userInitials=\"TS\"\n * />\n */\n@Component({\n selector: 'kf-portal-header',\n imports: [AdminBadge, Avatar],\n template: `\n @if (isAdmin()) {\n <div class=\"kf-portal-header__admin-bar\">\n <kf-admin-badge inline />\n <div class=\"kf-portal-header__admin-actions\">\n @for (action of adminActions(); track action.label) {\n <a class=\"kf-portal-header__admin-action\" [href]=\"action.href\">{{ action.label }}</a>\n }\n </div>\n </div>\n }\n <div class=\"kf-portal-header__brand-bar\">\n <span class=\"kf-portal-header__logo\">{{ brand() }}</span>\n <nav class=\"kf-portal-header__nav\">\n @for (item of navItems(); track item.label) {\n <a\n class=\"kf-portal-header__nav-item\"\n [class.kf-portal-header__nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n >\n {{ item.label }}\n </a>\n }\n </nav>\n <button type=\"button\" class=\"kf-portal-header__session\" (click)=\"sessionClick.emit()\">\n <kf-avatar [initials]=\"userInitials()\" pill />\n </button>\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-portal-header__admin-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-md);\n padding: var(--kf-space-xs) var(--kf-space-lg);\n background: var(--kf-color-tertiary-deep);\n }\n .kf-portal-header__admin-actions {\n display: flex;\n gap: var(--kf-space-md);\n }\n .kf-portal-header__admin-action {\n font-size: 0.8125rem;\n font-weight: 600;\n color: rgba(255, 255, 255, 0.85);\n text-decoration: none;\n }\n .kf-portal-header__admin-action:hover {\n color: var(--kf-color-white);\n }\n .kf-portal-header__brand-bar {\n display: flex;\n align-items: center;\n gap: var(--kf-space-lg);\n padding: var(--kf-space-sm) var(--kf-space-lg);\n background: var(--kf-color-tertiary-deep);\n border-top: 1px solid rgba(255, 255, 255, 0.1);\n }\n .kf-portal-header__logo {\n font-family: var(--kf-font-title);\n font-size: 1.25rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n color: var(--kf-color-white);\n text-transform: uppercase;\n }\n .kf-portal-header__nav {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n flex: 1 1 auto;\n }\n .kf-portal-header__nav-item {\n padding: var(--kf-space-xs) var(--kf-space-md);\n border-radius: var(--kf-radius-sm);\n color: rgba(255, 255, 255, 0.75);\n font-size: 0.875rem;\n font-weight: 600;\n text-decoration: none;\n transition:\n background 0.14s,\n color 0.14s;\n }\n /*\n * :not(--active) es necesario: sin él, este :hover pisa el color del\n * item activo (fondo blanco, texto --kf-color-ink) con blanco también,\n * dejando texto blanco sobre fondo blanco al pasar el mouse por encima\n * del item ya activo.\n */\n .kf-portal-header__nav-item:hover:not(.kf-portal-header__nav-item--active) {\n color: var(--kf-color-white);\n }\n .kf-portal-header__nav-item--active {\n background: var(--kf-color-white);\n color: var(--kf-color-ink);\n }\n .kf-portal-header__session {\n flex: none;\n border: none;\n background: transparent;\n padding: 0;\n cursor: pointer;\n }\n `,\n})\nexport class PortalHeader {\n readonly brand = input('DIVEMOTOR');\n readonly isAdmin = input(false, { transform: booleanAttribute });\n readonly adminActions = input<PortalHeaderAdminAction[]>([]);\n readonly navItems = input<PortalHeaderNavItem[]>([]);\n readonly userInitials = input.required<string>();\n\n readonly sessionClick = output<void>();\n}\n","import { Component, input } from '@angular/core';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Estado vacío de reservas en taller con llamada a agendar (página 36):\n * barra de estado vacío arriba (\"No tienes reservas de taller\"), panel de\n * invitación al medio (ícono en círculo azul, título, descripción, link) y\n * una fila de dos acciones al pie — un slot `[actions]` proyectado, para no\n * acoplar el componente a botones fijos.\n *\n * Distinto de `kf-empty-state` genérico: este combina la barra + la\n * invitación + las acciones como un bloque compuesto propio del dominio\n * \"taller\", no un placeholder de una sola pieza.\n *\n * <kf-reserve-block emptyLabel=\"No tienes reservas de taller\"\n * title=\"¿Necesitas mantención?\" description=\"Tenemos la mejor red de talleres.\"\n * actionLabel=\"Agenda tu reserva aquí\" actionHref=\"/taller/agendar\">\n * <kf-button actions icon=\"calendar\">Reservar hora</kf-button>\n * <kf-button actions variant=\"outline\" icon=\"list\">Ver agenda</kf-button>\n * </kf-reserve-block>\n */\n@Component({\n selector: 'kf-reserve-block',\n imports: [Icon],\n template: `\n <div class=\"kf-reserve-block__empty\">\n <kf-icon name=\"calendar\" size=\"sm\" />\n <span>{{ emptyLabel() }}</span>\n </div>\n <div class=\"kf-reserve-block__invite\">\n <span class=\"kf-reserve-block__invite-icon\">\n <kf-icon name=\"tool\" size=\"md\" />\n </span>\n <div class=\"kf-reserve-block__invite-text\">\n <span class=\"kf-reserve-block__invite-title\">{{ title() }}</span>\n @if (description()) {\n <span class=\"kf-reserve-block__invite-description\">{{ description() }}</span>\n }\n @if (actionLabel()) {\n <a class=\"kf-reserve-block__invite-action\" [href]=\"actionHref() || '#'\">\n {{ actionLabel() }}\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n </div>\n </div>\n <div class=\"kf-reserve-block__actions\">\n <ng-content select=\"[actions]\" />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-reserve-block__empty {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding-bottom: var(--kf-space-sm);\n border-bottom: 1px solid var(--kf-color-border);\n color: var(--kf-color-text-muted);\n font-size: 0.875rem;\n }\n .kf-reserve-block__invite {\n display: flex;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n }\n .kf-reserve-block__invite-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: 2.25rem;\n height: 2.25rem;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n }\n .kf-reserve-block__invite-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n }\n .kf-reserve-block__invite-title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-reserve-block__invite-description {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-reserve-block__invite-action {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n margin-top: var(--kf-space-xs);\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n .kf-reserve-block__invite-action:hover {\n text-decoration: underline;\n }\n .kf-reserve-block__actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class ReserveBlock {\n readonly emptyLabel = input('No tienes reservas de taller');\n readonly title = input.required<string>();\n readonly description = input<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Título de sub-sección con chip de ícono, pensado para anidarse dentro de\n * cards o paneles (a diferencia de `PageHeader`, que encabeza una página\n * completa). Un área de acciones opcional se proyecta vía\n * `<ng-content select=\"[actions]\">` para no acoplar el componente a un set\n * fijo de botones.\n *\n * `size=\"sm\"` reduce tipografía y espaciado para usarse dentro de cards ya\n * compactas. `solid` rellena el chip de ícono con el color primario sólido\n * en vez del tratamiento \"soft\" (fondo tenue) — pensado para superficies que\n * ya tienen un tinte de color propio, donde el chip \"soft\" perdería contraste.\n *\n * <kf-section-header icon=\"settings\" title=\"Preferencias\"\n * subtitle=\"Configuración general de la cuenta\">\n * <button actions>Editar</button>\n * </kf-section-header>\n *\n * <kf-section-header title=\"Detalle\" size=\"sm\" [solid]=\"true\" />\n */\n@Component({\n selector: 'kf-section-header',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <span class=\"kf-section-header__icon\" [class.kf-section-header__icon--solid]=\"solid()\">\n <kf-icon [name]=\"iconName\" [size]=\"size() === 'sm' ? 'sm' : 'md'\" />\n </span>\n }\n\n <span class=\"kf-section-header__text\">\n <span class=\"kf-section-header__title\">{{ title() }}</span>\n @if (subtitle()) {\n <span class=\"kf-section-header__subtitle\">{{ subtitle() }}</span>\n }\n </span>\n\n <span class=\"kf-section-header__actions\">\n <ng-content select=\"[actions]\" />\n </span>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n font-family: var(--kf-font-body);\n }\n :host(.kf-section-header--sm) {\n gap: var(--kf-space-xs);\n }\n .kf-section-header__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n inline-size: 2.5rem;\n block-size: 2.5rem;\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n :host(.kf-section-header--sm) .kf-section-header__icon {\n inline-size: 1.75rem;\n block-size: 1.75rem;\n border-radius: var(--kf-radius-xs);\n }\n .kf-section-header__icon--solid {\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n }\n .kf-section-header__text {\n display: flex;\n flex-direction: column;\n min-width: 0;\n flex: 1 1 auto;\n }\n .kf-section-header__title {\n font-family: var(--kf-font-title);\n font-size: 1rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n line-height: 1.3;\n }\n :host(.kf-section-header--sm) .kf-section-header__title {\n font-size: 0.875rem;\n }\n .kf-section-header__subtitle {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n line-height: 1.3;\n }\n :host(.kf-section-header--sm) .kf-section-header__subtitle {\n font-size: 0.75rem;\n }\n .kf-section-header__actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n `,\n host: {\n '[class.kf-section-header--sm]': \"size() === 'sm'\",\n },\n})\nexport class SectionHeader {\n readonly icon = input<IconName>();\n readonly title = input.required<string>();\n readonly subtitle = input<string>();\n readonly size = input<'sm'>();\n readonly solid = input(false, { transform: booleanAttribute });\n}\n","import { Component, computed, input, output } from '@angular/core';\n\nexport interface SegmentedOption {\n value: string;\n label: string;\n}\n\n/**\n * Control de segmentos relleno, tipo \"iOS segmented control\": 2-3 opciones\n * con un thumb que se desliza detrás de la opción activa.\n *\n * La posición del thumb se resuelve con una variable CSS (--kf-segmented-index)\n * y `transform: translateX()`, así la transición queda a cargo de CSS puro\n * (mismo criterio que Tabs), sin medir el DOM desde TypeScript.\n *\n * <kf-segmented [options]=\"options\" [value]=\"value\" (valueChange)=\"onChange($event)\" />\n */\n@Component({\n selector: 'kf-segmented',\n template: `\n <div class=\"kf-segmented__track\" [style.--kf-segmented-count]=\"options().length\">\n <div\n class=\"kf-segmented__thumb\"\n [style.--kf-segmented-index]=\"selectedIndex()\"\n [style.visibility]=\"selectedIndex() === -1 ? 'hidden' : 'visible'\"\n ></div>\n @for (option of options(); track option.value) {\n <button\n type=\"button\"\n class=\"kf-segmented__option\"\n [class.kf-segmented__option--active]=\"option.value === value()\"\n [attr.aria-pressed]=\"option.value === value()\"\n (click)=\"select(option.value)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-segmented__track {\n position: relative;\n display: grid;\n grid-template-columns: repeat(var(--kf-segmented-count), 1fr);\n gap: 2px;\n padding: 2px;\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n }\n .kf-segmented__thumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: calc((100% - 4px) / var(--kf-segmented-count));\n height: calc(100% - 4px);\n background: var(--kf-color-white);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-xs);\n transform: translateX(calc(var(--kf-segmented-index, 0) * 100%));\n transition: transform 0.2s ease;\n }\n .kf-segmented__option {\n position: relative;\n z-index: 1;\n font: inherit;\n padding: var(--kf-space-xs) var(--kf-space-md);\n border: none;\n background: transparent;\n color: var(--kf-color-text-muted);\n border-radius: var(--kf-radius-sm);\n cursor: pointer;\n transition: color 0.14s;\n }\n .kf-segmented__option:hover:not(.kf-segmented__option--active) {\n color: var(--kf-color-text);\n }\n .kf-segmented__option--active {\n color: var(--kf-color-ink);\n }\n .kf-segmented__option:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n `,\n})\nexport class Segmented {\n readonly options = input.required<SegmentedOption[]>();\n readonly value = input.required<string>();\n readonly valueChange = output<string>();\n\n /** Índice de la opción activa; -1 si `value` no matchea ninguna opción. */\n readonly selectedIndex = computed(() =>\n this.options().findIndex((option) => option.value === this.value()),\n );\n\n select(nextValue: string): void {\n if (nextValue === this.value()) {\n return;\n }\n this.valueChange.emit(nextValue);\n }\n}\n","import {\n Component,\n ElementRef,\n HostListener,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { FieldLabel } from '../field-label/FieldLabel';\n\nexport interface SelectMenuOption {\n value: string;\n label: string;\n}\n\nlet nextId = 0;\n\n/**\n * Dropdown de selección simple pero con panel propio (no usa `<select>` nativo),\n * para cuando se necesita más control visual que un `<select>` estándar permite.\n *\n * El panel flotante se implementa con `position: absolute` sobre el host\n * (sin Angular CDK Overlay, que no es dependencia del proyecto). Se abre y\n * cierra por click en el disparador, y se cierra al hacer click afuera o al\n * presionar Escape.\n *\n * <kf-select-menu\n * label=\"País\"\n * [options]=\"countries\"\n * [value]=\"selectedCountry()\"\n * (valueChange)=\"selectedCountry.set($event)\"\n * />\n *\n * Pendiente: el prop `icon` de otros componentes del design system requiere\n * un componente Icon / sprite SVG que esta librería todavía no tiene — este\n * componente no usa iconos, así que no aplica acá.\n */\n@Component({\n selector: 'kf-select-menu',\n imports: [FieldLabel],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n }\n <button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-select-menu__trigger\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n >\n <span\n class=\"kf-select-menu__value\"\n [class.kf-select-menu__value--placeholder]=\"!selectedOption()\"\n >\n {{ selectedOption()?.label ?? placeholder() }}\n </span>\n <span\n class=\"kf-select-menu__caret\"\n [class.kf-select-menu__caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n </button>\n @if (isOpen()) {\n <ul\n class=\"kf-select-menu__panel\"\n [id]=\"listboxId\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @for (option of options(); track option.value) {\n <li\n class=\"kf-select-menu__option\"\n [class.kf-select-menu__option--selected]=\"option.value === value()\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"option.value === value()\"\n (click)=\"select(option)\"\n (keydown.enter)=\"select(option)\"\n (keydown.space)=\"$event.preventDefault(); select(option)\"\n >\n {{ option.label }}\n </li>\n } @empty {\n <li class=\"kf-select-menu__empty\">Sin opciones disponibles</li>\n }\n </ul>\n }\n `,\n styles: `\n :host {\n display: inline-flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n position: relative;\n font: inherit;\n min-width: 200px;\n }\n .kf-select-menu__trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n width: 100%;\n font: inherit;\n font-family: var(--kf-font-body);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n color: var(--kf-color-text);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-select-menu__trigger:hover:not(:disabled) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-select-menu__trigger:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-select-menu__trigger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-select-menu__value {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .kf-select-menu__value--placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-select-menu__caret {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-text-muted);\n border-bottom: 2px solid var(--kf-color-text-muted);\n transform: rotate(45deg);\n transition: transform 0.14s;\n margin-top: -4px;\n }\n .kf-select-menu__caret--open {\n transform: rotate(-135deg);\n margin-top: 4px;\n }\n .kf-select-menu__panel {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 10;\n margin: var(--kf-space-xs) 0 0;\n padding: var(--kf-space-xs) 0;\n list-style: none;\n max-height: 240px;\n overflow-y: auto;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-md);\n }\n .kf-select-menu__option {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-select-menu__option:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-select-menu__option--selected {\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n font-weight: 600;\n }\n .kf-select-menu__empty {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class SelectMenu {\n readonly label = input<string>();\n readonly options = input<SelectMenuOption[]>([]);\n readonly value = input<string>();\n readonly placeholder = input<string>('Seleccionar');\n readonly disabled = input(false, { transform: booleanAttribute });\n\n readonly valueChange = output<string>();\n\n private readonly instanceId = `kf-select-menu-${nextId++}`;\n readonly triggerId = `${this.instanceId}-trigger`;\n readonly listboxId = `${this.instanceId}-listbox`;\n\n readonly isOpen = signal(false);\n\n readonly selectedOption = computed(() =>\n this.options().find((option) => option.value === this.value()),\n );\n\n private readonly host = inject(ElementRef<HTMLElement>);\n\n toggle(): void {\n if (this.disabled()) {\n return;\n }\n this.isOpen.update((open) => !open);\n }\n\n select(option: SelectMenuOption): void {\n this.isOpen.set(false);\n if (option.value !== this.value()) {\n this.valueChange.emit(option.value);\n }\n }\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(event: MouseEvent): void {\n if (this.isOpen() && !this.host.nativeElement.contains(event.target as Node)) {\n this.isOpen.set(false);\n }\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n this.isOpen.set(false);\n }\n}\n","import { Component, booleanAttribute, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Indicador numérico compacto (página 34): label + valor grande, con un\n * ícono a la derecha del label — más chico y sin badge de esquina que\n * `kf-metric-card`, pensado para grillas densas de KPIs simples (\"Total\n * vehículos: 4\", \"En taller: 1\"), no para dashboards con tendencia.\n *\n * Con `cta` en vez de `value`, se convierte en la variante de llamada a la\n * acción: un bloque de fondo suave con título, descripción y un link — sin\n * número, para promover el siguiente paso (ej. \"¿Necesitas mantención?\").\n *\n * <kf-stat-tile label=\"Total vehículos\" value=\"4\" icon=\"car\" />\n * <kf-stat-tile cta title=\"¿Necesitas mantención?\"\n * description=\"Tenemos la mejor red de talleres.\"\n * actionLabel=\"Agenda aquí\" actionHref=\"/taller/agendar\" />\n */\n@Component({\n selector: 'kf-stat-tile',\n imports: [Icon],\n template: `\n @if (cta()) {\n <span class=\"kf-stat-tile__cta-title\">{{ title() }}</span>\n @if (description()) {\n <span class=\"kf-stat-tile__cta-description\">{{ description() }}</span>\n }\n @if (actionLabel()) {\n <a class=\"kf-stat-tile__cta-action\" [href]=\"actionHref() || '#'\">\n {{ actionLabel() }}\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n } @else {\n <div class=\"kf-stat-tile__head\">\n <span class=\"kf-stat-tile__label\">{{ label() }}</span>\n @if (icon(); as iconName) {\n <span class=\"kf-stat-tile__icon\">\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n </span>\n }\n </div>\n <span class=\"kf-stat-tile__value\">{{ value() }}</span>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n }\n :host(.kf-stat-tile--cta) {\n background: var(--kf-color-surface);\n gap: 2px;\n }\n .kf-stat-tile__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-xs);\n }\n .kf-stat-tile__label {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-stat-tile__icon {\n display: inline-flex;\n color: var(--kf-color-primary);\n }\n .kf-stat-tile__value {\n font-family: var(--kf-font-title);\n font-size: 1.5rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-stat-tile__cta-title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-stat-tile__cta-description {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-stat-tile__cta-action {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n margin-top: var(--kf-space-xs);\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n .kf-stat-tile__cta-action:hover {\n text-decoration: underline;\n }\n `,\n host: {\n '[class.kf-stat-tile--cta]': 'cta()',\n },\n})\nexport class StatTile {\n readonly cta = input(false, { transform: booleanAttribute });\n // Variante numérica\n readonly label = input<string>();\n readonly value = input<string | number>();\n readonly icon = input<IconName>();\n // Variante CTA\n readonly title = input<string>();\n readonly description = input<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Pill con borde, en mayúsculas y con letter-spacing, pensada para indicadores\n * de estado únicos y prominentes (ej. \"ESTADO TÉCNICO\"). El fondo es siempre\n * transparente; el color de borde/texto/punto depende de `tone`.\n *\n * <kf-status-pill tone=\"ok\">Operativo</kf-status-pill>\n * <kf-status-pill tone=\"error\" dot>Fuera de servicio</kf-status-pill>\n */\n@Component({\n selector: 'kf-status-pill',\n template: `\n <span class=\"kf-status-pill\" [class]=\"'kf-status-pill--' + tone()\">\n @if (dot()) {\n <span class=\"kf-status-pill__dot\"></span>\n }\n <ng-content />\n </span>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-status-pill {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border: 1px solid currentColor;\n border-radius: var(--kf-radius-pill);\n background: transparent;\n font: inherit;\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n white-space: nowrap;\n }\n .kf-status-pill__dot {\n width: 6px;\n height: 6px;\n border-radius: var(--kf-radius-pill);\n background: currentColor;\n flex-shrink: 0;\n }\n .kf-status-pill--blue {\n color: var(--kf-color-info);\n }\n .kf-status-pill--ok {\n color: var(--kf-color-success);\n }\n .kf-status-pill--warn {\n color: var(--kf-color-warning);\n }\n .kf-status-pill--error {\n color: var(--kf-color-error);\n }\n `,\n})\nexport class StatusPill {\n readonly tone = input<'blue' | 'ok' | 'warn' | 'error'>('blue');\n readonly dot = input(false, { transform: booleanAttribute });\n}\n","import {\n Component,\n DestroyRef,\n ElementRef,\n afterNextRender,\n afterRenderEffect,\n computed,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\nexport interface TabOption {\n value: string;\n label: string;\n icon?: IconName;\n}\n\n/**\n * Barra de tabs subrayada: un único indicador se desliza horizontalmente hasta\n * la pestaña activa. Como las pestañas tienen ancho de contenido (labels de\n * largo distinto), la posición no se puede resolver con CSS puro: se mide el\n * `offsetLeft`/`offsetWidth` de la pestaña activa después de cada render y la\n * transición del `transform`/`width` queda a cargo de CSS.\n *\n * <kf-tabs [options]=\"tabs\" [value]=\"active\" (valueChange)=\"active = $event\" />\n */\n@Component({\n selector: 'kf-tabs',\n imports: [Icon],\n template: `\n <div class=\"kf-tabs\" role=\"tablist\" #track>\n @for (option of options(); track option.value) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"kf-tabs__tab\"\n [class.kf-tabs__tab--active]=\"option.value === value()\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.tabindex]=\"option.value === value() ? 0 : -1\"\n [id]=\"'kf-tab-' + option.value\"\n [attr.aria-controls]=\"'kf-tabpanel-' + option.value\"\n (click)=\"select(option.value)\"\n (keydown)=\"onKeydown($event, option.value)\"\n >\n @if (option.icon; as iconName) {\n <kf-icon class=\"kf-tabs__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <span class=\"kf-tabs__label\">{{ option.label }}</span>\n </button>\n }\n <span\n class=\"kf-tabs__indicator\"\n aria-hidden=\"true\"\n [style.transform]=\"indicatorTransform()\"\n [style.width.px]=\"indicatorWidth()\"\n [style.opacity]=\"indicatorWidth() ? 1 : 0\"\n ></span>\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-tabs {\n position: relative;\n display: flex;\n align-items: stretch;\n gap: var(--kf-space-md);\n border-bottom: 1px solid var(--kf-color-border);\n }\n .kf-tabs__tab {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n font: inherit;\n font-size: 0.9rem;\n color: var(--kf-color-text-muted);\n background: transparent;\n border: none;\n /* Sin padding horizontal propio: el espaciado entre tabs lo da el\n gap del contenedor — con ambos sumando (como antes) el conjunto\n quedaba más separado que en el PDF, que muestra las pestañas casi\n pegadas entre sí. El padding vertical se mantiene por área de click. */\n padding: var(--kf-space-sm) 0;\n cursor: pointer;\n transition: color 0.14s;\n }\n .kf-tabs__tab:hover:not(.kf-tabs__tab--active) {\n color: var(--kf-color-text);\n }\n .kf-tabs__tab:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n border-radius: var(--kf-radius-xs);\n }\n .kf-tabs__tab--active {\n color: var(--kf-color-primary);\n font-size: 1rem;\n font-weight: 700;\n }\n .kf-tabs__indicator {\n position: absolute;\n bottom: -1px;\n left: 0;\n height: 2px;\n background: var(--kf-color-primary);\n border-radius: 2px 2px 0 0;\n pointer-events: none;\n transition:\n transform 0.28s cubic-bezier(0.32, 0.72, 0, 1),\n width 0.28s cubic-bezier(0.32, 0.72, 0, 1),\n opacity 0.14s;\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-tabs__indicator {\n transition: opacity 0.14s;\n }\n }\n `,\n})\nexport class Tabs {\n readonly options = input.required<TabOption[]>();\n readonly value = input.required<string>();\n readonly valueChange = output<string>();\n\n private readonly track = viewChild.required<ElementRef<HTMLElement>>('track');\n private readonly destroyRef = inject(DestroyRef);\n\n /** Geometría de la pestaña activa; `null` mientras no haya una medición válida. */\n private readonly activeRect = signal<{ x: number; width: number } | null>(null);\n\n protected readonly indicatorTransform = computed(\n () => `translateX(${this.activeRect()?.x ?? 0}px)`,\n );\n protected readonly indicatorWidth = computed(() => this.activeRect()?.width ?? 0);\n\n constructor() {\n // Cada cambio de `value`/`options` re-mide después de que el DOM ya se actualizó.\n afterRenderEffect(() => {\n this.value();\n this.options();\n this.measure();\n });\n\n afterNextRender(() => {\n // El ancho de la pestaña activa cambia con el layout (resize, fuentes que\n // cargan tarde), y sin esto el indicador queda desfasado del texto.\n const observer = new ResizeObserver(() => this.measure());\n observer.observe(this.track().nativeElement);\n this.destroyRef.onDestroy(() => observer.disconnect());\n });\n }\n\n private measure(): void {\n const active = this.track().nativeElement.querySelector<HTMLElement>('.kf-tabs__tab--active');\n this.activeRect.set(active ? { x: active.offsetLeft, width: active.offsetWidth } : null);\n }\n\n select(value: string): void {\n if (value === this.value()) {\n return;\n }\n this.valueChange.emit(value);\n }\n\n /** Navegación estándar de ARIA tabs: flechas mueven el foco y activan la pestaña. */\n onKeydown(event: KeyboardEvent, currentValue: string): void {\n const items = this.options();\n const currentIndex = items.findIndex((option) => option.value === currentValue);\n\n let nextIndex: number;\n switch (event.key) {\n case 'ArrowRight':\n nextIndex = (currentIndex + 1) % items.length;\n break;\n case 'ArrowLeft':\n nextIndex = (currentIndex - 1 + items.length) % items.length;\n break;\n case 'Home':\n nextIndex = 0;\n break;\n case 'End':\n nextIndex = items.length - 1;\n break;\n default:\n return;\n }\n\n event.preventDefault();\n const nextOption = items[nextIndex];\n this.select(nextOption.value);\n\n const host = (event.currentTarget as HTMLElement).parentElement;\n const nextId = `kf-tab-${nextOption.value}`;\n const nextButton = Array.from(host?.querySelectorAll<HTMLButtonElement>('button') ?? []).find(\n (button) => button.id === nextId,\n );\n nextButton?.focus();\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n Injectable,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Visual tone of a toast. Maps to the state tokens in\n * projects/ui/src/tokens/base.css. `loading` has no auto-dismiss and shows an\n * indeterminate bar instead of a countdown — pair it with\n * {@link ToastService.promise}. It reuses the `info` tokens, the closest\n * semantic role to \"work in progress\".\n */\nexport type ToastTone = 'success' | 'error' | 'warning' | 'info' | 'loading';\n\n/** Fixed icon per tone (page 20 of the design system) — not configurable per call. */\nconst TOAST_ICON: Record<ToastTone, IconName> = {\n success: 'check-circle',\n error: 'alert-circle',\n warning: 'alert-triangle',\n info: 'bell',\n loading: 'bell',\n};\n\n/** Options for {@link ToastService.show}. */\nexport interface ToastOptions {\n /** Color tone. Defaults to `'info'`. */\n tone?: ToastTone;\n /** Milliseconds before auto-dismiss. Ignored when `tone` is `'loading'`. Defaults to `2800`. */\n duration?: number;\n}\n\n/** Messages for each leg of {@link ToastService.promise}. */\nexport interface ToastPromiseMessages<T = unknown> {\n loading?: string;\n success?: string | ((value: T) => string);\n error?: string | ((error: unknown) => string);\n}\n\n/** The single active toast, as rendered by `kf-toast-host`. */\nexport interface ToastState {\n id: number;\n message: string;\n tone: ToastTone;\n duration: number;\n leaving: boolean;\n}\n\nconst DEFAULT_DURATION_MS = 2800;\nconst EXIT_ANIMATION_MS = 200;\n\n/**\n * Shows one toast at a time — a new `show()` call replaces whatever is\n * currently up (this mirrors a global status line, not a notification stack).\n *\n * Angular has no global function that can mount UI on its own, so the\n * imperative `showToast(...)` of the reference design system becomes a\n * root-provided service holding signal state: `ToastService.show(...)` sets\n * the active toast and `ToastHost` (standalone, mounted once in the app\n * shell) renders it.\n *\n * @example\n * ```ts\n * // app.ts\n * imports: [ToastHost]\n * template: `<kf-toast-host />`\n *\n * // anywhere else\n * private readonly toast = inject(ToastService);\n * this.toast.show('Vehículo guardado', { tone: 'success' });\n *\n * // chains a `loading` toast into the promise's outcome:\n * this.toast.promise(this.api.save(vehicle), {\n * loading: 'Guardando…',\n * success: 'Vehículo guardado',\n * error: 'No se pudo guardar',\n * });\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class ToastService {\n private readonly _current = signal<ToastState | null>(null);\n private nextId = 0;\n private dismissTimer?: ReturnType<typeof setTimeout>;\n private removeTimer?: ReturnType<typeof setTimeout>;\n\n /** The single active toast, or `null`. */\n readonly current = this._current.asReadonly();\n\n /** Shows a toast, replacing whatever is currently shown. Returns its id. */\n show(message: string, options: ToastOptions = {}): number {\n const id = this.nextId++;\n const tone = options.tone ?? 'info';\n const duration = options.duration ?? DEFAULT_DURATION_MS;\n clearTimeout(this.dismissTimer);\n clearTimeout(this.removeTimer);\n this._current.set({ id, message, tone, duration, leaving: false });\n if (tone !== 'loading') {\n this.dismissTimer = setTimeout(() => this.dismiss(id), duration);\n }\n return id;\n }\n\n /**\n * Starts the exit animation, then removes the toast. No-op when `id` is no\n * longer the active toast, so a stale timer never kills a newer toast.\n */\n dismiss(id?: number): void {\n const toast = this._current();\n if (!toast || toast.leaving || (id !== undefined && toast.id !== id)) return;\n clearTimeout(this.dismissTimer);\n this._current.set({ ...toast, leaving: true });\n this.removeTimer = setTimeout(() => {\n if (this._current()?.id === toast.id) this._current.set(null);\n }, EXIT_ANIMATION_MS);\n }\n\n /**\n * Shows a `loading` toast, then swaps it for a `success`/`error` toast once\n * `work` settles. Re-throws `work`'s rejection so callers can still react to\n * the failure.\n */\n promise<T>(work: Promise<T>, messages: ToastPromiseMessages<T> = {}): Promise<T> {\n this.show(messages.loading ?? 'Procesando…', { tone: 'loading' });\n return work.then(\n (value) => {\n const msg = messages.success ?? 'Listo';\n this.show(typeof msg === 'function' ? msg(value) : msg, { tone: 'success' });\n return value;\n },\n (error) => {\n const msg = messages.error ?? 'Ocurrió un error';\n this.show(typeof msg === 'function' ? msg(error) : msg, { tone: 'error' });\n throw error;\n },\n );\n }\n}\n\n/**\n * Renders whatever `ToastService` currently holds, fixed bottom-right. Mount\n * one instance in the app shell (e.g. next to the router outlet); it takes no\n * inputs and re-renders itself from the service state.\n *\n * <kf-toast-host />\n */\n@Component({\n selector: 'kf-toast-host',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [Icon],\n template: `\n @for (t of toastList(); track t.id) {\n <div\n class=\"kf-toast kf-toast--{{ t.tone }}\"\n [class.kf-toast--leaving]=\"t.leaving\"\n role=\"status\"\n [attr.aria-live]=\"t.tone === 'error' ? 'assertive' : 'polite'\"\n >\n <kf-icon class=\"kf-toast__icon\" [name]=\"toastIcon(t.tone)\" size=\"sm\" />\n <span class=\"kf-toast__message\">{{ t.message }}</span>\n <button type=\"button\" class=\"kf-toast__dismiss\" aria-label=\"Cerrar\" (click)=\"dismiss(t.id)\">\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n <span class=\"kf-toast__bar\" [style.--kf-toast-dur]=\"t.duration + 'ms'\"></span>\n </div>\n }\n `,\n styles: `\n @keyframes kf-toast-in {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n }\n @keyframes kf-toast-bar {\n from {\n transform: scaleX(1);\n }\n to {\n transform: scaleX(0);\n }\n }\n @keyframes kf-toast-indeterminate {\n 0% {\n left: -40%;\n width: 40%;\n }\n 50% {\n left: 30%;\n width: 55%;\n }\n 100% {\n left: 100%;\n width: 40%;\n }\n }\n\n .kf-toast {\n /* Per-tone accent, overridden by the tone classes below. */\n --kf-toast-accent: var(--kf-color-info);\n\n position: fixed;\n inset-block-end: var(--kf-space-lg);\n inset-inline-end: var(--kf-space-lg);\n z-index: 1100;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n max-inline-size: 360px;\n padding: var(--kf-space-sm) var(--kf-space-sm) var(--kf-space-sm) var(--kf-space-md);\n border-radius: var(--kf-radius-md);\n border-left: 4px solid var(--kf-toast-accent);\n background: var(--kf-color-ink);\n color: var(--kf-color-white);\n box-shadow: var(--kf-shadow-lg);\n font-family: var(--kf-font-body);\n font-size: 0.875rem;\n font-weight: 600;\n line-height: 1.4;\n overflow: hidden;\n animation: kf-toast-in 0.25s ease forwards;\n transition:\n transform 0.2s ease,\n opacity 0.2s ease;\n }\n .kf-toast--leaving {\n transform: translateY(20px);\n opacity: 0;\n }\n .kf-toast--success {\n --kf-toast-accent: var(--kf-color-success);\n }\n .kf-toast--error {\n --kf-toast-accent: var(--kf-color-error);\n }\n .kf-toast--warning {\n --kf-toast-accent: var(--kf-color-warning);\n }\n .kf-toast--info,\n .kf-toast--loading {\n --kf-toast-accent: var(--kf-color-info);\n }\n\n .kf-toast__icon {\n flex: none;\n color: var(--kf-toast-accent);\n }\n .kf-toast__message {\n flex: 1;\n }\n .kf-toast__dismiss {\n flex: none;\n display: grid;\n place-items: center;\n inline-size: 24px;\n block-size: 24px;\n padding: 0;\n border: none;\n border-radius: var(--kf-radius-xs);\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1;\n cursor: pointer;\n opacity: 0.6;\n }\n .kf-toast__dismiss:hover {\n opacity: 1;\n }\n\n .kf-toast__bar {\n position: absolute;\n inset-block-end: 0;\n left: 0;\n block-size: 3px;\n inline-size: 100%;\n background: var(--kf-toast-accent);\n opacity: 0.7;\n transform-origin: left;\n animation: kf-toast-bar var(--kf-toast-dur, 2800ms) linear forwards;\n }\n .kf-toast--loading .kf-toast__bar {\n left: -40%;\n inline-size: 40%;\n opacity: 0.6;\n animation: kf-toast-indeterminate 1.4s ease-in-out infinite;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .kf-toast,\n .kf-toast__bar,\n .kf-toast--loading .kf-toast__bar {\n animation: none;\n }\n .kf-toast {\n transition: none;\n }\n }\n `,\n})\nexport class ToastHost {\n private readonly toastService = inject(ToastService);\n\n /** 0-or-1 wrapper so `@for track t.id` remounts the node on every new toast, restarting its animations. */\n protected readonly toastList = computed<ToastState[]>(() => {\n const toast = this.toastService.current();\n return toast ? [toast] : [];\n });\n\n protected toastIcon(tone: ToastTone): IconName {\n return TOAST_ICON[tone];\n }\n\n protected dismiss(id: number): void {\n this.toastService.dismiss(id);\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Estado puntual mostrado junto a la identidad del vehículo (ej. \"En ruta\",\n * \"Mantenimiento\", \"Fuera de servicio\"). `tone` define el color semántico:\n * \"crit\" no tiene token propio en base.css, se mapea a var(--kf-color-error).\n */\nexport interface VehicleHeaderStatus {\n label: string;\n tone?: 'ok' | 'warn' | 'crit';\n icon?: IconName;\n}\n\n/**\n * Header de identidad de un vehículo de flota: unidad (patente/id), modelo\n * (como badge, no texto plano — página 24: \"ABC-123\" junto a un badge\n * \"TITAN 4X2\"), VIN en fuente mono y un estado opcional. Un área de acciones\n * opcional se proyecta vía `<ng-content select=\"[actions]\">` para no acoplar\n * el componente a un set fijo de botones — el patrón real de la spec es\n * `kf-button variant=\"outline\"` (ej. \"Llamar\", con ícono) + un `primary`\n * (ej. \"Crear Ticket\", con ícono \"+\"):\n *\n * <kf-vehicle-header unit=\"AB123CD\" model=\"Sprinter 415\" vin=\"9BW...\"\n * [status]=\"{ label: 'En ruta', tone: 'ok' }\">\n * <kf-button actions variant=\"outline\" icon=\"phone\">Llamar</kf-button>\n * <kf-button actions icon=\"plus\">Crear Ticket</kf-button>\n * </kf-vehicle-header>\n */\n@Component({\n selector: 'kf-vehicle-header',\n imports: [Icon],\n template: `\n <div class=\"kf-vehicle-header__identity\">\n <span class=\"kf-vehicle-header__unit\">{{ unit() }}</span>\n @if (model()) {\n <span class=\"kf-vehicle-header__model\">{{ model() }}</span>\n }\n @if (vin()) {\n <span class=\"kf-vehicle-header__vin\">VIN: {{ vin() }}</span>\n }\n </div>\n\n @if (status(); as currentStatus) {\n <span\n class=\"kf-vehicle-header__status\"\n [class]=\"'kf-vehicle-header__status--' + (currentStatus.tone ?? 'ok')\"\n >\n @if (currentStatus.icon; as iconName) {\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n }\n {{ currentStatus.label }}\n </span>\n }\n\n <div class=\"kf-vehicle-header__actions\">\n <ng-content select=\"[actions]\" />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-md);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-surface);\n font-family: var(--kf-font-body);\n }\n .kf-vehicle-header__identity {\n display: flex;\n align-items: baseline;\n flex-wrap: wrap;\n gap: var(--kf-space-sm);\n flex: 1 1 auto;\n min-width: 0;\n }\n .kf-vehicle-header__unit {\n font-family: var(--kf-font-title);\n font-size: 1.125rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-vehicle-header__model {\n padding: 2px var(--kf-space-sm);\n border-radius: var(--kf-radius-xs);\n background: var(--kf-color-border);\n color: var(--kf-color-text-muted);\n font-size: 0.75rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n }\n .kf-vehicle-header__vin {\n font-family: var(--kf-font-mono);\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-vehicle-header__status {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1;\n white-space: nowrap;\n }\n .kf-vehicle-header__status--ok {\n background: var(--kf-color-success-soft);\n color: var(--kf-color-success);\n }\n .kf-vehicle-header__status--warn {\n background: var(--kf-color-warning-soft);\n color: var(--kf-color-warning);\n }\n .kf-vehicle-header__status--crit {\n background: var(--kf-color-error-soft);\n color: var(--kf-color-error);\n }\n .kf-vehicle-header__actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class VehicleHeader {\n readonly unit = input.required<string>();\n readonly model = input<string>();\n readonly vin = input<string>();\n readonly status = input<VehicleHeaderStatus>();\n}\n","import { Component, input, output } from '@angular/core';\n\nexport type ViewToggleOption = 'table' | 'cards';\n\n/**\n * Switch de dos posiciones para alternar entre vista de tabla y vista de\n * tarjetas. Pensado para usarse dentro de DataTable, pero es standalone e\n * independiente: no asume nada sobre el componente que lo contiene.\n *\n * Se implementa como un grupo de radio (role=\"radiogroup\") en vez de dos\n * botones sueltos: semánticamente es una única selección excluyente entre\n * dos estados, no dos acciones independientes. Esto también habilita\n * navegación con flechas izquierda/derecha, igual que un <input type=\"radio\">\n * nativo agrupado.\n *\n * <kf-view-toggle [view]=\"view\" (viewChange)=\"view = $event\" />\n */\n@Component({\n selector: 'kf-view-toggle',\n template: `\n <div class=\"kf-view-toggle\" role=\"radiogroup\" aria-label=\"Alternar tipo de vista\">\n <button\n type=\"button\"\n role=\"radio\"\n class=\"kf-view-toggle__option\"\n [class.kf-view-toggle__option--active]=\"view() === 'table'\"\n [attr.aria-checked]=\"view() === 'table'\"\n [attr.tabindex]=\"view() === 'table' ? 0 : -1\"\n (click)=\"select('table')\"\n (keydown)=\"onKeydown($event)\"\n >\n Tabla\n </button>\n <button\n type=\"button\"\n role=\"radio\"\n class=\"kf-view-toggle__option\"\n [class.kf-view-toggle__option--active]=\"view() === 'cards'\"\n [attr.aria-checked]=\"view() === 'cards'\"\n [attr.tabindex]=\"view() === 'cards' ? 0 : -1\"\n (click)=\"select('cards')\"\n (keydown)=\"onKeydown($event)\"\n >\n Tarjetas\n </button>\n </div>\n `,\n styles: `\n :host {\n display: inline-block;\n font-family: var(--kf-font-body);\n }\n .kf-view-toggle {\n display: inline-flex;\n align-items: stretch;\n gap: 2px;\n padding: 2px;\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n }\n .kf-view-toggle__option {\n font: inherit;\n font-size: 0.85rem;\n line-height: 1;\n color: var(--kf-color-text-muted);\n background: transparent;\n border: none;\n border-radius: var(--kf-radius-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n cursor: pointer;\n transition:\n background 0.14s,\n color 0.14s,\n box-shadow 0.14s;\n }\n .kf-view-toggle__option:hover:not(.kf-view-toggle__option--active) {\n color: var(--kf-color-text);\n }\n .kf-view-toggle__option:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-view-toggle__option--active {\n color: var(--kf-color-ink);\n background: var(--kf-color-white);\n box-shadow: var(--kf-shadow-xs);\n }\n `,\n})\nexport class ViewToggle {\n readonly view = input.required<ViewToggleOption>();\n readonly viewChange = output<ViewToggleOption>();\n\n select(next: ViewToggleOption): void {\n if (next === this.view()) {\n return;\n }\n this.viewChange.emit(next);\n }\n\n /** Navegación estándar de ARIA radiogroup: flechas mueven foco y seleccionan. */\n onKeydown(event: KeyboardEvent): void {\n if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') {\n return;\n }\n\n event.preventDefault();\n const next: ViewToggleOption = this.view() === 'table' ? 'cards' : 'table';\n this.select(next);\n\n const current = event.currentTarget as HTMLElement;\n const buttons =\n current.parentElement?.querySelectorAll<HTMLButtonElement>('.kf-view-toggle__option');\n const nextButton = Array.from(buttons ?? []).find((button) => button !== current);\n nextButton?.focus();\n }\n}\n","/*\n * Public API Surface of ui\n */\n\nexport * from './lib/action-tile/ActionTile';\nexport * from './lib/admin-badge/AdminBadge';\nexport * from './lib/button/button';\nexport * from './lib/alert/Alert';\nexport * from './lib/avatar/Avatar';\nexport * from './lib/badge/Badge';\nexport * from './lib/breadcrumb/Breadcrumb';\nexport * from './lib/card/Card';\nexport * from './lib/carousel/Carousel';\nexport * from './lib/checkbox/Checkbox';\nexport * from './lib/chip/Chip';\nexport * from './lib/company-selector/CompanySelector';\nexport * from './lib/content-slot/ContentSlot';\nexport * from './lib/content-state/ContentState';\nexport * from './lib/data-table/DataTable';\nexport * from './lib/empty-state/EmptyState';\nexport * from './lib/feature-card/FeatureCard';\nexport * from './lib/field/Field';\nexport * from './lib/field-label/FieldLabel';\nexport * from './lib/filter-chips/FilterChips';\nexport * from './lib/folder-tabs/FolderTabs';\nexport * from './lib/icon/Icon';\nexport * from './lib/input/Input';\nexport * from './lib/metric-card/MetricCard';\nexport * from './lib/modal/Modal';\nexport * from './lib/multi-select/MultiSelect';\nexport * from './lib/page-header/PageHeader';\nexport * from './lib/pagination/Pagination';\nexport * from './lib/panel/Panel';\nexport * from './lib/portal-header/PortalHeader';\nexport * from './lib/reserve-block/ReserveBlock';\nexport * from './lib/section-header/SectionHeader';\nexport * from './lib/segmented/Segmented';\nexport * from './lib/select/Select';\nexport * from './lib/select-menu/SelectMenu';\nexport * from './lib/skeleton/Skeleton';\nexport * from './lib/spinner/Spinner';\nexport * from './lib/stat-tile/StatTile';\nexport * from './lib/status-pill/StatusPill';\nexport * from './lib/tabs/Tabs';\nexport * from './lib/toast/Toast';\nexport * from './lib/vehicle-header/VehicleHeader';\nexport * from './lib/view-toggle/ViewToggle';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["nextId"],"mappings":"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"}