@c80/ui 1.0.22 → 1.0.24

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.
@@ -2,7 +2,41 @@ import { Component, Input, Output, signal, EventEmitter, inject, } from '@angula
2
2
  import { C80IconComponent } from '../icon/icon.component';
3
3
  import { C80ModalComponent, ModalService } from '../modal';
4
4
  import * as i0 from "@angular/core";
5
- export class C80TableComponent {
5
+ /**
6
+ * C80TableComponent - Componente de tabla avanzado con funcionalidades CRUD
7
+ *
8
+ * COMPORTAMIENTO DE VISIBILIDAD DE COLUMNAS:
9
+ * ========================================
10
+ *
11
+ * 1. PRIORIDAD MÁXIMA - visible: false
12
+ * - La columna se oculta SIEMPRE, sin excepciones
13
+ * - Ni en modo creación ni en modo edición se muestra
14
+ *
15
+ * 2. OCULTACIÓN AUTOMÁTICA - hideIfAllValuesAreNull: true
16
+ * - La columna se oculta solo si TODOS los valores actuales están vacíos
17
+ * - Valores considerados vacíos: null, undefined, '', [], {}
18
+ * - Valores NO vacíos: 0, false (son valores válidos)
19
+ * - EXCEPCIONES IMPORTANTES:
20
+ * * En modo creación (creating=true) estas columnas SÍ se muestran
21
+ * * En modo edición de una fila específica también se muestran
22
+ *
23
+ * 3. POR DEFECTO - Columnas normales
24
+ * - Se muestran siempre (visualización, creación y edición)
25
+ *
26
+ * VALORES POR DEFECTO EN CREACIÓN:
27
+ * ===============================
28
+ *
29
+ * - Propiedad `default?: unknown` permite definir valores por defecto para modo creación
30
+ * - Solo se aplica cuando se inicia el modo creación (startCreate)
31
+ * - Puede ser cualquier tipo: string, number, boolean, etc.
32
+ * - Si no se especifica `default`, se usa cadena vacía ('')
33
+ *
34
+ * EJEMPLOS:
35
+ * - { accessor: 'id', visible: false } → NUNCA se muestra
36
+ * - { accessor: 'motorPos', hideIfAllValuesAreNull: true, default: 0 } → Se autorellena con 0 en creación
37
+ * - { accessor: 'status', default: 'active' } → Se autorellena con 'active' en creación
38
+ * - { accessor: 'name' } → Siempre visible, sin valor por defecto (cadena vacía)
39
+ */ export class C80TableComponent {
6
40
  modalService = inject(ModalService);
7
41
  data$;
8
42
  columns = [];
@@ -47,6 +81,13 @@ export class C80TableComponent {
47
81
  getErrorMessage(err) {
48
82
  return err?.message || 'Error al cargar datos';
49
83
  }
84
+ /**
85
+ * Actualiza las keys de columnas visibles basándose en el estado actual
86
+ */
87
+ updateVisibleKeys() {
88
+ const visibleColumns = this.columns.filter(col => this.isColumnVisibleInHeader(col));
89
+ this.keys.set(visibleColumns.map((col) => col.accessor));
90
+ }
50
91
  ngOnInit() {
51
92
  // Check if the outputs have listeners
52
93
  this.hasCreateActionListener.set(this.createAction.observed);
@@ -66,9 +107,8 @@ export class C80TableComponent {
66
107
  next: (items) => {
67
108
  this.applySorting(items);
68
109
  this.data.set(items);
69
- // Solo mostrar las columnas visibles
70
- const visibleColumns = this.columns.filter((col) => col?.visible !== false);
71
- this.keys.set(visibleColumns.map((col) => col.accessor));
110
+ // Actualizar las columnas visibles basándose en el estado actual
111
+ this.updateVisibleKeys();
72
112
  // Mantener la selección existente después de actualizar los datos
73
113
  this.preserveSelection();
74
114
  },
@@ -130,18 +170,25 @@ export class C80TableComponent {
130
170
  }
131
171
  startCreate() {
132
172
  this.creating.set(true);
173
+ // Actualizar keys de columnas visibles cuando entramos en modo creación
174
+ this.updateVisibleKeys();
133
175
  // Inicializa newRow solo con columnas visibles y no readOnly
176
+ // En modo creación, mostramos columnas con hideIfAllValuesAreNull para permitir entrada de datos
134
177
  const row = {};
135
178
  this.columns
136
- .filter((col) => col.visible !== false && !col.readOnly)
179
+ .filter((col) => this.isColumnVisible(col, true) && !col.readOnly)
137
180
  .forEach((col) => {
138
- row[col.accessor] = '';
181
+ // Si la columna tiene un valor por defecto, usarlo; si no, usar cadena vacía
182
+ const defaultValue = col.default !== undefined ? col.default : '';
183
+ row[col.accessor] = defaultValue;
139
184
  });
140
185
  this.newRow.set(row);
141
186
  }
142
187
  cancelCreate() {
143
188
  this.creating.set(false);
144
189
  this.newRow.set(null);
190
+ // Actualizar keys de columnas visibles cuando salimos del modo creación
191
+ this.updateVisibleKeys();
145
192
  }
146
193
  updateNewRow(key, value) {
147
194
  const current = this.newRow();
@@ -154,7 +201,8 @@ export class C80TableComponent {
154
201
  if (!row)
155
202
  return;
156
203
  // Validar campos requeridos antes de crear - solo columnas visibles y no readOnly
157
- const visibleColumns = this.columns.filter((col) => col.visible !== false && !col.readOnly);
204
+ // En modo creación, incluimos columnas con hideIfAllValuesAreNull
205
+ const visibleColumns = this.columns.filter((col) => this.isColumnVisible(col, true) && !col.readOnly);
158
206
  const converted = visibleColumns.reduce((acc, col) => {
159
207
  acc[col.accessor] = this.convertCellValue(row[col.accessor], col);
160
208
  return acc;
@@ -237,9 +285,11 @@ export class C80TableComponent {
237
285
  }
238
286
  onEdit(row) {
239
287
  this.editing.set(row['id']);
288
+ // Actualizar keys de columnas visibles cuando entramos en modo edición
289
+ this.updateVisibleKeys();
240
290
  const edit = {};
241
291
  this.columns
242
- .filter((col) => col.visible !== false && !col.readOnly)
292
+ .filter((col) => this.isColumnVisible(col, true) && !col.readOnly)
243
293
  .forEach((col) => {
244
294
  const value = this.getCellValue(row, col.accessor);
245
295
  edit[col.accessor] = value;
@@ -249,6 +299,8 @@ export class C80TableComponent {
249
299
  cancelEdit() {
250
300
  this.editing.set(null);
251
301
  this.editRow.set(null);
302
+ // Actualizar keys de columnas visibles cuando salimos del modo edición
303
+ this.updateVisibleKeys();
252
304
  }
253
305
  onEditInput(event, key, col) {
254
306
  const current = this.editRow();
@@ -273,7 +325,7 @@ export class C80TableComponent {
273
325
  const id = row['id'];
274
326
  if ((typeof id !== 'string' && typeof id !== 'number') || !this.editRow())
275
327
  return;
276
- const visibleColumns = this.columns.filter((col) => col.visible !== false && !col.readOnly);
328
+ const visibleColumns = this.columns.filter((col) => this.isColumnVisible(col, true) && !col.readOnly);
277
329
  const converted = visibleColumns.reduce((acc, col) => {
278
330
  acc[col.accessor] = this.convertCellValue(this.editRow()[col.accessor], col);
279
331
  return acc;
@@ -559,6 +611,117 @@ export class C80TableComponent {
559
611
  const selectedItems = this.data().filter(item => selectedIds.has(item['id']));
560
612
  this.selectable.emit(selectedItems);
561
613
  }
614
+ /**
615
+ * Verifica si todos los valores de una columna están vacíos/nulos
616
+ */
617
+ areAllColumnValuesEmpty(column) {
618
+ const currentData = this.data();
619
+ if (currentData.length === 0) {
620
+ return true; // Si no hay datos, consideramos la columna como vacía
621
+ }
622
+ return currentData.every(row => {
623
+ const value = this.getCellValue(row, column.accessor);
624
+ // Considerar vacío: null, undefined, '', 0 (para números), false (para booleanos), arrays/objetos vacíos
625
+ if (value === null || value === undefined || value === '') {
626
+ return true;
627
+ }
628
+ // Para números, 0 se considera como valor válido, no vacío
629
+ if (typeof value === 'number') {
630
+ return false;
631
+ }
632
+ // Para booleanos, false se considera como valor válido, no vacío
633
+ if (typeof value === 'boolean') {
634
+ return false;
635
+ }
636
+ // Para arrays vacíos
637
+ if (Array.isArray(value) && value.length === 0) {
638
+ return true;
639
+ }
640
+ // Para objetos vacíos
641
+ if (typeof value === 'object' && value !== null && Object.keys(value).length === 0) {
642
+ return true;
643
+ }
644
+ return false;
645
+ });
646
+ }
647
+ /**
648
+ * Determina si una columna debe ser visible basándose en su configuración y datos.
649
+ *
650
+ * Orden de prioridad:
651
+ * 1. Si visible === false: SIEMPRE se oculta (máxima prioridad)
652
+ * 2. Si hideIfAllValuesAreNull === true Y todos los valores están vacíos: se oculta
653
+ * EXCEPCIÓN: En modo creación (creating === true), estas columnas se muestran para permitir entrada de datos
654
+ * 3. Por defecto: se muestra
655
+ *
656
+ * @param column - La definición de la columna
657
+ * @param forceShowInCreation - Si es true, ignora hideIfAllValuesAreNull (usado en modo creación)
658
+ */
659
+ isColumnVisible(column, forceShowInCreation = false) {
660
+ // PRIORIDAD 1: Si visible está explícitamente establecido en false, SIEMPRE ocultar
661
+ if (column.visible === false) {
662
+ return false;
663
+ }
664
+ // PRIORIDAD 2: Si hideIfAllValuesAreNull es true y todos los valores están vacíos, ocultar
665
+ // EXCEPCIÓN: En modo creación, mostramos estas columnas para permitir entrada de datos
666
+ if (column.hideIfAllValuesAreNull === true && !forceShowInCreation && this.areAllColumnValuesEmpty(column)) {
667
+ return false;
668
+ }
669
+ // Por defecto: mostrar
670
+ return true;
671
+ }
672
+ /**
673
+ * Determina si una columna debe ser visible en los headers.
674
+ * Los headers se muestran si la columna es visible en cualquiera de estos casos:
675
+ * - Visualización normal
676
+ * - Modo creación
677
+ * - Hay alguna fila en modo edición
678
+ *
679
+ * @param column - La definición de la columna
680
+ */
681
+ isColumnVisibleInHeader(column) {
682
+ // PRIORIDAD 1: Si visible está explícitamente establecido en false, SIEMPRE ocultar
683
+ if (column.visible === false) {
684
+ return false;
685
+ }
686
+ // Si estamos en modo creación, mostrar columnas con hideIfAllValuesAreNull
687
+ if (this.creating() && column.hideIfAllValuesAreNull === true) {
688
+ return true;
689
+ }
690
+ // Si hay alguna fila en modo edición, mostrar columnas con hideIfAllValuesAreNull
691
+ if (this.editing() !== null && column.hideIfAllValuesAreNull === true) {
692
+ return true;
693
+ }
694
+ // Si hideIfAllValuesAreNull es true y todos los valores están vacíos, ocultar
695
+ if (column.hideIfAllValuesAreNull === true && this.areAllColumnValuesEmpty(column)) {
696
+ return false;
697
+ }
698
+ // Por defecto: mostrar
699
+ return true;
700
+ }
701
+ /**
702
+ * Determina si una columna debe ser visible en una fila específica considerando el modo edición.
703
+ * En modo edición de esa fila específica, las columnas con hideIfAllValuesAreNull se muestran.
704
+ *
705
+ * @param column - La definición de la columna
706
+ * @param row - La fila actual
707
+ */
708
+ isColumnVisibleForRow(column, row) {
709
+ // PRIORIDAD 1: Si visible está explícitamente establecido en false, SIEMPRE ocultar
710
+ if (column.visible === false) {
711
+ return false;
712
+ }
713
+ // PRIORIDAD 2: Si esta fila específica está en modo edición, mostrar columnas con hideIfAllValuesAreNull
714
+ const isEditingThisRow = this.editing() === row['id'];
715
+ if (isEditingThisRow && column.hideIfAllValuesAreNull === true) {
716
+ return true;
717
+ }
718
+ // PRIORIDAD 3: Si hideIfAllValuesAreNull es true y todos los valores están vacíos, ocultar
719
+ if (column.hideIfAllValuesAreNull === true && this.areAllColumnValuesEmpty(column)) {
720
+ return false;
721
+ }
722
+ // Por defecto: mostrar
723
+ return true;
724
+ }
562
725
  applySorting(items) {
563
726
  const orderedColumns = this.columns.filter((col) => col.order);
564
727
  if (orderedColumns.length > 0) {
@@ -585,11 +748,11 @@ export class C80TableComponent {
585
748
  }
586
749
  }
587
750
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: C80TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
588
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: C80TableComponent, isStandalone: true, selector: "c80-table", inputs: { data$: "data$", columns: "columns", size: "size", multiple: "multiple", noConfirm: ["noConfirm", "noConfirm", (value) => value === '' || value === true || value === 'true'] }, outputs: { createAction: "createAction", updateAction: "updateAction", deleteAction: "deleteAction", cancelAction: "cancelAction", viewAction: "viewAction", getRowButtonAction: "getRowButtonAction", moveUpAction: "moveUpAction", moveDownAction: "moveDownAction", enableAction: "enableAction", searchTerm: "searchTerm", errorEvent: "errorEvent", selectable: "selectable" }, ngImport: i0, template: "<div class=\"table-responsive\" [style.max-height]=\"getTableMaxHeight()\" [style.overflow-y]=\"size > 0 ? 'auto' : 'visible'\">\n <!-- Search Bar -->\n @if (hasSearchTermListener()) {\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 (hasSelectableListener() && 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 (col.visible !== false) {\n @if (col.type === 'boolean') {\n <th class=\"text-center boolean-column\">{{ col.label }}</th>\n }\n @else if (col.type === 'number') {\n <th class=\"text-center number-column\">{{ col.label }}</th>\n }\n @else {\n <th>{{ col.label }}</th>\n }\n }\n }\n @if (hasCreateActionListener() || hasUpdateActionListener() || hasDeleteActionListener() ||\n hasCancelActionListener() || hasViewActionListener() || hasGetRowButtonListener() ||\n hasMoveUpActionListener() || hasMoveDownActionListener()) {\n <th class=\"table-actions-header\">\n <div class=\"actions-wrapper\">\n <span>Actions</span>\n @if (hasCreateActionListener()) {\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 (hasSelectableListener() && 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 (col.visible !== false) {\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') {\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\" (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)) }}</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)) }}</span>\n }\n }\n </td>\n }\n }\n }\n @if (hasCreateActionListener() || hasUpdateActionListener() || hasDeleteActionListener() ||\n hasCancelActionListener() || hasViewActionListener() || hasGetRowButtonListener() ||\n hasMoveUpActionListener() || hasMoveDownActionListener()) {\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (editing() === row['id']) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveEdit(row)\" [size]=\".7\"></c80-icon>\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelEdit()\" [size]=\".7\"></c80-icon>\n }\n @else {\n @if (hasUpdateActionListener()) {\n <c80-icon button icon=\"edit\" title=\"Editar\" (iconClick)=\"onEdit(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasCancelActionListener()) {\n <c80-icon button icon=\"cancel_circle\" color=\"secondary\" title=\"Cancelar\" (iconClick)=\"onCancel(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasViewActionListener()) {\n <c80-icon button icon=\"view\" color=\"primary\" title=\"Ver\" (iconClick)=\"onView(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasGetRowButtonListener()) {\n <c80-icon button icon=\"get\" color=\"success\" title=\"Vincular\" (iconClick)=\"onGetRowButton(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasMoveUpActionListener()) {\n <c80-icon button icon=\"arrow_up\" color=\"secondary\" title=\"Mover arriba\" (iconClick)=\"onMoveUp(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasMoveDownActionListener()) {\n <c80-icon button icon=\"arrow_down\" color=\"secondary\" title=\"Mover abajo\" (iconClick)=\"onMoveDown(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasEnableActionListener()) {\n <c80-icon button [icon]=\"getCellValue(row, 'enabled') ? 'toggle_on' : 'toggle_off'\" [color]=\"getCellValue(row, 'enabled') ? 'success' : 'secondary'\" [title]=\"getCellValue(row, 'enabled') ? 'Deshabilitar' : 'Habilitar'\"\n (iconClick)=\"onEnable(row)\" [size]=\".7\">\n </c80-icon>\n }\n @if (hasDeleteActionListener()) {\n <c80-icon button icon=\"delete\" color=\"warn\" title=\"Borrar\" (iconClick)=\"onDelete(row)\" [size]=\".7\"></c80-icon>\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n @if (creating() && hasCreateActionListener()) {\n <tr>\n @if (hasSelectableListener() && 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 (col.visible !== false) {\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') {\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\" (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 <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveCreate()\" [size]=\".7\"></c80-icon>\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:#6c757d;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]){min-width:160px!important;width:160px!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", "type"], outputs: ["iconClick"] }, { kind: "component", type: C80ModalComponent, selector: "c80-modal" }] });
751
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: C80TableComponent, isStandalone: true, selector: "c80-table", inputs: { data$: "data$", columns: "columns", size: "size", multiple: "multiple", noConfirm: ["noConfirm", "noConfirm", (value) => value === '' || value === true || value === 'true'] }, outputs: { createAction: "createAction", updateAction: "updateAction", deleteAction: "deleteAction", cancelAction: "cancelAction", viewAction: "viewAction", getRowButtonAction: "getRowButtonAction", moveUpAction: "moveUpAction", moveDownAction: "moveDownAction", enableAction: "enableAction", searchTerm: "searchTerm", errorEvent: "errorEvent", selectable: "selectable" }, ngImport: i0, template: "<div class=\"table-responsive\" [style.max-height]=\"getTableMaxHeight()\" [style.overflow-y]=\"size > 0 ? 'auto' : 'visible'\">\n <!-- Search Bar -->\n @if (hasSearchTermListener()) {\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 (hasSelectableListener() && 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') {\n <th class=\"text-center number-column\">{{ col.label }}</th>\n }\n @else {\n <th>{{ col.label }}</th>\n }\n }\n }\n @if (hasCreateActionListener() || hasUpdateActionListener() || hasDeleteActionListener() ||\n hasCancelActionListener() || hasViewActionListener() || hasGetRowButtonListener() ||\n hasMoveUpActionListener() || hasMoveDownActionListener()) {\n <th class=\"table-actions-header\">\n <div class=\"actions-wrapper\">\n <span>Actions</span>\n @if (hasCreateActionListener()) {\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 (hasSelectableListener() && 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') {\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\" (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)) }}</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)) }}</span>\n }\n }\n </td>\n }\n }\n }\n @if (hasCreateActionListener() || hasUpdateActionListener() || hasDeleteActionListener() ||\n hasCancelActionListener() || hasViewActionListener() || hasGetRowButtonListener() ||\n hasMoveUpActionListener() || hasMoveDownActionListener()) {\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (editing() === row['id']) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveEdit(row)\" [size]=\".7\"></c80-icon>\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelEdit()\" [size]=\".7\"></c80-icon>\n }\n @else {\n @if (hasUpdateActionListener()) {\n <c80-icon button icon=\"edit\" title=\"Editar\" (iconClick)=\"onEdit(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasCancelActionListener()) {\n <c80-icon button icon=\"cancel_circle\" color=\"secondary\" title=\"Cancelar\" (iconClick)=\"onCancel(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasViewActionListener()) {\n <c80-icon button icon=\"view\" color=\"primary\" title=\"Ver\" (iconClick)=\"onView(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasGetRowButtonListener()) {\n <c80-icon button icon=\"get\" color=\"success\" title=\"Vincular\" (iconClick)=\"onGetRowButton(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasMoveUpActionListener()) {\n <c80-icon button icon=\"arrow_up\" color=\"secondary\" title=\"Mover arriba\" (iconClick)=\"onMoveUp(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasMoveDownActionListener()) {\n <c80-icon button icon=\"arrow_down\" color=\"secondary\" title=\"Mover abajo\" (iconClick)=\"onMoveDown(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasEnableActionListener()) {\n <c80-icon button [icon]=\"getCellValue(row, 'enabled') ? 'toggle_on' : 'toggle_off'\" [color]=\"getCellValue(row, 'enabled') ? 'success' : 'secondary'\" [title]=\"getCellValue(row, 'enabled') ? 'Deshabilitar' : 'Habilitar'\"\n (iconClick)=\"onEnable(row)\" [size]=\".7\">\n </c80-icon>\n }\n @if (hasDeleteActionListener()) {\n <c80-icon button icon=\"delete\" color=\"warn\" title=\"Borrar\" (iconClick)=\"onDelete(row)\" [size]=\".7\"></c80-icon>\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n @if (creating() && hasCreateActionListener()) {\n <tr>\n @if (hasSelectableListener() && 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, true)) {\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') {\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\" (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 <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveCreate()\" [size]=\".7\"></c80-icon>\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:#6c757d;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", "type"], outputs: ["iconClick"] }, { kind: "component", type: C80ModalComponent, selector: "c80-modal" }] });
589
752
  }
590
753
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: C80TableComponent, decorators: [{
591
754
  type: Component,
592
- args: [{ selector: 'c80-table', standalone: true, imports: [C80IconComponent, C80ModalComponent], template: "<div class=\"table-responsive\" [style.max-height]=\"getTableMaxHeight()\" [style.overflow-y]=\"size > 0 ? 'auto' : 'visible'\">\n <!-- Search Bar -->\n @if (hasSearchTermListener()) {\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 (hasSelectableListener() && 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 (col.visible !== false) {\n @if (col.type === 'boolean') {\n <th class=\"text-center boolean-column\">{{ col.label }}</th>\n }\n @else if (col.type === 'number') {\n <th class=\"text-center number-column\">{{ col.label }}</th>\n }\n @else {\n <th>{{ col.label }}</th>\n }\n }\n }\n @if (hasCreateActionListener() || hasUpdateActionListener() || hasDeleteActionListener() ||\n hasCancelActionListener() || hasViewActionListener() || hasGetRowButtonListener() ||\n hasMoveUpActionListener() || hasMoveDownActionListener()) {\n <th class=\"table-actions-header\">\n <div class=\"actions-wrapper\">\n <span>Actions</span>\n @if (hasCreateActionListener()) {\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 (hasSelectableListener() && 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 (col.visible !== false) {\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') {\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\" (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)) }}</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)) }}</span>\n }\n }\n </td>\n }\n }\n }\n @if (hasCreateActionListener() || hasUpdateActionListener() || hasDeleteActionListener() ||\n hasCancelActionListener() || hasViewActionListener() || hasGetRowButtonListener() ||\n hasMoveUpActionListener() || hasMoveDownActionListener()) {\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (editing() === row['id']) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveEdit(row)\" [size]=\".7\"></c80-icon>\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelEdit()\" [size]=\".7\"></c80-icon>\n }\n @else {\n @if (hasUpdateActionListener()) {\n <c80-icon button icon=\"edit\" title=\"Editar\" (iconClick)=\"onEdit(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasCancelActionListener()) {\n <c80-icon button icon=\"cancel_circle\" color=\"secondary\" title=\"Cancelar\" (iconClick)=\"onCancel(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasViewActionListener()) {\n <c80-icon button icon=\"view\" color=\"primary\" title=\"Ver\" (iconClick)=\"onView(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasGetRowButtonListener()) {\n <c80-icon button icon=\"get\" color=\"success\" title=\"Vincular\" (iconClick)=\"onGetRowButton(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasMoveUpActionListener()) {\n <c80-icon button icon=\"arrow_up\" color=\"secondary\" title=\"Mover arriba\" (iconClick)=\"onMoveUp(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasMoveDownActionListener()) {\n <c80-icon button icon=\"arrow_down\" color=\"secondary\" title=\"Mover abajo\" (iconClick)=\"onMoveDown(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasEnableActionListener()) {\n <c80-icon button [icon]=\"getCellValue(row, 'enabled') ? 'toggle_on' : 'toggle_off'\" [color]=\"getCellValue(row, 'enabled') ? 'success' : 'secondary'\" [title]=\"getCellValue(row, 'enabled') ? 'Deshabilitar' : 'Habilitar'\"\n (iconClick)=\"onEnable(row)\" [size]=\".7\">\n </c80-icon>\n }\n @if (hasDeleteActionListener()) {\n <c80-icon button icon=\"delete\" color=\"warn\" title=\"Borrar\" (iconClick)=\"onDelete(row)\" [size]=\".7\"></c80-icon>\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n @if (creating() && hasCreateActionListener()) {\n <tr>\n @if (hasSelectableListener() && 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 (col.visible !== false) {\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') {\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\" (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 <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveCreate()\" [size]=\".7\"></c80-icon>\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:#6c757d;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]){min-width:160px!important;width:160px!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"] }]
755
+ args: [{ selector: 'c80-table', standalone: true, imports: [C80IconComponent, C80ModalComponent], template: "<div class=\"table-responsive\" [style.max-height]=\"getTableMaxHeight()\" [style.overflow-y]=\"size > 0 ? 'auto' : 'visible'\">\n <!-- Search Bar -->\n @if (hasSearchTermListener()) {\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 (hasSelectableListener() && 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') {\n <th class=\"text-center number-column\">{{ col.label }}</th>\n }\n @else {\n <th>{{ col.label }}</th>\n }\n }\n }\n @if (hasCreateActionListener() || hasUpdateActionListener() || hasDeleteActionListener() ||\n hasCancelActionListener() || hasViewActionListener() || hasGetRowButtonListener() ||\n hasMoveUpActionListener() || hasMoveDownActionListener()) {\n <th class=\"table-actions-header\">\n <div class=\"actions-wrapper\">\n <span>Actions</span>\n @if (hasCreateActionListener()) {\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 (hasSelectableListener() && 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') {\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\" (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)) }}</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)) }}</span>\n }\n }\n </td>\n }\n }\n }\n @if (hasCreateActionListener() || hasUpdateActionListener() || hasDeleteActionListener() ||\n hasCancelActionListener() || hasViewActionListener() || hasGetRowButtonListener() ||\n hasMoveUpActionListener() || hasMoveDownActionListener()) {\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (editing() === row['id']) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveEdit(row)\" [size]=\".7\"></c80-icon>\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelEdit()\" [size]=\".7\"></c80-icon>\n }\n @else {\n @if (hasUpdateActionListener()) {\n <c80-icon button icon=\"edit\" title=\"Editar\" (iconClick)=\"onEdit(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasCancelActionListener()) {\n <c80-icon button icon=\"cancel_circle\" color=\"secondary\" title=\"Cancelar\" (iconClick)=\"onCancel(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasViewActionListener()) {\n <c80-icon button icon=\"view\" color=\"primary\" title=\"Ver\" (iconClick)=\"onView(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasGetRowButtonListener()) {\n <c80-icon button icon=\"get\" color=\"success\" title=\"Vincular\" (iconClick)=\"onGetRowButton(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasMoveUpActionListener()) {\n <c80-icon button icon=\"arrow_up\" color=\"secondary\" title=\"Mover arriba\" (iconClick)=\"onMoveUp(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasMoveDownActionListener()) {\n <c80-icon button icon=\"arrow_down\" color=\"secondary\" title=\"Mover abajo\" (iconClick)=\"onMoveDown(row)\" [size]=\".7\"></c80-icon>\n }\n @if (hasEnableActionListener()) {\n <c80-icon button [icon]=\"getCellValue(row, 'enabled') ? 'toggle_on' : 'toggle_off'\" [color]=\"getCellValue(row, 'enabled') ? 'success' : 'secondary'\" [title]=\"getCellValue(row, 'enabled') ? 'Deshabilitar' : 'Habilitar'\"\n (iconClick)=\"onEnable(row)\" [size]=\".7\">\n </c80-icon>\n }\n @if (hasDeleteActionListener()) {\n <c80-icon button icon=\"delete\" color=\"warn\" title=\"Borrar\" (iconClick)=\"onDelete(row)\" [size]=\".7\"></c80-icon>\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n @if (creating() && hasCreateActionListener()) {\n <tr>\n @if (hasSelectableListener() && 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, true)) {\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') {\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\" (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 <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveCreate()\" [size]=\".7\"></c80-icon>\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:#6c757d;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"] }]
593
756
  }], propDecorators: { data$: [{
594
757
  type: Input
595
758
  }], columns: [{
@@ -626,4 +789,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
626
789
  }], selectable: [{
627
790
  type: Output
628
791
  }] } });
629
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy91aS9zcmMvbGliL3RhYmxlL3RhYmxlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL2xpYnMvdWkvc3JjL2xpYi90YWJsZS90YWJsZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sTUFBTSxFQUNOLFlBQVksRUFHWixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFlBQVksRUFBRSxNQUFNLFVBQVUsQ0FBQzs7QUF1QjNELE1BQU0sT0FBTyxpQkFBaUI7SUFDWCxZQUFZLEdBQWlCLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUMxRCxLQUFLLENBQW1CO0lBQ3hCLE9BQU8sR0FBcUIsRUFBRSxDQUFDO0lBQy9CLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyw2REFBNkQ7SUFDdkUsUUFBUSxHQUFHLElBQUksQ0FBQyxDQUFDLHlDQUF5QztJQUVuRSxTQUFTLEdBQUcsS0FBSyxDQUFDLENBQUMsZ0RBQWdEO0lBQ3pELFlBQVksR0FBRyxJQUFJLFlBQVksRUFBeUQsQ0FBQztJQUN6RixZQUFZLEdBQUcsSUFBSSxZQUFZLEVBQXFFLENBQUM7SUFDckcsWUFBWSxHQUFHLElBQUksWUFBWSxFQUFnRCxDQUFDO0lBQ2hGLFlBQVksR0FBRyxJQUFJLFlBQVksRUFBZ0QsQ0FBQztJQUNoRixVQUFVLEdBQUcsSUFBSSxZQUFZLEVBQUssQ0FBQztJQUNuQyxrQkFBa0IsR0FBRyxJQUFJLFlBQVksRUFBSyxDQUFDO0lBQzNDLFlBQVksR0FBRyxJQUFJLFlBQVksRUFBZ0QsQ0FBQztJQUNoRixjQUFjLEdBQUcsSUFB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QUFFO2dCQUUzRixZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFlBQVk7c0JBQXJCLE1BQU07Z0JBQ0csWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csa0JBQWtCO3NCQUEzQixNQUFNO2dCQUNHLFlBQVk7c0JBQXJCLE1BQU07Z0JBQ0csY0FBYztzQkFBdkIsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBRUcsVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBzaWduYWwsXG4gIEV2ZW50RW1pdHRlcixcbiAgT25Jbml0LFxuICBPbkRlc3Ryb3ksXG4gIGluamVjdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEM4MEljb25Db21wb25lbnQgfSBmcm9tICcuLi9pY29uL2ljb24uY29tcG9uZW50JztcbmltcG9ydCB7IEM4ME1vZGFsQ29tcG9uZW50LCBNb2RhbFNlcnZpY2UgfSBmcm9tICcuLi9tb2RhbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQzgwVGFibGVDb2xEZWYge1xuICBhY2Nlc3Nvcjogc3RyaW5nO1xuICBsYWJlbDogc3RyaW5nO1xuICB2aXNpYmxlPzogYm9vbGVhbjsgLy8gU2kgbm8gc2UgZXNwZWNpZmljYSwgc2UgYXN1bWUgdHJ1ZVxuICB0eXBlPzogJ3N0cmluZycgfCAnbnVtYmVyJyB8ICdib29sZWFuJyB8ICdwYXNzd29yZCcgfCAnZW51bSc7IC8vIFRpcG8gZGUgZGF0byBwYXJhIGxhIGNvbHVtbmFcbiAgb3JkZXI/OiAnQVNDJyB8ICdERVNDJzsgLy8gT3JkZW5hbWllbnRvIGRlIGxhIGNvbHVtbmFcbiAgcmVhZE9ubHk/OiBib29sZWFuOyAvLyBTaSBubyBzZSBlc3BlY2lmaWNhLCBzZSBhc3VtZSBmYWxzZVxuICBlbnVtPzogUmVjb3JkPHN0cmluZyB8IG51bWJlciwgc3RyaW5nPjsgLy8gT3BjaW9uZXMgZGVsIGVudW0gcGFyYSB0eXBlICdlbnVtJ1xuICBjb2xvcj86IFJlY29yZDxzdHJpbmcgfCBudW1iZXIsIHN0cmluZz47IC8vIENvbG9yZXMgQ1NTIGJhc2Fkb3MgZW4gZWwgdmFsb3IgZGUgbGEgY2VsZGFcbn1cblxuZXhwb3J0IHR5cGUgSUQgPSBudW1iZXIgfCBzdHJpbmc7XG5cbkBDb21wb25lbnQoe1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2NvbXBvbmVudC1zZWxlY3RvclxuICBzZWxlY3RvcjogJ2M4MC10YWJsZScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDODBJY29uQ29tcG9uZW50LCBDODBNb2RhbENvbXBvbmVudF0sXG4gIHRlbXBsYXRlVXJsOiAnLi90YWJsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi90YWJsZS5jb21wb25lbnQuc2NzcycsXG59KVxuZXhwb3J0IGNsYXNzIEM4MFRhYmxlQ29tcG9uZW50PFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4gaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgbW9kYWxTZXJ2aWNlOiBNb2RhbFNlcnZpY2UgPSBpbmplY3QoTW9kYWxTZXJ2aWNlKTtcbiAgQElucHV0KCkgZGF0YSQhOiBPYnNlcnZhYmxlPFRbXT47XG4gIEBJbnB1dCgpIGNvbHVtbnM6IEM4MFRhYmxlQ29sRGVmW10gPSBbXTtcbiAgQElucHV0KCkgc2l6ZSA9IDA7IC8vIFRhbWHDsW8gZGUgbGEgdGFibGEgKDAgPSBzaW4gbMOtbWl0ZSwgPiAwIGFwbGljYSBtYXgtaGVpZ2h0KVxuICBASW5wdXQoKSBtdWx0aXBsZSA9IHRydWU7IC8vIFBlcm1pdGUgc2VsZWNjacOzbiBtw7psdGlwbGUgcG9yIGRlZmVjdG9cbiAgQElucHV0KHsgdHJhbnNmb3JtOiAodmFsdWU6IGJvb2xlYW4gfCBzdHJpbmcpID0+IHZhbHVlID09PSAnJyB8fCB2YWx1ZSA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gJ3RydWUnIH0pXG4gIG5vQ29uZmlybSA9IGZhbHNlOyAvLyBTaSBlcyB0cnVlLCBubyBtdWVzdHJhIGNvbmZpcm1hY2lvbmVzIG1vZGFsZXNcbiAgQE91dHB1dCgpIGNyZWF0ZUFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8eyByb3c6IFBhcnRpYWw8VD47IGRvbmU6IChyZXN1bHQ6IGJvb2xlYW4pID0+IHZvaWQ7IH0+KCk7XG4gIEBPdXRwdXQoKSB1cGRhdGVBY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHsgaWQ6IElEOyBjaGFuZ2VzOiBQYXJ0aWFsPFQ+OyBkb25lOiAocmVzdWx0OiBib29sZWFuKSA9PiB2b2lkOyB9PigpO1xuICBAT3V0cHV0KCkgZGVsZXRlQWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBJRDsgZG9uZTogKHJlc3VsdDogYm9vbGVhbikgPT4gdm9pZDsgfT4oKTtcbiAgQE91dHB1dCgpIGNhbmNlbEFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBpZDogSUQ7IGRvbmU6IChyZXN1bHQ6IGJvb2xlYW4pID0+IHZvaWQ7IH0+KCk7XG4gIEBPdXRwdXQoKSB2aWV3QWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjxUPigpO1xuICBAT3V0cHV0KCkgZ2V0Um93QnV0dG9uQWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjxUPigpO1xuICBAT3V0cHV0KCkgbW92ZVVwQWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBJRDsgZG9uZTogKHJlc3VsdDogYm9vbGVhbikgPT4gdm9pZDsgfT4oKTtcbiAgQE91dHB1dCgpIG1vdmVEb3duQWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBJRDsgZG9uZTogKHJlc3VsdDogYm9vbGVhbikgPT4gdm9pZDsgfT4oKTtcbiAgQE91dHB1dCgpIGVuYWJsZUFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBpZDogSUQ7IGVuYWJsZWQ6IGJvb2xlYW47IGRvbmU6IChyZXN1bHQ6IGJvb2xlYW4pID0+IHZvaWQ7IH0+KCk7XG4gIEBPdXRwdXQoKSBzZWFyY2hUZXJtID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgQE91dHB1dCgpIGVycm9yRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgQE91dHB1dCgpIHNlbGVjdGFibGUgPSBuZXcgRXZlbnRFbWl0dGVyPFRbXT4oKTtcblxuICByZWFkb25seSBkYXRhID0gc2lnbmFsPFRbXT4oW10pO1xuICByZWFkb25seSBrZXlzID0gc2lnbmFsPHN0cmluZ1tdPihbXSk7XG4gIGNyZWF0aW5nID0gc2lnbmFsKGZhbHNlKTtcbiAgbmV3Um93ID0gc2lnbmFsPFBhcnRpYWw8VD4gfCBudWxsPihudWxsKTtcbiAgcmVhZG9ubHkgZWRpdGluZyA9IHNpZ25hbDxJRCB8IG51bGw+KG51bGwpOyAvLyBpZCBvZiByb3cgYmVpbmcgZWRpdGVkXG4gIHJlYWRvbmx5IGVkaXRSb3cgPSBzaWduYWw8UGFydGlhbDxUPiB8IG51bGw+KG51bGwpO1xuICByZWFkb25seSBzZWxlY3RlZEl0ZW1zID0gc2lnbmFsPFNldDxJRD4+KG5ldyBTZXQoKSk7XG4gIHJlYWRvbmx5IHNlbGVjdEFsbENoZWNrZWQgPSBzaWduYWwoZmFsc2UpO1xuICByZWFkb25seSBzZWxlY3RBbGxJbmRldGVybWluYXRlID0gc2lnbmFsKGZhbHNlKTtcbiAgcmVhZG9ubHkgc2VhcmNoVmFsdWUgPSBzaWduYWw8c3RyaW5nPignJyk7XG5cbiAgLy8gRmxhZ3MgdG8gY2hlY2sgaWYgZXZlbnRzIGhhdmUgbGlzdGVuZXJzXG4gIHJlYWRvbmx5IGhhc0NyZWF0ZUFjdGlvbkxpc3RlbmVyID0gc2lnbmFsKGZhbHNlKTtcbiAgcmVhZG9ubHkgaGFzVXBkYXRlQWN0aW9uTGlzdGVuZXIgPSBzaWduYWwoZmFsc2UpO1xuICByZWFkb25seSBoYXNEZWxldGVBY3Rpb25MaXN0ZW5lciA9IHNpZ25hbChmYWxzZSk7XG4gIHJlYWRvbmx5IGhhc0NhbmNlbEFjdGlvbkxpc3RlbmVyID0gc2lnbmFsKGZhbHNlKTtcbiAgcmVhZG9ubHkgaGFzVmlld0FjdGlvbkxpc3RlbmVyID0gc2lnbmFsKGZhbHNlKTtcbiAgcmVhZG9ubHkgaGFzR2V0Um93QnV0dG9uTGlzdGVuZXIgPSBzaWduYWwoZmFsc2UpO1xuICByZWFkb25seSBoYXNNb3ZlVXBBY3Rpb25MaXN0ZW5lciA9IHNpZ25hbChmYWxzZSk7XG4gIHJlYWRvbmx5IGhhc01vdmVEb3duQWN0aW9uTGlzdGVuZXIgPSBzaWduYWwoZmFsc2UpO1xuICByZWFkb25seSBoYXNFbmFibGVBY3Rpb25MaXN0ZW5lciA9IHNpZ25hbChmYWxzZSk7XG4gIHJlYWRvbmx5IGhhc1NlYXJjaFRlcm1MaXN0ZW5lciA9IHNpZ25hbChmYWxzZSk7XG4gIHJlYWRvbmx5IGhhc1NlbGVjdGFibGVMaXN0ZW5lciA9IHNpZ25hbChmYWxzZSk7XG5cbiAgcHJpdmF0ZSBkYXRhU3ViPzogU3Vic2NyaXB0aW9uO1xuXG4gIHByaXZhdGUgZ2V0RXJyb3JNZXNzYWdlKGVycjogdW5rbm93bik6IHN0cmluZyB7XG4gICAgcmV0dXJuIChlcnIgYXMgYW55KT8ubWVzc2FnZSB8fCAnRXJyb3IgYWwgY2FyZ2FyIGRhdG9zJztcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIC8vIENoZWNrIGlmIHRoZSBvdXRwdXRzIGhhdmUgbGlzdGVuZXJzXG4gICAgdGhpcy5oYXNDcmVhdGVBY3Rpb25MaXN0ZW5lci5zZXQodGhpcy5jcmVhdGVBY3Rpb24ub2JzZXJ2ZWQpO1xuICAgIHRoaXMuaGFzVXBkYXRlQWN0aW9uTGlzdGVuZXIuc2V0KHRoaXMudXBkYXRlQWN0aW9uLm9ic2VydmVkKTtcbiAgICB0aGlzLmhhc0RlbGV0ZUFjdGlvbkxpc3RlbmVyLnNldCh0aGlzLmRlbGV0ZUFjdGlvbi5vYnNlcnZlZCk7XG4gICAgdGhpcy5oYXNDYW5jZWxBY3Rpb25MaXN0ZW5lci5zZXQodGhpcy5jYW5jZWxBY3Rpb24ub2JzZXJ2ZWQpO1xuICAgIHRoaXMuaGFzVmlld0FjdGlvbkxpc3RlbmVyLnNldCh0aGlzLnZpZXdBY3Rpb24ub2JzZXJ2ZWQpO1xuICAgIHRoaXMuaGFzR2V0Um93QnV0dG9uTGlzdGVuZXIuc2V0KHRoaXMuZ2V0Um93QnV0dG9uQWN0aW9uLm9ic2VydmVkKTtcbiAgICB0aGlzLmhhc01vdmVVcEFjdGlvbkxpc3RlbmVyLnNldCh0aGlzLm1vdmVVcEFjdGlvbi5vYnNlcnZlZCk7XG4gICAgdGhpcy5oYXNNb3ZlRG93bkFjdGlvbkxpc3RlbmVyLnNldCh0aGlzLm1vdmVEb3duQWN0aW9uLm9ic2VydmVkKTtcbiAgICB0aGlzLmhhc0VuYWJsZUFjdGlvbkxpc3RlbmVyLnNldCh0aGlzLmVuYWJsZUFjdGlvbi5vYnNlcnZlZCk7XG4gICAgdGhpcy5oYXNTZWFyY2hUZXJtTGlzdGVuZXIuc2V0KHRoaXMuc2VhcmNoVGVybS5vYnNlcnZlZCk7XG4gICAgdGhpcy5oYXNTZWxlY3RhYmxlTGlzdGVuZXIuc2V0KHRoaXMuc2VsZWN0YWJsZS5vYnNlcnZlZCk7XG5cbiAgICBpZiAoIXRoaXMuZGF0YSQpIHJldHVybjtcbiAgICB0aGlzLmRhdGFTdWIgPSB0aGlzLmRhdGEkLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAoaXRlbXMpID0+IHtcbiAgICAgICAgdGhpcy5hcHBseVNvcnRpbmcoaXRlbXMpO1xuICAgICAgICB0aGlzLmRhdGEuc2V0KGl0ZW1zKTtcbiAgICAgICAgLy8gU29sbyBtb3N0cmFyIGxhcyBjb2x1bW5hcyB2aXNpYmxlc1xuICAgICAgICBjb25zdCB2aXNpYmxlQ29sdW1ucyA9IHRoaXMuY29sdW1ucy5maWx0ZXIoXG4gICAgICAgICAgKGNvbCkgPT4gY29sPy52aXNpYmxlICE9PSBmYWxzZVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmtleXMuc2V0KHZpc2libGVDb2x1bW5zLm1hcCgoY29sKSA9PiBjb2wuYWNjZXNzb3IpKTtcbiAgICAgICAgLy8gTWFudGVuZXIgbGEgc2VsZWNjacOzbiBleGlzdGVudGUgZGVzcHXDqXMgZGUgYWN0dWFsaXphciBsb3MgZGF0b3NcbiAgICAgICAgdGhpcy5wcmVzZXJ2ZVNlbGVjdGlvbigpO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyOiBhbnkpID0+XG4gICAgICAgIHRoaXMuZXJyb3JFdmVudC5lbWl0KHRoaXMuZ2V0RXJyb3JNZXNzYWdlKGVycikpLFxuICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5kYXRhU3ViPy51bnN1YnNjcmliZSgpO1xuXG4gICAgLy8gQ2xvc2UgYW55IG9wZW4gbW9kYWwgd2hlbiBjb21wb25lbnQgaXMgZGVzdHJveWVkXG4gICAgdGhpcy5tb2RhbFNlcnZpY2UuY2xvc2VNb2RhbCgpO1xuICB9XG5cbiAgb25JbnB1dChldmVudDogRXZlbnQsIGtleTogc3RyaW5nLCBjb2w/OiBDODBUYWJsZUNvbERlZikge1xuICAgIGlmIChjb2w/LnR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgY29uc3QgY2hlY2tlZCA9IChldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkuY2hlY2tlZDtcbiAgICAgIHRoaXMudXBkYXRlTmV3Um93KGtleSwgY2hlY2tlZCk7XG4gICAgfSBlbHNlIGlmIChjb2w/LnR5cGUgPT09ICdlbnVtJykge1xuICAgICAgY29uc3QgdmFsdWUgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxTZWxlY3RFbGVtZW50KS52YWx1ZTtcbiAgICAgIHRoaXMudXBkYXRlTmV3Um93KGtleSwgdmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgIGlmICh0YXJnZXQgJiYgdHlwZW9mIHRhcmdldC52YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhpcy51cGRhdGVOZXdSb3coa2V5LCB0YXJnZXQudmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIG9uRGVsZXRlKHJvdzogVCkge1xuICAgIGNvbnN0IGlkID0gcm93WydpZCddIGFzIElEO1xuXG4gICAgbGV0IGNvbmZpcm1lZCA9IHRydWU7XG4gICAgaWYgKCF0aGlzLm5vQ29uZmlybSkge1xuICAgICAgY29uZmlybWVkID0gYXdhaXQgdGhpcy5tb2RhbFNlcnZpY2UuY29uZmlybShcbiAgICAgICAgJ0NvbmZpcm1hciBlbGltaW5hY2nDs24nLFxuICAgICAgICAnwr9Fc3TDoSBzZWd1cm8gZGUgcXVlIGRlc2VhIGVsaW1pbmFyIGVzdGUgZWxlbWVudG8/IEVzdGEgYWNjacOzbiBubyBzZSBwdWVkZSBkZXNoYWNlci4nLFxuICAgICAgICAnRWxpbWluYXInLFxuICAgICAgICAnQ2FuY2VsYXInXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChjb25maXJtZWQpIHtcbiAgICAgIHRoaXMuZGVsZXRlQWN0aW9uLmVtaXQoe1xuICAgICAgICBpZCxcbiAgICAgICAgZG9uZTogKHN1Y2Nlc3M6IGJvb2xlYW4pID0+IHtcbiAgICAgICAgICBpZiAoc3VjY2VzcykgdGhpcy5jYW5jZWxFZGl0KCk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBvbkNhbmNlbChyb3c6IFQpIHtcbiAgICBjb25zdCBpZCA9IHJvd1snaWQnXSBhcyBJRDtcblxuICAgIGxldCBjb25maXJtZWQgPSB0cnVlO1xuICAgIGlmICghdGhpcy5ub0NvbmZpcm0pIHtcbiAgICAgIGNvbmZpcm1lZCA9IGF3YWl0IHRoaXMubW9kYWxTZXJ2aWNlLmNvbmZpcm0oXG4gICAgICAgICdDb25maXJtYXIgY2FuY2VsYWNpw7NuJyxcbiAgICAgICAgJ8K/RXN0w6Egc2VndXJvIGRlIHF1ZSBkZXNlYSBjYW5jZWxhciBlc3RlIGVsZW1lbnRvPycsXG4gICAgICAgICdDYW5jZWxhciBlbGVtZW50bycsXG4gICAgICAgICdObyBjYW5jZWxhcidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpcm1lZCkge1xuICAgICAgdGhpcy5jYW5jZWxBY3Rpb24uZW1pdCh7XG4gICAgICAgIGlkLFxuICAgICAgICBkb25lOiAoc3VjY2VzczogYm9vbGVhbikgPT4ge1xuICAgICAgICAgIGlmIChzdWNjZXNzKSB0aGlzLmNhbmNlbEVkaXQoKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHN0YXJ0Q3JlYXRlKCkge1xuICAgIHRoaXMuY3JlYXRpbmcuc2V0KHRydWUpO1xuICAgIC8vIEluaWNpYWxpemEgbmV3Um93IHNvbG8gY29uIGNvbHVtbmFzIHZpc2libGVzIHkgbm8gcmVhZE9ubHlcbiAgICBjb25zdCByb3c6IFBhcnRpYWw8VD4gPSB7fTtcbiAgICB0aGlzLmNvbHVtbnNcbiAgICAgIC5maWx0ZXIoKGNvbCkgPT4gY29sLnZpc2libGUgIT09IGZhbHNlICYmICFjb2wucmVhZE9ubHkpXG4gICAgICAuZm9yRWFjaCgoY29sKSA9PiB7XG4gICAgICAgIChyb3cgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW2NvbC5hY2Nlc3Nvcl0gPSAnJztcbiAgICAgIH0pO1xuICAgIHRoaXMubmV3Um93LnNldChyb3cpO1xuICB9XG5cbiAgY2FuY2VsQ3JlYXRlKCkge1xuICAgIHRoaXMuY3JlYXRpbmcuc2V0KGZhbHNlKTtcbiAgICB0aGlzLm5ld1Jvdy5zZXQobnVsbCk7XG4gIH1cblxuICB1cGRhdGVOZXdSb3coa2V5OiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKSB7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMubmV3Um93KCk7XG4gICAgaWYgKCFjdXJyZW50KSByZXR1cm47XG4gICAgdGhpcy5uZXdSb3cuc2V0KHsgLi4uY3VycmVudCwgW2tleV06IHZhbHVlIH0pO1xuICB9XG5cbiAgc2F2ZUNyZWF0ZSgpIHtcbiAgICBjb25zdCByb3cgPSB0aGlzLm5ld1JvdygpO1xuICAgIGlmICghcm93KSByZXR1cm47XG5cbiAgICAvLyBWYWxpZGFyIGNhbXBvcyByZXF1ZXJpZG9zIGFudGVzIGRlIGNyZWFyIC0gc29sbyBjb2x1bW5hcyB2aXNpYmxlcyB5IG5vIHJlYWRPbmx5XG4gICAgY29uc3QgdmlzaWJsZUNvbHVtbnMgPSB0aGlzLmNvbHVtbnMuZmlsdGVyKChjb2wpID0+IGNvbC52aXNpYmxlICE9PSBmYWxzZSAmJiAhY29sLnJlYWRPbmx5KTtcbiAgICBjb25zdCBjb252ZXJ0ZWQgPSB2aXNpYmxlQ29sdW1ucy5yZWR1Y2UoKGFjYywgY29sKSA9PiB7XG4gICAgICBhY2NbY29sLmFjY2Vzc29yXSA9IHRoaXMuY29udmVydENlbGxWYWx1ZShyb3dbY29sLmFjY2Vzc29yXSwgY29sKTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pIGFzIFBhcnRpYWw8VD47XG5cbiAgICB0aGlzLmNyZWF0ZUFjdGlvbi5lbWl0KHtcbiAgICAgIHJvdzogY29udmVydGVkLFxuICAgICAgZG9uZTogKHN1Y2Nlc3M6IGJvb2xlYW4pID0+IHtcbiAgICAgICAgaWYgKHN1Y2Nlc3MpIHtcbiAgICAgICAgICB0aGlzLmNhbmNlbENyZWF0ZSgpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgY2VsbCB2YWx1ZSBiYXNlZCBvbiBjb2x1bW4gdHlwZSBvciBzYW1wbGUgZGF0YS5cbiAgICogSGFuZGxlcyBzdHJpbmdpZmljYXRpb24gb2Ygb2JqZWN0cyBmb3Igc3RyaW5nIGNvbHVtbnMuXG4gICAqL1xuICAvKipcbiAgICogQ29udmVydHMgYSBjZWxsIHZhbHVlIGJhc2VkIG9uIGNvbHVtbiB0eXBlIG9yIHNhbXBsZSBkYXRhLlxuICAgKiBEZWxlZ2F0ZXMgdG8gdHlwZS1zcGVjaWZpYyBoZWxwZXJzIGZvciBjbGFyaXR5IGFuZCBtYWludGFpbmFiaWxpdHkuXG4gICAqL1xuICBwcml2YXRlIGNvbnZlcnRDZWxsVmFsdWUodmFsdWU6IHVua25vd24sIGNvbDogQzgwVGFibGVDb2xEZWYpOiB1bmtub3duIHtcbiAgICBpZiAoY29sLnR5cGUgPT09ICdib29sZWFuJykgcmV0dXJuIHRoaXMudG9Cb29sZWFuKHZhbHVlKTtcbiAgICBpZiAoY29sLnR5cGUgPT09ICdudW1iZXInKSByZXR1cm4gdGhpcy50b051bWJlcih2YWx1ZSk7XG4gICAgaWYgKGNvbC50eXBlID09PSAnc3RyaW5nJyB8fCBjb2wudHlwZSA9PT0gJ3Bhc3N3b3JkJylcbiAgICAgIHJldHVybiB0aGlzLnRvU3RyaW5nVmFsdWUodmFsdWUpO1xuXG4gICAgLy8gRmFsbGJhY2s6IHVzZSBzYW1wbGUgZGF0YSBpZiBhdmFpbGFibGVcbiAgICBjb25zdCBzYW1wbGUgPSB0aGlzLmRhdGEoKVswXTtcbiAgICBpZiAoc2FtcGxlKSB7XG4gICAgICBjb25zdCBzYW1wbGVWYWx1ZSA9IHRoaXMuZ2V0Q2VsbFZhbHVlKHNhbXBsZSwgY29sLmFjY2Vzc29yKTtcbiAgICAgIGlmICh0eXBlb2Ygc2FtcGxlVmFsdWUgPT09ICdib29sZWFuJykgcmV0dXJuIHRoaXMudG9Cb29sZWFuKHZhbHVlKTtcbiAgICAgIGlmICh0eXBlb2Ygc2FtcGxlVmFsdWUgPT09ICdudW1iZXInKSByZXR1cm4gdGhpcy50b051bWJlcih2YWx1ZSk7XG4gICAgICBpZiAodHlwZW9mIHNhbXBsZVZhbHVlID09PSAnc3RyaW5nJykgcmV0dXJuIHRoaXMudG9TdHJpbmdWYWx1ZSh2YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8qKiBDb252ZXJ0cyB2YWx1ZSB0byBib29sZWFuIHVzaW5nIGJlc3QgcHJhY3RpY2VzLiAqL1xuICBwcml2YXRlIHRvQm9vbGVhbih2YWx1ZTogdW5rbm93bik6IGJvb2xlYW4ge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykgcmV0dXJuIHZhbHVlO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgcmV0dXJuIHZhbHVlLnRyaW0oKS50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZScgfHwgdmFsdWUudHJpbSgpID09PSAnMSc7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHJldHVybiB2YWx1ZSA9PT0gMTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKiogQ29udmVydHMgdmFsdWUgdG8gbnVtYmVyIHVzaW5nIGJlc3QgcHJhY3RpY2VzLiAqL1xuICBwcml2YXRlIHRvTnVtYmVyKHZhbHVlOiB1bmtub3duKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykgcmV0dXJuIHZhbHVlO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgcmV0dXJuIHZhbHVlLnRyaW0oKSA9PT0gJycgPyB1bmRlZmluZWQgOiBOdW1iZXIodmFsdWUpO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykgcmV0dXJuIHZhbHVlID8gMSA6IDA7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKiBDb252ZXJ0cyB2YWx1ZSB0byBzdHJpbmcgdXNpbmcgYmVzdCBwcmFjdGljZXMsIGFsd2F5cyBzdHJpbmdpZmllcyBvYmplY3RzLiAqL1xuICBwcml2YXRlIHRvU3RyaW5nVmFsdWUodmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xuICAgIGlmICh2YWx1ZSA9PSBudWxsKSByZXR1cm4gJyc7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHJldHVybiB2YWx1ZTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJylcbiAgICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiAnW29iamVjdCBPYmplY3RdJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gRm9yIGZ1bmN0aW9ucywgc3ltYm9scywgdW5kZWZpbmVkLCBldGMuLCByZXR1cm4gZW1wdHkgc3RyaW5nXG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgb25FZGl0KHJvdzogVCkge1xuICAgIHRoaXMuZWRpdGluZy5zZXQocm93WydpZCddIGFzIElEKTtcbiAgICBjb25zdCBlZGl0OiBQYXJ0aWFsPFQ+ID0ge307XG4gICAgdGhpcy5jb2x1bW5zXG4gICAgICAuZmlsdGVyKChjb2wpID0+IGNvbC52aXNpYmxlICE9PSBmYWxzZSAmJiAhY29sLnJlYWRPbmx5KVxuICAgICAgLmZvckVhY2goKGNvbCkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0Q2VsbFZhbHVlKHJvdywgY29sLmFjY2Vzc29yKTtcbiAgICAgICAgKGVkaXQgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW2NvbC5hY2Nlc3Nvcl0gPSB2YWx1ZTtcbiAgICAgIH0pO1xuICAgIHRoaXMuZWRpdFJvdy5zZXQoZWRpdCk7XG4gIH1cblxuICBjYW5jZWxFZGl0KCkge1xuICAgIHRoaXMuZWRpdGluZy5zZXQobnVsbCk7XG4gICAgdGhpcy5lZGl0Um93LnNldChudWxsKTtcbiAgfVxuXG4gIG9uRWRpdElucHV0KGV2ZW50OiBFdmVudCwga2V5OiBzdHJpbmcsIGNvbD86IEM4MFRhYmxlQ29sRGVmKSB7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuZWRpdFJvdygpO1xuICAgIGlmICghY3VycmVudCkgcmV0dXJuO1xuICAgIGlmIChjb2w/LnR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgY29uc3QgY2hlY2tlZCA9IChldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkuY2hlY2tlZDtcbiAgICAgIHRoaXMuZWRpdFJvdy5zZXQoeyAuLi5jdXJyZW50LCBba2V5XTogY2hlY2tlZCB9KTtcbiAgICB9IGVsc2UgaWYgKGNvbD8udHlwZSA9PT0gJ2VudW0nKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IChldmVudC50YXJnZXQgYXMgSFRNTFNlbGVjdEVsZW1lbnQpLnZhbHVlO1xuICAgICAgdGhpcy5lZGl0Um93LnNldCh7IC4uLmN1cnJlbnQsIFtrZXldOiB2YWx1ZSB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgICBpZiAodGFyZ2V0ICYmIHR5cGVvZiB0YXJnZXQudmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMuZWRpdFJvdy5zZXQoeyAuLi5jdXJyZW50LCBba2V5XTogdGFyZ2V0LnZhbHVlIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNhdmVFZGl0KHJvdzogVCkge1xuICAgIGNvbnN0IGlkID0gcm93WydpZCddO1xuICAgIGlmICgodHlwZW9mIGlkICE9PSAnc3RyaW5nJyAmJiB0eXBlb2YgaWQgIT09ICdudW1iZXInKSB8fCAhdGhpcy5lZGl0Um93KCkpXG4gICAgICByZXR1cm47XG4gICAgY29uc3QgdmlzaWJsZUNvbHVtbnMgPSB0aGlzLmNvbHVtbnMuZmlsdGVyKFxuICAgICAgKGNvbCkgPT4gY29sLnZpc2libGUgIT09IGZhbHNlICYmICFjb2wucmVhZE9ubHlcbiAgICApO1xuICAgIGNvbnN0IGNvbnZlcnRlZCA9IHZpc2libGVDb2x1bW5zLnJlZHVjZSgoYWNjLCBjb2wpID0+IHtcbiAgICAgIGFjY1tjb2wuYWNjZXNzb3JdID0gdGhpcy5jb252ZXJ0Q2VsbFZhbHVlKFxuICAgICAgICB0aGlzLmVkaXRSb3coKSFbY29sLmFjY2Vzc29yXSxcbiAgICAgICAgY29sXG4gICAgICApO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgYXMgUGFydGlhbDxUPjtcblxuICAgIHRoaXMudXBkYXRlQWN0aW9uLmVtaXQoe1xuICAgICAgaWQsXG4gICAgICBjaGFuZ2VzOiBjb252ZXJ0ZWQsXG4gICAgICBkb25lOiAoc3VjY2VzczogYm9vbGVhbikgPT4ge1xuICAgICAgICBpZiAoc3VjY2Vzcykge1xuICAgICAgICAgIHRoaXMuY2FuY2VsRWRpdCgpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrQnkgZnVuY3Rpb24gZm9yIG5nRm9yIHRvIGF2b2lkIERPTSByZS1jcmVhdGlvbiAoTkcwOTU2IHdhcm5pbmcpLlxuICAgKi9cbiAgdHJhY2tCeUlkKGluZGV4OiBudW1iZXIsIHJvdzogVCk6IG51bWJlciB8IHN0cmluZyB7XG4gICAgY29uc3QgaWQgPVxuICAgICAgcm93ICYmIHR5cGVvZiByb3cgPT09ICdvYmplY3QnICYmICdpZCcgaW4gcm93XG4gICAgICAgID8gKHJvdyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbJ2lkJ11cbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHR5cGVvZiBpZCA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIGlkID09PSAnbnVtYmVyJyA/IGlkIDogaW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgdGhlIHZpZXcgZXZlbnQgd2l0aCB0aGUgZW50aXJlIHJvdyBkYXRhXG4gICAqL1xuICBvblZpZXcocm93OiBUKTogdm9pZCB7XG4gICAgdGhpcy52aWV3QWN0aW9uLmVtaXQocm93KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyB0aGUgZ2V0Um93QnV0dG9uQWN0aW9uIGV2ZW50IHdpdGggdGhlIGVudGlyZSByb3cgZGF0YVxuICAgKi9cbiAgb25HZXRSb3dCdXR0b24ocm93OiBUKTogdm9pZCB7XG4gICAgdGhpcy5nZXRSb3dCdXR0b25BY3Rpb24uZW1pdChyb3cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtaXRzIHRoZSBtb3ZlVXBBY3Rpb24gZXZlbnQgd2l0aCB0aGUgcm93IGlkXG4gICAqL1xuICBhc3luYyBvbk1vdmVVcChyb3c6IFQpIHtcbiAgICBjb25zdCBpZCA9IHJvd1snaWQnXSBhcyBJRDtcbiAgICB0aGlzLm1vdmVVcEFjdGlvbi5lbWl0KHtcbiAgICAgIGlkLFxuICAgICAgZG9uZTogKHN1Y2Nlc3M6IGJvb2xlYW4pID0+IHtcbiAgICAgICAgaWYgKHN1Y2Nlc3MpIHRoaXMuY2FuY2VsRWRpdCgpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyB0aGUgbW92ZURvd25BY3Rpb24gZXZlbnQgd2l0aCB0aGUgcm93IGlkXG4gICAqL1xuICBhc3luYyBvbk1vdmVEb3duKHJvdzogVCkge1xuICAgIGNvbnN0IGlkID0gcm93WydpZCddIGFzIElEO1xuICAgIHRoaXMubW92ZURvd25BY3Rpb24uZW1pdCh7XG4gICAgICBpZCxcbiAgICAgIGRvbmU6IChzdWNjZXNzOiBib29sZWFuKSA9PiB7XG4gICAgICAgIGlmIChzdWNjZXNzKSB0aGlzLmNhbmNlbEVkaXQoKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgdGhlIGVuYWJsZUFjdGlvbiBldmVudCB3aXRoIHRoZSByb3cgaWQgYW5kIGN1cnJlbnQgZW5hYmxlZCBzdGF0dXNcbiAgICovXG4gIGFzeW5jIG9uRW5hYmxlKHJvdzogVCkge1xuICAgIGNvbnN0IGlkID0gcm93WydpZCddIGFzIElEO1xuICAgIGNvbnN0IGN1cnJlbnRFbmFibGVkID0gcm93WydlbmFibGVkJ10gYXMgYm9vbGVhbjtcbiAgICB0aGlzLmVuYWJsZUFjdGlvbi5lbWl0KHtcbiAgICAgIGlkLFxuICAgICAgZW5hYmxlZDogIWN1cnJlbnRFbmFibGVkLCAvLyBUb2dnbGUgdGhlIGN1cnJlbnQgc3RhdGVcbiAgICAgIGRvbmU6IChzdWNjZXNzOiBib29sZWFuKSA9PiB7XG4gICAgICAgIGlmIChzdWNjZXNzKSB0aGlzLmNhbmNlbEVkaXQoKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyBzZWFyY2ggaW5wdXQgY2hhbmdlcyB3aXRoIGRlYm91bmNpbmdcbiAgICovXG4gIG9uU2VhcmNoSW5wdXQoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgY29uc3QgdmFsdWUgPSB0YXJnZXQudmFsdWU7XG4gICAgdGhpcy5zZWFyY2hWYWx1ZS5zZXQodmFsdWUpO1xuICAgIHRoaXMuc2VhcmNoVGVybS5lbWl0KHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgdGhlIHNlYXJjaCBpbnB1dFxuICAgKi9cbiAgY2xlYXJTZWFyY2goKTogdm9pZCB7XG4gICAgdGhpcy5zZWFyY2hWYWx1ZS5zZXQoJycpO1xuICAgIHRoaXMuc2VhcmNoVGVybS5lbWl0KCcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSB2YWx1ZSBmcm9tIGFuIG9iamVjdCB1c2luZyBkb3Qgbm90YXRpb24gKGUuZy4sICd0YXNrLm5hbWUnKVxuICAgKi9cbiAgcHJpdmF0ZSBnZXROZXN0ZWRWYWx1ZShvYmo6IGFueSwgYWNjZXNzb3I6IHN0cmluZyk6IHVua25vd24ge1xuICAgIHJldHVybiBhY2Nlc3Nvci5zcGxpdCgnLicpLnJlZHVjZSgoY3VycmVudCwga2V5KSA9PiB7XG4gICAgICByZXR1cm4gY3VycmVudCAmJiB0eXBlb2YgY3VycmVudCA9PT0gJ29iamVjdCcgPyBjdXJyZW50W2tleV0gOiB1bmRlZmluZWQ7XG4gICAgfSwgb2JqKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSB2YWx1ZSBmb3IgYSBjZWxsIHVzaW5nIHRoZSBhY2Nlc3Nvciwgc3VwcG9ydGluZyBkb3Qgbm90YXRpb24gZm9yIG5lc3RlZCBwcm9wZXJ0aWVzXG4gICAqL1xuICBnZXRDZWxsVmFsdWUocm93OiBULCBhY2Nlc3Nvcjogc3RyaW5nKTogdW5rbm93biB7XG4gICAgaWYgKGFjY2Vzc29yLmluY2x1ZGVzKCcuJykpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldE5lc3RlZFZhbHVlKHJvdywgYWNjZXNzb3IpO1xuICAgIH1cbiAgICByZXR1cm4gKHJvdyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbYWNjZXNzb3JdO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGRpc3BsYXkgdmFsdWUgZm9yIGEgY2VsbCwgc2hvd2luZyAnLScgZm9yIGZhbHN5IHZhbHVlcyBleGNlcHQgMCwgZmFsc2UsIGFuZCBlbXB0eSBvYmplY3RzL2FycmF5c1xuICAgKi9cbiAgZ2V0RGlzcGxheVZhbHVlKHZhbHVlOiB1bmtub3duKTogc3RyaW5nIHtcbiAgICAvLyBJZiB2YWx1ZSBpcyAwLCBzaG93IGl0XG4gICAgaWYgKHZhbHVlID09PSAwKSB7XG4gICAgICByZXR1cm4gJzAnO1xuICAgIH1cbiAgICAvLyBJZiB2YWx1ZSBpcyBmYWxzZSwgaXQgc2hvdWxkIGJlIGhhbmRsZWQgYnkgYm9vbGVhbiBsb2dpYyBpbiB0ZW1wbGF0ZSwgbm90IGhlcmVcbiAgICBpZiAodmFsdWUgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gJ2ZhbHNlJztcbiAgICB9XG4gICAgLy8gSGFuZGxlIG9iamVjdHMgYW5kIGFycmF5cyAoaW5jbHVkaW5nIGVtcHR5IG9uZXMpXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuICdbb2JqZWN0IE9iamVjdF0nO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBJZiB2YWx1ZSBpcyBvdGhlciBmYWxzeSB2YWx1ZXMgKG51bGwsIHVuZGVmaW5lZCwgJycpLCBzaG93ICctJ1xuICAgIGlmICghdmFsdWUpIHtcbiAgICAgIHJldHVybiAnLSc7XG4gICAgfVxuICAgIC8vIEhhbmRsZSBvdGhlciB0eXBlcyBleHBsaWNpdGx5XG4gICAgaWYgKFxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fFxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyB8fFxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbidcbiAgICApIHtcbiAgICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICAgIH1cbiAgICAvLyBGb3IgYW55IG90aGVyIHR5cGUgKGZ1bmN0aW9uLCBzeW1ib2wsIGV0Yy4pLCByZXR1cm4gYSBzYWZlIGZhbGxiYWNrXG4gICAgcmV0dXJuICctJztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBkaXNwbGF5IHRleHQgZm9yIGFuIGVudW0gdmFsdWVcbiAgICovXG4gIGdldEVudW1EaXNwbGF5VmFsdWUodmFsdWU6IHVua25vd24sIGNvbDogQzgwVGFibGVDb2xEZWYpOiBzdHJpbmcge1xuICAgIGlmICghY29sLmVudW0gfHwgKHZhbHVlICE9PSAwICYmICF2YWx1ZSkpIHtcbiAgICAgIHJldHVybiAnLSc7XG4gICAgfVxuICAgIGNvbnN0IGRpc3BsYXlWYWx1ZSA9IGNvbC5lbnVtW3ZhbHVlIGFzIHN0cmluZyB8IG51bWJlcl07XG4gICAgcmV0dXJuIChcbiAgICAgIGRpc3BsYXlWYWx1ZSB8fFxuICAgICAgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJ1xuICAgICAgICA/IFN0cmluZyh2YWx1ZSlcbiAgICAgICAgOiAnLScpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBlbnVtIG9wdGlvbnMgYXMgYW4gYXJyYXkgZm9yIHNlbGVjdCBkcm9wZG93bnNcbiAgICovXG4gIGdldEVudW1PcHRpb25zKFxuICAgIGNvbDogQzgwVGFibGVDb2xEZWZcbiAgKTogeyB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyOyBsYWJlbDogc3RyaW5nIH1bXSB7XG4gICAgaWYgKCFjb2wuZW51bSkgcmV0dXJuIFtdO1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhjb2wuZW51bSkubWFwKChbdmFsdWUsIGxhYmVsXSkgPT4gKHtcbiAgICAgIHZhbHVlOiBpc05hTihOdW1iZXIodmFsdWUpKSA/IHZhbHVlIDogTnVtYmVyKHZhbHVlKSxcbiAgICAgIGxhYmVsLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBDU1MgY29sb3IgZm9yIGEgY2VsbCB2YWx1ZSBiYXNlZCBvbiB0aGUgY29sdW1uJ3MgY29sb3IgY29uZmlndXJhdGlvblxuICAgKi9cbiAgZ2V0Q2VsbENvbG9yKHZhbHVlOiB1bmtub3duLCBjb2w6IEM4MFRhYmxlQ29sRGVmKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWNvbC5jb2xvciB8fCAodmFsdWUgIT09IDAgJiYgIXZhbHVlKSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIGNvbC5jb2xvclt2YWx1ZSBhcyBzdHJpbmcgfCBudW1iZXJdO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGEgZWwgbWF4LWhlaWdodCBkZSBsYSB0YWJsYSBiYXNhZG8gZW4gZWwgdGFtYcOxb1xuICAgKiBTaSBzaXplIGVzIDAsIHJldG9ybmEgdW5kZWZpbmVkIChzaW4gbMOtbWl0ZSBkZSBhbHR1cmEpXG4gICAqL1xuICBnZXRUYWJsZU1heEhlaWdodCgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh0aGlzLnNpemUgPD0gMCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDsgLy8gU2luIGzDrW1pdGUgZGUgYWx0dXJhXG4gICAgfVxuICAgIC8vIEFsdHVyYSBiYXNlIGRlIDQwMHB4ICogc2l6ZVxuICAgIGNvbnN0IGJhc2VIZWlnaHQgPSA0MDA7XG4gICAgY29uc3QgbWF4SGVpZ2h0ID0gTWF0aC5yb3VuZChiYXNlSGVpZ2h0ICogdGhpcy5zaXplKTtcbiAgICByZXR1cm4gYCR7bWF4SGVpZ2h0fXB4YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3Rpb24gbWV0aG9kc1xuICAgKi9cbiAgY2xlYXJTZWxlY3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZEl0ZW1zLnNldChuZXcgU2V0KCkpO1xuICAgIHRoaXMudXBkYXRlU2VsZWN0QWxsU3RhdGUoKTtcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYW50aWVuZSBsYSBzZWxlY2Npw7NuIGV4aXN0ZW50ZSBkZXNwdcOpcyBkZSBhY3R1YWxpemFyIGxvcyBkYXRvcyxcbiAgICogZWxpbWluYW5kbyBzb2xvIGxvcyBJRHMgcXVlIHlhIG5vIGV4aXN0ZW4gZW4gbG9zIG51ZXZvcyBkYXRvc1xuICAgKi9cbiAgcHJpdmF0ZSBwcmVzZXJ2ZVNlbGVjdGlvbigpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50U2VsZWN0aW9uID0gdGhpcy5zZWxlY3RlZEl0ZW1zKCk7XG4gICAgY29uc3QgY3VycmVudERhdGEgPSB0aGlzLmRhdGEoKTtcblxuICAgIGlmIChjdXJyZW50U2VsZWN0aW9uLnNpemUgPT09IDAgfHwgY3VycmVudERhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBTaSBubyBoYXkgc2VsZWNjacOzbiBvIG5vIGhheSBkYXRvcywgbGltcGlhciBsYSBzZWxlY2Npw7NuXG4gICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gT2J0ZW5lciBsb3MgSURzIGRpc3BvbmlibGVzIGVuIGxvcyBudWV2b3MgZGF0b3NcbiAgICBjb25zdCBhdmFpbGFibGVJZHMgPSBuZXcgU2V0KGN1cnJlbnREYXRhLm1hcChpdGVtID0+IGl0ZW1bJ2lkJ10gYXMgSUQpKTtcblxuICAgIC8vIEZpbHRyYXIgbGEgc2VsZWNjacOzbiBhY3R1YWwgcGFyYSBtYW50ZW5lciBzb2xvIGxvcyBJRHMgcXVlIGHDum4gZXhpc3RlblxuICAgIGNvbnN0IHByZXNlcnZlZFNlbGVjdGlvbiA9IG5ldyBTZXQoXG4gICAgICBBcnJheS5mcm9tKGN1cnJlbnRTZWxlY3Rpb24pLmZpbHRlcihpZCA9PiBhdmFpbGFibGVJZHMuaGFzKGlkKSlcbiAgICApO1xuXG4gICAgLy8gQWN0dWFsaXphciBsYSBzZWxlY2Npw7NuIGNvbiBsb3MgSURzIHByZXNlcnZhZG9zXG4gICAgdGhpcy5zZWxlY3RlZEl0ZW1zLnNldChwcmVzZXJ2ZWRTZWxlY3Rpb24pO1xuICAgIHRoaXMudXBkYXRlU2VsZWN0QWxsU3RhdGUoKTtcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgfVxuXG4gIHRvZ2dsZVNlbGVjdEFsbCgpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50U2VsZWN0aW9uID0gdGhpcy5zZWxlY3RlZEl0ZW1zKCk7XG4gICAgY29uc3QgYWxsSXRlbXMgPSB0aGlzLmRhdGEoKTtcblxuICAgIGlmIChjdXJyZW50U2VsZWN0aW9uLnNpemUgPT09IGFsbEl0ZW1zLmxlbmd0aCkge1xuICAgICAgLy8gRGVzZWxlY3QgYWxsXG4gICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFNlbGVjdCBhbGxcbiAgICAgIGNvbnN0IGFsbElkcyA9IG5ldyBTZXQoYWxsSXRlbXMubWFwKGl0ZW0gPT4gaXRlbVsnaWQnXSBhcyBJRCkpO1xuICAgICAgdGhpcy5zZWxlY3RlZEl0ZW1zLnNldChhbGxJZHMpO1xuICAgICAgdGhpcy51cGRhdGVTZWxlY3RBbGxTdGF0ZSgpO1xuICAgICAgdGhpcy5lbWl0U2VsZWN0aW9uKCk7XG4gICAgfVxuICB9XG5cbiAgdG9nZ2xlSXRlbVNlbGVjdGlvbihpdGVtOiBUKTogdm9pZCB7XG4gICAgY29uc3QgaWQgPSBpdGVtWydpZCddIGFzIElEO1xuICAgIGNvbnN0IGN1cnJlbnRTZWxlY3Rpb24gPSBuZXcgU2V0KHRoaXMuc2VsZWN0ZWRJdGVtcygpKTtcblxuICAgIGlmICghdGhpcy5tdWx0aXBsZSkge1xuICAgICAgLy8gU2VsZWNjacOzbiBzaW1wbGU6IHNvbG8gcGVybWl0aXIgdW4gZWxlbWVudG8gc2VsZWNjaW9uYWRvXG4gICAgICBpZiAoY3VycmVudFNlbGVjdGlvbi5oYXMoaWQpKSB7XG4gICAgICAgIC8vIERlc2VsZWNjaW9uYXIgZWwgZWxlbWVudG8gYWN0dWFsXG4gICAgICAgIGN1cnJlbnRTZWxlY3Rpb24uY2xlYXIoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFNlbGVjY2lvbmFyIHNvbG8gZXN0ZSBlbGVtZW50b1xuICAgICAgICBjdXJyZW50U2VsZWN0aW9uLmNsZWFyKCk7XG4gICAgICAgIGN1cnJlbnRTZWxlY3Rpb24uYWRkKGlkKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGN1cnJlbnRTZWxlY3Rpb24uaGFzKGlkKSkge1xuICAgICAgLy8gU2VsZWNjacOzbiBtw7psdGlwbGU6IGRlc2VsZWNjaW9uYXIgZWxlbWVudG8gZXhpc3RlbnRlXG4gICAgICBjdXJyZW50U2VsZWN0aW9uLmRlbGV0ZShpZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFNlbGVjY2nDs24gbcO6bHRpcGxlOiBhZ3JlZ2FyIG51ZXZvIGVsZW1lbnRvXG4gICAgICBjdXJyZW50U2VsZWN0aW9uLmFkZChpZCk7XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3RlZEl0ZW1zLnNldChjdXJyZW50U2VsZWN0aW9uKTtcbiAgICB0aGlzLnVwZGF0ZVNlbGVjdEFsbFN0YXRlKCk7XG4gICAgdGhpcy5lbWl0U2VsZWN0aW9uKCk7XG4gIH0gaXNJdGVtU2VsZWN0ZWQoaXRlbTogVCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGlkID0gaXRlbVsnaWQnXSBhcyBJRDtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZEl0ZW1zKCkuaGFzKGlkKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlU2VsZWN0QWxsU3RhdGUoKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0ZWRDb3VudCA9IHRoaXMuc2VsZWN0ZWRJdGVtcygpLnNpemU7XG4gICAgY29uc3QgdG90YWxDb3VudCA9IHRoaXMuZGF0YSgpLmxlbmd0aDtcblxuICAgIGlmIChzZWxlY3RlZENvdW50ID09PSAwKSB7XG4gICAgICB0aGlzLnNlbGVjdEFsbENoZWNrZWQuc2V0KGZhbHNlKTtcbiAgICAgIHRoaXMuc2VsZWN0QWxsSW5kZXRlcm1pbmF0ZS5zZXQoZmFsc2UpO1xuICAgIH0gZWxzZSBpZiAoc2VsZWN0ZWRDb3VudCA9PT0gdG90YWxDb3VudCkge1xuICAgICAgdGhpcy5zZWxlY3RBbGxDaGVja2VkLnNldCh0cnVlKTtcbiAgICAgIHRoaXMuc2VsZWN0QWxsSW5kZXRlcm1pbmF0ZS5zZXQoZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlbGVjdEFsbENoZWNrZWQuc2V0KGZhbHNlKTtcbiAgICAgIHRoaXMuc2VsZWN0QWxsSW5kZXRlcm1pbmF0ZS5zZXQodHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBlbWl0U2VsZWN0aW9uKCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGVkSWRzID0gdGhpcy5zZWxlY3RlZEl0ZW1zKCk7XG4gICAgY29uc3Qgc2VsZWN0ZWRJdGVtcyA9IHRoaXMuZGF0YSgpLmZpbHRlcihpdGVtID0+XG4gICAgICBzZWxlY3RlZElkcy5oYXMoaXRlbVsnaWQnXSBhcyBJRClcbiAgICApO1xuICAgIHRoaXMuc2VsZWN0YWJsZS5lbWl0KHNlbGVjdGVkSXRlbXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseVNvcnRpbmcoaXRlbXM6IFRbXSk6IHZvaWQge1xuICAgIGNvbnN0IG9yZGVyZWRDb2x1bW5zID0gdGhpcy5jb2x1bW5zLmZpbHRlcigoY29sKSA9PiBjb2wub3JkZXIpO1xuICAgIGlmIChvcmRlcmVkQ29sdW1ucy5sZW5ndGggPiAwKSB7XG4gICAgICBvcmRlcmVkQ29sdW1ucy5mb3JFYWNoKChjb2wpID0+IHtcbiAgICAgICAgaXRlbXMuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgIGNvbnN0IHZhbHVlQSA9IHRoaXMuZ2V0Q2VsbFZhbHVlKGEsIGNvbC5hY2Nlc3NvcikgYXMgc3RyaW5nIHwgbnVtYmVyO1xuICAgICAgICAgIGNvbnN0IHZhbHVlQiA9IHRoaXMuZ2V0Q2VsbFZhbHVlKGIsIGNvbC5hY2Nlc3NvcikgYXMgc3RyaW5nIHwgbnVtYmVyO1xuXG4gICAgICAgICAgaWYgKGNvbC5vcmRlciA9PT0gJ0FTQycpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZUEgPiB2YWx1ZUIpIHJldHVybiAxO1xuICAgICAgICAgICAgaWYgKHZhbHVlQSA8IHZhbHVlQikgcmV0dXJuIC0xO1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZUEgPCB2YWx1ZUIpIHJldHVybiAxO1xuICAgICAgICAgICAgaWYgKHZhbHVlQSA+IHZhbHVlQikgcmV0dXJuIC0xO1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInRhYmxlLXJlc3BvbnNpdmVcIiBbc3R5bGUubWF4LWhlaWdodF09XCJnZXRUYWJsZU1heEhlaWdodCgpXCIgW3N0eWxlLm92ZXJmbG93LXldPVwic2l6ZSA+IDAgPyAnYXV0bycgOiAndmlzaWJsZSdcIj5cbiAgPCEtLSBTZWFyY2ggQmFyIC0tPlxuICBAaWYgKGhhc1NlYXJjaFRlcm1MaXN0ZW5lcigpKSB7XG4gIDxkaXYgY2xhc3M9XCJzZWFyY2gtY29udGFpbmVyXCI+XG4gICAgPGRpdiBjbGFzcz1cInNlYXJjaC1pbnB1dC13cmFwcGVyXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJpbnB1dC1ncm91cC10ZXh0XCI+XG4gICAgICAgICAgPGM4MC1pY29uIGljb249XCJzZWFyY2hcIiBbc2l6ZV09XCIuOFwiPjwvYzgwLWljb24+XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgc2VhcmNoLWlucHV0XCIgcGxhY2Vob2xkZXI9XCJCdXNjYXIuLi5cIiBbdmFsdWVdPVwic2VhcmNoVmFsdWUoKVwiIChpbnB1dCk9XCJvblNlYXJjaElucHV0KCRldmVudClcIiBhcmlhLWxhYmVsPVwiQnVzY2FyIGVuIGxhIHRhYmxhXCIgLz5cbiAgICAgICAgQGlmIChzZWFyY2hWYWx1ZSgpKSB7XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtc2Vjb25kYXJ5IGJ0bi1ib3JyYXJcIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImNsZWFyU2VhcmNoKClcIiB0aXRsZT1cIkxpbXBpYXIgYsO6c3F1ZWRhXCI+XG4gICAgICAgICAgPGM4MC1pY29uIGljb249XCJjYW5jZWxcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIH1cblxuICA8dGFibGUgY2xhc3M9XCJ0YWJsZSB0YWJsZS1ib3JkZXJlZCB0YWJsZS1ob3ZlciBhbGlnbi1taWRkbGVcIj5cbiAgICA8dGhlYWQgY2xhc3M9XCJ0aGVhZCB0YWJsZS1saWdodCBzdGlja3ktaGVhZGVyXCI+XG4gICAgICA8dHI+XG4gICAgICAgIEBpZiAoaGFzU2VsZWN0YWJsZUxpc3RlbmVyKCkgJiYgZGF0YSgpLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlciBzZWxlY3Rpb24tY29sdW1uXCI+XG4gICAgICAgICAgQGlmIChtdWx0aXBsZSkge1xuICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbY2hlY2tlZF09XCJzZWxlY3RBbGxDaGVja2VkKClcIiBbaW5kZXRlcm1pbmF0ZV09XCJzZWxlY3RBbGxJbmRldGVybWluYXRlKClcIiAoY2hhbmdlKT1cInRvZ2dsZVNlbGVjdEFsbCgpXCIgYXJpYS1sYWJlbD1cIlNlbGVjY2lvbmFyIHRvZG9cIiAvPlxuICAgICAgICAgIH1cbiAgICAgICAgPC90aD5cbiAgICAgICAgfVxuICAgICAgICBAZm9yIChjb2wgb2YgY29sdW1uczsgdHJhY2sgY29sKSB7XG4gICAgICAgIEBpZiAoY29sLnZpc2libGUgIT09IGZhbHNlKSB7XG4gICAgICAgIEBpZiAoY29sLnR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlciBib29sZWFuLWNvbHVtblwiPnt7IGNvbC5sYWJlbCB9fTwvdGg+XG4gICAgICAgIH1cbiAgICAgICAgQGVsc2UgaWYgKGNvbC50eXBlID09PSAnbnVtYmVyJykge1xuICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlciBudW1iZXItY29sdW1uXCI+e3sgY29sLmxhYmVsIH19PC90aD5cbiAgICAgICAgfVxuICAgICAgICBAZWxzZSB7XG4gICAgICAgIDx0aD57eyBjb2wubGFiZWwgfX08L3RoPlxuICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGhhc0NyZWF0ZUFjdGlvbkxpc3RlbmVyKCkgfHwgaGFzVXBkYXRlQWN0aW9uTGlzdGVuZXIoKSB8fCBoYXNEZWxldGVBY3Rpb25MaXN0ZW5lcigpIHx8XG4gICAgICAgIGhhc0NhbmNlbEFjdGlvbkxpc3RlbmVyKCkgfHwgaGFzVmlld0FjdGlvbkxpc3RlbmVyKCkgfHwgaGFzR2V0Um93QnV0dG9uTGlzdGVuZXIoKSB8fFxuICAgICAgICBoYXNNb3ZlVXBBY3Rpb25MaXN0ZW5lcigpIHx8IGhhc01vdmVEb3duQWN0aW9uTGlzdGVuZXIoKSkge1xuICAgICAgICA8dGggY2xhc3M9XCJ0YWJsZS1hY3Rpb25zLWhlYWRlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb25zLXdyYXBwZXJcIj5cbiAgICAgICAgICAgIDxzcGFuPkFjdGlvbnM8L3NwYW4+XG4gICAgICAgICAgICBAaWYgKGhhc0NyZWF0ZUFjdGlvbkxpc3RlbmVyKCkpIHtcbiAgICAgICAgICAgIDxjODAtaWNvbiBidXR0b24gaWNvbj1cImFkZFwiIFtkaXNhYmxlZF09XCJjcmVhdGluZygpXCIgdGl0bGU9XCJBZ3JlZ2FyXCIgW3NpemVdPVwiLjZcIiAoaWNvbkNsaWNrKT1cInN0YXJ0Q3JlYXRlKClcIj48L2M4MC1pY29uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L3RoPlxuICAgICAgICB9XG4gICAgICA8L3RyPlxuICAgIDwvdGhlYWQ+XG4gICAgPHRib2R5PlxuICAgICAgQGZvciAocm93IG9mIGRhdGEoKTsgdHJhY2sgdHJhY2tCeUlkKGksIHJvdyk7IGxldCBpID0gJGluZGV4KSB7XG4gICAgICA8dHI+XG4gICAgICAgIEBpZiAoaGFzU2VsZWN0YWJsZUxpc3RlbmVyKCkgJiYgZGF0YSgpLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWNlbnRlciBzZWxlY3Rpb24tY29sdW1uXCI+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cImlzSXRlbVNlbGVjdGVkKHJvdylcIiAoY2hhbmdlKT1cInRvZ2dsZUl0ZW1TZWxlY3Rpb24ocm93KVwiIFthdHRyLmFyaWEtbGFiZWxdPVwiJ1NlbGVjY2lvbmFyIGZpbGEgJyArIChpICsgMSlcIiAvPlxuICAgICAgICA8L3RkPlxuICAgICAgICB9XG4gICAgICAgIEBmb3IgKGNvbCBvZiBjb2x1bW5zOyB0cmFjayBjb2wpIHtcbiAgICAgICAgQGlmIChjb2wudmlzaWJsZSAhPT0gZmFsc2UpIHtcbiAgICAgICAgQGlmIChjb2wudHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyIGJvb2xlYW4tY29sdW1uXCI+XG4gICAgICAgICAgQGlmIChlZGl0aW5nKCkgPT09IHJvd1snaWQnXSAmJiAhY29sLnJlYWRPbmx5KSB7XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cIiEhZWRpdFJvdygpPy5bY29sLmFjY2Vzc29yXVwiIChjaGFuZ2UpPVwib25FZGl0SW5wdXQoJGV2ZW50LCBjb2wuYWNjZXNzb3IsIGNvbClcIiBbYXR0ci5hcmlhLWxhYmVsXT1cImNvbC5sYWJlbFwiIC8+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBlbHNlIHtcbiAgICAgICAgICBAaWYgKGdldENlbGxWYWx1ZShyb3csIGNvbC5hY2Nlc3NvcikgPT09IHRydWUpIHtcbiAgICAgICAgICA8YzgwLWljb24gaWNvbj1cImNoZWNrXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgIDxiciAvPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSBpZiAoZ2V0Q2VsbFZhbHVlKHJvdywgY29sLmFjY2Vzc29yKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICA8YzgwLWljb24gaWNvbj1cImNhbmNlbFwiIFtzaXplXT1cIi43XCI+PC9jODAtaWNvbj5cbiAgICAgICAgICA8YnIgLz5cbiAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICA8L3RkPlxuICAgICAgICB9XG4gICAgICAgIEBlbHNlIGlmIChjb2wudHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgPHRkIGNsYXNzPVwidGV4dC1jZW50ZXIgbnVtYmVyLWNvbHVtblwiPlxuICAgICAgICAgIEBpZiAoZWRpdGluZygpID09PSByb3dbJ2lkJ10gJiYgIWNvbC5yZWFkT25seSkge1xuICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWNvbnRyb2wtc21cIiB0eXBlPVwibnVtYmVyXCIgW3ZhbHVlXT1cImVkaXRSb3coKT8uW2NvbC5hY2Nlc3Nvcl0gPz8gJydcIiBbcGxhY2Vob2xkZXJdPVwiY29sLmxhYmVsXCIgKGlucHV0KT1cIm9uRWRpdElucHV0KCRldmVudCwgY29sLmFjY2Vzc29yLCBjb2wpXCIgLz5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgIDxzcGFuIFtzdHlsZS5jb2xvcl09XCJnZXRDZWxsQ29sb3IoZ2V0Q2VsbFZhbHVlKHJvdywgY29sLmFjY2Vzc29yKSwgY29sKVwiPnt7IGdldERpc3BsYXlWYWx1ZShnZXRDZWxsVmFsdWUocm93LFxuICAgICAgICAgICAgY29sLmFjY2Vzc29yKSkgfX08L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICA8L3RkPlxuICAgICAgICB9XG4gICAgICAgIEBlbHNlIHtcbiAgICAgICAgPHRkPlxuICAgICAgICAgIEBpZiAoZWRpdGluZygpID09PSByb3dbJ2lkJ10gJiYgIWNvbC5yZWFkT25seSkge1xuICAgICAgICAgIEBpZiAoY29sLnR5cGUgPT09ICdlbnVtJykge1xuICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtXCIgW3ZhbHVlXT1cImVkaXRSb3coKT8uW2NvbC5hY2Nlc3Nvcl0gPz8gJydcIiAoY2hhbmdlKT1cIm9uRWRpdElucHV0KCRldmVudCwgY29sLmFjY2Vzc29yLCBjb2wpXCI+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+e3sgY29sLmxhYmVsIH19PC9vcHRpb24+XG4gICAgICAgICAgICBAZm9yIChvcHRpb24gb2YgZ2V0RW51bU9wdGlvbnMoY29sKTsgdHJhY2sgb3B0aW9uLnZhbHVlKSB7XG4gICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj57eyBvcHRpb24ubGFiZWwgfX08L29wdGlvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWNvbnRyb2wtc21cIiBbdHlwZV09XCJjb2wudHlwZSA9PT0gJ3Bhc3N3b3JkJyA/ICdwYXNzd29yZCcgOiAndGV4dCdcIiBbdmFsdWVdPVwiZWRpdFJvdygpPy5bY29sLmFjY2Vzc29yXSA/PyAnJ1wiIFtwbGFjZWhvbGRlcl09XCJjb2wubGFiZWxcIiAoaW5wdXQpPVwib25FZGl0SW5wdXQoJGV2ZW50LCBjb2wuYWNjZXNzb3IsIGNvbClcIiAvPlxuICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgIEBpZiAoY29sLnR5cGUgPT09ICdwYXNzd29yZCcpIHtcbiAgICAgICAgICA8c3BhbiBbc3R5bGUuY29sb3JdPVwiZ2V0Q2VsbENvbG9yKGdldENlbGxWYWx1ZShyb3csIGNvbC5hY2Nlc3NvciksIGNvbClcIj4qKioqKio8L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBlbHNlIGlmIChjb2wudHlwZSA9PT0gJ2VudW0nKSB7XG4gICAgICAgICAgPHNwYW4gW3N0eWxlLmNvbG9yXT1cImdldENlbGxDb2xvcihnZXRDZWxsVmFsdWUocm93LCBjb2wuYWNjZXNzb3IpLCBjb2wpXCI+e3tcbiAgICAgICAgICAgIGdldEVudW1EaXNwbGF5VmFsdWUoZ2V0Q2VsbFZhbHVlKHJvdywgY29sLmFjY2Vzc29yKSwgY29sKVxuICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBlbHNlIGlmIChnZXRDZWxsVmFsdWUocm93LCBjb2wuYWNjZXNzb3IpID09PSB0cnVlKSB7XG4gICAgICAgICAgPGM4MC1pY29uIGljb249XCJjaGVja1wiIFtzaXplXT1cIi43XCI+PC9jODAtaWNvbj5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGVsc2UgaWYgKGdldENlbGxWYWx1ZShyb3csIGNvbC5hY2Nlc3NvcikgPT09IGZhbHNlKSB7XG4gICAgICAgICAgPGM4MC1pY29uIGljb249XCJjYW5jZWxcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBlbHNlIHtcbiAgICAgICAgICA8c3BhbiBbc3R5bGUuY29sb3JdPVwiZ2V0Q2VsbENvbG9yKGdldENlbGxWYWx1ZShyb3csIGNvbC5hY2Nlc3NvciksIGNvbClcIj57eyBnZXREaXNwbGF5VmFsdWUoZ2V0Q2VsbFZhbHVlKHJvdyxcbiAgICAgICAgICAgIGNvbC5hY2Nlc3NvcikpIH19PC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIDwvdGQ+XG4gICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIEBpZiAoaGFzQ3JlYXRlQWN0aW9uTGlzdGVuZXIoKSB8fCBoYXNVcGRhdGVBY3Rpb25MaXN0ZW5lcigpIHx8IGhhc0RlbGV0ZUFjdGlvbkxpc3RlbmVyKCkgfHxcbiAgICAgICAgaGFzQ2FuY2VsQWN0aW9uTGlzdGVuZXIoKSB8fCBoYXNWaWV3QWN0aW9uTGlzdGVuZXIoKSB8fCBoYXNHZXRSb3dCdXR0b25MaXN0ZW5lcigpIHx8XG4gICAgICAgIGhhc01vdmVVcEFjdGlvbkxpc3RlbmVyKCkgfHwgaGFzTW92ZURvd25BY3Rpb25MaXN0ZW5lcigpKSB7XG4gICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyIGFjdGlvbnMtY2VsbFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb25zLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgQGlmIChlZGl0aW5nKCkgPT09IHJvd1snaWQnXSkge1xuICAgICAgICAgICAgPGM4MC1pY29uIGJ1dHRvbiBpY29uPVwiY2hlY2tcIiB0aXRsZT1cIkd1YXJkYXJcIiAoaWNvbkNsaWNrKT1cInNhdmVFZGl0KHJvdylcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgICA8YzgwLWljb24gYnV0dG9uIGljb249XCJjYW5jZWxcIiBjb2xvcj1cIndhcm5cIiB0aXRsZT1cIkNhbmNlbGFyXCIgKGljb25DbGljayk9XCJjYW5jZWxFZGl0KClcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAZWxzZSB7XG4gICAgICAgICAgICBAaWYgKGhhc1VwZGF0ZUFjdGlvbkxpc3RlbmVyKCkpIHtcbiAgICAgICAgICAgIDxjODAtaWNvbiBidXR0b24gaWNvbj1cImVkaXRcIiB0aXRsZT1cIkVkaXRhclwiIChpY29uQ2xpY2spPVwib25FZGl0KHJvdylcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAaWYgKGhhc0NhbmNlbEFjdGlvbkxpc3RlbmVyKCkpIHtcbiAgICAgICAgICAgIDxjODAtaWNvbiBidXR0b24gaWNvbj1cImNhbmNlbF9jaXJjbGVcIiBjb2xvcj1cInNlY29uZGFyeVwiIHRpdGxlPVwiQ2FuY2VsYXJcIiAoaWNvbkNsaWNrKT1cIm9uQ2FuY2VsKHJvdylcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAaWYgKGhhc1ZpZXdBY3Rpb25MaXN0ZW5lcigpKSB7XG4gICAgICAgICAgICA8YzgwLWljb24gYnV0dG9uIGljb249XCJ2aWV3XCIgY29sb3I9XCJwcmltYXJ5XCIgdGl0bGU9XCJWZXJcIiAoaWNvbkNsaWNrKT1cIm9uVmlldyhyb3cpXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGlmIChoYXNHZXRSb3dCdXR0b25MaXN0ZW5lcigpKSB7XG4gICAgICAgICAgICA8YzgwLWljb24gYnV0dG9uIGljb249XCJnZXRcIiBjb2xvcj1cInN1Y2Nlc3NcIiB0aXRsZT1cIlZpbmN1bGFyXCIgKGljb25DbGljayk9XCJvbkdldFJvd0J1dHRvbihyb3cpXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGlmIChoYXNNb3ZlVXBBY3Rpb25MaXN0ZW5lcigpKSB7XG4gICAgICAgICAgICA8YzgwLWljb24gYnV0dG9uIGljb249XCJhcnJvd191cFwiIGNvbG9yPVwic2Vjb25kYXJ5XCIgdGl0bGU9XCJNb3ZlciBhcnJpYmFcIiAoaWNvbkNsaWNrKT1cIm9uTW92ZVVwKHJvdylcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAaWYgKGhhc01vdmVEb3duQWN0aW9uTGlzdGVuZXIoKSkge1xuICAgICAgICAgICAgPGM4MC1pY29uIGJ1dHRvbiBpY29uPVwiYXJyb3dfZG93blwiIGNvbG9yPVwic2Vjb25kYXJ5XCIgdGl0bGU9XCJNb3ZlciBhYmFqb1wiIChpY29uQ2xpY2spPVwib25Nb3ZlRG93bihyb3cpXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGlmIChoYXNFbmFibGVBY3Rpb25MaXN0ZW5lcigpKSB7XG4gICAgICAgICAgICA8YzgwLWljb24gYnV0dG9uIFtpY29uXT1cImdldENlbGxWYWx1ZShyb3csICdlbmFibGVkJykgPyAndG9nZ2xlX29uJyA6ICd0b2dnbGVfb2ZmJ1wiIFtjb2xvcl09XCJnZXRDZWxsVmFsdWUocm93LCAnZW5hYmxlZCcpID8gJ3N1Y2Nlc3MnIDogJ3NlY29uZGFyeSdcIiBbdGl0bGVdPVwiZ2V0Q2VsbFZhbHVlKHJvdywgJ2VuYWJsZWQnKSA/ICdEZXNoYWJpbGl0YXInIDogJ0hhYmlsaXRhcidcIlxuICAgICAgICAgICAgICAoaWNvbkNsaWNrKT1cIm9uRW5hYmxlKHJvdylcIiBbc2l6ZV09XCIuN1wiPlxuICAgICAgICAgICAgPC9jODAtaWNvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBpZiAoaGFzRGVsZXRlQWN0aW9uTGlzdGVuZXIoKSkge1xuICAgICAgICAgICAgPGM4MC1pY29uIGJ1dHRvbiBpY29uPVwiZGVsZXRlXCIgY29sb3I9XCJ3YXJuXCIgdGl0bGU9XCJCb3JyYXJcIiAoaWNvbkNsaWNrKT1cIm9uRGVsZXRlKHJvdylcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvdGQ+XG4gICAgICAgIH1cbiAgICAgIDwvdHI+XG4gICAgICB9XG4gICAgICBAaWYgKGNyZWF0aW5nKCkgJiYgaGFzQ3JlYXRlQWN0aW9uTGlzdGVuZXIoKSkge1xuICAgICAgPHRyPlxuICAgICAgICBAaWYgKGhhc1NlbGVjdGFibGVMaXN0ZW5lcigpICYmIGRhdGEoKS5sZW5ndGggIT09IDApIHtcbiAgICAgICAgPHRkIGNsYXNzPVwidGV4dC1jZW50ZXIgc2VsZWN0aW9uLWNvbHVtblwiPlxuICAgICAgICAgIDwhLS0gRW1wdHkgY2VsbCBmb3IgYWxpZ25tZW50IC0tPlxuICAgICAgICA8L3RkPlxuICAgICAgICB9XG4gICAgICAgIEBmb3IgKGNvbCBvZiBjb2x1bW5zOyB0cmFjayBjb2wpIHtcbiAgICAgICAgQGlmIChjb2wudmlzaWJsZSAhPT0gZmFsc2UpIHtcbiAgICAgICAgQGlmIChjb2wudHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyXCI+XG4gICAgICAgICAgQGlmICghY29sLnJlYWRPbmx5KSB7XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cIiEhbmV3Um93KCk/Lltjb2wuYWNjZXNzb3JdXCIgKGNoYW5nZSk9XCJvbklucHV0KCRldmVudCwgY29sLmFjY2Vzc29yLCBjb2wpXCIgW2F0dHIuYXJpYS1sYWJlbF09XCJjb2wubGFiZWxcIiAvPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSB7XG4gICAgICAgICAgPCEtLSBSZWFkT25seSBib29sZWFuIGNvbHVtbiBpbiBjcmVhdGUgbW9kZSBzaG93cyBlbXB0eSAtLT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWRcIj4tPC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgPC90ZD5cbiAgICAgICAgfSBAZWxzZSBpZiAoY29sLnR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyIG51bWJlci1jb2x1bW5cIj5cbiAgICAgICAgICBAaWYgKCFjb2wucmVhZE9ubHkpIHtcbiAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtXCIgdHlwZT1cIm51bWJlclwiIFt2YWx1ZV09XCJuZXdSb3coKT8uW2NvbC5hY2Nlc3Nvcl0gPz8gJydcIiBbcGxhY2Vob2xkZXJdPVwiY29sLmxhYmVsXCIgKGlucHV0KT1cIm9uSW5wdXQoJGV2ZW50LCBjb2wuYWNjZXNzb3IsIGNvbClcIiAvPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSB7XG4gICAgICAgICAgPCEtLSBSZWFkT25seSBudW1iZXIgY29sdW1uIGluIGNyZWF0ZSBtb2RlIHNob3dzIGVtcHR5IC0tPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1tdXRlZFwiPi08L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICA8L3RkPlxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgPHRkPlxuICAgICAgICAgIEBpZiAoIWNvbC5yZWFkT25seSkge1xuICAgICAgICAgIEBpZiAoY29sLnR5cGUgPT09ICdlbnVtJykge1xuICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtXCIgW3ZhbHVlXT1cIm5ld1JvdygpPy5bY29sLmFjY2Vzc29yXSA/PyAnJ1wiIChjaGFuZ2UpPVwib25JbnB1dCgkZXZlbnQsIGNvbC5hY2Nlc3NvciwgY29sKVwiPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPnt7IGNvbC5sYWJlbCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIGdldEVudW1PcHRpb25zKGNvbCk7IHRyYWNrIG9wdGlvbi52YWx1ZSkge1xuICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+e3sgb3B0aW9uLmxhYmVsIH19PC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBlbHNlIHtcbiAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtXCIgdHlwZT1cInRleHRcIiBbdmFsdWVdPVwibmV3Um93KCk/Lltjb2wuYWNjZXNzb3JdID8/ICcnXCIgW3BsYWNlaG9sZGVyXT1cImNvbC5sYWJlbFwiIChpbnB1dCk9XCJvbklucHV0KCRldmVudCwgY29sLmFjY2Vzc29yLCBjb2wpXCIgLz5cbiAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIEBlbHNlIHtcbiAgICAgICAgICA8IS0tIFJlYWRPbmx5IGNvbHVtbiBpbiBjcmVhdGUgbW9kZSBzaG93cyBlbXB0eSAtLT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWRcIj4tPC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgPC90ZD5cbiAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgPHRkIGNsYXNzPVwidGV4dC1jZW50ZXIgYWN0aW9ucy1jZWxsXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbnMtY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8YzgwLWljb24gYnV0dG9uIGljb249XCJjaGVja1wiIHRpdGxlPVwiR3VhcmRhclwiIChpY29uQ2xpY2spPVwic2F2ZUNyZWF0ZSgpXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgICAgPGM4MC1pY29uIGJ1dHRvbiBpY29uPVwiY2FuY2VsXCIgY29sb3I9XCJ3YXJuXCIgdGl0bGU9XCJDYW5jZWxhclwiIChpY29uQ2xpY2spPVwiY2FuY2VsQ3JlYXRlKClcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L3RyPlxuICAgICAgfVxuICAgIDwvdGJvZHk+XG4gIDwvdGFibGU+XG4gIEBpZiAoZGF0YSgpLmxlbmd0aCA9PT0gMCAmJiAhY3JlYXRpbmcoKSkge1xuICA8ZGl2IGNsYXNzPVwidGV4dC1jZW50ZXIgdGV4dC1tdXRlZCBweS0zIHNtYWxsXCI+XG4gICAgTm8gaGF5IGRhdG9zIHBhcmEgbW9zdHJhci5cbiAgPC9kaXY+XG4gIH1cbjwvZGl2PlxuXG48YzgwLW1vZGFsPjwvYzgwLW1vZGFsPiJdfQ==
792
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy91aS9zcmMvbGliL3RhYmxlL3RhYmxlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL2xpYnMvdWkvc3JjL2xpYi90YWJsZS90YWJsZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sTUFBTSxFQUNOLFlBQVksRUFHWixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFlBQVksRUFBRSxNQUFNLFVBQVUsQ0FBQzs7QUFrQjNEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0NHLENBUUgsTUFBTSxPQUFPLGlCQUFpQjtJQUNYLFlBQVksR0FBaUIsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQzFELEtBQUssQ0FBbUI7SUFDeEIsT0FBTyxHQUFxQixFQUFFLENBQUM7SUFDL0IsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLDZEQUE2RDtJQUN2RSxRQUFRLEdBQUcsSUFBSSxDQUFDLENBQUMseUNBQXlDO0lBRW5FLFNBQVMsR0FBRyxLQUFLLENBQUMsQ0FBQyxnREFBZ0Q7SUFDekQsWUFBWSxHQUFHLElBQUksWUFBWSxFQUF5RCxDQUFDO0lBQ3pGLFlBQVksR0FBRyxJQUFJLFlBQVksRUFBcUUsQ0FBQztJQUNyRyxZQUFZLEdBQUcsSUFBSSxZQUFZLEVBQWdELENBQUM7SUFDaEYsWUFBWSxHQUFHLElBQUksWUFBWSxFQUFnRCxDQUFDO0lBQ2hGLFVBQVUsR0FBRyxJQUFJLFlBQVksRUFBSyxDQUFDO0lBQ25DLGtCQUFrQixHQUFHLElBQUksWUFBWSxFQUFLLENBQUM7SUFDM0MsWUFBWSxH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RSxTQUFTLEVBQUUsQ0FBQyxLQUF1QixFQUFFLEVBQUUsQ0FBQyxLQUFLLEtBQUssRUFBRSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxLQUFLLE1BQU0sRUFBRTtnQkFFM0YsWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFlBQVk7c0JBQXJCLE1BQU07Z0JBQ0csWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNO2dCQUNHLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLGNBQWM7c0JBQXZCLE1BQU07Z0JBQ0csWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNO2dCQUVHLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE91dHB1dCxcbiAgc2lnbmFsLFxuICBFdmVudEVtaXR0ZXIsXG4gIE9uSW5pdCxcbiAgT25EZXN0cm95LFxuICBpbmplY3QsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBDODBJY29uQ29tcG9uZW50IH0gZnJvbSAnLi4vaWNvbi9pY29uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDODBNb2RhbENvbXBvbmVudCwgTW9kYWxTZXJ2aWNlIH0gZnJvbSAnLi4vbW9kYWwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEM4MFRhYmxlQ29sRGVmIHtcbiAgYWNjZXNzb3I6IHN0cmluZztcbiAgbGFiZWw6IHN0cmluZztcbiAgdmlzaWJsZT86IGJvb2xlYW47IC8vIFNpIG5vIHNlIGVzcGVjaWZpY2EsIHNlIGFzdW1lIHRydWUuIFNpIGVzIGZhbHNlLCBsYSBjb2x1bW5hIHNlIG9jdWx0YSBTSUVNUFJFIChtw6F4aW1hIHByaW9yaWRhZClcbiAgdHlwZT86ICdzdHJpbmcnIHwgJ251bWJlcicgfCAnYm9vbGVhbicgfCAncGFzc3dvcmQnIHwgJ2VudW0nOyAvLyBUaXBvIGRlIGRhdG8gcGFyYSBsYSBjb2x1bW5hXG4gIG9yZGVyPzogJ0FTQycgfCAnREVTQyc7IC8vIE9yZGVuYW1pZW50byBkZSBsYSBjb2x1bW5hXG4gIHJlYWRPbmx5PzogYm9vbGVhbjsgLy8gU2kgbm8gc2UgZXNwZWNpZmljYSwgc2UgYXN1bWUgZmFsc2VcbiAgZW51bT86IFJlY29yZDxzdHJpbmcgfCBudW1iZXIsIHN0cmluZz47IC8vIE9wY2lvbmVzIGRlbCBlbnVtIHBhcmEgdHlwZSAnZW51bSdcbiAgY29sb3I/OiBSZWNvcmQ8c3RyaW5nIHwgbnVtYmVyLCBzdHJpbmc+OyAvLyBDb2xvcmVzIENTUyBiYXNhZG9zIGVuIGVsIHZhbG9yIGRlIGxhIGNlbGRhXG4gIGhpZGVJZkFsbFZhbHVlc0FyZU51bGw/OiBib29sZWFuOyAvLyBTaSBlcyB0cnVlLCBvY3VsdGEgbGEgY29sdW1uYSBjdWFuZG8gdG9kb3MgbG9zIHZhbG9yZXMgZXN0w6FuIHZhY8Otb3MgKGRlZmF1bHQ6IGZhbHNlKS5cbiAgLy8gU29sbyBhcGxpY2Egc2kgdmlzaWJsZSAhPT0gZmFsc2UuIEVYQ0VQQ0nDk046IEVuIG1vZG8gY3JlYWNpw7NuIFkgZWRpY2nDs24gc2llbXByZSBzZSBtdWVzdHJhLlxuICBkZWZhdWx0PzogdW5rbm93bjsgLy8gVmFsb3IgcG9yIGRlZmVjdG8gcGFyYSB1c2FyIGVuIG1vZG8gY3JlYWNpw7NuLiBQdWVkZSBzZXIgc3RyaW5nLCBudW1iZXIsIGJvb2xlYW4sIGV0Yy5cbn1cblxuZXhwb3J0IHR5cGUgSUQgPSBudW1iZXIgfCBzdHJpbmc7XG5cbi8qKlxuICogQzgwVGFibGVDb21wb25lbnQgLSBDb21wb25lbnRlIGRlIHRhYmxhIGF2YW56YWRvIGNvbiBmdW5jaW9uYWxpZGFkZXMgQ1JVRFxuICpcbiAqIENPTVBPUlRBTUlFTlRPIERFIFZJU0lCSUxJREFEIERFIENPTFVNTkFTOlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICpcbiAqIDEuIFBSSU9SSURBRCBNw4FYSU1BIC0gdmlzaWJsZTogZmFsc2VcbiAqICAgIC0gTGEgY29sdW1uYSBzZSBvY3VsdGEgU0lFTVBSRSwgc2luIGV4Y2VwY2lvbmVzXG4gKiAgICAtIE5pIGVuIG1vZG8gY3JlYWNpw7NuIG5pIGVuIG1vZG8gZWRpY2nDs24gc2UgbXVlc3RyYVxuICpcbiAqIDIuIE9DVUxUQUNJw5NOIEFVVE9Nw4FUSUNBIC0gaGlkZUlmQWxsVmFsdWVzQXJlTnVsbDogdHJ1ZVxuICogICAgLSBMYSBjb2x1bW5hIHNlIG9jdWx0YSBzb2xvIHNpIFRPRE9TIGxvcyB2YWxvcmVzIGFjdHVhbGVzIGVzdMOhbiB2YWPDrW9zXG4gKiAgICAtIFZhbG9yZXMgY29uc2lkZXJhZG9zIHZhY8Otb3M6IG51bGwsIHVuZGVmaW5lZCwgJycsIFtdLCB7fVxuICogICAgLSBWYWxvcmVzIE5PIHZhY8Otb3M6IDAsIGZhbHNlIChzb24gdmFsb3JlcyB2w6FsaWRvcylcbiAqICAgIC0gRVhDRVBDSU9ORVMgSU1QT1JUQU5URVM6XG4gKiAgICAgICogRW4gbW9kbyBjcmVhY2nDs24gKGNyZWF0aW5nPXRydWUpIGVzdGFzIGNvbHVtbmFzIFPDjSBzZSBtdWVzdHJhblxuICogICAgICAqIEVuIG1vZG8gZWRpY2nDs24gZGUgdW5hIGZpbGEgZXNwZWPDrWZpY2EgdGFtYmnDqW4gc2UgbXVlc3RyYW5cbiAqXG4gKiAzLiBQT1IgREVGRUNUTyAtIENvbHVtbmFzIG5vcm1hbGVzXG4gKiAgICAtIFNlIG11ZXN0cmFuIHNpZW1wcmUgKHZpc3VhbGl6YWNpw7NuLCBjcmVhY2nDs24geSBlZGljacOzbilcbiAqXG4gKiBWQUxPUkVTIFBPUiBERUZFQ1RPIEVOIENSRUFDScOTTjpcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqXG4gKiAtIFByb3BpZWRhZCBgZGVmYXVsdD86IHVua25vd25gIHBlcm1pdGUgZGVmaW5pciB2YWxvcmVzIHBvciBkZWZlY3RvIHBhcmEgbW9kbyBjcmVhY2nDs25cbiAqIC0gU29sbyBzZSBhcGxpY2EgY3VhbmRvIHNlIGluaWNpYSBlbCBtb2RvIGNyZWFjacOzbiAoc3RhcnRDcmVhdGUpXG4gKiAtIFB1ZWRlIHNlciBjdWFscXVpZXIgdGlwbzogc3RyaW5nLCBudW1iZXIsIGJvb2xlYW4sIGV0Yy5cbiAqIC0gU2kgbm8gc2UgZXNwZWNpZmljYSBgZGVmYXVsdGAsIHNlIHVzYSBjYWRlbmEgdmFjw61hICgnJylcbiAqXG4gKiBFSkVNUExPUzpcbiAqIC0geyBhY2Nlc3NvcjogJ2lkJywgdmlzaWJsZTogZmFsc2UgfSDihpIgTlVOQ0Egc2UgbXVlc3RyYVxuICogLSB7IGFjY2Vzc29yOiAnbW90b3JQb3MnLCBoaWRlSWZBbGxWYWx1ZXNBcmVOdWxsOiB0cnVlLCBkZWZhdWx0OiAwIH0g4oaSIFNlIGF1dG9yZWxsZW5hIGNvbiAwIGVuIGNyZWFjacOzblxuICogLSB7IGFjY2Vzc29yOiAnc3RhdHVzJywgZGVmYXVsdDogJ2FjdGl2ZScgfSDihpIgU2UgYXV0b3JlbGxlbmEgY29uICdhY3RpdmUnIGVuIGNyZWFjacOzblxuICogLSB7IGFjY2Vzc29yOiAnbmFtZScgfSDihpIgU2llbXByZSB2aXNpYmxlLCBzaW4gdmFsb3IgcG9yIGRlZmVjdG8gKGNhZGVuYSB2YWPDrWEpXG4gKi9AQ29tcG9uZW50KHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9jb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdjODAtdGFibGUnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQzgwSWNvbkNvbXBvbmVudCwgQzgwTW9kYWxDb21wb25lbnRdLFxuICB0ZW1wbGF0ZVVybDogJy4vdGFibGUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vdGFibGUuY29tcG9uZW50LnNjc3MnLFxufSlcbmV4cG9ydCBjbGFzcyBDODBUYWJsZUNvbXBvbmVudDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIHJlYWRvbmx5IG1vZGFsU2VydmljZTogTW9kYWxTZXJ2aWNlID0gaW5qZWN0KE1vZGFsU2VydmljZSk7XG4gIEBJbnB1dCgpIGRhdGEkITogT2JzZXJ2YWJsZTxUW10+O1xuICBASW5wdXQoKSBjb2x1bW5zOiBDODBUYWJsZUNvbERlZltdID0gW107XG4gIEBJbnB1dCgpIHNpemUgPSAwOyAvLyBUYW1hw7FvIGRlIGxhIHRhYmxhICgwID0gc2luIGzDrW1pdGUsID4gMCBhcGxpY2EgbWF4LWhlaWdodClcbiAgQElucHV0KCkgbXVsdGlwbGUgPSB0cnVlOyAvLyBQZXJtaXRlIHNlbGVjY2nDs24gbcO6bHRpcGxlIHBvciBkZWZlY3RvXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogKHZhbHVlOiBib29sZWFuIHwgc3RyaW5nKSA9PiB2YWx1ZSA9PT0gJycgfHwgdmFsdWUgPT09IHRydWUgfHwgdmFsdWUgPT09ICd0cnVlJyB9KVxuICBub0NvbmZpcm0gPSBmYWxzZTsgLy8gU2kgZXMgdHJ1ZSwgbm8gbXVlc3RyYSBjb25maXJtYWNpb25lcyBtb2RhbGVzXG4gIEBPdXRwdXQoKSBjcmVhdGVBY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHsgcm93OiBQYXJ0aWFsPFQ+OyBkb25lOiAocmVzdWx0OiBib29sZWFuKSA9PiB2b2lkOyB9PigpO1xuICBAT3V0cHV0KCkgdXBkYXRlQWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBJRDsgY2hhbmdlczogUGFydGlhbDxUPjsgZG9uZTogKHJlc3VsdDogYm9vbGVhbikgPT4gdm9pZDsgfT4oKTtcbiAgQE91dHB1dCgpIGRlbGV0ZUFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBpZDogSUQ7IGRvbmU6IChyZXN1bHQ6IGJvb2xlYW4pID0+IHZvaWQ7IH0+KCk7XG4gIEBPdXRwdXQoKSBjYW5jZWxBY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHsgaWQ6IElEOyBkb25lOiAocmVzdWx0OiBib29sZWFuKSA9PiB2b2lkOyB9PigpO1xuICBAT3V0cHV0KCkgdmlld0FjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8VD4oKTtcbiAgQE91dHB1dCgpIGdldFJvd0J1dHRvbkFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8VD4oKTtcbiAgQE91dHB1dCgpIG1vdmVVcEFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBpZDogSUQ7IGRvbmU6IChyZXN1bHQ6IGJvb2xlYW4pID0+IHZvaWQ7IH0+KCk7XG4gIEBPdXRwdXQoKSBtb3ZlRG93bkFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBpZDogSUQ7IGRvbmU6IChyZXN1bHQ6IGJvb2xlYW4pID0+IHZvaWQ7IH0+KCk7XG4gIEBPdXRwdXQoKSBlbmFibGVBY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHsgaWQ6IElEOyBlbmFibGVkOiBib29sZWFuOyBkb25lOiAocmVzdWx0OiBib29sZWFuKSA9PiB2b2lkOyB9PigpO1xuICBAT3V0cHV0KCkgc2VhcmNoVGVybSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIEBPdXRwdXQoKSBlcnJvckV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIEBPdXRwdXQoKSBzZWxlY3RhYmxlID0gbmV3IEV2ZW50RW1pdHRlcjxUW10+KCk7XG5cbiAgcmVhZG9ubHkgZGF0YSA9IHNpZ25hbDxUW10+KFtdKTtcbiAgcmVhZG9ubHkga2V5cyA9IHNpZ25hbDxzdHJpbmdbXT4oW10pO1xuICBjcmVhdGluZyA9IHNpZ25hbChmYWxzZSk7XG4gIG5ld1JvdyA9IHNpZ25hbDxQYXJ0aWFsPFQ+IHwgbnVsbD4obnVsbCk7XG4gIHJlYWRvbmx5IGVkaXRpbmcgPSBzaWduYWw8SUQgfCBudWxsPihudWxsKTsgLy8gaWQgb2Ygcm93IGJlaW5nIGVkaXRlZFxuICByZWFkb25seSBlZGl0Um93ID0gc2lnbmFsPFBhcnRpYWw8VD4gfCBudWxsPihudWxsKTtcbiAgcmVhZG9ubHkgc2VsZWN0ZWRJdGVtcyA9IHNpZ25hbDxTZXQ8SUQ+PihuZXcgU2V0KCkpO1xuICByZWFkb25seSBzZWxlY3RBbGxDaGVja2VkID0gc2lnbmFsKGZhbHNlKTtcbiAgcmVhZG9ubHkgc2VsZWN0QWxsSW5kZXRlcm1pbmF0ZSA9IHNpZ25hbChmYWxzZSk7XG4gIHJlYWRvbmx5IHNlYXJjaFZhbHVlID0gc2lnbmFsPHN0cmluZz4oJycpO1xuXG4gIC8vIEZsYWdzIHRvIGNoZWNrIGlmIGV2ZW50cyBoYXZlIGxpc3RlbmVyc1xuICByZWFkb25seSBoYXNDcmVhdGVBY3Rpb25MaXN0ZW5lciA9IHNpZ25hbChmYWxzZSk7XG4gIHJlYWRvbmx5IGhhc1VwZGF0ZUFjdGlvbkxpc3RlbmVyID0gc2lnbmFsKGZhbHNlKTtcbiAgcmVhZG9ubHkgaGFzRGVsZXRlQWN0aW9uTGlzdGVuZXIgPSBzaWduYWwoZmFsc2UpO1xuICByZWFkb25seSBoYXNDYW5jZWxBY3Rpb25MaXN0ZW5lciA9IHNpZ25hbChmYWxzZSk7XG4gIHJlYWRvbmx5IGhhc1ZpZXdBY3Rpb25MaXN0ZW5lciA9IHNpZ25hbChmYWxzZSk7XG4gIHJlYWRvbmx5IGhhc0dldFJvd0J1dHRvbkxpc3RlbmVyID0gc2lnbmFsKGZhbHNlKTtcbiAgcmVhZG9ubHkgaGFzTW92ZVVwQWN0aW9uTGlzdGVuZXIgPSBzaWduYWwoZmFsc2UpO1xuICByZWFkb25seSBoYXNNb3ZlRG93bkFjdGlvbkxpc3RlbmVyID0gc2lnbmFsKGZhbHNlKTtcbiAgcmVhZG9ubHkgaGFzRW5hYmxlQWN0aW9uTGlzdGVuZXIgPSBzaWduYWwoZmFsc2UpO1xuICByZWFkb25seSBoYXNTZWFyY2hUZXJtTGlzdGVuZXIgPSBzaWduYWwoZmFsc2UpO1xuICByZWFkb25seSBoYXNTZWxlY3RhYmxlTGlzdGVuZXIgPSBzaWduYWwoZmFsc2UpO1xuXG4gIHByaXZhdGUgZGF0YVN1Yj86IFN1YnNjcmlwdGlvbjtcblxuICBwcml2YXRlIGdldEVycm9yTWVzc2FnZShlcnI6IHVua25vd24pOiBzdHJpbmcge1xuICAgIHJldHVybiAoZXJyIGFzIGFueSk/Lm1lc3NhZ2UgfHwgJ0Vycm9yIGFsIGNhcmdhciBkYXRvcyc7XG4gIH1cblxuICAvKipcbiAgICogQWN0dWFsaXphIGxhcyBrZXlzIGRlIGNvbHVtbmFzIHZpc2libGVzIGJhc8OhbmRvc2UgZW4gZWwgZXN0YWRvIGFjdHVhbFxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVWaXNpYmxlS2V5cygpOiB2b2lkIHtcbiAgICBjb25zdCB2aXNpYmxlQ29sdW1ucyA9IHRoaXMuY29sdW1ucy5maWx0ZXIoY29sID0+IHRoaXMuaXNDb2x1bW5WaXNpYmxlSW5IZWFkZXIoY29sKSk7XG4gICAgdGhpcy5rZXlzLnNldCh2aXNpYmxlQ29sdW1ucy5tYXAoKGNvbCkgPT4gY29sLmFjY2Vzc29yKSk7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICAvLyBDaGVjayBpZiB0aGUgb3V0cHV0cyBoYXZlIGxpc3RlbmVyc1xuICAgIHRoaXMuaGFzQ3JlYXRlQWN0aW9uTGlzdGVuZXIuc2V0KHRoaXMuY3JlYXRlQWN0aW9uLm9ic2VydmVkKTtcbiAgICB0aGlzLmhhc1VwZGF0ZUFjdGlvbkxpc3RlbmVyLnNldCh0aGlzLnVwZGF0ZUFjdGlvbi5vYnNlcnZlZCk7XG4gICAgdGhpcy5oYXNEZWxldGVBY3Rpb25MaXN0ZW5lci5zZXQodGhpcy5kZWxldGVBY3Rpb24ub2JzZXJ2ZWQpO1xuICAgIHRoaXMuaGFzQ2FuY2VsQWN0aW9uTGlzdGVuZXIuc2V0KHRoaXMuY2FuY2VsQWN0aW9uLm9ic2VydmVkKTtcbiAgICB0aGlzLmhhc1ZpZXdBY3Rpb25MaXN0ZW5lci5zZXQodGhpcy52aWV3QWN0aW9uLm9ic2VydmVkKTtcbiAgICB0aGlzLmhhc0dldFJvd0J1dHRvbkxpc3RlbmVyLnNldCh0aGlzLmdldFJvd0J1dHRvbkFjdGlvbi5vYnNlcnZlZCk7XG4gICAgdGhpcy5oYXNNb3ZlVXBBY3Rpb25MaXN0ZW5lci5zZXQodGhpcy5tb3ZlVXBBY3Rpb24ub2JzZXJ2ZWQpO1xuICAgIHRoaXMuaGFzTW92ZURvd25BY3Rpb25MaXN0ZW5lci5zZXQodGhpcy5tb3ZlRG93bkFjdGlvbi5vYnNlcnZlZCk7XG4gICAgdGhpcy5oYXNFbmFibGVBY3Rpb25MaXN0ZW5lci5zZXQodGhpcy5lbmFibGVBY3Rpb24ub2JzZXJ2ZWQpO1xuICAgIHRoaXMuaGFzU2VhcmNoVGVybUxpc3RlbmVyLnNldCh0aGlzLnNlYXJjaFRlcm0ub2JzZXJ2ZWQpO1xuICAgIHRoaXMuaGFzU2VsZWN0YWJsZUxpc3RlbmVyLnNldCh0aGlzLnNlbGVjdGFibGUub2JzZXJ2ZWQpO1xuXG4gICAgaWYgKCF0aGlzLmRhdGEkKSByZXR1cm47XG4gICAgdGhpcy5kYXRhU3ViID0gdGhpcy5kYXRhJC5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKGl0ZW1zKSA9PiB7XG4gICAgICAgIHRoaXMuYXBwbHlTb3J0aW5nKGl0ZW1zKTtcbiAgICAgICAgdGhpcy5kYXRhLnNldChpdGVtcyk7XG4gICAgICAgIC8vIEFjdHVhbGl6YXIgbGFzIGNvbHVtbmFzIHZpc2libGVzIGJhc8OhbmRvc2UgZW4gZWwgZXN0YWRvIGFjdHVhbFxuICAgICAgICB0aGlzLnVwZGF0ZVZpc2libGVLZXlzKCk7XG4gICAgICAgIC8vIE1hbnRlbmVyIGxhIHNlbGVjY2nDs24gZXhpc3RlbnRlIGRlc3B1w6lzIGRlIGFjdHVhbGl6YXIgbG9zIGRhdG9zXG4gICAgICAgIHRoaXMucHJlc2VydmVTZWxlY3Rpb24oKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKGVycjogYW55KSA9PlxuICAgICAgICB0aGlzLmVycm9yRXZlbnQuZW1pdCh0aGlzLmdldEVycm9yTWVzc2FnZShlcnIpKSxcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuZGF0YVN1Yj8udW5zdWJzY3JpYmUoKTtcblxuICAgIC8vIENsb3NlIGFueSBvcGVuIG1vZGFsIHdoZW4gY29tcG9uZW50IGlzIGRlc3Ryb3llZFxuICAgIHRoaXMubW9kYWxTZXJ2aWNlLmNsb3NlTW9kYWwoKTtcbiAgfVxuXG4gIG9uSW5wdXQoZXZlbnQ6IEV2ZW50LCBrZXk6IHN0cmluZywgY29sPzogQzgwVGFibGVDb2xEZWYpIHtcbiAgICBpZiAoY29sPy50eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgIGNvbnN0IGNoZWNrZWQgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLmNoZWNrZWQ7XG4gICAgICB0aGlzLnVwZGF0ZU5ld1JvdyhrZXksIGNoZWNrZWQpO1xuICAgIH0gZWxzZSBpZiAoY29sPy50eXBlID09PSAnZW51bScpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MU2VsZWN0RWxlbWVudCkudmFsdWU7XG4gICAgICB0aGlzLnVwZGF0ZU5ld1JvdyhrZXksIHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgICBpZiAodGFyZ2V0ICYmIHR5cGVvZiB0YXJnZXQudmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMudXBkYXRlTmV3Um93KGtleSwgdGFyZ2V0LnZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBhc3luYyBvbkRlbGV0ZShyb3c6IFQpIHtcbiAgICBjb25zdCBpZCA9IHJvd1snaWQnXSBhcyBJRDtcblxuICAgIGxldCBjb25maXJtZWQgPSB0cnVlO1xuICAgIGlmICghdGhpcy5ub0NvbmZpcm0pIHtcbiAgICAgIGNvbmZpcm1lZCA9IGF3YWl0IHRoaXMubW9kYWxTZXJ2aWNlLmNvbmZpcm0oXG4gICAgICAgICdDb25maXJtYXIgZWxpbWluYWNpw7NuJyxcbiAgICAgICAgJ8K/RXN0w6Egc2VndXJvIGRlIHF1ZSBkZXNlYSBlbGltaW5hciBlc3RlIGVsZW1lbnRvPyBFc3RhIGFjY2nDs24gbm8gc2UgcHVlZGUgZGVzaGFjZXIuJyxcbiAgICAgICAgJ0VsaW1pbmFyJyxcbiAgICAgICAgJ0NhbmNlbGFyJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoY29uZmlybWVkKSB7XG4gICAgICB0aGlzLmRlbGV0ZUFjdGlvbi5lbWl0KHtcbiAgICAgICAgaWQsXG4gICAgICAgIGRvbmU6IChzdWNjZXNzOiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgaWYgKHN1Y2Nlc3MpIHRoaXMuY2FuY2VsRWRpdCgpO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgb25DYW5jZWwocm93OiBUKSB7XG4gICAgY29uc3QgaWQgPSByb3dbJ2lkJ10gYXMgSUQ7XG5cbiAgICBsZXQgY29uZmlybWVkID0gdHJ1ZTtcbiAgICBpZiAoIXRoaXMubm9Db25maXJtKSB7XG4gICAgICBjb25maXJtZWQgPSBhd2FpdCB0aGlzLm1vZGFsU2VydmljZS5jb25maXJtKFxuICAgICAgICAnQ29uZmlybWFyIGNhbmNlbGFjacOzbicsXG4gICAgICAgICfCv0VzdMOhIHNlZ3VybyBkZSBxdWUgZGVzZWEgY2FuY2VsYXIgZXN0ZSBlbGVtZW50bz8nLFxuICAgICAgICAnQ2FuY2VsYXIgZWxlbWVudG8nLFxuICAgICAgICAnTm8gY2FuY2VsYXInXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChjb25maXJtZWQpIHtcbiAgICAgIHRoaXMuY2FuY2VsQWN0aW9uLmVtaXQoe1xuICAgICAgICBpZCxcbiAgICAgICAgZG9uZTogKHN1Y2Nlc3M6IGJvb2xlYW4pID0+IHtcbiAgICAgICAgICBpZiAoc3VjY2VzcykgdGhpcy5jYW5jZWxFZGl0KCk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBzdGFydENyZWF0ZSgpIHtcbiAgICB0aGlzLmNyZWF0aW5nLnNldCh0cnVlKTtcbiAgICAvLyBBY3R1YWxpemFyIGtleXMgZGUgY29sdW1uYXMgdmlzaWJsZXMgY3VhbmRvIGVudHJhbW9zIGVuIG1vZG8gY3JlYWNpw7NuXG4gICAgdGhpcy51cGRhdGVWaXNpYmxlS2V5cygpO1xuICAgIC8vIEluaWNpYWxpemEgbmV3Um93IHNvbG8gY29uIGNvbHVtbmFzIHZpc2libGVzIHkgbm8gcmVhZE9ubHlcbiAgICAvLyBFbiBtb2RvIGNyZWFjacOzbiwgbW9zdHJhbW9zIGNvbHVtbmFzIGNvbiBoaWRlSWZBbGxWYWx1ZXNBcmVOdWxsIHBhcmEgcGVybWl0aXIgZW50cmFkYSBkZSBkYXRvc1xuICAgIGNvbnN0IHJvdzogUGFydGlhbDxUPiA9IHt9O1xuICAgIHRoaXMuY29sdW1uc1xuICAgICAgLmZpbHRlcigoY29sKSA9PiB0aGlzLmlzQ29sdW1uVmlzaWJsZShjb2wsIHRydWUpICYmICFjb2wucmVhZE9ubHkpXG4gICAgICAuZm9yRWFjaCgoY29sKSA9PiB7XG4gICAgICAgIC8vIFNpIGxhIGNvbHVtbmEgdGllbmUgdW4gdmFsb3IgcG9yIGRlZmVjdG8sIHVzYXJsbzsgc2kgbm8sIHVzYXIgY2FkZW5hIHZhY8OtYVxuICAgICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBjb2wuZGVmYXVsdCAhPT0gdW5kZWZpbmVkID8gY29sLmRlZmF1bHQgOiAnJztcbiAgICAgICAgKHJvdyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbY29sLmFjY2Vzc29yXSA9IGRlZmF1bHRWYWx1ZTtcbiAgICAgIH0pO1xuICAgIHRoaXMubmV3Um93LnNldChyb3cpO1xuICB9XG5cbiAgY2FuY2VsQ3JlYXRlKCkge1xuICAgIHRoaXMuY3JlYXRpbmcuc2V0KGZhbHNlKTtcbiAgICB0aGlzLm5ld1Jvdy5zZXQobnVsbCk7XG4gICAgLy8gQWN0dWFsaXphciBrZXlzIGRlIGNvbHVtbmFzIHZpc2libGVzIGN1YW5kbyBzYWxpbW9zIGRlbCBtb2RvIGNyZWFjacOzblxuICAgIHRoaXMudXBkYXRlVmlzaWJsZUtleXMoKTtcbiAgfVxuXG4gIHVwZGF0ZU5ld1JvdyhrZXk6IHN0cmluZywgdmFsdWU6IHVua25vd24pIHtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5uZXdSb3coKTtcbiAgICBpZiAoIWN1cnJlbnQpIHJldHVybjtcbiAgICB0aGlzLm5ld1Jvdy5zZXQoeyAuLi5jdXJyZW50LCBba2V5XTogdmFsdWUgfSk7XG4gIH1cblxuICBzYXZlQ3JlYXRlKCkge1xuICAgIGNvbnN0IHJvdyA9IHRoaXMubmV3Um93KCk7XG4gICAgaWYgKCFyb3cpIHJldHVybjtcblxuICAgIC8vIFZhbGlkYXIgY2FtcG9zIHJlcXVlcmlkb3MgYW50ZXMgZGUgY3JlYXIgLSBzb2xvIGNvbHVtbmFzIHZpc2libGVzIHkgbm8gcmVhZE9ubHlcbiAgICAvLyBFbiBtb2RvIGNyZWFjacOzbiwgaW5jbHVpbW9zIGNvbHVtbmFzIGNvbiBoaWRlSWZBbGxWYWx1ZXNBcmVOdWxsXG4gICAgY29uc3QgdmlzaWJsZUNvbHVtbnMgPSB0aGlzLmNvbHVtbnMuZmlsdGVyKChjb2wpID0+IHRoaXMuaXNDb2x1bW5WaXNpYmxlKGNvbCwgdHJ1ZSkgJiYgIWNvbC5yZWFkT25seSk7XG4gICAgY29uc3QgY29udmVydGVkID0gdmlzaWJsZUNvbHVtbnMucmVkdWNlKChhY2MsIGNvbCkgPT4ge1xuICAgICAgYWNjW2NvbC5hY2Nlc3Nvcl0gPSB0aGlzLmNvbnZlcnRDZWxsVmFsdWUocm93W2NvbC5hY2Nlc3Nvcl0sIGNvbCk7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSBhcyBQYXJ0aWFsPFQ+O1xuXG4gICAgdGhpcy5jcmVhdGVBY3Rpb24uZW1pdCh7XG4gICAgICByb3c6IGNvbnZlcnRlZCxcbiAgICAgIGRvbmU6IChzdWNjZXNzOiBib29sZWFuKSA9PiB7XG4gICAgICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICAgICAgdGhpcy5jYW5jZWxDcmVhdGUoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIGNlbGwgdmFsdWUgYmFzZWQgb24gY29sdW1uIHR5cGUgb3Igc2FtcGxlIGRhdGEuXG4gICAqIEhhbmRsZXMgc3RyaW5naWZpY2F0aW9uIG9mIG9iamVjdHMgZm9yIHN0cmluZyBjb2x1bW5zLlxuICAgKi9cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgY2VsbCB2YWx1ZSBiYXNlZCBvbiBjb2x1bW4gdHlwZSBvciBzYW1wbGUgZGF0YS5cbiAgICogRGVsZWdhdGVzIHRvIHR5cGUtc3BlY2lmaWMgaGVscGVycyBmb3IgY2xhcml0eSBhbmQgbWFpbnRhaW5hYmlsaXR5LlxuICAgKi9cbiAgcHJpdmF0ZSBjb252ZXJ0Q2VsbFZhbHVlKHZhbHVlOiB1bmtub3duLCBjb2w6IEM4MFRhYmxlQ29sRGVmKTogdW5rbm93biB7XG4gICAgaWYgKGNvbC50eXBlID09PSAnYm9vbGVhbicpIHJldHVybiB0aGlzLnRvQm9vbGVhbih2YWx1ZSk7XG4gICAgaWYgKGNvbC50eXBlID09PSAnbnVtYmVyJykgcmV0dXJuIHRoaXMudG9OdW1iZXIodmFsdWUpO1xuICAgIGlmIChjb2wudHlwZSA9PT0gJ3N0cmluZycgfHwgY29sLnR5cGUgPT09ICdwYXNzd29yZCcpXG4gICAgICByZXR1cm4gdGhpcy50b1N0cmluZ1ZhbHVlKHZhbHVlKTtcblxuICAgIC8vIEZhbGxiYWNrOiB1c2Ugc2FtcGxlIGRhdGEgaWYgYXZhaWxhYmxlXG4gICAgY29uc3Qgc2FtcGxlID0gdGhpcy5kYXRhKClbMF07XG4gICAgaWYgKHNhbXBsZSkge1xuICAgICAgY29uc3Qgc2FtcGxlVmFsdWUgPSB0aGlzLmdldENlbGxWYWx1ZShzYW1wbGUsIGNvbC5hY2Nlc3Nvcik7XG4gICAgICBpZiAodHlwZW9mIHNhbXBsZVZhbHVlID09PSAnYm9vbGVhbicpIHJldHVybiB0aGlzLnRvQm9vbGVhbih2YWx1ZSk7XG4gICAgICBpZiAodHlwZW9mIHNhbXBsZVZhbHVlID09PSAnbnVtYmVyJykgcmV0dXJuIHRoaXMudG9OdW1iZXIodmFsdWUpO1xuICAgICAgaWYgKHR5cGVvZiBzYW1wbGVWYWx1ZSA9PT0gJ3N0cmluZycpIHJldHVybiB0aGlzLnRvU3RyaW5nVmFsdWUodmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvKiogQ29udmVydHMgdmFsdWUgdG8gYm9vbGVhbiB1c2luZyBiZXN0IHByYWN0aWNlcy4gKi9cbiAgcHJpdmF0ZSB0b0Jvb2xlYW4odmFsdWU6IHVua25vd24pOiBib29sZWFuIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHJldHVybiB2YWx1ZTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgIHJldHVybiB2YWx1ZS50cmltKCkudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnIHx8IHZhbHVlLnRyaW0oKSA9PT0gJzEnO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSByZXR1cm4gdmFsdWUgPT09IDE7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqIENvbnZlcnRzIHZhbHVlIHRvIG51bWJlciB1c2luZyBiZXN0IHByYWN0aWNlcy4gKi9cbiAgcHJpdmF0ZSB0b051bWJlcih2YWx1ZTogdW5rbm93bik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHJldHVybiB2YWx1ZTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgIHJldHVybiB2YWx1ZS50cmltKCkgPT09ICcnID8gdW5kZWZpbmVkIDogTnVtYmVyKHZhbHVlKTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHJldHVybiB2YWx1ZSA/IDEgOiAwO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKiogQ29udmVydHMgdmFsdWUgdG8gc3RyaW5nIHVzaW5nIGJlc3QgcHJhY3RpY2VzLCBhbHdheXMgc3RyaW5naWZpZXMgb2JqZWN0cy4gKi9cbiAgcHJpdmF0ZSB0b1N0cmluZ1ZhbHVlKHZhbHVlOiB1bmtub3duKTogc3RyaW5nIHtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuICcnO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSByZXR1cm4gdmFsdWU7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgfHwgdHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpXG4gICAgICByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gJ1tvYmplY3QgT2JqZWN0XSc7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEZvciBmdW5jdGlvbnMsIHN5bWJvbHMsIHVuZGVmaW5lZCwgZXRjLiwgcmV0dXJuIGVtcHR5IHN0cmluZ1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIG9uRWRpdChyb3c6IFQpIHtcbiAgICB0aGlzLmVkaXRpbmcuc2V0KHJvd1snaWQnXSBhcyBJRCk7XG4gICAgLy8gQWN0dWFsaXphciBrZXlzIGRlIGNvbHVtbmFzIHZpc2libGVzIGN1YW5kbyBlbnRyYW1vcyBlbiBtb2RvIGVkaWNpw7NuXG4gICAgdGhpcy51cGRhdGVWaXNpYmxlS2V5cygpO1xuICAgIGNvbnN0IGVkaXQ6IFBhcnRpYWw8VD4gPSB7fTtcbiAgICB0aGlzLmNvbHVtbnNcbiAgICAgIC5maWx0ZXIoKGNvbCkgPT4gdGhpcy5pc0NvbHVtblZpc2libGUoY29sLCB0cnVlKSAmJiAhY29sLnJlYWRPbmx5KVxuICAgICAgLmZvckVhY2goKGNvbCkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0Q2VsbFZhbHVlKHJvdywgY29sLmFjY2Vzc29yKTtcbiAgICAgICAgKGVkaXQgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW2NvbC5hY2Nlc3Nvcl0gPSB2YWx1ZTtcbiAgICAgIH0pO1xuICAgIHRoaXMuZWRpdFJvdy5zZXQoZWRpdCk7XG4gIH1cblxuICBjYW5jZWxFZGl0KCkge1xuICAgIHRoaXMuZWRpdGluZy5zZXQobnVsbCk7XG4gICAgdGhpcy5lZGl0Um93LnNldChudWxsKTtcbiAgICAvLyBBY3R1YWxpemFyIGtleXMgZGUgY29sdW1uYXMgdmlzaWJsZXMgY3VhbmRvIHNhbGltb3MgZGVsIG1vZG8gZWRpY2nDs25cbiAgICB0aGlzLnVwZGF0ZVZpc2libGVLZXlzKCk7XG4gIH1cblxuICBvbkVkaXRJbnB1dChldmVudDogRXZlbnQsIGtleTogc3RyaW5nLCBjb2w/OiBDODBUYWJsZUNvbERlZikge1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmVkaXRSb3coKTtcbiAgICBpZiAoIWN1cnJlbnQpIHJldHVybjtcbiAgICBpZiAoY29sPy50eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICAgIGNvbnN0IGNoZWNrZWQgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLmNoZWNrZWQ7XG4gICAgICB0aGlzLmVkaXRSb3cuc2V0KHsgLi4uY3VycmVudCwgW2tleV06IGNoZWNrZWQgfSk7XG4gICAgfSBlbHNlIGlmIChjb2w/LnR5cGUgPT09ICdlbnVtJykge1xuICAgICAgY29uc3QgdmFsdWUgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxTZWxlY3RFbGVtZW50KS52YWx1ZTtcbiAgICAgIHRoaXMuZWRpdFJvdy5zZXQoeyAuLi5jdXJyZW50LCBba2V5XTogdmFsdWUgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgaWYgKHRhcmdldCAmJiB0eXBlb2YgdGFyZ2V0LnZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLmVkaXRSb3cuc2V0KHsgLi4uY3VycmVudCwgW2tleV06IHRhcmdldC52YWx1ZSB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzYXZlRWRpdChyb3c6IFQpIHtcbiAgICBjb25zdCBpZCA9IHJvd1snaWQnXTtcbiAgICBpZiAoKHR5cGVvZiBpZCAhPT0gJ3N0cmluZycgJiYgdHlwZW9mIGlkICE9PSAnbnVtYmVyJykgfHwgIXRoaXMuZWRpdFJvdygpKVxuICAgICAgcmV0dXJuO1xuICAgIGNvbnN0IHZpc2libGVDb2x1bW5zID0gdGhpcy5jb2x1bW5zLmZpbHRlcihcbiAgICAgIChjb2wpID0+IHRoaXMuaXNDb2x1bW5WaXNpYmxlKGNvbCwgdHJ1ZSkgJiYgIWNvbC5yZWFkT25seVxuICAgICk7XG4gICAgY29uc3QgY29udmVydGVkID0gdmlzaWJsZUNvbHVtbnMucmVkdWNlKChhY2MsIGNvbCkgPT4ge1xuICAgICAgYWNjW2NvbC5hY2Nlc3Nvcl0gPSB0aGlzLmNvbnZlcnRDZWxsVmFsdWUoXG4gICAgICAgIHRoaXMuZWRpdFJvdygpIVtjb2wuYWNjZXNzb3JdLFxuICAgICAgICBjb2xcbiAgICAgICk7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSBhcyBQYXJ0aWFsPFQ+O1xuXG4gICAgdGhpcy51cGRhdGVBY3Rpb24uZW1pdCh7XG4gICAgICBpZCxcbiAgICAgIGNoYW5nZXM6IGNvbnZlcnRlZCxcbiAgICAgIGRvbmU6IChzdWNjZXNzOiBib29sZWFuKSA9PiB7XG4gICAgICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICAgICAgdGhpcy5jYW5jZWxFZGl0KCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhY2tCeSBmdW5jdGlvbiBmb3IgbmdGb3IgdG8gYXZvaWQgRE9NIHJlLWNyZWF0aW9uIChORzA5NTYgd2FybmluZykuXG4gICAqL1xuICB0cmFja0J5SWQoaW5kZXg6IG51bWJlciwgcm93OiBUKTogbnVtYmVyIHwgc3RyaW5nIHtcbiAgICBjb25zdCBpZCA9XG4gICAgICByb3cgJiYgdHlwZW9mIHJvdyA9PT0gJ29iamVjdCcgJiYgJ2lkJyBpbiByb3dcbiAgICAgICAgPyAocm93IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVsnaWQnXVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gdHlwZW9mIGlkID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgaWQgPT09ICdudW1iZXInID8gaWQgOiBpbmRleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyB0aGUgdmlldyBldmVudCB3aXRoIHRoZSBlbnRpcmUgcm93IGRhdGFcbiAgICovXG4gIG9uVmlldyhyb3c6IFQpOiB2b2lkIHtcbiAgICB0aGlzLnZpZXdBY3Rpb24uZW1pdChyb3cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtaXRzIHRoZSBnZXRSb3dCdXR0b25BY3Rpb24gZXZlbnQgd2l0aCB0aGUgZW50aXJlIHJvdyBkYXRhXG4gICAqL1xuICBvbkdldFJvd0J1dHRvbihyb3c6IFQpOiB2b2lkIHtcbiAgICB0aGlzLmdldFJvd0J1dHRvbkFjdGlvbi5lbWl0KHJvdyk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgdGhlIG1vdmVVcEFjdGlvbiBldmVudCB3aXRoIHRoZSByb3cgaWRcbiAgICovXG4gIGFzeW5jIG9uTW92ZVVwKHJvdzogVCkge1xuICAgIGNvbnN0IGlkID0gcm93WydpZCddIGFzIElEO1xuICAgIHRoaXMubW92ZVVwQWN0aW9uLmVtaXQoe1xuICAgICAgaWQsXG4gICAgICBkb25lOiAoc3VjY2VzczogYm9vbGVhbikgPT4ge1xuICAgICAgICBpZiAoc3VjY2VzcykgdGhpcy5jYW5jZWxFZGl0KCk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtaXRzIHRoZSBtb3ZlRG93bkFjdGlvbiBldmVudCB3aXRoIHRoZSByb3cgaWRcbiAgICovXG4gIGFzeW5jIG9uTW92ZURvd24ocm93OiBUKSB7XG4gICAgY29uc3QgaWQgPSByb3dbJ2lkJ10gYXMgSUQ7XG4gICAgdGhpcy5tb3ZlRG93bkFjdGlvbi5lbWl0KHtcbiAgICAgIGlkLFxuICAgICAgZG9uZTogKHN1Y2Nlc3M6IGJvb2xlYW4pID0+IHtcbiAgICAgICAgaWYgKHN1Y2Nlc3MpIHRoaXMuY2FuY2VsRWRpdCgpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyB0aGUgZW5hYmxlQWN0aW9uIGV2ZW50IHdpdGggdGhlIHJvdyBpZCBhbmQgY3VycmVudCBlbmFibGVkIHN0YXR1c1xuICAgKi9cbiAgYXN5bmMgb25FbmFibGUocm93OiBUKSB7XG4gICAgY29uc3QgaWQgPSByb3dbJ2lkJ10gYXMgSUQ7XG4gICAgY29uc3QgY3VycmVudEVuYWJsZWQgPSByb3dbJ2VuYWJsZWQnXSBhcyBib29sZWFuO1xuICAgIHRoaXMuZW5hYmxlQWN0aW9uLmVtaXQoe1xuICAgICAgaWQsXG4gICAgICBlbmFibGVkOiAhY3VycmVudEVuYWJsZWQsIC8vIFRvZ2dsZSB0aGUgY3VycmVudCBzdGF0ZVxuICAgICAgZG9uZTogKHN1Y2Nlc3M6IGJvb2xlYW4pID0+IHtcbiAgICAgICAgaWYgKHN1Y2Nlc3MpIHRoaXMuY2FuY2VsRWRpdCgpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIHNlYXJjaCBpbnB1dCBjaGFuZ2VzIHdpdGggZGVib3VuY2luZ1xuICAgKi9cbiAgb25TZWFyY2hJbnB1dChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICBjb25zdCB2YWx1ZSA9IHRhcmdldC52YWx1ZTtcbiAgICB0aGlzLnNlYXJjaFZhbHVlLnNldCh2YWx1ZSk7XG4gICAgdGhpcy5zZWFyY2hUZXJtLmVtaXQodmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFycyB0aGUgc2VhcmNoIGlucHV0XG4gICAqL1xuICBjbGVhclNlYXJjaCgpOiB2b2lkIHtcbiAgICB0aGlzLnNlYXJjaFZhbHVlLnNldCgnJyk7XG4gICAgdGhpcy5zZWFyY2hUZXJtLmVtaXQoJycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHZhbHVlIGZyb20gYW4gb2JqZWN0IHVzaW5nIGRvdCBub3RhdGlvbiAoZS5nLiwgJ3Rhc2submFtZScpXG4gICAqL1xuICBwcml2YXRlIGdldE5lc3RlZFZhbHVlKG9iajogYW55LCBhY2Nlc3Nvcjogc3RyaW5nKTogdW5rbm93biB7XG4gICAgcmV0dXJuIGFjY2Vzc29yLnNwbGl0KCcuJykucmVkdWNlKChjdXJyZW50LCBrZXkpID0+IHtcbiAgICAgIHJldHVybiBjdXJyZW50ICYmIHR5cGVvZiBjdXJyZW50ID09PSAnb2JqZWN0JyA/IGN1cnJlbnRba2V5XSA6IHVuZGVmaW5lZDtcbiAgICB9LCBvYmopO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHZhbHVlIGZvciBhIGNlbGwgdXNpbmcgdGhlIGFjY2Vzc29yLCBzdXBwb3J0aW5nIGRvdCBub3RhdGlvbiBmb3IgbmVzdGVkIHByb3BlcnRpZXNcbiAgICovXG4gIGdldENlbGxWYWx1ZShyb3c6IFQsIGFjY2Vzc29yOiBzdHJpbmcpOiB1bmtub3duIHtcbiAgICBpZiAoYWNjZXNzb3IuaW5jbHVkZXMoJy4nKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0TmVzdGVkVmFsdWUocm93LCBhY2Nlc3Nvcik7XG4gICAgfVxuICAgIHJldHVybiAocm93IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVthY2Nlc3Nvcl07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZGlzcGxheSB2YWx1ZSBmb3IgYSBjZWxsLCBzaG93aW5nICctJyBmb3IgZmFsc3kgdmFsdWVzIGV4Y2VwdCAwLCBmYWxzZSwgYW5kIGVtcHR5IG9iamVjdHMvYXJyYXlzXG4gICAqL1xuICBnZXREaXNwbGF5VmFsdWUodmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xuICAgIC8vIElmIHZhbHVlIGlzIDAsIHNob3cgaXRcbiAgICBpZiAodmFsdWUgPT09IDApIHtcbiAgICAgIHJldHVybiAnMCc7XG4gICAgfVxuICAgIC8vIElmIHZhbHVlIGlzIGZhbHNlLCBpdCBzaG91bGQgYmUgaGFuZGxlZCBieSBib29sZWFuIGxvZ2ljIGluIHRlbXBsYXRlLCBub3QgaGVyZVxuICAgIGlmICh2YWx1ZSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiAnZmFsc2UnO1xuICAgIH1cbiAgICAvLyBIYW5kbGUgb2JqZWN0cyBhbmQgYXJyYXlzIChpbmNsdWRpbmcgZW1wdHkgb25lcylcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gJ1tvYmplY3QgT2JqZWN0XSc7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIElmIHZhbHVlIGlzIG90aGVyIGZhbHN5IHZhbHVlcyAobnVsbCwgdW5kZWZpbmVkLCAnJyksIHNob3cgJy0nXG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgcmV0dXJuICctJztcbiAgICB9XG4gICAgLy8gSGFuZGxlIG90aGVyIHR5cGVzIGV4cGxpY2l0bHlcbiAgICBpZiAoXG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnIHx8XG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInIHx8XG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJ1xuICAgICkge1xuICAgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gICAgfVxuICAgIC8vIEZvciBhbnkgb3RoZXIgdHlwZSAoZnVuY3Rpb24sIHN5bWJvbCwgZXRjLiksIHJldHVybiBhIHNhZmUgZmFsbGJhY2tcbiAgICByZXR1cm4gJy0nO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGRpc3BsYXkgdGV4dCBmb3IgYW4gZW51bSB2YWx1ZVxuICAgKi9cbiAgZ2V0RW51bURpc3BsYXlWYWx1ZSh2YWx1ZTogdW5rbm93biwgY29sOiBDODBUYWJsZUNvbERlZik6IHN0cmluZyB7XG4gICAgaWYgKCFjb2wuZW51bSB8fCAodmFsdWUgIT09IDAgJiYgIXZhbHVlKSkge1xuICAgICAgcmV0dXJuICctJztcbiAgICB9XG4gICAgY29uc3QgZGlzcGxheVZhbHVlID0gY29sLmVudW1bdmFsdWUgYXMgc3RyaW5nIHwgbnVtYmVyXTtcbiAgICByZXR1cm4gKFxuICAgICAgZGlzcGxheVZhbHVlIHx8XG4gICAgICAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInXG4gICAgICAgID8gU3RyaW5nKHZhbHVlKVxuICAgICAgICA6ICctJylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGVudW0gb3B0aW9ucyBhcyBhbiBhcnJheSBmb3Igc2VsZWN0IGRyb3Bkb3duc1xuICAgKi9cbiAgZ2V0RW51bU9wdGlvbnMoXG4gICAgY29sOiBDODBUYWJsZUNvbERlZlxuICApOiB7IHZhbHVlOiBzdHJpbmcgfCBudW1iZXI7IGxhYmVsOiBzdHJpbmcgfVtdIHtcbiAgICBpZiAoIWNvbC5lbnVtKSByZXR1cm4gW107XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGNvbC5lbnVtKS5tYXAoKFt2YWx1ZSwgbGFiZWxdKSA9PiAoe1xuICAgICAgdmFsdWU6IGlzTmFOKE51bWJlcih2YWx1ZSkpID8gdmFsdWUgOiBOdW1iZXIodmFsdWUpLFxuICAgICAgbGFiZWwsXG4gICAgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIENTUyBjb2xvciBmb3IgYSBjZWxsIHZhbHVlIGJhc2VkIG9uIHRoZSBjb2x1bW4ncyBjb2xvciBjb25maWd1cmF0aW9uXG4gICAqL1xuICBnZXRDZWxsQ29sb3IodmFsdWU6IHVua25vd24sIGNvbDogQzgwVGFibGVDb2xEZWYpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICghY29sLmNvbG9yIHx8ICh2YWx1ZSAhPT0gMCAmJiAhdmFsdWUpKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gY29sLmNvbG9yW3ZhbHVlIGFzIHN0cmluZyB8IG51bWJlcl07XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYSBlbCBtYXgtaGVpZ2h0IGRlIGxhIHRhYmxhIGJhc2FkbyBlbiBlbCB0YW1hw7FvXG4gICAqIFNpIHNpemUgZXMgMCwgcmV0b3JuYSB1bmRlZmluZWQgKHNpbiBsw61taXRlIGRlIGFsdHVyYSlcbiAgICovXG4gIGdldFRhYmxlTWF4SGVpZ2h0KCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHRoaXMuc2l6ZSA8PSAwKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkOyAvLyBTaW4gbMOtbWl0ZSBkZSBhbHR1cmFcbiAgICB9XG4gICAgLy8gQWx0dXJhIGJhc2UgZGUgNDAwcHggKiBzaXplXG4gICAgY29uc3QgYmFzZUhlaWdodCA9IDQwMDtcbiAgICBjb25zdCBtYXhIZWlnaHQgPSBNYXRoLnJvdW5kKGJhc2VIZWlnaHQgKiB0aGlzLnNpemUpO1xuICAgIHJldHVybiBgJHttYXhIZWlnaHR9cHhgO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbGVjdGlvbiBtZXRob2RzXG4gICAqL1xuICBjbGVhclNlbGVjdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkSXRlbXMuc2V0KG5ldyBTZXQoKSk7XG4gICAgdGhpcy51cGRhdGVTZWxlY3RBbGxTdGF0ZSgpO1xuICAgIHRoaXMuZW1pdFNlbGVjdGlvbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1hbnRpZW5lIGxhIHNlbGVjY2nDs24gZXhpc3RlbnRlIGRlc3B1w6lzIGRlIGFjdHVhbGl6YXIgbG9zIGRhdG9zLFxuICAgKiBlbGltaW5hbmRvIHNvbG8gbG9zIElEcyBxdWUgeWEgbm8gZXhpc3RlbiBlbiBsb3MgbnVldm9zIGRhdG9zXG4gICAqL1xuICBwcml2YXRlIHByZXNlcnZlU2VsZWN0aW9uKCk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRTZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGVkSXRlbXMoKTtcbiAgICBjb25zdCBjdXJyZW50RGF0YSA9IHRoaXMuZGF0YSgpO1xuXG4gICAgaWYgKGN1cnJlbnRTZWxlY3Rpb24uc2l6ZSA9PT0gMCB8fCBjdXJyZW50RGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgIC8vIFNpIG5vIGhheSBzZWxlY2Npw7NuIG8gbm8gaGF5IGRhdG9zLCBsaW1waWFyIGxhIHNlbGVjY2nDs25cbiAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb24oKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBPYnRlbmVyIGxvcyBJRHMgZGlzcG9uaWJsZXMgZW4gbG9zIG51ZXZvcyBkYXRvc1xuICAgIGNvbnN0IGF2YWlsYWJsZUlkcyA9IG5ldyBTZXQoY3VycmVudERhdGEubWFwKGl0ZW0gPT4gaXRlbVsnaWQnXSBhcyBJRCkpO1xuXG4gICAgLy8gRmlsdHJhciBsYSBzZWxlY2Npw7NuIGFjdHVhbCBwYXJhIG1hbnRlbmVyIHNvbG8gbG9zIElEcyBxdWUgYcO6biBleGlzdGVuXG4gICAgY29uc3QgcHJlc2VydmVkU2VsZWN0aW9uID0gbmV3IFNldChcbiAgICAgIEFycmF5LmZyb20oY3VycmVudFNlbGVjdGlvbikuZmlsdGVyKGlkID0+IGF2YWlsYWJsZUlkcy5oYXMoaWQpKVxuICAgICk7XG5cbiAgICAvLyBBY3R1YWxpemFyIGxhIHNlbGVjY2nDs24gY29uIGxvcyBJRHMgcHJlc2VydmFkb3NcbiAgICB0aGlzLnNlbGVjdGVkSXRlbXMuc2V0KHByZXNlcnZlZFNlbGVjdGlvbik7XG4gICAgdGhpcy51cGRhdGVTZWxlY3RBbGxTdGF0ZSgpO1xuICAgIHRoaXMuZW1pdFNlbGVjdGlvbigpO1xuICB9XG5cbiAgdG9nZ2xlU2VsZWN0QWxsKCk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRTZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGVkSXRlbXMoKTtcbiAgICBjb25zdCBhbGxJdGVtcyA9IHRoaXMuZGF0YSgpO1xuXG4gICAgaWYgKGN1cnJlbnRTZWxlY3Rpb24uc2l6ZSA9PT0gYWxsSXRlbXMubGVuZ3RoKSB7XG4gICAgICAvLyBEZXNlbGVjdCBhbGxcbiAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb24oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gU2VsZWN0IGFsbFxuICAgICAgY29uc3QgYWxsSWRzID0gbmV3IFNldChhbGxJdGVtcy5tYXAoaXRlbSA9PiBpdGVtWydpZCddIGFzIElEKSk7XG4gICAgICB0aGlzLnNlbGVjdGVkSXRlbXMuc2V0KGFsbElkcyk7XG4gICAgICB0aGlzLnVwZGF0ZVNlbGVjdEFsbFN0YXRlKCk7XG4gICAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgICB9XG4gIH1cblxuICB0b2dnbGVJdGVtU2VsZWN0aW9uKGl0ZW06IFQpOiB2b2lkIHtcbiAgICBjb25zdCBpZCA9IGl0ZW1bJ2lkJ10gYXMgSUQ7XG4gICAgY29uc3QgY3VycmVudFNlbGVjdGlvbiA9IG5ldyBTZXQodGhpcy5zZWxlY3RlZEl0ZW1zKCkpO1xuXG4gICAgaWYgKCF0aGlzLm11bHRpcGxlKSB7XG4gICAgICAvLyBTZWxlY2Npw7NuIHNpbXBsZTogc29sbyBwZXJtaXRpciB1biBlbGVtZW50byBzZWxlY2Npb25hZG9cbiAgICAgIGlmIChjdXJyZW50U2VsZWN0aW9uLmhhcyhpZCkpIHtcbiAgICAgICAgLy8gRGVzZWxlY2Npb25hciBlbCBlbGVtZW50byBhY3R1YWxcbiAgICAgICAgY3VycmVudFNlbGVjdGlvbi5jbGVhcigpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gU2VsZWNjaW9uYXIgc29sbyBlc3RlIGVsZW1lbnRvXG4gICAgICAgIGN1cnJlbnRTZWxlY3Rpb24uY2xlYXIoKTtcbiAgICAgICAgY3VycmVudFNlbGVjdGlvbi5hZGQoaWQpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY3VycmVudFNlbGVjdGlvbi5oYXMoaWQpKSB7XG4gICAgICAvLyBTZWxlY2Npw7NuIG3Dumx0aXBsZTogZGVzZWxlY2Npb25hciBlbGVtZW50byBleGlzdGVudGVcbiAgICAgIGN1cnJlbnRTZWxlY3Rpb24uZGVsZXRlKGlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gU2VsZWNjacOzbiBtw7psdGlwbGU6IGFncmVnYXIgbnVldm8gZWxlbWVudG9cbiAgICAgIGN1cnJlbnRTZWxlY3Rpb24uYWRkKGlkKTtcbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdGVkSXRlbXMuc2V0KGN1cnJlbnRTZWxlY3Rpb24pO1xuICAgIHRoaXMudXBkYXRlU2VsZWN0QWxsU3RhdGUoKTtcbiAgICB0aGlzLmVtaXRTZWxlY3Rpb24oKTtcbiAgfSBpc0l0ZW1TZWxlY3RlZChpdGVtOiBUKTogYm9vbGVhbiB7XG4gICAgY29uc3QgaWQgPSBpdGVtWydpZCddIGFzIElEO1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkSXRlbXMoKS5oYXMoaWQpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVTZWxlY3RBbGxTdGF0ZSgpOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3RlZENvdW50ID0gdGhpcy5zZWxlY3RlZEl0ZW1zKCkuc2l6ZTtcbiAgICBjb25zdCB0b3RhbENvdW50ID0gdGhpcy5kYXRhKCkubGVuZ3RoO1xuXG4gICAgaWYgKHNlbGVjdGVkQ291bnQgPT09IDApIHtcbiAgICAgIHRoaXMuc2VsZWN0QWxsQ2hlY2tlZC5zZXQoZmFsc2UpO1xuICAgICAgdGhpcy5zZWxlY3RBbGxJbmRldGVybWluYXRlLnNldChmYWxzZSk7XG4gICAgfSBlbHNlIGlmIChzZWxlY3RlZENvdW50ID09PSB0b3RhbENvdW50KSB7XG4gICAgICB0aGlzLnNlbGVjdEFsbENoZWNrZWQuc2V0KHRydWUpO1xuICAgICAgdGhpcy5zZWxlY3RBbGxJbmRldGVybWluYXRlLnNldChmYWxzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VsZWN0QWxsQ2hlY2tlZC5zZXQoZmFsc2UpO1xuICAgICAgdGhpcy5zZWxlY3RBbGxJbmRldGVybWluYXRlLnNldCh0cnVlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGVtaXRTZWxlY3Rpb24oKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0ZWRJZHMgPSB0aGlzLnNlbGVjdGVkSXRlbXMoKTtcbiAgICBjb25zdCBzZWxlY3RlZEl0ZW1zID0gdGhpcy5kYXRhKCkuZmlsdGVyKGl0ZW0gPT5cbiAgICAgIHNlbGVjdGVkSWRzLmhhcyhpdGVtWydpZCddIGFzIElEKVxuICAgICk7XG4gICAgdGhpcy5zZWxlY3RhYmxlLmVtaXQoc2VsZWN0ZWRJdGVtcyk7XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZpY2Egc2kgdG9kb3MgbG9zIHZhbG9yZXMgZGUgdW5hIGNvbHVtbmEgZXN0w6FuIHZhY8Otb3MvbnVsb3NcbiAgICovXG4gIHByaXZhdGUgYXJlQWxsQ29sdW1uVmFsdWVzRW1wdHkoY29sdW1uOiBDODBUYWJsZUNvbERlZik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGN1cnJlbnREYXRhID0gdGhpcy5kYXRhKCk7XG5cbiAgICBpZiAoY3VycmVudERhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTsgLy8gU2kgbm8gaGF5IGRhdG9zLCBjb25zaWRlcmFtb3MgbGEgY29sdW1uYSBjb21vIHZhY8OtYVxuICAgIH1cblxuICAgIHJldHVybiBjdXJyZW50RGF0YS5ldmVyeShyb3cgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldENlbGxWYWx1ZShyb3csIGNvbHVtbi5hY2Nlc3Nvcik7XG5cbiAgICAgIC8vIENvbnNpZGVyYXIgdmFjw61vOiBudWxsLCB1bmRlZmluZWQsICcnLCAwIChwYXJhIG7Dum1lcm9zKSwgZmFsc2UgKHBhcmEgYm9vbGVhbm9zKSwgYXJyYXlzL29iamV0b3MgdmFjw61vc1xuICAgICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09ICcnKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBQYXJhIG7Dum1lcm9zLCAwIHNlIGNvbnNpZGVyYSBjb21vIHZhbG9yIHbDoWxpZG8sIG5vIHZhY8Otb1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICAvLyBQYXJhIGJvb2xlYW5vcywgZmFsc2Ugc2UgY29uc2lkZXJhIGNvbW8gdmFsb3IgdsOhbGlkbywgbm8gdmFjw61vXG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICAvLyBQYXJhIGFycmF5cyB2YWPDrW9zXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBQYXJhIG9iamV0b3MgdmFjw61vc1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluYSBzaSB1bmEgY29sdW1uYSBkZWJlIHNlciB2aXNpYmxlIGJhc8OhbmRvc2UgZW4gc3UgY29uZmlndXJhY2nDs24geSBkYXRvcy5cbiAgICpcbiAgICogT3JkZW4gZGUgcHJpb3JpZGFkOlxuICAgKiAxLiBTaSB2aXNpYmxlID09PSBmYWxzZTogU0lFTVBSRSBzZSBvY3VsdGEgKG3DoXhpbWEgcHJpb3JpZGFkKVxuICAgKiAyLiBTaSBoaWRlSWZBbGxWYWx1ZXNBcmVOdWxsID09PSB0cnVlIFkgdG9kb3MgbG9zIHZhbG9yZXMgZXN0w6FuIHZhY8Otb3M6IHNlIG9jdWx0YVxuICAgKiAgICBFWENFUENJw5NOOiBFbiBtb2RvIGNyZWFjacOzbiAoY3JlYXRpbmcgPT09IHRydWUpLCBlc3RhcyBjb2x1bW5hcyBzZSBtdWVzdHJhbiBwYXJhIHBlcm1pdGlyIGVudHJhZGEgZGUgZGF0b3NcbiAgICogMy4gUG9yIGRlZmVjdG86IHNlIG11ZXN0cmFcbiAgICpcbiAgICogQHBhcmFtIGNvbHVtbiAtIExhIGRlZmluaWNpw7NuIGRlIGxhIGNvbHVtbmFcbiAgICogQHBhcmFtIGZvcmNlU2hvd0luQ3JlYXRpb24gLSBTaSBlcyB0cnVlLCBpZ25vcmEgaGlkZUlmQWxsVmFsdWVzQXJlTnVsbCAodXNhZG8gZW4gbW9kbyBjcmVhY2nDs24pXG4gICAqL1xuICBpc0NvbHVtblZpc2libGUoY29sdW1uOiBDODBUYWJsZUNvbERlZiwgZm9yY2VTaG93SW5DcmVhdGlvbiA9IGZhbHNlKTogYm9vbGVhbiB7XG4gICAgLy8gUFJJT1JJREFEIDE6IFNpIHZpc2libGUgZXN0w6EgZXhwbMOtY2l0YW1lbnRlIGVzdGFibGVjaWRvIGVuIGZhbHNlLCBTSUVNUFJFIG9jdWx0YXJcbiAgICBpZiAoY29sdW1uLnZpc2libGUgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUFJJT1JJREFEIDI6IFNpIGhpZGVJZkFsbFZhbHVlc0FyZU51bGwgZXMgdHJ1ZSB5IHRvZG9zIGxvcyB2YWxvcmVzIGVzdMOhbiB2YWPDrW9zLCBvY3VsdGFyXG4gICAgLy8gRVhDRVBDScOTTjogRW4gbW9kbyBjcmVhY2nDs24sIG1vc3RyYW1vcyBlc3RhcyBjb2x1bW5hcyBwYXJhIHBlcm1pdGlyIGVudHJhZGEgZGUgZGF0b3NcbiAgICBpZiAoY29sdW1uLmhpZGVJZkFsbFZhbHVlc0FyZU51bGwgPT09IHRydWUgJiYgIWZvcmNlU2hvd0luQ3JlYXRpb24gJiYgdGhpcy5hcmVBbGxDb2x1bW5WYWx1ZXNFbXB0eShjb2x1bW4pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUG9yIGRlZmVjdG86IG1vc3RyYXJcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmEgc2kgdW5hIGNvbHVtbmEgZGViZSBzZXIgdmlzaWJsZSBlbiBsb3MgaGVhZGVycy5cbiAgICogTG9zIGhlYWRlcnMgc2UgbXVlc3RyYW4gc2kgbGEgY29sdW1uYSBlcyB2aXNpYmxlIGVuIGN1YWxxdWllcmEgZGUgZXN0b3MgY2Fzb3M6XG4gICAqIC0gVmlzdWFsaXphY2nDs24gbm9ybWFsXG4gICAqIC0gTW9kbyBjcmVhY2nDs25cbiAgICogLSBIYXkgYWxndW5hIGZpbGEgZW4gbW9kbyBlZGljacOzblxuICAgKlxuICAgKiBAcGFyYW0gY29sdW1uIC0gTGEgZGVmaW5pY2nDs24gZGUgbGEgY29sdW1uYVxuICAgKi9cbiAgaXNDb2x1bW5WaXNpYmxlSW5IZWFkZXIoY29sdW1uOiBDODBUYWJsZUNvbERlZik6IGJvb2xlYW4ge1xuICAgIC8vIFBSSU9SSURBRCAxOiBTaSB2aXNpYmxlIGVzdMOhIGV4cGzDrWNpdGFtZW50ZSBlc3RhYmxlY2lkbyBlbiBmYWxzZSwgU0lFTVBSRSBvY3VsdGFyXG4gICAgaWYgKGNvbHVtbi52aXNpYmxlID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFNpIGVzdGFtb3MgZW4gbW9kbyBjcmVhY2nDs24sIG1vc3RyYXIgY29sdW1uYXMgY29uIGhpZGVJZkFsbFZhbHVlc0FyZU51bGxcbiAgICBpZiAodGhpcy5jcmVhdGluZygpICYmIGNvbHVtbi5oaWRlSWZBbGxWYWx1ZXNBcmVOdWxsID09PSB0cnVlKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBTaSBoYXkgYWxndW5hIGZpbGEgZW4gbW9kbyBlZGljacOzbiwgbW9zdHJhciBjb2x1bW5hcyBjb24gaGlkZUlmQWxsVmFsdWVzQXJlTnVsbFxuICAgIGlmICh0aGlzLmVkaXRpbmcoKSAhPT0gbnVsbCAmJiBjb2x1bW4uaGlkZUlmQWxsVmFsdWVzQXJlTnVsbCA9PT0gdHJ1ZSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gU2kgaGlkZUlmQWxsVmFsdWVzQXJlTnVsbCBlcyB0cnVlIHkgdG9kb3MgbG9zIHZhbG9yZXMgZXN0w6FuIHZhY8Otb3MsIG9jdWx0YXJcbiAgICBpZiAoY29sdW1uLmhpZGVJZkFsbFZhbHVlc0FyZU51bGwgPT09IHRydWUgJiYgdGhpcy5hcmVBbGxDb2x1bW5WYWx1ZXNFbXB0eShjb2x1bW4pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUG9yIGRlZmVjdG86IG1vc3RyYXJcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmEgc2kgdW5hIGNvbHVtbmEgZGViZSBzZXIgdmlzaWJsZSBlbiB1bmEgZmlsYSBlc3BlY8OtZmljYSBjb25zaWRlcmFuZG8gZWwgbW9kbyBlZGljacOzbi5cbiAgICogRW4gbW9kbyBlZGljacOzbiBkZSBlc2EgZmlsYSBlc3BlY8OtZmljYSwgbGFzIGNvbHVtbmFzIGNvbiBoaWRlSWZBbGxWYWx1ZXNBcmVOdWxsIHNlIG11ZXN0cmFuLlxuICAgKlxuICAgKiBAcGFyYW0gY29sdW1uIC0gTGEgZGVmaW5pY2nDs24gZGUgbGEgY29sdW1uYVxuICAgKiBAcGFyYW0gcm93IC0gTGEgZmlsYSBhY3R1YWxcbiAgICovXG4gIGlzQ29sdW1uVmlzaWJsZUZvclJvdyhjb2x1bW46IEM4MFRhYmxlQ29sRGVmLCByb3c6IFQpOiBib29sZWFuIHtcbiAgICAvLyBQUklPUklEQUQgMTogU2kgdmlzaWJsZSBlc3TDoSBleHBsw61jaXRhbWVudGUgZXN0YWJsZWNpZG8gZW4gZmFsc2UsIFNJRU1QUkUgb2N1bHRhclxuICAgIGlmIChjb2x1bW4udmlzaWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBQUklPUklEQUQgMjogU2kgZXN0YSBmaWxhIGVzcGVjw61maWNhIGVzdMOhIGVuIG1vZG8gZWRpY2nDs24sIG1vc3RyYXIgY29sdW1uYXMgY29uIGhpZGVJZkFsbFZhbHVlc0FyZU51bGxcbiAgICBjb25zdCBpc0VkaXRpbmdUaGlzUm93ID0gdGhpcy5lZGl0aW5nKCkgPT09IHJvd1snaWQnXTtcbiAgICBpZiAoaXNFZGl0aW5nVGhpc1JvdyAmJiBjb2x1bW4uaGlkZUlmQWxsVmFsdWVzQXJlTnVsbCA9PT0gdHJ1ZSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gUFJJT1JJREFEIDM6IFNpIGhpZGVJZkFsbFZhbHVlc0FyZU51bGwgZXMgdHJ1ZSB5IHRvZG9zIGxvcyB2YWxvcmVzIGVzdMOhbiB2YWPDrW9zLCBvY3VsdGFyXG4gICAgaWYgKGNvbHVtbi5oaWRlSWZBbGxWYWx1ZXNBcmVOdWxsID09PSB0cnVlICYmIHRoaXMuYXJlQWxsQ29sdW1uVmFsdWVzRW1wdHkoY29sdW1uKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFBvciBkZWZlY3RvOiBtb3N0cmFyXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGFwcGx5U29ydGluZyhpdGVtczogVFtdKTogdm9pZCB7XG4gICAgY29uc3Qgb3JkZXJlZENvbHVtbnMgPSB0aGlzLmNvbHVtbnMuZmlsdGVyKChjb2wpID0+IGNvbC5vcmRlcik7XG4gICAgaWYgKG9yZGVyZWRDb2x1bW5zLmxlbmd0aCA+IDApIHtcbiAgICAgIG9yZGVyZWRDb2x1bW5zLmZvckVhY2goKGNvbCkgPT4ge1xuICAgICAgICBpdGVtcy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgY29uc3QgdmFsdWVBID0gdGhpcy5nZXRDZWxsVmFsdWUoYSwgY29sLmFjY2Vzc29yKSBhcyBzdHJpbmcgfCBudW1iZXI7XG4gICAgICAgICAgY29uc3QgdmFsdWVCID0gdGhpcy5nZXRDZWxsVmFsdWUoYiwgY29sLmFjY2Vzc29yKSBhcyBzdHJpbmcgfCBudW1iZXI7XG5cbiAgICAgICAgICBpZiAoY29sLm9yZGVyID09PSAnQVNDJykge1xuICAgICAgICAgICAgaWYgKHZhbHVlQSA+IHZhbHVlQikgcmV0dXJuIDE7XG4gICAgICAgICAgICBpZiAodmFsdWVBIDwgdmFsdWVCKSByZXR1cm4gLTE7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHZhbHVlQSA8IHZhbHVlQikgcmV0dXJuIDE7XG4gICAgICAgICAgICBpZiAodmFsdWVBID4gdmFsdWVCKSByZXR1cm4gLTE7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwidGFibGUtcmVzcG9uc2l2ZVwiIFtzdHlsZS5tYXgtaGVpZ2h0XT1cImdldFRhYmxlTWF4SGVpZ2h0KClcIiBbc3R5bGUub3ZlcmZsb3cteV09XCJzaXplID4gMCA/ICdhdXRvJyA6ICd2aXNpYmxlJ1wiPlxuICA8IS0tIFNlYXJjaCBCYXIgLS0+XG4gIEBpZiAoaGFzU2VhcmNoVGVybUxpc3RlbmVyKCkpIHtcbiAgPGRpdiBjbGFzcz1cInNlYXJjaC1jb250YWluZXJcIj5cbiAgICA8ZGl2IGNsYXNzPVwic2VhcmNoLWlucHV0LXdyYXBwZXJcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlucHV0LWdyb3VwLXRleHRcIj5cbiAgICAgICAgICA8YzgwLWljb24gaWNvbj1cInNlYXJjaFwiIFtzaXplXT1cIi44XCI+PC9jODAtaWNvbj5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBzZWFyY2gtaW5wdXRcIiBwbGFjZWhvbGRlcj1cIkJ1c2Nhci4uLlwiIFt2YWx1ZV09XCJzZWFyY2hWYWx1ZSgpXCIgKGlucHV0KT1cIm9uU2VhcmNoSW5wdXQoJGV2ZW50KVwiIGFyaWEtbGFiZWw9XCJCdXNjYXIgZW4gbGEgdGFibGFcIiAvPlxuICAgICAgICBAaWYgKHNlYXJjaFZhbHVlKCkpIHtcbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1zZWNvbmRhcnkgYnRuLWJvcnJhclwiIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiY2xlYXJTZWFyY2goKVwiIHRpdGxlPVwiTGltcGlhciBiw7pzcXVlZGFcIj5cbiAgICAgICAgICA8YzgwLWljb24gaWNvbj1cImNhbmNlbFwiIFtzaXplXT1cIi43XCI+PC9jODAtaWNvbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgfVxuXG4gIDx0YWJsZSBjbGFzcz1cInRhYmxlIHRhYmxlLWJvcmRlcmVkIHRhYmxlLWhvdmVyIGFsaWduLW1pZGRsZVwiPlxuICAgIDx0aGVhZCBjbGFzcz1cInRoZWFkIHRhYmxlLWxpZ2h0IHN0aWNreS1oZWFkZXJcIj5cbiAgICAgIDx0cj5cbiAgICAgICAgQGlmIChoYXNTZWxlY3RhYmxlTGlzdGVuZXIoKSAmJiBkYXRhKCkubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIDx0aCBjbGFzcz1cInRleHQtY2VudGVyIHNlbGVjdGlvbi1jb2x1bW5cIj5cbiAgICAgICAgICBAaWYgKG11bHRpcGxlKSB7XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cInNlbGVjdEFsbENoZWNrZWQoKVwiIFtpbmRldGVybWluYXRlXT1cInNlbGVjdEFsbEluZGV0ZXJtaW5hdGUoKVwiIChjaGFuZ2UpPVwidG9nZ2xlU2VsZWN0QWxsKClcIiBhcmlhLWxhYmVsPVwiU2VsZWNjaW9uYXIgdG9kb1wiIC8+XG4gICAgICAgICAgfVxuICAgICAgICA8L3RoPlxuICAgICAgICB9XG4gICAgICAgIEBmb3IgKGNvbCBvZiBjb2x1bW5zOyB0cmFjayBjb2wpIHtcbiAgICAgICAgQGlmIChpc0NvbHVtblZpc2libGVJbkhlYWRlcihjb2wpKSB7XG4gICAgICAgIEBpZiAoY29sLnR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlciBib29sZWFuLWNvbHVtblwiPnt7IGNvbC5sYWJlbCB9fTwvdGg+XG4gICAgICAgIH1cbiAgICAgICAgQGVsc2UgaWYgKGNvbC50eXBlID09PSAnbnVtYmVyJykge1xuICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlciBudW1iZXItY29sdW1uXCI+e3sgY29sLmxhYmVsIH19PC90aD5cbiAgICAgICAgfVxuICAgICAgICBAZWxzZSB7XG4gICAgICAgIDx0aD57eyBjb2wubGFiZWwgfX08L3RoPlxuICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGhhc0NyZWF0ZUFjdGlvbkxpc3RlbmVyKCkgfHwgaGFzVXBkYXRlQWN0aW9uTGlzdGVuZXIoKSB8fCBoYXNEZWxldGVBY3Rpb25MaXN0ZW5lcigpIHx8XG4gICAgICAgIGhhc0NhbmNlbEFjdGlvbkxpc3RlbmVyKCkgfHwgaGFzVmlld0FjdGlvbkxpc3RlbmVyKCkgfHwgaGFzR2V0Um93QnV0dG9uTGlzdGVuZXIoKSB8fFxuICAgICAgICBoYXNNb3ZlVXBBY3Rpb25MaXN0ZW5lcigpIHx8IGhhc01vdmVEb3duQWN0aW9uTGlzdGVuZXIoKSkge1xuICAgICAgICA8dGggY2xhc3M9XCJ0YWJsZS1hY3Rpb25zLWhlYWRlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb25zLXdyYXBwZXJcIj5cbiAgICAgICAgICAgIDxzcGFuPkFjdGlvbnM8L3NwYW4+XG4gICAgICAgICAgICBAaWYgKGhhc0NyZWF0ZUFjdGlvbkxpc3RlbmVyKCkpIHtcbiAgICAgICAgICAgIDxjODAtaWNvbiBidXR0b24gaWNvbj1cImFkZFwiIFtkaXNhYmxlZF09XCJjcmVhdGluZygpXCIgdGl0bGU9XCJBZ3JlZ2FyXCIgW3NpemVdPVwiLjZcIiAoaWNvbkNsaWNrKT1cInN0YXJ0Q3JlYXRlKClcIj48L2M4MC1pY29uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L3RoPlxuICAgICAgICB9XG4gICAgICA8L3RyPlxuICAgIDwvdGhlYWQ+XG4gICAgPHRib2R5PlxuICAgICAgQGZvciAocm93IG9mIGRhdGEoKTsgdHJhY2sgdHJhY2tCeUlkKGksIHJvdyk7IGxldCBpID0gJGluZGV4KSB7XG4gICAgICA8dHI+XG4gICAgICAgIEBpZiAoaGFzU2VsZWN0YWJsZUxpc3RlbmVyKCkgJiYgZGF0YSgpLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWNlbnRlciBzZWxlY3Rpb24tY29sdW1uXCI+XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cImlzSXRlbVNlbGVjdGVkKHJvdylcIiAoY2hhbmdlKT1cInRvZ2dsZUl0ZW1TZWxlY3Rpb24ocm93KVwiIFthdHRyLmFyaWEtbGFiZWxdPVwiJ1NlbGVjY2lvbmFyIGZpbGEgJyArIChpICsgMSlcIiAvPlxuICAgICAgICA8L3RkPlxuICAgICAgICB9XG4gICAgICAgIEBmb3IgKGNvbCBvZiBjb2x1bW5zOyB0cmFjayBjb2wpIHtcbiAgICAgICAgQGlmIChpc0NvbHVtblZpc2libGVGb3JSb3coY29sLCByb3cpKSB7XG4gICAgICAgIEBpZiAoY29sLnR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWNlbnRlciBib29sZWFuLWNvbHVtblwiPlxuICAgICAgICAgIEBpZiAoZWRpdGluZygpID09PSByb3dbJ2lkJ10gJiYgIWNvbC5yZWFkT25seSkge1xuICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbY2hlY2tlZF09XCIhIWVkaXRSb3coKT8uW2NvbC5hY2Nlc3Nvcl1cIiAoY2hhbmdlKT1cIm9uRWRpdElucHV0KCRldmVudCwgY29sLmFjY2Vzc29yLCBjb2wpXCIgW2F0dHIuYXJpYS1sYWJlbF09XCJjb2wubGFiZWxcIiAvPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSB7XG4gICAgICAgICAgQGlmIChnZXRDZWxsVmFsdWUocm93LCBjb2wuYWNjZXNzb3IpID09PSB0cnVlKSB7XG4gICAgICAgICAgPGM4MC1pY29uIGljb249XCJjaGVja1wiIFtzaXplXT1cIi43XCI+PC9jODAtaWNvbj5cbiAgICAgICAgICA8YnIgLz5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGVsc2UgaWYgKGdldENlbGxWYWx1ZShyb3csIGNvbC5hY2Nlc3NvcikgPT09IGZhbHNlKSB7XG4gICAgICAgICAgPGM4MC1pY29uIGljb249XCJjYW5jZWxcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgPGJyIC8+XG4gICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgPC90ZD5cbiAgICAgICAgfVxuICAgICAgICBAZWxzZSBpZiAoY29sLnR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyIG51bWJlci1jb2x1bW5cIj5cbiAgICAgICAgICBAaWYgKGVkaXRpbmcoKSA9PT0gcm93WydpZCddICYmICFjb2wucmVhZE9ubHkpIHtcbiAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtXCIgdHlwZT1cIm51bWJlclwiIFt2YWx1ZV09XCJlZGl0Um93KCk/Lltjb2wuYWNjZXNzb3JdID8/ICcnXCIgW3BsYWNlaG9sZGVyXT1cImNvbC5sYWJlbFwiIChpbnB1dCk9XCJvbkVkaXRJbnB1dCgkZXZlbnQsIGNvbC5hY2Nlc3NvciwgY29sKVwiIC8+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBlbHNlIHtcbiAgICAgICAgICA8c3BhbiBbc3R5bGUuY29sb3JdPVwiZ2V0Q2VsbENvbG9yKGdldENlbGxWYWx1ZShyb3csIGNvbC5hY2Nlc3NvciksIGNvbClcIj57eyBnZXREaXNwbGF5VmFsdWUoZ2V0Q2VsbFZhbHVlKHJvdyxcbiAgICAgICAgICAgIGNvbC5hY2Nlc3NvcikpIH19PC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgPC90ZD5cbiAgICAgICAgfVxuICAgICAgICBAZWxzZSB7XG4gICAgICAgIDx0ZD5cbiAgICAgICAgICBAaWYgKGVkaXRpbmcoKSA9PT0gcm93WydpZCddICYmICFjb2wucmVhZE9ubHkpIHtcbiAgICAgICAgICBAaWYgKGNvbC50eXBlID09PSAnZW51bScpIHtcbiAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tY29udHJvbC1zbVwiIFt2YWx1ZV09XCJlZGl0Um93KCk/Lltjb2wuYWNjZXNzb3JdID8/ICcnXCIgKGNoYW5nZSk9XCJvbkVkaXRJbnB1dCgkZXZlbnQsIGNvbC5hY2Nlc3NvciwgY29sKVwiPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPnt7IGNvbC5sYWJlbCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIGdldEVudW1PcHRpb25zKGNvbCk7IHRyYWNrIG9wdGlvbi52YWx1ZSkge1xuICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+e3sgb3B0aW9uLmxhYmVsIH19PC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBlbHNlIHtcbiAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtXCIgW3R5cGVdPVwiY29sLnR5cGUgPT09ICdwYXNzd29yZCcgPyAncGFzc3dvcmQnIDogJ3RleHQnXCIgW3ZhbHVlXT1cImVkaXRSb3coKT8uW2NvbC5hY2Nlc3Nvcl0gPz8gJydcIiBbcGxhY2Vob2xkZXJdPVwiY29sLmxhYmVsXCIgKGlucHV0KT1cIm9uRWRpdElucHV0KCRldmVudCwgY29sLmFjY2Vzc29yLCBjb2wpXCIgLz5cbiAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIEBlbHNlIHtcbiAgICAgICAgICBAaWYgKGNvbC50eXBlID09PSAncGFzc3dvcmQnKSB7XG4gICAgICAgICAgPHNwYW4gW3N0eWxlLmNvbG9yXT1cImdldENlbGxDb2xvcihnZXRDZWxsVmFsdWUocm93LCBjb2wuYWNjZXNzb3IpLCBjb2wpXCI+KioqKioqPC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSBpZiAoY29sLnR5cGUgPT09ICdlbnVtJykge1xuICAgICAgICAgIDxzcGFuIFtzdHlsZS5jb2xvcl09XCJnZXRDZWxsQ29sb3IoZ2V0Q2VsbFZhbHVlKHJvdywgY29sLmFjY2Vzc29yKSwgY29sKVwiPnt7XG4gICAgICAgICAgICBnZXRFbnVtRGlzcGxheVZhbHVlKGdldENlbGxWYWx1ZShyb3csIGNvbC5hY2Nlc3NvciksIGNvbClcbiAgICAgICAgICAgIH19PC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSBpZiAoZ2V0Q2VsbFZhbHVlKHJvdywgY29sLmFjY2Vzc29yKSA9PT0gdHJ1ZSkge1xuICAgICAgICAgIDxjODAtaWNvbiBpY29uPVwiY2hlY2tcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBlbHNlIGlmIChnZXRDZWxsVmFsdWUocm93LCBjb2wuYWNjZXNzb3IpID09PSBmYWxzZSkge1xuICAgICAgICAgIDxjODAtaWNvbiBpY29uPVwiY2FuY2VsXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSB7XG4gICAgICAgICAgPHNwYW4gW3N0eWxlLmNvbG9yXT1cImdldENlbGxDb2xvcihnZXRDZWxsVmFsdWUocm93LCBjb2wuYWNjZXNzb3IpLCBjb2wpXCI+e3sgZ2V0RGlzcGxheVZhbHVlKGdldENlbGxWYWx1ZShyb3csXG4gICAgICAgICAgICBjb2wuYWNjZXNzb3IpKSB9fTwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICA8L3RkPlxuICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGhhc0NyZWF0ZUFjdGlvbkxpc3RlbmVyKCkgfHwgaGFzVXBkYXRlQWN0aW9uTGlzdGVuZXIoKSB8fCBoYXNEZWxldGVBY3Rpb25MaXN0ZW5lcigpIHx8XG4gICAgICAgIGhhc0NhbmNlbEFjdGlvbkxpc3RlbmVyKCkgfHwgaGFzVmlld0FjdGlvbkxpc3RlbmVyKCkgfHwgaGFzR2V0Um93QnV0dG9uTGlzdGVuZXIoKSB8fFxuICAgICAgICBoYXNNb3ZlVXBBY3Rpb25MaXN0ZW5lcigpIHx8IGhhc01vdmVEb3duQWN0aW9uTGlzdGVuZXIoKSkge1xuICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWNlbnRlciBhY3Rpb25zLWNlbGxcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9ucy1jb250YWluZXJcIj5cbiAgICAgICAgICAgIEBpZiAoZWRpdGluZygpID09PSByb3dbJ2lkJ10pIHtcbiAgICAgICAgICAgIDxjODAtaWNvbiBidXR0b24gaWNvbj1cImNoZWNrXCIgdGl0bGU9XCJHdWFyZGFyXCIgKGljb25DbGljayk9XCJzYXZlRWRpdChyb3cpXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgICAgPGM4MC1pY29uIGJ1dHRvbiBpY29uPVwiY2FuY2VsXCIgY29sb3I9XCJ3YXJuXCIgdGl0bGU9XCJDYW5jZWxhclwiIChpY29uQ2xpY2spPVwiY2FuY2VsRWRpdCgpXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgICAgQGlmIChoYXNVcGRhdGVBY3Rpb25MaXN0ZW5lcigpKSB7XG4gICAgICAgICAgICA8YzgwLWljb24gYnV0dG9uIGljb249XCJlZGl0XCIgdGl0bGU9XCJFZGl0YXJcIiAoaWNvbkNsaWNrKT1cIm9uRWRpdChyb3cpXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGlmIChoYXNDYW5jZWxBY3Rpb25MaXN0ZW5lcigpKSB7XG4gICAgICAgICAgICA8YzgwLWljb24gYnV0dG9uIGljb249XCJjYW5jZWxfY2lyY2xlXCIgY29sb3I9XCJzZWNvbmRhcnlcIiB0aXRsZT1cIkNhbmNlbGFyXCIgKGljb25DbGljayk9XCJvbkNhbmNlbChyb3cpXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGlmIChoYXNWaWV3QWN0aW9uTGlzdGVuZXIoKSkge1xuICAgICAgICAgICAgPGM4MC1pY29uIGJ1dHRvbiBpY29uPVwidmlld1wiIGNvbG9yPVwicHJpbWFyeVwiIHRpdGxlPVwiVmVyXCIgKGljb25DbGljayk9XCJvblZpZXcocm93KVwiIFtzaXplXT1cIi43XCI+PC9jODAtaWNvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBpZiAoaGFzR2V0Um93QnV0dG9uTGlzdGVuZXIoKSkge1xuICAgICAgICAgICAgPGM4MC1pY29uIGJ1dHRvbiBpY29uPVwiZ2V0XCIgY29sb3I9XCJzdWNjZXNzXCIgdGl0bGU9XCJWaW5jdWxhclwiIChpY29uQ2xpY2spPVwib25HZXRSb3dCdXR0b24ocm93KVwiIFtzaXplXT1cIi43XCI+PC9jODAtaWNvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBpZiAoaGFzTW92ZVVwQWN0aW9uTGlzdGVuZXIoKSkge1xuICAgICAgICAgICAgPGM4MC1pY29uIGJ1dHRvbiBpY29uPVwiYXJyb3dfdXBcIiBjb2xvcj1cInNlY29uZGFyeVwiIHRpdGxlPVwiTW92ZXIgYXJyaWJhXCIgKGljb25DbGljayk9XCJvbk1vdmVVcChyb3cpXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGlmIChoYXNNb3ZlRG93bkFjdGlvbkxpc3RlbmVyKCkpIHtcbiAgICAgICAgICAgIDxjODAtaWNvbiBidXR0b24gaWNvbj1cImFycm93X2Rvd25cIiBjb2xvcj1cInNlY29uZGFyeVwiIHRpdGxlPVwiTW92ZXIgYWJham9cIiAoaWNvbkNsaWNrKT1cIm9uTW92ZURvd24ocm93KVwiIFtzaXplXT1cIi43XCI+PC9jODAtaWNvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBpZiAoaGFzRW5hYmxlQWN0aW9uTGlzdGVuZXIoKSkge1xuICAgICAgICAgICAgPGM4MC1pY29uIGJ1dHRvbiBbaWNvbl09XCJnZXRDZWxsVmFsdWUocm93LCAnZW5hYmxlZCcpID8gJ3RvZ2dsZV9vbicgOiAndG9nZ2xlX29mZidcIiBbY29sb3JdPVwiZ2V0Q2VsbFZhbHVlKHJvdywgJ2VuYWJsZWQnKSA/ICdzdWNjZXNzJyA6ICdzZWNvbmRhcnknXCIgW3RpdGxlXT1cImdldENlbGxWYWx1ZShyb3csICdlbmFibGVkJykgPyAnRGVzaGFiaWxpdGFyJyA6ICdIYWJpbGl0YXInXCJcbiAgICAgICAgICAgICAgKGljb25DbGljayk9XCJvbkVuYWJsZShyb3cpXCIgW3NpemVdPVwiLjdcIj5cbiAgICAgICAgICAgIDwvYzgwLWljb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAaWYgKGhhc0RlbGV0ZUFjdGlvbkxpc3RlbmVyKCkpIHtcbiAgICAgICAgICAgIDxjODAtaWNvbiBidXR0b24gaWNvbj1cImRlbGV0ZVwiIGNvbG9yPVwid2FyblwiIHRpdGxlPVwiQm9ycmFyXCIgKGljb25DbGljayk9XCJvbkRlbGV0ZShyb3cpXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L3RkPlxuICAgICAgICB9XG4gICAgICA8L3RyPlxuICAgICAgfVxuICAgICAgQGlmIChjcmVhdGluZygpICYmIGhhc0NyZWF0ZUFjdGlvbkxpc3RlbmVyKCkpIHtcbiAgICAgIDx0cj5cbiAgICAgICAgQGlmIChoYXNTZWxlY3RhYmxlTGlzdGVuZXIoKSAmJiBkYXRhKCkubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyIHNlbGVjdGlvbi1jb2x1bW5cIj5cbiAgICAgICAgICA8IS0tIEVtcHR5IGNlbGwgZm9yIGFsaWdubWVudCAtLT5cbiAgICAgICAgPC90ZD5cbiAgICAgICAgfVxuICAgICAgICBAZm9yIChjb2wgb2YgY29sdW1uczsgdHJhY2sgY29sKSB7XG4gICAgICAgIEBpZiAoaXNDb2x1bW5WaXNpYmxlKGNvbCwgdHJ1ZSkpIHtcbiAgICAgICAgQGlmIChjb2wudHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyXCI+XG4gICAgICAgICAgQGlmICghY29sLnJlYWRPbmx5KSB7XG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cIiEhbmV3Um93KCk/Lltjb2wuYWNjZXNzb3JdXCIgKGNoYW5nZSk9XCJvbklucHV0KCRldmVudCwgY29sLmFjY2Vzc29yLCBjb2wpXCIgW2F0dHIuYXJpYS1sYWJlbF09XCJjb2wubGFiZWxcIiAvPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSB7XG4gICAgICAgICAgPCEtLSBSZWFkT25seSBib29sZWFuIGNvbHVtbiBpbiBjcmVhdGUgbW9kZSBzaG93cyBlbXB0eSAtLT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWRcIj4tPC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgPC90ZD5cbiAgICAgICAgfSBAZWxzZSBpZiAoY29sLnR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyIG51bWJlci1jb2x1bW5cIj5cbiAgICAgICAgICBAaWYgKCFjb2wucmVhZE9ubHkpIHtcbiAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtXCIgdHlwZT1cIm51bWJlclwiIFt2YWx1ZV09XCJuZXdSb3coKT8uW2NvbC5hY2Nlc3Nvcl0gPz8gJydcIiBbcGxhY2Vob2xkZXJdPVwiY29sLmxhYmVsXCIgKGlucHV0KT1cIm9uSW5wdXQoJGV2ZW50LCBjb2wuYWNjZXNzb3IsIGNvbClcIiAvPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAZWxzZSB7XG4gICAgICAgICAgPCEtLSBSZWFkT25seSBudW1iZXIgY29sdW1uIGluIGNyZWF0ZSBtb2RlIHNob3dzIGVtcHR5IC0tPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1tdXRlZFwiPi08L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICA8L3RkPlxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgPHRkPlxuICAgICAgICAgIEBpZiAoIWNvbC5yZWFkT25seSkge1xuICAgICAgICAgIEBpZiAoY29sLnR5cGUgPT09ICdlbnVtJykge1xuICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtXCIgW3ZhbHVlXT1cIm5ld1JvdygpPy5bY29sLmFjY2Vzc29yXSA/PyAnJ1wiIChjaGFuZ2UpPVwib25JbnB1dCgkZXZlbnQsIGNvbC5hY2Nlc3NvciwgY29sKVwiPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPnt7IGNvbC5sYWJlbCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIGdldEVudW1PcHRpb25zKGNvbCk7IHRyYWNrIG9wdGlvbi52YWx1ZSkge1xuICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+e3sgb3B0aW9uLmxhYmVsIH19PC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBlbHNlIHtcbiAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtXCIgdHlwZT1cInRleHRcIiBbdmFsdWVdPVwibmV3Um93KCk/Lltjb2wuYWNjZXNzb3JdID8/ICcnXCIgW3BsYWNlaG9sZGVyXT1cImNvbC5sYWJlbFwiIChpbnB1dCk9XCJvbklucHV0KCRldmVudCwgY29sLmFjY2Vzc29yLCBjb2wpXCIgLz5cbiAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIEBlbHNlIHtcbiAgICAgICAgICA8IS0tIFJlYWRPbmx5IGNvbHVtbiBpbiBjcmVhdGUgbW9kZSBzaG93cyBlbXB0eSAtLT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWRcIj4tPC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgPC90ZD5cbiAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgPHRkIGNsYXNzPVwidGV4dC1jZW50ZXIgYWN0aW9ucy1jZWxsXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbnMtY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8YzgwLWljb24gYnV0dG9uIGljb249XCJjaGVja1wiIHRpdGxlPVwiR3VhcmRhclwiIChpY29uQ2xpY2spPVwic2F2ZUNyZWF0ZSgpXCIgW3NpemVdPVwiLjdcIj48L2M4MC1pY29uPlxuICAgICAgICAgICAgPGM4MC1pY29uIGJ1dHRvbiBpY29uPVwiY2FuY2VsXCIgY29sb3I9XCJ3YXJuXCIgdGl0bGU9XCJDYW5jZWxhclwiIChpY29uQ2xpY2spPVwiY2FuY2VsQ3JlYXRlKClcIiBbc2l6ZV09XCIuN1wiPjwvYzgwLWljb24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L3RyPlxuICAgICAgfVxuICAgIDwvdGJvZHk+XG4gIDwvdGFibGU+XG4gIEBpZiAoZGF0YSgpLmxlbmd0aCA9PT0gMCAmJiAhY3JlYXRpbmcoKSkge1xuICA8ZGl2IGNsYXNzPVwidGV4dC1jZW50ZXIgdGV4dC1tdXRlZCBweS0zIHNtYWxsXCI+XG4gICAgTm8gaGF5IGRhdG9zIHBhcmEgbW9zdHJhci5cbiAgPC9kaXY+XG4gIH1cbjwvZGl2PlxuXG48YzgwLW1vZGFsPjwvYzgwLW1vZGFsPiJdfQ==
@@ -10,9 +10,45 @@ export interface C80TableColDef {
10
10
  readOnly?: boolean;
11
11
  enum?: Record<string | number, string>;
12
12
  color?: Record<string | number, string>;
13
+ hideIfAllValuesAreNull?: boolean;
14
+ default?: unknown;
13
15
  }
14
16
  export type ID = number | string;
15
- export declare class C80TableComponent<T extends Record<string, unknown>> implements OnInit, OnDestroy {
17
+ /**
18
+ * C80TableComponent - Componente de tabla avanzado con funcionalidades CRUD
19
+ *
20
+ * COMPORTAMIENTO DE VISIBILIDAD DE COLUMNAS:
21
+ * ========================================
22
+ *
23
+ * 1. PRIORIDAD MÁXIMA - visible: false
24
+ * - La columna se oculta SIEMPRE, sin excepciones
25
+ * - Ni en modo creación ni en modo edición se muestra
26
+ *
27
+ * 2. OCULTACIÓN AUTOMÁTICA - hideIfAllValuesAreNull: true
28
+ * - La columna se oculta solo si TODOS los valores actuales están vacíos
29
+ * - Valores considerados vacíos: null, undefined, '', [], {}
30
+ * - Valores NO vacíos: 0, false (son valores válidos)
31
+ * - EXCEPCIONES IMPORTANTES:
32
+ * * En modo creación (creating=true) estas columnas SÍ se muestran
33
+ * * En modo edición de una fila específica también se muestran
34
+ *
35
+ * 3. POR DEFECTO - Columnas normales
36
+ * - Se muestran siempre (visualización, creación y edición)
37
+ *
38
+ * VALORES POR DEFECTO EN CREACIÓN:
39
+ * ===============================
40
+ *
41
+ * - Propiedad `default?: unknown` permite definir valores por defecto para modo creación
42
+ * - Solo se aplica cuando se inicia el modo creación (startCreate)
43
+ * - Puede ser cualquier tipo: string, number, boolean, etc.
44
+ * - Si no se especifica `default`, se usa cadena vacía ('')
45
+ *
46
+ * EJEMPLOS:
47
+ * - { accessor: 'id', visible: false } → NUNCA se muestra
48
+ * - { accessor: 'motorPos', hideIfAllValuesAreNull: true, default: 0 } → Se autorellena con 0 en creación
49
+ * - { accessor: 'status', default: 'active' } → Se autorellena con 'active' en creación
50
+ * - { accessor: 'name' } → Siempre visible, sin valor por defecto (cadena vacía)
51
+ */ export declare class C80TableComponent<T extends Record<string, unknown>> implements OnInit, OnDestroy {
16
52
  private readonly modalService;
17
53
  data$: Observable<T[]>;
18
54
  columns: C80TableColDef[];
@@ -77,6 +113,10 @@ export declare class C80TableComponent<T extends Record<string, unknown>> implem
77
113
  readonly hasSelectableListener: import("@angular/core").WritableSignal<boolean>;
78
114
  private dataSub?;
79
115
  private getErrorMessage;
116
+ /**
117
+ * Actualiza las keys de columnas visibles basándose en el estado actual
118
+ */
119
+ private updateVisibleKeys;
80
120
  ngOnInit(): void;
81
121
  ngOnDestroy(): void;
82
122
  onInput(event: Event, key: string, col?: C80TableColDef): void;
@@ -183,6 +223,41 @@ export declare class C80TableComponent<T extends Record<string, unknown>> implem
183
223
  isItemSelected(item: T): boolean;
184
224
  private updateSelectAllState;
185
225
  private emitSelection;
226
+ /**
227
+ * Verifica si todos los valores de una columna están vacíos/nulos
228
+ */
229
+ private areAllColumnValuesEmpty;
230
+ /**
231
+ * Determina si una columna debe ser visible basándose en su configuración y datos.
232
+ *
233
+ * Orden de prioridad:
234
+ * 1. Si visible === false: SIEMPRE se oculta (máxima prioridad)
235
+ * 2. Si hideIfAllValuesAreNull === true Y todos los valores están vacíos: se oculta
236
+ * EXCEPCIÓN: En modo creación (creating === true), estas columnas se muestran para permitir entrada de datos
237
+ * 3. Por defecto: se muestra
238
+ *
239
+ * @param column - La definición de la columna
240
+ * @param forceShowInCreation - Si es true, ignora hideIfAllValuesAreNull (usado en modo creación)
241
+ */
242
+ isColumnVisible(column: C80TableColDef, forceShowInCreation?: boolean): boolean;
243
+ /**
244
+ * Determina si una columna debe ser visible en los headers.
245
+ * Los headers se muestran si la columna es visible en cualquiera de estos casos:
246
+ * - Visualización normal
247
+ * - Modo creación
248
+ * - Hay alguna fila en modo edición
249
+ *
250
+ * @param column - La definición de la columna
251
+ */
252
+ isColumnVisibleInHeader(column: C80TableColDef): boolean;
253
+ /**
254
+ * Determina si una columna debe ser visible en una fila específica considerando el modo edición.
255
+ * En modo edición de esa fila específica, las columnas con hideIfAllValuesAreNull se muestran.
256
+ *
257
+ * @param column - La definición de la columna
258
+ * @param row - La fila actual
259
+ */
260
+ isColumnVisibleForRow(column: C80TableColDef, row: T): boolean;
186
261
  private applySorting;
187
262
  static ɵfac: i0.ɵɵFactoryDeclaration<C80TableComponent<any>, never>;
188
263
  static ɵcmp: i0.ɵɵComponentDeclaration<C80TableComponent<any>, "c80-table", never, { "data$": { "alias": "data$"; "required": false; }; "columns": { "alias": "columns"; "required": false; }; "size": { "alias": "size"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "noConfirm": { "alias": "noConfirm"; "required": false; }; }, { "createAction": "createAction"; "updateAction": "updateAction"; "deleteAction": "deleteAction"; "cancelAction": "cancelAction"; "viewAction": "viewAction"; "getRowButtonAction": "getRowButtonAction"; "moveUpAction": "moveUpAction"; "moveDownAction": "moveDownAction"; "enableAction": "enableAction"; "searchTerm": "searchTerm"; "errorEvent": "errorEvent"; "selectable": "selectable"; }, never, never, true, never>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c80/ui",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "peerDependencies": {
5
5
  "@angular/core": "^18.2.0",
6
6
  "rxjs": "~7.8.0",