@esfaenza/es-table 13.1.12 → 13.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/lib/components/es-table/es_table.component.mjs +22 -8
- package/esm2020/lib/core/handlers/ColumnMetadataHandler.mjs +669 -0
- package/esm2020/lib/core/handlers/DynamicModeHandler.mjs +63 -0
- package/esm2020/lib/core/handlers/ExportHandler.mjs +103 -0
- package/esm2020/lib/core/handlers/HierarchyModeHandler.mjs +136 -0
- package/esm2020/lib/core/handlers/ItemsHandler.mjs +111 -0
- package/esm2020/lib/core/handlers/ReportModeHandler.mjs +70 -0
- package/esm2020/lib/core/handlers/RowGroupingHandler.mjs +480 -0
- package/esm2020/lib/core/handlers/SelectionHandler.mjs +524 -0
- package/esm2020/lib/core/handlers/UtilitiesHandler.mjs +152 -0
- package/esm2020/lib/directives/es_th.directive.mjs +6 -2
- package/esm2020/lib/domain/configuration/EsTableDefaultable.mjs +1 -1
- package/esm2020/lib/domain/externals/CornerMenuOption.mjs +4 -0
- package/esm2020/lib/domain/externals/EsTableColumnsDefinition.mjs +31 -0
- package/esm2020/lib/domain/externals/EsTableOperationDefinition.mjs +22 -0
- package/esm2020/lib/domain/externals/appsearch/AppOrdering.mjs +16 -0
- package/esm2020/lib/domain/externals/appsearch/AppSearch.mjs +35 -0
- package/esm2020/lib/domain/externals/appsearch/GenericItem.mjs +11 -0
- package/esm2020/lib/domain/externals/appsearch/Group.mjs +17 -0
- package/esm2020/lib/domain/externals/appsearch/GroupAggregation.mjs +16 -0
- package/esm2020/lib/domain/externals/appsearch/GroupFilter.mjs +14 -0
- package/esm2020/lib/domain/externals/appsearch/GroupOrAggregation.mjs +16 -0
- package/esm2020/lib/domain/externals/appsearch/ItemsSelection.mjs +23 -0
- package/esm2020/lib/domain/externals/report/ReportColumn.mjs +4 -0
- package/esm2020/lib/domain/externals/report/ReportDefinition.mjs +4 -0
- package/esm2020/lib/domain/externals/report/ReportOrder.mjs +4 -0
- package/esm2020/lib/domain/externals/report/ReportParam.mjs +4 -0
- package/esm2020/lib/domain/externals/report/ReportResult.mjs +4 -0
- package/esm2020/lib/domain/externals/report/ReportRow.mjs +4 -0
- package/esm2020/lib/domain/internals/CacheTriptic.mjs +16 -0
- package/esm2020/lib/domain/internals/EsTableColumn.mjs +27 -0
- package/esm2020/lib/domain/internals/GroupPager.mjs +22 -0
- package/esm2020/lib/domain/internals/GroupRouteFragment.mjs +17 -0
- package/esm2020/lib/domain/internals/TdElement.mjs +2 -0
- package/esm2020/lib/domain/internals/ThAggregation.mjs +16 -0
- package/esm2020/lib/domain/internals/ThElement.mjs +2 -0
- package/esm2020/public-api.mjs +18 -5
- package/fesm2015/esfaenza-es-table.mjs +484 -498
- package/fesm2015/esfaenza-es-table.mjs.map +1 -1
- package/fesm2020/esfaenza-es-table.mjs +468 -482
- package/fesm2020/esfaenza-es-table.mjs.map +1 -1
- package/lib/components/es-table/es_table.component.d.ts +26 -6
- package/lib/core/handlers/{classes/ColumnMetadataHandler.d.ts → ColumnMetadataHandler.d.ts} +9 -7
- package/lib/core/handlers/{classes/DynamicModeHandler.d.ts → DynamicModeHandler.d.ts} +2 -2
- package/lib/core/handlers/{classes/ExportHandler.d.ts → ExportHandler.d.ts} +1 -1
- package/lib/core/handlers/{classes/HierarchyModeHandler.d.ts → HierarchyModeHandler.d.ts} +1 -1
- package/lib/core/handlers/{classes/ItemsHandler.d.ts → ItemsHandler.d.ts} +1 -1
- package/lib/core/handlers/{classes/ReportModeHandler.d.ts → ReportModeHandler.d.ts} +2 -2
- package/lib/core/handlers/{classes/RowGroupingHandler.d.ts → RowGroupingHandler.d.ts} +8 -3
- package/lib/core/handlers/{classes/SelectionHandler.d.ts → SelectionHandler.d.ts} +3 -3
- package/lib/core/handlers/{classes/UtilitiesHandler.d.ts → UtilitiesHandler.d.ts} +0 -0
- package/lib/directives/es_th.directive.d.ts +4 -2
- package/lib/domain/configuration/EsTableDefaultable.d.ts +1 -0
- package/lib/domain/externals/{classes/CornerMenuOption.d.ts → CornerMenuOption.d.ts} +0 -0
- package/lib/domain/externals/{classes/EsTableColumnsDefinition.d.ts → EsTableColumnsDefinition.d.ts} +0 -0
- package/lib/domain/externals/{classes/EsTableOperationDefinition.d.ts → EsTableOperationDefinition.d.ts} +0 -0
- package/lib/domain/externals/{classes/appsearch → appsearch}/AppOrdering.d.ts +0 -0
- package/lib/domain/externals/{classes/appsearch → appsearch}/AppSearch.d.ts +0 -0
- package/lib/domain/externals/{classes/appsearch → appsearch}/GenericItem.d.ts +0 -0
- package/lib/domain/externals/{classes/appsearch → appsearch}/Group.d.ts +0 -0
- package/lib/domain/externals/{classes/appsearch → appsearch}/GroupAggregation.d.ts +0 -0
- package/lib/domain/externals/{classes/appsearch → appsearch}/GroupFilter.d.ts +0 -0
- package/lib/domain/externals/{classes/appsearch → appsearch}/GroupOrAggregation.d.ts +0 -0
- package/lib/domain/externals/{classes/appsearch → appsearch}/ItemsSelection.d.ts +1 -1
- package/lib/domain/externals/{classes/report → report}/ReportColumn.d.ts +0 -0
- package/lib/domain/externals/{classes/report → report}/ReportDefinition.d.ts +3 -1
- package/lib/domain/externals/{classes/report → report}/ReportOrder.d.ts +0 -0
- package/lib/domain/externals/{classes/report → report}/ReportParam.d.ts +0 -0
- package/lib/domain/externals/{classes/report → report}/ReportResult.d.ts +2 -1
- package/lib/domain/externals/{classes/report → report}/ReportRow.d.ts +0 -0
- package/lib/domain/internals/{classes/CacheTriptic.d.ts → CacheTriptic.d.ts} +0 -0
- package/lib/domain/internals/{classes/EsTableColumn.d.ts → EsTableColumn.d.ts} +2 -1
- package/lib/domain/internals/{classes/GroupPager.d.ts → GroupPager.d.ts} +2 -1
- package/lib/domain/internals/{classes/GroupRouteFragment.d.ts → GroupRouteFragment.d.ts} +0 -0
- package/lib/domain/internals/{classes/TdElement.d.ts → TdElement.d.ts} +17 -1
- package/lib/domain/internals/{classes/ThAggregation.d.ts → ThAggregation.d.ts} +0 -0
- package/lib/domain/internals/{classes/ThElement.d.ts → ThElement.d.ts} +0 -0
- package/package.json +1 -1
- package/public-api.d.ts +17 -1
- package/esm2020/lib/core/handlers/classes/ColumnMetadataHandler.mjs +0 -667
- package/esm2020/lib/core/handlers/classes/DynamicModeHandler.mjs +0 -64
- package/esm2020/lib/core/handlers/classes/ExportHandler.mjs +0 -103
- package/esm2020/lib/core/handlers/classes/HierarchyModeHandler.mjs +0 -136
- package/esm2020/lib/core/handlers/classes/ItemsHandler.mjs +0 -111
- package/esm2020/lib/core/handlers/classes/ReportModeHandler.mjs +0 -70
- package/esm2020/lib/core/handlers/classes/RowGroupingHandler.mjs +0 -477
- package/esm2020/lib/core/handlers/classes/SelectionHandler.mjs +0 -525
- package/esm2020/lib/core/handlers/classes/UtilitiesHandler.mjs +0 -152
- package/esm2020/lib/core/handlers/index.mjs +0 -10
- package/esm2020/lib/domain/externals/classes/CornerMenuOption.mjs +0 -4
- package/esm2020/lib/domain/externals/classes/EsTableColumnsDefinition.mjs +0 -31
- package/esm2020/lib/domain/externals/classes/EsTableOperationDefinition.mjs +0 -22
- package/esm2020/lib/domain/externals/classes/appsearch/AppOrdering.mjs +0 -16
- package/esm2020/lib/domain/externals/classes/appsearch/AppSearch.mjs +0 -35
- package/esm2020/lib/domain/externals/classes/appsearch/GenericItem.mjs +0 -11
- package/esm2020/lib/domain/externals/classes/appsearch/Group.mjs +0 -17
- package/esm2020/lib/domain/externals/classes/appsearch/GroupAggregation.mjs +0 -16
- package/esm2020/lib/domain/externals/classes/appsearch/GroupFilter.mjs +0 -14
- package/esm2020/lib/domain/externals/classes/appsearch/GroupOrAggregation.mjs +0 -16
- package/esm2020/lib/domain/externals/classes/appsearch/ItemsSelection.mjs +0 -23
- package/esm2020/lib/domain/externals/classes/report/ReportColumn.mjs +0 -4
- package/esm2020/lib/domain/externals/classes/report/ReportDefinition.mjs +0 -4
- package/esm2020/lib/domain/externals/classes/report/ReportOrder.mjs +0 -4
- package/esm2020/lib/domain/externals/classes/report/ReportParam.mjs +0 -4
- package/esm2020/lib/domain/externals/classes/report/ReportResult.mjs +0 -4
- package/esm2020/lib/domain/externals/classes/report/ReportRow.mjs +0 -4
- package/esm2020/lib/domain/externals/index.mjs +0 -18
- package/esm2020/lib/domain/index.mjs +0 -3
- package/esm2020/lib/domain/internals/classes/CacheTriptic.mjs +0 -16
- package/esm2020/lib/domain/internals/classes/EsTableColumn.mjs +0 -26
- package/esm2020/lib/domain/internals/classes/GroupPager.mjs +0 -22
- package/esm2020/lib/domain/internals/classes/GroupRouteFragment.mjs +0 -17
- package/esm2020/lib/domain/internals/classes/TdElement.mjs +0 -2
- package/esm2020/lib/domain/internals/classes/ThAggregation.mjs +0 -16
- package/esm2020/lib/domain/internals/classes/ThElement.mjs +0 -2
- package/esm2020/lib/domain/internals/index.mjs +0 -8
- package/lib/core/handlers/index.d.ts +0 -9
- package/lib/domain/externals/index.d.ts +0 -17
- package/lib/domain/index.d.ts +0 -2
- package/lib/domain/internals/index.d.ts +0 -7
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
import { CacheTriptic } from "../../domain/internals/CacheTriptic";
|
|
2
|
+
/** Classe che gestisce le selezioni degli oggetti */
|
|
3
|
+
export class SelectionHandler {
|
|
4
|
+
/** @ignore Costruttore */
|
|
5
|
+
constructor(est, rgHandler) {
|
|
6
|
+
this.est = est;
|
|
7
|
+
this.rgHandler = rgHandler;
|
|
8
|
+
/** Cache di selezione Hash - Oggetto per la variabile **items** dell'itemSelector. Facilita le operazioni di lookup via hash*/
|
|
9
|
+
this.itemsCache = new Map();
|
|
10
|
+
/** Cache di selezione Hash - Oggetto per la variabile **groups** dell'itemSelector. Facilita le operazioni di lookup via hash */
|
|
11
|
+
this.groupsCache = new Map();
|
|
12
|
+
/** Cache di selezione Hash - Oggetto per la variabile **exclusions** dell'itemSelector. Facilita le operazioni di lookup via hash */
|
|
13
|
+
this.exclusionsCache = new Map();
|
|
14
|
+
/** Cache di selezione Hash - Oggetto per la variabile **group_exclusions** dell'itemSelector. Facilita le operazioni di lookup via hash */
|
|
15
|
+
this.group_exclusionsCache = new Map();
|
|
16
|
+
/** Cache di selezione Hash - Oggetto per la variabile **items** dell'itemSelector. Facilita le operazioni di lookup via indice*/
|
|
17
|
+
this.i_itemsCache = new Map();
|
|
18
|
+
/** Cache di selezione Hash - Oggetto per la variabile **groups** dell'itemSelector. Facilita le operazioni di lookup via indice */
|
|
19
|
+
this.i_groupsCache = new Map();
|
|
20
|
+
/** Cache di selezione Hash - Oggetto per la variabile **exclusions** dell'itemSelector. Facilita le operazioni di lookup via indice */
|
|
21
|
+
this.i_exclusionsCache = new Map();
|
|
22
|
+
/** Cache di selezione Hash - Oggetto per la variabile **group_exclusions** dell'itemSelector. Facilita le operazioni di lookup via indice */
|
|
23
|
+
this.i_group_exclusionsCache = new Map();
|
|
24
|
+
}
|
|
25
|
+
/** Ripulisce le cache di selezione */
|
|
26
|
+
clearSelectionCaches() {
|
|
27
|
+
this.itemsCache.clear();
|
|
28
|
+
this.groupsCache.clear();
|
|
29
|
+
this.exclusionsCache.clear();
|
|
30
|
+
this.group_exclusionsCache.clear();
|
|
31
|
+
this.i_itemsCache.clear();
|
|
32
|
+
this.i_groupsCache.clear();
|
|
33
|
+
this.i_exclusionsCache.clear();
|
|
34
|
+
this.i_group_exclusionsCache.clear();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Valuta quali elementi devono essere marcati come selezionati nella vista attuale. Si basa sull'oggetto **selection** interno all'AppSearch
|
|
38
|
+
*
|
|
39
|
+
* @param {any[]} items Oggetti di cui valutare la selezione
|
|
40
|
+
* @param {ItemsSelection<any>} selectionItem Oggetti di selezione derivante dalla view o dall'oggetto per Array
|
|
41
|
+
*/
|
|
42
|
+
evaluateSelection(items, selectionItem) {
|
|
43
|
+
if (!selectionItem)
|
|
44
|
+
return;
|
|
45
|
+
this.handleSelectionEvaluation(items, selectionItem);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Implementazione agnostica della valutazione delle selezioni degli oggetti. Richiede gli oggetti della vista attuale e l'itemSelector
|
|
49
|
+
*
|
|
50
|
+
* @param {any[]} items Oggetti di cui aggiornare lo stato di selezione
|
|
51
|
+
* @param {ItemsSelection<any>} selectionItem Oggetto contenente lo stato attuale di selezione
|
|
52
|
+
*/
|
|
53
|
+
handleSelectionEvaluation(items, selectionItem) {
|
|
54
|
+
for (let i = 0; i < items.length; i++) {
|
|
55
|
+
let itm = items[i];
|
|
56
|
+
let hash = itm._hash;
|
|
57
|
+
let itemGroup = itm._group ? null : this.getItemGroup(itm);
|
|
58
|
+
// Reidrato la cache di selezione coi nuovi oggetti altrimenti non riuscirei a beccare gli indici giusti
|
|
59
|
+
// Dopodiché la uso per calcolare istantaneamente se gli oggetti sono selezionati o no
|
|
60
|
+
this.rehidrateCache(itm);
|
|
61
|
+
if (itm._item) {
|
|
62
|
+
if (selectionItem.all)
|
|
63
|
+
itm._selected = !this.exclusionsCache.has(hash) && ((!this.groupsCache.has(itemGroup?._hash) && this.itemsCache.has(hash)) || !this.group_exclusionsCache.has(itemGroup?._hash));
|
|
64
|
+
else
|
|
65
|
+
itm._selected = !this.exclusionsCache.has(hash) && (this.groupsCache.has(itemGroup?._hash) || this.itemsCache.has(hash) || (this.parentTreeStatus(itemGroup) == 'included' && !this.group_exclusionsCache.has(itemGroup?._hash)));
|
|
66
|
+
}
|
|
67
|
+
else if (itm._group) {
|
|
68
|
+
if (selectionItem.all)
|
|
69
|
+
itm._selected = !this.group_exclusionsCache.has(hash) && this.parentTreeStatus(itm) != 'excluded';
|
|
70
|
+
else
|
|
71
|
+
itm._selected = this.groupsCache.has(hash) || (this.parentTreeStatus(itm) == 'included' && !this.group_exclusionsCache.has(hash));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Se tutti gli oggetti di questa pagina sono solezionati allora posso mettere il global check a true
|
|
75
|
+
// Se sono in situazione di all-select anche metto la global checkbox, nonostante ci possano essere delle esclusioni
|
|
76
|
+
this.est.globalCheck = this.est.boundSource.length > 0 && this.est.boundSource.filter(t => t._group || t._item).every(t => t._selected);
|
|
77
|
+
this.est.canSelectAll = selectionItem.count > 0 && this.est.SelectAll;
|
|
78
|
+
// Potrebbe cambiare qualora qualcuno inserisse dati a manazza in modalità Array e desse il refresh manuale alla tabella
|
|
79
|
+
// Comunque costa 0 quindi mi permetto di refreshare
|
|
80
|
+
if (this.est.arrayMode) {
|
|
81
|
+
let prevSelected = this.est.selectedObjects;
|
|
82
|
+
this.finalizeSelectionInformations(selectionItem);
|
|
83
|
+
if (this.est.selectedObjects != prevSelected)
|
|
84
|
+
this.est.onSelectionChanged.emit(selectionItem);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Dato un oggetto trova la cella di cache in cui è registrato e aggiorna il contenuto
|
|
89
|
+
*
|
|
90
|
+
* @param {any} item Oggetto da aggiornare
|
|
91
|
+
*/
|
|
92
|
+
rehidrateCache(item) {
|
|
93
|
+
let ctx = item._hash;
|
|
94
|
+
if (this.itemsCache.has(ctx))
|
|
95
|
+
this.itemsCache.set(ctx, item);
|
|
96
|
+
if (this.group_exclusionsCache.has(ctx))
|
|
97
|
+
this.group_exclusionsCache.set(ctx, item);
|
|
98
|
+
if (this.groupsCache.has(ctx))
|
|
99
|
+
this.groupsCache.set(ctx, item);
|
|
100
|
+
if (this.exclusionsCache.has(ctx))
|
|
101
|
+
this.exclusionsCache.set(ctx, item);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Dato un gruppo controlla ricorsivamente l'albero di cui fa parte se c'è stata una inclusione o esclusione diretta
|
|
105
|
+
*
|
|
106
|
+
* @param {any} grp Gruppo da controllare
|
|
107
|
+
*
|
|
108
|
+
* @returns {'none' | 'excluded' | 'included'}
|
|
109
|
+
* 'none' se non ci sono informazioni su inclusioni o esclusioni
|
|
110
|
+
* 'included' se il gruppo controllato è stato incluso in maniera esplicita dall'albero dei gruppi padri
|
|
111
|
+
* 'excluded' se il gruppo controllato è stato escluso in maniera esplicita dall'albero dei gruppi padri
|
|
112
|
+
*/
|
|
113
|
+
parentTreeStatus(grp) {
|
|
114
|
+
if (!grp)
|
|
115
|
+
return 'none';
|
|
116
|
+
let parentGroup = this.rgHandler.rgGroupCache.get(grp._parent);
|
|
117
|
+
if (!parentGroup)
|
|
118
|
+
return 'none';
|
|
119
|
+
if (this.group_exclusionsCache.has(parentGroup._hash))
|
|
120
|
+
return 'excluded';
|
|
121
|
+
if (this.groupsCache.has(parentGroup._hash))
|
|
122
|
+
return 'included';
|
|
123
|
+
return this.parentTreeStatus(parentGroup);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Helper per gestire la selezione di N elementi utilizzando la Cache di selezione ed eventualmente aggiornando il concetto di "all selection"
|
|
127
|
+
*
|
|
128
|
+
* Vunziona sia in modalità Array che in modalità View Semplice o View Avanzata (con le Custom Cells)
|
|
129
|
+
*
|
|
130
|
+
* @param {any[]} items Oggetti da selezionare o deselezionare
|
|
131
|
+
* @param {boolean} forcedVal Valore forzato di check da assegnare agli oggetti
|
|
132
|
+
* @param {boolean} globalCheck Valore del check globale
|
|
133
|
+
*
|
|
134
|
+
* @returns {ItemsSelection<any>} Oggetto di selezione aggiornato con le informazioni sull'ultima operazione effettuata
|
|
135
|
+
*/
|
|
136
|
+
handleItemsSelection(items, forcedVal = null, globalCheck = null) {
|
|
137
|
+
let si = this.est.View?.selection || this.est.arraymodeSelection;
|
|
138
|
+
// Se sono in modalità di selezione singola e devo selezionare un'oggetto, per prima cosa devo deselezionare tutti gli altri
|
|
139
|
+
if (this.est.SingleSelection && items[0]?._selected && !items[0]?._group) {
|
|
140
|
+
if (items.length > 1 && forcedVal == null)
|
|
141
|
+
throw "Tentativo di selezionare o deselezionare più di un elemento con SingleSelection attivo";
|
|
142
|
+
if (items.length == 1 && forcedVal == null) {
|
|
143
|
+
si = this.handleItemsSelection(this.est.boundSource.filter(t => !t._group), false, null);
|
|
144
|
+
items[0]._selected = true;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
for (let i = 0; i < items.length; i++) {
|
|
148
|
+
let item = items[i];
|
|
149
|
+
let toChange = forcedVal != null ? item._selected != forcedVal : globalCheck != null ? item._selected != this.est.globalCheck : false;
|
|
150
|
+
// Se dev'essere overridato il valore di check effettuo l'override o col valore forzato o col valore globale
|
|
151
|
+
if (toChange && !item.locked)
|
|
152
|
+
item._selected = forcedVal != null ? forcedVal : this.est.globalCheck;
|
|
153
|
+
// Se il valore non dev'essere variato e vengo da una selezione globale semplicemente evito di effettuare operaizoni inutili. L'item/gruppo è già nello stato giusto
|
|
154
|
+
if (!toChange && globalCheck != null)
|
|
155
|
+
continue;
|
|
156
|
+
let allSelection = si.all;
|
|
157
|
+
let isGroup = item._group;
|
|
158
|
+
let isSelection = item._selected;
|
|
159
|
+
let itemGroup = null, allItems = null, selectedItems = null, unselectedItems = null, allGroups = null, selectedGroups = null, unselectedGroups = null, parentGroupSelected = null, parentGroupUnselected = null;
|
|
160
|
+
if (isGroup) {
|
|
161
|
+
let pts = this.parentTreeStatus(item);
|
|
162
|
+
parentGroupSelected = pts == 'included';
|
|
163
|
+
parentGroupUnselected = pts == 'excluded';
|
|
164
|
+
allItems = this.getGroupItems(si, item, null, true);
|
|
165
|
+
selectedItems = this.getGroupItems(si, item, 'selected', true, allItems);
|
|
166
|
+
unselectedItems = this.getGroupItems(si, item, 'unselected', true, allItems);
|
|
167
|
+
allGroups = this.getGroupChildGroups(si, item, null, true);
|
|
168
|
+
selectedGroups = this.getGroupChildGroups(si, item, 'selected', true, allGroups);
|
|
169
|
+
unselectedGroups = this.getGroupChildGroups(si, item, 'unselected', true, allGroups);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
itemGroup = this.getItemGroup(item);
|
|
173
|
+
parentGroupSelected = itemGroup == null ? null : itemGroup._selected;
|
|
174
|
+
parentGroupUnselected = itemGroup == null ? null : !itemGroup._selected;
|
|
175
|
+
}
|
|
176
|
+
if (!this.est.ArrayGrouping)
|
|
177
|
+
this.performSelectionOperations(si, item, allSelection, isGroup, isSelection, selectedItems, selectedGroups, unselectedItems, unselectedGroups, allItems, allGroups, parentGroupSelected, parentGroupUnselected);
|
|
178
|
+
else
|
|
179
|
+
this.performSimpleSelectionOperations(si, item, isGroup, isSelection, itemGroup, selectedItems, unselectedItems, allItems, allGroups);
|
|
180
|
+
}
|
|
181
|
+
// Imposto il check globale in base a se tutti gli elementi sono selezionati o meno.
|
|
182
|
+
// Evito di fare queste operazioni se la selezione deriva proprio dal global Check
|
|
183
|
+
if (globalCheck == null)
|
|
184
|
+
this.est.globalCheck = !this.est.boundSource.some(t => !t._selected && !t._sep);
|
|
185
|
+
this.finalizeSelectionInformations(si);
|
|
186
|
+
return si;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Dato L'oggetto di selezione, l'oggetto da selezionare/deselezionare e tutti i parametri del caso effettua le operazioni che servono.
|
|
190
|
+
*
|
|
191
|
+
* Logica semplificata rispetto all'originale **performSelectionOperations** per lavorare in una modalità in cui tutti gli elementi sono caricati (**ArrayGrouping** = true)
|
|
192
|
+
*/
|
|
193
|
+
performSimpleSelectionOperations(base, item, group, sel, itm_group, sel_itm, desel_itm, all_itms, all_grps) {
|
|
194
|
+
let tripticItem = this.getTriptic('item', base);
|
|
195
|
+
if (group) {
|
|
196
|
+
if (sel) {
|
|
197
|
+
all_grps.forEach(gr => { gr._selected = true; });
|
|
198
|
+
if (desel_itm)
|
|
199
|
+
desel_itm.forEach(el => { el._selected = true; this.addItem(el, tripticItem); });
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
all_grps.forEach(gr => { gr._selected = false; });
|
|
203
|
+
if (sel_itm)
|
|
204
|
+
sel_itm.forEach(el => { el._selected = false; this.removeItem(el, tripticItem); });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
if (sel) {
|
|
209
|
+
this.addItem(item, tripticItem);
|
|
210
|
+
if (itm_group && all_itms && all_itms.every(t => t._selected))
|
|
211
|
+
this.selectGroup(itm_group);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
this.removeItem(item, tripticItem);
|
|
215
|
+
if (itm_group)
|
|
216
|
+
itm_group._selected = false;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Helper per selezionare un gruppo e, ricorsivamente, se tutti i gruppi sottostanti al parent sono selezionati, selezionare i gruppi padri
|
|
222
|
+
*
|
|
223
|
+
* @param {any} group Gruppo da selezionare
|
|
224
|
+
*/
|
|
225
|
+
selectGroup(group) {
|
|
226
|
+
group._selected = true;
|
|
227
|
+
let parent = this.getGroupParent(group);
|
|
228
|
+
if (parent && this.getGroupChildGroups(null, parent, null, true).every(t => t._selected))
|
|
229
|
+
this.selectGroup(parent);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Dato L'oggetto di selezione, l'oggetto da selezionare/deselezionare e tutti i parametri del caso effettua le operazioni che servono.
|
|
233
|
+
*
|
|
234
|
+
* La logica di questa funzione è nata essenzialmente da spam di trial & error ed è stata testata solo fino a due livelli di raggruppamento,
|
|
235
|
+
* qualsiasi cosa vada oltre non è 100% detto che funzioni...
|
|
236
|
+
*/
|
|
237
|
+
performSelectionOperations(base, item, all, group, sel, sel_itm, sel_grp, desel_itm, desel_grp, all_itms, all_grps, parent_incl, parent_excl) {
|
|
238
|
+
let tripticGroup = this.getTriptic('group', base);
|
|
239
|
+
let tripticItem = this.getTriptic('item', base);
|
|
240
|
+
let tripticExcl = this.getTriptic('exclusion', base);
|
|
241
|
+
let tripticgrpExcl = this.getTriptic('group_exclusion', base);
|
|
242
|
+
if (group) {
|
|
243
|
+
if (sel) {
|
|
244
|
+
if (all || parent_incl)
|
|
245
|
+
this.removeItem(item, tripticgrpExcl);
|
|
246
|
+
else
|
|
247
|
+
this.addItem(item, tripticGroup);
|
|
248
|
+
if (sel_itm)
|
|
249
|
+
sel_itm.forEach(el => this.removeItem(el, tripticItem));
|
|
250
|
+
if (sel_grp)
|
|
251
|
+
sel_grp.forEach(gr => this.removeItem(gr, tripticGroup));
|
|
252
|
+
if (all_itms)
|
|
253
|
+
all_itms.forEach(el => { el._selected = true; this.removeItem(el, tripticExcl); });
|
|
254
|
+
if (all_grps)
|
|
255
|
+
all_grps.forEach(gr => { gr._selected = true; this.removeItem(gr, tripticgrpExcl); });
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
if (all || parent_incl)
|
|
259
|
+
this.addItem(item, tripticgrpExcl);
|
|
260
|
+
else
|
|
261
|
+
this.removeItem(item, tripticGroup);
|
|
262
|
+
if (desel_itm)
|
|
263
|
+
desel_itm.forEach(el => this.removeItem(el, tripticExcl));
|
|
264
|
+
if (desel_grp)
|
|
265
|
+
desel_grp.forEach(gr => this.removeItem(gr, tripticExcl));
|
|
266
|
+
if (all_itms)
|
|
267
|
+
all_itms.forEach(el => { el._selected = false; this.removeItem(el, tripticItem); });
|
|
268
|
+
if (all_grps)
|
|
269
|
+
all_grps.forEach(gr => { gr._selected = false; this.removeItem(gr, tripticGroup); });
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
if (sel) {
|
|
274
|
+
if ((parent_excl == null && all) || parent_incl)
|
|
275
|
+
this.removeItem(item, tripticExcl);
|
|
276
|
+
else
|
|
277
|
+
this.addItem(item, tripticItem);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
if (parent_excl || (!all && parent_excl == null))
|
|
281
|
+
this.removeItem(item, tripticItem);
|
|
282
|
+
else
|
|
283
|
+
this.addItem(item, tripticExcl);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/** Helper per evitare di riscrivere ogni santa volta array.splice(array.indexof(item), 1); */
|
|
288
|
+
removeItem(item, triptic) {
|
|
289
|
+
let index = triptic.index_cache.get(item._hash);
|
|
290
|
+
if (index != null) {
|
|
291
|
+
triptic.cache.delete(item._hash);
|
|
292
|
+
triptic.index_cache.delete(item._hash);
|
|
293
|
+
triptic.array[index] = null;
|
|
294
|
+
}
|
|
295
|
+
return !!index;
|
|
296
|
+
}
|
|
297
|
+
/** Helper per evitare di riscrivere ogni santa volta array.push(item); e la gestione della */
|
|
298
|
+
addItem(item, triptic) {
|
|
299
|
+
if (triptic.index_cache.get(item._hash) == null) {
|
|
300
|
+
let i = triptic.array.push(item) - 1;
|
|
301
|
+
triptic.cache.set(item._hash, item);
|
|
302
|
+
triptic.index_cache.set(item._hash, i);
|
|
303
|
+
return true;
|
|
304
|
+
}
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Ottiene il trittico di selezione, cioè l'array degli oggetti che si vuole manipolare e le due cache collegate ad esso
|
|
309
|
+
*
|
|
310
|
+
* @param {'group' | 'item' | 'group_exclusion' | 'exclusion'} subject Oggetto logico desiderato su cui effettuare le operazioni successive
|
|
311
|
+
* @param {ItemsSelection<any>} base Selettore di base
|
|
312
|
+
*
|
|
313
|
+
* @returns {CacheTriptic} Trittico di selezione
|
|
314
|
+
*/
|
|
315
|
+
getTriptic(subject, base) {
|
|
316
|
+
switch (subject) {
|
|
317
|
+
case 'group':
|
|
318
|
+
return new CacheTriptic(this.groupsCache, this.i_groupsCache, base.groups);
|
|
319
|
+
case 'item':
|
|
320
|
+
return new CacheTriptic(this.itemsCache, this.i_itemsCache, base.items);
|
|
321
|
+
case 'group_exclusion':
|
|
322
|
+
return new CacheTriptic(this.group_exclusionsCache, this.i_group_exclusionsCache, base.group_exclusions);
|
|
323
|
+
case 'exclusion':
|
|
324
|
+
return new CacheTriptic(this.exclusionsCache, this.i_exclusionsCache, base.exclusions);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Dato un oggetto restituisce il gruppo di cui fa parte, se esiste
|
|
329
|
+
*
|
|
330
|
+
* @param {any} item Oggetto di cui trovare il gruppo
|
|
331
|
+
*/
|
|
332
|
+
getItemGroup(item) {
|
|
333
|
+
let parent = this.rgHandler.rgGroupCache.get(item._thisKey);
|
|
334
|
+
if (parent)
|
|
335
|
+
return parent;
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Data la chiave di un gruppo restituisce tutti gli oggetti con quella chiave
|
|
340
|
+
*
|
|
341
|
+
* @param {any} group Chiave da cercare
|
|
342
|
+
* @param {'selected' | 'unselected'} status Stato degli elementi, selezionati o no
|
|
343
|
+
* @param {boolean} recursive Indica se cercare solo gli elementi direttamente collegati o se prendere anche quelli dei gruppi figli
|
|
344
|
+
*
|
|
345
|
+
* @returns {any[]} Oggetti di tipo **_item** facenti capo alla chiave **groupKey**
|
|
346
|
+
*/
|
|
347
|
+
getGroupItems(sel, group, status, recursive = false, allbase = null) {
|
|
348
|
+
let items = [];
|
|
349
|
+
if (allbase)
|
|
350
|
+
items = allbase;
|
|
351
|
+
else {
|
|
352
|
+
if (recursive) {
|
|
353
|
+
// In modalità ricorsiva prendo gli oggetti di tutte le chiavi simili che trovo
|
|
354
|
+
for (let key of this.rgHandler.rgItemCache.keys())
|
|
355
|
+
if (key.startsWith(group._thisKey))
|
|
356
|
+
items.push(...this.rgHandler.rgItemCache.get(key));
|
|
357
|
+
}
|
|
358
|
+
else
|
|
359
|
+
items = this.rgHandler.rgItemCache.get(group._thisKey);
|
|
360
|
+
}
|
|
361
|
+
items = items.filter(t => !status || (t._selected && status == 'selected') || (!t._selected && status == 'unselected'));
|
|
362
|
+
// Non trovo nessun oggetto, però magari di oggetti ne ho all'interno dell'oggetto di selezione.
|
|
363
|
+
// Questo può essere vero solo se NON sono in modalità array, in caso contrario gli oggetti li devo per forza avere tutti
|
|
364
|
+
if (items.length != 0 || !sel || this.est.arrayMode)
|
|
365
|
+
return items;
|
|
366
|
+
if (status == 'unselected')
|
|
367
|
+
items = sel.exclusions.filter(t => t != null &&
|
|
368
|
+
(!recursive && t._thisKey == group._thisKey) ||
|
|
369
|
+
(recursive && t._thisKey.startsWith(group._thisKey)));
|
|
370
|
+
else if (status == 'selected')
|
|
371
|
+
items = sel.items.filter(t => t != null &&
|
|
372
|
+
(!recursive && t._thisKey == group._thisKey) ||
|
|
373
|
+
(recursive && t._thisKey.startsWith(group._thisKey)));
|
|
374
|
+
return items;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Data la chiave di un gruppo restituisce tutti gli oggetti con quella chiave
|
|
378
|
+
*
|
|
379
|
+
* @param {any} group Gruppo di cui cercare il parent
|
|
380
|
+
*
|
|
381
|
+
* @returns {any} Oggetto di tipo **_group** rappresentante il parent del **group** attuale
|
|
382
|
+
*/
|
|
383
|
+
getGroupParent(group) {
|
|
384
|
+
let parent = this.rgHandler.rgGroupCache.get(group._parent);
|
|
385
|
+
if (parent)
|
|
386
|
+
return parent;
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Data la chiave di un gruppo restituisce tutti i gruppi figli
|
|
391
|
+
*
|
|
392
|
+
* @param {string} group Gruppo che rappresenta il padre di cui cercare i figli
|
|
393
|
+
* @param {'selected' | 'unselected'} status Stato dei gruppi, selezionati o no
|
|
394
|
+
* @param {boolean} recursive Indica se cercare solo i gruppi direttamente collegati o se prendere anche quelli dei gruppi figli
|
|
395
|
+
*
|
|
396
|
+
* @returns {any[]} Oggetti di tipo **_group** facenti capo alla chiave **groupKey**
|
|
397
|
+
*/
|
|
398
|
+
getGroupChildGroups(sel, group, status, recursive = false, allbase = null) {
|
|
399
|
+
let thisGroup = this.rgHandler.rgGroupCache.get(group._thisKey);
|
|
400
|
+
let items = [];
|
|
401
|
+
if (allbase)
|
|
402
|
+
items = allbase;
|
|
403
|
+
else {
|
|
404
|
+
if (recursive) {
|
|
405
|
+
// In modalità ricorsiva prendo gli oggetti di tutte le chiavi simili che trovo
|
|
406
|
+
for (let key of this.rgHandler.rgChildGroupsCache.keys())
|
|
407
|
+
if (key.startsWith(group._thisKey))
|
|
408
|
+
items.push(...this.rgHandler.rgChildGroupsCache.get(key));
|
|
409
|
+
}
|
|
410
|
+
else
|
|
411
|
+
items = this.rgHandler.rgChildGroupsCache.get(group._thisKey);
|
|
412
|
+
}
|
|
413
|
+
items = items.filter(t => !status || (t._selected && status == 'selected') || (!t._selected && status == 'unselected'));
|
|
414
|
+
// Non trovo nessun oggetto, però magari di oggetti ne ho all'interno dell'oggetto di selezione
|
|
415
|
+
if (items.length != 0 || !sel)
|
|
416
|
+
return items;
|
|
417
|
+
if (status == 'unselected')
|
|
418
|
+
items = sel.group_exclusions.filter((t) => t != null && ((!recursive && t._thisRoute.length == thisGroup._thisRoute.length + 1 && t._thisRoute.startsWith(group._thisKey)) ||
|
|
419
|
+
(recursive && t._thisKey.startsWith(group._thisKey))));
|
|
420
|
+
else
|
|
421
|
+
items = sel.groups.filter((t) => t != null && ((!recursive && t._thisRoute.length == thisGroup._thisRoute.length + 1 && t._thisRoute.startsWith(group._thisKey)) ||
|
|
422
|
+
(recursive && t._thisKey.startsWith(group._thisKey))));
|
|
423
|
+
return items;
|
|
424
|
+
}
|
|
425
|
+
/** Finalizza le informazioni di selezione del **ItemsSelection** corrente */
|
|
426
|
+
finalizeSelectionInformations(selectionItem) {
|
|
427
|
+
// Dato che le delete sono logiche dato che tengo la cache degli indici devo renderle fisiche
|
|
428
|
+
let tmpGrp = [], tmpItems = [], tmpExcl = [], tmpGrpExcl = [];
|
|
429
|
+
let grpRemoved = false, itemsRemoved = false, exclRemoved = false, grpExclRemoved = false;
|
|
430
|
+
for (let i = 0; i < selectionItem.items.length; i++)
|
|
431
|
+
if (selectionItem.items[i] != null)
|
|
432
|
+
tmpItems.push(selectionItem.items[i]);
|
|
433
|
+
else
|
|
434
|
+
itemsRemoved = true;
|
|
435
|
+
for (let i = 0; i < selectionItem.exclusions.length; i++)
|
|
436
|
+
if (selectionItem.exclusions[i] != null)
|
|
437
|
+
tmpExcl.push(selectionItem.exclusions[i]);
|
|
438
|
+
else
|
|
439
|
+
exclRemoved = true;
|
|
440
|
+
// In vecchie versioni dell'AppSearch per cui non vengono deserializzate queste informaizoni potrebbero esserci casini
|
|
441
|
+
if (selectionItem.groups) {
|
|
442
|
+
for (let i = 0; i < selectionItem.groups.length; i++)
|
|
443
|
+
if (selectionItem.groups[i] != null)
|
|
444
|
+
tmpGrp.push(selectionItem.groups[i]);
|
|
445
|
+
else
|
|
446
|
+
grpRemoved = true;
|
|
447
|
+
}
|
|
448
|
+
if (selectionItem.group_exclusions) {
|
|
449
|
+
for (let i = 0; i < selectionItem.group_exclusions.length; i++)
|
|
450
|
+
if (selectionItem.group_exclusions[i] != null)
|
|
451
|
+
tmpGrpExcl.push(selectionItem.group_exclusions[i]);
|
|
452
|
+
else
|
|
453
|
+
grpExclRemoved = true;
|
|
454
|
+
}
|
|
455
|
+
selectionItem.items = tmpItems;
|
|
456
|
+
selectionItem.group_exclusions = tmpGrpExcl;
|
|
457
|
+
selectionItem.exclusions = tmpExcl;
|
|
458
|
+
selectionItem.groups = tmpGrp;
|
|
459
|
+
// Le cache degli indici potrebbero avere buchi, risolvo
|
|
460
|
+
if (grpRemoved)
|
|
461
|
+
this.i_groupsCache = this.compactIndexMap(this.i_groupsCache);
|
|
462
|
+
if (itemsRemoved)
|
|
463
|
+
this.i_itemsCache = this.compactIndexMap(this.i_itemsCache);
|
|
464
|
+
if (exclRemoved)
|
|
465
|
+
this.i_exclusionsCache = this.compactIndexMap(this.i_exclusionsCache);
|
|
466
|
+
if (grpExclRemoved)
|
|
467
|
+
this.i_group_exclusionsCache = this.compactIndexMap(this.i_group_exclusionsCache);
|
|
468
|
+
// Poi riprendo a fare tutto in normalità
|
|
469
|
+
selectionItem.count = this.evaluateSelected();
|
|
470
|
+
// Se ho fatto selezione "all" ma poi mi sono messo a togliere tutti gli elementi fino a rimanerne 0 resetto l'oggetto di selezione
|
|
471
|
+
if (selectionItem.count == 0) {
|
|
472
|
+
this.est.boundSource.forEach(t => t._selected = false);
|
|
473
|
+
selectionItem.all = false;
|
|
474
|
+
selectionItem.exclusions = [];
|
|
475
|
+
selectionItem.items = [];
|
|
476
|
+
selectionItem.groups = [];
|
|
477
|
+
selectionItem.group_exclusions = [];
|
|
478
|
+
// Ripulisco la cache altrimenti mi rimane piena di tutte le esclusioni
|
|
479
|
+
this.clearSelectionCaches();
|
|
480
|
+
}
|
|
481
|
+
// Se la possibilità di fare "Seleziona tutto" è abilitata allora la considero appena mi viene selezionato qualcosa
|
|
482
|
+
this.est.canSelectAll = selectionItem.count > 0 && this.est.SelectAll;
|
|
483
|
+
}
|
|
484
|
+
/** Compatta una cache di indici */
|
|
485
|
+
compactIndexMap(map) {
|
|
486
|
+
let index = 0;
|
|
487
|
+
let ret = new Map();
|
|
488
|
+
for (let key of map.keys())
|
|
489
|
+
ret.set(key, index++);
|
|
490
|
+
return ret;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Valuta la quantità di oggetti che sono stati selezionati al termine di un evento di selezione
|
|
494
|
+
*
|
|
495
|
+
* @returns {number} Numero di oggetti selezionati
|
|
496
|
+
*/
|
|
497
|
+
evaluateSelected() {
|
|
498
|
+
let si = this.est.View?.selection || this.est.arraymodeSelection;
|
|
499
|
+
let excByGroup = si.group_exclusions.reduce((prev, curr) => prev + curr.count, 0);
|
|
500
|
+
let incByGroup = si.groups.reduce((prev, curr) => prev + curr.count, 0);
|
|
501
|
+
this.est.selectedObjects = (si.all ? this.est.BaseItemsCount : incByGroup) - excByGroup + si.items.length - si.exclusions.length;
|
|
502
|
+
return this.est.selectedObjects;
|
|
503
|
+
}
|
|
504
|
+
/** Gestisce il comando di "Seleziona tutto in tutte le pagine" o il suo contrario, cioè "Reimposta selezione" */
|
|
505
|
+
selectAllOrResetSelection() {
|
|
506
|
+
let selectionItem = this.est.View.selection || this.est.arraymodeSelection;
|
|
507
|
+
this.clearSelectionCaches();
|
|
508
|
+
selectionItem.all = !selectionItem.all;
|
|
509
|
+
selectionItem.exclusions = [];
|
|
510
|
+
selectionItem.groups = [];
|
|
511
|
+
selectionItem.group_exclusions = [];
|
|
512
|
+
selectionItem.items = [];
|
|
513
|
+
// Ripulisco gli stati UI di selezione globale se l'ho disattivata
|
|
514
|
+
if (!selectionItem.all) {
|
|
515
|
+
this.est.canSelectAll = false;
|
|
516
|
+
this.est.globalCheck = false;
|
|
517
|
+
}
|
|
518
|
+
this.finalizeSelectionInformations(selectionItem);
|
|
519
|
+
this.est.onSelectionChanged.emit(selectionItem);
|
|
520
|
+
// Dopo aver resettato direttamente il solo oggetto this.View.selection devo anche riallineare a tutti gli oggetti bindati
|
|
521
|
+
this.evaluateSelection(this.est.boundSource, selectionItem);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VsZWN0aW9uSGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2VzLXRhYmxlL3NyYy9saWIvY29yZS9oYW5kbGVycy9TZWxlY3Rpb25IYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQVFuRSxxREFBcUQ7QUFDckQsTUFBTSxPQUFPLGdCQUFnQjtJQW9CekIsMEJBQTBCO0lBQzFCLFlBQW9CLEdBQXFCLEVBQVUsU0FBNkI7UUFBNUQsUUFBRyxHQUFILEdBQUcsQ0FBa0I7UUFBVSxjQUFTLEdBQVQsU0FBUyxDQUFvQjtRQW5CaEYsK0hBQStIO1FBQ3ZILGVBQVUsR0FBcUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNqRCxpSUFBaUk7UUFDekgsZ0JBQVcsR0FBcUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNsRCxxSUFBcUk7UUFDN0gsb0JBQWUsR0FBcUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUN0RCwySUFBMkk7UUFDbkksMEJBQXFCLEdBQXFCLElBQUksR0FBRyxFQUFFLENBQUM7UUFFNUQsaUlBQWlJO1FBQ3pILGlCQUFZLEdBQXdCLElBQUksR0FBRyxFQUFFLENBQUM7UUFDdEQsbUlBQW1JO1FBQzNILGtCQUFhLEdBQXdCLElBQUksR0FBRyxFQUFFLENBQUM7UUFDdkQsdUlBQXVJO1FBQy9ILHNCQUFpQixHQUF3QixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQzNELDZJQUE2STtRQUNySSw0QkFBdUIsR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUdtQixDQUFDO0lBRXJGLHNDQUFzQztJQUMvQixvQkFBb0I7UUFDdkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUssRUFBRSxDQUFDO1FBRW5DLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3pDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLGlCQUFpQixDQUFDLEtBQVksRUFBRSxhQUFrQztRQUNyRSxJQUFJLENBQUMsYUFBYTtZQUNkLE9BQU87UUFFWCxJQUFJLENBQUMseUJBQXlCLENBQUMsS0FBSyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNLLHlCQUF5QixDQUFDLEtBQVksRUFBRSxhQUFrQztRQUM5RSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNuQyxJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbkIsSUFBSSxJQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQztZQUNyQixJQUFJLFNBQVMsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDM0Qsd0dBQXdHO1lBQ3hHLHNGQUFzRjtZQUN0RixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRXpCLElBQUksR0FBRyxDQUFDLEtBQUssRUFBRTtnQkFDWCxJQUFJLGFBQWEsQ0FBQyxHQUFHO29CQUNqQixHQUFHLENBQUMsU0FBUyxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDOztvQkFFakwsR0FBRyxDQUFDLFNBQVMsR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxJQUFJLFVBQVUsSUFBSSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUN6TztpQkFDSSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEVBQUU7Z0JBQ2pCLElBQUksYUFBYSxDQUFDLEdBQUc7b0JBQ2pCLEdBQUcsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxVQUFVLENBQUM7O29CQUVsRyxHQUFHLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxJQUFJLFVBQVUsSUFBSSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQzthQUN6STtTQUNKO1FBRUQscUdBQXFHO1FBQ3JHLG9IQUFvSDtRQUNwSCxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN4SSxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksR0FBRyxhQUFhLENBQUMsS0FBSyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQztRQUV0RSx3SEFBd0g7UUFDeEgsb0RBQW9EO1FBQ3BELElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUU7WUFDcEIsSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUM7WUFDNUMsSUFBSSxDQUFDLDZCQUE2QixDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ2xELElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxlQUFlLElBQUksWUFBWTtnQkFDeEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7U0FDdkQ7SUFDTCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLGNBQWMsQ0FBQyxJQUFTO1FBQzVCLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDckIsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7WUFDeEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRW5DLElBQUksSUFBSSxDQUFDLHFCQUFxQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7WUFDbkMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFOUMsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7WUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRXBDLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO1lBQzdCLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ssZ0JBQWdCLENBQUMsR0FBUTtRQUM3QixJQUFJLENBQUMsR0FBRztZQUNKLE9BQU8sTUFBTSxDQUFDO1FBRWxCLElBQUksV0FBVyxHQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFcEUsSUFBSSxDQUFDLFdBQVc7WUFDWixPQUFPLE1BQU0sQ0FBQztRQUVsQixJQUFJLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQztZQUNqRCxPQUFPLFVBQVUsQ0FBQztRQUV0QixJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUM7WUFDdkMsT0FBTyxVQUFVLENBQUM7UUFFdEIsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUdEOzs7Ozs7Ozs7O09BVUc7SUFDSSxvQkFBb0IsQ0FBQyxLQUFZLEVBQUUsWUFBcUIsSUFBSSxFQUFFLGNBQXVCLElBQUk7UUFDNUYsSUFBSSxFQUFFLEdBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUF1QixFQUFFLFNBQVMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDO1FBRXJGLDRIQUE0SDtRQUM1SCxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsZUFBZSxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFO1lBQ3RFLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksU0FBUyxJQUFJLElBQUk7Z0JBQ3JDLE1BQU0sd0ZBQXdGLENBQUM7WUFFbkcsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxTQUFTLElBQUksSUFBSSxFQUFFO2dCQUN4QyxFQUFFLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDekYsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7YUFDN0I7U0FDSjtRQUVELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ25DLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwQixJQUFJLFFBQVEsR0FBRyxTQUFTLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO1lBRXRJLDRHQUE0RztZQUM1RyxJQUFJLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO2dCQUN4QixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUM7WUFFMUUsb0tBQW9LO1lBQ3BLLElBQUksQ0FBQyxRQUFRLElBQUksV0FBVyxJQUFJLElBQUk7Z0JBQ2hDLFNBQVM7WUFFYixJQUFJLFlBQVksR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDO1lBQzFCLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDMUIsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUNqQyxJQUFJLFNBQVMsR0FBRyxJQUFJLEVBQUUsUUFBUSxHQUFHLElBQUksRUFBRSxhQUFhLEdBQUcsSUFBSSxFQUFFLGVBQWUsR0FBRyxJQUFJLEVBQUUsU0FBUyxHQUFHLElBQUksRUFBRSxjQUFjLEdBQUcsSUFBSSxFQUFFLGdCQUFnQixHQUFHLElBQUksRUFBRSxtQkFBbUIsR0FBRyxJQUFJLEVBQUUscUJBQXFCLEdBQUcsSUFBSSxDQUFDO1lBRWhOLElBQUksT0FBTyxFQUFFO2dCQUNULElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDdEMsbUJBQW1CLEdBQUcsR0FBRyxJQUFJLFVBQVUsQ0FBQztnQkFDeEMscUJBQXFCLEdBQUcsR0FBRyxJQUFJLFVBQVUsQ0FBQztnQkFDMUMsUUFBUSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ3BELGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDekUsZUFBZSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUM3RSxTQUFTLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUMzRCxjQUFjLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDakYsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQzthQUN4RjtpQkFDSTtnQkFDRCxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDcEMsbUJBQW1CLEdBQUcsU0FBUyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDO2dCQUNyRSxxQkFBcUIsR0FBRyxTQUFTLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQzthQUMzRTtZQUVELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWE7Z0JBQ3ZCLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsbUJBQW1CLEVBQUUscUJBQXFCLENBQUMsQ0FBQzs7Z0JBRWpOLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1NBQzdJO1FBRUQsb0ZBQW9GO1FBQ3BGLGtGQUFrRjtRQUNsRixJQUFJLFdBQVcsSUFBSSxJQUFJO1lBQ25CLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXBGLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUV2QyxPQUFPLEVBQUUsQ0FBQztJQUNkLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssZ0NBQWdDLENBQUMsSUFBeUIsRUFBRSxJQUFTLEVBQUUsS0FBYyxFQUFFLEdBQVksRUFBRSxTQUFjLEVBQUUsT0FBYyxFQUFFLFNBQWdCLEVBQUUsUUFBZSxFQUFFLFFBQWU7UUFDM0wsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFaEQsSUFBSSxLQUFLLEVBQUU7WUFDUCxJQUFJLEdBQUcsRUFBRTtnQkFDTCxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDakQsSUFBSSxTQUFTO29CQUNULFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLFdBQVcsQ0FBQyxDQUFBLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDdkY7aUJBQ0k7Z0JBQ0QsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2xELElBQUksT0FBTztvQkFDUCxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxXQUFXLENBQUMsQ0FBQSxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ3pGO1NBQ0o7YUFDSTtZQUNELElBQUksR0FBRyxFQUFFO2dCQUNMLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO2dCQUNoQyxJQUFJLFNBQVMsSUFBSSxRQUFRLElBQUksUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7b0JBQ3pELElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7YUFDbkM7aUJBQ0k7Z0JBQ0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7Z0JBQ25DLElBQUksU0FBUztvQkFDVCxTQUFTLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQzthQUNuQztTQUNKO0lBQ0wsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxXQUFXLENBQUMsS0FBVTtRQUMxQixLQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN2QixJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3hDLElBQUksTUFBTSxJQUFJLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ3BGLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssMEJBQTBCLENBQUMsSUFBeUIsRUFBRSxJQUFTLEVBQUUsR0FBWSxFQUFFLEtBQWMsRUFBRSxHQUFZLEVBQUUsT0FBYyxFQUFFLE9BQWMsRUFBRSxTQUFnQixFQUFFLFNBQWdCLEVBQUUsUUFBZSxFQUFFLFFBQWUsRUFBRSxXQUFvQixFQUFFLFdBQW9CO1FBQ2pRLElBQUksWUFBWSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2xELElBQUksV0FBVyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hELElBQUksV0FBVyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3JELElBQUksY0FBYyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFOUQsSUFBSSxLQUFLLEVBQUU7WUFDUCxJQUFJLEdBQUcsRUFBRTtnQkFDTCxJQUFJLEdBQUcsSUFBSSxXQUFXO29CQUNsQixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQzs7b0JBRXRDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFDO2dCQUVyQyxJQUFJLE9BQU87b0JBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7Z0JBQ3JFLElBQUksT0FBTztvQkFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztnQkFDdEUsSUFBSSxRQUFRO29CQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pHLElBQUksUUFBUTtvQkFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ3ZHO2lCQUNJO2dCQUNELElBQUksR0FBRyxJQUFJLFdBQVc7b0JBQ2xCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxDQUFDOztvQkFFbkMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUM7Z0JBRXhDLElBQUksU0FBUztvQkFBRSxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztnQkFDekUsSUFBSSxTQUFTO29CQUFFLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDO2dCQUN6RSxJQUFJLFFBQVE7b0JBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbEcsSUFBSSxRQUFRO29CQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDdEc7U0FDSjthQUNJO1lBQ0QsSUFBSSxHQUFHLEVBQUU7Z0JBQ0wsSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLElBQUksR0FBRyxDQUFDLElBQUksV0FBVztvQkFDM0MsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7O29CQUVuQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQzthQUN2QztpQkFDSTtnQkFDRCxJQUFJLFdBQVcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLFdBQVcsSUFBSSxJQUFJLENBQUM7b0JBQzVDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDOztvQkFFbkMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7YUFDdkM7U0FDSjtJQUNMLENBQUM7SUFFRCw4RkFBOEY7SUFDdEYsVUFBVSxDQUFDLElBQVMsRUFBRSxPQUFzQjtRQUNoRCxJQUFJLEtBQUssR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDaEQsSUFBSSxLQUFLLElBQUksSUFBSSxFQUFFO1lBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2pDLE9BQU8sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN2QyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQztTQUMvQjtRQUVELE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUNuQixDQUFDO0lBRUQsK0ZBQStGO0lBQ3ZGLE9BQU8sQ0FBQyxJQUFTLEVBQUUsT0FBc0I7UUFDN0MsSUFBSSxPQUFPLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxFQUFFO1lBQzdDLElBQUksQ0FBQyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNyQyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3BDLE9BQU8sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDdkMsT0FBTyxJQUFJLENBQUM7U0FDZjtRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0ssVUFBVSxDQUFDLE9BQTJELEVBQUUsSUFBeUI7UUFDckcsUUFBUSxPQUFPLEVBQUU7WUFDYixLQUFLLE9BQU87Z0JBQ1IsT0FBTyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQy9FLEtBQUssTUFBTTtnQkFDUCxPQUFPLElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUUsS0FBSyxpQkFBaUI7Z0JBQ2xCLE9BQU8sSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLHFCQUFxQixFQUFFLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUM3RyxLQUFLLFdBQVc7Z0JBQ1osT0FBTyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDOUY7SUFDTCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLFlBQVksQ0FBQyxJQUFTO1FBQzFCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDM0QsSUFBSSxNQUFNO1lBQ04sT0FBTyxNQUFNLENBQUM7UUFFbEIsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ssYUFBYSxDQUFDLEdBQXdCLEVBQUUsS0FBVSxFQUFFLE1BQWtDLEVBQUUsWUFBcUIsS0FBSyxFQUFFLFVBQWlCLElBQUk7UUFDN0ksSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBRWYsSUFBSSxPQUFPO1lBQ1AsS0FBSyxHQUFHLE9BQU8sQ0FBQzthQUNmO1lBQ0QsSUFBSSxTQUFTLEVBQUU7Z0JBQ1gsK0VBQStFO2dCQUMvRSxLQUFLLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRTtvQkFDN0MsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUM7d0JBQzlCLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQzthQUM5RDs7Z0JBRUcsS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDOUQ7UUFFRCxLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsSUFBSSxNQUFNLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLElBQUksTUFBTSxJQUFJLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFFeEgsaUdBQWlHO1FBQ2pHLHlIQUF5SDtRQUN6SCxJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUztZQUMvQyxPQUFPLEtBQUssQ0FBQztRQUVqQixJQUFJLE1BQU0sSUFBSSxZQUFZO1lBQ3RCLEtBQUssR0FBRyxHQUFHLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJO2dCQUN4QyxDQUFDLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxRQUFRLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQztnQkFDNUMsQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUN6RCxJQUFJLE1BQU0sSUFBSSxVQUFVO1lBQ3pCLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJO2dCQUNuQyxDQUFDLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxRQUFRLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQztnQkFDNUMsQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU5RCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssY0FBYyxDQUFDLEtBQVU7UUFDN0IsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUMzRCxJQUFJLE1BQU07WUFDTixPQUFPLE1BQU0sQ0FBQztRQUVsQixPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSyxtQkFBbUIsQ0FBQyxHQUF3QixFQUFFLEtBQVUsRUFBRSxNQUFrQyxFQUFFLFlBQXFCLEtBQUssRUFBRSxVQUFpQixJQUFJO1FBQ25KLElBQUksU0FBUyxHQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDckUsSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBRWYsSUFBSSxPQUFPO1lBQ1AsS0FBSyxHQUFHLE9BQU8sQ0FBQzthQUNmO1lBQ0QsSUFBSSxTQUFTLEVBQUU7Z0JBQ1gsK0VBQStFO2dCQUMvRSxLQUFLLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsSUFBSSxFQUFFO29CQUNwRCxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQzt3QkFDOUIsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7YUFDckU7O2dCQUVHLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDckU7UUFFRCxLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsSUFBSSxNQUFNLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLElBQUksTUFBTSxJQUFJLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFFeEgsK0ZBQStGO1FBQy9GLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHO1lBQ3pCLE9BQU8sS0FBSyxDQUFDO1FBRWpCLElBQUksTUFBTSxJQUFJLFlBQVk7WUFDdEIsS0FBSyxHQUFHLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksQ0FDekQsQ0FBQyxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sSUFBSSxTQUFTLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNqSCxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7O1lBRTNELEtBQUssR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUMvQyxDQUFDLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxJQUFJLFNBQVMsQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2pILENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUvRCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0lBRUQsNkVBQTZFO0lBQ3JFLDZCQUE2QixDQUFDLGFBQWtDO1FBQ3BFLDZGQUE2RjtRQUM3RixJQUFJLE1BQU0sR0FBRyxFQUFFLEVBQUUsUUFBUSxHQUFHLEVBQUUsRUFBRSxPQUFPLEdBQUcsRUFBRSxFQUFFLFVBQVUsR0FBRyxFQUFFLENBQUM7UUFDOUQsSUFBSSxVQUFVLEdBQUcsS0FBSyxFQUFFLFlBQVksR0FBRyxLQUFLLEVBQUUsV0FBVyxHQUFHLEtBQUssRUFBRSxjQUFjLEdBQUcsS0FBSyxDQUFDO1FBRTFGLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUU7WUFDL0MsSUFBSSxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUk7Z0JBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7O2dCQUNyRSxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBRTdCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxhQUFhLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUU7WUFDcEQsSUFBSSxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUk7Z0JBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7O2dCQUM5RSxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBRTVCLHNIQUFzSDtRQUN0SCxJQUFJLGFBQWEsQ0FBQyxNQUFNLEVBQUU7WUFDdEIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRTtnQkFDaEQsSUFBSSxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUk7b0JBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7O29CQUNyRSxVQUFVLEdBQUcsSUFBSSxDQUFDO1NBQzlCO1FBRUQsSUFBSSxhQUFhLENBQUMsZ0JBQWdCLEVBQUU7WUFDaEMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFO2dCQUMxRCxJQUFJLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJO29CQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7O29CQUM3RixjQUFjLEdBQUcsSUFBSSxDQUFDO1NBQ2xDO1FBRUQsYUFBYSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUM7UUFDL0IsYUFBYSxDQUFDLGdCQUFnQixHQUFHLFVBQVUsQ0FBQztRQUM1QyxhQUFhLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQztRQUNuQyxhQUFhLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUU5Qix3REFBd0Q7UUFDeEQsSUFBSSxVQUFVO1lBQ1YsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNsRSxJQUFJLFlBQVk7WUFDWixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ2hFLElBQUksV0FBVztZQUNYLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQzFFLElBQUksY0FBYztZQUNkLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBRXRGLHlDQUF5QztRQUN6QyxhQUFhLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBRTlDLG1JQUFtSTtRQUNuSSxJQUFJLGFBQWEsQ0FBQyxLQUFLLElBQUksQ0FBQyxFQUFFO1lBQzFCLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDLENBQUM7WUFDdkQsYUFBYSxDQUFDLEdBQUcsR0FBRyxLQUFLLENBQUM7WUFDMUIsYUFBYSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7WUFDOUIsYUFBYSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDekIsYUFBYSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7WUFDMUIsYUFBYSxDQUFDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztZQUVwQyx1RUFBdUU7WUFDdkUsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7U0FDL0I7UUFFRCxtSEFBbUg7UUFDbkgsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEdBQUcsYUFBYSxDQUFDLEtBQUssR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUM7SUFDMUUsQ0FBQztJQUVELG1DQUFtQztJQUMzQixlQUFlLENBQUMsR0FBd0I7UUFDNUMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ2QsSUFBSSxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNwQixLQUFLLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLEVBQUU7WUFDdEIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUUxQixPQUFPLEdBQUcsQ0FBQztJQUNmLENBQUM7SUFHRDs7OztPQUlHO0lBQ0ssZ0JBQWdCO1FBQ3BCLElBQUksRUFBRSxHQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBdUIsRUFBRSxTQUFTLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQztRQUVyRixJQUFJLFVBQVUsR0FBRyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDbEYsSUFBSSxVQUFVLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUV4RSxJQUFJLENBQUMsR0FBRyxDQUFDLGVBQWUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsR0FBRyxVQUFVLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUM7UUFDakksT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQztJQUNwQyxDQUFDO0lBRUQsaUhBQWlIO0lBQzFHLHlCQUF5QjtRQUM1QixJQUFJLGFBQWEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQztRQUMzRSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUM1QixhQUFhLENBQUMsR0FBRyxHQUFHLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQztRQUN2QyxhQUFhLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQztRQUM5QixhQUFhLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUMxQixhQUFhLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO1FBQ3BDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBRXpCLGtFQUFrRTtRQUNsRSxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRTtZQUNwQixJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7WUFDOUIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO1NBQ2hDO1FBRUQsSUFBSSxDQUFDLDZCQUE2QixDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRWxELElBQUksQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRWhELDBIQUEwSDtRQUMxSCxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDaEUsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiLy8gTW9kZWxsaVxyXG5pbXBvcnQgeyBBcHBTZWFyY2ggfSBmcm9tIFwiLi4vLi4vZG9tYWluL2V4dGVybmFscy9hcHBzZWFyY2gvQXBwU2VhcmNoXCI7XHJcbmltcG9ydCB7IEl0ZW1zU2VsZWN0aW9uIH0gZnJvbSBcIi4uLy4uL2RvbWFpbi9leHRlcm5hbHMvYXBwc2VhcmNoL0l0ZW1zU2VsZWN0aW9uXCI7XHJcbmltcG9ydCB7IENhY2hlVHJpcHRpYyB9IGZyb20gXCIuLi8uLi9kb21haW4vaW50ZXJuYWxzL0NhY2hlVHJpcHRpY1wiO1xyXG5cclxuLy8gQ29tcG9uZW50aVxyXG5pbXBvcnQgeyBFc1RhYmxlQ29tcG9uZW50IH0gZnJvbSBcIi4uLy4uL2NvbXBvbmVudHMvZXMtdGFibGUvZXNfdGFibGUuY29tcG9uZW50XCJcclxuXHJcbi8vIEhhbmRsZXJzXHJcbmltcG9ydCB7IFJvd0dyb3VwaW5nSGFuZGxlciB9IGZyb20gXCIuL1Jvd0dyb3VwaW5nSGFuZGxlclwiO1xyXG5cclxuLyoqIENsYXNzZSBjaGUgZ2VzdGlzY2UgbGUgc2VsZXppb25pIGRlZ2xpIG9nZ2V0dGkgKi9cclxuZXhwb3J0IGNsYXNzIFNlbGVjdGlvbkhhbmRsZXIge1xyXG5cclxuICAgIC8qKiBDYWNoZSBkaSBzZWxlemlvbmUgSGFzaCAtIE9nZ2V0dG8gcGVyIGxhIHZhcmlhYmlsZSAqKml0ZW1zKiogZGVsbCdpdGVtU2VsZWN0b3IuIEZhY2lsaXRhIGxlIG9wZXJhemlvbmkgZGkgbG9va3VwIHZpYSBoYXNoKi9cclxuICAgIHByaXZhdGUgaXRlbXNDYWNoZTogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcclxuICAgIC8qKiBDYWNoZSBkaSBzZWxlemlvbmUgSGFzaCAtIE9nZ2V0dG8gcGVyIGxhIHZhcmlhYmlsZSAqKmdyb3VwcyoqIGRlbGwnaXRlbVNlbGVjdG9yLiBGYWNpbGl0YSBsZSBvcGVyYXppb25pIGRpIGxvb2t1cCB2aWEgaGFzaCAqL1xyXG4gICAgcHJpdmF0ZSBncm91cHNDYWNoZTogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcclxuICAgIC8qKiBDYWNoZSBkaSBzZWxlemlvbmUgSGFzaCAtIE9nZ2V0dG8gcGVyIGxhIHZhcmlhYmlsZSAqKmV4Y2x1c2lvbnMqKiBkZWxsJ2l0ZW1TZWxlY3Rvci4gRmFjaWxpdGEgbGUgb3BlcmF6aW9uaSBkaSBsb29rdXAgdmlhIGhhc2ggKi9cclxuICAgIHByaXZhdGUgZXhjbHVzaW9uc0NhY2hlOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xyXG4gICAgLyoqIENhY2hlIGRpIHNlbGV6aW9uZSBIYXNoIC0gT2dnZXR0byBwZXIgbGEgdmFyaWFiaWxlICoqZ3JvdXBfZXhjbHVzaW9ucyoqIGRlbGwnaXRlbVNlbGVjdG9yLiBGYWNpbGl0YSBsZSBvcGVyYXppb25pIGRpIGxvb2t1cCB2aWEgaGFzaCAqL1xyXG4gICAgcHJpdmF0ZSBncm91cF9leGNsdXNpb25zQ2FjaGU6IE1hcDxzdHJpbmcsIGFueT4gPSBuZXcgTWFwKCk7XHJcblxyXG4gICAgLyoqIENhY2hlIGRpIHNlbGV6aW9uZSBIYXNoIC0gT2dnZXR0byBwZXIgbGEgdmFyaWFiaWxlICoqaXRlbXMqKiBkZWxsJ2l0ZW1TZWxlY3Rvci4gRmFjaWxpdGEgbGUgb3BlcmF6aW9uaSBkaSBsb29rdXAgdmlhIGluZGljZSovXHJcbiAgICBwcml2YXRlIGlfaXRlbXNDYWNoZTogTWFwPHN0cmluZywgbnVtYmVyPiA9IG5ldyBNYXAoKTtcclxuICAgIC8qKiBDYWNoZSBkaSBzZWxlemlvbmUgSGFzaCAtIE9nZ2V0dG8gcGVyIGxhIHZhcmlhYmlsZSAqKmdyb3VwcyoqIGRlbGwnaXRlbVNlbGVjdG9yLiBGYWNpbGl0YSBsZSBvcGVyYXppb25pIGRpIGxvb2t1cCB2aWEgaW5kaWNlICovXHJcbiAgICBwcml2YXRlIGlfZ3JvdXBzQ2FjaGU6IE1hcDxzdHJpbmcsIG51bWJlcj4gPSBuZXcgTWFwKCk7XHJcbiAgICAvKiogQ2FjaGUgZGkgc2VsZXppb25lIEhhc2ggLSBPZ2dldHRvIHBlciBsYSB2YXJpYWJpbGUgKipleGNsdXNpb25zKiogZGVsbCdpdGVtU2VsZWN0b3IuIEZhY2lsaXRhIGxlIG9wZXJhemlvbmkgZGkgbG9va3VwIHZpYSBpbmRpY2UgKi9cclxuICAgIHByaXZhdGUgaV9leGNsdXNpb25zQ2FjaGU6IE1hcDxzdHJpbmcsIG51bWJlcj4gPSBuZXcgTWFwKCk7XHJcbiAgICAvKiogQ2FjaGUgZGkgc2VsZXppb25lIEhhc2ggLSBPZ2dldHRvIHBlciBsYSB2YXJpYWJpbGUgKipncm91cF9leGNsdXNpb25zKiogZGVsbCdpdGVtU2VsZWN0b3IuIEZhY2lsaXRhIGxlIG9wZXJhemlvbmkgZGkgbG9va3VwIHZpYSBpbmRpY2UgKi9cclxuICAgIHByaXZhdGUgaV9ncm91cF9leGNsdXNpb25zQ2FjaGU6IE1hcDxzdHJpbmcsIG51bWJlcj4gPSBuZXcgTWFwKCk7XHJcblxyXG4gICAgLyoqIEBpZ25vcmUgQ29zdHJ1dHRvcmUgKi9cclxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZXN0OiBFc1RhYmxlQ29tcG9uZW50LCBwcml2YXRlIHJnSGFuZGxlcjogUm93R3JvdXBpbmdIYW5kbGVyKSB7IH1cclxuXHJcbiAgICAvKiogUmlwdWxpc2NlIGxlIGNhY2hlIGRpIHNlbGV6aW9uZSAqL1xyXG4gICAgcHVibGljIGNsZWFyU2VsZWN0aW9uQ2FjaGVzKCkge1xyXG4gICAgICAgIHRoaXMuaXRlbXNDYWNoZS5jbGVhcigpO1xyXG4gICAgICAgIHRoaXMuZ3JvdXBzQ2FjaGUuY2xlYXIoKTtcclxuICAgICAgICB0aGlzLmV4Y2x1c2lvbnNDYWNoZS5jbGVhcigpO1xyXG4gICAgICAgIHRoaXMuZ3JvdXBfZXhjbHVzaW9uc0NhY2hlLmNsZWFyKCk7XHJcblxyXG4gICAgICAgIHRoaXMuaV9pdGVtc0NhY2hlLmNsZWFyKCk7XHJcbiAgICAgICAgdGhpcy5pX2dyb3Vwc0NhY2hlLmNsZWFyKCk7XHJcbiAgICAgICAgdGhpcy5pX2V4Y2x1c2lvbnNDYWNoZS5jbGVhcigpO1xyXG4gICAgICAgIHRoaXMuaV9ncm91cF9leGNsdXNpb25zQ2FjaGUuY2xlYXIoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFZhbHV0YSBxdWFsaSBlbGVtZW50aSBkZXZvbm8gZXNzZXJlIG1hcmNhdGkgY29tZSBzZWxlemlvbmF0aSBuZWxsYSB2aXN0YSBhdHR1YWxlLiBTaSBiYXNhIHN1bGwnb2dnZXR0byAqKnNlbGVjdGlvbioqIGludGVybm8gYWxsJ0FwcFNlYXJjaFxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55W119IGl0ZW1zIE9nZ2V0dGkgZGkgY3VpIHZhbHV0YXJlIGxhIHNlbGV6aW9uZVxyXG4gICAgICogQHBhcmFtIHtJdGVtc1NlbGVjdGlvbjxhbnk+fSBzZWxlY3Rpb25JdGVtIE9nZ2V0dGkgZGkgc2VsZXppb25lIGRlcml2YW50ZSBkYWxsYSB2aWV3IG8gZGFsbCdvZ2dldHRvIHBlciBBcnJheVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZXZhbHVhdGVTZWxlY3Rpb24oaXRlbXM6IGFueVtdLCBzZWxlY3Rpb25JdGVtOiBJdGVtc1NlbGVjdGlvbjxhbnk+KSB7XHJcbiAgICAgICAgaWYgKCFzZWxlY3Rpb25JdGVtKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIHRoaXMuaGFuZGxlU2VsZWN0aW9uRXZhbHVhdGlvbihpdGVtcywgc2VsZWN0aW9uSXRlbSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbXBsZW1lbnRhemlvbmUgYWdub3N0aWNhIGRlbGxhIHZhbHV0YXppb25lIGRlbGxlIHNlbGV6aW9uaSBkZWdsaSBvZ2dldHRpLiBSaWNoaWVkZSBnbGkgb2dnZXR0aSBkZWxsYSB2aXN0YSBhdHR1YWxlIGUgbCdpdGVtU2VsZWN0b3JcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge2FueVtdfSBpdGVtcyBPZ2dldHRpIGRpIGN1aSBhZ2dpb3JuYXJlIGxvIHN0YXRvIGRpIHNlbGV6aW9uZVxyXG4gICAgICogQHBhcmFtIHtJdGVtc1NlbGVjdGlvbjxhbnk+fSBzZWxlY3Rpb25JdGVtIE9nZ2V0dG8gY29udGVuZW50ZSBsbyBzdGF0byBhdHR1YWxlIGRpIHNlbGV6aW9uZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGhhbmRsZVNlbGVjdGlvbkV2YWx1YXRpb24oaXRlbXM6IGFueVtdLCBzZWxlY3Rpb25JdGVtOiBJdGVtc1NlbGVjdGlvbjxhbnk+KSB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgaXRtID0gaXRlbXNbaV07XHJcbiAgICAgICAgICAgIGxldCBoYXNoID0gaXRtLl9oYXNoO1xyXG4gICAgICAgICAgICBsZXQgaXRlbUdyb3VwID0gaXRtLl9ncm91cCA/IG51bGwgOiB0aGlzLmdldEl0ZW1Hcm91cChpdG0pO1xyXG4gICAgICAgICAgICAvLyBSZWlkcmF0byBsYSBjYWNoZSBkaSBzZWxlemlvbmUgY29pIG51b3ZpIG9nZ2V0dGkgYWx0cmltZW50aSBub24gcml1c2NpcmVpIGEgYmVjY2FyZSBnbGkgaW5kaWNpIGdpdXN0aVxyXG4gICAgICAgICAgICAvLyBEb3BvZGljaMOpIGxhIHVzbyBwZXIgY2FsY29sYXJlIGlzdGFudGFuZWFtZW50ZSBzZSBnbGkgb2dnZXR0aSBzb25vIHNlbGV6aW9uYXRpIG8gbm9cclxuICAgICAgICAgICAgdGhpcy5yZWhpZHJhdGVDYWNoZShpdG0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKGl0bS5faXRlbSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvbkl0ZW0uYWxsKVxyXG4gICAgICAgICAgICAgICAgICAgIGl0bS5fc2VsZWN0ZWQgPSAhdGhpcy5leGNsdXNpb25zQ2FjaGUuaGFzKGhhc2gpICYmICgoIXRoaXMuZ3JvdXBzQ2FjaGUuaGFzKGl0ZW1Hcm91cD8uX2hhc2gpICYmIHRoaXMuaXRlbXNDYWNoZS5oYXMoaGFzaCkpIHx8ICF0aGlzLmdyb3VwX2V4Y2x1c2lvbnNDYWNoZS5oYXMoaXRlbUdyb3VwPy5faGFzaCkpO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIGl0bS5fc2VsZWN0ZWQgPSAhdGhpcy5leGNsdXNpb25zQ2FjaGUuaGFzKGhhc2gpICYmICh0aGlzLmdyb3Vwc0NhY2hlLmhhcyhpdGVtR3JvdXA/Ll9oYXNoKSB8fCB0aGlzLml0ZW1zQ2FjaGUuaGFzKGhhc2gpIHx8ICh0aGlzLnBhcmVudFRyZWVTdGF0dXMoaXRlbUdyb3VwKSA9PSAnaW5jbHVkZWQnICYmICF0aGlzLmdyb3VwX2V4Y2x1c2lvbnNDYWNoZS5oYXMoaXRlbUdyb3VwPy5faGFzaCkpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChpdG0uX2dyb3VwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uSXRlbS5hbGwpXHJcbiAgICAgICAgICAgICAgICAgICAgaXRtLl9zZWxlY3RlZCA9ICF0aGlzLmdyb3VwX2V4Y2x1c2lvbnNDYWNoZS5oYXMoaGFzaCkgJiYgdGhpcy5wYXJlbnRUcmVlU3RhdHVzKGl0bSkgIT0gJ2V4Y2x1ZGVkJztcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBpdG0uX3NlbGVjdGVkID0gdGhpcy5ncm91cHNDYWNoZS5oYXMoaGFzaCkgfHwgKHRoaXMucGFyZW50VHJlZVN0YXR1cyhpdG0pID09ICdpbmNsdWRlZCcgJiYgIXRoaXMuZ3JvdXBfZXhjbHVzaW9uc0NhY2hlLmhhcyhoYXNoKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFNlIHR1dHRpIGdsaSBvZ2dldHRpIGRpIHF1ZXN0YSBwYWdpbmEgc29ubyBzb2xlemlvbmF0aSBhbGxvcmEgcG9zc28gbWV0dGVyZSBpbCBnbG9iYWwgY2hlY2sgYSB0cnVlXHJcbiAgICAgICAgLy8gU2Ugc29ubyBpbiBzaXR1YXppb25lIGRpIGFsbC1zZWxlY3QgYW5jaGUgbWV0dG8gbGEgZ2xvYmFsIGNoZWNrYm94LCBub25vc3RhbnRlIGNpIHBvc3Nhbm8gZXNzZXJlIGRlbGxlIGVzY2x1c2lvbmlcclxuICAgICAgICB0aGlzLmVzdC5nbG9iYWxDaGVjayA9IHRoaXMuZXN0LmJvdW5kU291cmNlLmxlbmd0aCA+IDAgJiYgdGhpcy5lc3QuYm91bmRTb3VyY2UuZmlsdGVyKHQgPT4gdC5fZ3JvdXAgfHwgdC5faXRlbSkuZXZlcnkodCA9PiB0Ll9zZWxlY3RlZCk7XHJcbiAgICAgICAgdGhpcy5lc3QuY2FuU2VsZWN0QWxsID0gc2VsZWN0aW9uSXRlbS5jb3VudCA+IDAgJiYgdGhpcy5lc3QuU2VsZWN0QWxsO1xyXG5cclxuICAgICAgICAvLyBQb3RyZWJiZSBjYW1iaWFyZSBxdWFsb3JhIHF1YWxjdW5vIGluc2VyaXNzZSBkYXRpIGEgbWFuYXp6YSBpbiBtb2RhbGl0w6AgQXJyYXkgZSBkZXNzZSBpbCByZWZyZXNoIG1hbnVhbGUgYWxsYSB0YWJlbGxhXHJcbiAgICAgICAgLy8gQ29tdW5xdWUgY29zdGEgMCBxdWluZGkgbWkgcGVybWV0dG8gZGkgcmVmcmVzaGFyZVxyXG4gICAgICAgIGlmICh0aGlzLmVzdC5hcnJheU1vZGUpIHtcclxuICAgICAgICAgICAgbGV0IHByZXZTZWxlY3RlZCA9IHRoaXMuZXN0LnNlbGVjdGVkT2JqZWN0cztcclxuICAgICAgICAgICAgdGhpcy5maW5hbGl6ZVNlbGVjdGlvbkluZm9ybWF0aW9ucyhzZWxlY3Rpb25JdGVtKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuZXN0LnNlbGVjdGVkT2JqZWN0cyAhPSBwcmV2U2VsZWN0ZWQpXHJcbiAgICAgICAgICAgICAgICB0aGlzLmVzdC5vblNlbGVjdGlvbkNoYW5nZWQuZW1pdChzZWxlY3Rpb25JdGVtKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEYXRvIHVuIG9nZ2V0dG8gdHJvdmEgbGEgY2VsbGEgZGkgY2FjaGUgaW4gY3VpIMOoIHJlZ2lzdHJhdG8gZSBhZ2dpb3JuYSBpbCBjb250ZW51dG9cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IGl0ZW0gT2dnZXR0byBkYSBhZ2dpb3JuYXJlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgcmVoaWRyYXRlQ2FjaGUoaXRlbTogYW55KSB7XHJcbiAgICAgICAgbGV0IGN0eCA9IGl0ZW0uX2hhc2g7XHJcbiAgICAgICAgaWYgKHRoaXMuaXRlbXNDYWNoZS5oYXMoY3R4KSlcclxuICAgICAgICAgICAgdGhpcy5pdGVtc0NhY2hlLnNldChjdHgsIGl0ZW0pO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5ncm91cF9leGNsdXNpb25zQ2FjaGUuaGFzKGN0eCkpXHJcbiAgICAgICAgICAgIHRoaXMuZ3JvdXBfZXhjbHVzaW9uc0NhY2hlLnNldChjdHgsIGl0ZW0pO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5ncm91cHNDYWNoZS5oYXMoY3R4KSlcclxuICAgICAgICAgICAgdGhpcy5ncm91cHNDYWNoZS5zZXQoY3R4LCBpdGVtKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuZXhjbHVzaW9uc0NhY2hlLmhhcyhjdHgpKVxyXG4gICAgICAgICAgICB0aGlzLmV4Y2x1c2lvbnNDYWNoZS5zZXQoY3R4LCBpdGVtKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERhdG8gdW4gZ3J1cHBvIGNvbnRyb2xsYSByaWNvcnNpdmFtZW50ZSBsJ2FsYmVybyBkaSBjdWkgZmEgcGFydGUgc2UgYyfDqCBzdGF0YSB1bmEgaW5jbHVzaW9uZSBvIGVzY2x1c2lvbmUgZGlyZXR0YVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gZ3JwIEdydXBwbyBkYSBjb250cm9sbGFyZVxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7J25vbmUnIHwgJ2V4Y2x1ZGVkJyB8ICdpbmNsdWRlZCd9IFxyXG4gICAgICogJ25vbmUnIHNlIG5vbiBjaSBzb25vIGluZm9ybWF6aW9uaSBzdSBpbmNsdXNpb25pIG8gZXNjbHVzaW9uaSBcclxuICAgICAqICdpbmNsdWRlZCcgc2UgaWwgZ3J1cHBvIGNvbnRyb2xsYXRvIMOoIHN0YXRvIGluY2x1c28gaW4gbWFuaWVyYSBlc3BsaWNpdGEgZGFsbCdhbGJlcm8gZGVpIGdydXBwaSBwYWRyaVxyXG4gICAgICogJ2V4Y2x1ZGVkJyBzZSBpbCBncnVwcG8gY29udHJvbGxhdG8gw6ggc3RhdG8gZXNjbHVzbyBpbiBtYW5pZXJhIGVzcGxpY2l0YSBkYWxsJ2FsYmVybyBkZWkgZ3J1cHBpIHBhZHJpXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgcGFyZW50VHJlZVN0YXR1cyhncnA6IGFueSk6ICdub25lJyB8ICdleGNsdWRlZCcgfCAnaW5jbHVkZWQnIHtcclxuICAgICAgICBpZiAoIWdycClcclxuICAgICAgICAgICAgcmV0dXJuICdub25lJztcclxuXHJcbiAgICAgICAgbGV0IHBhcmVudEdyb3VwOiBhbnkgPSB0aGlzLnJnSGFuZGxlci5yZ0dyb3VwQ2FjaGUuZ2V0KGdycC5fcGFyZW50KTtcclxuXHJcbiAgICAgICAgaWYgKCFwYXJlbnRHcm91cClcclxuICAgICAgICAgICAgcmV0dXJuICdub25lJztcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuZ3JvdXBfZXhjbHVzaW9uc0NhY2hlLmhhcyhwYXJlbnRHcm91cC5faGFzaCkpXHJcbiAgICAgICAgICAgIHJldHVybiAnZXhjbHVkZWQnO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5ncm91cHNDYWNoZS5oYXMocGFyZW50R3JvdXAuX2hhc2gpKVxyXG4gICAgICAgICAgICByZXR1cm4gJ2luY2x1ZGVkJztcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50VHJlZVN0YXR1cyhwYXJlbnRHcm91cCk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGVscGVyIHBlciBnZXN0aXJlIGxhIHNlbGV6aW9uZSBkaSBOIGVsZW1lbnRpIHV0aWxpenphbmRvIGxhIENhY2hlIGRpIHNlbGV6aW9uZSBlZCBldmVudHVhbG1lbnRlIGFnZ2lvcm5hbmRvIGlsIGNvbmNldHRvIGRpIFwiYWxsIHNlbGVjdGlvblwiXHJcbiAgICAgKlxyXG4gICAgICogVnVuemlvbmEgc2lhIGluIG1vZGFsaXTDoCBBcnJheSBjaGUgaW4gbW9kYWxpdMOgIFZpZXcgU2VtcGxpY2UgbyBWaWV3IEF2YW56YXRhIChjb24gbGUgQ3VzdG9tIENlbGxzKVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55W119IGl0ZW1zIE9nZ2V0dGkgZGEgc2VsZXppb25hcmUgbyBkZXNlbGV6aW9uYXJlXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGZvcmNlZFZhbCBWYWxvcmUgZm9yemF0byBkaSBjaGVjayBkYSBhc3NlZ25hcmUgYWdsaSBvZ2dldHRpXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGdsb2JhbENoZWNrIFZhbG9yZSBkZWwgY2hlY2sgZ2xvYmFsZVxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtJdGVtc1NlbGVjdGlvbjxhbnk+fSBPZ2dldHRvIGRpIHNlbGV6aW9uZSBhZ2dpb3JuYXRvIGNvbiBsZSBpbmZvcm1hemlvbmkgc3VsbCd1bHRpbWEgb3BlcmF6aW9uZSBlZmZldHR1YXRhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBoYW5kbGVJdGVtc1NlbGVjdGlvbihpdGVtczogYW55W10sIGZvcmNlZFZhbDogYm9vbGVhbiA9IG51bGwsIGdsb2JhbENoZWNrOiBib29sZWFuID0gbnVsbCk6IEl0ZW1zU2VsZWN0aW9uPGFueT4ge1xyXG4gICAgICAgIGxldCBzaSA9ICh0aGlzLmVzdC5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+KT8uc2VsZWN0aW9uIHx8IHRoaXMuZXN0LmFycmF5bW9kZVNlbGVjdGlvbjtcclxuXHJcbiAgICAgICAgLy8gU2Ugc29ubyBpbiBtb2RhbGl0w6AgZGkgc2VsZXppb25lIHNpbmdvbGEgZSBkZXZvIHNlbGV6aW9uYXJlIHVuJ29nZ2V0dG8sIHBlciBwcmltYSBjb3NhIGRldm8gZGVzZWxlemlvbmFyZSB0dXR0aSBnbGkgYWx0cmlcclxuICAgICAgICBpZiAodGhpcy5lc3QuU2luZ2xlU2VsZWN0aW9uICYmIGl0ZW1zWzBdPy5fc2VsZWN0ZWQgJiYgIWl0ZW1zWzBdPy5fZ3JvdXApIHtcclxuICAgICAgICAgICAgaWYgKGl0ZW1zLmxlbmd0aCA+IDEgJiYgZm9yY2VkVmFsID09IG51bGwpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBcIlRlbnRhdGl2byBkaSBzZWxlemlvbmFyZSBvIGRlc2VsZXppb25hcmUgcGnDuSBkaSB1biBlbGVtZW50byBjb24gU2luZ2xlU2VsZWN0aW9uIGF0dGl2b1wiO1xyXG5cclxuICAgICAgICAgICAgaWYgKGl0ZW1zLmxlbmd0aCA9PSAxICYmIGZvcmNlZFZhbCA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBzaSA9IHRoaXMuaGFuZGxlSXRlbXNTZWxlY3Rpb24odGhpcy5lc3QuYm91bmRTb3VyY2UuZmlsdGVyKHQgPT4gIXQuX2dyb3VwKSwgZmFsc2UsIG51bGwpO1xyXG4gICAgICAgICAgICAgICAgaXRlbXNbMF0uX3NlbGVjdGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgaXRlbSA9IGl0ZW1zW2ldO1xyXG4gICAgICAgICAgICBsZXQgdG9DaGFuZ2UgPSBmb3JjZWRWYWwgIT0gbnVsbCA/IGl0ZW0uX3NlbGVjdGVkICE9IGZvcmNlZFZhbCA6IGdsb2JhbENoZWNrICE9IG51bGwgPyBpdGVtLl9zZWxlY3RlZCAhPSB0aGlzLmVzdC5nbG9iYWxDaGVjayA6IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgLy8gU2UgZGV2J2Vzc2VyZSBvdmVycmlkYXRvIGlsIHZhbG9yZSBkaSBjaGVjayBlZmZldHR1byBsJ292ZXJyaWRlIG8gY29sIHZhbG9yZSBmb3J6YXRvIG8gY29sIHZhbG9yZSBnbG9iYWxlXHJcbiAgICAgICAgICAgIGlmICh0b0NoYW5nZSAmJiAhaXRlbS5sb2NrZWQpXHJcbiAgICAgICAgICAgICAgICBpdGVtLl9zZWxlY3RlZCA9IGZvcmNlZFZhbCAhPSBudWxsID8gZm9yY2VkVmFsIDogdGhpcy5lc3QuZ2xvYmFsQ2hlY2s7XHJcblxyXG4gICAgICAgICAgICAvLyBTZSBpbCB2YWxvcmUgbm9uIGRldidlc3NlcmUgdmFyaWF0byBlIHZlbmdvIGRhIHVuYSBzZWxlemlvbmUgZ2xvYmFsZSBzZW1wbGljZW1lbnRlIGV2aXRvIGRpIGVmZmV0dHVhcmUgb3BlcmFpem9uaSBpbnV0aWxpLiBMJ2l0ZW0vZ3J1cHBvIMOoIGdpw6AgbmVsbG8gc3RhdG8gZ2l1c3RvXHJcbiAgICAgICAgICAgIGlmICghdG9DaGFuZ2UgJiYgZ2xvYmFsQ2hlY2sgIT0gbnVsbClcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgbGV0IGFsbFNlbGVjdGlvbiA9IHNpLmFsbDtcclxuICAgICAgICAgICAgbGV0IGlzR3JvdXAgPSBpdGVtLl9ncm91cDtcclxuICAgICAgICAgICAgbGV0IGlzU2VsZWN0aW9uID0gaXRlbS5fc2VsZWN0ZWQ7XHJcbiAgICAgICAgICAgIGxldCBpdGVtR3JvdXAgPSBudWxsLCBhbGxJdGVtcyA9IG51bGwsIHNlbGVjdGVkSXRlbXMgPSBudWxsLCB1bnNlbGVjdGVkSXRlbXMgPSBudWxsLCBhbGxHcm91cHMgPSBudWxsLCBzZWxlY3RlZEdyb3VwcyA9IG51bGwsIHVuc2VsZWN0ZWRHcm91cHMgPSBudWxsLCBwYXJlbnRHcm91cFNlbGVjdGVkID0gbnVsbCwgcGFyZW50R3JvdXBVbnNlbGVjdGVkID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgIGlmIChpc0dyb3VwKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgcHRzID0gdGhpcy5wYXJlbnRUcmVlU3RhdHVzKGl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgcGFyZW50R3JvdXBTZWxlY3RlZCA9IHB0cyA9PSAnaW5jbHVkZWQnO1xyXG4gICAgICAgICAgICAgICAgcGFyZW50R3JvdXBVbnNlbGVjdGVkID0gcHRzID09ICdleGNsdWRlZCc7XHJcbiAgICAgICAgICAgICAgICBhbGxJdGVtcyA9IHRoaXMuZ2V0R3JvdXBJdGVtcyhzaSwgaXRlbSwgbnVsbCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEl0ZW1zID0gdGhpcy5nZXRHcm91cEl0ZW1zKHNpLCBpdGVtLCAnc2VsZWN0ZWQnLCB0cnVlLCBhbGxJdGVtcyk7XHJcbiAgICAgICAgICAgICAgICB1bnNlbGVjdGVkSXRlbXMgPSB0aGlzLmdldEdyb3VwSXRlbXMoc2ksIGl0ZW0sICd1bnNlbGVjdGVkJywgdHJ1ZSwgYWxsSXRlbXMpO1xyXG4gICAgICAgICAgICAgICAgYWxsR3JvdXBzID0gdGhpcy5nZXRHcm91cENoaWxkR3JvdXBzKHNpLCBpdGVtLCBudWxsLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgIHNlbGVjdGVkR3JvdXBzID0gdGhpcy5nZXRHcm91cENoaWxkR3JvdXBzKHNpLCBpdGVtLCAnc2VsZWN0ZWQnLCB0cnVlLCBhbGxHcm91cHMpO1xyXG4gICAgICAgICAgICAgICAgdW5zZWxlY3RlZEdyb3VwcyA9IHRoaXMuZ2V0R3JvdXBDaGlsZEdyb3VwcyhzaSwgaXRlbSwgJ3Vuc2VsZWN0ZWQnLCB0cnVlLCBhbGxHcm91cHMpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaXRlbUdyb3VwID0gdGhpcy5nZXRJdGVtR3JvdXAoaXRlbSk7XHJcbiAgICAgICAgICAgICAgICBwYXJlbnRHcm91cFNlbGVjdGVkID0gaXRlbUdyb3VwID09IG51bGwgPyBudWxsIDogaXRlbUdyb3VwLl9zZWxlY3RlZDtcclxuICAgICAgICAgICAgICAgIHBhcmVudEdyb3VwVW5zZWxlY3RlZCA9IGl0ZW1Hcm91cCA9PSBudWxsID8gbnVsbCA6ICFpdGVtR3JvdXAuX3NlbGVjdGVkO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuZXN0LkFycmF5R3JvdXBpbmcpXHJcbiAgICAgICAgICAgICAgICB0aGlzLnBlcmZvcm1TZWxlY3Rpb25PcGVyYXRpb25zKHNpLCBpdGVtLCBhbGxTZWxlY3Rpb24sIGlzR3JvdXAsIGlzU2VsZWN0aW9uLCBzZWxlY3RlZEl0ZW1zLCBzZWxlY3RlZEdyb3VwcywgdW5zZWxlY3RlZEl0ZW1zLCB1bnNlbGVjdGVkR3JvdXBzLCBhbGxJdGVtcywgYWxsR3JvdXBzLCBwYXJlbnRHcm91cFNlbGVjdGVkLCBwYXJlbnRHcm91cFVuc2VsZWN0ZWQpO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICB0aGlzLnBlcmZvcm1TaW1wbGVTZWxlY3Rpb25PcGVyYXRpb25zKHNpLCBpdGVtLCBpc0dyb3VwLCBpc1NlbGVjdGlvbiwgaXRlbUdyb3VwLCBzZWxlY3RlZEl0ZW1zLCB1bnNlbGVjdGVkSXRlbXMsIGFsbEl0ZW1zLCBhbGxHcm91cHMpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSW1wb3N0byBpbCBjaGVjayBnbG9iYWxlIGluIGJhc2UgYSBzZSB0dXR0aSBnbGkgZWxlbWVudGkgc29ubyBzZWxlemlvbmF0aSBvIG1lbm8uXHJcbiAgICAgICAgLy8gRXZpdG8gZGkgZmFyZSBxdWVzdGUgb3BlcmF6aW9uaSBzZSBsYSBzZWxlemlvbmUgZGVyaXZhIHByb3ByaW8gZGFsIGdsb2JhbCBDaGVja1xyXG4gICAgICAgIGlmIChnbG9iYWxDaGVjayA9PSBudWxsKVxyXG4gICAgICAgICAgICB0aGlzLmVzdC5nbG9iYWxDaGVjayA9ICF0aGlzLmVzdC5ib3VuZFNvdXJjZS5zb21lKHQgPT4gIXQuX3NlbGVjdGVkICYmICF0Ll9zZXApO1xyXG5cclxuICAgICAgICB0aGlzLmZpbmFsaXplU2VsZWN0aW9uSW5mb3JtYXRpb25zKHNpKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHNpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGF0byBMJ29nZ2V0dG8gZGkgc2VsZXppb25lLCBsJ29nZ2V0dG8gZGEgc2VsZXppb25hcmUvZGVzZWxlemlvbmFyZSBlIHR1dHRpIGkgcGFyYW1ldHJpIGRlbCBjYXNvIGVmZmV0dHVhIGxlIG9wZXJhemlvbmkgY2hlIHNlcnZvbm8uXHJcbiAgICAgKiBcclxuICAgICAqIExvZ2ljYSBzZW1wbGlmaWNhdGEgcmlzcGV0dG8gYWxsJ29yaWdpbmFsZSAqKnBlcmZvcm1TZWxlY3Rpb25PcGVyYXRpb25zKiogcGVyIGxhdm9yYXJlIGluIHVuYSBtb2RhbGl0w6AgaW4gY3VpIHR1dHRpIGdsaSBlbGVtZW50aSBzb25vIGNhcmljYXRpICgqKkFycmF5R3JvdXBpbmcqKiA9IHRydWUpXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgcGVyZm9ybVNpbXBsZVNlbGVjdGlvbk9wZXJhdGlvbnMoYmFzZTogSXRlbXNTZWxlY3Rpb248YW55PiwgaXRlbTogYW55LCBncm91cDogYm9vbGVhbiwgc2VsOiBib29sZWFuLCBpdG1fZ3JvdXA6IGFueSwgc2VsX2l0bTogYW55W10sIGRlc2VsX2l0bTogYW55W10sIGFsbF9pdG1zOiBhbnlbXSwgYWxsX2dycHM6IGFueVtdKSB7XHJcbiAgICAgICAgbGV0IHRyaXB0aWNJdGVtID0gdGhpcy5nZXRUcmlwdGljKCdpdGVtJywgYmFzZSk7XHJcblxyXG4gICAgICAgIGlmIChncm91cCkge1xyXG4gICAgICAgICAgICBpZiAoc2VsKSB7XHJcbiAgICAgICAgICAgICAgICBhbGxfZ3Jwcy5mb3JFYWNoKGdyID0+IHsgZ3IuX3NlbGVjdGVkID0gdHJ1ZTsgfSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGVzZWxfaXRtKVxyXG4gICAgICAgICAgICAgICAgICAgIGRlc2VsX2l0bS5mb3JFYWNoKGVsID0+IHsgZWwuX3NlbGVjdGVkID0gdHJ1ZTsgdGhpcy5hZGRJdGVtKGVsLCB0cmlwdGljSXRlbSkgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBhbGxfZ3Jwcy5mb3JFYWNoKGdyID0+IHsgZ3IuX3NlbGVjdGVkID0gZmFsc2U7IH0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlbF9pdG0pXHJcbiAgICAgICAgICAgICAgICAgICAgc2VsX2l0bS5mb3JFYWNoKGVsID0+IHsgZWwuX3NlbGVjdGVkID0gZmFsc2U7IHRoaXMucmVtb3ZlSXRlbShlbCwgdHJpcHRpY0l0ZW0pIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAoc2VsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmFkZEl0ZW0oaXRlbSwgdHJpcHRpY0l0ZW0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKGl0bV9ncm91cCAmJiBhbGxfaXRtcyAmJiBhbGxfaXRtcy5ldmVyeSh0ID0+IHQuX3NlbGVjdGVkKSlcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdEdyb3VwKGl0bV9ncm91cCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUl0ZW0oaXRlbSwgdHJpcHRpY0l0ZW0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKGl0bV9ncm91cClcclxuICAgICAgICAgICAgICAgICAgICBpdG1fZ3JvdXAuX3NlbGVjdGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIZWxwZXIgcGVyIHNlbGV6aW9uYXJlIHVuIGdydXBwbyBlLCByaWNvcnNpdmFtZW50ZSwgc2UgdHV0dGkgaSBncnVwcGkgc290dG9zdGFudGkgYWwgcGFyZW50IHNvbm8gc2VsZXppb25hdGksIHNlbGV6aW9uYXJlIGkgZ3J1cHBpIHBhZHJpXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55fSBncm91cCBHcnVwcG8gZGEgc2VsZXppb25hcmVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBzZWxlY3RHcm91cChncm91cDogYW55KSB7XHJcbiAgICAgICAgZ3JvdXAuX3NlbGVjdGVkID0gdHJ1ZTtcclxuICAgICAgICBsZXQgcGFyZW50ID0gdGhpcy5nZXRHcm91cFBhcmVudChncm91cCk7XHJcbiAgICAgICAgaWYgKHBhcmVudCAmJiB0aGlzLmdldEdyb3VwQ2hpbGRHcm91cHMobnVsbCwgcGFyZW50LCBudWxsLCB0cnVlKS5ldmVyeSh0ID0+IHQuX3NlbGVjdGVkKSlcclxuICAgICAgICAgICAgdGhpcy5zZWxlY3RHcm91cChwYXJlbnQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGF0byBMJ29nZ2V0dG8gZGkgc2VsZXppb25lLCBsJ29nZ2V0dG8gZGEgc2VsZXppb25hcmUvZGVzZWxlemlvbmFyZSBlIHR1dHRpIGkgcGFyYW1ldHJpIGRlbCBjYXNvIGVmZmV0dHVhIGxlIG9wZXJhemlvbmkgY2hlIHNlcnZvbm8uXHJcbiAgICAgKiBcclxuICAgICAqIExhIGxvZ2ljYSBkaSBxdWVzdGEgZnVuemlvbmUgw6ggbmF0YSBlc3NlbnppYWxtZW50ZSBkYSBzcGFtIGRpIHRyaWFsICYgZXJyb3IgZWQgw6ggc3RhdGEgdGVzdGF0YSBzb2xvIGZpbm8gYSBkdWUgbGl2ZWxsaSBkaSByYWdncnVwcGFtZW50byxcclxuICAgICAqIHF1YWxzaWFzaSBjb3NhIHZhZGEgb2x0cmUgbm9uIMOoIDEwMCUgZGV0dG8gY2hlIGZ1bnppb25pLi4uXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgcGVyZm9ybVNlbGVjdGlvbk9wZXJhdGlvbnMoYmFzZTogSXRlbXNTZWxlY3Rpb248YW55PiwgaXRlbTogYW55LCBhbGw6IGJvb2xlYW4sIGdyb3VwOiBib29sZWFuLCBzZWw6IGJvb2xlYW4sIHNlbF9pdG06IGFueVtdLCBzZWxfZ3JwOiBhbnlbXSwgZGVzZWxfaXRtOiBhbnlbXSwgZGVzZWxfZ3JwOiBhbnlbXSwgYWxsX2l0bXM6IGFueVtdLCBhbGxfZ3JwczogYW55W10sIHBhcmVudF9pbmNsOiBib29sZWFuLCBwYXJlbnRfZXhjbDogYm9vbGVhbikge1xyXG4gICAgICAgIGxldCB0cmlwdGljR3JvdXAgPSB0aGlzLmdldFRyaXB0aWMoJ2dyb3VwJywgYmFzZSk7XHJcbiAgICAgICAgbGV0IHRyaXB0aWNJdGVtID0gdGhpcy5nZXRUcmlwdGljKCdpdGVtJywgYmFzZSk7XHJcbiAgICAgICAgbGV0IHRyaXB0aWNFeGNsID0gdGhpcy5nZXRUcmlwdGljKCdleGNsdXNpb24nLCBiYXNlKTtcclxuICAgICAgICBsZXQgdHJpcHRpY2dycEV4Y2wgPSB0aGlzLmdldFRyaXB0aWMoJ2dyb3VwX2V4Y2x1c2lvbicsIGJhc2UpO1xyXG5cclxuICAgICAgICBpZiAoZ3JvdXApIHtcclxuICAgICAgICAgICAgaWYgKHNlbCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFsbCB8fCBwYXJlbnRfaW5jbClcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUl0ZW0oaXRlbSwgdHJpcHRpY2dycEV4Y2wpO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkSXRlbShpdGVtLCB0cmlwdGljR3JvdXApO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChzZWxfaXRtKSBzZWxfaXRtLmZvckVhY2goZWwgPT4gdGhpcy5yZW1vdmVJdGVtKGVsLCB0cmlwdGljSXRlbSkpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlbF9ncnApIHNlbF9ncnAuZm9yRWFjaChnciA9PiB0aGlzLnJlbW92ZUl0ZW0oZ3IsIHRyaXB0aWNHcm91cCkpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGFsbF9pdG1zKSBhbGxfaXRtcy5mb3JFYWNoKGVsID0+IHsgZWwuX3NlbGVjdGVkID0gdHJ1ZTsgdGhpcy5yZW1vdmVJdGVtKGVsLCB0cmlwdGljRXhjbCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKGFsbF9ncnBzKSBhbGxfZ3Jwcy5mb3JFYWNoKGdyID0+IHsgZ3IuX3NlbGVjdGVkID0gdHJ1ZTsgdGhpcy5yZW1vdmVJdGVtKGdyLCB0cmlwdGljZ3JwRXhjbCk7IH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFsbCB8fCBwYXJlbnRfaW5jbClcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZEl0ZW0oaXRlbSwgdHJpcHRpY2dycEV4Y2wpO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlSXRlbShpdGVtLCB0cmlwdGljR3JvdXApO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChkZXNlbF9pdG0pIGRlc2VsX2l0bS5mb3JFYWNoKGVsID0+IHRoaXMucmVtb3ZlSXRlbShlbCwgdHJpcHRpY0V4Y2wpKTtcclxuICAgICAgICAgICAgICAgIGlmIChkZXNlbF9ncnApIGRlc2VsX2dycC5mb3JFYWNoKGdyID0+IHRoaXMucmVtb3ZlSXRlbShnciwgdHJpcHRpY0V4Y2wpKTtcclxuICAgICAgICAgICAgICAgIGlmIChhbGxfaXRtcykgYWxsX2l0bXMuZm9yRWFjaChlbCA9PiB7IGVsLl9zZWxlY3RlZCA9IGZhbHNlOyB0aGlzLnJlbW92ZUl0ZW0oZWwsIHRyaXB0aWNJdGVtKTsgfSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoYWxsX2dycHMpIGFsbF9ncnBzLmZvckVhY2goZ3IgPT4geyBnci5fc2VsZWN0ZWQgPSBmYWxzZTsgdGhpcy5yZW1vdmVJdGVtKGdyLCB0cmlwdGljR3JvdXApOyB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHNlbCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKChwYXJlbnRfZXhjbCA9PSBudWxsICYmIGFsbCkgfHwgcGFyZW50X2luY2wpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVJdGVtKGl0ZW0sIHRyaXB0aWNFeGNsKTtcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZEl0ZW0oaXRlbSwgdHJpcHRpY0l0ZW0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKHBhcmVudF9leGNsIHx8ICghYWxsICYmIHBhcmVudF9leGNsID09IG51bGwpKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlSXRlbShpdGVtLCB0cmlwdGljSXRlbSk7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRJdGVtKGl0ZW0sIHRyaXB0aWNFeGNsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiogSGVscGVyIHBlciBldml0YXJlIGRpIHJpc2NyaXZlcmUgb2duaSBzYW50YSB2b2x0YSBhcnJheS5zcGxpY2UoYXJyYXkuaW5kZXhvZihpdGVtKSwgMSk7ICovXHJcbiAgICBwcml2YXRlIHJlbW92ZUl0ZW0oaXRlbTogYW55LCB0cmlwdGljPzogQ2FjaGVUcmlwdGljKSB7XHJcbiAgICAgICAgbGV0IGluZGV4ID0gdHJpcHRpYy5pbmRleF9jYWNoZS5nZXQoaXRlbS5faGFzaCk7XHJcbiAgICAgICAgaWYgKGluZGV4ICE9IG51bGwpIHtcclxuICAgICAgICAgICAgdHJpcHRpYy5jYWNoZS5kZWxldGUoaXRlbS5faGFzaCk7XHJcbiAgICAgICAgICAgIHRyaXB0aWMuaW5kZXhfY2FjaGUuZGVsZXRlKGl0ZW0uX2hhc2gpO1xyXG4gICAgICAgICAgICB0cmlwdGljLmFycmF5W2luZGV4XSA9IG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gISFpbmRleDtcclxuICAgIH1cclxuXHJcbiAgICAvKiogSGVscGVyIHBlciBldml0YXJlIGRpIHJpc2NyaXZlcmUgb2duaSBzYW50YSB2b2x0YSBhcnJheS5wdXNoKGl0ZW0pOyBlIGxhIGdlc3Rpb25lIGRlbGxhICAqL1xyXG4gICAgcHJpdmF0ZSBhZGRJdGVtKGl0ZW06IGFueSwgdHJpcHRpYz86IENhY2hlVHJpcHRpYyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICh0cmlwdGljLmluZGV4X2NhY2hlLmdldChpdGVtLl9oYXNoKSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIGxldCBpID0gdHJpcHRpYy5hcnJheS5wdXNoKGl0ZW0pIC0gMTtcclxuICAgICAgICAgICAgdHJpcHRpYy5jYWNoZS5zZXQoaXRlbS5faGFzaCwgaXRlbSk7XHJcbiAgICAgICAgICAgIHRyaXB0aWMuaW5kZXhfY2FjaGUuc2V0KGl0ZW0uX2hhc2gsIGkpO1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE90dGllbmUgaWwgdHJpdHRpY28gZGkgc2VsZXppb25lLCBjaW/DqCBsJ2FycmF5IGRlZ2xpIG9nZ2V0dGkgY2hlIHNpIHZ1b2xlIG1hbmlwb2xhcmUgZSBsZSBkdWUgY2FjaGUgY29sbGVnYXRlIGFkIGVzc29cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHsnZ3JvdXAnIHwgJ2l0ZW0nIHwgJ2dyb3VwX2V4Y2x1c2lvbicgfCAnZXhjbHVzaW9uJ30gc3ViamVjdCBPZ2dldHRvIGxvZ2ljbyBkZXNpZGVyYXRvIHN1IGN1aSBlZmZldHR1YXJlIGxlIG9wZXJhemlvbmkgc3VjY2Vzc2l2ZVxyXG4gICAgICogQHBhcmFtIHtJdGVtc1NlbGVjdGlvbjxhbnk+fSBiYXNlIFNlbGV0dG9yZSBkaSBiYXNlXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHtDYWNoZVRyaXB0aWN9IFRyaXR0aWNvIGRpIHNlbGV6aW9uZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldFRyaXB0aWMoc3ViamVjdDogJ2dyb3VwJyB8ICdpdGVtJyB8ICdncm91cF9leGNsdXNpb24nIHwgJ2V4Y2x1c2lvbicsIGJhc2U6IEl0ZW1zU2VsZWN0aW9uPGFueT4pOiBDYWNoZVRyaXB0aWMge1xyXG4gICAgICAgIHN3aXRjaCAoc3ViamVjdCkge1xyXG4gICAgICAgICAgICBjYXNlICdncm91cCc6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENhY2hlVHJpcHRpYyh0aGlzLmdyb3Vwc0NhY2hlLCB0aGlzLmlfZ3JvdXBzQ2FjaGUsIGJhc2UuZ3JvdXBzKTtcclxuICAgICAgICAgICAgY2FzZSAnaXRlbSc6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENhY2hlVHJpcHRpYyh0aGlzLml0ZW1zQ2FjaGUsIHRoaXMuaV9pdGVtc0NhY2hlLCBiYXNlLml0ZW1zKTtcclxuICAgICAgICAgICAgY2FzZSAnZ3JvdXBfZXhjbHVzaW9uJzpcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ2FjaGVUcmlwdGljKHRoaXMuZ3JvdXBfZXhjbHVzaW9uc0NhY2hlLCB0aGlzLmlfZ3JvdXBfZXhjbHVzaW9uc0NhY2hlLCBiYXNlLmdyb3VwX2V4Y2x1c2lvbnMpO1xyXG4gICAgICAgICAgICBjYXNlICdleGNsdXNpb24nOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDYWNoZVRyaXB0aWModGhpcy5leGNsdXNpb25zQ2FjaGUsIHRoaXMuaV9leGNsdXNpb25zQ2FjaGUsIGJhc2UuZXhjbHVzaW9ucyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGF0byB1biBvZ2dldHRvIHJlc3RpdHVpc2NlIGlsIGdydXBwbyBkaSBjdWkgZmEgcGFydGUsIHNlIGVzaXN0ZVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gaXRlbSBPZ2dldHRvIGRpIGN1aSB0cm92YXJlIGlsIGdydXBwb1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldEl0ZW1Hcm91cChpdGVtOiBhbnkpOiBhbnkge1xyXG4gICAgICAgIGxldCBwYXJlbnQgPSB0aGlzLnJnSGFuZGxlci5yZ0dyb3VwQ2FjaGUuZ2V0KGl0ZW0uX3RoaXNLZXkpXHJcbiAgICAgICAgaWYgKHBhcmVudClcclxuICAgICAgICAgICAgcmV0dXJuIHBhcmVudDtcclxuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEYXRhIGxhIGNoaWF2ZSBkaSB1biBncnVwcG8gcmVzdGl0dWlzY2UgdHV0dGkgZ2xpIG9nZ2V0dGkgY29uIHF1ZWxsYSBjaGlhdmVcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IGdyb3VwIENoaWF2ZSBkYSBjZXJjYXJlXHJcbiAgICAgKiBAcGFyYW0geydzZWxlY3RlZCcgfCAndW5zZWxlY3RlZCd9IHN0YXR1cyBTdGF0byBkZWdsaSBlbGVtZW50aSwgc2VsZXppb25hdGkgbyBub1xyXG4gICAgICogQHBhcmFtIHtib29sZWFufSByZWN1cnNpdmUgSW5kaWNhIHNlIGNlcmNhcmUgc29sbyBnbGkgZWxlbWVudGkgZGlyZXR0YW1lbnRlIGNvbGxlZ2F0aSBvIHNlIHByZW5kZXJlIGFuY2hlIHF1ZWxsaSBkZWkgZ3J1cHBpIGZpZ2xpXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHthbnlbXX0gT2dnZXR0aSBkaSB0aXBvICoqX2l0ZW0qKiBmYWNlbnRpIGNhcG8gYWxsYSBjaGlhdmUgKipncm91cEtleSoqXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0R3JvdXBJdGVtcyhzZWw6IEl0ZW1zU2VsZWN0aW9uPGFueT4sIGdyb3VwOiBhbnksIHN0YXR1cz86ICdzZWxlY3RlZCcgfCAndW5zZWxlY3RlZCcsIHJlY3Vyc2l2ZTogYm9vbGVhbiA9IGZhbHNlLCBhbGxiYXNlOiBhbnlbXSA9IG51bGwpOiBhbnlbXSB7XHJcbiAgICAgICAgbGV0IGl0ZW1zID0gW107XHJcblxyXG4gICAgICAgIGlmIChhbGxiYXNlKVxyXG4gICAgICAgICAgICBpdGVtcyA9IGFsbGJhc2U7XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChyZWN1cnNpdmUpIHtcclxuICAgICAgICAgICAgICAgIC8vIEluIG1vZGFsaXTDoCByaWNvcnNpdmEgcHJlbmRvIGdsaSBvZ2dldHRpIGRpIHR1dHRlIGxlIGNoaWF2aSBzaW1pbGkgY2hlIHRyb3ZvXHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBrZXkgb2YgdGhpcy5yZ0hhbmRsZXIucmdJdGVtQ2FjaGUua2V5cygpKVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkuc3RhcnRzV2l0aChncm91cC5fdGhpc0tleSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2goLi4udGhpcy5yZ0hhbmRsZXIucmdJdGVtQ2FjaGUuZ2V0KGtleSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIGl0ZW1zID0gdGhpcy5yZ0hhbmRsZXIucmdJdGVtQ2FjaGUuZ2V0KGdyb3VwLl90aGlzS2V5KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGl0ZW1zID0gaXRlbXMuZmlsdGVyKHQgPT4gIXN0YXR1cyB8fCAodC5fc2VsZWN0ZWQgJiYgc3RhdHVzID09ICdzZWxlY3RlZCcpIHx8ICghdC5fc2VsZWN0ZWQgJiYgc3RhdHVzID09ICd1bnNlbGVjdGVkJykpO1xyXG5cclxuICAgICAgICAvLyBOb24gdHJvdm8gbmVzc3VuIG9nZ2V0dG8sIHBlcsOyIG1hZ2FyaSBkaSBvZ2dldHRpIG5lIGhvIGFsbCdpbnRlcm5vIGRlbGwnb2dnZXR0byBkaSBzZWxlemlvbmUuIFxyXG4gICAgICAgIC8vIFF1ZXN0byBwdcOyIGVzc2VyZSB2ZXJvIHNvbG8gc2UgTk9OIHNvbm8gaW4gbW9kYWxpdMOgIGFycmF5LCBpbiBjYXNvIGNvbnRyYXJpbyBnbGkgb2dnZXR0aSBsaSBkZXZvIHBlciBmb3J6YSBhdmVyZSB0dXR0aVxyXG4gICAgICAgIGlmIChpdGVtcy5sZW5ndGggIT0gMCB8fCAhc2VsIHx8IHRoaXMuZXN0LmFycmF5TW9kZSlcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zO1xyXG5cclxuICAgICAgICBpZiAoc3RhdHVzID09ICd1bnNlbGVjdGVkJylcclxuICAgICAgICAgICAgaXRlbXMgPSBzZWwuZXhjbHVzaW9ucy5maWx0ZXIodCA9PiB0ICE9IG51bGwgJiZcclxuICAgICAgICAgICAgICAgICghcmVjdXJzaXZlICYmIHQuX3RoaXNLZXkgPT0gZ3JvdXAuX3RoaXNLZXkpIHx8XHJcbiAgICAgICAgICAgICAgICAocmVjdXJzaXZlICYmIHQuX3RoaXNLZXkuc3RhcnRzV2l0aChncm91cC5fdGhpc0tleSkpKTtcclxuICAgICAgICBlbHNlIGlmIChzdGF0dXMgPT0gJ3NlbGVjdGVkJylcclxuICAgICAgICAgICAgaXRlbXMgPSBzZWwuaXRlbXMuZmlsdGVyKHQgPT4gdCAhPSBudWxsICYmXHJcbiAgICAgICAgICAgICAgICAoIXJlY3Vyc2l2ZSAmJiB0Ll90aGlzS2V5ID09IGdyb3VwLl90aGlzS2V5KSB8fFxyXG4gICAgICAgICAgICAgICAgKHJlY3Vyc2l2ZSAmJiB0Ll90aGlzS2V5LnN0YXJ0c1dpdGgoZ3JvdXAuX3RoaXNLZXkpKSk7XHJcblxyXG4gICAgICAgIHJldHVybiBpdGVtcztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERhdGEgbGEgY2hpYXZlIGRpIHVuIGdydXBwbyByZXN0aXR1aXNjZSB0dXR0aSBnbGkgb2dnZXR0aSBjb24gcXVlbGxhIGNoaWF2ZVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gZ3JvdXAgR3J1cHBvIGRpIGN1aSBjZXJjYXJlIGlsIHBhcmVudFxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7YW55fSBPZ2dldHRvIGRpIHRpcG8gKipfZ3JvdXAqKiByYXBwcmVzZW50YW50ZSBpbCBwYXJlbnQgZGVsICoqZ3JvdXAqKiBhdHR1YWxlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0R3JvdXBQYXJlbnQoZ3JvdXA6IGFueSk6IGFueSB7XHJcbiAgICAgICAgbGV0IHBhcmVudCA9IHRoaXMucmdIYW5kbGVyLnJnR3JvdXBDYWNoZS5nZXQoZ3JvdXAuX3BhcmVudClcclxuICAgICAgICBpZiAocGFyZW50KVxyXG4gICAgICAgICAgICByZXR1cm4gcGFyZW50O1xyXG5cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERhdGEgbGEgY2hpYXZlIGRpIHVuIGdydXBwbyByZXN0aXR1aXNjZSB0dXR0aSBpIGdydXBwaSBmaWdsaVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZ3JvdXAgR3J1cHBvIGNoZSByYXBwcmVzZW50YSBpbCBwYWRyZSBkaSBjdWkgY2VyY2FyZSBpIGZpZ2xpXHJcbiAgICAgKiBAcGFyYW0geydzZWxlY3RlZCcgfCAndW5zZWxlY3RlZCd9IHN0YXR1cyBTdGF0byBkZWkgZ3J1cHBpLCBzZWxlemlvbmF0aSBvIG5vXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHJlY3Vyc2l2ZSBJbmRpY2Egc2UgY2VyY2FyZSBzb2xvIGkgZ3J1cHBpIGRpcmV0dGFtZW50ZSBjb2xsZWdhdGkgbyBzZSBwcmVuZGVyZSBhbmNoZSBxdWVsbGkgZGVpIGdydXBwaSBmaWdsaVxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7YW55W119IE9nZ2V0dGkgZGkgdGlwbyAqKl9ncm91cCoqIGZhY2VudGkgY2FwbyBhbGxhIGNoaWF2ZSAqKmdyb3VwS2V5KipcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZXRHcm91cENoaWxkR3JvdXBzKHNlbDogSXRlbXNTZWxlY3Rpb248YW55PiwgZ3JvdXA6IGFueSwgc3RhdHVzPzogJ3NlbGVjdGVkJyB8ICd1bnNlbGVjdGVkJywgcmVjdXJzaXZlOiBib29sZWFuID0gZmFsc2UsIGFsbGJhc2U6IGFueVtdID0gbnVsbCkge1xyXG4gICAgICAgIGxldCB0aGlzR3JvdXA6IGFueSA9IHRoaXMucmdIYW5kbGVyLnJnR3JvdXBDYWNoZS5nZXQoZ3JvdXAuX3RoaXNLZXkpO1xyXG4gICAgICAgIGxldCBpdGVtcyA9IFtdO1xyXG5cclxuICAgICAgICBpZiAoYWxsYmFzZSlcclxuICAgICAgICAgICAgaXRlbXMgPSBhbGxiYXNlO1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAocmVjdXJzaXZlKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBJbiBtb2RhbGl0w6Agcmljb3JzaXZhIHByZW5kbyBnbGkgb2dnZXR0aSBkaSB0dXR0ZSBsZSBjaGlhdmkgc2ltaWxpIGNoZSB0cm92b1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQga2V5IG9mIHRoaXMucmdIYW5kbGVyLnJnQ2hpbGRHcm91cHNDYWNoZS5rZXlzKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGtleS5zdGFydHNXaXRoKGdyb3VwLl90aGlzS2V5KSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMucHVzaCguLi50aGlzLnJnSGFuZGxlci5yZ0NoaWxkR3JvdXBzQ2FjaGUuZ2V0KGtleSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIGl0ZW1zID0gdGhpcy5yZ0hhbmRsZXIucmdDaGlsZEdyb3Vwc0NhY2hlLmdldChncm91cC5fdGhpc0tleSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpdGVtcyA9IGl0ZW1zLmZpbHRlcih0ID0+ICFzdGF0dXMgfHwgKHQuX3NlbGVjdGVkICYmIHN0YXR1cyA9PSAnc2VsZWN0ZWQnKSB8fCAoIXQuX3NlbGVjdGVkICYmIHN0YXR1cyA9PSAndW5zZWxlY3RlZCcpKTtcclxuXHJcbiAgICAgICAgLy8gTm9uIHRyb3ZvIG5lc3N1biBvZ2dldHRvLCBwZXLDsiBtYWdhcmkgZGkgb2dnZXR0aSBuZSBobyBhbGwnaW50ZXJubyBkZWxsJ29nZ2V0dG8gZGkgc2VsZXppb25lXHJcbiAgICAgICAgaWYgKGl0ZW1zLmxlbmd0aCAhPSAwIHx8ICFzZWwpXHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtcztcclxuXHJcbiAgICAgICAgaWYgKHN0YXR1cyA9PSAndW5zZWxlY3RlZCcpXHJcbiAgICAgICAgICAgIGl0ZW1zID0gc2VsLmdyb3VwX2V4Y2x1c2lvbnMuZmlsdGVyKCh0OiBhbnkpID0+IHQgIT0gbnVsbCAmJiAoXHJcbiAgICAgICAgICAgICAgICAoIXJlY3Vyc2l2ZSAmJiB0Ll90aGlzUm91dGUubGVuZ3RoID09IHRoaXNHcm91cC5fdGhpc1JvdXRlLmxlbmd0aCArIDEgJiYgdC5fdGhpc1JvdXRlLnN0YXJ0c1dpdGgoZ3JvdXAuX3RoaXNLZXkpKSB8fFxyXG4gICAgICAgICAgICAgICAgKHJlY3Vyc2l2ZSAmJiB0Ll90aGlzS2V5LnN0YXJ0c1dpdGgoZ3JvdXAuX3RoaXNLZXkpKSkpO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgaXRlbXMgPSBzZWwuZ3JvdXBzLmZpbHRlcigodDogYW55KSA9PiB0ICE9IG51bGwgJiYgKFxyXG4gICAgICAgICAgICAgICAgKCFyZWN1cnNpdmUgJiYgdC5fdGhpc1JvdXRlLmxlbmd0aCA9PSB0aGlzR3JvdXAuX3RoaXNSb3V0ZS5sZW5ndGggKyAxICYmIHQuX3RoaXNSb3V0ZS5zdGFydHNXaXRoKGdyb3VwLl90aGlzS2V5KSkgfHxcclxuICAgICAgICAgICAgICAgIChyZWN1cnNpdmUgJiYgdC5fdGhpc0tleS5zdGFydHNXaXRoKGdyb3VwLl90aGlzS2V5KSkpKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGl0ZW1zO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBGaW5hbGl6emEgbGUgaW5mb3JtYXppb25pIGRpIHNlbGV6aW9uZSBkZWwgKipJdGVtc1NlbGVjdGlvbioqIGNvcnJlbnRlICovXHJcbiAgICBwcml2YXRlIGZpbmFsaXplU2VsZWN0aW9uSW5mb3JtYXRpb25zKHNlbGVjdGlvbkl0ZW06IEl0ZW1zU2VsZWN0aW9uPGFueT4pIHtcclxuICAgICAgICAvLyBEYXRvIGNoZSBsZSBkZWxldGUgc29ubyBsb2dpY2hlIGRhdG8gY2hlIHRlbmdvIGxhIGNhY2hlIGRlZ2xpIGluZGljaSBkZXZvIHJlbmRlcmxlIGZpc2ljaGVcclxuICAgICAgICBsZXQgdG1wR3JwID0gW10sIHRtcEl0ZW1zID0gW10sIHRtcEV4Y2wgPSBbXSwgdG1wR3JwRXhjbCA9IFtdO1xyXG4gICAgICAgIGxldCBncnBSZW1vdmVkID0gZmFsc2UsIGl0ZW1zUmVtb3ZlZCA9IGZhbHNlLCBleGNsUmVtb3ZlZCA9IGZhbHNlLCBncnBFeGNsUmVtb3ZlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlbGVjdGlvbkl0ZW0uaXRlbXMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgIGlmIChzZWxlY3Rpb25JdGVtLml0ZW1zW2ldICE9IG51bGwpIHRtcEl0ZW1zLnB1c2goc2VsZWN0aW9uSXRlbS5pdGVtc1tpXSk7XHJcbiAgICAgICAgICAgIGVsc2UgaXRlbXNSZW1vdmVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxlY3Rpb25JdGVtLmV4Y2x1c2lvbnMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgIGlmIChzZWxlY3Rpb25JdGVtLmV4Y2x1c2lvbnNbaV0gIT0gbnVsbCkgdG1wRXhjbC5wdXNoKHNlbGVjdGlvbkl0ZW0uZXhjbHVzaW9uc1tpXSk7XHJcbiAgICAgICAgICAgIGVsc2UgZXhjbFJlbW92ZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICAvLyBJbiB2ZWNjaGllIHZlcnNpb25pIGRlbGwnQXBwU2VhcmNoIHBlciBjdWkgbm9uIHZlbmdvbm8gZGVzZXJpYWxpenphdGUgcXVlc3RlIGluZm9ybWFpem9uaSBwb3RyZWJiZXJvIGVzc2VyY2kgY2FzaW5pXHJcbiAgICAgICAgaWYgKHNlbGVjdGlvbkl0ZW0uZ3JvdXBzKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZWN0aW9uSXRlbS5ncm91cHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uSXRlbS5ncm91cHNbaV0gIT0gbnVsbCkgdG1wR3JwLnB1c2goc2VsZWN0aW9uSXRlbS5ncm91cHNbaV0pO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBncnBSZW1vdmVkID0gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChzZWxlY3Rpb25JdGVtLmdyb3VwX2V4Y2x1c2lvbnMpIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxlY3Rpb25JdGVtLmdyb3VwX2V4Y2x1c2lvbnMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uSXRlbS5ncm91cF9leGNsdXNpb25zW2ldICE9IG51bGwpIHRtcEdycEV4Y2wucHVzaChzZWxlY3Rpb25JdGVtLmdyb3VwX2V4Y2x1c2lvbnNbaV0pO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBncnBFeGNsUmVtb3ZlZCA9IHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzZWxlY3Rpb25JdGVtLml0ZW1zID0gdG1wSXRlbXM7XHJcbiAgICAgICAgc2VsZWN0aW9uSXRlbS5ncm91cF9leGNsdXNpb25zID0gdG1wR3JwRXhjbDtcclxuICAgICAgICBzZWxlY3Rpb25JdGVtLmV4Y2x1c2lvbnMgPSB0bXBFeGNsO1xyXG4gICAgICAgIHNlbGVjdGlvbkl0ZW0uZ3JvdXBzID0gdG1wR3JwO1xyXG5cclxuICAgICAgICAvLyBMZSBjYWNoZSBkZWdsaSBpbmRpY2kgcG90cmViYmVybyBhdmVyZSBidWNoaSwgcmlzb2x2b1xyXG4gICAgICAgIGlmIChncnBSZW1vdmVkKVxyXG4gICAgICAgICAgICB0aGlzLmlfZ3JvdXBzQ2FjaGUgPSB0aGlzLmNvbXBhY3RJbmRleE1hcCh0aGlzLmlfZ3JvdXBzQ2FjaGUpO1xyXG4gICAgICAgIGlmIChpdGVtc1JlbW92ZWQpXHJcbiAgICAgICAgICAgIHRoaXMuaV9pdGVtc0NhY2hlID0gdGhpcy5jb21wYWN0SW5kZXhNYXAodGhpcy5pX2l0ZW1zQ2FjaGUpO1xyXG4gICAgICAgIGlmIChleGNsUmVtb3ZlZClcclxuICAgICAgICAgICAgdGhpcy5pX2V4Y2x1c2lvbnNDYWNoZSA9IHRoaXMuY29tcGFjdEluZGV4TWFwKHRoaXMuaV9leGNsdXNpb25zQ2FjaGUpO1xyXG4gICAgICAgIGlmIChncnBFeGNsUmVtb3ZlZClcclxuICAgICAgICAgICAgdGhpcy5pX2dyb3VwX2V4Y2x1c2lvbnNDYWNoZSA9IHRoaXMuY29tcGFjdEluZGV4TWFwKHRoaXMuaV9ncm91cF9leGNsdXNpb25zQ2FjaGUpO1xyXG5cclxuICAgICAgICAvLyBQb2kgcmlwcmVuZG8gYSBmYXJlIHR1dHRvIGluIG5vcm1hbGl0w6BcclxuICAgICAgICBzZWxlY3Rpb25JdGVtLmNvdW50ID0gdGhpcy5ldmFsdWF0ZVNlbGVjdGVkKCk7XHJcblxyXG4gICAgICAgIC8vIFNlIGhvIGZhdHRvIHNlbGV6aW9uZSBcImFsbFwiIG1hIHBvaSBtaSBzb25vIG1lc3NvIGEgdG9nbGllcmUgdHV0dGkgZ2xpIGVsZW1lbnRpIGZpbm8gYSByaW1hbmVybmUgMCByZXNldHRvIGwnb2dnZXR0byBkaSBzZWxlemlvbmVcclxuICAgICAgICBpZiAoc2VsZWN0aW9uSXRlbS5jb3VudCA9PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXN0LmJvdW5kU291cmNlLmZvckVhY2godCA9PiB0Ll9zZWxlY3RlZCA9IGZhbHNlKTtcclxuICAgICAgICAgICAgc2VsZWN0aW9uSXRlbS5hbGwgPSBmYWxzZTtcclxuICAgICAgICAgICAgc2VsZWN0aW9uSXRlbS5leGNsdXNpb25zID0gW107XHJcbiAgICAgICAgICAgIHNlbGVjdGlvbkl0ZW0uaXRlbXMgPSBbXTtcclxuICAgICAgICAgICAgc2VsZWN0aW9uSXRlbS5ncm91cHMgPSBbXTtcclxuICAgICAgICAgICAgc2VsZWN0aW9uSXRlbS5ncm91cF9leGNsdXNpb25zID0gW107XHJcblxyXG4gICAgICAgICAgICAvLyBSaXB1bGlzY28gbGEgY2FjaGUgYWx0cmltZW50aSBtaSByaW1hbmUgcGllbmEgZGkgdHV0dGUgbGUgZXNjbHVzaW9uaVxyXG4gICAgICAgICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uQ2FjaGVzKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBTZSBsYSBwb3NzaWJpbGl0w6AgZGkgZmFyZSBcIlNlbGV6aW9uYSB0dXR0b1wiIMOoIGFiaWxpdGF0YSBhbGxvcmEgbGEgY29uc2lkZXJvIGFwcGVuYSBtaSB2aWVuZSBzZWxlemlvbmF0byBxdWFsY29zYVxyXG4gICAgICAgIHRoaXMuZXN0LmNhblNlbGVjdEFsbCA9IHNlbGVjdGlvbkl0ZW0uY291bnQgPiAwICYmIHRoaXMuZXN0LlNlbGVjdEFsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQ29tcGF0dGEgdW5hIGNhY2hlIGRpIGluZGljaSAqL1xyXG4gICAgcHJpdmF0ZSBjb21wYWN0SW5kZXhNYXAobWFwOiBNYXA8c3RyaW5nLCBudW1iZXI+KTogTWFwPHN0cmluZywgbnVtYmVyPiB7XHJcbiAgICAgICAgbGV0IGluZGV4ID0gMDtcclxuICAgICAgICBsZXQgcmV0ID0gbmV3IE1hcCgpO1xyXG4gICAgICAgIGZvciAobGV0IGtleSBvZiBtYXAua2V5cygpKVxyXG4gICAgICAgICAgICByZXQuc2V0KGtleSwgaW5kZXgrKyk7XHJcblxyXG4gICAgICAgIHJldHVybiByZXQ7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVmFsdXRhIGxhIHF1YW50aXTDoCBkaSBvZ2dldHRpIGNoZSBzb25vIHN0YXRpIHNlbGV6aW9uYXRpIGFsIHRlcm1pbmUgZGkgdW4gZXZlbnRvIGRpIHNlbGV6aW9uZVxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IE51bWVybyBkaSBvZ2dldHRpIHNlbGV6aW9uYXRpXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZXZhbHVhdGVTZWxlY3RlZCgpOiBudW1iZXIge1xyXG4gICAgICAgIGxldCBzaSA9ICh0aGlzLmVzdC5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+KT8uc2VsZWN0aW9uIHx8IHRoaXMuZXN0LmFycmF5bW9kZVNlbGVjdGlvbjtcclxuXHJcbiAgICAgICAgbGV0IGV4Y0J5R3JvdXAgPSBzaS5ncm91cF9leGNsdXNpb25zLnJlZHVjZSgocHJldiwgY3VycikgPT4gcHJldiArIGN1cnIuY291bnQsIDApO1xyXG4gICAgICAgIGxldCBpbmNCeUdyb3VwID0gc2kuZ3JvdXBzLnJlZHVjZSgocHJldiwgY3VycikgPT4gcHJldiArIGN1cnIuY291bnQsIDApO1xyXG5cclxuICAgICAgICB0aGlzLmVzdC5zZWxlY3RlZE9iamVjdHMgPSAoc2kuYWxsID8gdGhpcy5lc3QuQmFzZUl0ZW1zQ291bnQgOiBpbmNCeUdyb3VwKSAtIGV4Y0J5R3JvdXAgKyBzaS5pdGVtcy5sZW5ndGggLSBzaS5leGNsdXNpb25zLmxlbmd0aDtcclxuICAgICAgICByZXR1cm4gdGhpcy5lc3Quc2VsZWN0ZWRPYmplY3RzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBHZXN0aXNjZSBpbCBjb21hbmRvIGRpIFwiU2VsZXppb25hIHR1dHRvIGluIHR1dHRlIGxlIHBhZ2luZVwiIG8gaWwgc3VvIGNvbnRyYXJpbywgY2lvw6ggXCJSZWltcG9zdGEgc2VsZXppb25lXCIgKi9cclxuICAgIHB1YmxpYyBzZWxlY3RBbGxPclJlc2V0U2VsZWN0aW9uKCkge1xyXG4gICAgICAgIGxldCBzZWxlY3Rpb25JdGVtID0gdGhpcy5lc3QuVmlldy5zZWxlY3Rpb24gfHwgdGhpcy5lc3QuYXJyYXltb2RlU2VsZWN0aW9uO1xyXG4gICAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb25DYWNoZXMoKTtcclxuICAgICAgICBzZWxlY3Rpb25JdGVtLmFsbCA9ICFzZWxlY3Rpb25JdGVtLmFsbDtcclxuICAgICAgICBzZWxlY3Rpb25JdGVtLmV4Y2x1c2lvbnMgPSBbXTtcclxuICAgICAgICBzZWxlY3Rpb25JdGVtLmdyb3VwcyA9IFtdO1xyXG4gICAgICAgIHNlbGVjdGlvbkl0ZW0uZ3JvdXBfZXhjbHVzaW9ucyA9IFtdO1xyXG4gICAgICAgIHNlbGVjdGlvbkl0ZW0uaXRlbXMgPSBbXTtcclxuXHJcbiAgICAgICAgLy8gUmlwdWxpc2NvIGdsaSBzdGF0aSBVSSBkaSBzZWxlemlvbmUgZ2xvYmFsZSBzZSBsJ2hvIGRpc2F0dGl2YXRhXHJcbiAgICAgICAgaWYgKCFzZWxlY3Rpb25JdGVtLmFsbCkge1xyXG4gICAgICAgICAgICB0aGlzLmVzdC5jYW5TZWxlY3RBbGwgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5lc3QuZ2xvYmFsQ2hlY2sgPSBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuZmluYWxpemVTZWxlY3Rpb25JbmZvcm1hdGlvbnMoc2VsZWN0aW9uSXRlbSk7XHJcblxyXG4gICAgICAgIHRoaXMuZXN0Lm9uU2VsZWN0aW9uQ2hhbmdlZC5lbWl0KHNlbGVjdGlvbkl0ZW0pO1xyXG5cclxuICAgICAgICAvLyBEb3BvIGF2ZXIgcmVzZXR0YXRvIGRpcmV0dGFtZW50ZSBpbCBzb2xvIG9nZ2V0dG8gdGhpcy5WaWV3LnNlbGVjdGlvbiBkZXZvIGFuY2hlIHJpYWxsaW5lYXJlIGEgdHV0dGkgZ2xpIG9nZ2V0dGkgYmluZGF0aVxyXG4gICAgICAgIHRoaXMuZXZhbHVhdGVTZWxlY3Rpb24odGhpcy5lc3QuYm91bmRTb3VyY2UsIHNlbGVjdGlvbkl0ZW0pO1xyXG4gICAgfVxyXG59Il19
|