@c80/ui 1.0.42 → 1.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/c80-ui.d.ts +5 -0
- package/esm2022/c80-ui.js +5 -0
- package/esm2022/c80-ui.js.map +1 -0
- package/esm2022/index.js +6 -0
- package/esm2022/index.js.map +1 -0
- package/esm2022/lib/card-level/card-level.component.js +56 -0
- package/esm2022/lib/card-level/card-level.component.js.map +1 -0
- package/esm2022/lib/card-level/card-level.interface.js +2 -0
- package/esm2022/lib/card-level/card-level.interface.js.map +1 -0
- package/esm2022/lib/card-level/index.js +3 -0
- package/esm2022/lib/card-level/index.js.map +1 -0
- package/esm2022/lib/icon/icon.component.js +48 -0
- package/esm2022/lib/icon/icon.component.js.map +1 -0
- package/esm2022/lib/icon/icon.constants.js +237 -0
- package/esm2022/lib/icon/icon.constants.js.map +1 -0
- package/esm2022/lib/icon/icon.types.js +2 -0
- package/esm2022/lib/icon/icon.types.js.map +1 -0
- package/esm2022/lib/icon/icon.utils.js +4 -0
- package/esm2022/lib/icon/icon.utils.js.map +1 -0
- package/esm2022/lib/icon/index.js +4 -0
- package/esm2022/lib/icon/index.js.map +1 -0
- package/esm2022/lib/modal/index.js +3 -0
- package/esm2022/lib/modal/index.js.map +1 -0
- package/esm2022/lib/modal/modal.component.js +86 -0
- package/esm2022/lib/modal/modal.component.js.map +1 -0
- package/esm2022/lib/modal/modal.service.js +83 -0
- package/esm2022/lib/modal/modal.service.js.map +1 -0
- package/esm2022/lib/stat-card/index.js +2 -0
- package/esm2022/lib/stat-card/index.js.map +1 -0
- package/esm2022/lib/stat-card/stat-card.component.js +13 -0
- package/esm2022/lib/stat-card/stat-card.component.js.map +1 -0
- package/esm2022/lib/table/index.js +9 -0
- package/esm2022/lib/table/index.js.map +1 -0
- package/esm2022/lib/table/table-column-visibility.service.js +105 -0
- package/esm2022/lib/table/table-column-visibility.service.js.map +1 -0
- package/esm2022/lib/table/table-crud-state.service.js +115 -0
- package/esm2022/lib/table/table-crud-state.service.js.map +1 -0
- package/esm2022/lib/table/table-data-converter.service.js +145 -0
- package/esm2022/lib/table/table-data-converter.service.js.map +1 -0
- package/esm2022/lib/table/table-data-utils.service.js +193 -0
- package/esm2022/lib/table/table-data-utils.service.js.map +1 -0
- package/esm2022/lib/table/table-selection.service.js +121 -0
- package/esm2022/lib/table/table-selection.service.js.map +1 -0
- package/esm2022/lib/table/table.component.js +413 -0
- package/esm2022/lib/table/table.component.js.map +1 -0
- package/esm2022/lib/table/table.types.js +5 -0
- package/esm2022/lib/table/table.types.js.map +1 -0
- package/esm2022/lib/table/table.utils.js +107 -0
- package/esm2022/lib/table/table.utils.js.map +1 -0
- package/lib/icon/icon.component.d.ts +1 -1
- package/lib/modal/index.d.ts +2 -3
- package/lib/stat-card/stat-card.component.d.ts +2 -2
- package/lib/table/index.d.ts +1 -0
- package/lib/table/table-column-visibility.service.d.ts +17 -35
- package/lib/table/table-crud-state.service.d.ts +10 -27
- package/lib/table/table-data-utils.service.d.ts +15 -5
- package/lib/table/table-selection.service.d.ts +19 -18
- package/lib/table/table.component.d.ts +123 -98
- package/lib/table/table.types.d.ts +25 -2
- package/lib/table/table.utils.d.ts +42 -0
- package/package.json +7 -9
- package/esm2022/c80-ui.mjs +0 -5
- package/esm2022/index.mjs +0 -6
- package/esm2022/lib/card-level/card-level.component.mjs +0 -57
- package/esm2022/lib/card-level/card-level.interface.mjs +0 -2
- package/esm2022/lib/card-level/index.mjs +0 -3
- package/esm2022/lib/icon/icon.component.mjs +0 -49
- package/esm2022/lib/icon/icon.constants.mjs +0 -237
- package/esm2022/lib/icon/icon.types.mjs +0 -2
- package/esm2022/lib/icon/icon.utils.mjs +0 -4
- package/esm2022/lib/icon/index.mjs +0 -4
- package/esm2022/lib/modal/index.mjs +0 -3
- package/esm2022/lib/modal/modal.component.mjs +0 -86
- package/esm2022/lib/modal/modal.service.mjs +0 -83
- package/esm2022/lib/stat-card/index.mjs +0 -2
- package/esm2022/lib/stat-card/stat-card.component.mjs +0 -16
- package/esm2022/lib/table/index.mjs +0 -8
- package/esm2022/lib/table/table-column-visibility.service.mjs +0 -156
- package/esm2022/lib/table/table-crud-state.service.mjs +0 -186
- package/esm2022/lib/table/table-data-converter.service.mjs +0 -145
- package/esm2022/lib/table/table-data-utils.service.mjs +0 -166
- package/esm2022/lib/table/table-selection.service.mjs +0 -138
- package/esm2022/lib/table/table.component.mjs +0 -476
- package/esm2022/lib/table/table.types.mjs +0 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OnInit, OnDestroy } from '@angular/core';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { C80TableColDef, CustomTableAction } from './table.types';
|
|
4
|
+
import { getActionTooltip } from './table.utils';
|
|
5
5
|
import * as i0 from "@angular/core";
|
|
6
6
|
/**
|
|
7
7
|
* C80TableComponent - Componente de tabla avanzado con funcionalidades CRUD
|
|
@@ -51,142 +51,170 @@ import * as i0 from "@angular/core";
|
|
|
51
51
|
* - 'password': Texto oculto (input type="password")
|
|
52
52
|
* - 'enum': Lista de opciones predefinidas (select)
|
|
53
53
|
*
|
|
54
|
-
*
|
|
54
|
+
* SISTEMA DE ACCIONES UNIFICADO (customActions):
|
|
55
|
+
* =============================================
|
|
56
|
+
*
|
|
57
|
+
* Input: `customActions: CustomTableAction[]` - Array de acciones dinámicas
|
|
58
|
+
* Output: `(actionClick)` - Evento unificado que emite { action: string, row: T }
|
|
59
|
+
*
|
|
60
|
+
* ACCIONES CRUD PREDEFINIDAS (TABLE_CRUD_ACTIONS):
|
|
61
|
+
* ------------------------------------------------
|
|
62
|
+
* - CREATE: Solo aparece como botón "+" en header (no en filas)
|
|
63
|
+
* - UPDATE: Activa modo edición (muestra inputs), botón "✓" guarda cambios
|
|
64
|
+
* - DELETE: Muestra confirmación y emite evento delete
|
|
65
|
+
* - CANCEL: Muestra confirmación y emite evento cancel (opcional)
|
|
66
|
+
*
|
|
67
|
+
* ACCIONES PERSONALIZADAS (Custom Actions):
|
|
68
|
+
* -----------------------------------------
|
|
69
|
+
* Interfaz: { name: string, icon: IconType, condition?: (row) => boolean, tooltip?: string }
|
|
70
|
+
* - name: ID único de la acción
|
|
71
|
+
* - icon: Icono del botón (ej: 'settings', 'upload', 'refresh')
|
|
72
|
+
* - condition: Función opcional para mostrar/ocultar según estado de fila
|
|
73
|
+
* - tooltip: Texto al hacer hover (default: name)
|
|
74
|
+
*
|
|
75
|
+
* MANEJO EN COMPONENTE:
|
|
76
|
+
* --------------------
|
|
77
|
+
* ```typescript
|
|
78
|
+
* // 1. Definir acciones en constants:
|
|
79
|
+
* export const ENTITY_TABLE_ACTIONS: CustomTableAction[] = [
|
|
80
|
+
* TABLE_CRUD_ACTIONS.CREATE,
|
|
81
|
+
* TABLE_CRUD_ACTIONS.UPDATE,
|
|
82
|
+
* { name: 'custom-action', icon: 'settings', tooltip: 'Configurar' },
|
|
83
|
+
* TABLE_CRUD_ACTIONS.DELETE
|
|
84
|
+
* ];
|
|
85
|
+
*
|
|
86
|
+
* // 2. En el componente:
|
|
87
|
+
* readonly tableActions = ENTITY_TABLE_ACTIONS;
|
|
88
|
+
*
|
|
89
|
+
* handleAction({ action, row }) {
|
|
90
|
+
* const entity = row as unknown as EntityType;
|
|
91
|
+
* switch (action) {
|
|
92
|
+
* case 'create': this.onCreate(row); break;
|
|
93
|
+
* case 'update': this.onUpdate(entity); break;
|
|
94
|
+
* case 'delete': this.onDelete(entity.id); break;
|
|
95
|
+
* case 'custom-action': this.onCustom(entity); break;
|
|
96
|
+
* }
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* ACCIONES CON CONDICIÓN:
|
|
101
|
+
* ----------------------
|
|
102
|
+
* ```typescript
|
|
103
|
+
* {
|
|
104
|
+
* name: 'enable',
|
|
105
|
+
* icon: 'toggleOn',
|
|
106
|
+
* tooltip: 'Habilitar',
|
|
107
|
+
* condition: (row) => row['enabled'] === false
|
|
108
|
+
* }
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* CONSTANTES REUTILIZABLES:
|
|
112
|
+
* ------------------------
|
|
113
|
+
* - TABLE_CRUD_ACTIONS: Objeto con CREATE, UPDATE, DELETE, CANCEL
|
|
114
|
+
* - BASIC_CRUD_ACTIONS: Array con [CREATE, UPDATE, DELETE]
|
|
115
|
+
* Importar desde: `@shared` o `@shared/constants`
|
|
116
|
+
*
|
|
117
|
+
* EJEMPLOS COMPLETOS:
|
|
118
|
+
* ------------------
|
|
55
119
|
* - { accessor: 'id', visible: false } → NUNCA se muestra
|
|
56
120
|
* - { accessor: 'motorPos', hideIfAllValuesAreNull: true, default: 0, type: 'integer' } → Entero (5.7 → 5)
|
|
57
121
|
* - { accessor: 'weight', type: 'number', default: 2.5 } → Decimal preservado (5.7 → 5.7)
|
|
58
122
|
* - { accessor: 'status', default: 'active' } → Se autorellena con 'active' en creación
|
|
59
123
|
* - { accessor: 'name' } → Siempre visible, sin valor por defecto (cadena vacía)
|
|
60
124
|
* - inputValues$ emite { motorPos: 5, weight: 2.3 } → actualiza inputs dinámicamente
|
|
125
|
+
* - customActions con CREATE → Muestra botón "+" en header
|
|
126
|
+
* - customActions con UPDATE → Botón "edit" activa modo edición
|
|
127
|
+
* - customActions con custom → Botón personalizado emite evento
|
|
61
128
|
*/ export declare class C80TableComponent<T extends Record<string, unknown>> implements OnInit, OnDestroy {
|
|
62
129
|
private readonly modalService;
|
|
63
130
|
private readonly visibilityService;
|
|
64
131
|
private readonly dataUtils;
|
|
132
|
+
private readonly dataConverter;
|
|
65
133
|
private readonly selectionService;
|
|
66
134
|
private readonly crudService;
|
|
67
|
-
data$: Observable<T[]
|
|
68
|
-
columns: C80TableColDef[]
|
|
69
|
-
inputValues
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
updateAction: EventEmitter<{
|
|
80
|
-
id: ID;
|
|
81
|
-
changes: Partial<T>;
|
|
82
|
-
done: (result: boolean) => void;
|
|
83
|
-
}>;
|
|
84
|
-
deleteAction: EventEmitter<{
|
|
85
|
-
id: ID;
|
|
86
|
-
done: (result: boolean) => void;
|
|
135
|
+
readonly data$: import("@angular/core").InputSignal<Observable<T[]>>;
|
|
136
|
+
readonly columns: import("@angular/core").InputSignal<C80TableColDef[]>;
|
|
137
|
+
readonly inputValues$: import("@angular/core").InputSignal<Observable<Partial<T>> | undefined>;
|
|
138
|
+
readonly customActions: import("@angular/core").InputSignal<CustomTableAction[]>;
|
|
139
|
+
readonly size: import("@angular/core").InputSignal<number>;
|
|
140
|
+
readonly multiple: import("@angular/core").InputSignal<boolean>;
|
|
141
|
+
readonly searchable: import("@angular/core").InputSignalWithTransform<boolean, string | boolean>;
|
|
142
|
+
readonly allowSelection: import("@angular/core").InputSignalWithTransform<boolean, string | boolean>;
|
|
143
|
+
readonly noConfirm: import("@angular/core").InputSignalWithTransform<boolean, string | boolean>;
|
|
144
|
+
readonly actionClick: import("@angular/core").OutputEmitterRef<{
|
|
145
|
+
action: string;
|
|
146
|
+
row: T;
|
|
87
147
|
}>;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}>;
|
|
92
|
-
viewAction: EventEmitter<T>;
|
|
93
|
-
uploadAction: EventEmitter<T>;
|
|
94
|
-
getRowButtonAction: EventEmitter<T>;
|
|
95
|
-
customAction: EventEmitter<T>;
|
|
96
|
-
moveUpAction: EventEmitter<{
|
|
97
|
-
id: ID;
|
|
98
|
-
done: (result: boolean) => void;
|
|
99
|
-
}>;
|
|
100
|
-
moveDownAction: EventEmitter<{
|
|
101
|
-
id: ID;
|
|
102
|
-
done: (result: boolean) => void;
|
|
103
|
-
}>;
|
|
104
|
-
enableAction: EventEmitter<{
|
|
105
|
-
id: ID;
|
|
106
|
-
enabled: boolean;
|
|
107
|
-
done: (result: boolean) => void;
|
|
108
|
-
}>;
|
|
109
|
-
searchTerm: EventEmitter<string>;
|
|
110
|
-
errorEvent: EventEmitter<string>;
|
|
111
|
-
selectable: EventEmitter<T[]>;
|
|
148
|
+
readonly searchTerm: import("@angular/core").OutputEmitterRef<string>;
|
|
149
|
+
readonly errorEvent: import("@angular/core").OutputEmitterRef<string>;
|
|
150
|
+
readonly selectable: import("@angular/core").OutputEmitterRef<T[]>;
|
|
112
151
|
readonly data: import("@angular/core").WritableSignal<T[]>;
|
|
113
|
-
readonly keys: import("@angular/core").WritableSignal<string[]>;
|
|
114
152
|
readonly searchValue: import("@angular/core").WritableSignal<string>;
|
|
115
153
|
private readonly selectionState;
|
|
116
|
-
readonly selectedItems: import("@angular/core").Signal<Set<
|
|
154
|
+
readonly selectedItems: import("@angular/core").Signal<Set<string>>;
|
|
117
155
|
readonly selectAllChecked: import("@angular/core").Signal<boolean>;
|
|
118
156
|
readonly selectAllIndeterminate: import("@angular/core").Signal<boolean>;
|
|
119
157
|
private readonly crudState;
|
|
120
158
|
readonly creating: import("@angular/core").Signal<boolean>;
|
|
121
159
|
readonly newRow: import("@angular/core").Signal<Partial<T> | null>;
|
|
122
|
-
readonly editing: import("@angular/core").Signal<
|
|
160
|
+
readonly editing: import("@angular/core").Signal<string | null>;
|
|
123
161
|
readonly editRow: import("@angular/core").Signal<Partial<T> | null>;
|
|
124
|
-
readonly
|
|
125
|
-
readonly
|
|
126
|
-
readonly
|
|
127
|
-
readonly
|
|
128
|
-
readonly
|
|
129
|
-
readonly
|
|
130
|
-
readonly
|
|
131
|
-
readonly hasCustomActionListener: import("@angular/core").WritableSignal<boolean>;
|
|
132
|
-
readonly hasMoveUpActionListener: import("@angular/core").WritableSignal<boolean>;
|
|
133
|
-
readonly hasMoveDownActionListener: import("@angular/core").WritableSignal<boolean>;
|
|
134
|
-
readonly hasEnableActionListener: import("@angular/core").WritableSignal<boolean>;
|
|
135
|
-
readonly hasSearchTermListener: import("@angular/core").WritableSignal<boolean>;
|
|
136
|
-
readonly hasSelectableListener: import("@angular/core").WritableSignal<boolean>;
|
|
162
|
+
readonly keys: import("@angular/core").Signal<string[]>;
|
|
163
|
+
readonly hasAnyActions: import("@angular/core").Signal<boolean>;
|
|
164
|
+
readonly hasCrudCreate: import("@angular/core").Signal<boolean>;
|
|
165
|
+
readonly hasCrudUpdate: import("@angular/core").Signal<boolean>;
|
|
166
|
+
readonly hasCrudDelete: import("@angular/core").Signal<boolean>;
|
|
167
|
+
readonly hasCrudCancel: import("@angular/core").Signal<boolean>;
|
|
168
|
+
readonly tableMaxHeight: import("@angular/core").Signal<string | undefined>;
|
|
137
169
|
private dataSub?;
|
|
138
170
|
private inputValuesSub?;
|
|
139
|
-
private getErrorMessage;
|
|
140
171
|
/**
|
|
141
|
-
*
|
|
172
|
+
* Maneja input de creación/edición de forma unificada
|
|
142
173
|
*/
|
|
143
|
-
private
|
|
174
|
+
private handleInput;
|
|
144
175
|
/**
|
|
145
|
-
*
|
|
146
|
-
* Solo actualiza si estamos en modo creación (creating = true) o edición (editing != null)
|
|
176
|
+
* Maneja confirmación modal de forma genérica
|
|
147
177
|
*/
|
|
148
|
-
private
|
|
178
|
+
private handleConfirmAction;
|
|
149
179
|
ngOnInit(): void;
|
|
150
180
|
ngOnDestroy(): void;
|
|
151
181
|
onInput(event: Event, key: string, col?: C80TableColDef): void;
|
|
182
|
+
onEditInput(event: Event, key: string, col?: C80TableColDef): void;
|
|
152
183
|
onDelete(row: T): Promise<void>;
|
|
153
184
|
onCancel(row: T): Promise<void>;
|
|
154
185
|
startCreate(): void;
|
|
155
186
|
cancelCreate(): void;
|
|
156
|
-
updateNewRow(key: string, value: unknown): void;
|
|
157
187
|
saveCreate(): void;
|
|
158
188
|
onEdit(row: T): void;
|
|
159
189
|
cancelEdit(): void;
|
|
160
|
-
onEditInput(event: Event, key: string, col?: C80TableColDef): void;
|
|
161
190
|
saveEdit(row: T): void;
|
|
162
191
|
/**
|
|
163
|
-
*
|
|
192
|
+
* Convierte todos los valores de una fila según los tipos definidos en las columnas
|
|
193
|
+
* Asegura que los datos emitidos tengan el tipo correcto (integer, number, boolean, etc.)
|
|
164
194
|
*/
|
|
165
|
-
|
|
195
|
+
private convertRowTypes;
|
|
166
196
|
/**
|
|
167
|
-
*
|
|
168
|
-
*/
|
|
169
|
-
onView(row: T): void;
|
|
170
|
-
/**
|
|
171
|
-
* Emits the getRowButtonAction event with the entire row data
|
|
197
|
+
* TrackBy function for ngFor to avoid DOM re-creation (NG0956 warning).
|
|
172
198
|
*/
|
|
173
|
-
|
|
199
|
+
readonly trackById: (index: number, row: T) => string | number;
|
|
174
200
|
/**
|
|
175
|
-
*
|
|
201
|
+
* Verifica si una acción personalizada debe mostrarse para una fila específica
|
|
176
202
|
*/
|
|
177
|
-
|
|
203
|
+
readonly shouldShowAction: (action: CustomTableAction, row: T) => boolean;
|
|
178
204
|
/**
|
|
179
|
-
*
|
|
205
|
+
* Obtiene el tooltip de una acción
|
|
180
206
|
*/
|
|
181
|
-
|
|
207
|
+
readonly getActionTooltip: typeof getActionTooltip;
|
|
182
208
|
/**
|
|
183
|
-
*
|
|
209
|
+
* Maneja el click en una acción personalizada dinámica
|
|
210
|
+
* UPDATE activa el modo edición, otras acciones emiten directamente
|
|
211
|
+
* Si la acción tiene configuración de confirmación, muestra modal antes de ejecutar
|
|
184
212
|
*/
|
|
185
|
-
|
|
213
|
+
onDynamicAction(action: CustomTableAction, row: T): void;
|
|
186
214
|
/**
|
|
187
|
-
*
|
|
215
|
+
* Maneja acciones que requieren confirmación del usuario
|
|
188
216
|
*/
|
|
189
|
-
|
|
217
|
+
private handleActionWithConfirmation;
|
|
190
218
|
/**
|
|
191
219
|
* Handles search input changes with debouncing
|
|
192
220
|
*/
|
|
@@ -195,15 +223,14 @@ import * as i0 from "@angular/core";
|
|
|
195
223
|
* Clears the search input
|
|
196
224
|
*/
|
|
197
225
|
clearSearch(): void;
|
|
198
|
-
getCellValue(row:
|
|
199
|
-
getDisplayValue(value: unknown)
|
|
200
|
-
getEnumDisplayValue(value: unknown, col: C80TableColDef)
|
|
201
|
-
getEnumOptions(col: C80TableColDef)
|
|
226
|
+
readonly getCellValue: <T_1 extends Record<string, unknown>>(row: T_1, accessor: string) => unknown;
|
|
227
|
+
readonly getDisplayValue: (value: unknown, col?: C80TableColDef) => string;
|
|
228
|
+
readonly getEnumDisplayValue: (value: unknown, col: C80TableColDef) => string;
|
|
229
|
+
readonly getEnumOptions: (col: C80TableColDef) => {
|
|
202
230
|
value: string | number;
|
|
203
231
|
label: string;
|
|
204
232
|
}[];
|
|
205
|
-
getCellColor(value: unknown, col: C80TableColDef)
|
|
206
|
-
getTableMaxHeight(): string | undefined;
|
|
233
|
+
readonly getCellColor: (value: unknown, col: C80TableColDef) => string | undefined;
|
|
207
234
|
/**
|
|
208
235
|
* Selection methods
|
|
209
236
|
*/
|
|
@@ -216,11 +243,9 @@ import * as i0 from "@angular/core";
|
|
|
216
243
|
toggleSelectAll(): void;
|
|
217
244
|
toggleItemSelection(item: T): void;
|
|
218
245
|
isItemSelected(item: T): boolean;
|
|
219
|
-
isColumnVisible(column: C80TableColDef
|
|
246
|
+
isColumnVisible(column: C80TableColDef): boolean;
|
|
220
247
|
isColumnVisibleInHeader(column: C80TableColDef): boolean;
|
|
221
248
|
isColumnVisibleForRow(column: C80TableColDef, row: T): boolean;
|
|
222
|
-
onUpload(row: T): void;
|
|
223
249
|
static ɵfac: i0.ɵɵFactoryDeclaration<C80TableComponent<any>, never>;
|
|
224
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<C80TableComponent<any>, "c80-table", never, { "data$": { "alias": "data$"; "required":
|
|
225
|
-
static ngAcceptInputType_noConfirm: boolean | string;
|
|
250
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<C80TableComponent<any>, "c80-table", never, { "data$": { "alias": "data$"; "required": true; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "inputValues$": { "alias": "inputValues$"; "required": false; "isSignal": true; }; "customActions": { "alias": "customActions"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "allowSelection": { "alias": "allowSelection"; "required": false; "isSignal": true; }; "noConfirm": { "alias": "noConfirm"; "required": false; "isSignal": true; }; }, { "actionClick": "actionClick"; "searchTerm": "searchTerm"; "errorEvent": "errorEvent"; "selectable": "selectable"; }, never, never, true, never>;
|
|
226
251
|
}
|
|
@@ -1,16 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tipos comunes para las tablas C80
|
|
3
3
|
*/
|
|
4
|
-
|
|
4
|
+
import type { IconType } from '../icon';
|
|
5
5
|
export interface C80TableColDef {
|
|
6
6
|
accessor: string;
|
|
7
7
|
label: string;
|
|
8
8
|
visible?: boolean;
|
|
9
|
-
type?: 'string' | 'number' | 'integer' | 'boolean' | 'password' | 'enum';
|
|
9
|
+
type?: 'string' | 'number' | 'integer' | 'boolean' | 'password' | 'enum' | 'date';
|
|
10
10
|
order?: 'ASC' | 'DESC';
|
|
11
11
|
readOnly?: boolean;
|
|
12
12
|
enum?: Record<string | number, string>;
|
|
13
13
|
color?: Record<string | number, string>;
|
|
14
14
|
hideIfAllValuesAreNull?: boolean;
|
|
15
15
|
default?: unknown;
|
|
16
|
+
min?: number;
|
|
17
|
+
max?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Configuración de confirmación para acciones de tabla
|
|
21
|
+
*/
|
|
22
|
+
export interface ActionConfirmation {
|
|
23
|
+
title: string;
|
|
24
|
+
message: string;
|
|
25
|
+
confirmText?: string;
|
|
26
|
+
cancelText?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Definición de acción personalizada para tabla
|
|
30
|
+
* Permite agregar acciones dinámicas sin modificar el componente
|
|
31
|
+
*/
|
|
32
|
+
export interface CustomTableAction {
|
|
33
|
+
name: string;
|
|
34
|
+
icon: IconType;
|
|
35
|
+
color?: string;
|
|
36
|
+
condition?: <T extends Record<string, unknown>>(row: T) => boolean;
|
|
37
|
+
tooltip?: string;
|
|
38
|
+
confirmation?: ActionConfirmation;
|
|
16
39
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { C80TableColDef, CustomTableAction } from './table.types';
|
|
2
|
+
/**
|
|
3
|
+
* Transform function para convertir valores string/boolean a boolean
|
|
4
|
+
* Usado en @Input() con transform para habilitar sintaxis de atributos booleanos
|
|
5
|
+
* @example [searchable]="true" o simplemente searchable
|
|
6
|
+
*/
|
|
7
|
+
export declare function booleanAttribute(value: boolean | string): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Extrae mensaje de error de forma segura desde un objeto unknown
|
|
10
|
+
* @param err - Error desconocido (puede ser Error, string, object, etc.)
|
|
11
|
+
* @returns Mensaje de error legible
|
|
12
|
+
*/
|
|
13
|
+
export declare function getErrorMessage(err: unknown): string;
|
|
14
|
+
/**
|
|
15
|
+
* Obtiene el valor de un input HTML según el tipo de columna
|
|
16
|
+
* IMPORTANTE: Convierte el valor al tipo correcto antes de retornarlo
|
|
17
|
+
* @param event - Evento del input
|
|
18
|
+
* @param col - Definición de columna (opcional)
|
|
19
|
+
* @returns Valor extraído y convertido según el tipo de columna
|
|
20
|
+
*/
|
|
21
|
+
export declare function getInputValue(event: Event, col?: C80TableColDef): unknown;
|
|
22
|
+
/**
|
|
23
|
+
* Extrae el ID de una fila para usar como trackBy en ngFor
|
|
24
|
+
* @param index - Índice de la fila
|
|
25
|
+
* @param row - Fila de datos
|
|
26
|
+
* @returns ID como string o índice como fallback
|
|
27
|
+
*/
|
|
28
|
+
export declare function trackById<T extends Record<string, unknown>>(index: number, row: T): string | number;
|
|
29
|
+
/**
|
|
30
|
+
* Verifica si una acción debe mostrarse para una fila específica
|
|
31
|
+
* CREATE se excluye porque se maneja con el botón "+" en el header
|
|
32
|
+
* @param action - Acción a verificar
|
|
33
|
+
* @param row - Fila de datos
|
|
34
|
+
* @returns true si la acción debe mostrarse
|
|
35
|
+
*/
|
|
36
|
+
export declare function shouldShowAction<T extends Record<string, unknown>>(action: CustomTableAction, row: T): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Obtiene el tooltip de una acción (usa tooltip personalizado o name por defecto)
|
|
39
|
+
* @param action - Acción
|
|
40
|
+
* @returns Texto del tooltip
|
|
41
|
+
*/
|
|
42
|
+
export declare function getActionTooltip(action: CustomTableAction): string;
|
package/package.json
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c80/ui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.45",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@angular/core": "^
|
|
5
|
+
"@angular/core": "^20.3.9",
|
|
6
6
|
"rxjs": "~7.8.0",
|
|
7
|
-
"@angular/common": "~
|
|
7
|
+
"@angular/common": "~20.3.9"
|
|
8
8
|
},
|
|
9
9
|
"sideEffects": false,
|
|
10
|
-
"module": "esm2022/c80-ui.
|
|
11
|
-
"typings": "
|
|
10
|
+
"module": "esm2022/c80-ui.js",
|
|
11
|
+
"typings": "c80-ui.d.ts",
|
|
12
12
|
"exports": {
|
|
13
13
|
"./package.json": {
|
|
14
14
|
"default": "./package.json"
|
|
15
15
|
},
|
|
16
16
|
".": {
|
|
17
|
-
"types": "./
|
|
18
|
-
"
|
|
19
|
-
"esm": "./esm2022/c80-ui.mjs",
|
|
20
|
-
"default": "./esm2022/c80-ui.mjs"
|
|
17
|
+
"types": "./c80-ui.d.ts",
|
|
18
|
+
"default": "./esm2022/c80-ui.js"
|
|
21
19
|
}
|
|
22
20
|
},
|
|
23
21
|
"dependencies": {
|
package/esm2022/c80-ui.mjs
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generated bundle index. Do not edit.
|
|
3
|
-
*/
|
|
4
|
-
export * from './index';
|
|
5
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYzgwLXVpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGlicy91aS9zcmMvYzgwLXVpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vaW5kZXgnO1xuIl19
|
package/esm2022/index.mjs
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export * from './lib/table';
|
|
2
|
-
export * from './lib/icon';
|
|
3
|
-
export * from './lib/stat-card';
|
|
4
|
-
export * from './lib/card-level';
|
|
5
|
-
export * from './lib/modal';
|
|
6
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWJzL3VpL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLFlBQVksQ0FBQztBQUMzQixjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyxhQUFhLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2xpYi90YWJsZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9pY29uJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3N0YXQtY2FyZCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jYXJkLWxldmVsJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGFsJztcbiJdfQ==
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { Component, input, computed } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import * as i0 from "@angular/core";
|
|
4
|
-
export class CardLevelComponent {
|
|
5
|
-
cardLevelData = input.required();
|
|
6
|
-
size = input(1); // Multiplicador del tamaño base (220px)
|
|
7
|
-
_generatedId;
|
|
8
|
-
get generatedId() {
|
|
9
|
-
if (!this._generatedId) {
|
|
10
|
-
const label = this.cardLevelData().label.toLowerCase().replaceAll(/\s+/g, '-');
|
|
11
|
-
const randomNum = Math.floor(Math.random() * 10000);
|
|
12
|
-
this._generatedId = `${label}-${randomNum}`;
|
|
13
|
-
}
|
|
14
|
-
return this._generatedId;
|
|
15
|
-
}
|
|
16
|
-
get cardWidth() {
|
|
17
|
-
const baseWidth = 140;
|
|
18
|
-
const calculatedWidth = baseWidth * this.size();
|
|
19
|
-
return `${calculatedWidth}px`;
|
|
20
|
-
}
|
|
21
|
-
// Detecta si el rango es bidireccional (min negativo, max positivo)
|
|
22
|
-
isBidirectional = computed(() => {
|
|
23
|
-
const data = this.cardLevelData();
|
|
24
|
-
return data.min < 0 && data.max > 0;
|
|
25
|
-
});
|
|
26
|
-
// Calcula el porcentaje de fill para barras bidireccionales
|
|
27
|
-
bidirectionalFillPercent = computed(() => {
|
|
28
|
-
const data = this.cardLevelData();
|
|
29
|
-
const totalRange = data.max - data.min;
|
|
30
|
-
return Math.abs(data.value / totalRange) * 100;
|
|
31
|
-
});
|
|
32
|
-
// Determina la dirección del fill (left/right)
|
|
33
|
-
fillDirection = computed(() => {
|
|
34
|
-
return this.cardLevelData().value >= 0 ? 'right' : 'left';
|
|
35
|
-
});
|
|
36
|
-
// Color según el valor y umbrales
|
|
37
|
-
fillColor = computed(() => {
|
|
38
|
-
const data = this.cardLevelData();
|
|
39
|
-
const absValue = Math.abs(data.value);
|
|
40
|
-
const absHigh = Math.abs(data.high);
|
|
41
|
-
const absLow = Math.abs(data.low);
|
|
42
|
-
if (absValue >= absHigh) {
|
|
43
|
-
return 'var(--color-danger)';
|
|
44
|
-
}
|
|
45
|
-
if (absValue >= absLow) {
|
|
46
|
-
return 'var(--color-warning)';
|
|
47
|
-
}
|
|
48
|
-
return 'var(--color-success)';
|
|
49
|
-
});
|
|
50
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CardLevelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
51
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: CardLevelComponent, isStandalone: true, selector: "c80-card-level", inputs: { cardLevelData: { classPropertyName: "cardLevelData", publicName: "cardLevelData", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"card-level-container\" [style.width]=\"cardWidth\">\r\n <label [for]=\"generatedId\">\r\n <strong>{{ cardLevelData().label }}</strong>\r\n\r\n <span class=\"value-display\">\r\n @if (isBidirectional()) {\r\n <!-- Barra bidireccional desde el centro -->\r\n <div class=\"bidirectional-meter\">\r\n <div class=\"meter-track\">\r\n <div class=\"center-line\"></div>\r\n <div class=\"meter-fill\" [class.fill-left]=\"fillDirection() === 'left'\" [class.fill-right]=\"fillDirection() === 'right'\" [style.width.%]=\"bidirectionalFillPercent()\" [style.background]=\"fillColor()\">\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <!-- Meter est\u00E1ndar para rangos unidireccionales -->\r\n <meter [id]=\"generatedId\" [optimum]=\"cardLevelData().optimum\" [min]=\"cardLevelData().min\" [max]=\"cardLevelData().max\" [low]=\"cardLevelData().low\" [high]=\"cardLevelData().high\" [value]=\"cardLevelData().value\">\r\n </meter>\r\n }\r\n\r\n {{ cardLevelData().value }}{{ cardLevelData().unit }}\r\n </span>\r\n </label>\r\n</div>", styles: [".card-level-container{background:#fff;border-radius:5px;padding:8px;margin:4px;box-shadow:0 4px 6px #0000001a,0 1px 3px #00000014;min-width:100px;flex:1}.card-level-container label{display:flex;flex-direction:column;margin:0}.card-level-container label strong{font-size:12px;font-weight:600;color:#2d3748;text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}.card-level-container label .value-display{font-size:12px;font-weight:600;color:#1a202c;text-align:center;padding:0 5px;background:#4299e11a;border-radius:5px}.card-level-container label .bidirectional-meter{width:100%;margin-bottom:4px}.card-level-container label .bidirectional-meter .meter-track{position:relative;width:100%;height:10px;background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a;overflow:hidden}.card-level-container label .bidirectional-meter .meter-track .center-line{position:absolute;left:50%;top:0;bottom:0;width:4px;background:#4a5568;transform:translate(-50%);z-index:1}.card-level-container label .bidirectional-meter .meter-track .meter-fill{position:absolute;top:0;bottom:0;border-radius:5px}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-right{left:50%}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-left{right:50%}.card-level-container label meter{width:100%;border-radius:12px;border:none;background:#e2e8f0;margin-bottom:4px}.card-level-container label meter::-webkit-meter-bar{background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a}.card-level-container label meter::-webkit-meter-optimum-value{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}.card-level-container label meter::-webkit-meter-suboptimum-value{background:linear-gradient(90deg,#ed8936,#dd6b20);border-radius:12px}.card-level-container label meter::-webkit-meter-even-less-good-value{background:linear-gradient(90deg,#f56565,#e53e3e);border-radius:12px}.card-level-container label meter::-moz-meter-bar{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}:host{--color-success: linear-gradient(90deg, #48bb78, #38a169);--color-warning: linear-gradient(90deg, #ed8936, #dd6b20);--color-danger: linear-gradient(90deg, #f56565, #e53e3e)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
52
|
-
}
|
|
53
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CardLevelComponent, decorators: [{
|
|
54
|
-
type: Component,
|
|
55
|
-
args: [{ selector: 'c80-card-level', standalone: true, imports: [CommonModule], template: "<div class=\"card-level-container\" [style.width]=\"cardWidth\">\r\n <label [for]=\"generatedId\">\r\n <strong>{{ cardLevelData().label }}</strong>\r\n\r\n <span class=\"value-display\">\r\n @if (isBidirectional()) {\r\n <!-- Barra bidireccional desde el centro -->\r\n <div class=\"bidirectional-meter\">\r\n <div class=\"meter-track\">\r\n <div class=\"center-line\"></div>\r\n <div class=\"meter-fill\" [class.fill-left]=\"fillDirection() === 'left'\" [class.fill-right]=\"fillDirection() === 'right'\" [style.width.%]=\"bidirectionalFillPercent()\" [style.background]=\"fillColor()\">\r\n </div>\r\n </div>\r\n </div>\r\n } @else {\r\n <!-- Meter est\u00E1ndar para rangos unidireccionales -->\r\n <meter [id]=\"generatedId\" [optimum]=\"cardLevelData().optimum\" [min]=\"cardLevelData().min\" [max]=\"cardLevelData().max\" [low]=\"cardLevelData().low\" [high]=\"cardLevelData().high\" [value]=\"cardLevelData().value\">\r\n </meter>\r\n }\r\n\r\n {{ cardLevelData().value }}{{ cardLevelData().unit }}\r\n </span>\r\n </label>\r\n</div>", styles: [".card-level-container{background:#fff;border-radius:5px;padding:8px;margin:4px;box-shadow:0 4px 6px #0000001a,0 1px 3px #00000014;min-width:100px;flex:1}.card-level-container label{display:flex;flex-direction:column;margin:0}.card-level-container label strong{font-size:12px;font-weight:600;color:#2d3748;text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}.card-level-container label .value-display{font-size:12px;font-weight:600;color:#1a202c;text-align:center;padding:0 5px;background:#4299e11a;border-radius:5px}.card-level-container label .bidirectional-meter{width:100%;margin-bottom:4px}.card-level-container label .bidirectional-meter .meter-track{position:relative;width:100%;height:10px;background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a;overflow:hidden}.card-level-container label .bidirectional-meter .meter-track .center-line{position:absolute;left:50%;top:0;bottom:0;width:4px;background:#4a5568;transform:translate(-50%);z-index:1}.card-level-container label .bidirectional-meter .meter-track .meter-fill{position:absolute;top:0;bottom:0;border-radius:5px}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-right{left:50%}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-left{right:50%}.card-level-container label meter{width:100%;border-radius:12px;border:none;background:#e2e8f0;margin-bottom:4px}.card-level-container label meter::-webkit-meter-bar{background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a}.card-level-container label meter::-webkit-meter-optimum-value{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}.card-level-container label meter::-webkit-meter-suboptimum-value{background:linear-gradient(90deg,#ed8936,#dd6b20);border-radius:12px}.card-level-container label meter::-webkit-meter-even-less-good-value{background:linear-gradient(90deg,#f56565,#e53e3e);border-radius:12px}.card-level-container label meter::-moz-meter-bar{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}:host{--color-success: linear-gradient(90deg, #48bb78, #38a169);--color-warning: linear-gradient(90deg, #ed8936, #dd6b20);--color-danger: linear-gradient(90deg, #f56565, #e53e3e)}\n"] }]
|
|
56
|
-
}] });
|
|
57
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FyZC1sZXZlbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL3VpL3NyYy9saWIvY2FyZC1sZXZlbC9jYXJkLWxldmVsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL2xpYnMvdWkvc3JjL2xpYi9jYXJkLWxldmVsL2NhcmQtbGV2ZWwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7QUFXL0MsTUFBTSxPQUFPLGtCQUFrQjtJQUM3QixhQUFhLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBaUIsQ0FBQztJQUNoRCxJQUFJLEdBQUcsS0FBSyxDQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsd0NBQXdDO0lBRXpELFlBQVksQ0FBVTtJQUU5QixJQUFJLFdBQVc7UUFDYixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztZQUMvRSxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMsWUFBWSxHQUFHLEdBQUcsS0FBSyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQzlDLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUM7SUFDM0IsQ0FBQztJQUVELElBQUksU0FBUztRQUNYLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQztRQUN0QixNQUFNLGVBQWUsR0FBRyxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2hELE9BQU8sR0FBRyxlQUFlLElBQUksQ0FBQztJQUNoQyxDQUFDO0lBRUQsb0VBQW9FO0lBQ3BFLGVBQWUsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1FBQzlCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNsQyxPQUFPLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBQ3RDLENBQUMsQ0FBQyxDQUFDO0lBRUgsNERBQTREO0lBQzVELHdCQUF3QixHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7UUFDdkMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztRQUN2QyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxVQUFVLENBQUMsR0FBRyxHQUFHLENBQUM7SUFDakQsQ0FBQyxDQUFDLENBQUM7SUFFSCwrQ0FBK0M7SUFDL0MsYUFBYSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7UUFDNUIsT0FBTyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDNUQsQ0FBQyxDQUFDLENBQUM7SUFFSCxrQ0FBa0M7SUFDbEMsU0FBUyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7UUFDeEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRWxDLElBQUksUUFBUSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ3hCLE9BQU8scUJBQXFCLENBQUM7UUFDL0IsQ0FBQztRQUNELElBQUksUUFBUSxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ3ZCLE9BQU8sc0JBQXNCLENBQUM7UUFDaEMsQ0FBQztRQUNELE9BQU8sc0JBQXNCLENBQUM7SUFDaEMsQ0FBQyxDQUFDLENBQUM7d0dBckRRLGtCQUFrQjs0RkFBbEIsa0JBQWtCLDBWQ1ovQix3bkNBdUJNLDB2RURmTSxZQUFZOzs0RkFJWCxrQkFBa0I7a0JBUjlCLFNBQVM7K0JBRUUsZ0JBQWdCLGNBQ2QsSUFBSSxXQUNQLENBQUMsWUFBWSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBpbnB1dCwgY29tcHV0ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgQ2FyZExldmVsRGF0YSB9IGZyb20gJy4vY2FyZC1sZXZlbC5pbnRlcmZhY2UnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9jb21wb25lbnQtc2VsZWN0b3JcclxuICBzZWxlY3RvcjogJ2M4MC1jYXJkLWxldmVsJyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9jYXJkLWxldmVsLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybDogJy4vY2FyZC1sZXZlbC5jb21wb25lbnQuc2NzcydcclxufSlcclxuZXhwb3J0IGNsYXNzIENhcmRMZXZlbENvbXBvbmVudCB7XHJcbiAgY2FyZExldmVsRGF0YSA9IGlucHV0LnJlcXVpcmVkPENhcmRMZXZlbERhdGE+KCk7XHJcbiAgc2l6ZSA9IGlucHV0PG51bWJlcj4oMSk7IC8vIE11bHRpcGxpY2Fkb3IgZGVsIHRhbWHDsW8gYmFzZSAoMjIwcHgpXHJcblxyXG4gIHByaXZhdGUgX2dlbmVyYXRlZElkPzogc3RyaW5nO1xyXG5cclxuICBnZXQgZ2VuZXJhdGVkSWQoKTogc3RyaW5nIHtcclxuICAgIGlmICghdGhpcy5fZ2VuZXJhdGVkSWQpIHtcclxuICAgICAgY29uc3QgbGFiZWwgPSB0aGlzLmNhcmRMZXZlbERhdGEoKS5sYWJlbC50b0xvd2VyQ2FzZSgpLnJlcGxhY2VBbGwoL1xccysvZywgJy0nKTtcclxuICAgICAgY29uc3QgcmFuZG9tTnVtID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTAwMDApO1xyXG4gICAgICB0aGlzLl9nZW5lcmF0ZWRJZCA9IGAke2xhYmVsfS0ke3JhbmRvbU51bX1gO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuX2dlbmVyYXRlZElkO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGNhcmRXaWR0aCgpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgYmFzZVdpZHRoID0gMTQwO1xyXG4gICAgY29uc3QgY2FsY3VsYXRlZFdpZHRoID0gYmFzZVdpZHRoICogdGhpcy5zaXplKCk7XHJcbiAgICByZXR1cm4gYCR7Y2FsY3VsYXRlZFdpZHRofXB4YDtcclxuICB9XHJcblxyXG4gIC8vIERldGVjdGEgc2kgZWwgcmFuZ28gZXMgYmlkaXJlY2Npb25hbCAobWluIG5lZ2F0aXZvLCBtYXggcG9zaXRpdm8pXHJcbiAgaXNCaWRpcmVjdGlvbmFsID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gICAgY29uc3QgZGF0YSA9IHRoaXMuY2FyZExldmVsRGF0YSgpO1xyXG4gICAgcmV0dXJuIGRhdGEubWluIDwgMCAmJiBkYXRhLm1heCA+IDA7XHJcbiAgfSk7XHJcblxyXG4gIC8vIENhbGN1bGEgZWwgcG9yY2VudGFqZSBkZSBmaWxsIHBhcmEgYmFycmFzIGJpZGlyZWNjaW9uYWxlc1xyXG4gIGJpZGlyZWN0aW9uYWxGaWxsUGVyY2VudCA9IGNvbXB1dGVkKCgpID0+IHtcclxuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmNhcmRMZXZlbERhdGEoKTtcclxuICAgIGNvbnN0IHRvdGFsUmFuZ2UgPSBkYXRhLm1heCAtIGRhdGEubWluO1xyXG4gICAgcmV0dXJuIE1hdGguYWJzKGRhdGEudmFsdWUgLyB0b3RhbFJhbmdlKSAqIDEwMDtcclxuICB9KTtcclxuXHJcbiAgLy8gRGV0ZXJtaW5hIGxhIGRpcmVjY2nDs24gZGVsIGZpbGwgKGxlZnQvcmlnaHQpXHJcbiAgZmlsbERpcmVjdGlvbiA9IGNvbXB1dGVkKCgpID0+IHtcclxuICAgIHJldHVybiB0aGlzLmNhcmRMZXZlbERhdGEoKS52YWx1ZSA+PSAwID8gJ3JpZ2h0JyA6ICdsZWZ0JztcclxuICB9KTtcclxuXHJcbiAgLy8gQ29sb3Igc2Vnw7puIGVsIHZhbG9yIHkgdW1icmFsZXNcclxuICBmaWxsQ29sb3IgPSBjb21wdXRlZCgoKSA9PiB7XHJcbiAgICBjb25zdCBkYXRhID0gdGhpcy5jYXJkTGV2ZWxEYXRhKCk7XHJcbiAgICBjb25zdCBhYnNWYWx1ZSA9IE1hdGguYWJzKGRhdGEudmFsdWUpO1xyXG4gICAgY29uc3QgYWJzSGlnaCA9IE1hdGguYWJzKGRhdGEuaGlnaCk7XHJcbiAgICBjb25zdCBhYnNMb3cgPSBNYXRoLmFicyhkYXRhLmxvdyk7XHJcblxyXG4gICAgaWYgKGFic1ZhbHVlID49IGFic0hpZ2gpIHtcclxuICAgICAgcmV0dXJuICd2YXIoLS1jb2xvci1kYW5nZXIpJztcclxuICAgIH1cclxuICAgIGlmIChhYnNWYWx1ZSA+PSBhYnNMb3cpIHtcclxuICAgICAgcmV0dXJuICd2YXIoLS1jb2xvci13YXJuaW5nKSc7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gJ3ZhcigtLWNvbG9yLXN1Y2Nlc3MpJztcclxuICB9KTtcclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwiY2FyZC1sZXZlbC1jb250YWluZXJcIiBbc3R5bGUud2lkdGhdPVwiY2FyZFdpZHRoXCI+XHJcbiAgPGxhYmVsIFtmb3JdPVwiZ2VuZXJhdGVkSWRcIj5cclxuICAgIDxzdHJvbmc+e3sgY2FyZExldmVsRGF0YSgpLmxhYmVsIH19PC9zdHJvbmc+XHJcblxyXG4gICAgPHNwYW4gY2xhc3M9XCJ2YWx1ZS1kaXNwbGF5XCI+XHJcbiAgICAgIEBpZiAoaXNCaWRpcmVjdGlvbmFsKCkpIHtcclxuICAgICAgPCEtLSBCYXJyYSBiaWRpcmVjY2lvbmFsIGRlc2RlIGVsIGNlbnRybyAtLT5cclxuICAgICAgPGRpdiBjbGFzcz1cImJpZGlyZWN0aW9uYWwtbWV0ZXJcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwibWV0ZXItdHJhY2tcIj5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjZW50ZXItbGluZVwiPjwvZGl2PlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cIm1ldGVyLWZpbGxcIiBbY2xhc3MuZmlsbC1sZWZ0XT1cImZpbGxEaXJlY3Rpb24oKSA9PT0gJ2xlZnQnXCIgW2NsYXNzLmZpbGwtcmlnaHRdPVwiZmlsbERpcmVjdGlvbigpID09PSAncmlnaHQnXCIgW3N0eWxlLndpZHRoLiVdPVwiYmlkaXJlY3Rpb25hbEZpbGxQZXJjZW50KClcIiBbc3R5bGUuYmFja2dyb3VuZF09XCJmaWxsQ29sb3IoKVwiPlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICB9IEBlbHNlIHtcclxuICAgICAgPCEtLSBNZXRlciBlc3TDoW5kYXIgcGFyYSByYW5nb3MgdW5pZGlyZWNjaW9uYWxlcyAtLT5cclxuICAgICAgPG1ldGVyIFtpZF09XCJnZW5lcmF0ZWRJZFwiIFtvcHRpbXVtXT1cImNhcmRMZXZlbERhdGEoKS5vcHRpbXVtXCIgW21pbl09XCJjYXJkTGV2ZWxEYXRhKCkubWluXCIgW21heF09XCJjYXJkTGV2ZWxEYXRhKCkubWF4XCIgW2xvd109XCJjYXJkTGV2ZWxEYXRhKCkubG93XCIgW2hpZ2hdPVwiY2FyZExldmVsRGF0YSgpLmhpZ2hcIiBbdmFsdWVdPVwiY2FyZExldmVsRGF0YSgpLnZhbHVlXCI+XHJcbiAgICAgIDwvbWV0ZXI+XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHt7IGNhcmRMZXZlbERhdGEoKS52YWx1ZSB9fXt7IGNhcmRMZXZlbERhdGEoKS51bml0IH19XHJcbiAgICA8L3NwYW4+XHJcbiAgPC9sYWJlbD5cclxuPC9kaXY+Il19
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FyZC1sZXZlbC5pbnRlcmZhY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL3VpL3NyYy9saWIvY2FyZC1sZXZlbC9jYXJkLWxldmVsLmludGVyZmFjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGludGVyZmFjZSBDYXJkTGV2ZWxEYXRhIHtcclxuICBsYWJlbDogc3RyaW5nO1xyXG4gIHZhbHVlOiBudW1iZXI7XHJcbiAgbWluOiBudW1iZXI7XHJcbiAgbWF4OiBudW1iZXI7XHJcbiAgb3B0aW11bTogbnVtYmVyO1xyXG4gIGxvdzogbnVtYmVyO1xyXG4gIGhpZ2g6IG51bWJlcjtcclxuICB1bml0OiBzdHJpbmc7XHJcbn1cclxuIl19
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export * from './card-level.component';
|
|
2
|
-
export * from './card-level.interface';
|
|
3
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL3VpL3NyYy9saWIvY2FyZC1sZXZlbC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsd0JBQXdCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2NhcmQtbGV2ZWwuY29tcG9uZW50JztcclxuZXhwb3J0ICogZnJvbSAnLi9jYXJkLWxldmVsLmludGVyZmFjZSc7XHJcbiJdfQ==
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { Component, input, output, computed } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { BASE_ICON_SIZE, BASE_ICON_COLORS, DISABLED_COLOR, DEFAULT_ICON_COLOR, DISABLED_OPACITY, SECONDARY_WARN_OPACITY, DEFAULT_OPACITY, ICON_PATHS, ICON_ADDITIONAL_SHAPES, } from './icon.constants';
|
|
4
|
-
import { transformToBoolean } from './icon.utils';
|
|
5
|
-
import * as i0 from "@angular/core";
|
|
6
|
-
import * as i1 from "@angular/common";
|
|
7
|
-
export class C80IconComponent {
|
|
8
|
-
icon = input('check'); // Tipo de icono a mostrar
|
|
9
|
-
color = input('primary'); // Color del icono (primary, secondary, warn, success)
|
|
10
|
-
customColor = input(undefined); // Color personalizado (sobrescribe color)
|
|
11
|
-
disabled = input(false); // Estado deshabilitado
|
|
12
|
-
size = input(1); // Multiplicador de tamaño (1 = 24px)
|
|
13
|
-
button = input(false, { transform: transformToBoolean }); // Renderiza como botón clickeable
|
|
14
|
-
border = input(false, { transform: transformToBoolean }); // Agrega borde al wrapper
|
|
15
|
-
type = input('button'); // Tipo de botón (button, submit, reset)
|
|
16
|
-
textLeft = input(undefined); // Texto a la izquierda del icono
|
|
17
|
-
textRight = input(undefined); // Texto a la derecha del icono
|
|
18
|
-
iconClick = output(); // Evento emitido al hacer click (solo si button=true)
|
|
19
|
-
iconSize = computed(() => BASE_ICON_SIZE * this.size());
|
|
20
|
-
iconColor = computed(() => {
|
|
21
|
-
if (this.disabled())
|
|
22
|
-
return DISABLED_COLOR;
|
|
23
|
-
const custom = this.customColor();
|
|
24
|
-
if (custom)
|
|
25
|
-
return custom;
|
|
26
|
-
return BASE_ICON_COLORS[this.color()] ?? DEFAULT_ICON_COLOR;
|
|
27
|
-
});
|
|
28
|
-
iconOpacity = computed(() => {
|
|
29
|
-
if (this.disabled())
|
|
30
|
-
return DISABLED_OPACITY;
|
|
31
|
-
const hasCustomColor = this.customColor() !== undefined;
|
|
32
|
-
const isSecondaryOrWarn = ['secondary', 'warn'].includes(this.color());
|
|
33
|
-
return !hasCustomColor && isSecondaryOrWarn ? SECONDARY_WARN_OPACITY : DEFAULT_OPACITY;
|
|
34
|
-
});
|
|
35
|
-
iconPath = computed(() => ICON_PATHS[this.icon()] ?? ICON_PATHS['default']);
|
|
36
|
-
additionalShapes = computed(() => ICON_ADDITIONAL_SHAPES[this.icon()] ?? []);
|
|
37
|
-
onButtonClick(event) {
|
|
38
|
-
if (!this.disabled()) {
|
|
39
|
-
this.iconClick.emit(event);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: C80IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
43
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: C80IconComponent, isStandalone: true, selector: "c80-icon", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, customColor: { classPropertyName: "customColor", publicName: "customColor", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, button: { classPropertyName: "button", publicName: "button", isSignal: true, isRequired: false, transformFunction: null }, border: { classPropertyName: "border", publicName: "border", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, textLeft: { classPropertyName: "textLeft", publicName: "textLeft", isSignal: true, isRequired: false, transformFunction: null }, textRight: { classPropertyName: "textRight", publicName: "textRight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { iconClick: "iconClick" }, ngImport: i0, template: "<ng-template #svgContent>\r\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\r\n @for (shape of additionalShapes(); track $index) {\r\n @if (shape.type === 'circle') {\r\n <circle [attr.cx]=\"shape['cx']\" [attr.cy]=\"shape['cy']\" [attr.r]=\"shape['r']\" [attr.stroke]=\"iconColor()\" stroke-width=\"2\" [attr.fill]=\"shape['fill'] === 'color' ? iconColor() : 'none'\" />\r\n } @else if (shape.type === 'rect') {\r\n <rect [attr.x]=\"shape['x']\" [attr.y]=\"shape['y']\" [attr.width]=\"shape['width']\" [attr.height]=\"shape['height']\" [attr.rx]=\"shape['rx']\" [attr.stroke]=\"iconColor()\" stroke-width=\"2\" fill=\"none\" />\r\n } @else if (shape.type === 'path') {\r\n <path [attr.d]=\"shape['d']\" [attr.stroke]=\"iconColor()\" stroke-width=\"2\" [attr.fill]=\"shape['fill'] === 'color' ? iconColor() : 'none'\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n }\r\n }\r\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"icon() === 'delete' ? iconColor() : 'none'\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n</ng-template>\r\n\r\n<ng-template #textContent>\r\n @if (textLeft()) {\r\n <span class=\"icon-text\" style=\"margin-left: 12px\">{{ textLeft() }}</span>\r\n }\r\n <span class=\"icon-content\" [style.width.px]=\"iconSize() + 8\" [style.height.px]=\"iconSize() + 8\">\r\n <ng-container *ngTemplateOutlet=\"svgContent\" />\r\n </span>\r\n @if (textRight()) {\r\n <span class=\"icon-text\" style=\"margin-right: 12px\">{{ textRight() }}</span>\r\n }\r\n</ng-template>\r\n\r\n@if (button()) {\r\n<button [type]=\"type()\" [disabled]=\"disabled()\" class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" (click)=\"onButtonClick($event)\">\r\n <ng-container *ngTemplateOutlet=\"textContent\" />\r\n</button>\r\n} @else {\r\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\">\r\n <ng-container *ngTemplateOutlet=\"textContent\" />\r\n</span>\r\n}", styles: [":host .icon-wrapper{display:inline-flex;align-items:center;gap:8px;background:transparent;padding:0;border:none;outline:none;cursor:pointer;transition:opacity .2s}:host button.icon-wrapper:focus-visible{outline:2px solid #1976d2;outline-offset:2px;border-radius:4px}:host button.icon-wrapper:disabled{opacity:.5;cursor:default}:host .icon-content{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;min-width:0;min-height:0;padding:4px;margin:0 4px;transition:background .2s;box-sizing:border-box}:host button.icon-wrapper:hover:not(:disabled) .icon-content{background:#1976d214}:host button.icon-wrapper:active:not(:disabled) .icon-content{background:#1976d229}:host .icon-text{font-size:14px;line-height:1;white-space:nowrap;-webkit-user-select:none;user-select:none}:host .icon-wrapper-border{border:1px solid rgba(0,0,0,.23);border-radius:4px;padding:4px 8px}:host button.icon-wrapper-border:hover:not(:disabled){border-color:#000000de}:host button.icon-wrapper-border:disabled{border-color:#0000001f}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
44
|
-
}
|
|
45
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: C80IconComponent, decorators: [{
|
|
46
|
-
type: Component,
|
|
47
|
-
args: [{ selector: 'c80-icon', standalone: true, imports: [CommonModule], template: "<ng-template #svgContent>\r\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\r\n @for (shape of additionalShapes(); track $index) {\r\n @if (shape.type === 'circle') {\r\n <circle [attr.cx]=\"shape['cx']\" [attr.cy]=\"shape['cy']\" [attr.r]=\"shape['r']\" [attr.stroke]=\"iconColor()\" stroke-width=\"2\" [attr.fill]=\"shape['fill'] === 'color' ? iconColor() : 'none'\" />\r\n } @else if (shape.type === 'rect') {\r\n <rect [attr.x]=\"shape['x']\" [attr.y]=\"shape['y']\" [attr.width]=\"shape['width']\" [attr.height]=\"shape['height']\" [attr.rx]=\"shape['rx']\" [attr.stroke]=\"iconColor()\" stroke-width=\"2\" fill=\"none\" />\r\n } @else if (shape.type === 'path') {\r\n <path [attr.d]=\"shape['d']\" [attr.stroke]=\"iconColor()\" stroke-width=\"2\" [attr.fill]=\"shape['fill'] === 'color' ? iconColor() : 'none'\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n }\r\n }\r\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"icon() === 'delete' ? iconColor() : 'none'\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n</ng-template>\r\n\r\n<ng-template #textContent>\r\n @if (textLeft()) {\r\n <span class=\"icon-text\" style=\"margin-left: 12px\">{{ textLeft() }}</span>\r\n }\r\n <span class=\"icon-content\" [style.width.px]=\"iconSize() + 8\" [style.height.px]=\"iconSize() + 8\">\r\n <ng-container *ngTemplateOutlet=\"svgContent\" />\r\n </span>\r\n @if (textRight()) {\r\n <span class=\"icon-text\" style=\"margin-right: 12px\">{{ textRight() }}</span>\r\n }\r\n</ng-template>\r\n\r\n@if (button()) {\r\n<button [type]=\"type()\" [disabled]=\"disabled()\" class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" (click)=\"onButtonClick($event)\">\r\n <ng-container *ngTemplateOutlet=\"textContent\" />\r\n</button>\r\n} @else {\r\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\">\r\n <ng-container *ngTemplateOutlet=\"textContent\" />\r\n</span>\r\n}", styles: [":host .icon-wrapper{display:inline-flex;align-items:center;gap:8px;background:transparent;padding:0;border:none;outline:none;cursor:pointer;transition:opacity .2s}:host button.icon-wrapper:focus-visible{outline:2px solid #1976d2;outline-offset:2px;border-radius:4px}:host button.icon-wrapper:disabled{opacity:.5;cursor:default}:host .icon-content{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;min-width:0;min-height:0;padding:4px;margin:0 4px;transition:background .2s;box-sizing:border-box}:host button.icon-wrapper:hover:not(:disabled) .icon-content{background:#1976d214}:host button.icon-wrapper:active:not(:disabled) .icon-content{background:#1976d229}:host .icon-text{font-size:14px;line-height:1;white-space:nowrap;-webkit-user-select:none;user-select:none}:host .icon-wrapper-border{border:1px solid rgba(0,0,0,.23);border-radius:4px;padding:4px 8px}:host button.icon-wrapper-border:hover:not(:disabled){border-color:#000000de}:host button.icon-wrapper-border:disabled{border-color:#0000001f}\n"] }]
|
|
48
|
-
}] });
|
|
49
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWNvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL3VpL3NyYy9saWIvaWNvbi9pY29uLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL2xpYnMvdWkvc3JjL2xpYi9pY29uL2ljb24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUNMLGNBQWMsRUFDZCxnQkFBZ0IsRUFDaEIsY0FBYyxFQUNkLGtCQUFrQixFQUNsQixnQkFBZ0IsRUFDaEIsc0JBQXNCLEVBQ3RCLGVBQWUsRUFDZixVQUFVLEVBQ1Ysc0JBQXNCLEdBQ3ZCLE1BQU0sa0JBQWtCLENBQUM7QUFFMUIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sY0FBYyxDQUFDOzs7QUFVbEQsTUFBTSxPQUFPLGdCQUFnQjtJQUNsQixJQUFJLEdBQUcsS0FBSyxDQUFXLE9BQU8sQ0FBQyxDQUFDLENBQUMsMEJBQTBCO0lBQzNELEtBQUssR0FBRyxLQUFLLENBQVksU0FBUyxDQUFDLENBQUMsQ0FBQyxzREFBc0Q7SUFDM0YsV0FBVyxHQUFHLEtBQUssQ0FBcUIsU0FBUyxDQUFDLENBQUMsQ0FBQywwQ0FBMEM7SUFDOUYsUUFBUSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLHVCQUF1QjtJQUNoRCxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMscUNBQXFDO0lBQ3RELE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsU0FBUyxFQUFFLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxDQUFDLGtDQUFrQztJQUM1RixNQUFNLEdBQUcsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLFNBQVMsRUFBRSxrQkFBa0IsRUFBRSxDQUFDLENBQUMsQ0FBQywwQkFBMEI7SUFDcEYsSUFBSSxHQUFHLEtBQUssQ0FBYSxRQUFRLENBQUMsQ0FBQyxDQUFDLHdDQUF3QztJQUM1RSxRQUFRLEdBQUcsS0FBSyxDQUFxQixTQUFTLENBQUMsQ0FBQyxDQUFDLGlDQUFpQztJQUNsRixTQUFTLEdBQUcsS0FBSyxDQUFxQixTQUFTLENBQUMsQ0FBQyxDQUFDLCtCQUErQjtJQUVqRixTQUFTLEdBQUcsTUFBTSxFQUFTLENBQUMsQ0FBQyxzREFBc0Q7SUFFbkYsUUFBUSxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFFeEQsU0FBUyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7UUFDakMsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQUUsT0FBTyxjQUFjLENBQUM7UUFFM0MsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2xDLElBQUksTUFBTTtZQUFFLE9BQU8sTUFBTSxDQUFDO1FBRTFCLE9BQU8sZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLElBQUksa0JBQWtCLENBQUM7SUFDOUQsQ0FBQyxDQUFDLENBQUM7SUFFTSxXQUFXLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtRQUNuQyxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFBRSxPQUFPLGdCQUFnQixDQUFDO1FBRTdDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsS0FBSyxTQUFTLENBQUM7UUFDeEQsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFFdkUsT0FBTyxDQUFDLGNBQWMsSUFBSSxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQztJQUN6RixDQUFDLENBQUMsQ0FBQztJQUVNLFFBQVEsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO0lBQzVFLGdCQUFnQixHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUV0RixhQUFhLENBQUMsS0FBWTtRQUN4QixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0IsQ0FBQztJQUNILENBQUM7d0dBekNVLGdCQUFnQjs0RkFBaEIsZ0JBQWdCLGsxQ0N4QjdCLGdqRUFtQ0Msb2tDRGZXLFlBQVk7OzRGQUlYLGdCQUFnQjtrQkFSNUIsU0FBUzsrQkFFRSxVQUFVLGNBQ1IsSUFBSSxXQUNQLENBQUMsWUFBWSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBpbnB1dCwgb3V0cHV0LCBjb21wdXRlZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEJBU0VfSUNPTl9TSVpFLFxuICBCQVNFX0lDT05fQ09MT1JTLFxuICBESVNBQkxFRF9DT0xPUixcbiAgREVGQVVMVF9JQ09OX0NPTE9SLFxuICBESVNBQkxFRF9PUEFDSVRZLFxuICBTRUNPTkRBUllfV0FSTl9PUEFDSVRZLFxuICBERUZBVUxUX09QQUNJVFksXG4gIElDT05fUEFUSFMsXG4gIElDT05fQURESVRJT05BTF9TSEFQRVMsXG59IGZyb20gJy4vaWNvbi5jb25zdGFudHMnO1xuaW1wb3J0IHR5cGUgeyBJY29uVHlwZSwgQ29sb3JUeXBlLCBCdXR0b25UeXBlIH0gZnJvbSAnLi9pY29uLnR5cGVzJztcbmltcG9ydCB7IHRyYW5zZm9ybVRvQm9vbGVhbiB9IGZyb20gJy4vaWNvbi51dGlscyc7XG5cbkBDb21wb25lbnQoe1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2NvbXBvbmVudC1zZWxlY3RvclxuICBzZWxlY3RvcjogJ2M4MC1pY29uJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9pY29uLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vaWNvbi5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBDODBJY29uQ29tcG9uZW50IHtcbiAgcmVhZG9ubHkgaWNvbiA9IGlucHV0PEljb25UeXBlPignY2hlY2snKTsgLy8gVGlwbyBkZSBpY29ubyBhIG1vc3RyYXJcbiAgcmVhZG9ubHkgY29sb3IgPSBpbnB1dDxDb2xvclR5cGU+KCdwcmltYXJ5Jyk7IC8vIENvbG9yIGRlbCBpY29ubyAocHJpbWFyeSwgc2Vjb25kYXJ5LCB3YXJuLCBzdWNjZXNzKVxuICByZWFkb25seSBjdXN0b21Db2xvciA9IGlucHV0PHN0cmluZyB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTsgLy8gQ29sb3IgcGVyc29uYWxpemFkbyAoc29icmVzY3JpYmUgY29sb3IpXG4gIHJlYWRvbmx5IGRpc2FibGVkID0gaW5wdXQoZmFsc2UpOyAvLyBFc3RhZG8gZGVzaGFiaWxpdGFkb1xuICByZWFkb25seSBzaXplID0gaW5wdXQoMSk7IC8vIE11bHRpcGxpY2Fkb3IgZGUgdGFtYcOxbyAoMSA9IDI0cHgpXG4gIHJlYWRvbmx5IGJ1dHRvbiA9IGlucHV0KGZhbHNlLCB7IHRyYW5zZm9ybTogdHJhbnNmb3JtVG9Cb29sZWFuIH0pOyAvLyBSZW5kZXJpemEgY29tbyBib3TDs24gY2xpY2tlYWJsZVxuICByZWFkb25seSBib3JkZXIgPSBpbnB1dChmYWxzZSwgeyB0cmFuc2Zvcm06IHRyYW5zZm9ybVRvQm9vbGVhbiB9KTsgLy8gQWdyZWdhIGJvcmRlIGFsIHdyYXBwZXJcbiAgcmVhZG9ubHkgdHlwZSA9IGlucHV0PEJ1dHRvblR5cGU+KCdidXR0b24nKTsgLy8gVGlwbyBkZSBib3TDs24gKGJ1dHRvbiwgc3VibWl0LCByZXNldClcbiAgcmVhZG9ubHkgdGV4dExlZnQgPSBpbnB1dDxzdHJpbmcgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7IC8vIFRleHRvIGEgbGEgaXpxdWllcmRhIGRlbCBpY29ub1xuICByZWFkb25seSB0ZXh0UmlnaHQgPSBpbnB1dDxzdHJpbmcgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7IC8vIFRleHRvIGEgbGEgZGVyZWNoYSBkZWwgaWNvbm9cblxuICByZWFkb25seSBpY29uQ2xpY2sgPSBvdXRwdXQ8RXZlbnQ+KCk7IC8vIEV2ZW50byBlbWl0aWRvIGFsIGhhY2VyIGNsaWNrIChzb2xvIHNpIGJ1dHRvbj10cnVlKVxuXG4gIHJlYWRvbmx5IGljb25TaXplID0gY29tcHV0ZWQoKCkgPT4gQkFTRV9JQ09OX1NJWkUgKiB0aGlzLnNpemUoKSk7XG5cbiAgcmVhZG9ubHkgaWNvbkNvbG9yID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKCkpIHJldHVybiBESVNBQkxFRF9DT0xPUjtcblxuICAgIGNvbnN0IGN1c3RvbSA9IHRoaXMuY3VzdG9tQ29sb3IoKTtcbiAgICBpZiAoY3VzdG9tKSByZXR1cm4gY3VzdG9tO1xuXG4gICAgcmV0dXJuIEJBU0VfSUNPTl9DT0xPUlNbdGhpcy5jb2xvcigpXSA/PyBERUZBVUxUX0lDT05fQ09MT1I7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IGljb25PcGFjaXR5ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKCkpIHJldHVybiBESVNBQkxFRF9PUEFDSVRZO1xuXG4gICAgY29uc3QgaGFzQ3VzdG9tQ29sb3IgPSB0aGlzLmN1c3RvbUNvbG9yKCkgIT09IHVuZGVmaW5lZDtcbiAgICBjb25zdCBpc1NlY29uZGFyeU9yV2FybiA9IFsnc2Vjb25kYXJ5JywgJ3dhcm4nXS5pbmNsdWRlcyh0aGlzLmNvbG9yKCkpO1xuXG4gICAgcmV0dXJuICFoYXNDdXN0b21Db2xvciAmJiBpc1NlY29uZGFyeU9yV2FybiA/IFNFQ09OREFSWV9XQVJOX09QQUNJVFkgOiBERUZBVUxUX09QQUNJVFk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IGljb25QYXRoID0gY29tcHV0ZWQoKCkgPT4gSUNPTl9QQVRIU1t0aGlzLmljb24oKV0gPz8gSUNPTl9QQVRIU1snZGVmYXVsdCddKTtcbiAgcmVhZG9ubHkgYWRkaXRpb25hbFNoYXBlcyA9IGNvbXB1dGVkKCgpID0+IElDT05fQURESVRJT05BTF9TSEFQRVNbdGhpcy5pY29uKCldID8/IFtdKTtcblxuICBvbkJ1dHRvbkNsaWNrKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5kaXNhYmxlZCgpKSB7XG4gICAgICB0aGlzLmljb25DbGljay5lbWl0KGV2ZW50KTtcbiAgICB9XG4gIH1cbn1cbiIsIjxuZy10ZW1wbGF0ZSAjc3ZnQ29udGVudD5cclxuICA8c3ZnIFthdHRyLndpZHRoXT1cImljb25TaXplKClcIiBbYXR0ci5oZWlnaHRdPVwiaWNvblNpemUoKVwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIFtzdHlsZS5vcGFjaXR5XT1cImljb25PcGFjaXR5KClcIj5cclxuICAgIEBmb3IgKHNoYXBlIG9mIGFkZGl0aW9uYWxTaGFwZXMoKTsgdHJhY2sgJGluZGV4KSB7XHJcbiAgICBAaWYgKHNoYXBlLnR5cGUgPT09ICdjaXJjbGUnKSB7XHJcbiAgICA8Y2lyY2xlIFthdHRyLmN4XT1cInNoYXBlWydjeCddXCIgW2F0dHIuY3ldPVwic2hhcGVbJ2N5J11cIiBbYXR0ci5yXT1cInNoYXBlWydyJ11cIiBbYXR0ci5zdHJva2VdPVwiaWNvbkNvbG9yKClcIiBzdHJva2Utd2lkdGg9XCIyXCIgW2F0dHIuZmlsbF09XCJzaGFwZVsnZmlsbCddID09PSAnY29sb3InID8gaWNvbkNvbG9yKCkgOiAnbm9uZSdcIiAvPlxyXG4gICAgfSBAZWxzZSBpZiAoc2hhcGUudHlwZSA9PT0gJ3JlY3QnKSB7XHJcbiAgICA8cmVjdCBbYXR0ci54XT1cInNoYXBlWyd4J11cIiBbYXR0ci55XT1cInNoYXBlWyd5J11cIiBbYXR0ci53aWR0aF09XCJzaGFwZVsnd2lkdGgnXVwiIFthdHRyLmhlaWdodF09XCJzaGFwZVsnaGVpZ2h0J11cIiBbYXR0ci5yeF09XCJzaGFwZVsncngnXVwiIFthdHRyLnN0cm9rZV09XCJpY29uQ29sb3IoKVwiIHN0cm9rZS13aWR0aD1cIjJcIiBmaWxsPVwibm9uZVwiIC8+XHJcbiAgICB9IEBlbHNlIGlmIChzaGFwZS50eXBlID09PSAncGF0aCcpIHtcclxuICAgIDxwYXRoIFthdHRyLmRdPVwic2hhcGVbJ2QnXVwiIFthdHRyLnN0cm9rZV09XCJpY29uQ29sb3IoKVwiIHN0cm9rZS13aWR0aD1cIjJcIiBbYXR0ci5maWxsXT1cInNoYXBlWydmaWxsJ10gPT09ICdjb2xvcicgPyBpY29uQ29sb3IoKSA6ICdub25lJ1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICB9XHJcbiAgICB9XHJcbiAgICA8cGF0aCBbYXR0ci5kXT1cImljb25QYXRoKClcIiBbYXR0ci5zdHJva2VdPVwiaWNvbkNvbG9yKClcIiBbYXR0ci5maWxsXT1cImljb24oKSA9PT0gJ2RlbGV0ZScgPyBpY29uQ29sb3IoKSA6ICdub25lJ1wiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gIDwvc3ZnPlxyXG48L25nLXRlbXBsYXRlPlxyXG5cclxuPG5nLXRlbXBsYXRlICN0ZXh0Q29udGVudD5cclxuICBAaWYgKHRleHRMZWZ0KCkpIHtcclxuICA8c3BhbiBjbGFzcz1cImljb24tdGV4dFwiIHN0eWxlPVwibWFyZ2luLWxlZnQ6IDEycHhcIj57eyB0ZXh0TGVmdCgpIH19PC9zcGFuPlxyXG4gIH1cclxuICA8c3BhbiBjbGFzcz1cImljb24tY29udGVudFwiIFtzdHlsZS53aWR0aC5weF09XCJpY29uU2l6ZSgpICsgOFwiIFtzdHlsZS5oZWlnaHQucHhdPVwiaWNvblNpemUoKSArIDhcIj5cclxuICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJzdmdDb250ZW50XCIgLz5cclxuICA8L3NwYW4+XHJcbiAgQGlmICh0ZXh0UmlnaHQoKSkge1xyXG4gIDxzcGFuIGNsYXNzPVwiaWNvbi10ZXh0XCIgc3R5bGU9XCJtYXJnaW4tcmlnaHQ6IDEycHhcIj57eyB0ZXh0UmlnaHQoKSB9fTwvc3Bhbj5cclxuICB9XHJcbjwvbmctdGVtcGxhdGU+XHJcblxyXG5AaWYgKGJ1dHRvbigpKSB7XHJcbjxidXR0b24gW3R5cGVdPVwidHlwZSgpXCIgW2Rpc2FibGVkXT1cImRpc2FibGVkKClcIiBjbGFzcz1cImljb24td3JhcHBlclwiIFtjbGFzcy5pY29uLXdyYXBwZXItYm9yZGVyXT1cImJvcmRlcigpXCIgKGNsaWNrKT1cIm9uQnV0dG9uQ2xpY2soJGV2ZW50KVwiPlxyXG4gIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0ZXh0Q29udGVudFwiIC8+XHJcbjwvYnV0dG9uPlxyXG59IEBlbHNlIHtcclxuPHNwYW4gY2xhc3M9XCJpY29uLXdyYXBwZXJcIiBbY2xhc3MuaWNvbi13cmFwcGVyLWJvcmRlcl09XCJib3JkZXIoKVwiPlxyXG4gIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0ZXh0Q29udGVudFwiIC8+XHJcbjwvc3Bhbj5cclxufSJdfQ==
|