@c80/ui 1.0.44 → 1.0.46
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 +2 -2
- package/lib/modal/index.d.ts +2 -3
- package/lib/stat-card/stat-card.component.d.ts +2 -2
- package/lib/table/table.component.d.ts +10 -13
- 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 -9
- package/esm2022/lib/table/table-column-visibility.service.mjs +0 -105
- package/esm2022/lib/table/table-crud-state.service.mjs +0 -115
- package/esm2022/lib/table/table-data-converter.service.mjs +0 -145
- package/esm2022/lib/table/table-data-utils.service.mjs +0 -193
- package/esm2022/lib/table/table-selection.service.mjs +0 -121
- package/esm2022/lib/table/table.component.mjs +0 -432
- package/esm2022/lib/table/table.types.mjs +0 -5
- package/esm2022/lib/table/table.utils.mjs +0 -107
|
@@ -1,432 +0,0 @@
|
|
|
1
|
-
import { Component, Input, signal, computed, output, inject, } from '@angular/core';
|
|
2
|
-
import { C80IconComponent } from '../icon';
|
|
3
|
-
import { TableColumnVisibilityService } from './table-column-visibility.service';
|
|
4
|
-
import { TableDataUtilsService } from './table-data-utils.service';
|
|
5
|
-
import { TableDataConverterService } from './table-data-converter.service';
|
|
6
|
-
import { TableSelectionService } from './table-selection.service';
|
|
7
|
-
import { TableCrudStateService } from './table-crud-state.service';
|
|
8
|
-
import { C80ModalComponent, ModalService } from '../modal';
|
|
9
|
-
import { booleanAttribute, getErrorMessage, getInputValue, trackById, shouldShowAction, getActionTooltip, } from './table.utils';
|
|
10
|
-
import * as i0 from "@angular/core";
|
|
11
|
-
/**
|
|
12
|
-
* C80TableComponent - Componente de tabla avanzado con funcionalidades CRUD
|
|
13
|
-
*
|
|
14
|
-
* COMPORTAMIENTO DE VISIBILIDAD DE COLUMNAS:
|
|
15
|
-
* ========================================
|
|
16
|
-
*
|
|
17
|
-
* 1. PRIORIDAD MÁXIMA - visible: false
|
|
18
|
-
* - La columna se oculta SIEMPRE, sin excepciones
|
|
19
|
-
* - Ni en modo creación ni en modo edición se muestra
|
|
20
|
-
*
|
|
21
|
-
* 2. OCULTACIÓN AUTOMÁTICA - hideIfAllValuesAreNull: true
|
|
22
|
-
* - La columna se oculta solo si TODOS los valores actuales están vacíos
|
|
23
|
-
* - Valores considerados vacíos: null, undefined, '', [], {}
|
|
24
|
-
* - Valores NO vacíos: 0, false (son valores válidos)
|
|
25
|
-
* - EXCEPCIONES IMPORTANTES:
|
|
26
|
-
* * En modo creación (creating=true) estas columnas SÍ se muestran
|
|
27
|
-
* * En modo edición de una fila específica se muestran SOLO si esa fila tiene valor
|
|
28
|
-
*
|
|
29
|
-
* 3. POR DEFECTO - Columnas normales
|
|
30
|
-
* - Se muestran siempre (visualización, creación y edición)
|
|
31
|
-
*
|
|
32
|
-
* VALORES POR DEFECTO EN CREACIÓN:
|
|
33
|
-
* ===============================
|
|
34
|
-
*
|
|
35
|
-
* - Propiedad `default?: unknown` permite definir valores por defecto para modo creación
|
|
36
|
-
* - Solo se aplica cuando se inicia el modo creación (startCreate)
|
|
37
|
-
* - Puede ser cualquier tipo: string, number, boolean, etc.
|
|
38
|
-
* - Si no se especifica `default`, se usa cadena vacía ('')
|
|
39
|
-
*
|
|
40
|
-
* VALORES DINÁMICOS EN CREACIÓN Y EDICIÓN:
|
|
41
|
-
* =======================================
|
|
42
|
-
*
|
|
43
|
-
* - Input `inputValues$?: Observable<Partial<T>>` permite actualizar valores dinámicamente
|
|
44
|
-
* - Solo se aplica durante modo creación (creating=true) o edición (editing!=null)
|
|
45
|
-
* - Los valores se aplican automáticamente cuando el Observable emite
|
|
46
|
-
* - Permite cambios múltiples durante el mismo modo de creación/edición
|
|
47
|
-
* - Los nuevos valores sobrescriben los existentes (spread operator)
|
|
48
|
-
*
|
|
49
|
-
* TIPOS DE DATOS SOPORTADOS:
|
|
50
|
-
* =========================
|
|
51
|
-
*
|
|
52
|
-
* - 'string': Texto normal (default)
|
|
53
|
-
* - 'number': Números decimales (preserva decimales: 5.3 → 5.3)
|
|
54
|
-
* - 'integer': Números enteros (convierte a entero: 5.3 → 5)
|
|
55
|
-
* - 'boolean': Verdadero/Falso (checkbox)
|
|
56
|
-
* - 'password': Texto oculto (input type="password")
|
|
57
|
-
* - 'enum': Lista de opciones predefinidas (select)
|
|
58
|
-
*
|
|
59
|
-
* SISTEMA DE ACCIONES UNIFICADO (customActions):
|
|
60
|
-
* =============================================
|
|
61
|
-
*
|
|
62
|
-
* Input: `customActions: CustomTableAction[]` - Array de acciones dinámicas
|
|
63
|
-
* Output: `(actionClick)` - Evento unificado que emite { action: string, row: T }
|
|
64
|
-
*
|
|
65
|
-
* ACCIONES CRUD PREDEFINIDAS (TABLE_CRUD_ACTIONS):
|
|
66
|
-
* ------------------------------------------------
|
|
67
|
-
* - CREATE: Solo aparece como botón "+" en header (no en filas)
|
|
68
|
-
* - UPDATE: Activa modo edición (muestra inputs), botón "✓" guarda cambios
|
|
69
|
-
* - DELETE: Muestra confirmación y emite evento delete
|
|
70
|
-
* - CANCEL: Muestra confirmación y emite evento cancel (opcional)
|
|
71
|
-
*
|
|
72
|
-
* ACCIONES PERSONALIZADAS (Custom Actions):
|
|
73
|
-
* -----------------------------------------
|
|
74
|
-
* Interfaz: { name: string, icon: IconType, condition?: (row) => boolean, tooltip?: string }
|
|
75
|
-
* - name: ID único de la acción
|
|
76
|
-
* - icon: Icono del botón (ej: 'settings', 'upload', 'refresh')
|
|
77
|
-
* - condition: Función opcional para mostrar/ocultar según estado de fila
|
|
78
|
-
* - tooltip: Texto al hacer hover (default: name)
|
|
79
|
-
*
|
|
80
|
-
* MANEJO EN COMPONENTE:
|
|
81
|
-
* --------------------
|
|
82
|
-
* ```typescript
|
|
83
|
-
* // 1. Definir acciones en constants:
|
|
84
|
-
* export const ENTITY_TABLE_ACTIONS: CustomTableAction[] = [
|
|
85
|
-
* TABLE_CRUD_ACTIONS.CREATE,
|
|
86
|
-
* TABLE_CRUD_ACTIONS.UPDATE,
|
|
87
|
-
* { name: 'custom-action', icon: 'settings', tooltip: 'Configurar' },
|
|
88
|
-
* TABLE_CRUD_ACTIONS.DELETE
|
|
89
|
-
* ];
|
|
90
|
-
*
|
|
91
|
-
* // 2. En el componente:
|
|
92
|
-
* readonly tableActions = ENTITY_TABLE_ACTIONS;
|
|
93
|
-
*
|
|
94
|
-
* handleAction({ action, row }) {
|
|
95
|
-
* const entity = row as unknown as EntityType;
|
|
96
|
-
* switch (action) {
|
|
97
|
-
* case 'create': this.onCreate(row); break;
|
|
98
|
-
* case 'update': this.onUpdate(entity); break;
|
|
99
|
-
* case 'delete': this.onDelete(entity.id); break;
|
|
100
|
-
* case 'custom-action': this.onCustom(entity); break;
|
|
101
|
-
* }
|
|
102
|
-
* }
|
|
103
|
-
* ```
|
|
104
|
-
*
|
|
105
|
-
* ACCIONES CON CONDICIÓN:
|
|
106
|
-
* ----------------------
|
|
107
|
-
* ```typescript
|
|
108
|
-
* {
|
|
109
|
-
* name: 'enable',
|
|
110
|
-
* icon: 'toggleOn',
|
|
111
|
-
* tooltip: 'Habilitar',
|
|
112
|
-
* condition: (row) => row['enabled'] === false
|
|
113
|
-
* }
|
|
114
|
-
* ```
|
|
115
|
-
*
|
|
116
|
-
* CONSTANTES REUTILIZABLES:
|
|
117
|
-
* ------------------------
|
|
118
|
-
* - TABLE_CRUD_ACTIONS: Objeto con CREATE, UPDATE, DELETE, CANCEL
|
|
119
|
-
* - BASIC_CRUD_ACTIONS: Array con [CREATE, UPDATE, DELETE]
|
|
120
|
-
* Importar desde: `@shared` o `@shared/constants`
|
|
121
|
-
*
|
|
122
|
-
* EJEMPLOS COMPLETOS:
|
|
123
|
-
* ------------------
|
|
124
|
-
* - { accessor: 'id', visible: false } → NUNCA se muestra
|
|
125
|
-
* - { accessor: 'motorPos', hideIfAllValuesAreNull: true, default: 0, type: 'integer' } → Entero (5.7 → 5)
|
|
126
|
-
* - { accessor: 'weight', type: 'number', default: 2.5 } → Decimal preservado (5.7 → 5.7)
|
|
127
|
-
* - { accessor: 'status', default: 'active' } → Se autorellena con 'active' en creación
|
|
128
|
-
* - { accessor: 'name' } → Siempre visible, sin valor por defecto (cadena vacía)
|
|
129
|
-
* - inputValues$ emite { motorPos: 5, weight: 2.3 } → actualiza inputs dinámicamente
|
|
130
|
-
* - customActions con CREATE → Muestra botón "+" en header
|
|
131
|
-
* - customActions con UPDATE → Botón "edit" activa modo edición
|
|
132
|
-
* - customActions con custom → Botón personalizado emite evento
|
|
133
|
-
*/ export class C80TableComponent {
|
|
134
|
-
// Servicios inyectados
|
|
135
|
-
modalService = inject(ModalService);
|
|
136
|
-
visibilityService = inject(TableColumnVisibilityService);
|
|
137
|
-
dataUtils = inject(TableDataUtilsService);
|
|
138
|
-
dataConverter = inject(TableDataConverterService);
|
|
139
|
-
selectionService = inject(TableSelectionService);
|
|
140
|
-
crudService = inject(TableCrudStateService);
|
|
141
|
-
// Inputs
|
|
142
|
-
data$;
|
|
143
|
-
columns = [];
|
|
144
|
-
inputValues$; // Observable para actualizar valores de inputs dinámicamente en creación/edición
|
|
145
|
-
customActions = []; // Acciones personalizadas dinámicas
|
|
146
|
-
size = 0; // Tamaño de la tabla (0 = sin límite, > 0 aplica max-height)
|
|
147
|
-
multiple = true; // Permite selección múltiple por defecto
|
|
148
|
-
searchable = false; // Si es true, muestra barra de búsqueda
|
|
149
|
-
allowSelection = false; // Si es true, permite selección de filas
|
|
150
|
-
noConfirm = false; // Si es true, no muestra confirmaciones modales
|
|
151
|
-
// Outputs - Acciones unificadas (Angular 18+ output API)
|
|
152
|
-
actionClick = output(); // Output unificado para TODAS las acciones (CRUD + custom)
|
|
153
|
-
// Outputs - Utilidades
|
|
154
|
-
searchTerm = output();
|
|
155
|
-
errorEvent = output();
|
|
156
|
-
selectable = output();
|
|
157
|
-
// Estado principal
|
|
158
|
-
data = signal([]);
|
|
159
|
-
searchValue = signal('');
|
|
160
|
-
// Estado de selección (delegado a servicio)
|
|
161
|
-
selectionState = this.selectionService.createSelectionState();
|
|
162
|
-
selectedItems = this.selectionState.selectedItems;
|
|
163
|
-
selectAllChecked = this.selectionState.selectAllChecked;
|
|
164
|
-
selectAllIndeterminate = this.selectionState.selectAllIndeterminate;
|
|
165
|
-
// Estado CRUD (delegado a servicio)
|
|
166
|
-
crudState = this.crudService.createCrudState();
|
|
167
|
-
creating = this.crudState.creating;
|
|
168
|
-
newRow = this.crudState.newRow;
|
|
169
|
-
editing = this.crudState.editing;
|
|
170
|
-
editRow = this.crudState.editRow;
|
|
171
|
-
// Keys visibles computed automáticamente
|
|
172
|
-
keys = computed(() => this.visibilityService.updateVisibleKeys(this.columns, this.data(), this.creating(), this.editing()));
|
|
173
|
-
// Computed - Detecta acciones CRUD y custom
|
|
174
|
-
hasAnyActions = computed(() => this.customActions.length > 0);
|
|
175
|
-
hasCrudCreate = computed(() => this.customActions.some(a => a.name === 'create'));
|
|
176
|
-
hasCrudUpdate = computed(() => this.customActions.some(a => a.name === 'update'));
|
|
177
|
-
hasCrudDelete = computed(() => this.customActions.some(a => a.name === 'delete'));
|
|
178
|
-
hasCrudCancel = computed(() => this.customActions.some(a => a.name === 'cancel'));
|
|
179
|
-
// Table max height computed
|
|
180
|
-
tableMaxHeight = computed(() => this.dataUtils.getTableMaxHeight(this.size));
|
|
181
|
-
dataSub;
|
|
182
|
-
inputValuesSub;
|
|
183
|
-
/**
|
|
184
|
-
* Maneja input de creación/edición de forma unificada
|
|
185
|
-
*/
|
|
186
|
-
handleInput(event, key, col, isEdit) {
|
|
187
|
-
const updateFn = isEdit
|
|
188
|
-
? this.crudState.updateEditRow.bind(this.crudState)
|
|
189
|
-
: this.crudState.updateNewRow.bind(this.crudState);
|
|
190
|
-
const value = getInputValue(event, col);
|
|
191
|
-
if (value !== undefined) {
|
|
192
|
-
updateFn(key, value);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Maneja confirmación modal de forma genérica
|
|
197
|
-
*/
|
|
198
|
-
async handleConfirmAction(title, message, confirmText, action) {
|
|
199
|
-
if (this.noConfirm) {
|
|
200
|
-
action();
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
const confirmed = await this.modalService.confirm(title, message, confirmText, 'Cancelar');
|
|
204
|
-
if (confirmed) {
|
|
205
|
-
action();
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
ngOnInit() {
|
|
209
|
-
if (!this.data$)
|
|
210
|
-
return;
|
|
211
|
-
this.dataSub = this.data$.subscribe({
|
|
212
|
-
next: (items) => {
|
|
213
|
-
this.dataUtils.applySorting(items, this.columns);
|
|
214
|
-
this.data.set(items);
|
|
215
|
-
this.preserveSelection();
|
|
216
|
-
},
|
|
217
|
-
error: (err) => this.errorEvent.emit(getErrorMessage(err)),
|
|
218
|
-
});
|
|
219
|
-
// Suscribirse a inputValues$ para actualizar valores dinámicamente en creación/edición
|
|
220
|
-
if (this.inputValues$) {
|
|
221
|
-
this.inputValuesSub = this.inputValues$.subscribe({
|
|
222
|
-
next: (partialValues) => {
|
|
223
|
-
this.crudState.applyInputValues(partialValues);
|
|
224
|
-
},
|
|
225
|
-
error: (err) => console.warn('Error en inputValues$:', getErrorMessage(err)),
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
ngOnDestroy() {
|
|
230
|
-
this.dataSub?.unsubscribe();
|
|
231
|
-
this.inputValuesSub?.unsubscribe();
|
|
232
|
-
// Close any open modal when component is destroyed
|
|
233
|
-
this.modalService.closeModal();
|
|
234
|
-
}
|
|
235
|
-
onInput(event, key, col) {
|
|
236
|
-
this.handleInput(event, key, col, false);
|
|
237
|
-
}
|
|
238
|
-
onEditInput(event, key, col) {
|
|
239
|
-
this.handleInput(event, key, col, true);
|
|
240
|
-
}
|
|
241
|
-
async onDelete(row) {
|
|
242
|
-
await this.handleConfirmAction('Confirmar eliminación', '¿Está seguro de que desea eliminar este elemento? Esta acción no se puede deshacer.', 'Eliminar', () => this.actionClick.emit({ action: 'delete', row }));
|
|
243
|
-
}
|
|
244
|
-
async onCancel(row) {
|
|
245
|
-
await this.handleConfirmAction('Confirmar cancelación', '¿Está seguro de que desea cancelar este elemento?', 'Cancelar elemento', () => this.actionClick.emit({ action: 'cancel', row }));
|
|
246
|
-
}
|
|
247
|
-
startCreate() {
|
|
248
|
-
this.crudState.startCreate(this.columns, this.data());
|
|
249
|
-
}
|
|
250
|
-
cancelCreate() {
|
|
251
|
-
this.crudState.cancelCreate();
|
|
252
|
-
}
|
|
253
|
-
saveCreate() {
|
|
254
|
-
const current = this.newRow();
|
|
255
|
-
if (current) {
|
|
256
|
-
const convertedRow = this.convertRowTypes(current);
|
|
257
|
-
this.actionClick.emit({ action: 'create', row: convertedRow });
|
|
258
|
-
this.cancelCreate();
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
onEdit(row) {
|
|
262
|
-
this.crudState.startEdit(row, this.columns, this.data());
|
|
263
|
-
}
|
|
264
|
-
cancelEdit() {
|
|
265
|
-
this.crudState.cancelEdit();
|
|
266
|
-
}
|
|
267
|
-
saveEdit(row) {
|
|
268
|
-
const changes = this.editRow();
|
|
269
|
-
if (changes) {
|
|
270
|
-
const convertedChanges = this.convertRowTypes(changes);
|
|
271
|
-
const updatedRow = { ...row, ...convertedChanges };
|
|
272
|
-
this.actionClick.emit({ action: 'update', row: updatedRow });
|
|
273
|
-
this.cancelEdit();
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Convierte todos los valores de una fila según los tipos definidos en las columnas
|
|
278
|
-
* Asegura que los datos emitidos tengan el tipo correcto (integer, number, boolean, etc.)
|
|
279
|
-
*/
|
|
280
|
-
convertRowTypes(row) {
|
|
281
|
-
const converted = {};
|
|
282
|
-
const columnsMap = new Map(this.columns.map(col => [col.accessor, col]));
|
|
283
|
-
for (const [key, value] of Object.entries(row)) {
|
|
284
|
-
const col = columnsMap.get(key);
|
|
285
|
-
if (col) {
|
|
286
|
-
converted[key] = this.dataConverter.convertCellValue(value, col);
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
converted[key] = value;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
return converted;
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* TrackBy function for ngFor to avoid DOM re-creation (NG0956 warning).
|
|
296
|
-
*/
|
|
297
|
-
trackById = (trackById);
|
|
298
|
-
/**
|
|
299
|
-
* Verifica si una acción personalizada debe mostrarse para una fila específica
|
|
300
|
-
*/
|
|
301
|
-
shouldShowAction = (shouldShowAction);
|
|
302
|
-
/**
|
|
303
|
-
* Obtiene el tooltip de una acción
|
|
304
|
-
*/
|
|
305
|
-
getActionTooltip = getActionTooltip;
|
|
306
|
-
/**
|
|
307
|
-
* Maneja el click en una acción personalizada dinámica
|
|
308
|
-
* UPDATE activa el modo edición, otras acciones emiten directamente
|
|
309
|
-
* Si la acción tiene configuración de confirmación, muestra modal antes de ejecutar
|
|
310
|
-
*/
|
|
311
|
-
onDynamicAction(action, row) {
|
|
312
|
-
if (action.name === 'update') {
|
|
313
|
-
this.onEdit(row);
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
if (action.name === 'delete') {
|
|
317
|
-
void this.onDelete(row);
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
if (action.name === 'cancel') {
|
|
321
|
-
void this.onCancel(row);
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
// Si la acción tiene confirmación configurada, mostrar modal
|
|
325
|
-
if (action.confirmation) {
|
|
326
|
-
void this.handleActionWithConfirmation(action, row);
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
// Sin confirmación, emitir directamente
|
|
330
|
-
this.actionClick.emit({ action: action.name, row });
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Maneja acciones que requieren confirmación del usuario
|
|
334
|
-
*/
|
|
335
|
-
async handleActionWithConfirmation(action, row) {
|
|
336
|
-
if (!action.confirmation)
|
|
337
|
-
return;
|
|
338
|
-
const confirmed = await this.modalService.confirm(action.confirmation.title, action.confirmation.message, action.confirmation.confirmText || 'Confirmar', action.confirmation.cancelText || 'Cancelar');
|
|
339
|
-
if (confirmed) {
|
|
340
|
-
this.actionClick.emit({ action: action.name, row });
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* Handles search input changes with debouncing
|
|
345
|
-
*/
|
|
346
|
-
onSearchInput(event) {
|
|
347
|
-
const target = event.target;
|
|
348
|
-
const value = target.value;
|
|
349
|
-
this.searchValue.set(value);
|
|
350
|
-
this.searchTerm.emit(value);
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* Clears the search input
|
|
354
|
-
*/
|
|
355
|
-
clearSearch() {
|
|
356
|
-
this.searchValue.set('');
|
|
357
|
-
this.searchTerm.emit('');
|
|
358
|
-
}
|
|
359
|
-
// Referencias readonly a métodos de servicios (evita wrappers innecesarios)
|
|
360
|
-
getCellValue = this.dataUtils.getCellValue.bind(this.dataUtils);
|
|
361
|
-
getDisplayValue = this.dataUtils.getDisplayValue.bind(this.dataUtils);
|
|
362
|
-
getEnumDisplayValue = this.dataUtils.getEnumDisplayValue.bind(this.dataUtils);
|
|
363
|
-
getEnumOptions = this.dataUtils.getEnumOptions.bind(this.dataUtils);
|
|
364
|
-
getCellColor = this.dataUtils.getCellColor.bind(this.dataUtils);
|
|
365
|
-
/**
|
|
366
|
-
* Selection methods
|
|
367
|
-
*/
|
|
368
|
-
clearSelection() {
|
|
369
|
-
this.selectionState.clearSelection();
|
|
370
|
-
this.selectionService.emitSelection(this.selectionState, this.data(), this.selectable);
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* Mantiene la selección existente después de actualizar los datos,
|
|
374
|
-
* eliminando solo los IDs que ya no existen en los nuevos datos
|
|
375
|
-
*/
|
|
376
|
-
preserveSelection() {
|
|
377
|
-
this.selectionState.preserveSelection(this.data());
|
|
378
|
-
this.selectionService.emitSelection(this.selectionState, this.data(), this.selectable);
|
|
379
|
-
}
|
|
380
|
-
toggleSelectAll() {
|
|
381
|
-
this.selectionState.toggleSelectAll(this.data());
|
|
382
|
-
this.selectionService.emitSelection(this.selectionState, this.data(), this.selectable);
|
|
383
|
-
}
|
|
384
|
-
toggleItemSelection(item) {
|
|
385
|
-
this.selectionState.toggleItemSelection(item, this.multiple);
|
|
386
|
-
this.selectionService.emitSelection(this.selectionState, this.data(), this.selectable);
|
|
387
|
-
}
|
|
388
|
-
isItemSelected(item) {
|
|
389
|
-
return this.selectionState.isItemSelected(item);
|
|
390
|
-
}
|
|
391
|
-
// Métodos de visibilidad delegados a servicio
|
|
392
|
-
isColumnVisible(column) {
|
|
393
|
-
return this.visibilityService.isColumnVisible(column, this.data(), {
|
|
394
|
-
creating: this.creating(),
|
|
395
|
-
row: this.newRow() ?? undefined
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
isColumnVisibleInHeader(column) {
|
|
399
|
-
return this.visibilityService.isColumnVisibleInHeader(column, this.data(), this.creating(), this.editing());
|
|
400
|
-
}
|
|
401
|
-
isColumnVisibleForRow(column, row) {
|
|
402
|
-
return this.visibilityService.isColumnVisibleForRow(column, row, this.data(), this.editing());
|
|
403
|
-
}
|
|
404
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: C80TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
405
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: C80TableComponent, isStandalone: true, selector: "c80-table", inputs: { data$: "data$", columns: "columns", inputValues$: "inputValues$", customActions: "customActions", size: "size", multiple: "multiple", searchable: ["searchable", "searchable", booleanAttribute], allowSelection: ["allowSelection", "allowSelection", booleanAttribute], noConfirm: ["noConfirm", "noConfirm", booleanAttribute] }, outputs: { actionClick: "actionClick", searchTerm: "searchTerm", errorEvent: "errorEvent", selectable: "selectable" }, ngImport: i0, template: "<div class=\"table-responsive\" [style.max-height]=\"tableMaxHeight()\" [style.overflow-y]=\"size > 0 ? 'auto' : 'visible'\">\n <!-- Search Bar -->\n @if (searchable) {\n <div class=\"search-container\">\n <div class=\"search-input-wrapper\">\n <div class=\"input-group\">\n <span class=\"input-group-text\">\n <c80-icon icon=\"search\" [size]=\".8\"></c80-icon>\n </span>\n <input type=\"text\" class=\"form-control search-input\" placeholder=\"Buscar...\" [value]=\"searchValue()\" (input)=\"onSearchInput($event)\" aria-label=\"Buscar en la tabla\" />\n @if (searchValue()) {\n <button class=\"btn btn-outline-secondary btn-borrar\" type=\"button\" (click)=\"clearSearch()\" title=\"Limpiar b\u00FAsqueda\">\n <c80-icon icon=\"cancel\" [size]=\".7\"></c80-icon>\n </button>\n }\n </div>\n </div>\n </div>\n }\n\n <table class=\"table table-bordered table-hover align-middle\">\n <thead class=\"thead table-light sticky-header\">\n <tr>\n @if (allowSelection && data().length !== 0) {\n <th class=\"text-center selection-column\">\n @if (multiple) {\n <input type=\"checkbox\" [checked]=\"selectAllChecked()\" [indeterminate]=\"selectAllIndeterminate()\" (change)=\"toggleSelectAll()\" aria-label=\"Seleccionar todo\" />\n }\n </th>\n }\n @for (col of columns; track col) {\n @if (isColumnVisibleInHeader(col)) {\n @if (col.type === 'boolean') {\n <th class=\"text-center boolean-column\">{{ col.label }}</th>\n }\n @else if (col.type === 'number' || col.type === 'integer') {\n <th class=\"text-center number-column\">{{ col.label }}</th>\n }\n @else {\n <th>{{ col.label }}</th>\n }\n }\n }\n @if (hasAnyActions()) {\n <th class=\"table-actions-header\">\n <div class=\"actions-wrapper\">\n <span>Actions</span>\n @if (hasCrudCreate()) {\n <c80-icon button icon=\"add\" [disabled]=\"creating()\" title=\"Agregar\" [size]=\".6\" (iconClick)=\"startCreate()\"></c80-icon>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of data(); track trackById(i, row); let i = $index) {\n <tr>\n @if (allowSelection && data().length !== 0) {\n <td class=\"text-center selection-column\">\n <input type=\"checkbox\" [checked]=\"isItemSelected(row)\" (change)=\"toggleItemSelection(row)\" [attr.aria-label]=\"'Seleccionar fila ' + (i + 1)\" />\n </td>\n }\n @for (col of columns; track col) {\n @if (isColumnVisibleForRow(col, row)) {\n @if (col.type === 'boolean') {\n <td class=\"text-center boolean-column\">\n @if (editing() === row['id'] && !col.readOnly) {\n <input type=\"checkbox\" [checked]=\"!!editRow()?.[col.accessor]\" (change)=\"onEditInput($event, col.accessor, col)\" [attr.aria-label]=\"col.label\" />\n }\n @else {\n @if (getCellValue(row, col.accessor) === true) {\n <c80-icon icon=\"check\" [size]=\".7\"></c80-icon>\n <br />\n }\n @else if (getCellValue(row, col.accessor) === false) {\n <c80-icon icon=\"cancel\" [size]=\".7\"></c80-icon>\n <br />\n }\n }\n </td>\n }\n @else if (col.type === 'number' || col.type === 'integer') {\n <td class=\"text-center number-column\">\n @if (editing() === row['id'] && !col.readOnly) {\n <input class=\"form-control form-control-sm\" type=\"number\" [value]=\"editRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" [min]=\"col.min\" [max]=\"col.max\" [step]=\"col.type === 'integer' ? '1' : 'any'\"\n (input)=\"onEditInput($event, col.accessor, col)\" />\n }\n @else {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{ getDisplayValue(getCellValue(row,\n col.accessor), col) }}</span>\n }\n </td>\n }\n @else {\n <td>\n @if (editing() === row['id'] && !col.readOnly) {\n @if (col.type === 'enum') {\n <select class=\"form-control form-control-sm\" [value]=\"editRow()?.[col.accessor] ?? ''\" (change)=\"onEditInput($event, col.accessor, col)\">\n <option value=\"\">{{ col.label }}</option>\n @for (option of getEnumOptions(col); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <input class=\"form-control form-control-sm\" [type]=\"col.type === 'password' ? 'password' : 'text'\" [value]=\"editRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" (input)=\"onEditInput($event, col.accessor, col)\" />\n }\n }\n @else {\n @if (col.type === 'password') {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">******</span>\n }\n @else if (col.type === 'enum') {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{\n getEnumDisplayValue(getCellValue(row, col.accessor), col)\n }}</span>\n }\n @else if (getCellValue(row, col.accessor) === true) {\n <c80-icon icon=\"check\" [size]=\".7\"></c80-icon>\n }\n @else if (getCellValue(row, col.accessor) === false) {\n <c80-icon icon=\"cancel\" [size]=\".7\"></c80-icon>\n }\n @else {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{ getDisplayValue(getCellValue(row,\n col.accessor), col) }}</span>\n }\n }\n </td>\n }\n }\n }\n @if (hasAnyActions()) {\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (editing() === row['id']) {\n <!-- Modo edici\u00F3n: mostrar guardar y cancelar -->\n @if (hasCrudUpdate()) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveEdit(row)\" [size]=\".7\"></c80-icon>\n }\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelEdit()\" [size]=\".7\"></c80-icon>\n }\n @else {\n @for (action of customActions; track action.name) {\n @if (shouldShowAction(action, row)) {\n <c80-icon button [icon]=\"action.icon\" [customColor]=\"action.color\" [color]=\"action.name === 'delete' ? 'warn' : 'primary'\" [title]=\"getActionTooltip(action)\" (iconClick)=\"onDynamicAction(action, row)\" [size]=\".7\"></c80-icon>\n }\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n @if (creating() && hasCrudCreate()) {\n <tr>\n @if (allowSelection && data().length !== 0) {\n <td class=\"text-center selection-column\">\n <!-- Empty cell for alignment -->\n </td>\n }\n @for (col of columns; track col) {\n @if (isColumnVisible(col)) {\n @if (col.type === 'boolean') {\n <td class=\"text-center\">\n @if (!col.readOnly) {\n <input type=\"checkbox\" [checked]=\"!!newRow()?.[col.accessor]\" (change)=\"onInput($event, col.accessor, col)\" [attr.aria-label]=\"col.label\" />\n }\n @else {\n <!-- ReadOnly boolean column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n } @else if (col.type === 'number' || col.type === 'integer') {\n <td class=\"text-center number-column\">\n @if (!col.readOnly) {\n <input class=\"form-control form-control-sm\" type=\"number\" [value]=\"newRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" [min]=\"col.min\" [max]=\"col.max\" [step]=\"col.type === 'integer' ? '1' : 'any'\"\n (input)=\"onInput($event, col.accessor, col)\" />\n }\n @else {\n <!-- ReadOnly number column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n } @else {\n <td>\n @if (!col.readOnly) {\n @if (col.type === 'enum') {\n <select class=\"form-control form-control-sm\" [value]=\"newRow()?.[col.accessor] ?? ''\" (change)=\"onInput($event, col.accessor, col)\">\n <option value=\"\">{{ col.label }}</option>\n @for (option of getEnumOptions(col); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <input class=\"form-control form-control-sm\" type=\"text\" [value]=\"newRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" (input)=\"onInput($event, col.accessor, col)\" />\n }\n }\n @else {\n <!-- ReadOnly column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n }\n }\n }\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (hasCrudCreate()) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveCreate()\" [size]=\".7\"></c80-icon>\n }\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelCreate()\" [size]=\".7\"></c80-icon>\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n @if (data().length === 0 && !creating()) {\n <div class=\"text-center text-muted py-3 small\">\n No hay datos para mostrar.\n </div>\n }\n</div>\n\n<c80-modal></c80-modal>", styles: ["@charset \"UTF-8\";input[type=checkbox]{width:1.3rem!important;height:1.3rem!important;accent-color:rgba(226,0,0,.7647058824);background:#fff;margin:0 .25rem;vertical-align:middle;cursor:pointer}.table-responsive{width:100%;overflow-x:auto}.table-responsive .search-container{margin-bottom:-.06rem}.table-responsive .search-container .search-input-wrapper .input-group .btn-borrar{border-bottom-right-radius:0;border-color:#dee2e6}.table-responsive .search-container .search-input-wrapper .input-group .input-group-text{background-color:#f8f9fa;border-color:#dee2e6;border-bottom-left-radius:0;color:#495057;width:56px}.table-responsive .search-container .search-input-wrapper .input-group .input-group-text c80-icon{display:flex;align-items:center;justify-content:center;padding-bottom:.2rem}.table-responsive .search-container .search-input-wrapper .input-group .search-input{border-color:#dee2e6;border-bottom-right-radius:0;font-size:.95rem;outline:none!important}.table-responsive .search-container .search-input-wrapper .input-group .search-input:focus{outline:none!important}.table-responsive .search-container .search-input-wrapper .input-group .search-input::placeholder{color:#999;font-style:italic}.table-responsive .table{min-width:0px;margin-bottom:.5rem}.table-responsive .table .sticky-header{position:sticky;top:0;z-index:10;background-color:#f8f9fa!important}.table-responsive .table .sticky-header .table-actions-header{display:table-cell;vertical-align:middle;padding:.2rem .6rem!important;background-color:#f8f9fa!important}.table-responsive .table .sticky-header .actions-wrapper{display:flex;align-items:center;justify-content:center;gap:.5rem;height:100%}.table-responsive .table .sticky-header th{max-height:31px!important;vertical-align:middle!important;padding:.2rem .6rem!important;font-size:small!important;background-color:#f8f9fa!important;border-bottom:2px solid #dee2e6}.table-responsive .table tbody td{height:35px!important;min-height:35px!important;max-height:35px!important;vertical-align:middle!important;padding:.2rem .8rem!important;font-size:small}.table-responsive .table tbody tr{height:35px!important;min-height:35px!important;max-height:35px!important;cursor:pointer}.table-responsive .table tbody tr:hover{background-color:#f5f5f5}.table-responsive .table tbody input{border:1px solid rgba(34,0,255,.37);height:100%!important;font-size:smaller!important}.table-responsive .table tbody input[type=text],.table-responsive .table tbody input:not([type]){width:100%!important}.table-responsive .table tbody input[type=number]{min-width:80px!important;width:80px!important;text-align:center}.table-responsive .table thead th.boolean-column,.table-responsive .table tbody td.boolean-column,.table-responsive .table thead th.selection-column,.table-responsive .table tbody td.selection-column,.table-responsive .table thead th.table-actions-header,.table-responsive .table tbody td.table-actions-header{width:1%;white-space:nowrap}.table-responsive .table thead th.number-column,.table-responsive .table tbody td.number-column{width:1%;white-space:nowrap;text-align:center}.table-responsive .table thead th.number-column input[type=number],.table-responsive .table tbody td.number-column input[type=number]{min-width:80px!important;width:80px!important;text-align:center}.table-responsive .table .actions-cell{white-space:nowrap;padding:0!important}.table-responsive .table .actions-container{display:flex;flex-direction:row;justify-content:center;align-items:center;width:100%;height:100%}\n"], dependencies: [{ kind: "component", type: C80IconComponent, selector: "c80-icon", inputs: ["icon", "color", "customColor", "disabled", "size", "button", "border", "type", "textLeft", "textRight"], outputs: ["iconClick"] }, { kind: "component", type: C80ModalComponent, selector: "c80-modal" }] });
|
|
406
|
-
}
|
|
407
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: C80TableComponent, decorators: [{
|
|
408
|
-
type: Component,
|
|
409
|
-
args: [{ selector: 'c80-table', standalone: true, imports: [C80IconComponent, C80ModalComponent], template: "<div class=\"table-responsive\" [style.max-height]=\"tableMaxHeight()\" [style.overflow-y]=\"size > 0 ? 'auto' : 'visible'\">\n <!-- Search Bar -->\n @if (searchable) {\n <div class=\"search-container\">\n <div class=\"search-input-wrapper\">\n <div class=\"input-group\">\n <span class=\"input-group-text\">\n <c80-icon icon=\"search\" [size]=\".8\"></c80-icon>\n </span>\n <input type=\"text\" class=\"form-control search-input\" placeholder=\"Buscar...\" [value]=\"searchValue()\" (input)=\"onSearchInput($event)\" aria-label=\"Buscar en la tabla\" />\n @if (searchValue()) {\n <button class=\"btn btn-outline-secondary btn-borrar\" type=\"button\" (click)=\"clearSearch()\" title=\"Limpiar b\u00FAsqueda\">\n <c80-icon icon=\"cancel\" [size]=\".7\"></c80-icon>\n </button>\n }\n </div>\n </div>\n </div>\n }\n\n <table class=\"table table-bordered table-hover align-middle\">\n <thead class=\"thead table-light sticky-header\">\n <tr>\n @if (allowSelection && data().length !== 0) {\n <th class=\"text-center selection-column\">\n @if (multiple) {\n <input type=\"checkbox\" [checked]=\"selectAllChecked()\" [indeterminate]=\"selectAllIndeterminate()\" (change)=\"toggleSelectAll()\" aria-label=\"Seleccionar todo\" />\n }\n </th>\n }\n @for (col of columns; track col) {\n @if (isColumnVisibleInHeader(col)) {\n @if (col.type === 'boolean') {\n <th class=\"text-center boolean-column\">{{ col.label }}</th>\n }\n @else if (col.type === 'number' || col.type === 'integer') {\n <th class=\"text-center number-column\">{{ col.label }}</th>\n }\n @else {\n <th>{{ col.label }}</th>\n }\n }\n }\n @if (hasAnyActions()) {\n <th class=\"table-actions-header\">\n <div class=\"actions-wrapper\">\n <span>Actions</span>\n @if (hasCrudCreate()) {\n <c80-icon button icon=\"add\" [disabled]=\"creating()\" title=\"Agregar\" [size]=\".6\" (iconClick)=\"startCreate()\"></c80-icon>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of data(); track trackById(i, row); let i = $index) {\n <tr>\n @if (allowSelection && data().length !== 0) {\n <td class=\"text-center selection-column\">\n <input type=\"checkbox\" [checked]=\"isItemSelected(row)\" (change)=\"toggleItemSelection(row)\" [attr.aria-label]=\"'Seleccionar fila ' + (i + 1)\" />\n </td>\n }\n @for (col of columns; track col) {\n @if (isColumnVisibleForRow(col, row)) {\n @if (col.type === 'boolean') {\n <td class=\"text-center boolean-column\">\n @if (editing() === row['id'] && !col.readOnly) {\n <input type=\"checkbox\" [checked]=\"!!editRow()?.[col.accessor]\" (change)=\"onEditInput($event, col.accessor, col)\" [attr.aria-label]=\"col.label\" />\n }\n @else {\n @if (getCellValue(row, col.accessor) === true) {\n <c80-icon icon=\"check\" [size]=\".7\"></c80-icon>\n <br />\n }\n @else if (getCellValue(row, col.accessor) === false) {\n <c80-icon icon=\"cancel\" [size]=\".7\"></c80-icon>\n <br />\n }\n }\n </td>\n }\n @else if (col.type === 'number' || col.type === 'integer') {\n <td class=\"text-center number-column\">\n @if (editing() === row['id'] && !col.readOnly) {\n <input class=\"form-control form-control-sm\" type=\"number\" [value]=\"editRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" [min]=\"col.min\" [max]=\"col.max\" [step]=\"col.type === 'integer' ? '1' : 'any'\"\n (input)=\"onEditInput($event, col.accessor, col)\" />\n }\n @else {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{ getDisplayValue(getCellValue(row,\n col.accessor), col) }}</span>\n }\n </td>\n }\n @else {\n <td>\n @if (editing() === row['id'] && !col.readOnly) {\n @if (col.type === 'enum') {\n <select class=\"form-control form-control-sm\" [value]=\"editRow()?.[col.accessor] ?? ''\" (change)=\"onEditInput($event, col.accessor, col)\">\n <option value=\"\">{{ col.label }}</option>\n @for (option of getEnumOptions(col); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <input class=\"form-control form-control-sm\" [type]=\"col.type === 'password' ? 'password' : 'text'\" [value]=\"editRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" (input)=\"onEditInput($event, col.accessor, col)\" />\n }\n }\n @else {\n @if (col.type === 'password') {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">******</span>\n }\n @else if (col.type === 'enum') {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{\n getEnumDisplayValue(getCellValue(row, col.accessor), col)\n }}</span>\n }\n @else if (getCellValue(row, col.accessor) === true) {\n <c80-icon icon=\"check\" [size]=\".7\"></c80-icon>\n }\n @else if (getCellValue(row, col.accessor) === false) {\n <c80-icon icon=\"cancel\" [size]=\".7\"></c80-icon>\n }\n @else {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{ getDisplayValue(getCellValue(row,\n col.accessor), col) }}</span>\n }\n }\n </td>\n }\n }\n }\n @if (hasAnyActions()) {\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (editing() === row['id']) {\n <!-- Modo edici\u00F3n: mostrar guardar y cancelar -->\n @if (hasCrudUpdate()) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveEdit(row)\" [size]=\".7\"></c80-icon>\n }\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelEdit()\" [size]=\".7\"></c80-icon>\n }\n @else {\n @for (action of customActions; track action.name) {\n @if (shouldShowAction(action, row)) {\n <c80-icon button [icon]=\"action.icon\" [customColor]=\"action.color\" [color]=\"action.name === 'delete' ? 'warn' : 'primary'\" [title]=\"getActionTooltip(action)\" (iconClick)=\"onDynamicAction(action, row)\" [size]=\".7\"></c80-icon>\n }\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n @if (creating() && hasCrudCreate()) {\n <tr>\n @if (allowSelection && data().length !== 0) {\n <td class=\"text-center selection-column\">\n <!-- Empty cell for alignment -->\n </td>\n }\n @for (col of columns; track col) {\n @if (isColumnVisible(col)) {\n @if (col.type === 'boolean') {\n <td class=\"text-center\">\n @if (!col.readOnly) {\n <input type=\"checkbox\" [checked]=\"!!newRow()?.[col.accessor]\" (change)=\"onInput($event, col.accessor, col)\" [attr.aria-label]=\"col.label\" />\n }\n @else {\n <!-- ReadOnly boolean column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n } @else if (col.type === 'number' || col.type === 'integer') {\n <td class=\"text-center number-column\">\n @if (!col.readOnly) {\n <input class=\"form-control form-control-sm\" type=\"number\" [value]=\"newRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" [min]=\"col.min\" [max]=\"col.max\" [step]=\"col.type === 'integer' ? '1' : 'any'\"\n (input)=\"onInput($event, col.accessor, col)\" />\n }\n @else {\n <!-- ReadOnly number column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n } @else {\n <td>\n @if (!col.readOnly) {\n @if (col.type === 'enum') {\n <select class=\"form-control form-control-sm\" [value]=\"newRow()?.[col.accessor] ?? ''\" (change)=\"onInput($event, col.accessor, col)\">\n <option value=\"\">{{ col.label }}</option>\n @for (option of getEnumOptions(col); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <input class=\"form-control form-control-sm\" type=\"text\" [value]=\"newRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" (input)=\"onInput($event, col.accessor, col)\" />\n }\n }\n @else {\n <!-- ReadOnly column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n }\n }\n }\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (hasCrudCreate()) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveCreate()\" [size]=\".7\"></c80-icon>\n }\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelCreate()\" [size]=\".7\"></c80-icon>\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n @if (data().length === 0 && !creating()) {\n <div class=\"text-center text-muted py-3 small\">\n No hay datos para mostrar.\n </div>\n }\n</div>\n\n<c80-modal></c80-modal>", styles: ["@charset \"UTF-8\";input[type=checkbox]{width:1.3rem!important;height:1.3rem!important;accent-color:rgba(226,0,0,.7647058824);background:#fff;margin:0 .25rem;vertical-align:middle;cursor:pointer}.table-responsive{width:100%;overflow-x:auto}.table-responsive .search-container{margin-bottom:-.06rem}.table-responsive .search-container .search-input-wrapper .input-group .btn-borrar{border-bottom-right-radius:0;border-color:#dee2e6}.table-responsive .search-container .search-input-wrapper .input-group .input-group-text{background-color:#f8f9fa;border-color:#dee2e6;border-bottom-left-radius:0;color:#495057;width:56px}.table-responsive .search-container .search-input-wrapper .input-group .input-group-text c80-icon{display:flex;align-items:center;justify-content:center;padding-bottom:.2rem}.table-responsive .search-container .search-input-wrapper .input-group .search-input{border-color:#dee2e6;border-bottom-right-radius:0;font-size:.95rem;outline:none!important}.table-responsive .search-container .search-input-wrapper .input-group .search-input:focus{outline:none!important}.table-responsive .search-container .search-input-wrapper .input-group .search-input::placeholder{color:#999;font-style:italic}.table-responsive .table{min-width:0px;margin-bottom:.5rem}.table-responsive .table .sticky-header{position:sticky;top:0;z-index:10;background-color:#f8f9fa!important}.table-responsive .table .sticky-header .table-actions-header{display:table-cell;vertical-align:middle;padding:.2rem .6rem!important;background-color:#f8f9fa!important}.table-responsive .table .sticky-header .actions-wrapper{display:flex;align-items:center;justify-content:center;gap:.5rem;height:100%}.table-responsive .table .sticky-header th{max-height:31px!important;vertical-align:middle!important;padding:.2rem .6rem!important;font-size:small!important;background-color:#f8f9fa!important;border-bottom:2px solid #dee2e6}.table-responsive .table tbody td{height:35px!important;min-height:35px!important;max-height:35px!important;vertical-align:middle!important;padding:.2rem .8rem!important;font-size:small}.table-responsive .table tbody tr{height:35px!important;min-height:35px!important;max-height:35px!important;cursor:pointer}.table-responsive .table tbody tr:hover{background-color:#f5f5f5}.table-responsive .table tbody input{border:1px solid rgba(34,0,255,.37);height:100%!important;font-size:smaller!important}.table-responsive .table tbody input[type=text],.table-responsive .table tbody input:not([type]){width:100%!important}.table-responsive .table tbody input[type=number]{min-width:80px!important;width:80px!important;text-align:center}.table-responsive .table thead th.boolean-column,.table-responsive .table tbody td.boolean-column,.table-responsive .table thead th.selection-column,.table-responsive .table tbody td.selection-column,.table-responsive .table thead th.table-actions-header,.table-responsive .table tbody td.table-actions-header{width:1%;white-space:nowrap}.table-responsive .table thead th.number-column,.table-responsive .table tbody td.number-column{width:1%;white-space:nowrap;text-align:center}.table-responsive .table thead th.number-column input[type=number],.table-responsive .table tbody td.number-column input[type=number]{min-width:80px!important;width:80px!important;text-align:center}.table-responsive .table .actions-cell{white-space:nowrap;padding:0!important}.table-responsive .table .actions-container{display:flex;flex-direction:row;justify-content:center;align-items:center;width:100%;height:100%}\n"] }]
|
|
410
|
-
}], propDecorators: { data$: [{
|
|
411
|
-
type: Input
|
|
412
|
-
}], columns: [{
|
|
413
|
-
type: Input
|
|
414
|
-
}], inputValues$: [{
|
|
415
|
-
type: Input
|
|
416
|
-
}], customActions: [{
|
|
417
|
-
type: Input
|
|
418
|
-
}], size: [{
|
|
419
|
-
type: Input
|
|
420
|
-
}], multiple: [{
|
|
421
|
-
type: Input
|
|
422
|
-
}], searchable: [{
|
|
423
|
-
type: Input,
|
|
424
|
-
args: [{ transform: booleanAttribute }]
|
|
425
|
-
}], allowSelection: [{
|
|
426
|
-
type: Input,
|
|
427
|
-
args: [{ transform: booleanAttribute }]
|
|
428
|
-
}], noConfirm: [{
|
|
429
|
-
type: Input,
|
|
430
|
-
args: [{ transform: booleanAttribute }]
|
|
431
|
-
}] } });
|
|
432
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy91aS9zcmMvbGliL3RhYmxlL3RhYmxlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL2xpYnMvdWkvc3JjL2xpYi90YWJsZS90YWJsZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sUUFBUSxFQUNSLE1BQU0sRUFHTixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzNDLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ25FLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzNFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRW5FLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxZQUFZLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDM0QsT0FBTyxFQUNMLGdCQUFnQixFQUNoQixlQUFlLEVBQ2YsYUFBYSxFQUNiLFNBQVMsRUFDVCxnQkFBZ0IsRUFDaEIsZ0JBQWdCLEdBQ2pCLE1BQU0sZUFBZSxDQUFDOztBQUV2Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwSEcsQ0FRSCxNQUFNLE9BQU8saUJBQWlCO0lBQzVCLHVCQUF1QjtJQUNOLFlBQVks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QUUsZ0JBQWdCLEVBQUU7Z0JBR3RDLGNBQWM7c0JBRGIsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRTtnQkFHdEMsU0FBUztzQkFEUixLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgc2lnbmFsLFxuICBjb21wdXRlZCxcbiAgb3V0cHV0LFxuICBPbkluaXQsXG4gIE9uRGVzdHJveSxcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQzgwSWNvbkNvbXBvbmVudCB9IGZyb20gJy4uL2ljb24nO1xuaW1wb3J0IHsgVGFibGVDb2x1bW5WaXNpYmlsaXR5U2VydmljZSB9IGZyb20gJy4vdGFibGUtY29sdW1uLXZpc2liaWxpdHkuc2VydmljZSc7XG5pbXBvcnQgeyBUYWJsZURhdGFVdGlsc1NlcnZpY2UgfSBmcm9tICcuL3RhYmxlLWRhdGEtdXRpbHMuc2VydmljZSc7XG5pbXBvcnQgeyBUYWJsZURhdGFDb252ZXJ0ZXJTZXJ2aWNlIH0gZnJvbSAnLi90YWJsZS1kYXRhLWNvbnZlcnRlci5zZXJ2aWNlJztcbmltcG9ydCB7IFRhYmxlU2VsZWN0aW9uU2VydmljZSB9IGZyb20gJy4vdGFibGUtc2VsZWN0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgVGFibGVDcnVkU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi90YWJsZS1jcnVkLXN0YXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgQzgwVGFibGVDb2xEZWYsIEN1c3RvbVRhYmxlQWN0aW9uIH0gZnJvbSAnLi90YWJsZS50eXBlcyc7XG5pbXBvcnQgeyBDODBNb2RhbENvbXBvbmVudCwgTW9kYWxTZXJ2aWNlIH0gZnJvbSAnLi4vbW9kYWwnO1xuaW1wb3J0IHtcbiAgYm9vbGVhbkF0dHJpYnV0ZSxcbiAgZ2V0RXJyb3JNZXNzYWdlLFxuICBnZXRJbnB1dFZhbHVlLFxuICB0cmFja0J5SWQsXG4gIHNob3VsZFNob3dBY3Rpb24sXG4gIGdldEFjdGlvblRvb2x0aXAsXG59IGZyb20gJy4vdGFibGUudXRpbHMnO1xuXG4vKipcbiAqIEM4MFRhYmxlQ29tcG9uZW50IC0gQ29tcG9uZW50ZSBkZSB0YWJsYSBhdmFuemFkbyBjb24gZnVuY2lvbmFsaWRhZGVzIENSVURcbiAqXG4gKiBDT01QT1JUQU1JRU5UTyBERSBWSVNJQklMSURBRCBERSBDT0xVTU5BUzpcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqXG4gKiAxLiBQUklPUklEQUQgTcOBWElNQSAtIHZpc2libGU6IGZhbHNlXG4gKiAgICAtIExhIGNvbHVtbmEgc2Ugb2N1bHRhIFNJRU1QUkUsIHNpbiBleGNlcGNpb25lc1xuICogICAgLSBOaSBlbiBtb2RvIGNyZWFjacOzbiBuaSBlbiBtb2RvIGVkaWNpw7NuIHNlIG11ZXN0cmFcbiAqXG4gKiAyLiBPQ1VMVEFDScOTTiBBVVRPTcOBVElDQSAtIGhpZGVJZkFsbFZhbHVlc0FyZU51bGw6IHRydWVcbiAqICAgIC0gTGEgY29sdW1uYSBzZSBvY3VsdGEgc29sbyBzaSBUT0RPUyBsb3MgdmFsb3JlcyBhY3R1YWxlcyBlc3TDoW4gdmFjw61vc1xuICogICAgLSBWYWxvcmVzIGNvbnNpZGVyYWRvcyB2YWPDrW9zOiBudWxsLCB1bmRlZmluZWQsICcnLCBbXSwge31cbiAqICAgIC0gVmFsb3JlcyBOTyB2YWPDrW9zOiAwLCBmYWxzZSAoc29uIHZhbG9yZXMgdsOhbGlkb3MpXG4gKiAgICAtIEVYQ0VQQ0lPTkVTIElNUE9SVEFOVEVTOlxuICogICAgICAqIEVuIG1vZG8gY3JlYWNpw7NuIChjcmVhdGluZz10cnVlKSBlc3RhcyBjb2x1bW5hcyBTw40gc2UgbXVlc3RyYW5cbiAqICAgICAgKiBFbiBtb2RvIGVkaWNpw7NuIGRlIHVuYSBmaWxhIGVzcGVjw61maWNhIHNlIG11ZXN0cmFuIFNPTE8gc2kgZXNhIGZpbGEgdGllbmUgdmFsb3JcbiAqXG4gKiAzLiBQT1IgREVGRUNUTyAtIENvbHVtbmFzIG5vcm1hbGVzXG4gKiAgICAtIFNlIG11ZXN0cmFuIHNpZW1wcmUgKHZpc3VhbGl6YWNpw7NuLCBjcmVhY2nDs24geSBlZGljacOzbilcbiAqXG4gKiBWQUxPUkVTIFBPUiBERUZFQ1RPIEVOIENSRUFDScOTTjpcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqXG4gKiAtIFByb3BpZWRhZCBgZGVmYXVsdD86IHVua25vd25gIHBlcm1pdGUgZGVmaW5pciB2YWxvcmVzIHBvciBkZWZlY3RvIHBhcmEgbW9kbyBjcmVhY2nDs25cbiAqIC0gU29sbyBzZSBhcGxpY2EgY3VhbmRvIHNlIGluaWNpYSBlbCBtb2RvIGNyZWFjacOzbiAoc3RhcnRDcmVhdGUpXG4gKiAtIFB1ZWRlIHNlciBjdWFscXVpZXIgdGlwbzogc3RyaW5nLCBudW1iZXIsIGJvb2xlYW4sIGV0Yy5cbiAqIC0gU2kgbm8gc2UgZXNwZWNpZmljYSBgZGVmYXVsdGAsIHNlIHVzYSBjYWRlbmEgdmFjw61hICgnJylcbiAqXG4gKiBWQUxPUkVTIERJTsOBTUlDT1MgRU4gQ1JFQUNJw5NOIFkgRURJQ0nDk046XG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqXG4gKiAtIElucHV0IGBpbnB1dFZhbHVlcyQ/OiBPYnNlcnZhYmxlPFBhcnRpYWw8VD4+YCBwZXJtaXRlIGFjdHVhbGl6YXIgdmFsb3JlcyBkaW7DoW1pY2FtZW50ZVxuICogLSBTb2xvIHNlIGFwbGljYSBkdXJhbnRlIG1vZG8gY3JlYWNpw7NuIChjcmVhdGluZz10cnVlKSBvIGVkaWNpw7NuIChlZGl0aW5nIT1udWxsKVxuICogLSBMb3MgdmFsb3JlcyBzZSBhcGxpY2FuIGF1dG9tw6F0aWNhbWVudGUgY3VhbmRvIGVsIE9ic2VydmFibGUgZW1pdGVcbiAqIC0gUGVybWl0ZSBjYW1iaW9zIG3Dumx0aXBsZXMgZHVyYW50ZSBlbCBtaXNtbyBtb2RvIGRlIGNyZWFjacOzbi9lZGljacOzblxuICogLSBMb3MgbnVldm9zIHZhbG9yZXMgc29icmVzY3JpYmVuIGxvcyBleGlzdGVudGVzIChzcHJlYWQgb3BlcmF0b3IpXG4gKlxuICogVElQT1MgREUgREFUT1MgU09QT1JUQURPUzpcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqXG4gKiAtICdzdHJpbmcnOiBUZXh0byBub3JtYWwgKGRlZmF1bHQpXG4gKiAtICdudW1iZXInOiBOw7ptZXJvcyBkZWNpbWFsZXMgKHByZXNlcnZhIGRlY2ltYWxlczogNS4zIOKGkiA1LjMpXG4gKiAtICdpbnRlZ2VyJzogTsO6bWVyb3MgZW50ZXJvcyAoY29udmllcnRlIGEgZW50ZXJvOiA1LjMg4oaSIDUpXG4gKiAtICdib29sZWFuJzogVmVyZGFkZXJvL0ZhbHNvIChjaGVja2JveClcbiAqIC0gJ3Bhc3N3b3JkJzogVGV4dG8gb2N1bHRvIChpbnB1dCB0eXBlPVwicGFzc3dvcmRcIilcbiAqIC0gJ2VudW0nOiBMaXN0YSBkZSBvcGNpb25lcyBwcmVkZWZpbmlkYXMgKHNlbGVjdClcbiAqXG4gKiBTSVNURU1BIERFIEFDQ0lPTkVTIFVOSUZJQ0FETyAoY3VzdG9tQWN0aW9ucyk6XG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqXG4gKiBJbnB1dDogYGN1c3RvbUFjdGlvbnM6IEN1c3RvbVRhYmxlQWN0aW9uW11gIC0gQXJyYXkgZGUgYWNjaW9uZXMgZGluw6FtaWNhc1xuICogT3V0cHV0OiBgKGFjdGlvbkNsaWNrKWAgLSBFdmVudG8gdW5pZmljYWRvIHF1ZSBlbWl0ZSB7IGFjdGlvbjogc3RyaW5nLCByb3c6IFQgfVxuICpcbiAqIEFDQ0lPTkVTIENSVUQgUFJFREVGSU5JREFTIChUQUJMRV9DUlVEX0FDVElPTlMpOlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiAtIENSRUFURTogU29sbyBhcGFyZWNlIGNvbW8gYm90w7NuIFwiK1wiIGVuIGhlYWRlciAobm8gZW4gZmlsYXMpXG4gKiAtIFVQREFURTogQWN0aXZhIG1vZG8gZWRpY2nDs24gKG11ZXN0cmEgaW5wdXRzKSwgYm90w7NuIFwi4pyTXCIgZ3VhcmRhIGNhbWJpb3NcbiAqIC0gREVMRVRFOiBNdWVzdHJhIGNvbmZpcm1hY2nDs24geSBlbWl0ZSBldmVudG8gZGVsZXRlXG4gKiAtIENBTkNFTDogTXVlc3RyYSBjb25maXJtYWNpw7NuIHkgZW1pdGUgZXZlbnRvIGNhbmNlbCAob3BjaW9uYWwpXG4gKlxuICogQUNDSU9ORVMgUEVSU09OQUxJWkFEQVMgKEN1c3RvbSBBY3Rpb25zKTpcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBJbnRlcmZhejogeyBuYW1lOiBzdHJpbmcsIGljb246IEljb25UeXBlLCBjb25kaXRpb24/OiAocm93KSA9PiBib29sZWFuLCB0b29sdGlwPzogc3RyaW5nIH1cbiAqIC0gbmFtZTogSUQgw7puaWNvIGRlIGxhIGFjY2nDs25cbiAqIC0gaWNvbjogSWNvbm8gZGVsIGJvdMOzbiAoZWo6ICdzZXR0aW5ncycsICd1cGxvYWQnLCAncmVmcmVzaCcpXG4gKiAtIGNvbmRpdGlvbjogRnVuY2nDs24gb3BjaW9uYWwgcGFyYSBtb3N0cmFyL29jdWx0YXIgc2Vnw7puIGVzdGFkbyBkZSBmaWxhXG4gKiAtIHRvb2x0aXA6IFRleHRvIGFsIGhhY2VyIGhvdmVyIChkZWZhdWx0OiBuYW1lKVxuICpcbiAqIE1BTkVKTyBFTiBDT01QT05FTlRFOlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIDEuIERlZmluaXIgYWNjaW9uZXMgZW4gY29uc3RhbnRzOlxuICogZXhwb3J0IGNvbnN0IEVOVElUWV9UQUJMRV9BQ1RJT05TOiBDdXN0b21UYWJsZUFjdGlvbltdID0gW1xuICogICBUQUJMRV9DUlVEX0FDVElPTlMuQ1JFQVRFLFxuICogICBUQUJMRV9DUlVEX0FDVElPTlMuVVBEQVRFLFxuICogICB7IG5hbWU6ICdjdXN0b20tYWN0aW9uJywgaWNvbjogJ3NldHRpbmdzJywgdG9vbHRpcDogJ0NvbmZpZ3VyYXInIH0sXG4gKiAgIFRBQkxFX0NSVURfQUNUSU9OUy5ERUxFVEVcbiAqIF07XG4gKlxuICogLy8gMi4gRW4gZWwgY29tcG9uZW50ZTpcbiAqIHJlYWRvbmx5IHRhYmxlQWN0aW9ucyA9IEVOVElUWV9UQUJMRV9BQ1RJT05TO1xuICpcbiAqIGhhbmRsZUFjdGlvbih7IGFjdGlvbiwgcm93IH0pIHtcbiAqICAgY29uc3QgZW50aXR5ID0gcm93IGFzIHVua25vd24gYXMgRW50aXR5VHlwZTtcbiAqICAgc3dpdGNoIChhY3Rpb24pIHtcbiAqICAgICBjYXNlICdjcmVhdGUnOiB0aGlzLm9uQ3JlYXRlKHJvdyk7IGJyZWFrO1xuICogICAgIGNhc2UgJ3VwZGF0ZSc6IHRoaXMub25VcGRhdGUoZW50aXR5KTsgYnJlYWs7XG4gKiAgICAgY2FzZSAnZGVsZXRlJzogdGhpcy5vbkRlbGV0ZShlbnRpdHkuaWQpOyBicmVhaztcbiAqICAgICBjYXNlICdjdXN0b20tYWN0aW9uJzogdGhpcy5vbkN1c3RvbShlbnRpdHkpOyBicmVhaztcbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogQUNDSU9ORVMgQ09OIENPTkRJQ0nDk046XG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiB7XG4gKiAgIG5hbWU6ICdlbmFibGUnLFxuICogICBpY29uOiAndG9nZ2xlT24nLFxuICogICB0b29sdGlwOiAnSGFiaWxpdGFyJyxcbiAqICAgY29uZGl0aW9uOiAocm93KSA9PiByb3dbJ2VuYWJsZWQnXSA9PT0gZmFsc2VcbiAqIH1cbiAqIGBgYFxuICpcbiAqIENPTlNUQU5URVMgUkVVVElMSVpBQkxFUzpcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogLSBUQUJMRV9DUlVEX0FDVElPTlM6IE9iamV0byBjb24gQ1JFQVRFLCBVUERBVEUsIERFTEVURSwgQ0FOQ0VMXG4gKiAtIEJBU0lDX0NSVURfQUNUSU9OUzogQXJyYXkgY29uIFtDUkVBVEUsIFVQREFURSwgREVMRVRFXVxuICogSW1wb3J0YXIgZGVzZGU6IGBAc2hhcmVkYCBvIGBAc2hhcmVkL2NvbnN0YW50c2BcbiAqXG4gKiBFSkVNUExPUyBDT01QTEVUT1M6XG4gKiAtLS0tLS0tLS0tLS0tLS0tLS1cbiAqIC0geyBhY2Nlc3NvcjogJ2lkJywgdmlzaWJsZTogZmFsc2UgfSDihpIgTlVOQ0Egc2UgbXVlc3RyYVxuICogLSB7IGFjY2Vzc29yOiAnbW90b3JQb3MnLCBoaWRlSWZBbGxWYWx1ZXNBcmVOdWxsOiB0cnVlLCBkZWZhdWx0OiAwLCB0eXBlOiAnaW50ZWdlcicgfSDihpIgRW50ZXJvICg1Ljcg4oaSIDUpXG4gKiAtIHsgYWNjZXNzb3I6ICd3ZWlnaHQnLCB0eXBlOiAnbnVtYmVyJywgZGVmYXVsdDogMi41IH0g4oaSIERlY2ltYWwgcHJlc2VydmFkbyAoNS43IOKGkiA1LjcpXG4gKiAtIHsgYWNjZXNzb3I6ICdzdGF0dXMnLCBkZWZhdWx0OiAnYWN0aXZlJyB9IOKGkiBTZSBhdXRvcmVsbGVuYSBjb24gJ2FjdGl2ZScgZW4gY3JlYWNpw7NuXG4gKiAtIHsgYWNjZXNzb3I6ICduYW1lJyB9IOKGkiBTaWVtcHJlIHZpc2libGUsIHNpbiB2YWxvciBwb3IgZGVmZWN0byAoY2FkZW5hIHZhY8OtYSlcbiAqIC0gaW5wdXRWYWx1ZXMkIGVtaXRlIHsgbW90b3JQb3M6IDUsIHdlaWdodDogMi4zIH0g4oaSIGFjdHVhbGl6YSBpbnB1dHMgZGluw6FtaWNhbWVudGVcbiAqIC0gY3VzdG9tQWN0aW9ucyBjb24gQ1JFQVRFIOKGkiBNdWVzdHJhIGJvdMOzbiBcIitcIiBlbiBoZWFkZXJcbiAqIC0gY3VzdG9tQWN0aW9ucyBjb24gVVBEQVRFIOKGkiBCb3TDs24gXCJlZGl0XCIgYWN0aXZhIG1vZG8gZWRpY2nDs25cbiAqIC0gY3VzdG9tQWN0aW9ucyBjb24gY3VzdG9tIOKGkiBCb3TDs24gcGVyc29uYWxpemFkbyBlbWl0ZSBldmVudG9cbiAqL0BDb21wb25lbnQoe1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2NvbXBvbmVudC1zZWxlY3RvclxuICBzZWxlY3RvcjogJ2M4MC10YWJsZScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDODBJY29uQ29tcG9uZW50LCBDODBNb2RhbENvbXBvbmVudF0sXG4gIHRlbXBsYXRlVXJsOiAnLi90YWJsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi90YWJsZS5jb21wb25lbnQuc2NzcycsXG59KVxuZXhwb3J0IGNsYXNzIEM4MFRhYmxlQ29tcG9uZW50PFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4gaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIC8vIFNlcnZpY2lvcyBpbnllY3RhZG9zXG4gIHByaXZhdGUgcmVhZG9ubHkgbW9kYWxTZXJ2aWNlID0gaW5qZWN0KE1vZGFsU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgdmlzaWJpbGl0eVNlcnZpY2UgPSBpbmplY3QoVGFibGVDb2x1bW5WaXNpYmlsaXR5U2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGF0YVV0aWxzID0gaW5qZWN0KFRhYmxlRGF0YVV0aWxzU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGF0YUNvbnZlcnRlciA9IGluamVjdChUYWJsZURhdGFDb252ZXJ0ZXJTZXJ2aWNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBzZWxlY3Rpb25TZXJ2aWNlID0gaW5qZWN0KFRhYmxlU2VsZWN0aW9uU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgY3J1ZFNlcnZpY2UgPSBpbmplY3QoVGFibGVDcnVkU3RhdGVTZXJ2aWNlKTtcblxuICAvLyBJbnB1dHNcbiAgQElucHV0KCkgZGF0YSQhOiBPYnNlcnZhYmxlPFRbXT47XG4gIEBJbnB1dCgpIGNvbHVtbnM6IEM4MFRhYmxlQ29sRGVmW10gPSBbXTtcbiAgQElucHV0KCkgaW5wdXRWYWx1ZXMkPzogT2JzZXJ2YWJsZTxQYXJ0aWFsPFQ+PjsgLy8gT2JzZXJ2YWJsZSBwYXJhIGFjdHVhbGl6YXIgdmFsb3JlcyBkZSBpbnB1dHMgZGluw6FtaWNhbWVudGUgZW4gY3JlYWNpw7NuL2VkaWNpw7NuXG4gIEBJbnB1dCgpIGN1c3RvbUFjdGlvbnM6IEN1c3RvbVRhYmxlQWN0aW9uW10gPSBbXTsgLy8gQWNjaW9uZXMgcGVyc29uYWxpemFkYXMgZGluw6FtaWNhc1xuICBASW5wdXQoKSBzaXplID0gMDsgLy8gVGFtYcOxbyBkZSBsYSB0YWJsYSAoMCA9IHNpbiBsw61taXRlLCA+IDAgYXBsaWNhIG1heC1oZWlnaHQpXG4gIEBJbnB1dCgpIG11bHRpcGxlID0gdHJ1ZTsgLy8gUGVybWl0ZSBzZWxlY2Npw7NuIG3Dumx0aXBsZSBwb3IgZGVmZWN0b1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSlcbiAgc2VhcmNoYWJsZSA9IGZhbHNlOyAvLyBTaSBlcyB0cnVlLCBtdWVzdHJhIGJhcnJhIGRlIGLDunNxdWVkYVxuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSlcbiAgYWxsb3dTZWxlY3Rpb24gPSBmYWxzZTsgLy8gU2kgZXMgdHJ1ZSwgcGVybWl0ZSBzZWxlY2Npw7NuIGRlIGZpbGFzXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KVxuICBub0NvbmZpcm0gPSBmYWxzZTsgLy8gU2kgZXMgdHJ1ZSwgbm8gbXVlc3RyYSBjb25maXJtYWNpb25lcyBtb2RhbGVzXG5cbiAgLy8gT3V0cHV0cyAtIEFjY2lvbmVzIHVuaWZpY2FkYXMgKEFuZ3VsYXIgMTgrIG91dHB1dCBBUEkpXG4gIHJlYWRvbmx5IGFjdGlvbkNsaWNrID0gb3V0cHV0PHsgYWN0aW9uOiBzdHJpbmc7IHJvdzogVCB9PigpOyAvLyBPdXRwdXQgdW5pZmljYWRvIHBhcmEgVE9EQVMgbGFzIGFjY2lvbmVzIChDUlVEICsgY3VzdG9tKVxuXG4gIC8vIE91dHB1dHMgLSBVdGlsaWRhZGVzXG4gIHJlYWRvbmx5IHNlYXJjaFRlcm0gPSBvdXRwdXQ8c3RyaW5nPigpO1xuICByZWFkb25seSBlcnJvckV2ZW50ID0gb3V0cHV0PHN0cmluZz4oKTtcbiAgcmVhZG9ubHkgc2VsZWN0YWJsZSA9IG91dHB1dDxUW10+KCk7XG5cbiAgLy8gRXN0YWRvIHByaW5jaXBhbFxuICByZWFkb25seSBkYXRhID0gc2lnbmFsPFRbXT4oW10pO1xuICByZWFkb25seSBzZWFyY2hWYWx1ZSA9IHNpZ25hbDxzdHJpbmc+KCcnKTtcblxuICAvLyBFc3RhZG8gZGUgc2VsZWNjacOzbiAoZGVsZWdhZG8gYSBzZXJ2aWNpbylcbiAgcHJpdmF0ZSByZWFkb25seSBzZWxlY3Rpb25TdGF0ZSA9IHRoaXMuc2VsZWN0aW9uU2VydmljZS5jcmVhdGVTZWxlY3Rpb25TdGF0ZTxUPigpO1xuICByZWFkb25seSBzZWxlY3RlZEl0ZW1zID0gdGhpcy5zZWxlY3Rpb25TdGF0ZS5zZWxlY3RlZEl0ZW1zO1xuICByZWFkb25seSBzZWxlY3RBbGxDaGVja2VkID0gdGhpcy5zZWxlY3Rpb25TdGF0ZS5zZWxlY3RBbGxDaGVja2VkO1xuICByZWFkb25seSBzZWxlY3RBbGxJbmRldGVybWluYXRlID0gdGhpcy5zZWxlY3Rpb25TdGF0ZS5zZWxlY3RBbGxJbmRldGVybWluYXRlO1xuXG4gIC8vIEVzdGFkbyBDUlVEIChkZWxlZ2FkbyBhIHNlcnZpY2lvKVxuICBwcml2YXRlIHJlYWRvbmx5IGNydWRTdGF0ZSA9IHRoaXMuY3J1ZFNlcnZpY2UuY3JlYXRlQ3J1ZFN0YXRlPFQ+KCk7XG4gIHJlYWRvbmx5IGNyZWF0aW5nID0gdGhpcy5jcnVkU3RhdGUuY3JlYXRpbmc7XG4gIHJlYWRvbmx5IG5ld1JvdyA9IHRoaXMuY3J1ZFN0YXRlLm5ld1JvdztcbiAgcmVhZG9ubHkgZWRpdGluZyA9IHRoaXMuY3J1ZFN0YXRlLmVkaXRpbmc7XG4gIHJlYWRvbmx5IGVkaXRSb3cgPSB0aGlzLmNydWRTdGF0ZS5lZGl0Um93O1xuXG4gIC8vIEtleXMgdmlzaWJsZXMgY29tcHV0ZWQgYXV0b23DoXRpY2FtZW50ZVxuICByZWFkb25seSBrZXlzID0gY29tcHV0ZWQoKCkgPT5cbiAgICB0aGlzLnZpc2liaWxpdHlTZXJ2aWNlLnVwZGF0ZVZpc2libGVLZXlzKFxuICAgICAgdGhpcy5jb2x1bW5zLFxuICAgICAgdGhpcy5kYXRhKCksXG4gICAgICB0aGlzLmNyZWF0aW5nKCksXG4gICAgICB0aGlzLmVkaXRpbmcoKVxuICAgIClcbiAgKTtcblxuICAvLyBDb21wdXRlZCAtIERldGVjdGEgYWNjaW9uZXMgQ1JVRCB5IGN1c3RvbVxuICByZWFkb25seSBoYXNBbnlBY3Rpb25zID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jdXN0b21BY3Rpb25zLmxlbmd0aCA+IDApO1xuICByZWFkb25seSBoYXNDcnVkQ3JlYXRlID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jdXN0b21BY3Rpb25zLnNvbWUoYSA9PiBhLm5hbWUgPT09ICdjcmVhdGUnKSk7XG4gIHJlYWRvbmx5IGhhc0NydWRVcGRhdGUgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmN1c3RvbUFjdGlvbnMuc29tZShhID0+IGEubmFtZSA9PT0gJ3VwZGF0ZScpKTtcbiAgcmVhZG9ubHkgaGFzQ3J1ZERlbGV0ZSA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY3VzdG9tQWN0aW9ucy5zb21lKGEgPT4gYS5uYW1lID09PSAnZGVsZXRlJykpO1xuICByZWFkb25seSBoYXNDcnVkQ2FuY2VsID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jdXN0b21BY3Rpb25zLnNvbWUoYSA9PiBhLm5hbWUgPT09ICdjYW5jZWwnKSk7XG5cbiAgLy8gVGFibGUgbWF4IGhlaWdodCBjb21wdXRlZFxuICByZWFkb25seSB0YWJsZU1heEhlaWdodCA9IGNvbXB1dGVkKCgpID0+XG4gICAgdGhpcy5kYXRhVXRpbHMuZ2V0VGFibGVNYXhIZWlnaHQodGhpcy5zaXplKVxuICApO1xuXG4gIHByaXZhdGUgZGF0YVN1Yj86IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSBpbnB1dFZhbHVlc1N1Yj86IFN1YnNjcmlwdGlvbjtcblxuICAvKipcbiAgICogTWFuZWphIGlucHV0IGRlIGNyZWFjacOzbi9lZGljacOzbiBkZSBmb3JtYSB1bmlmaWNhZGFcbiAgICovXG4gIHByaXZhdGUgaGFuZGxlSW5wdXQoXG4gICAgZXZlbnQ6IEV2ZW50LFxuICAgIGtleTogc3RyaW5nLFxuICAgIGNvbDogQzgwVGFibGVDb2xEZWYgfCB1bmRlZmluZWQsXG4gICAgaXNFZGl0OiBib29sZWFuXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHVwZGF0ZUZuID0gaXNFZGl0XG4gICAgICA/IHRoaXMuY3J1ZFN0YXRlLnVwZGF0ZUVkaXRSb3cuYmluZCh0aGlzLmNydWRTdGF0ZSlcbiAgICAgIDogdGhpcy5jcnVkU3RhdGUudXBkYXRlTmV3Um93LmJpbmQodGhpcy5jcnVkU3RhdGUpO1xuXG4gICAgY29uc3QgdmFsdWUgPSBnZXRJbnB1dFZhbHVlKGV2ZW50LCBjb2wpO1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB1cGRhdGVGbihrZXksIHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWFuZWphIGNvbmZpcm1hY2nDs24gbW9kYWwgZGUgZm9ybWEgZ2Vuw6lyaWNhXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGhhbmRsZUNvbmZpcm1BY3Rpb24oXG4gICAgdGl0bGU6IHN0cmluZyxcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICAgY29uZmlybVRleHQ6IHN0cmluZyxcbiAgICBhY3Rpb246ICgpID0+IHZvaWRcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMubm9Db25maXJtKSB7XG4gICAgICBhY3Rpb24oKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjb25maXJtZWQgPSBhd2FpdCB0aGlzLm1vZGFsU2VydmljZS5jb25maXJtKFxuICAgICAgdGl0bGUsXG4gICAgICBtZXNzYWdlLFxuICAgICAgY29uZmlybVRleHQsXG4gICAgICAnQ2FuY2VsYXInXG4gICAgKTtcblxuICAgIGlmIChjb25maXJtZWQpIHtcbiAgICAgIGFjdGlvbigpO1xuICAgIH1cbiAgfVxuXG5cblxuICBuZ09uSW5pdCgpIHtcbiAgICBpZiAoIXRoaXMuZGF0YSQpIHJldHVybjtcbiAgICB0aGlzLmRhdGFTdWIgPSB0aGlzLmRhdGEkLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAoaXRlbXMpID0+IHtcbiAgICAgICAgdGhpcy5kYXRhVXRpbHMuYXBwbHlTb3J0aW5nKGl0ZW1zLCB0aGlzLmNvbHVtbnMpO1xuICAgICAgICB0aGlzLmRhdGEuc2V0KGl0ZW1zKTtcbiAgICAgICAgdGhpcy5wcmVzZXJ2ZVNlbGVjdGlvbigpO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyOiB1bmtub3duKSA9PlxuICAgICAgICB0aGlzLmVycm9yRXZlbnQuZW1pdChnZXRFcnJvck1lc3NhZ2UoZXJyKSksXG4gICAgfSk7XG5cbiAgICAvLyBTdXNjcmliaXJzZSBhIGlucHV0VmFsdWVzJCBwYXJhIGFjdHVhbGl6YXIgdmFsb3JlcyBkaW7DoW1pY2FtZW50ZSBlbiBjcmVhY2nDs24vZWRpY2nDs25cbiAgICBpZiAodGhpcy5pbnB1dFZhbHVlcyQpIHtcbiAgICAgIHRoaXMuaW5wdXRWYWx1ZXNTdWIgPSB0aGlzLmlucHV0VmFsdWVzJC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocGFydGlhbFZhbHVlcykgPT4ge1xuICAgICAgICAgIHRoaXMuY3J1ZFN0YXRlLmFwcGx5SW5wdXRWYWx1ZXMocGFydGlhbFZhbHVlcyk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoZXJyOiB1bmtub3duKSA9PlxuICAgICAgICAgIGNvbnNvbGUud2FybignRXJyb3IgZW4gaW5wdXRWYWx1ZXMkOicsIGdldEVycm9yTWVzc2FnZShlcnIpKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuZGF0YVN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmlucHV0VmFsdWVzU3ViPy51bnN1YnNjcmliZSgpO1xuXG4gICAgLy8gQ2xvc2UgYW55IG9wZW4gbW9kYWwgd2hlbiBjb21wb25lbnQgaXMgZGVzdHJveWVkXG4gICAgdGhpcy5tb2RhbFNlcnZpY2UuY2xvc2VNb2RhbCgpO1xuICB9XG5cbiAgb25JbnB1dChldmVudDogRXZlbnQsIGtleTogc3RyaW5nLCBjb2w/OiBDODBUYWJsZUNvbERlZik6IHZvaWQge1xuICAgIHRoaXMuaGFuZGxlSW5wdXQoZXZlbnQsIGtleSwgY29sLCBmYWxzZSk7XG4gIH1cblxuICBvbkVkaXRJbnB1dChldmVudDogRXZlbnQsIGtleTogc3RyaW5nLCBjb2w/OiBDODBUYWJsZUNvbERlZik6IHZvaWQge1xuICAgIHRoaXMuaGFuZGxlSW5wdXQoZXZlbnQsIGtleSwgY29sLCB0cnVlKTtcbiAgfVxuXG4gIGFzeW5jIG9uRGVsZXRlKHJvdzogVCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuaGFuZGxlQ29uZmlybUFjdGlvbihcbiAgICAgICdDb25maXJtYXIgZWxpbWluYWNpw7NuJyxcbiAgICAgICfCv0VzdMOhIHNlZ3VybyBkZSBxdWUgZGVzZWEgZWxpbWluYXIgZXN0ZSBlbGVtZW50bz8gRXN0YSBhY2Npw7NuIG5vIHNlIHB1ZWRlIGRlc2hhY2VyLicsXG4gICAgICAnRWxpbWluYXInLFxuICAgICAgKCkgPT4gdGhpcy5hY3Rpb25DbGljay5lbWl0KHsgYWN0aW9uOiAnZGVsZXRlJywgcm93IH0pXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIG9uQ2FuY2VsKHJvdzogVCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuaGFuZGxlQ29uZmlybUFjdGlvbihcbiAgICAgICdDb25maXJtYXIgY2FuY2VsYWNpw7NuJyxcbiAgICAgICfCv0VzdMOhIHNlZ3VybyBkZSBxdWUgZGVzZWEgY2FuY2VsYXIgZXN0ZSBlbGVtZW50bz8nLFxuICAgICAgJ0NhbmNlbGFyIGVsZW1lbnRvJyxcbiAgICAgICgpID0+IHRoaXMuYWN0aW9uQ2xpY2suZW1pdCh7IGFjdGlvbjogJ2NhbmNlbCcsIHJvdyB9KVxuICAgICk7XG4gIH1cblxuICBzdGFydENyZWF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNydWRTdGF0ZS5zdGFydENyZWF0ZSh0aGlzLmNvbHVtbnMsIHRoaXMuZGF0YSgpKTtcbiAgfVxuXG4gIGNhbmNlbENyZWF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNydWRTdGF0ZS5jYW5jZWxDcmVhdGUoKTtcbiAgfVxuXG4gIHNhdmVDcmVhdGUoKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMubmV3Um93KCk7XG4gICAgaWYgKGN1cnJlbnQpIHtcbiAgICAgIGNvbnN0IGNvbnZlcnRlZFJvdyA9IHRoaXMuY29udmVydFJvd1R5cGVzKGN1cnJlbnQpO1xuICAgICAgdGhpcy5hY3Rpb25DbGljay5lbWl0KHsgYWN0aW9uOiAnY3JlYXRlJywgcm93OiBjb252ZXJ0ZWRSb3cgYXMgVCB9KTtcbiAgICAgIHRoaXMuY2FuY2VsQ3JlYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgb25FZGl0KHJvdzogVCk6IHZvaWQge1xuICAgIHRoaXMuY3J1ZFN0YXRlLnN0YXJ0RWRpdChyb3csIHRoaXMuY29sdW1ucywgdGhpcy5kYXRhKCkpO1xuICB9XG5cbiAgY2FuY2VsRWRpdCgpOiB2b2lkIHtcbiAgICB0aGlzLmNydWRTdGF0ZS5jYW5jZWxFZGl0KCk7XG4gIH1cblxuICBzYXZlRWRpdChyb3c6IFQpOiB2b2lkIHtcbiAgICBjb25zdCBjaGFuZ2VzID0gdGhpcy5lZGl0Um93KCk7XG4gICAgaWYgKGNoYW5nZXMpIHtcbiAgICAgIGNvbnN0IGNvbnZlcnRlZENoYW5nZXMgPSB0aGlzLmNvbnZlcnRSb3dUeXBlcyhjaGFuZ2VzKTtcbiAgICAgIGNvbnN0IHVwZGF0ZWRSb3cgPSB7IC4uLnJvdywgLi4uY29udmVydGVkQ2hhbmdlcyB9IGFzIFQ7XG4gICAgICB0aGlzLmFjdGlvbkNsaWNrLmVtaXQoeyBhY3Rpb246ICd1cGRhdGUnLCByb3c6IHVwZGF0ZWRSb3cgfSk7XG4gICAgICB0aGlzLmNhbmNlbEVkaXQoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29udmllcnRlIHRvZG9zIGxvcyB2YWxvcmVzIGRlIHVuYSBmaWxhIHNlZ8O6biBsb3MgdGlwb3MgZGVmaW5pZG9zIGVuIGxhcyBjb2x1bW5hc1xuICAgKiBBc2VndXJhIHF1ZSBsb3MgZGF0b3MgZW1pdGlkb3MgdGVuZ2FuIGVsIHRpcG8gY29ycmVjdG8gKGludGVnZXIsIG51bWJlciwgYm9vbGVhbiwgZXRjLilcbiAgICovXG4gIHByaXZhdGUgY29udmVydFJvd1R5cGVzKHJvdzogUGFydGlhbDxUPik6IFBhcnRpYWw8VD4ge1xuICAgIGNvbnN0IGNvbnZlcnRlZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgICBjb25zdCBjb2x1bW5zTWFwID0gbmV3IE1hcCh0aGlzLmNvbHVtbnMubWFwKGNvbCA9PiBbY29sLmFjY2Vzc29yLCBjb2xdKSk7XG5cbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhyb3cpKSB7XG4gICAgICBjb25zdCBjb2wgPSBjb2x1bW5zTWFwLmdldChrZXkpO1xuICAgICAgaWYgKGNvbCkge1xuICAgICAgICBjb252ZXJ0ZWRba2V5XSA9IHRoaXMuZGF0YUNvbnZlcnRlci5jb252ZXJ0Q2VsbFZhbHVlKHZhbHVlLCBjb2wpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udmVydGVkW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY29udmVydGVkIGFzIFBhcnRpYWw8VD47XG4gIH1cblxuICAvKipcbiAgICogVHJhY2tCeSBmdW5jdGlvbiBmb3IgbmdGb3IgdG8gYXZvaWQgRE9NIHJlLWNyZWF0aW9uIChORzA5NTYgd2FybmluZykuXG4gICAqL1xuICByZWFkb25seSB0cmFja0J5SWQgPSB0cmFja0J5SWQ8VD47XG5cbiAgLyoqXG4gICAqIFZlcmlmaWNhIHNpIHVuYSBhY2Npw7NuIHBlcnNvbmFsaXphZGEgZGViZSBtb3N0cmFyc2UgcGFyYSB1bmEgZmlsYSBlc3BlY8OtZmljYVxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkU2hvd0FjdGlvbiA9IHNob3VsZFNob3dBY3Rpb248VD47XG5cbiAgLyoqXG4gICAqIE9idGllbmUgZWwgdG9vbHRpcCBkZSB1bmEgYWNjacOzblxuICAgKi9cbiAgcmVhZG9ubHkgZ2V0QWN0aW9uVG9vbHRpcCA9IGdldEFjdGlvblRvb2x0aXA7XG5cbiAgLyoqXG4gICAqIE1hbmVqYSBlbCBjbGljayBlbiB1bmEgYWNjacOzbiBwZXJzb25hbGl6YWRhIGRpbsOhbWljYVxuICAgKiBVUERBVEUgYWN0aXZhIGVsIG1vZG8gZWRpY2nDs24sIG90cmFzIGFjY2lvbmVzIGVtaXRlbiBkaXJlY3RhbWVudGVcbiAgICogU2kgbGEgYWNjacOzbiB0aWVuZSBjb25maWd1cmFjacOzbiBkZSBjb25maXJtYWNpw7NuLCBtdWVzdHJhIG1vZGFsIGFudGVzIGRlIGVqZWN1dGFyXG4gICAqL1xuICBvbkR5bmFtaWNBY3Rpb24oYWN0aW9uOiBDdXN0b21UYWJsZUFjdGlvbiwgcm93OiBUKTogdm9pZCB7XG4gICAgaWYgKGFjdGlvbi5uYW1lID09PSAndXBkYXRlJykge1xuICAgICAgdGhpcy5vbkVkaXQocm93KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoYWN0aW9uLm5hbWUgPT09ICdkZWxldGUnKSB7XG4gICAgICB2b2lkIHRoaXMub25EZWxldGUocm93KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoYWN0aW9uLm5hbWUgPT09ICdjYW5jZWwnKSB7XG4gICAgICB2b2lkIHRoaXMub25DYW5jZWwocm93KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTaSBsYSBhY2Npw7NuIHRpZW5lIGNvbmZpcm1hY2nDs24gY29uZmlndXJhZGEsIG1vc3RyYXIgbW9kYWxcbiAgICBpZiAoYWN0aW9uLmNvbmZpcm1hdGlvbikge1xuICAgICAgdm9pZCB0aGlzLmhhbmRsZUFjdGlvbldpdGhDb25maXJtYXRpb24oYWN0aW9uLCByb3cpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNpbiBjb25maXJtYWNpw7NuLCBlbWl0aXIgZGlyZWN0YW1lbnRlXG4gICAgdGhpcy5hY3Rpb25DbGljay5lbWl0KHsgYWN0aW9uOiBhY3Rpb24ubmFtZSwgcm93IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1hbmVqYSBhY2Npb25lcyBxdWUgcmVxdWllcmVuIGNvbmZpcm1hY2nDs24gZGVsIHVzdWFyaW9cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlQWN0aW9uV2l0aENvbmZpcm1hdGlvbihhY3Rpb246IEN1c3RvbVRhYmxlQWN0aW9uLCByb3c6IFQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIWFjdGlvbi5jb25maXJtYXRpb24pIHJldHVybjtcblxuICAgIGNvbnN0IGNvbmZpcm1lZCA9IGF3YWl0IHRoaXMubW9kYWxTZXJ2aWNlLmNvbmZpcm0oXG4gICAgICBhY3Rpb24uY29uZmlybWF0aW9uLnRpdGxlLFxuICAgICAgYWN0aW9uLmNvbmZpcm1hdGlvbi5tZXNzYWdlLFxuICAgICAgYWN0aW9uLmNvbmZpcm1hdGlvbi5jb25maXJtVGV4dCB8fCAnQ29uZmlybWFyJyxcbiAgICAgIGFjdGlvbi5jb25maXJtYXRpb24uY2FuY2VsVGV4dCB8fCAnQ2FuY2VsYXInXG4gICAgKTtcblxuICAgIGlmIChjb25maXJtZWQpIHtcbiAgICAgIHRoaXMuYWN0aW9uQ2xpY2suZW1pdCh7IGFjdGlvbjogYWN0aW9uLm5hbWUsIHJvdyB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyBzZWFyY2ggaW5wdXQgY2hhbmdlcyB3aXRoIGRlYm91bmNpbmdcbiAgICovXG4gIG9uU2VhcmNoSW5wdXQoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgY29uc3QgdmFsdWUgPSB0YXJnZXQudmFsdWU7XG4gICAgdGhpcy5zZWFyY2hWYWx1ZS5zZXQodmFsdWUpO1xuICAgIHRoaXMuc2VhcmNoVGVybS5lbWl0KHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgdGhlIHNlYXJjaCBpbnB1dFxuICAgKi9cbiAgY2xlYXJTZWFyY2goKTogdm9pZCB7XG4gICAgdGhpcy5zZWFyY2hWYWx1ZS5zZXQoJycpO1xuICAgIHRoaXMuc2VhcmNoVGVybS5lbWl0KCcnKTtcbiAgfVxuXG4gIC8vIFJlZmVyZW5jaWFzIHJlYWRvbmx5IGEgbcOpdG9kb3MgZGUgc2VydmljaW9zIChldml0YSB3cmFwcGVycyBpbm5lY2VzYXJpb3MpXG4gIHJlYWRvbmx5IGdldENlbGxWYWx1ZSA9IHRoaXMuZGF0YVV0aWxzLmdldENlbGxWYWx1ZS5iaW5kKHRoaXMuZGF0YVV0aWxzKTtcbiAgcmVhZG9ubHkgZ2V0RGlzcGxheVZhbHVlID0gdGhpcy5kYXRhVXRpbHMuZ2V0RGlzcGxheVZhbHVlLmJpbmQodGhpcy5kYXRhVXRpbHMpO1xuICByZWFkb25seSBnZXRFbnVtRGlzcGxheVZhbHVlID0gdGhpcy5kYXRhVXRpbHMuZ2V0RW51bURpc3BsYXlWYWx1ZS5iaW5kKHRoaXMuZGF0YVV0aWxzKTtcbiAgcmVhZG9ubHkgZ2V0RW51bU9wdGlvbnMgPSB0aGlzLmRhdGFVdGlscy5nZXRFbnVtT3B0aW9ucy5iaW5kKHRoaXMuZGF0YVV0aWxzKTtcbiAgcmVhZG9ubHkgZ2V0Q2VsbENvbG9yID0gdGhpcy5kYXRhVXRpbHMuZ2V0Q2VsbENvbG9yLmJpbmQodGhpcy5kYXRhVXRpbHMpO1xuXG4gIC8qKlxuICAgKiBTZWxlY3Rpb24gbWV0aG9kc1xuICAgKi9cbiAgY2xlYXJTZWxlY3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3Rpb25TdGF0ZS5jbGVhclNlbGVjdGlvbigpO1xuICAgIHRoaXMuc2VsZWN0aW9uU2VydmljZS5lbWl0U2VsZWN0aW9uKHRoaXMuc2VsZWN0aW9uU3RhdGUgYXMgbmV2ZXIsIHRoaXMuZGF0YSgpLCB0aGlzLnNlbGVjdGFibGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1hbnRpZW5lIGxhIHNlbGVjY2nDs24gZXhpc3RlbnRlIGRlc3B1w6lzIGRlIGFjdHVhbGl6YXIgbG9zIGRhdG9zLFxuICAgKiBlbGltaW5hbmRvIHNvbG8gbG9zIElEcyBxdWUgeWEgbm8gZXhpc3RlbiBlbiBsb3MgbnVldm9zIGRhdG9zXG4gICAqL1xuICBwcml2YXRlIHByZXNlcnZlU2VsZWN0aW9uKCk6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0aW9uU3RhdGUucHJlc2VydmVTZWxlY3Rpb24odGhpcy5kYXRhKCkpO1xuICAgIHRoaXMuc2VsZWN0aW9uU2VydmljZS5lbWl0U2VsZWN0aW9uKHRoaXMuc2VsZWN0aW9uU3RhdGUgYXMgbmV2ZXIsIHRoaXMuZGF0YSgpLCB0aGlzLnNlbGVjdGFibGUpO1xuICB9XG5cbiAgdG9nZ2xlU2VsZWN0QWxsKCk6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0aW9uU3RhdGUudG9nZ2xlU2VsZWN0QWxsKHRoaXMuZGF0YSgpKTtcbiAgICB0aGlzLnNlbGVjdGlvblNlcnZpY2UuZW1pdFNlbGVjdGlvbih0aGlzLnNlbGVjdGlvblN0YXRlIGFzIG5ldmVyLCB0aGlzLmRhdGEoKSwgdGhpcy5zZWxlY3RhYmxlKTtcbiAgfVxuXG4gIHRvZ2dsZUl0ZW1TZWxlY3Rpb24oaXRlbTogVCk6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0aW9uU3RhdGUudG9nZ2xlSXRlbVNlbGVjdGlvbihpdGVtLCB0aGlzLm11bHRpcGxlKTtcbiAgICB0aGlzLnNlbGVjdGlvblNlcnZpY2UuZW1pdFNlbGVjdGlvbih0aGlzLnNlbGVjdGlvblN0YXRlIGFzIG5ldmVyLCB0aGlzLmRhdGEoKSwgdGhpcy5zZWxlY3RhYmxlKTtcbiAgfVxuXG4gIGlzSXRlbVNlbGVjdGVkKGl0ZW06IFQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rpb25TdGF0ZS5pc0l0ZW1TZWxlY3RlZChpdGVtKTtcbiAgfVxuXG5cblxuICAvLyBNw6l0b2RvcyBkZSB2aXNpYmlsaWRhZCBkZWxlZ2Fkb3MgYSBzZXJ2aWNpb1xuICBpc0NvbHVtblZpc2libGUoY29sdW1uOiBDODBUYWJsZUNvbERlZik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZpc2liaWxpdHlTZXJ2aWNlLmlzQ29sdW1uVmlzaWJsZShjb2x1bW4sIHRoaXMuZGF0YSgpLCB7XG4gICAgICBjcmVhdGluZzogdGhpcy5jcmVhdGluZygpLFxuICAgICAgcm93OiB0aGlzLm5ld1JvdygpID8/IHVuZGVmaW5lZFxuICAgIH0pO1xuICB9XG5cbiAgaXNDb2x1bW5WaXNpYmxlSW5IZWFkZXIoY29sdW1uOiBDODBUYWJsZUNvbERlZik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZpc2liaWxpdHlTZXJ2aWNlLmlzQ29sdW1uVmlzaWJsZUluSGVhZGVyKFxuICAgICAgY29sdW1uLFxuICAgICAgdGhpcy5kYXRhKCksXG4gICAgICB0aGlzLmNyZWF0aW5nKCksXG4gICAgICB0aGlzLmVkaXRpbmcoKVxuICAgICk7XG4gIH1cblxuICBpc0NvbHVtblZpc2libGVGb3JSb3coY29sdW1uOiBDODBUYWJsZUNvbERlZiwgcm93OiBUKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudmlzaWJpbGl0eVNlcnZpY2UuaXNDb2x1bW5WaXNpYmxlRm9yUm93KFxuICAgICAgY29sdW1uLFxuICAgICAgcm93LFxuICAgICAgdGhpcy5kYXRhKCksXG4gICAgICB0aGlzLmVkaXRpbmcoKVxuICAgICk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJ0YWJsZS1yZXNwb25zaXZlXCIgW3N0eWxlLm1heC1oZWlnaHRdPVwidGFibGVNYXhIZWlnaHQoKVwiIFtzdHlsZS5vdmVyZmxvdy15XT1cInNpemUgPiAwID8gJ2F1dG8nIDogJ3Zpc2libGUnXCI+XG4gIDwhLS0gU2VhcmNoIEJhciAtLT5cbiAgQGlmIChzZWFyY2hhYmxlKSB7XG4gIDxkaXYgY2xhc3M9XCJzZWFyY2gtY29udGFpbmVyXCI+XG4gICAgPGRpdiBjbGFzcz1cInNlYXJjaC1pbnB1dC13cmFwcGVyXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJpbnB1dC1ncm91cC10ZXh0XCI+XG4gICAgICAgICAgPGM4MC1pY29uIGljb249XCJzZWFyY2hcIiBbc2l6ZV09XCIuOFwiPjwvYzgwLWljb24+XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgc2VhcmNoLWlucHV0XCIgcGxhY2Vob2xkZXI9XCJCdXNjYXIuLi5cIiBbdmFsdWVdPVwic2VhcmNoVmFsdWUoKVwiIChpbnB1dCk9XCJvblNlYXJjaElucHV0KCRldmVudClcIiBhcmlhLWxhYmVsPVwiQnVzY2FyIGVuIGxhIHRhYmxhXCIgLz5cbiAgICAgICAgQGlmIChzZWFyY2hWYWx1ZSgpKSB7XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtc2Vjb25kYXJ5IGJ0bi1ib3JyYXJcIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImNsZWFyU2VhcmNoKClcIiB0aXRsZT1cIkxpbXBpYXIgYsO6c3F1ZWRhXCI+XG4gICAgICAgICAgPGM4MC1pY29uIGljb249XCJjYW5jZWxcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIH1cblxuICA8dGFibGUgY2xhc3M9XCJ0YWJsZSB0YWJsZS1ib3JkZXJlZCB0YWJsZS1ob3ZlciBhbGlnbi1taWRkbGVcIj5cbiAgICA8dGhlYWQgY2xhc3M9XCJ0aGVhZCB0YWJsZS1saWdodCBzdGlja3ktaGVhZGVyXCI+XG4gICAgICA8dHI+XG4gICAgICAgIEBpZiAoYWxsb3dTZWxlY3Rpb24gJiYgZGF0YSgpLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlciBzZWxlY3Rpb24tY29sdW1uXCI+XG4gICAgICAgICAgQGlmIChtdWx0aXBsZSkge1xuICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbY2hlY2tlZF09XCJzZWxlY3RBbGxDaGVja2VkKClcIiBbaW5kZXRlcm1pbmF0ZV09XCJzZWxlY3RBbGxJbmRldGVybWluYXRlKClcIiAoY2hhbmdlKT1cInRvZ2dsZVNlbGVjdEFsbCgpXCIgYXJpYS1sYWJlbD1cIlNlbGVjY2lvbmFyIHRvZG9cIiAvPlxuICAgICAgICAgIH1cbiAgICAgICAgPC90aD5cbiAgICAgICAgfVxuICAgICAgICBAZm9yIChjb2wgb2YgY29sdW1uczsgdHJhY2sgY29sKSB7XG4gICAgICAgIEBpZiAoaXNDb2x1bW5WaXNpYmxlSW5IZWFkZXIoY29sKSkge1xuICAgICAgICBAaWYgKGNvbC50eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgPHRoIGNsYXNzPVwidGV4dC1jZW50ZXIgYm9vbGVhbi1jb2x1bW5cIj57eyBjb2wubGFiZWwgfX08L3RoPlxuICAgICAgICB9XG4gICAgICAgIEBlbHNlIGlmIChjb2wudHlwZSA9PT0gJ251bWJlcicgfHwgY29sLnR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlciBudW1iZXItY29sdW1uXCI+e3sgY29sLmxhYmVsIH19PC90aD5cbiAgICAgICAgfVxuICAgICAgICBAZWxzZSB7XG4gICAgICAgIDx0aD57eyBjb2wubGFiZWwgfX08L3RoPlxuICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGhhc0FueUFjdGlvbnMoKSkge1xuICAgICAgICA8dGggY2xhc3M9XCJ0YWJsZS1hY3Rpb25zLWhlYWRlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb25zLXdyYXBwZXJcIj5cbiAgICAgICAgICAgIDxzcGFuPkFjdGlvbnM8L3NwYW4+XG4gICAgICAgICAgICBAaWYgKGhhc0NydWRDcmVhdGUoKSkge1xuICAgICAgICAgICAgPGM4MC1pY29uIGJ1dHRvbiBpY29uPVwiYWRkXCIgW2Rpc2FibGVkXT1cImNyZWF0aW5nKClcIiB0aXRsZT1cIkFncmVnYXJcIiBbc2l6ZV09XCIuNlwiIChpY29uQ2xpY2spPVwic3RhcnRDcmVhdGUoKVwiPjwvYzgwLWljb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvdGg+XG4gICAgICAgIH1cbiAgICAgIDwvdHI+XG4gICAgPC90aGVhZD5cbiAgICA8dGJvZHk+XG4gICAgICBAZm9yIChyb3cgb2YgZGF0YSgpOyB0cmFjayB0cmFja0J5SWQoaSwgcm93KTsgbGV0IGkgPSAkaW5kZXgpIHtcbiAgICAgIDx0cj5cbiAgICAgICAgQGlmIChhbGxvd1NlbGVjdGlvbiAmJiBkYXRhKCkubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyIHNlbGVjdGlvbi1jb2x1bW5cIj5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgW2NoZWNrZWRdPVwiaXNJdGVtU2VsZWN0ZWQocm93KVwiIChjaGFuZ2UpPVwidG9nZ2xlSXRlbVNlbGVjdGlvbihyb3cpXCIgW2F0dHIuYXJpYS1sYWJlbF09XCInU2VsZWNjaW9uYXIgZmlsYSAnICsgKGkgKyAxKVwiIC8+XG4gICAgICAgIDwvdGQ+XG4gICAgICAgIH1cbiAgICAgICAgQGZvciAoY29sIG9mIGNvbHVtbnM7IHRyYWNrIGNvbCkge1xuICAgICAgICBAaWYgKGlzQ29sdW1uVmlzaWJsZUZvclJvdyhjb2wsIHJvdykpIHtcbiAgICAgICAgQGlmIChjb2wudHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyIGJvb2xlYW4tY29sdW1uXCI+XG4gICAgICAgICAgQGlmIChlZGl0aW5nKCkgPT09IHJvd1snaWQnXSAmJiAhY29sLnJlYWRPbmx5KSB7XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cIiEhZWRpdFJvdygpPy5bY29sLmFjY2Vzc29yXVwiIChjaGFuZ2UpPVwib25FZGl0SW5wdXQoJGV2ZW50LCBjb2wuYWNjZXNzb3IsIGNvbClcIiBbYXR0ci5hcmlhLWxhYmVsXT1cImNvbC5sYWJlbFwiIC8+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBlbHNlIHtcbiAgICAgICAgICBAaWYgKGdldENlbGxWYWx1ZShyb3csIGNvbC5hY2Nlc3NvcikgPT09IHRydWUpIHtcbiAgICAgICAgICA8YzgwLWljb24gaWNvbj1cImNoZWNrXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgIDxiciAvPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSBpZiAoZ2V0Q2VsbFZhbHVlKHJvdywgY29sLmFjY2Vzc29yKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICA8YzgwLWljb24gaWNvbj1cImNhbmNlbFwiIFtzaXplXT1cIi43XCI+PC9jODAtaWNvbj5cbiAgICAgICAgICA8YnIgLz5cbiAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICA8L3RkPlxuICAgICAgICB9XG4gICAgICAgIEBlbHNlIGlmIChjb2wudHlwZSA9PT0gJ251bWJlcicgfHwgY29sLnR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWNlbnRlciBudW1iZXItY29sdW1uXCI+XG4gICAgICAgICAgQGlmIChlZGl0aW5nKCkgPT09IHJvd1snaWQnXSAmJiAhY29sLnJlYWRPbmx5KSB7XG4gICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tY29udHJvbC1zbVwiIHR5cGU9XCJudW1iZXJcIiBbdmFsdWVdPVwiZWRpdFJvdygpPy5bY29sLmFjY2Vzc29yXSA/PyAnJ1wiIFtwbGFjZWhvbGRlcl09XCJjb2wubGFiZWxcIiBbbWluXT1cImNvbC5taW5cIiBbbWF4XT1cImNvbC5tYXhcIiBbc3RlcF09XCJjb2wudHlwZSA9PT0gJ2ludGVnZXInID8gJzEnIDogJ2FueSdcIlxuICAgICAgICAgICAgKGlucHV0KT1cIm9uRWRpdElucHV0KCRldmVudCwgY29sLmFjY2Vzc29yLCBjb2wpXCIgLz5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgIDxzcGFuIFtzdHlsZS5jb2xvcl09XCJnZXRDZWxsQ29sb3IoZ2V0Q2VsbFZhbHVlKHJvdywgY29sLmFjY2Vzc29yKSwgY29sKVwiPnt7IGdldERpc3BsYXlWYWx1ZShnZXRDZWxsVmFsdWUocm93LFxuICAgICAgICAgICAgY29sLmFjY2Vzc29yKSwgY29sKSB9fTwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvdGQ+XG4gICAgICAgIH1cbiAgICAgICAgQGVsc2Uge1xuICAgICAgICA8dGQ+XG4gICAgICAgICAgQGlmIChlZGl0aW5nKCkgPT09IHJvd1snaWQnXSAmJiAhY29sLnJlYWRPbmx5KSB7XG4gICAgICAgICAgQGlmIChjb2wudHlwZSA9PT0gJ2VudW0nKSB7XG4gICAgICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWNvbnRyb2wtc21cIiBbdmFsdWVdPVwiZWRpdFJvdygpPy5bY29sLmFjY2Vzc29yXSA/PyAnJ1wiIChjaGFuZ2UpPVwib25FZGl0SW5wdXQoJGV2ZW50LCBjb2wuYWNjZXNzb3IsIGNvbClcIj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj57eyBjb2wubGFiZWwgfX08L29wdGlvbj5cbiAgICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiBnZXRFbnVtT3B0aW9ucyhjb2wpOyB0cmFjayBvcHRpb24udmFsdWUpIHtcbiAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPnt7IG9wdGlvbi5sYWJlbCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSB7XG4gICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tY29udHJvbC1zbVwiIFt0eXBlXT1cImNvbC50eXBlID09PSAncGFzc3dvcmQnID8gJ3Bhc3N3b3JkJyA6ICd0ZXh0J1wiIFt2YWx1ZV09XCJlZGl0Um93KCk/Lltjb2wuYWNjZXNzb3JdID8/ICcnXCIgW3BsYWNlaG9sZGVyXT1cImNvbC5sYWJlbFwiIChpbnB1dCk9XCJvbkVkaXRJbnB1dCgkZXZlbnQsIGNvbC5hY2Nlc3NvciwgY29sKVwiIC8+XG4gICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSB7XG4gICAgICAgICAgQGlmIChjb2wudHlwZSA9PT0gJ3Bhc3N3b3JkJykge1xuICAgICAgICAgIDxzcGFuIFtzdHlsZS5jb2xvcl09XCJnZXRDZWxsQ29sb3IoZ2V0Q2VsbFZhbHVlKHJvdywgY29sLmFjY2Vzc29yKSwgY29sKVwiPioqKioqKjwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGVsc2UgaWYgKGNvbC50eXBlID09PSAnZW51bScpIHtcbiAgICAgICAgICA8c3BhbiBbc3R5bGUuY29sb3JdPVwiZ2V0Q2VsbENvbG9yKGdldENlbGxWYWx1ZShyb3csIGNvbC5hY2Nlc3NvciksIGNvbClcIj57e1xuICAgICAgICAgICAgZ2V0RW51bURpc3BsYXlWYWx1ZShnZXRDZWxsVmFsdWUocm93LCBjb2wuYWNjZXNzb3IpLCBjb2wpXG4gICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGVsc2UgaWYgKGdldENlbGxWYWx1ZShyb3csIGNvbC5hY2Nlc3NvcikgPT09IHRydWUpIHtcbiAgICAgICAgICA8YzgwLWljb24gaWNvbj1cImNoZWNrXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSBpZiAoZ2V0Q2VsbFZhbHVlKHJvdywgY29sLmFjY2Vzc29yKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICA8YzgwLWljb24gaWNvbj1cImNhbmNlbFwiIFtzaXplXT1cIi43XCI+PC9jODAtaWNvbj5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgIDxzcGFuIFtzdHlsZS5jb2xvcl09XCJnZXRDZWxsQ29sb3IoZ2V0Q2VsbFZhbHVlKHJvdywgY29sLmFjY2Vzc29yKSwgY29sKVwiPnt7IGdldERpc3BsYXlWYWx1ZShnZXRDZWxsVmFsdWUocm93LFxuICAgICAgICAgICAgY29sLmFjY2Vzc29yKSwgY29sKSB9fTwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICA8L3RkPlxuICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGhhc0FueUFjdGlvbnMoKSkge1xuICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWNlbnRlciBhY3Rpb25zLWNlbGxcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9ucy1jb250YWluZXJcIj5cbiAgICAgICAgICAgIEBpZiAoZWRpdGluZygpID09PSByb3dbJ2lkJ10pIHtcbiAgICAgICAgICAgIDwhLS0gTW9kbyBlZGljacOzbjogbW9zdHJhciBndWFyZGFyIHkgY2FuY2VsYXIgLS0+XG4gICAgICAgICAgICBAaWYgKGhhc0NydWRVcGRhdGUoKSkge1xuICAgICAgICAgICAgPGM4MC1pY29uIGJ1dHRvbiBpY29uPVwiY2hlY2tcIiB0aXRsZT1cIkd1YXJkYXJcIiAoaWNvbkNsaWNrKT1cInNhdmVFZGl0KHJvdylcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8YzgwLWljb24gYnV0dG9uIGljb249XCJjYW5jZWxcIiBjb2xvcj1cIndhcm5cIiB0aXRsZT1cIkNhbmNlbGFyXCIgKGljb25DbGljayk9XCJjYW5jZWxFZGl0KClcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAZWxzZSB7XG4gICAgICAgICAgICBAZm9yIChhY3Rpb24gb2YgY3VzdG9tQWN0aW9uczsgdHJhY2sgYWN0aW9uLm5hbWUpIHtcbiAgICAgICAgICAgIEBpZiAoc2hvdWxkU2hvd0FjdGlvbihhY3Rpb24sIHJvdykpIHtcbiAgICAgICAgICAgIDxjODAtaWNvbiBidXR0b24gW2ljb25dPVwiYWN0aW9uLmljb25cIiBbY3VzdG9tQ29sb3JdPVwiYWN0aW9uLmNvbG9yXCIgW2NvbG9yXT1cImFjdGlvbi5uYW1lID09PSAnZGVsZXRlJyA/ICd3YXJuJyA6ICdwcmltYXJ5J1wiIFt0aXRsZV09XCJnZXRBY3Rpb25Ub29sdGlwKGFjdGlvbilcIiAoaWNvbkNsaWNrKT1cIm9uRHluYW1pY0FjdGlvbihhY3Rpb24sIHJvdylcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvdGQ+XG4gICAgICAgIH1cbiAgICAgIDwvdHI+XG4gICAgICB9XG4gICAgICBAaWYgKGNyZWF0aW5nKCkgJiYgaGFzQ3J1ZENyZWF0ZSgpKSB7XG4gICAgICA8dHI+XG4gICAgICAgIEBpZiAoYWxsb3dTZWxlY3Rpb24gJiYgZGF0YSgpLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWNlbnRlciBzZWxlY3Rpb24tY29sdW1uXCI+XG4gICAgICAgICAgPCEtLSBFbXB0eSBjZWxsIGZvciBhbGlnbm1lbnQgLS0+XG4gICAgICAgIDwvdGQ+XG4gICAgICAgIH1cbiAgICAgICAgQGZvciAoY29sIG9mIGNvbHVtbnM7IHRyYWNrIGNvbCkge1xuICAgICAgICBAaWYgKGlzQ29sdW1uVmlzaWJsZShjb2wpKSB7XG4gICAgICAgIEBpZiAoY29sLnR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPlxuICAgICAgICAgIEBpZiAoIWNvbC5yZWFkT25seSkge1xuICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbY2hlY2tlZF09XCIhIW5ld1JvdygpPy5bY29sLmFjY2Vzc29yXVwiIChjaGFuZ2UpPVwib25JbnB1dCgkZXZlbnQsIGNvbC5hY2Nlc3NvciwgY29sKVwiIFthdHRyLmFyaWEtbGFiZWxdPVwiY29sLmxhYmVsXCIgLz5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgIDwhLS0gUmVhZE9ubHkgYm9vbGVhbiBjb2x1bW4gaW4gY3JlYXRlIG1vZGUgc2hvd3MgZW1wdHkgLS0+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LW11dGVkXCI+LTwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvdGQ+XG4gICAgICAgIH0gQGVsc2UgaWYgKGNvbC50eXBlID09PSAnbnVtYmVyJyB8fCBjb2wudHlwZSA9PT0gJ2ludGVnZXInKSB7XG4gICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyIG51bWJlci1jb2x1bW5cIj5cbiAgICAgICAgICBAaWYgKCFjb2wucmVhZE9ubHkpIHtcbiAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtXCIgdHlwZT1cIm51bWJlclwiIFt2YWx1ZV09XCJuZXdSb3coKT8uW2NvbC5hY2Nlc3Nvcl0gPz8gJydcIiBbcGxhY2Vob2xkZXJdPVwiY29sLmxhYmVsXCIgW21pbl09XCJjb2wubWluXCIgW21heF09XCJjb2wubWF4XCIgW3N0ZXBdPVwiY29sLnR5cGUgPT09ICdpbnRlZ2VyJyA/ICcxJyA6ICdhbnknXCJcbiAgICAgICAgICAgIChpbnB1dCk9XCJvbklucHV0KCRldmVudCwgY29sLmFjY2Vzc29yLCBjb2wpXCIgLz5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgIDwhLS0gUmVhZE9ubHkgbnVtYmVyIGNvbHVtbiBpbiBjcmVhdGUgbW9kZSBzaG93cyBlbXB0eSAtLT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWRcIj4tPC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgPC90ZD5cbiAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgIDx0ZD5cbiAgICAgICAgICBAaWYgKCFjb2wucmVhZE9ubHkpIHtcbiAgICAgICAgICBAaWYgKGNvbC50eXBlID09PSAnZW51bScpIHtcbiAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tY29udHJvbC1zbVwiIFt2YWx1ZV09XCJuZXdSb3coKT8uW2NvbC5hY2Nlc3Nvcl0gPz8gJydcIiAoY2hhbmdlKT1cIm9uSW5wdXQoJGV2ZW50LCBjb2wuYWNjZXNzb3IsIGNvbClcIj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj57eyBjb2wubGFiZWwgfX08L29wdGlvbj5cbiAgICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiBnZXRFbnVtT3B0aW9ucyhjb2wpOyB0cmFjayBvcHRpb24udmFsdWUpIHtcbiAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPnt7IG9wdGlvbi5sYWJlbCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSB7XG4gICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tY29udHJvbC1zbVwiIHR5cGU9XCJ0ZXh0XCIgW3ZhbHVlXT1cIm5ld1JvdygpPy5bY29sLmFjY2Vzc29yXSA/PyAnJ1wiIFtwbGFjZWhvbGRlcl09XCJjb2wubGFiZWxcIiAoaW5wdXQpPVwib25JbnB1dCgkZXZlbnQsIGNvbC5hY2Nlc3NvciwgY29sKVwiIC8+XG4gICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSB7XG4gICAgICAgICAgPCEtLSBSZWFkT25seSBjb2x1bW4gaW4gY3JlYXRlIG1vZGUgc2hvd3MgZW1wdHkgLS0+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LW11dGVkXCI+LTwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvdGQ+XG4gICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyIGFjdGlvbnMtY2VsbFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb25zLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgQGlmIChoYXNDcnVkQ3JlYXRlKCkpIHtcbiAgICAgICAgICAgIDxjODAtaWNvbiBidXR0b24gaWNvbj1cImNoZWNrXCIgdGl0bGU9XCJHdWFyZGFyXCIgKGljb25DbGljayk9XCJzYXZlQ3JlYXRlKClcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8YzgwLWljb24gYnV0dG9uIGljb249XCJjYW5jZWxcIiBjb2xvcj1cIndhcm5cIiB0aXRsZT1cIkNhbmNlbGFyXCIgKGljb25DbGljayk9XCJjYW5jZWxDcmVhdGUoKVwiIFtzaXplXT1cIi43XCI+PC9jODAtaWNvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvdHI+XG4gICAgICB9XG4gICAgPC90Ym9keT5cbiAgPC90YWJsZT5cbiAgQGlmIChkYXRhKCkubGVuZ3RoID09PSAwICYmICFjcmVhdGluZygpKSB7XG4gIDxkaXYgY2xhc3M9XCJ0ZXh0LWNlbnRlciB0ZXh0LW11dGVkIHB5LTMgc21hbGxcIj5cbiAgICBObyBoYXkgZGF0b3MgcGFyYSBtb3N0cmFyLlxuICA8L2Rpdj5cbiAgfVxuPC9kaXY+XG5cbjxjODAtbW9kYWw+PC9jODAtbW9kYWw+Il19
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tipos comunes para las tablas C80
|
|
3
|
-
*/
|
|
4
|
-
export {};
|
|
5
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUudHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL3VpL3NyYy9saWIvdGFibGUvdGFibGUudHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUciLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRpcG9zIGNvbXVuZXMgcGFyYSBsYXMgdGFibGFzIEM4MFxuICovXG5cbmltcG9ydCB0eXBlIHsgSWNvblR5cGUgfSBmcm9tICcuLi9pY29uJztcblxuZXhwb3J0IGludGVyZmFjZSBDODBUYWJsZUNvbERlZiB7XG4gIGFjY2Vzc29yOiBzdHJpbmc7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIHZpc2libGU/OiBib29sZWFuOyAvLyBTaSBubyBzZSBlc3BlY2lmaWNhLCBzZSBhc3VtZSB0cnVlLiBTaSBlcyBmYWxzZSwgbGEgY29sdW1uYSBzZSBvY3VsdGEgU0lFTVBSRSAobcOheGltYSBwcmlvcmlkYWQpXG4gIHR5cGU/OiAnc3RyaW5nJyB8ICdudW1iZXInIHwgJ2ludGVnZXInIHwgJ2Jvb2xlYW4nIHwgJ3Bhc3N3b3JkJyB8ICdlbnVtJyB8ICdkYXRlJzsgLy8gVGlwbyBkZSBkYXRvIHBhcmEgbGEgY29sdW1uYVxuICBvcmRlcj86ICdBU0MnIHwgJ0RFU0MnOyAvLyBPcmRlbmFtaWVudG8gZGUgbGEgY29sdW1uYVxuICByZWFkT25seT86IGJvb2xlYW47IC8vIFNpIG5vIHNlIGVzcGVjaWZpY2EsIHNlIGFzdW1lIGZhbHNlXG4gIGVudW0/OiBSZWNvcmQ8c3RyaW5nIHwgbnVtYmVyLCBzdHJpbmc+OyAvLyBPcGNpb25lcyBkZWwgZW51bSBwYXJhIHR5cGUgJ2VudW0nXG4gIGNvbG9yPzogUmVjb3JkPHN0cmluZyB8IG51bWJlciwgc3RyaW5nPjsgLy8gQ29sb3JlcyBDU1MgYmFzYWRvcyBlbiBlbCB2YWxvciBkZSBsYSBjZWxkYVxuICBoaWRlSWZBbGxWYWx1ZXNBcmVOdWxsPzogYm9vbGVhbjsgLy8gU2kgZXMgdHJ1ZSwgb2N1bHRhIGxhIGNvbHVtbmEgY3VhbmRvIHRvZG9zIGxvcyB2YWxvcmVzIGVzdMOhbiB2YWPDrW9zIChkZWZhdWx0OiBmYWxzZSkuXG4gIC8vIFNvbG8gYXBsaWNhIHNpIHZpc2libGUgIT09IGZhbHNlLiBFWENFUENJw5NOOiBFbiBtb2RvIGNyZWFjacOzbiBZIGVkaWNpw7NuIHNpZW1wcmUgc2UgbXVlc3RyYS5cbiAgZGVmYXVsdD86IHVua25vd247IC8vIFZhbG9yIHBvciBkZWZlY3RvIHBhcmEgdXNhciBlbiBtb2RvIGNyZWFjacOzbi4gUHVlZGUgc2VyIHN0cmluZywgbnVtYmVyLCBib29sZWFuLCBldGMuXG4gIG1pbj86IG51bWJlcjsgLy8gVmFsb3IgbcOtbmltbyBwZXJtaXRpZG8gcGFyYSBjb2x1bW5hcyBudW3DqXJpY2FzXG4gIG1heD86IG51bWJlcjsgLy8gVmFsb3IgbcOheGltbyBwZXJtaXRpZG8gcGFyYSBjb2x1bW5hcyBudW3DqXJpY2FzXG59XG5cbi8qKlxuICogQ29uZmlndXJhY2nDs24gZGUgY29uZmlybWFjacOzbiBwYXJhIGFjY2lvbmVzIGRlIHRhYmxhXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWN0aW9uQ29uZmlybWF0aW9uIHtcbiAgdGl0bGU6IHN0cmluZzsgICAgICAgIC8vIFTDrXR1bG8gZGVsIG1vZGFsIGRlIGNvbmZpcm1hY2nDs25cbiAgbWVzc2FnZTogc3RyaW5nOyAgICAgIC8vIE1lbnNhamUgZGVsIG1vZGFsIChwdWVkZSBpbmNsdWlyIHRlbXBsYXRlIGNvbiB7cHJvcGVydHlOYW1lfSlcbiAgY29uZmlybVRleHQ/OiBzdHJpbmc7IC8vIFRleHRvIGRlbCBib3TDs24gZGUgY29uZmlybWFyIChkZWZhdWx0OiBcIkNvbmZpcm1hclwiKVxuICBjYW5jZWxUZXh0Pzogc3RyaW5nOyAgLy8gVGV4dG8gZGVsIGJvdMOzbiBkZSBjYW5jZWxhciAoZGVmYXVsdDogXCJDYW5jZWxhclwiKVxufVxuXG4vKipcbiAqIERlZmluaWNpw7NuIGRlIGFjY2nDs24gcGVyc29uYWxpemFkYSBwYXJhIHRhYmxhXG4gKiBQZXJtaXRlIGFncmVnYXIgYWNjaW9uZXMgZGluw6FtaWNhcyBzaW4gbW9kaWZpY2FyIGVsIGNvbXBvbmVudGVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDdXN0b21UYWJsZUFjdGlvbiB7XG4gIG5hbWU6IHN0cmluZztcbiAgaWNvbjogSWNvblR5cGU7XG4gIGNvbG9yPzogc3RyaW5nO1xuICBjb25kaXRpb24/OiA8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHVua25vd24+Pihyb3c6IFQpID0+IGJvb2xlYW47XG4gIHRvb2x0aXA/OiBzdHJpbmc7XG4gIGNvbmZpcm1hdGlvbj86IEFjdGlvbkNvbmZpcm1hdGlvbjtcbn1cbiJdfQ==
|