@esfaenza/es-table 11.2.21 → 11.2.22-beta1
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/bundles/esfaenza-es-table.umd.js +2265 -557
- package/bundles/esfaenza-es-table.umd.js.map +1 -1
- package/bundles/esfaenza-es-table.umd.min.js +2 -2
- package/bundles/esfaenza-es-table.umd.min.js.map +1 -1
- package/esfaenza-es-table.d.ts +5 -5
- package/esfaenza-es-table.metadata.json +1 -1
- package/esm2015/esfaenza-es-table.js +6 -6
- package/esm2015/lib/directives/es_td.directive.js +2 -4
- package/esm2015/lib/directives/es_th.directive.js +23 -7
- package/esm2015/lib/domain/externals/classes/CornerMenuOption.js +4 -0
- package/esm2015/lib/domain/externals/classes/EsTableColumnsDefinition.js +31 -0
- package/esm2015/lib/domain/externals/classes/EsTableOperationDefinition.js +22 -0
- package/esm2015/lib/domain/externals/classes/appsearch/AppOrdering.js +16 -0
- package/esm2015/lib/domain/externals/classes/appsearch/AppSearch.js +35 -0
- package/esm2015/lib/domain/externals/classes/appsearch/GenericItem.js +11 -0
- package/esm2015/lib/domain/externals/classes/appsearch/Group.js +17 -0
- package/esm2015/lib/domain/externals/classes/appsearch/GroupAggregation.js +16 -0
- package/esm2015/lib/domain/externals/classes/appsearch/GroupFilter.js +14 -0
- package/esm2015/lib/domain/externals/classes/appsearch/GroupOrAggregation.js +16 -0
- package/esm2015/lib/domain/externals/classes/appsearch/ItemsSelection.js +23 -0
- package/esm2015/lib/domain/externals/classes/report/ReportColumn.js +4 -0
- package/esm2015/lib/domain/externals/classes/report/ReportDefinition.js +4 -0
- package/esm2015/lib/domain/externals/classes/report/ReportOrder.js +4 -0
- package/esm2015/lib/domain/externals/classes/report/ReportParam.js +4 -0
- package/esm2015/lib/domain/externals/classes/report/ReportResult.js +4 -0
- package/esm2015/lib/domain/externals/classes/report/ReportRow.js +4 -0
- package/esm2015/lib/domain/externals/index.js +18 -0
- package/esm2015/lib/domain/index.js +3 -16
- package/esm2015/lib/domain/internals/classes/CacheTriptic.js +16 -0
- package/esm2015/lib/domain/internals/classes/EsTableColumn.js +24 -0
- package/esm2015/lib/domain/internals/classes/GroupPager.js +21 -0
- package/esm2015/lib/domain/internals/classes/GroupRouteFragment.js +17 -0
- package/esm2015/lib/domain/internals/classes/ThAggregation.js +16 -0
- package/esm2015/lib/domain/internals/index.js +6 -0
- package/esm2015/lib/es-table.module.js +9 -4
- package/esm2015/lib/es_table.component.js +1820 -325
- package/esm2015/lib/es_table.component.loc.js +6 -7
- package/esm2015/lib/es_td.component.js +28 -43
- package/esm2015/lib/es_th.component.js +16 -44
- package/esm2015/lib/models/EsTableDefaultable.js +4 -0
- package/esm2015/lib/models/EsTableModuleConfig.js +2 -4
- package/esm2015/lib/pager/table_pager.component.js +47 -26
- package/esm2015/lib/pager/table_pager.component.loc.js +5 -7
- package/esm2015/lib/tokens.js +6 -4
- package/esm2015/public-api.js +3 -2
- package/fesm2015/esfaenza-es-table.js +2152 -552
- package/fesm2015/esfaenza-es-table.js.map +1 -1
- package/lib/directives/es_td.directive.d.ts +1 -3
- package/lib/directives/es_th.directive.d.ts +18 -5
- package/lib/domain/externals/classes/CornerMenuOption.d.ts +7 -0
- package/lib/domain/{classes → externals/classes}/EsTableColumnsDefinition.d.ts +5 -7
- package/lib/domain/{classes → externals/classes}/EsTableOperationDefinition.d.ts +1 -3
- package/lib/domain/{classes → externals/classes/appsearch}/AppOrdering.d.ts +0 -0
- package/lib/domain/externals/classes/appsearch/AppSearch.d.ts +67 -0
- package/lib/domain/externals/classes/appsearch/GenericItem.d.ts +13 -0
- package/lib/domain/externals/classes/appsearch/Group.d.ts +17 -0
- package/lib/domain/externals/classes/appsearch/GroupAggregation.d.ts +14 -0
- package/lib/domain/externals/classes/appsearch/GroupFilter.d.ts +12 -0
- package/lib/domain/externals/classes/appsearch/GroupOrAggregation.d.ts +14 -0
- package/lib/domain/externals/classes/appsearch/ItemsSelection.d.ts +22 -0
- package/lib/domain/externals/classes/report/ReportColumn.d.ts +15 -0
- package/lib/domain/externals/classes/report/ReportDefinition.d.ts +24 -0
- package/lib/domain/externals/classes/report/ReportOrder.d.ts +7 -0
- package/lib/domain/externals/classes/report/ReportParam.d.ts +40 -0
- package/lib/domain/externals/classes/report/ReportResult.d.ts +12 -0
- package/lib/domain/externals/classes/report/ReportRow.d.ts +5 -0
- package/lib/domain/externals/index.d.ts +17 -0
- package/lib/domain/index.d.ts +2 -15
- package/lib/domain/internals/classes/CacheTriptic.d.ts +14 -0
- package/lib/domain/{classes → internals/classes}/EsTableColumn.d.ts +6 -4
- package/lib/domain/internals/classes/GroupPager.d.ts +22 -0
- package/lib/domain/internals/classes/GroupRouteFragment.d.ts +15 -0
- package/lib/domain/internals/classes/ThAggregation.d.ts +14 -0
- package/lib/domain/internals/index.d.ts +5 -0
- package/lib/es_table.component.d.ts +462 -62
- package/lib/es_table.component.loc.d.ts +2 -6
- package/lib/es_td.component.d.ts +14 -36
- package/lib/es_th.component.d.ts +21 -61
- package/lib/models/EsTableDefaultable.d.ts +19 -0
- package/lib/models/EsTableModuleConfig.d.ts +8 -7
- package/lib/pager/table_pager.component.d.ts +25 -30
- package/lib/pager/table_pager.component.loc.d.ts +2 -6
- package/lib/tokens.d.ts +6 -3
- package/package.json +2 -1
- package/public-api.d.ts +2 -1
- package/esm2015/lib/domain/classes/AppOrdering.js +0 -16
- package/esm2015/lib/domain/classes/AppSearch.js +0 -35
- package/esm2015/lib/domain/classes/CornerMenuOption.js +0 -6
- package/esm2015/lib/domain/classes/EsTableColumn.js +0 -22
- package/esm2015/lib/domain/classes/EsTableColumnsDefinition.js +0 -31
- package/esm2015/lib/domain/classes/EsTableOperationDefinition.js +0 -24
- package/esm2015/lib/domain/classes/GenericItem.js +0 -15
- package/esm2015/lib/domain/classes/IAppSearch.js +0 -2
- package/esm2015/lib/domain/classes/ItemsSelection.js +0 -25
- package/esm2015/lib/domain/classes/ReportColumn.js +0 -6
- package/esm2015/lib/domain/classes/ReportDefinition.js +0 -6
- package/esm2015/lib/domain/classes/ReportOrder.js +0 -6
- package/esm2015/lib/domain/classes/ReportParam.js +0 -6
- package/esm2015/lib/domain/classes/ReportResult.js +0 -6
- package/esm2015/lib/domain/classes/ReportRow.js +0 -6
- package/lib/domain/classes/AppSearch.d.ts +0 -76
- package/lib/domain/classes/CornerMenuOption.d.ts +0 -13
- package/lib/domain/classes/GenericItem.d.ts +0 -25
- package/lib/domain/classes/IAppSearch.d.ts +0 -67
- package/lib/domain/classes/ItemsSelection.d.ts +0 -27
- package/lib/domain/classes/ReportColumn.d.ts +0 -29
- package/lib/domain/classes/ReportDefinition.d.ts +0 -46
- package/lib/domain/classes/ReportOrder.d.ts +0 -13
- package/lib/domain/classes/ReportParam.d.ts +0 -76
- package/lib/domain/classes/ReportResult.d.ts +0 -22
- package/lib/domain/classes/ReportRow.d.ts +0 -9
|
@@ -1,39 +1,46 @@
|
|
|
1
1
|
import { __awaiter } from "tslib";
|
|
2
2
|
// Angular
|
|
3
|
-
import { Component, forwardRef, ContentChildren, ChangeDetectorRef, ChangeDetectionStrategy, Input, EventEmitter, Output, ContentChild, ViewChild, ViewEncapsulation, Optional, Self } from '@angular/core';
|
|
3
|
+
import { Component, forwardRef, ContentChildren, ChangeDetectorRef, ChangeDetectionStrategy, Input, EventEmitter, Output, ContentChild, ViewChild, ViewEncapsulation, Optional, Self, Inject } from '@angular/core';
|
|
4
4
|
import { NgControl } from '@angular/forms';
|
|
5
5
|
// Configurazioni
|
|
6
|
-
import { HashingService, UtilityService, ExportService } from '@esfaenza/extensions';
|
|
6
|
+
import { HashingService, UtilityService, ExportService, MessageService, DateService } from '@esfaenza/extensions';
|
|
7
7
|
import { LocalizationService } from '@esfaenza/localizations';
|
|
8
8
|
import { PreferencesService } from '@esfaenza/preferences';
|
|
9
9
|
// Modelli
|
|
10
|
-
import { AppSearch, AppOrdering, EsTableColumnsDefinition, ReportDefinition, ReportOrder, EsTableColumn } from './domain';
|
|
10
|
+
import { AppSearch, AppOrdering, EsTableColumnsDefinition, ReportDefinition, ReportOrder, EsTableColumn, GroupAggregation, GroupPager, GroupRouteFragment, CacheTriptic } from './domain';
|
|
11
11
|
// Componenti e Localizzazione
|
|
12
12
|
import { EsTd } from './es_td.component';
|
|
13
13
|
import { EsTh } from './es_th.component';
|
|
14
14
|
import { EsTdDirective } from './directives/es_td.directive';
|
|
15
15
|
import { EsThDirective } from './directives/es_th.directive';
|
|
16
16
|
import { EsTableLoc } from './es_table.component.loc';
|
|
17
|
-
import { ItemsSelection } from './domain/classes/ItemsSelection';
|
|
17
|
+
import { ItemsSelection } from './domain/externals/classes/appsearch/ItemsSelection';
|
|
18
|
+
import { GroupOrAggregation } from "./domain/externals/classes/appsearch/GroupOrAggregation";
|
|
19
|
+
import { GroupFilter } from "./domain/externals/classes/appsearch/GroupFilter";
|
|
20
|
+
import { Group } from "./domain/externals/classes/appsearch/Group";
|
|
21
|
+
import { EsTableDefaultable } from './models/EsTableDefaultable';
|
|
22
|
+
import { EST_DEFAULTS, EST_LOCALE } from './tokens';
|
|
18
23
|
/** Componente che permette di rappresentare una griglia di valori */
|
|
19
24
|
export class EsTableComponent {
|
|
20
25
|
/** @ignore */
|
|
21
|
-
constructor(ngControl, prefService, lc, cdr, hashExts, utiExts, expExts) {
|
|
26
|
+
constructor(ngControl, prefService, deafults, locale, lc, cdr, hashExts, utiExts, expExts, dateExts, msgExts) {
|
|
27
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
22
28
|
this.ngControl = ngControl;
|
|
23
29
|
this.prefService = prefService;
|
|
30
|
+
this.deafults = deafults;
|
|
31
|
+
this.locale = locale;
|
|
24
32
|
this.lc = lc;
|
|
25
33
|
this.cdr = cdr;
|
|
26
34
|
this.hashExts = hashExts;
|
|
27
35
|
this.utiExts = utiExts;
|
|
28
36
|
this.expExts = expExts;
|
|
37
|
+
this.dateExts = dateExts;
|
|
38
|
+
this.msgExts = msgExts;
|
|
29
39
|
/** View finale su cui bindarsi lato Frontend, il tipo può essere IAppSearch<any> (per la **viewMode**), any[] (per l'**arrayMode**) e ReportDefinition per la **reportMode** */
|
|
30
40
|
this.View = null;
|
|
31
41
|
/** Indica se l'es-table deve mostrare il check globale nell'header per fare il "seleziona tutto" */
|
|
32
42
|
this.globalCheck = false;
|
|
33
|
-
/**
|
|
34
|
-
* Tiene da conto l'ultimo elemento selezionato in modo da fare ragionamenti del tipo
|
|
35
|
-
* "Ho selezionato questo, l'ultimo selezionato era **lastSelected**, devo selezionare tutti quelli in mezzo", ad esempio per la selezione multipla
|
|
36
|
-
*/
|
|
43
|
+
/** Tiene da conto l'ultimo elemento selezionato in modo da poter effettuare il SHIFT+CLICK */
|
|
37
44
|
this.lastSelected = null;
|
|
38
45
|
/** Conteggio interno per il numero di elementi selezionati */
|
|
39
46
|
this.selectedObjects = 0;
|
|
@@ -72,6 +79,10 @@ export class EsTableComponent {
|
|
|
72
79
|
this.RowTHs = null;
|
|
73
80
|
/** Modello di appoggio temporaneo per i **RowTHs** */
|
|
74
81
|
this.TMPRowTHs = null;
|
|
82
|
+
/** Modello di appoggio temporaneo per i **RowThGroups** */
|
|
83
|
+
this.TMPRowThGroups = null;
|
|
84
|
+
/** Modello rappresentante un singolo header group della tabella. Questa lista è già ordinata e pronta per essere utilizzata in ngFor */
|
|
85
|
+
this.RowThGroups = null;
|
|
75
86
|
/** Cache per i routerLink generati nelle tabelle dinamiche */
|
|
76
87
|
this.DynamicTableRouterLinkCache = {};
|
|
77
88
|
/**
|
|
@@ -118,7 +129,11 @@ export class EsTableComponent {
|
|
|
118
129
|
* @deprecated Utilizzare l'Input **Template** delle es-td e assegnare un template con tutti i binding che si vuole ai click
|
|
119
130
|
*/
|
|
120
131
|
this.CustomCellActionsOn = '';
|
|
121
|
-
/**
|
|
132
|
+
/**
|
|
133
|
+
* Serve per decidere di lanciare o meno il **event.stopPropagation()** al termine della gestione dell'evento
|
|
134
|
+
*
|
|
135
|
+
* @deprecated Utilizzare l'Input **Template** delle es-td e assegnare un template con tutti i binding che si vuole ai click
|
|
136
|
+
*/
|
|
122
137
|
this.CellActionPropagates = true;
|
|
123
138
|
/**
|
|
124
139
|
* Decide se utilizzare o meno le CustomCells. Impostandolo a **true** l'es-table diventa in grado di gestire nativamente:
|
|
@@ -134,14 +149,14 @@ export class EsTableComponent {
|
|
|
134
149
|
this.UseCustomCells = null;
|
|
135
150
|
/** Permette di impostare l'altezza massima della tabella. Se null la dimensione si adatta al numero di elementi attualmente in visualizzazione */
|
|
136
151
|
this.MaxHeight = null;
|
|
137
|
-
/** Classi da applicare
|
|
138
|
-
this.
|
|
152
|
+
/** Classi da applicare al contenitore della tabella */
|
|
153
|
+
this.ContainerClass = null;
|
|
139
154
|
/** Permette o meno l'export in formato XLSX */
|
|
140
155
|
this.XLSXExport = null;
|
|
141
156
|
/** Permette o meno l'export in formato CSV */
|
|
142
157
|
this.CSVExport = true;
|
|
143
158
|
/** Permette di visualizzare o meno l'opzione di paginazione "Tutti" */
|
|
144
|
-
this.AllSearch =
|
|
159
|
+
this.AllSearch = null;
|
|
145
160
|
/** Diminuisce gli spazi fra una cella e l'altra, e internamente il padding del font in modo da presentare molti più dati in un'unica pagina */
|
|
146
161
|
this.HighCellDensity = null;
|
|
147
162
|
/** Abilita o meno la possibilità di selezionare oggetti */
|
|
@@ -160,8 +175,6 @@ export class EsTableComponent {
|
|
|
160
175
|
this.Export = null;
|
|
161
176
|
/** Indica se permettere la selezione multipla Windows-like cliccando un oggetto e facendo poi Shift + click su un oggetto successivo */
|
|
162
177
|
this.ShiftClick = null;
|
|
163
|
-
/** Mostra o nasconde le informazioni di paginazione, sia i pulsanti, sia il selettore degli oggetti per pagina */
|
|
164
|
-
this.ShowPaging = true;
|
|
165
178
|
/** Indica se nascondere o mostrare il componente di paginazione */
|
|
166
179
|
this.HidePaging = null;
|
|
167
180
|
/** Indica se nascondere o mostrare il conteggio degli elementi trovati */
|
|
@@ -173,12 +186,10 @@ export class EsTableComponent {
|
|
|
173
186
|
/** Nome dell'esportazione generata da questa tabella */
|
|
174
187
|
this.ExportFileName = 'Export.csv';
|
|
175
188
|
/** Classe (HTML) di default della tabella */
|
|
176
|
-
this.TableClass =
|
|
177
|
-
/**
|
|
178
|
-
this.CountLabel = this.lc.loc('Found objects');
|
|
179
|
-
/** Indica la presenza di raggruppamenti a livello di header */
|
|
189
|
+
this.TableClass = null;
|
|
190
|
+
/** @deprecated Indica la presenza di raggruppamenti a livello di header */
|
|
180
191
|
this.HasHeaderGroup = null;
|
|
181
|
-
/** Indica la presenza di raggruppamenti a livello del raggruppamento precedentemente esistente, chiaramente è insensata senza **HasHeaderGroup** */
|
|
192
|
+
/** @deprecated Indica la presenza di raggruppamenti a livello del raggruppamento precedentemente esistente, chiaramente è insensata senza **HasHeaderGroup** */
|
|
182
193
|
this.HasSecondaryHeaderGroup = null;
|
|
183
194
|
/** Utilizzato per dividere la sorgente in modalità EndlessScroll */
|
|
184
195
|
this.SliceSize = 100;
|
|
@@ -210,11 +221,7 @@ export class EsTableComponent {
|
|
|
210
221
|
this.HiddenColumns = null;
|
|
211
222
|
/** Permette di riordinare le colonne in base alle impostazioni effettuate dal Menù contestuale in alto a destra */
|
|
212
223
|
this.ColumnsOrdering = null;
|
|
213
|
-
/**
|
|
214
|
-
* Eventuale supporto alle ricerche applicate alla modalità Array
|
|
215
|
-
*
|
|
216
|
-
* @deprecated Utilizzato solo per un caso particolare del Metering
|
|
217
|
-
*/
|
|
224
|
+
/** Eventuale supporto alle ricerche applicate alla modalità Array */
|
|
218
225
|
this.SearchView = null;
|
|
219
226
|
/** Abilita o disabilita il sistema che permette di selezionare tutti gli elementi nella vista */
|
|
220
227
|
this.SelectAll = null;
|
|
@@ -234,6 +241,10 @@ export class EsTableComponent {
|
|
|
234
241
|
this.StartsExpanded = true;
|
|
235
242
|
/** Indica se effettuare il salvataggio delle preferenze di ricerca */
|
|
236
243
|
this.SavePreferences = null;
|
|
244
|
+
/** Indica dove visualizzare le informazioni di paginazione, se sopra, sotto o in entrambi */
|
|
245
|
+
this.PagingStyle = null;
|
|
246
|
+
/** Indica dove visualizzare le informazioni di paginazione, se sopra, sotto o in entrambi */
|
|
247
|
+
this.RowGroupingPagingStyle = null;
|
|
237
248
|
/**
|
|
238
249
|
* Sorgente dati secondaria
|
|
239
250
|
*
|
|
@@ -247,12 +258,19 @@ export class EsTableComponent {
|
|
|
247
258
|
*/
|
|
248
259
|
this.TertiarySource = null;
|
|
249
260
|
/** Indica se utilizzare la cache di selezione che permette di mantenere gli stati di selezione dei vari oggetti navigando da una pagina all'altra */
|
|
250
|
-
this.UseSelectionCache =
|
|
261
|
+
this.UseSelectionCache = null;
|
|
262
|
+
/** Permette di decidere se, in modalità raggruppamento, mostrare o meno il valore delle colonne di gruppo negli oggetti finali. Di default sono nascosti */
|
|
263
|
+
this.ShowItemGroupsColumns = null;
|
|
251
264
|
/** Evento che viene richiamato al cambio di oridnamento di una colonna */
|
|
252
265
|
this.onOrderChanged = new EventEmitter();
|
|
253
266
|
/**
|
|
254
267
|
* Evento che viene richiamato quando l'es-table ritiene sia necessario ri-effettuare la ricerca.
|
|
255
|
-
* Il booleano dell'evento indica se viene suggerito di resettare la pagina o meno
|
|
268
|
+
* Il booleano dell'evento indica se viene suggerito di resettare la pagina o meno.
|
|
269
|
+
*
|
|
270
|
+
* Solo in caso venga utilizzata la modalità a raggruppamenti di righe può succedere che l'es-table passi un intero AppSearch come parametro di ricerca,
|
|
271
|
+
* in quel caso l'applicazione ricevente dovrà onorare la richiesta spedendo al backand l'oggetto di ricerca AS-IS
|
|
272
|
+
*
|
|
273
|
+
* il tipo dell'Emitter invece di essere [boolean | AppSearch<any>] è stato impostato a "any" per evitare problemi di retrocompatibilità
|
|
256
274
|
*/
|
|
257
275
|
this.onSearchRequest = new EventEmitter();
|
|
258
276
|
/** Evento che parte ad ogni modifica di "checkaggio" in forma di comodo array. Espone l'oggetto con lo stato di check attuale */
|
|
@@ -275,19 +293,91 @@ export class EsTableComponent {
|
|
|
275
293
|
/** Numero di pagine (durante la paginazione in modalità Array) */
|
|
276
294
|
this.arraymodePages = 1;
|
|
277
295
|
/** Oggetti per ogni pagina (durante la paginazione in modalità Array) */
|
|
278
|
-
this.ArraymodeItemsPerPage =
|
|
296
|
+
this.ArraymodeItemsPerPage = null;
|
|
297
|
+
/** Colonne da visualizzare in modalità array */
|
|
298
|
+
this.arrayColumns = [];
|
|
299
|
+
/** Ordine delle colonne da visualizzare in modalità array */
|
|
300
|
+
this.arrayColumnOrdering = [];
|
|
301
|
+
/** Ordinamenti ASC-DESC sulle colonne in modalità array */
|
|
302
|
+
this.arrayOrders = [];
|
|
279
303
|
/**
|
|
280
304
|
* Variabile che serve a gestire il momento in cui l'es-table aggiorna la paginazione (pulsanti ecc).
|
|
281
305
|
* Essendo operazioni comunque costose le effettuo solo su binding esterni, non su rewrite generati internamente
|
|
282
306
|
*/
|
|
283
307
|
this.internalWriteCall = false;
|
|
284
|
-
/**
|
|
285
|
-
|
|
308
|
+
/**
|
|
309
|
+
* Cache che conterrà tutte le ricerche effettuate su gruppi diversi dal primo e su elementi contenuti nei gruppi.
|
|
310
|
+
* In caso di cambi di ordinamento delle colonne diverse dalla prima tutte le chiamate fatte dal secondo livello in poi devono essere rieseguite secondo la seguente logica:
|
|
311
|
+
*
|
|
312
|
+
*
|
|
313
|
+
* **Cambio ordinamento sul primo gruppo**: reload completo, non mi occupo di ripulire gli elementi bindati in alcun modo
|
|
314
|
+
*
|
|
315
|
+
* **Cambio ordinamento sulla colonna relativa all'N-esimo gruppo**: reload completo del contenuto dei gruppi precedenti, ripulendo precedentemente
|
|
316
|
+
* tutti gli elementi con **_grouplevel** = N
|
|
317
|
+
*
|
|
318
|
+
* **Cambio ordinamento su una colonna non raggruppata**: reload completo per tutti i gruppi finali aperti, devo precedentemente ripulire tutti gli elementi con **_item** = true
|
|
319
|
+
*
|
|
320
|
+
* Altri eventi non dovrebbero rappresentare problemi:
|
|
321
|
+
* - Selezione: non cambia nulla
|
|
322
|
+
* - Paginazione: cambia a livello root quindi viene ricaricato tutto comunque, stesso vale per le paginazioni interne
|
|
323
|
+
*/
|
|
324
|
+
this.groupSearchRequestsCache = [];
|
|
325
|
+
/** Variabile d'appoggio per capire se c'è bisogno di ri-effettuare una ricerca o meno */
|
|
326
|
+
this.ResearchNeeded = false;
|
|
327
|
+
/** Colonne visibili della vista attuale. Valorizzato di default al numero massimo di colonne supportate dalla tabella per le casistiche in assenza di custom cells */
|
|
328
|
+
this.Columns = { Visibile: 100, VisibleUnpinned: 100, Global: 100 };
|
|
329
|
+
/** In caso di Row Grouping qui viene salvata la vista principale dei gruppi base */
|
|
330
|
+
this.MainGroupView = null;
|
|
331
|
+
/** Conteggio base degli oggetti. In modalità normale viene resettato ad ogni nuova View inserita, in modalità RowGrouping viene resettato solo ad una nuova View di livello "0" */
|
|
332
|
+
this.BaseItemsCount = null;
|
|
333
|
+
/** Cache per salvare per ogni chiave di ogni gruppo chi è il gruppo rappresentato */
|
|
334
|
+
this.rgGroupCache = new Map();
|
|
335
|
+
/** Cache per salvare per ogni chiave di ogni gruppo chi sono gli oggetti sottostanti, non dei sottogruppi */
|
|
336
|
+
this.rgItemCache = new Map();
|
|
337
|
+
/** Cache per salvare per ogni chiave di ogni gruppo chi sono gli oggetti sottostanti, non dei sottogruppi */
|
|
338
|
+
this.rgChildGroupsCache = new Map();
|
|
339
|
+
/** Cache di selezione Hash - Oggetto per la variabile **items** dell'itemSelector. Facilita le operazioni di lookup via hash*/
|
|
340
|
+
this.itemsCache = new Map();
|
|
341
|
+
/** Cache di selezione Hash - Oggetto per la variabile **groups** dell'itemSelector. Facilita le operazioni di lookup via hash */
|
|
342
|
+
this.groupsCache = new Map();
|
|
343
|
+
/** Cache di selezione Hash - Oggetto per la variabile **exclusions** dell'itemSelector. Facilita le operazioni di lookup via hash */
|
|
344
|
+
this.exclusionsCache = new Map();
|
|
345
|
+
/** Cache di selezione Hash - Oggetto per la variabile **group_exclusions** dell'itemSelector. Facilita le operazioni di lookup via hash */
|
|
346
|
+
this.group_exclusionsCache = new Map();
|
|
347
|
+
/** Cache di selezione Hash - Oggetto per la variabile **items** dell'itemSelector. Facilita le operazioni di lookup via indice*/
|
|
348
|
+
this.i_itemsCache = new Map();
|
|
349
|
+
/** Cache di selezione Hash - Oggetto per la variabile **groups** dell'itemSelector. Facilita le operazioni di lookup via indice */
|
|
350
|
+
this.i_groupsCache = new Map();
|
|
351
|
+
/** Cache di selezione Hash - Oggetto per la variabile **exclusions** dell'itemSelector. Facilita le operazioni di lookup via indice */
|
|
352
|
+
this.i_exclusionsCache = new Map();
|
|
353
|
+
/** Cache di selezione Hash - Oggetto per la variabile **group_exclusions** dell'itemSelector. Facilita le operazioni di lookup via indice */
|
|
354
|
+
this.i_group_exclusionsCache = new Map();
|
|
355
|
+
/** Indica se nonostante siamo in modalità array sono stati individuati dei gruppi. In tal caso es-table si comporta da pseudo backend ed effettua le aggregazioni e raggruppamenti completamente lato client */
|
|
356
|
+
this.ArrayGrouping = false;
|
|
357
|
+
this.PagerOptions = { PagerCount: null, ShowCount: true, ShowPaging: true, UsesView: true, View: null, Ready: false, Searches: 'items' };
|
|
286
358
|
/** @ignore */
|
|
287
359
|
this.propagateChange = (_) => { };
|
|
288
360
|
if (ngControl)
|
|
289
361
|
ngControl.valueAccessor = this;
|
|
290
|
-
|
|
362
|
+
// Assegnazione per tutti gli Input di default
|
|
363
|
+
this.ColumnsResizable = this.InputOrDefault(this.ColumnsResizable, (_a = this.deafults) === null || _a === void 0 ? void 0 : _a.ColumnsResizable);
|
|
364
|
+
this.AutoUpdate = this.InputOrDefault(this.AutoUpdate, (_b = this.deafults) === null || _b === void 0 ? void 0 : _b.AutoUpdate);
|
|
365
|
+
this.AllSearch = this.InputOrDefault(this.AllSearch, (_c = this.deafults) === null || _c === void 0 ? void 0 : _c.AllSearch, true);
|
|
366
|
+
this.Export = this.InputOrDefault(this.Export, (_d = this.deafults) === null || _d === void 0 ? void 0 : _d.Export);
|
|
367
|
+
this.HidePaging = this.InputOrDefault(this.HidePaging, (_e = this.deafults) === null || _e === void 0 ? void 0 : _e.HidePaging, false);
|
|
368
|
+
this.HidePagingCount = this.InputOrDefault(this.HidePagingCount, (_f = this.deafults) === null || _f === void 0 ? void 0 : _f.HidePagingCount);
|
|
369
|
+
this.HidePagingButtons = this.InputOrDefault(this.HidePagingButtons, (_g = this.deafults) === null || _g === void 0 ? void 0 : _g.HidePagingButtons);
|
|
370
|
+
this.ContainerClass = this.InputOrDefault(this.ContainerClass, (_h = this.deafults) === null || _h === void 0 ? void 0 : _h.ContainerClass, '');
|
|
371
|
+
this.TableClass = this.InputOrDefault(this.TableClass, (_j = this.deafults) === null || _j === void 0 ? void 0 : _j.TableClass, 'table table-striped table-hover table-sm');
|
|
372
|
+
this.Selection = this.InputOrDefault(this.Selection, (_k = this.deafults) === null || _k === void 0 ? void 0 : _k.Selection);
|
|
373
|
+
this.SavePreferences = this.InputOrDefault(this.SavePreferences, (_l = this.deafults) === null || _l === void 0 ? void 0 : _l.SavePreferences);
|
|
374
|
+
this.PagingStyle = this.InputOrDefault(this.PagingStyle, (_m = this.deafults) === null || _m === void 0 ? void 0 : _m.PagingStyle, 'bottom');
|
|
375
|
+
this.RowGroupingPagingStyle = this.InputOrDefault(this.RowGroupingPagingStyle, (_o = this.deafults) === null || _o === void 0 ? void 0 : _o.RowGroupingPagingStyle, 'left');
|
|
376
|
+
this.UseSelectionCache = this.InputOrDefault(this.UseSelectionCache, (_p = this.deafults) === null || _p === void 0 ? void 0 : _p.UseSelectionCache, true);
|
|
377
|
+
this.ShowItemGroupsColumns = this.InputOrDefault(this.ShowItemGroupsColumns, (_q = this.deafults) === null || _q === void 0 ? void 0 : _q.ShowItemGroupsColumns, false);
|
|
378
|
+
this.ArraymodeItemsPerPage = this.InputOrDefault(this.ArraymodeItemsPerPage, (_r = this.deafults) === null || _r === void 0 ? void 0 : _r.ArraymodeItemsPerPage, 15);
|
|
379
|
+
}
|
|
380
|
+
// #region Ciclo di vita ES-Table - Inizializzazioni
|
|
291
381
|
/** @ignore */
|
|
292
382
|
ngOnInit() {
|
|
293
383
|
//Per poter cambiare il layout in base al livello gerarchico il componente deva avere il pieno controllo di ogni cella,
|
|
@@ -296,6 +386,9 @@ export class EsTableComponent {
|
|
|
296
386
|
throw "Es-table error: Per poter utilizzare l'es-table con [Hierarchy]=\"true\" è richiesto anche [UseCustomCells]=\"true\"";
|
|
297
387
|
// click destro su una riga con selezione attiva: Tiro fuori il context menu e selezione l'elemento corrente
|
|
298
388
|
this.ctxMenuSubscription = (this.ContextMenu || this.tableEmptyMenu).open.subscribe(t => {
|
|
389
|
+
// Gruppi va bene, oggetti pure, ma separatori fra gruppi proprio no...
|
|
390
|
+
if (t.item._sep)
|
|
391
|
+
return;
|
|
299
392
|
let shouldEmit = !t.item._selected;
|
|
300
393
|
t.item._selected = true;
|
|
301
394
|
var itemSelection = this.handleItemsSelection([t.item]);
|
|
@@ -323,6 +416,26 @@ export class EsTableComponent {
|
|
|
323
416
|
this.ShiftClick = true;
|
|
324
417
|
}
|
|
325
418
|
}
|
|
419
|
+
/**
|
|
420
|
+
* Se l'Input è null (valore non settato) vede se c'è un default con cui valorizzarlo. Se non c'è utilizza il valore di fallback (qualora fornito)
|
|
421
|
+
*
|
|
422
|
+
* @param {T} inputValue Valore dell'Input
|
|
423
|
+
* @param {T} defaultValue Valore di default impostato da configurazione
|
|
424
|
+
* @param {T} fallbackValue Valore dell'Input per quando non è stato assegnato dal programmatore e non ha un default
|
|
425
|
+
*/
|
|
426
|
+
InputOrDefault(inputValue, defaultValue, fallbackValue) {
|
|
427
|
+
// Input valorizzato dal programmatore
|
|
428
|
+
if (inputValue != null && inputValue != undefined)
|
|
429
|
+
return inputValue;
|
|
430
|
+
// Input valorizzato da configurazione globale
|
|
431
|
+
if (defaultValue != null && defaultValue != undefined)
|
|
432
|
+
return defaultValue;
|
|
433
|
+
//Input non valorizzato da niente e da nessuno
|
|
434
|
+
if (fallbackValue != null && fallbackValue != undefined)
|
|
435
|
+
return fallbackValue;
|
|
436
|
+
// I casi in cui si arriva qui sono i casi di Input che di default va bene che siano nulli e che nessuno si caga
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
326
439
|
/** @ignore */
|
|
327
440
|
ngOnDestroy() {
|
|
328
441
|
if (this.ctxMenuSubscription)
|
|
@@ -336,6 +449,7 @@ export class EsTableComponent {
|
|
|
336
449
|
this.arrayPulsanti = this.getPagesArray(6, this.SearchView.page, this.SearchView.pages || 1);
|
|
337
450
|
});
|
|
338
451
|
}
|
|
452
|
+
// #endregion
|
|
339
453
|
// #region Implementazione ControlValueAccessor ignorabile
|
|
340
454
|
/** @ignore */
|
|
341
455
|
registerOnChange(fn) { this.propagateChange = fn; }
|
|
@@ -346,6 +460,7 @@ export class EsTableComponent {
|
|
|
346
460
|
// #endregion
|
|
347
461
|
/** @ignore */
|
|
348
462
|
writeValue(obj) {
|
|
463
|
+
var _a;
|
|
349
464
|
this.View = obj ? obj : null;
|
|
350
465
|
// Mi è arrivata l'AppSearch quindi di sicuro non ho una ricerca in progress
|
|
351
466
|
this.researchInProgress = false;
|
|
@@ -378,10 +493,11 @@ export class EsTableComponent {
|
|
|
378
493
|
else if (this.View && this.View instanceof AppSearch) {
|
|
379
494
|
// Se cambia l'oggetto intero significa che ho rimandato la ricerca
|
|
380
495
|
this.setMode('view');
|
|
496
|
+
let firstItemGroupOrNoGrouping = (((_a = this.View.requestedgroups) === null || _a === void 0 ? void 0 : _a.length) || 0) == 0;
|
|
381
497
|
// Se vengo da una ricerca interna mantengo lo stato di selezione precedente (quindi su cambio pagina, cambio ipp, ecc...)
|
|
382
498
|
// se invece l'utente ha fatto una ricerca lui (quindi cambiando filtri), secco le info di selezione
|
|
383
|
-
if (!this.View.selection || !this.View.internalsearchrequest || !this.UseSelectionCache) {
|
|
384
|
-
this.
|
|
499
|
+
if (!this.View.selection || (!this.View.internalsearchrequest && firstItemGroupOrNoGrouping) || !this.UseSelectionCache) {
|
|
500
|
+
this.clearSelectionCaches();
|
|
385
501
|
this.View.selection = new ItemsSelection([]);
|
|
386
502
|
this.onSelectionChanged.emit(this.View.selection);
|
|
387
503
|
}
|
|
@@ -400,55 +516,136 @@ export class EsTableComponent {
|
|
|
400
516
|
}
|
|
401
517
|
}
|
|
402
518
|
}
|
|
403
|
-
|
|
519
|
+
// La paginazione devo farla solamente quando richiedo o un gruppo principale (se sono in row grouping) o se non richiedo gruppi (in tutti lgi altri casi)
|
|
520
|
+
if (firstItemGroupOrNoGrouping)
|
|
521
|
+
this.arrayPulsanti = this.getPagesArray(6, this.View.page, this.View.pages || 1);
|
|
404
522
|
}
|
|
405
523
|
else if (this.View && (this.View.length != null && this.View.length != undefined)) {
|
|
406
524
|
this.setMode('array');
|
|
407
525
|
if (!this.UseSelectionCache || !this.arraymodeSelection) {
|
|
408
|
-
this.
|
|
526
|
+
this.clearSelectionCaches();
|
|
409
527
|
this.arraymodeSelection = new ItemsSelection([]);
|
|
410
528
|
;
|
|
411
529
|
this.onSelectionChanged.emit(this.arraymodeSelection);
|
|
412
530
|
}
|
|
531
|
+
// Recupero Preference
|
|
532
|
+
if (this.SavePreferences) {
|
|
533
|
+
if (!this.ngControl.name)
|
|
534
|
+
console.error("Non posso utilizzare le preference senza avere un 'name' per questa tabella");
|
|
535
|
+
else if (!this.prefService)
|
|
536
|
+
console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
|
|
537
|
+
else {
|
|
538
|
+
var prefs = this.prefService.retrieve(this.ngControl.name);
|
|
539
|
+
if (prefs) {
|
|
540
|
+
this.arrayColumns = prefs.columns;
|
|
541
|
+
this.arrayColumnOrdering = prefs.column_ordering;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
413
545
|
if (this.SearchView)
|
|
414
546
|
this.arrayPulsanti = this.getPagesArray(6, this.SearchView.page, this.SearchView.pages || 1);
|
|
415
547
|
}
|
|
416
|
-
if (this.View && !(this.View instanceof ReportDefinition))
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
548
|
+
if (this.View && !(this.View instanceof ReportDefinition))
|
|
549
|
+
this.finalizeContext();
|
|
550
|
+
this.postBoundSourceCalculation();
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Successivamente al bind del nuovo input questa funzione si occupa di finalizzare tutti i parametri di funzionamento dell'es-table
|
|
554
|
+
* in base a Input - Modello, e qualsiasi altra cosa possa servire
|
|
555
|
+
*/
|
|
556
|
+
finalizeContext() {
|
|
557
|
+
let viewCasted = this.View;
|
|
558
|
+
/*
|
|
559
|
+
*Uso la tecnica di EndlessScroll se la variabile relativa è attiva e se
|
|
560
|
+
* 1) Ho un Array, oppure
|
|
561
|
+
* 2) Ho un AppSearch che sta cercando con paginazione "Tutto", oppure
|
|
562
|
+
* 3) Ho un AppSearch che sta cercando con paginazione diversa da "Tutto" ma con la variabile EndlessScrollOnlyForAll a false
|
|
563
|
+
*/
|
|
564
|
+
let isAppSearchWithIppMax = this.viewMode && viewCasted.itemsperpageoverride == this.defaultAllPageOverride;
|
|
565
|
+
let isAppSearchNoMaxIpp = this.viewMode && viewCasted.itemsperpageoverride != this.defaultAllPageOverride;
|
|
566
|
+
this.UseEndlessscroll = this.EndlessScroll && (this.arrayMode || isAppSearchWithIppMax || (isAppSearchNoMaxIpp && !this.EndlessScrollOnlyForAll));
|
|
567
|
+
let hasRowGroups = (viewCasted.groupings && viewCasted.groupings.filter(t => !t.aggregation).length > 0) || (this.arrayMode && this.EsThsDirective.some(t => t.thGroup));
|
|
568
|
+
// Se ho dei gruppi in modalità array devo sistemare un po' di variabili che diventano insensate
|
|
569
|
+
if (this.arrayMode) {
|
|
570
|
+
if (hasRowGroups)
|
|
571
|
+
this.UseArrayModePaging = false;
|
|
572
|
+
}
|
|
573
|
+
// Riempimento della TMPBoundSource con gli oggetti che verranno poi mostrati ad interfaccia
|
|
574
|
+
if (this.UseEndlessscroll && !hasRowGroups) {
|
|
575
|
+
this.addedSlices = [];
|
|
576
|
+
this.boundSubSources = this.getItemSlices();
|
|
577
|
+
let firstSub = this.boundSubSources[0];
|
|
578
|
+
this.TMPBoundSource = firstSub ? firstSub : [];
|
|
579
|
+
if (firstSub)
|
|
580
|
+
this.addedSlices.push(0);
|
|
581
|
+
}
|
|
582
|
+
else
|
|
583
|
+
this.TMPBoundSource = this.getItemsByMode(false, !this.internalWriteCall);
|
|
584
|
+
// Se ho una gerarchia, assegno i livelli gerarchici alla TMPBoundSource
|
|
585
|
+
if (this.Hierarchy && !hasRowGroups)
|
|
586
|
+
this.assignHierarchyLevels(this.TMPBoundSource);
|
|
587
|
+
// L'hashing degli oggetti lo faccio a prescindere
|
|
588
|
+
this.calculateHash(this.TMPBoundSource);
|
|
589
|
+
// Assegno a una variabile mia l'eventuale override per la classe della riga
|
|
590
|
+
// Se poi sono in modalità gerarchica inietto anche la classe per la configurazione del livello della riga
|
|
591
|
+
if ((this.TMPBoundSource && this.RowClassAssigner) || this.Hierarchy) {
|
|
592
|
+
for (let i = 0; i < this.TMPBoundSource.length; i++) {
|
|
593
|
+
let item = this.TMPBoundSource[i];
|
|
594
|
+
item._rowClass = this.RowClassAssigner ? this.RowClassAssigner(item) : "";
|
|
595
|
+
item._rowClass += this.Hierarchy ? " est-row-lvl-" + item._level : "";
|
|
433
596
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
/** Genera le informzioni di paginazione per la vista globale dell'es-table */
|
|
600
|
+
setupPagingInformations() {
|
|
601
|
+
this.PagerOptions.ShowCount = !this.HidePagingCount;
|
|
602
|
+
if (this.arrayMode && this.UseArrayModePaging && !this.SearchView) {
|
|
603
|
+
this.PagerOptions.PagerCount = this.View.length || 0;
|
|
604
|
+
this.PagerOptions.ShowPaging = !this.HidePaging && this.View.length > 10;
|
|
605
|
+
this.PagerOptions.View = this.View;
|
|
606
|
+
this.PagerOptions.UsesView = false;
|
|
607
|
+
}
|
|
608
|
+
else if (this.arrayMode && (!this.UseArrayModePaging || this.SearchView)) {
|
|
609
|
+
if (this.SearchView) {
|
|
610
|
+
this.PagerOptions.View = this.SearchView;
|
|
611
|
+
this.PagerOptions.PagerCount = this.SearchView.objectcount || 0;
|
|
447
612
|
}
|
|
613
|
+
else
|
|
614
|
+
this.PagerOptions.PagerCount = this.View.length || 0;
|
|
615
|
+
this.PagerOptions.ShowCount = this.PagerOptions.ShowCount || (this.View && this.View.length) || (this.SearchView && this.SearchView.objectcount && this.SearchView.objectcount != -1);
|
|
616
|
+
}
|
|
617
|
+
else if (this.viewMode) {
|
|
618
|
+
let tmpView = this.MainGroupView || this.View;
|
|
619
|
+
let count = (tmpView === null || tmpView === void 0 ? void 0 : tmpView.groupcount) || (tmpView === null || tmpView === void 0 ? void 0 : tmpView.objectcount);
|
|
620
|
+
this.PagerOptions.Searches = (tmpView === null || tmpView === void 0 ? void 0 : tmpView.groupcount) != null && (tmpView === null || tmpView === void 0 ? void 0 : tmpView.groupcount) != undefined ? 'groups' : 'items';
|
|
621
|
+
this.PagerOptions.PagerCount = count || 0;
|
|
622
|
+
this.PagerOptions.View = tmpView;
|
|
623
|
+
this.PagerOptions.ShowCount = this.PagerOptions.ShowCount || (tmpView && count && count != -1);
|
|
624
|
+
this.PagerOptions.ShowPaging = !this.HidePaging;
|
|
625
|
+
}
|
|
626
|
+
else if (this.reportMode) {
|
|
627
|
+
let rvc = this.ReportValues.count;
|
|
628
|
+
this.PagerOptions.View = this.View;
|
|
629
|
+
this.PagerOptions.PagerCount = rvc && rvc == -1 ? this.ReportValues.rows.length : rvc && rvc > 0 ? this.ReportValues.count : 0;
|
|
630
|
+
this.PagerOptions.ShowCount = this.PagerOptions.ShowCount || (this.View && this.View.objectcount && this.View.objectcount != -1);
|
|
631
|
+
this.PagerOptions.ShowPaging = !this.HidePaging && this.View.pagingavailable;
|
|
448
632
|
}
|
|
449
|
-
this.postBoundSourceCalculation();
|
|
450
633
|
}
|
|
451
|
-
|
|
634
|
+
/**
|
|
635
|
+
* Ripulisce le cache di selezione
|
|
636
|
+
*
|
|
637
|
+
* @todo: SELECTION
|
|
638
|
+
*/
|
|
639
|
+
clearSelectionCaches() {
|
|
640
|
+
this.itemsCache.clear();
|
|
641
|
+
this.groupsCache.clear();
|
|
642
|
+
this.exclusionsCache.clear();
|
|
643
|
+
this.group_exclusionsCache.clear();
|
|
644
|
+
this.i_itemsCache.clear();
|
|
645
|
+
this.i_groupsCache.clear();
|
|
646
|
+
this.i_exclusionsCache.clear();
|
|
647
|
+
this.i_group_exclusionsCache.clear();
|
|
648
|
+
}
|
|
452
649
|
/**
|
|
453
650
|
* In base alla modalità specificata (ArrayMode, ViewMode, ecc...) questo metodo recupera l'array di oggetti da bindare ad interfaccia
|
|
454
651
|
*
|
|
@@ -457,6 +654,8 @@ export class EsTableComponent {
|
|
|
457
654
|
* @param {boolean} allIfPossible [false] Indica se prendere tutti gli oggetti quaora possibile, usato solo in ArrayMode
|
|
458
655
|
*
|
|
459
656
|
* @returns {any[]} Lista degli oggetti su cui effettuare il bind lato interfaccia
|
|
657
|
+
*
|
|
658
|
+
* @todo: ITEMS
|
|
460
659
|
*/
|
|
461
660
|
getItemsByMode(onlyselected = false, refreshPaging = false, allIfPossible = false) {
|
|
462
661
|
let items = [];
|
|
@@ -464,6 +663,8 @@ export class EsTableComponent {
|
|
|
464
663
|
items = this.getViewItemsBySource();
|
|
465
664
|
}
|
|
466
665
|
else if (this.arrayMode) {
|
|
666
|
+
this.View.forEach(itm => { itm._item = true; });
|
|
667
|
+
// Se faccio dei raggruppamenti ignoro la paginazione
|
|
467
668
|
if (this.UseArrayModePaging && !allIfPossible) {
|
|
468
669
|
// Se sono in modalità array ma la ricerca dipende da una view devo riallineare gli itemperpage
|
|
469
670
|
if (this.SearchView)
|
|
@@ -482,16 +683,61 @@ export class EsTableComponent {
|
|
|
482
683
|
return items.filter(t => t._selected);
|
|
483
684
|
return items;
|
|
484
685
|
}
|
|
485
|
-
/**
|
|
686
|
+
/**
|
|
687
|
+
* @ignore
|
|
688
|
+
*
|
|
689
|
+
* @todo: ITEMS
|
|
690
|
+
*/
|
|
486
691
|
getViewItemsBySource() {
|
|
487
|
-
|
|
692
|
+
var _a, _b;
|
|
693
|
+
let castedView = this.View;
|
|
694
|
+
let groupKeys = castedView.groupings ? castedView.groupings.filter(t => !t.aggregation).length : 0;
|
|
695
|
+
//Gruppi intermedi
|
|
696
|
+
if ((((_a = castedView.requestedgroups) === null || _a === void 0 ? void 0 : _a.length) != groupKeys || ((_b = castedView.requestedgroups) === null || _b === void 0 ? void 0 : _b.length) == 0) && groupKeys > 0) {
|
|
697
|
+
let ret = castedView.groups;
|
|
698
|
+
ret.forEach(itm => {
|
|
699
|
+
// Setto variabile interna per capire che questo è in realtà un gruppo
|
|
700
|
+
itm._group = true;
|
|
701
|
+
// Le informazioni passate come lista le metto dentro a una cache per velocizzarne l'accesso quando devo tirare fuori il display della proprietà
|
|
702
|
+
this.cacheAggregations(itm);
|
|
703
|
+
});
|
|
704
|
+
return ret;
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
let ret = this.SecondarySource ? this.View.items2 : this.TertiarySource ? this.View.items3 : this.View.items;
|
|
708
|
+
// Setto variabile interna per specificare che questo è un elemento normale, non un gruppo o altro
|
|
709
|
+
ret.forEach(itm => { itm._item = true; });
|
|
710
|
+
return ret;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Helper per effettuare il caching delle aggregazioni. Le sposta da una lista di **GroupAggregation** a una **<Map<string, Map<string, string>>**
|
|
715
|
+
*
|
|
716
|
+
* @todo: ROWGROUPING
|
|
717
|
+
*/
|
|
718
|
+
cacheAggregations(group) {
|
|
719
|
+
group._aggregationsCache = new Map();
|
|
720
|
+
let castedAgCache = group._aggregationsCache;
|
|
721
|
+
for (let i = 0; i < group.aggregations.length; i++) {
|
|
722
|
+
let agg = group.aggregations[i];
|
|
723
|
+
if (castedAgCache.has(agg.column))
|
|
724
|
+
castedAgCache.get(agg.column).set(agg.aggregation, agg.value);
|
|
725
|
+
else {
|
|
726
|
+
let tmp = new Map();
|
|
727
|
+
tmp.set(agg.aggregation, agg.value);
|
|
728
|
+
castedAgCache.set(agg.column, tmp);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
488
731
|
}
|
|
489
732
|
/**
|
|
490
733
|
* Metodo che prende tutti gli oggetti di cui dispone divisi in bucket da 100 elementi
|
|
491
734
|
*
|
|
492
735
|
* @returns {any[][]} Matrice di array Nx100
|
|
736
|
+
*
|
|
737
|
+
* @todo: ITEMS
|
|
493
738
|
*/
|
|
494
739
|
getItemSlices() {
|
|
740
|
+
// Se sono qui di sicuro non ho rowgrouping
|
|
495
741
|
let items = this.getItemsByMode();
|
|
496
742
|
if (!items)
|
|
497
743
|
return [];
|
|
@@ -525,8 +771,6 @@ export class EsTableComponent {
|
|
|
525
771
|
}
|
|
526
772
|
}
|
|
527
773
|
}
|
|
528
|
-
// #endregion
|
|
529
|
-
// #region Gestione di tutto il ciclo di vita post binding oggetti
|
|
530
774
|
/**
|
|
531
775
|
* Metodo lanciato dopo che la sorgente dati è stata correttamente bindata, si occupa di ricalcolare tutto ciò che serve
|
|
532
776
|
* all'es-table per renderizzare i valori da mostrare
|
|
@@ -536,113 +780,444 @@ export class EsTableComponent {
|
|
|
536
780
|
this.RowContexts = [];
|
|
537
781
|
this.OrderDirectives = [];
|
|
538
782
|
this.lastSelectedItemID = null;
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
this.
|
|
544
|
-
|
|
545
|
-
if (this.viewMode && this.UseCustomCells) {
|
|
546
|
-
let view = this.View;
|
|
547
|
-
let ths = this.EsThs && this.EsThs.length > 0 ? this.EsThs.toArray() : this.EsThsDirective && this.EsThsDirective.length > 0 ? this.EsThsDirective.toArray() : [];
|
|
548
|
-
let tds = this.EsTds && this.EsTds.length > 0 ? this.EsTds.toArray() : this.EsTdsDirective && this.EsTdsDirective.length > 0 ? this.EsTdsDirective.toArray() : [];
|
|
549
|
-
// N.B: Rispettare l'ordine di queste 3 macrocategorie è VITALE
|
|
550
|
-
// ************************************* Sistemazioni di TH, TD, e visibilità varie *************************************
|
|
551
|
-
this.alignColumnsIfLoadedView(view); // Se sto caricando una View da hotpotato (quindi con savedstate = true) riallineo la visibilità delle colonne e il loro ordine.
|
|
552
|
-
this.refreshColumnsVisibility(ths, tds, view); // Lavoro sui TH ed eventualmente modifico la visibilità anche dei TD.
|
|
553
|
-
this.alignHeadersOrdering(ths, view); // Allineo gli ordinamenti agli header
|
|
554
|
-
this.reviewColumnsList(ths); // Aggiorna la lista delle colonne da mostrare nella dialog per ordinamento ecc
|
|
555
|
-
// ************************************* Generazione binding per righe e colonne *************************************
|
|
556
|
-
this.evaluateRowThs(ths); // Raccolgo i TH
|
|
557
|
-
this.evaluateRowTds(ths, tds); // Raccolgo i TD in contesti separati, un contesto per ogni item
|
|
558
|
-
// ************************************* Ultimi aggiustmaenti dei binding *************************************
|
|
559
|
-
this.generateDefaultOrder(view); // Genero le direttive di ordinamento, che siano default o derivanti dalla AppSearch
|
|
560
|
-
this.applyOrdering(view, true); // Applico l'ordinamento sulle colonne (non ASC DESC, ma "prima questa o quella colonna")
|
|
561
|
-
this.MoveTemporaryVariablesToRealOnes(); // Collego TH e TD aggiustati fino ad ora alle variabili di Binding HTML
|
|
562
|
-
this.evaluateSelection(view.items, view.selection); // Riallineo le info di selezione degli elementi della View
|
|
563
|
-
}
|
|
564
|
-
else if (this.viewMode && !this.UseCustomCells) {
|
|
565
|
-
// Riallineo le info di selezione degli elementi della View
|
|
566
|
-
let view = this.View;
|
|
567
|
-
this.evaluateSelection(view.items, view.selection);
|
|
568
|
-
}
|
|
569
|
-
else if (this.arrayMode) {
|
|
570
|
-
// Riallineo le info di selezione degli elementi dell'array
|
|
571
|
-
this.arrayModeEvaluateSelection(this.View);
|
|
572
|
-
}
|
|
573
|
-
// Collego gli oggetti da mostrare
|
|
574
|
-
this.boundSource = this.TMPBoundSource;
|
|
575
|
-
// Per essere sicuro che dopo un bind di oggetti la es-table aggiorni la grafica
|
|
576
|
-
this.cdr.markForCheck();
|
|
577
|
-
this.FirstBind = false;
|
|
578
|
-
});
|
|
783
|
+
if (this.EsThsDirective && this.EsThsDirective.length > 0 && this.EsTdsDirective && this.EsTdsDirective.length > 0)
|
|
784
|
+
this.internalPostBoundSource();
|
|
785
|
+
else {
|
|
786
|
+
this.cdr.detectChanges();
|
|
787
|
+
setTimeout(() => { this.internalPostBoundSource(); });
|
|
788
|
+
}
|
|
579
789
|
}
|
|
580
790
|
/**
|
|
581
|
-
*
|
|
791
|
+
* Per poter distinguere le chiamate a questo metodo: Dopo il setTimeout se uso gli EsTd/EsTh vecchi, senza il setTimeout se uso le nuove direttive
|
|
582
792
|
*/
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
this.
|
|
793
|
+
internalPostBoundSource() {
|
|
794
|
+
let View = this.View;
|
|
795
|
+
let ths = this.EsThs && this.EsThs.length > 0 ? this.EsThs.toArray() : this.EsThsDirective && this.EsThsDirective.length > 0 ? this.EsThsDirective.toArray() : [];
|
|
796
|
+
let tds = this.EsTds && this.EsTds.length > 0 ? this.EsTds.toArray() : this.EsTdsDirective && this.EsTdsDirective.length > 0 ? this.EsTdsDirective.toArray() : [];
|
|
797
|
+
// Se non ho colonne dinamiche ma sono in modalità dinamica (lo capisco perché c'è una view piena di genericitem) metto il default delle colonne
|
|
798
|
+
this.eventuallyReviewDynamicColumns();
|
|
799
|
+
this.bindDisplayToLoadedItemsOrGroups(View);
|
|
800
|
+
// Questo dev'essere per forza lanciato dopo **bindDisplayToLoadedItemsOrGroups** dato che è lì che alcune cose vengono valorizzate
|
|
801
|
+
this.setupPagingInformations();
|
|
802
|
+
// Molte cose sono ovviamente disponibili solo in modalità View
|
|
803
|
+
if ((this.viewMode || this.arrayMode) && this.UseCustomCells) {
|
|
804
|
+
let view = this.viewMode ? View : null;
|
|
805
|
+
let itemsAndGroups = this.viewMode ? [...(view.items || []), ...(view.groups || [])] : View;
|
|
806
|
+
let si = this.viewMode ? view.selection : this.arraymodeSelection;
|
|
807
|
+
// N.B: Rispettare l'ordine di queste 3 macrocategorie è VITALE
|
|
808
|
+
// ************************************* Sistemazioni di TH, TD, e visibilità varie *************************************
|
|
809
|
+
let hI = this.evaluateHeadersGroupingInfos(ths); // Prepassaggio per tirare fuori tutte le info utili sugli headers in modo da non ricacolarseli sempre dopo
|
|
810
|
+
if (this.arrayMode) { // In modalità array non ho un backend...
|
|
811
|
+
this.arrayModeReviewOrderings(); // ... quindi gli ordinamenti li devo fare lato client, e ...
|
|
812
|
+
this.arrayModeReviewGroupings(hI.leafs); // ... i raggruppamenti li devo fare lato client
|
|
813
|
+
}
|
|
814
|
+
this.reviewColumnsList(hI.leafs); // Aggiorna la lista delle colonne da mostrare nella dialog per ordinamento ecc
|
|
815
|
+
this.moveFixedColumnsAtTheBeginning(hI.leafs, tds); // Sposto tutte le cose fixed all'inizio in modo che la creazione di th e td sia più snella (Utilizza le ColumnsList, quindi dev'essere richiamata PIRMA di reviewColumnsList)
|
|
816
|
+
this.alignHeadersOrdering(hI.leafs, view); // Allineo gli ordinamenti agli header
|
|
817
|
+
this.alignColumnsIfLoadedView(view); // Se sto caricando una View da hotpotato (quindi con savedstate = true) riallineo la visibilità delle colonne e il loro ordine.
|
|
818
|
+
this.refreshColumnsVisibility(hI.leafs, tds, view); // Lavoro sui TH ed eventualmente modifico la visibilità anche dei TD.
|
|
819
|
+
this.evaluatePinnedColumnsWidth(); // Se sono presenti colonne pinnate valuta la dimensione del contenitore
|
|
820
|
+
this.generateDefaultOrder(hI.leafs, view); // Genero le direttive di ordinamento, che siano default o derivanti dalla AppSearch
|
|
821
|
+
this.evaluateHeaderGroups(hI); // Valuto i raggruppamenti degli header se presenti
|
|
822
|
+
// ************************************* Generazione binding per righe e colonne *************************************
|
|
823
|
+
this.evaluateRowThs(hI.leafs); // Raccolgo i TH
|
|
824
|
+
this.evaluateRowTds(hI.leafs, tds); // Raccolgo i TD in contesti separati, un contesto per ogni item o gruppo
|
|
825
|
+
// ************************************* Ultimi aggiustmaenti dei binding *************************************
|
|
826
|
+
this.applyOrdering(view, true); // Applico l'ordinamento sulle colonne (non ASC DESC, ma "prima questa o quella colonna")
|
|
827
|
+
this.MoveTemporaryVariablesToRealOnes(); // Collego TH e TD aggiustati fino ad ora alle variabili di Binding HTML
|
|
828
|
+
this.evaluateSelection(itemsAndGroups, si); // Riallineo le info di selezione degli elementi della View
|
|
829
|
+
if (this.ResearchNeeded) {
|
|
830
|
+
this.changed();
|
|
831
|
+
this.emitSearchRequest(false);
|
|
832
|
+
this.ResearchNeeded = false;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
else if ((this.viewMode || this.arrayMode) && !this.UseCustomCells) {
|
|
836
|
+
// Riallineo le info di selezione degli elementi della View
|
|
837
|
+
let items = this.viewMode ? View.items : View;
|
|
838
|
+
let si = this.viewMode ? View.selection : this.arraymodeSelection;
|
|
839
|
+
this.evaluateSelection(items, si);
|
|
840
|
+
}
|
|
841
|
+
// Per essere sicuro che dopo un bind di oggetti la es-table aggiorni la grafica
|
|
842
|
+
this.cdr.markForCheck();
|
|
843
|
+
this.FirstBind = false;
|
|
586
844
|
}
|
|
587
845
|
/**
|
|
588
|
-
*
|
|
846
|
+
* Se in modalità array applica gli ordinamenti ASC-DESC delle colonne
|
|
589
847
|
*
|
|
590
|
-
* @
|
|
591
|
-
* @param {ItemsSelection<any>} selectionItem Oggetti di selezione derivante dalla view o dall'oggetto per Array
|
|
848
|
+
* @todo: INTERNALDB
|
|
592
849
|
*/
|
|
593
|
-
|
|
594
|
-
if (
|
|
850
|
+
arrayModeReviewOrderings() {
|
|
851
|
+
if (this.arrayOrders.length > 0)
|
|
852
|
+
this.arrayOrders.forEach(t => {
|
|
853
|
+
this.boundSource = this.boundSource.sort((a, b) => (a[t.id] > b[t.id] ? 1 : -1) * (t.order == 'DESC' ? -1 : 1));
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Se in modalità array applica i raggruppamenti definiti lato row-grouping
|
|
858
|
+
*
|
|
859
|
+
* @param {ths: EsTh[] | EsThDirective[]} ths Header
|
|
860
|
+
*
|
|
861
|
+
* @todo: ROW GROUPING
|
|
862
|
+
*/
|
|
863
|
+
arrayModeReviewGroupings(ths) {
|
|
864
|
+
if (ths.length == 0)
|
|
595
865
|
return;
|
|
596
|
-
this.
|
|
866
|
+
if (this.isEsTh(ths[0]))
|
|
867
|
+
return;
|
|
868
|
+
let headerGroups = [];
|
|
869
|
+
let headerAggregations = [];
|
|
870
|
+
for (let i = 0; i < ths.length; i++) {
|
|
871
|
+
let th = ths[i];
|
|
872
|
+
if (th.thGroup)
|
|
873
|
+
headerGroups.push(new Group(th.th, 0, ""));
|
|
874
|
+
else if (th.thAggregation)
|
|
875
|
+
headerAggregations = [...headerAggregations, ...this.getGroupAggregations(th)];
|
|
876
|
+
}
|
|
877
|
+
if (headerGroups.length > 0) {
|
|
878
|
+
// Pulizia delle cache
|
|
879
|
+
this.rgGroupCache.clear();
|
|
880
|
+
this.rgItemCache.clear();
|
|
881
|
+
this.rgChildGroupsCache.clear();
|
|
882
|
+
this.ArrayGrouping = true;
|
|
883
|
+
this.boundSource = this.getGroupsRecursive(headerGroups, 0, this.boundSource, headerAggregations, null);
|
|
884
|
+
}
|
|
597
885
|
}
|
|
598
886
|
/**
|
|
599
|
-
*
|
|
887
|
+
* Data la definizione dei gruppi da generare da una lista di oggetti, suddivide gli oggetti passati in gruppi e sottogruppi
|
|
600
888
|
*
|
|
601
|
-
* @param {
|
|
889
|
+
* @param {Group[]} grps Definizione dei gruppi
|
|
890
|
+
* @param {number} currentIndex Indice di elaborazione. Al livello 0 ho tutti gli oggetti e devo generare i primi gruppi, a livello 1 ho tutti i gruppi principali e devo
|
|
891
|
+
* elaborare i sottogruppi, e così via ricorsivamente...
|
|
892
|
+
* @param {any[]} items Oggetti da raggruppare
|
|
893
|
+
* @param {GroupOrAggregation[]} aggregations Info di aggregazione
|
|
894
|
+
* @param {any} parent Riferimento al gruppo padre
|
|
895
|
+
*
|
|
896
|
+
* @todo: INTERNALDB
|
|
602
897
|
*/
|
|
603
|
-
|
|
604
|
-
|
|
898
|
+
getGroupsRecursive(grps, currentIndex, items, aggregations, parent) {
|
|
899
|
+
// Se l'indice è 0 devo sicuramente nascondere tutti gli oggetti. Solo i gruppi saranno visualizzati
|
|
900
|
+
if (currentIndex == 0)
|
|
901
|
+
items.forEach(i => i._visible = false);
|
|
902
|
+
let grp = grps[currentIndex];
|
|
903
|
+
let ret = [];
|
|
904
|
+
let last = grps.length == currentIndex + 1;
|
|
905
|
+
let groups = this.groupBy(items, grp.column);
|
|
906
|
+
for (let prop in groups) {
|
|
907
|
+
let itms = groups[prop];
|
|
908
|
+
let gp = new Group(grp.column, itms.length, prop);
|
|
909
|
+
gp.aggregations = this.generateAggregations(itms, aggregations);
|
|
910
|
+
let anygp = gp;
|
|
911
|
+
anygp._group = true;
|
|
912
|
+
anygp._expanded = false;
|
|
913
|
+
if (!parent) {
|
|
914
|
+
anygp._thisRoute = [{ column: gp.column, value: gp.value }];
|
|
915
|
+
anygp._thisKey = gp.value;
|
|
916
|
+
anygp._grouplevel = 0;
|
|
917
|
+
}
|
|
918
|
+
else {
|
|
919
|
+
anygp._parent = parent._thisKey;
|
|
920
|
+
anygp._parentRoute = parent._thisRoute;
|
|
921
|
+
anygp._thisRoute = [...parent._thisRoute, { column: gp.column, value: gp.value }];
|
|
922
|
+
anygp._thisKey = parent._thisKey + gp.value;
|
|
923
|
+
anygp._grouplevel = parent._grouplevel + 1;
|
|
924
|
+
}
|
|
925
|
+
// Pusho il gruppo, tutti i gruppi del livello sotto, o gli item se io sono l'ultimo gruppo.
|
|
926
|
+
// La visibilità è solo per il gruppo a livello 0, tutti gli altri gruppi saranno mostrati o nascosti di conseguenza
|
|
927
|
+
if (currentIndex == 0)
|
|
928
|
+
anygp._visible = true;
|
|
929
|
+
this.calculateHash([anygp]);
|
|
930
|
+
this.cacheAggregations(anygp);
|
|
931
|
+
// Aggiungo il gruppo padre
|
|
932
|
+
ret.push(anygp);
|
|
933
|
+
this.rgGroupCache.set(anygp._thisKey, anygp);
|
|
934
|
+
if (!last) {
|
|
935
|
+
//Dal gruppo padre, se non è l'ultimo gruppo della catena, calcolo ricorsivamente tutta la catena sotto
|
|
936
|
+
let subGroupsAndItems = this.getGroupsRecursive(grps, currentIndex + 1, itms, aggregations, anygp);
|
|
937
|
+
let childgroups = subGroupsAndItems.filter(t => t._group && t._parent == anygp._thisKey);
|
|
938
|
+
anygp._groupscount = childgroups.length;
|
|
939
|
+
// Aggiungo la catena del gruppo sotto, aggiungendo alla cache solo i gruppi padre
|
|
940
|
+
ret.push(...subGroupsAndItems);
|
|
941
|
+
this.rgChildGroupsCache.set(anygp._thisKey, childgroups);
|
|
942
|
+
}
|
|
943
|
+
else {
|
|
944
|
+
// Al gruppo padre, se è l'ultimo assegno tutte le foglie assegnandogli anche la chiave del gruppo
|
|
945
|
+
itms.forEach(i => i._thisKey = anygp._thisKey);
|
|
946
|
+
ret.push(...itms);
|
|
947
|
+
this.rgItemCache.set(anygp._thisKey, itms);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
return ret;
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* Data una lista di oggetti genera le aggregazioni specificate. Si considera di avere tutti gli oggetti
|
|
954
|
+
*
|
|
955
|
+
* @param {any[]} items Oggetti di cui calcolare le aggregazione
|
|
956
|
+
* @param {GroupOrAggregation[]} aggregations Aggergazioni da generare
|
|
957
|
+
*
|
|
958
|
+
* @todo: INTERNALDB
|
|
959
|
+
*/
|
|
960
|
+
generateAggregations(items, aggregations) {
|
|
961
|
+
let rets = [];
|
|
962
|
+
let aggregationValue = "", feField = null, stringAgg = null, dateAgg = null, numberAgg = null;
|
|
963
|
+
for (let i = 0; i < aggregations.length; i++) {
|
|
964
|
+
let agg = aggregations[i];
|
|
965
|
+
feField = agg.column;
|
|
966
|
+
if (!feField)
|
|
967
|
+
continue;
|
|
968
|
+
switch (agg.datatype) {
|
|
969
|
+
case 'string':
|
|
970
|
+
stringAgg = items.map(i => i[feField].toString());
|
|
971
|
+
break;
|
|
972
|
+
case 'date':
|
|
973
|
+
dateAgg = items.map(i => new Date(i[feField]).getTime());
|
|
974
|
+
break;
|
|
975
|
+
case 'number':
|
|
976
|
+
numberAgg = items.map(i => parseFloat(i[feField]));
|
|
977
|
+
break;
|
|
978
|
+
}
|
|
979
|
+
switch (agg.aggregation) {
|
|
980
|
+
case 'max':
|
|
981
|
+
switch (agg.datatype) {
|
|
982
|
+
case 'string':
|
|
983
|
+
aggregationValue = stringAgg.sort().reverse()[0];
|
|
984
|
+
break;
|
|
985
|
+
case 'date':
|
|
986
|
+
aggregationValue = new Date(Math.max(...dateAgg)).toString();
|
|
987
|
+
break;
|
|
988
|
+
case 'number':
|
|
989
|
+
aggregationValue = Math.max(...numberAgg).toString();
|
|
990
|
+
break;
|
|
991
|
+
}
|
|
992
|
+
break;
|
|
993
|
+
case 'min':
|
|
994
|
+
switch (agg.datatype) {
|
|
995
|
+
case 'string':
|
|
996
|
+
aggregationValue = stringAgg.sort()[0];
|
|
997
|
+
break;
|
|
998
|
+
case 'date':
|
|
999
|
+
aggregationValue = new Date(Math.min(...dateAgg)).toString();
|
|
1000
|
+
break;
|
|
1001
|
+
case 'number':
|
|
1002
|
+
aggregationValue = Math.min(...numberAgg).toString();
|
|
1003
|
+
break;
|
|
1004
|
+
}
|
|
1005
|
+
break;
|
|
1006
|
+
case 'sum':
|
|
1007
|
+
switch (agg.datatype) {
|
|
1008
|
+
case 'string':
|
|
1009
|
+
aggregationValue = stringAgg.join(", ");
|
|
1010
|
+
break;
|
|
1011
|
+
case 'date':
|
|
1012
|
+
aggregationValue = "";
|
|
1013
|
+
break;
|
|
1014
|
+
case 'number':
|
|
1015
|
+
aggregationValue = numberAgg.reduce((pre, curr) => pre + curr, 0).toString();
|
|
1016
|
+
break;
|
|
1017
|
+
}
|
|
1018
|
+
break;
|
|
1019
|
+
}
|
|
1020
|
+
rets.push(new GroupAggregation(agg.column, agg.aggregation, aggregationValue));
|
|
1021
|
+
}
|
|
1022
|
+
return rets;
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Data una lista di oggetti effettua dei raggruppamenti in base alla proprietà **field**, restituendo un oggetto del tipo { Gruppo1: oggetti[], Gruppo2: oggetti[], ecc... }
|
|
1026
|
+
*
|
|
1027
|
+
* @param {any[]} array Lista degli oggetti da raggruppare
|
|
1028
|
+
* @param {string} field Campo su cui effettuare i raggruppamenti
|
|
1029
|
+
*
|
|
1030
|
+
* @returns {{ [id: string]: any[] }} Dizionario dei gruppi
|
|
1031
|
+
*
|
|
1032
|
+
* @todo: INTERNALDB
|
|
1033
|
+
*/
|
|
1034
|
+
groupBy(array, field) {
|
|
1035
|
+
let ret = {};
|
|
1036
|
+
for (let i = 0; i < array.length; i++) {
|
|
1037
|
+
let x = array[i];
|
|
1038
|
+
(ret[x[field]] = ret[x[field]] || []).push(x);
|
|
1039
|
+
}
|
|
1040
|
+
return ret;
|
|
1041
|
+
}
|
|
1042
|
+
;
|
|
1043
|
+
/**
|
|
1044
|
+
* Effettua il binding degli oggetti pervenuti da questa chiamata con gli oggetti effettivamente da graficare
|
|
1045
|
+
*
|
|
1046
|
+
* @param {any} view View da cui sono arrivati gli oggetti. Può essere o un array se sono in **arrayMode** o una AppSearch<T> se sono in **viewMode**
|
|
1047
|
+
*/
|
|
1048
|
+
bindDisplayToLoadedItemsOrGroups(view) {
|
|
1049
|
+
var _a, _b;
|
|
1050
|
+
if (this.TMPBoundSource.length == 0) {
|
|
1051
|
+
this.BaseItemsCount = 0;
|
|
605
1052
|
return;
|
|
606
|
-
|
|
1053
|
+
}
|
|
1054
|
+
if (this.arrayMode || !this.UseCustomCells) {
|
|
1055
|
+
this.boundSource = this.TMPBoundSource;
|
|
1056
|
+
this.BaseItemsCount = (view === null || view === void 0 ? void 0 : view.objectcount) || view.length;
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
let groupingKeys = ((_b = (_a = view.groupings) === null || _a === void 0 ? void 0 : _a.filter(t => !t.aggregation)) === null || _b === void 0 ? void 0 : _b.length) || 0;
|
|
1060
|
+
if (groupingKeys == 0) {
|
|
1061
|
+
this.boundSource = this.TMPBoundSource;
|
|
1062
|
+
this.BaseItemsCount = view.objectcount;
|
|
1063
|
+
return;
|
|
1064
|
+
}
|
|
1065
|
+
this.handleNewDataOnRowGrouping(view, groupingKeys);
|
|
607
1066
|
}
|
|
608
1067
|
/**
|
|
609
|
-
*
|
|
1068
|
+
* In modalità rowgrouping quando mi arriva un nuovo blocco di oggetti devo aggiungerlo alla vista attuale:
|
|
610
1069
|
*
|
|
611
|
-
*
|
|
612
|
-
*
|
|
1070
|
+
* 1) Se non viene richiesto il dettaglio di alcun gruppo significa che devo considerare mi siano arrivati tutti i gruppi principali
|
|
1071
|
+
* 2) Se viene richiesto il dettaglio di un gruppo diverso dall'ultimo devo aggiungere dopo al gruppo cliccato la lista dei sottogruppi
|
|
1072
|
+
* 2) Se viene richiesto il dettaglio dell'ultimo gruppo devo aggiungere dopo al gruppo cliccato la lista degli oggetti
|
|
1073
|
+
*
|
|
1074
|
+
* @param {any} view AppSearch<T> da cui sono arrivati gli oggetti
|
|
1075
|
+
* @param {number} groupingKeys Livelli di raggruppamento da aspettarsi sui dati
|
|
1076
|
+
*
|
|
1077
|
+
* @todo: ROWGROUPING
|
|
613
1078
|
*/
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
itm.
|
|
626
|
-
|
|
1079
|
+
handleNewDataOnRowGrouping(view, groupingKeys) {
|
|
1080
|
+
var _a, _b;
|
|
1081
|
+
// 1) Se non viene richiesto il dettaglio di alcun gruppo significa che la chiamata restituisce la lista paginata dei gruppi principali.
|
|
1082
|
+
// Li tratto come se fosse una qualsiasi altra query paginata su N elementi
|
|
1083
|
+
if ((((_a = view.requestedgroups) === null || _a === void 0 ? void 0 : _a.length) || 0) == 0) {
|
|
1084
|
+
this.boundSource = this.TMPBoundSource;
|
|
1085
|
+
this.rgGroupCache = new Map();
|
|
1086
|
+
this.rgItemCache = new Map();
|
|
1087
|
+
this.rgChildGroupsCache = new Map();
|
|
1088
|
+
this.TMPBoundSource.forEach(itm => {
|
|
1089
|
+
itm._thisRoute = itm._group ? [{ column: itm.column, value: itm.value }] : [];
|
|
1090
|
+
itm._thisKey = itm._group ? itm.value : null;
|
|
1091
|
+
itm._grouplevel = 0;
|
|
1092
|
+
this.rgGroupCache.set(itm._thisKey, itm);
|
|
1093
|
+
});
|
|
1094
|
+
// Resetto la ricerca alla cache di questa "sessione"
|
|
1095
|
+
let firstItem = this.TMPBoundSource[0];
|
|
1096
|
+
this.MainGroupView = Object.assign({}, view);
|
|
1097
|
+
this.groupSearchRequestsCache = [{ path: '', route: [{ column: firstItem.column, value: firstItem.value }], view: this.MainGroupView, group_column: this.TMPBoundSource[0].column }];
|
|
1098
|
+
this.BaseItemsCount = view.objectcount;
|
|
627
1099
|
}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
1100
|
+
else {
|
|
1101
|
+
// 2) Se viene richiesto il dettaglio di un qualsiasi gruppo diverso dall'ultimo vuol dire che devo aggiungere
|
|
1102
|
+
// dopo al gruppo che ho cliccato la lista dei gruppi tirata fuori questa volta (intermediateGroup = true)
|
|
1103
|
+
/*
|
|
1104
|
+
* GruppoA GruppoA
|
|
1105
|
+
* GruppoB GruppoB
|
|
1106
|
+
* GruppoC <- Clicco qui GruppoC
|
|
1107
|
+
* GruppoD GruppoC1
|
|
1108
|
+
* GruppoE GruppoC2
|
|
1109
|
+
* GruppoD
|
|
1110
|
+
* GruppoE
|
|
1111
|
+
*/
|
|
1112
|
+
// 3) se i gruppi richiesti dalla view sono uguali ai gruppi presenti vuol dire che sto prendendo gli oggetti veri e propri, sono in
|
|
1113
|
+
// view.items e quindi in TMPBoundSource, ho inoltre le informazioni di paginazione **per il singolo sottogruppo** (intermediateGroup = false)
|
|
1114
|
+
/*
|
|
1115
|
+
* GruppoA GruppoA
|
|
1116
|
+
* GruppoC1 GruppoC1
|
|
1117
|
+
* GruppoB GruppoB
|
|
1118
|
+
* GruppoC GruppoC
|
|
1119
|
+
* GruppoC1 <-- Clicco qui GruppoC1
|
|
1120
|
+
* Oggetto1
|
|
1121
|
+
* Oggetto2
|
|
1122
|
+
* Oggetto3
|
|
1123
|
+
* GruppoC2 GruppoC2
|
|
1124
|
+
* GruppoD GruppoD
|
|
1125
|
+
* GruppoE GruppoE
|
|
1126
|
+
*/
|
|
1127
|
+
let intermediateGroup = view.requestedgroups.length != groupingKeys;
|
|
1128
|
+
let items = this.boundSource;
|
|
1129
|
+
let insertIndex = 0;
|
|
1130
|
+
let groupKey = "";
|
|
1131
|
+
let groupRoute = [];
|
|
1132
|
+
// Navigo la stuttura dei gruppi ignorando ricorsivamente tutti gli indici fino ai gruppi che mi interessano in modo da non beccare il primo "GruppoC1" del caso sopra
|
|
1133
|
+
for (let i = 0; i < view.requestedgroups.length; i++) {
|
|
1134
|
+
let rg = view.requestedgroups[i];
|
|
1135
|
+
groupKey += rg.value;
|
|
1136
|
+
groupRoute.push({ column: rg.column, value: rg.value });
|
|
1137
|
+
insertIndex = items.findIndex((t, i) => i >= insertIndex && t._group && t.column == rg.column && t.value == rg.value);
|
|
1138
|
+
}
|
|
1139
|
+
let itemsCacheReference;
|
|
1140
|
+
let childGroupsCacheReference;
|
|
1141
|
+
// Se non è un gruppo intermedio devo ripulire la cache del gruppo su cui ho attualmente cliccato. Gli oggetti saranno riaggiunti dopo
|
|
1142
|
+
if (!intermediateGroup) {
|
|
1143
|
+
this.rgItemCache.set(groupKey, []);
|
|
1144
|
+
itemsCacheReference = this.rgItemCache.get(groupKey);
|
|
1145
|
+
}
|
|
1146
|
+
else {
|
|
1147
|
+
// Se invece è un gruppo intermedio devo ripulire sia tutti i child group ricorsivamente, sia tutti gli item
|
|
1148
|
+
for (let key of this.rgChildGroupsCache.keys())
|
|
1149
|
+
if (key.startsWith(groupKey))
|
|
1150
|
+
this.rgChildGroupsCache.delete(key);
|
|
1151
|
+
for (let key of this.rgItemCache.keys())
|
|
1152
|
+
if (key.startsWith(groupKey))
|
|
1153
|
+
this.rgItemCache.delete(key);
|
|
1154
|
+
this.rgChildGroupsCache.set(groupKey, []);
|
|
1155
|
+
childGroupsCacheReference = this.rgChildGroupsCache.get(groupKey);
|
|
1156
|
+
}
|
|
1157
|
+
// Assegno un livello ai valori che arrivano da usare per formattare la parte grafica. Il primo gruppo cliccato sarà a livello 1,
|
|
1158
|
+
// il secondo sarà a livello 2 e così via...
|
|
1159
|
+
// Li marco inoltre con il parent in modo da poter eliminare i vecchi qualora servisse
|
|
1160
|
+
this.TMPBoundSource.forEach(itm => {
|
|
1161
|
+
itm._parent = groupKey;
|
|
1162
|
+
itm._parentRoute = groupRoute;
|
|
1163
|
+
itm._thisRoute = itm._group ? [...groupRoute, new GroupRouteFragment(itm.column, itm.value)] : [];
|
|
1164
|
+
itm._thisKey = itm._group ? groupKey + itm.value : groupKey;
|
|
1165
|
+
// Per le ricerca intermedie metto i gruppi nella cache dei gruppi
|
|
1166
|
+
if (intermediateGroup) {
|
|
1167
|
+
itm._grouplevel = view.requestedgroups.length;
|
|
1168
|
+
this.rgGroupCache.set(itm._thisKey, itm);
|
|
1169
|
+
childGroupsCacheReference.push(itm);
|
|
1170
|
+
}
|
|
1171
|
+
else {
|
|
1172
|
+
// Metto anche gli oggetti nella cache non ricorsiva
|
|
1173
|
+
itemsCacheReference.push(itm);
|
|
1174
|
+
}
|
|
1175
|
+
});
|
|
1176
|
+
// Elimino gli oggetti vecchi
|
|
1177
|
+
// 1) Ricerca intermedia, stato salvato - Elimino tutti gli item e tutti i gruppi la cui route è più lunga della corrente, tutti gli item relativi alla path corrente, e tutte
|
|
1178
|
+
// le cache di ricerca effettuate su una path più profonda dell'attuale
|
|
1179
|
+
// 2) Ricerca finale o ricerca intermedia senza stato salvato - Elimino tutti gli item relativi alla path corrente
|
|
1180
|
+
// Per "stato salvato" si intendono ricerche vecchie salvate per poter essere rieffettuate in caso di ordinamenti su colonne di interesse
|
|
1181
|
+
if (intermediateGroup && view.savedstate) {
|
|
1182
|
+
this.boundSource = this.boundSource.filter(t => !(t._item || t._thisRoute.length > groupRoute.length));
|
|
1183
|
+
this.groupSearchRequestsCache = this.groupSearchRequestsCache.filter(t => !(t.route.length > groupRoute.length));
|
|
1184
|
+
}
|
|
1185
|
+
this.boundSource = this.boundSource.filter(t => !(t._parent == groupKey));
|
|
1186
|
+
let thisGroup = this.boundSource[insertIndex];
|
|
1187
|
+
if (intermediateGroup)
|
|
1188
|
+
thisGroup._groupscount = (_b = this.View) === null || _b === void 0 ? void 0 : _b.groupcount;
|
|
1189
|
+
// Li sostituisco coi nuovi di questa ricerca
|
|
1190
|
+
this.boundSource.splice(insertIndex + 1, 0, ...this.TMPBoundSource);
|
|
1191
|
+
// Aggiungo un separatore alla fine o all'inizio di questi gruppi che dovrà occuparsi di caricare ALTRI gruppi o oggetti (se sono all'ultimo gruppo)
|
|
1192
|
+
let addLast = false;
|
|
1193
|
+
this.boundSource.splice(insertIndex + 1 + (addLast ? this.TMPBoundSource.length : 0), 0, this.getGroupSeparator(view, groupKey, groupRoute, view.requestedgroups.length, intermediateGroup ? 'groups' : 'items'));
|
|
1194
|
+
// Aggiungo la ricerca alla cache di questa "sessione"
|
|
1195
|
+
let toAdd = { path: groupKey, route: groupRoute, view: Object.assign({}, view), group_column: intermediateGroup ? this.TMPBoundSource[0].column : '' };
|
|
1196
|
+
let prev = this.groupSearchRequestsCache.findIndex(t => t.path == toAdd.path && t.group_column == toAdd.group_column);
|
|
1197
|
+
if (prev == -1)
|
|
1198
|
+
this.groupSearchRequestsCache.push(toAdd);
|
|
1199
|
+
else
|
|
1200
|
+
this.groupSearchRequestsCache.splice(prev, 1, toAdd);
|
|
639
1201
|
}
|
|
640
1202
|
}
|
|
1203
|
+
/**
|
|
1204
|
+
* Metodo richiamato solo quando **TMPRowTDs** e **TMPRowTHs** sono completamente generati ed aggiustati. Serve per collegarli alle variabili usate lato binding HTML
|
|
1205
|
+
*/
|
|
1206
|
+
MoveTemporaryVariablesToRealOnes() {
|
|
1207
|
+
this.RowTDs = this.TMPRowTDs;
|
|
1208
|
+
this.RowTHs = this.TMPRowTHs;
|
|
1209
|
+
this.RowThGroups = this.TMPRowThGroups ? this.TMPRowThGroups.reverse() : null;
|
|
1210
|
+
this.Columns.Visibile = this.RowTHs.filter(t => t.Visible).length;
|
|
1211
|
+
this.Columns.VisibleUnpinned = this.RowTHs.filter(t => t.Visible && !t.Pinned).length;
|
|
1212
|
+
this.Columns.Global = this.Columns.VisibleUnpinned + (this.HasPinnedColumns ? 1 : 0) + (this.Selection ? 1 : 0) + (this.Removal ? 1 : 0) + (this.Export || this.HiddenColumns || this.ColumnsOrdering || this.CornerMenuOptions ? 1 : 0);
|
|
1213
|
+
}
|
|
641
1214
|
/**
|
|
642
1215
|
* Permette di selezionare o deselezionare in maniera arbitraria degli oggetti
|
|
643
1216
|
*
|
|
644
1217
|
* @param {any[]} items Oggetti da selezionare o deselezionare
|
|
645
1218
|
* @param {boolean} select **true** per selezionarli, **false** per non toccarli
|
|
1219
|
+
*
|
|
1220
|
+
* @todo: SELECTION
|
|
646
1221
|
*/
|
|
647
1222
|
setSelectionStatus(items, select) {
|
|
648
1223
|
this.handleItemsSelection(items, select);
|
|
@@ -676,7 +1251,7 @@ export class EsTableComponent {
|
|
|
676
1251
|
* @param {EsTh[] | EsThDirective[]} ths Colonne della tabella
|
|
677
1252
|
*/
|
|
678
1253
|
reviewColumnsList(ths) {
|
|
679
|
-
this.
|
|
1254
|
+
this.TMPColumnsList = [];
|
|
680
1255
|
if (ths.length == 0)
|
|
681
1256
|
return;
|
|
682
1257
|
// Appena il contentChildren è valorizzato scorro tutti gli header
|
|
@@ -690,18 +1265,99 @@ export class EsTableComponent {
|
|
|
690
1265
|
// Salvo le informazioni dell'header per far parte della lista da cui scegliere quali colonne visualizzare/nascondere
|
|
691
1266
|
// Di default la visibilità è quella impostata nel componente
|
|
692
1267
|
if (this.HiddenColumns || th.Visible)
|
|
693
|
-
this.
|
|
1268
|
+
this.TMPColumnsList.push(new EsTableColumn(th.ID, th.Description, th.Visible, th.Fixed, null, null, null));
|
|
694
1269
|
}
|
|
695
1270
|
else {
|
|
1271
|
+
let column = th.th;
|
|
696
1272
|
// Se non ho un id il th è considerato inerte
|
|
697
|
-
if (!
|
|
1273
|
+
if (!column)
|
|
698
1274
|
continue;
|
|
699
1275
|
// Salvo le informazioni dell'header per far parte della lista da cui scegliere quali colonne visualizzare/nascondere
|
|
700
1276
|
// Di default la visibilità è quella impostata nel componente
|
|
701
|
-
if (this.HiddenColumns || th.thVisible)
|
|
702
|
-
this.ColumnsList.
|
|
1277
|
+
if (this.HiddenColumns || th.thVisible) {
|
|
1278
|
+
let previouslyPinned = !this.ColumnsList || this.ColumnsList.length == 0 || !this.ColumnsList.find(t => t.id == column) ? null : this.ColumnsList.find(t => t.id == column).pinned;
|
|
1279
|
+
this.TMPColumnsList.push(new EsTableColumn(column, null, th.thVisible, (th.thFixed || th.thGroup), previouslyPinned == null ? th.thPinned : previouslyPinned, th.thPinnedWidth, th.Template));
|
|
1280
|
+
}
|
|
703
1281
|
}
|
|
704
1282
|
}
|
|
1283
|
+
this.ColumnsList = [];
|
|
1284
|
+
this.TMPColumnsList.forEach(c => { this.ColumnsList.push(Object.assign({}, c)); });
|
|
1285
|
+
}
|
|
1286
|
+
/**
|
|
1287
|
+
* Prende i th e i td in modalità diretive e li ordina in base a se ci sono colonne fixed o meno
|
|
1288
|
+
*/
|
|
1289
|
+
moveFixedColumnsAtTheBeginning(ths, tds) {
|
|
1290
|
+
let thsCache = {};
|
|
1291
|
+
let fixeds = 0, pinneds = 0;
|
|
1292
|
+
let columnsCache = {};
|
|
1293
|
+
let columnsIndexCache = {};
|
|
1294
|
+
// Creo la cache delle colonne
|
|
1295
|
+
for (let coli = 0; coli < this.ColumnsList.length; coli++) {
|
|
1296
|
+
let col = this.ColumnsList[coli];
|
|
1297
|
+
columnsCache[col.id] = col;
|
|
1298
|
+
}
|
|
1299
|
+
// Sposto tutti gli header fixed o pinned all'inizio
|
|
1300
|
+
for (let i = 0; i < ths.length; i++) {
|
|
1301
|
+
let th = ths[i];
|
|
1302
|
+
if (this.isEsTh(th)) {
|
|
1303
|
+
thsCache[th.ID] = th;
|
|
1304
|
+
if (th.Fixed) {
|
|
1305
|
+
if (i != pinneds + fixeds)
|
|
1306
|
+
this.arrayMove(ths, i, pinneds + fixeds);
|
|
1307
|
+
fixeds++;
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
else {
|
|
1311
|
+
thsCache[th.th] = th;
|
|
1312
|
+
// Riassegno sempre per ripulire valori di partenza o per aggiornarli in caso di modifiche utente
|
|
1313
|
+
th.thPinned = (!columnsCache[th.th] && th.thPinned) || (columnsCache[th.th] && columnsCache[th.th].pinned);
|
|
1314
|
+
if (th.thPinned) {
|
|
1315
|
+
if (i != pinneds)
|
|
1316
|
+
this.arrayMove(ths, i, pinneds);
|
|
1317
|
+
pinneds++;
|
|
1318
|
+
}
|
|
1319
|
+
//In questo caso sono informazioni statiche invece, non modificabili dall'utente, quindi non mi dò preoccupazioni
|
|
1320
|
+
if (th.thFixed || th.thGroup) {
|
|
1321
|
+
if (i != pinneds + fixeds)
|
|
1322
|
+
this.arrayMove(ths, i, pinneds + fixeds);
|
|
1323
|
+
fixeds++;
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
if (this.isEsTh(ths[0]) || this.isEsTd(tds[0]))
|
|
1328
|
+
return;
|
|
1329
|
+
// Cache degli indici per riposizionare i td come i th
|
|
1330
|
+
for (let i = 0; i < ths.length; i++)
|
|
1331
|
+
columnsIndexCache[ths[i].th] = i;
|
|
1332
|
+
// Riordino le celle per fargli mantenere la stessa struttura dei th
|
|
1333
|
+
let newTds = new Array(ths.length);
|
|
1334
|
+
for (let i = 0; i < tds.length; i++) {
|
|
1335
|
+
let item = tds[i];
|
|
1336
|
+
newTds[columnsIndexCache[item.td]] = item;
|
|
1337
|
+
}
|
|
1338
|
+
this.HasPinnedColumns = pinneds > 0;
|
|
1339
|
+
}
|
|
1340
|
+
/**
|
|
1341
|
+
* In base alla configurazione delle colonne calcola le dimenioni delle colonne pinnate
|
|
1342
|
+
*/
|
|
1343
|
+
evaluatePinnedColumnsWidth() {
|
|
1344
|
+
if (!this.HasPinnedColumns)
|
|
1345
|
+
return;
|
|
1346
|
+
this.PinnedContainerWidth = 0;
|
|
1347
|
+
for (let i = 0; i < this.ColumnsList.length; i++) {
|
|
1348
|
+
let col = this.ColumnsList[i];
|
|
1349
|
+
if (col.pinned && col.visible)
|
|
1350
|
+
this.PinnedContainerWidth += col.pinnedWidth;
|
|
1351
|
+
}
|
|
1352
|
+
this.PinnedContainerWidth += this.Selection ? 25 : 0;
|
|
1353
|
+
}
|
|
1354
|
+
/**
|
|
1355
|
+
* Helper per spostare un oggetto di un array da un indice all'altro, in place
|
|
1356
|
+
*/
|
|
1357
|
+
arrayMove(array, oldI, newI) {
|
|
1358
|
+
if (newI > array.length - 1 || oldI > array.length - 1 || newI < 0 || oldI < 0)
|
|
1359
|
+
throw "Gli indici passati non fanno riferimento a una posizione dell'array. Length: " + array.length + " Old:" + oldI + " New: " + newI;
|
|
1360
|
+
array.splice(newI, 0, array.splice(oldI, 1)[0]);
|
|
705
1361
|
}
|
|
706
1362
|
/**
|
|
707
1363
|
* Terminato il binding delle colonne da **reviewColumnsList** e della **View** dal **writeValue** questo metodo si occupa
|
|
@@ -710,14 +1366,19 @@ export class EsTableComponent {
|
|
|
710
1366
|
* @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
|
|
711
1367
|
*/
|
|
712
1368
|
alignColumnsIfLoadedView(view) {
|
|
713
|
-
let emitChanged = view.savedstate;
|
|
1369
|
+
let emitChanged = this.viewMode && view.savedstate;
|
|
714
1370
|
let newColset = [];
|
|
715
1371
|
if (!this.ColumnsList || this.ColumnsList.length == 0)
|
|
716
1372
|
return;
|
|
1373
|
+
let columns = this.viewMode ? view.columns : this.arrayColumns;
|
|
717
1374
|
this.ColumnsList.forEach(c => {
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
1375
|
+
// Se la colonna è pinnata mi arriva col simoleon
|
|
1376
|
+
let exCl = columns.filter(cc => cc.replace('§', '') == c.id);
|
|
1377
|
+
// Se la colonna è pinnata aggiorno l'informazione nella view
|
|
1378
|
+
if (exCl.length == 1)
|
|
1379
|
+
c.pinned = exCl[0].startsWith('§');
|
|
1380
|
+
// Se l'appsearch viene da uno stato precedente, uso le informazioni sulle colonne che ha dentro, altrimenti sovrascrivo tutto **
|
|
1381
|
+
if (c.visible && columns.length == 0)
|
|
721
1382
|
newColset.push(c.id);
|
|
722
1383
|
// Se ho una colonna lato AppSearch e nella ColumnList non è visibile, allineo all'AppSearch
|
|
723
1384
|
else if (exCl.length == 1 && !c.visible)
|
|
@@ -727,21 +1388,22 @@ export class EsTableComponent {
|
|
|
727
1388
|
c.visible = false;
|
|
728
1389
|
});
|
|
729
1390
|
// Non ho colonne nella appsearch, vuol dire che sono al primo binding
|
|
730
|
-
if (
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
1391
|
+
if (columns.length == 0) {
|
|
1392
|
+
if (this.viewMode)
|
|
1393
|
+
view.columns = newColset;
|
|
1394
|
+
else
|
|
1395
|
+
this.arrayColumns = newColset;
|
|
1396
|
+
}
|
|
1397
|
+
if ((this.viewMode && view.savedstate) && this.ColumnsOrdering && view.column_ordering.length > 0) {
|
|
734
1398
|
// Scorro gli ordinamenti che avevo salvato e ricreo la ColumnsList in base a loro
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
newColList.push(c);
|
|
739
|
-
});
|
|
740
|
-
});
|
|
1399
|
+
let newColList = [];
|
|
1400
|
+
view.column_ordering.forEach(co => { this.ColumnsList.forEach(c => { if (c.id == co)
|
|
1401
|
+
newColList.push(c); }); });
|
|
741
1402
|
this.ColumnsList = newColList;
|
|
742
1403
|
}
|
|
743
1404
|
// In ogni caso questo non mi serve più, lo resetto **
|
|
744
|
-
|
|
1405
|
+
if (this.viewMode)
|
|
1406
|
+
view.savedstate = false;
|
|
745
1407
|
if (emitChanged)
|
|
746
1408
|
this.changed();
|
|
747
1409
|
}
|
|
@@ -752,20 +1414,22 @@ export class EsTableComponent {
|
|
|
752
1414
|
* @param {'DESC' | 'ASC'} order Nuovo ordine selezionato per la colonna
|
|
753
1415
|
*/
|
|
754
1416
|
thOrderChanged(id, order) {
|
|
755
|
-
if (!this.viewMode) {
|
|
756
|
-
console.warn('Order changed on a table not in viewMode. Operation not supported');
|
|
1417
|
+
if (!this.viewMode && !this.arrayMode) {
|
|
1418
|
+
console.warn('Order changed on a table not in viewMode or Array mode. Operation not supported');
|
|
757
1419
|
return;
|
|
758
1420
|
}
|
|
759
1421
|
if (!this.OrderByColumn)
|
|
760
1422
|
return;
|
|
761
|
-
let
|
|
1423
|
+
let orders = this.viewMode ? this.View.orders : this.arrayOrders;
|
|
762
1424
|
let orderToAdd = true;
|
|
763
1425
|
let orderToRemove = null;
|
|
764
1426
|
// Se per qualche motivo il costruttore non è passato (cache tarpate o simila) fixo
|
|
765
|
-
if (!
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
1427
|
+
if (!orders && this.viewMode)
|
|
1428
|
+
this.View.orders = [];
|
|
1429
|
+
else if (!orders && this.arrayMode)
|
|
1430
|
+
this.arrayOrders = [];
|
|
1431
|
+
for (let i = 0; i < orders.length; i++) {
|
|
1432
|
+
let t = orders[i];
|
|
769
1433
|
if (t.id == id) {
|
|
770
1434
|
if (order) {
|
|
771
1435
|
t.order = order;
|
|
@@ -776,27 +1440,46 @@ export class EsTableComponent {
|
|
|
776
1440
|
}
|
|
777
1441
|
}
|
|
778
1442
|
if (orderToRemove != null) {
|
|
779
|
-
|
|
1443
|
+
orders.splice(orderToRemove, 1);
|
|
780
1444
|
}
|
|
781
1445
|
else if (orderToAdd) {
|
|
782
1446
|
if (this.MultipleOrderingDirectives)
|
|
783
|
-
|
|
784
|
-
else
|
|
785
|
-
|
|
1447
|
+
orders.push(new AppOrdering(id, order));
|
|
1448
|
+
else {
|
|
1449
|
+
if (this.viewMode)
|
|
1450
|
+
this.View.orders = [new AppOrdering(id, order)];
|
|
1451
|
+
else if (this.arrayMode)
|
|
1452
|
+
this.arrayOrders = [new AppOrdering(id, order)];
|
|
1453
|
+
}
|
|
786
1454
|
}
|
|
787
1455
|
this.onOrderChanged.emit({ id, order });
|
|
788
|
-
this.
|
|
1456
|
+
if (this.viewMode) {
|
|
1457
|
+
if (this.groupSearchRequestsCache.length > 0)
|
|
1458
|
+
this.emitRowGroupingSearches(id, orders);
|
|
1459
|
+
else
|
|
1460
|
+
this.emitSearchRequest(false);
|
|
1461
|
+
}
|
|
1462
|
+
else if (this.arrayMode)
|
|
1463
|
+
this.internalWriteValue();
|
|
789
1464
|
}
|
|
790
1465
|
/**
|
|
791
1466
|
* Metodo da chiamare ogni volta che si vuole dare evidenza all'esterno del bisogno di rieffettuare la ricerca
|
|
1467
|
+
*
|
|
1468
|
+
* @param {boolean} resetsPage Indica al listener che deve resettare il numero di pagina
|
|
1469
|
+
* @param {AppSearch<any>} viewOverride Override della view da emettere per questa ricerca
|
|
792
1470
|
*/
|
|
793
|
-
emitSearchRequest(
|
|
794
|
-
if (this.viewMode) {
|
|
1471
|
+
emitSearchRequest(resetsPage, viewOverride) {
|
|
1472
|
+
if (this.viewMode && !viewOverride) {
|
|
795
1473
|
this.View.internalsearchrequest = true;
|
|
796
1474
|
this.changed();
|
|
797
1475
|
}
|
|
1476
|
+
if (viewOverride) {
|
|
1477
|
+
if (resetsPage)
|
|
1478
|
+
viewOverride.page = 1;
|
|
1479
|
+
viewOverride.internalsearchrequest = true;
|
|
1480
|
+
}
|
|
798
1481
|
this.researchInProgress = true;
|
|
799
|
-
this.onSearchRequest.emit(
|
|
1482
|
+
this.onSearchRequest.emit(viewOverride ? viewOverride : resetsPage);
|
|
800
1483
|
}
|
|
801
1484
|
/**
|
|
802
1485
|
* In base alla visibilità registrata nelle **ColumnsList** questo metodo si occupa di prendere tutti i **EsThs** ed **EsTds** relativi e nasonderli/mostrarli
|
|
@@ -808,16 +1491,19 @@ export class EsTableComponent {
|
|
|
808
1491
|
* @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
|
|
809
1492
|
*/
|
|
810
1493
|
refreshColumnsVisibility(ths, tds, view) {
|
|
811
|
-
let columnsCache = {};
|
|
812
1494
|
let newColset = [];
|
|
813
1495
|
let fixedThs = {};
|
|
1496
|
+
let columnsCache = {};
|
|
814
1497
|
for (let coli = 0; coli < this.ColumnsList.length; coli++) {
|
|
815
1498
|
let col = this.ColumnsList[coli];
|
|
816
1499
|
columnsCache[col.id] = col;
|
|
817
1500
|
if (col.visible)
|
|
818
|
-
newColset.push(col.id);
|
|
1501
|
+
newColset.push((col.pinned ? "§" : "") + col.id);
|
|
819
1502
|
}
|
|
820
|
-
view
|
|
1503
|
+
if (view)
|
|
1504
|
+
view.columns = newColset;
|
|
1505
|
+
else
|
|
1506
|
+
this.arrayColumns = newColset;
|
|
821
1507
|
// Da qui in poi devono essere eseguiti SOLO in fase di writeValue quindi devo assicurarmi di passarli null in tutti i passaggi diversi da quello
|
|
822
1508
|
if (ths) {
|
|
823
1509
|
// Definisco se la colonna è visibile in base alla sua rappresentazione locale in ColumnsList
|
|
@@ -830,7 +1516,7 @@ export class EsTableComponent {
|
|
|
830
1516
|
}
|
|
831
1517
|
else {
|
|
832
1518
|
th.thVisible = th.thFixed || (columnsCache[th.th] ? columnsCache[th.th].visible : th.thVisible);
|
|
833
|
-
if (th.thFixed)
|
|
1519
|
+
if (th.thFixed || th.thGroup)
|
|
834
1520
|
fixedThs[th.th] = true;
|
|
835
1521
|
}
|
|
836
1522
|
}
|
|
@@ -847,18 +1533,6 @@ export class EsTableComponent {
|
|
|
847
1533
|
}
|
|
848
1534
|
this.changed();
|
|
849
1535
|
}
|
|
850
|
-
/**
|
|
851
|
-
*
|
|
852
|
-
*/
|
|
853
|
-
isEsTd(td) {
|
|
854
|
-
return !td._directive;
|
|
855
|
-
}
|
|
856
|
-
/**
|
|
857
|
-
*
|
|
858
|
-
*/
|
|
859
|
-
isEsTh(th) {
|
|
860
|
-
return !th._directive;
|
|
861
|
-
}
|
|
862
1536
|
/**
|
|
863
1537
|
* Allinea gli ordinamenti dati fra le **EsThs** e le informazioni all'interno della View bindata
|
|
864
1538
|
*
|
|
@@ -866,30 +1540,28 @@ export class EsTableComponent {
|
|
|
866
1540
|
* @param {EsTh[] | EsThDirective[]} ths Colonne della tabella
|
|
867
1541
|
*/
|
|
868
1542
|
alignHeadersOrdering(ths, view) {
|
|
869
|
-
let
|
|
1543
|
+
let orders = view ? view.orders : this.arrayOrders;
|
|
870
1544
|
for (let i = 0; i < ths.length; i++) {
|
|
871
1545
|
let th = ths[i];
|
|
872
1546
|
if (this.isEsTh(th)) {
|
|
873
1547
|
th.Order = null;
|
|
874
1548
|
// Assegno tutti gli ordinamenti che mi vengono da AppSearch. Sono i più importanti. Non faccio cache o cose strano perché tanto questa
|
|
875
1549
|
// variabile sarà sempre massimo 3 elementi
|
|
876
|
-
for (let i = 0; i <
|
|
877
|
-
let or =
|
|
1550
|
+
for (let i = 0; i < orders.length; i++) {
|
|
1551
|
+
let or = orders[i];
|
|
878
1552
|
if (or.id == th.ID)
|
|
879
1553
|
th.Order = or.order;
|
|
880
1554
|
}
|
|
881
1555
|
}
|
|
882
1556
|
else {
|
|
883
1557
|
th.thOrder = null;
|
|
884
|
-
for (let i = 0; i <
|
|
885
|
-
let or =
|
|
1558
|
+
for (let i = 0; i < orders.length; i++) {
|
|
1559
|
+
let or = orders[i];
|
|
886
1560
|
if (or.id == th.th)
|
|
887
1561
|
th.thOrder = or.order;
|
|
888
1562
|
}
|
|
889
1563
|
}
|
|
890
1564
|
}
|
|
891
|
-
if (researchNeeded)
|
|
892
|
-
this.emitSearchRequest(false);
|
|
893
1565
|
}
|
|
894
1566
|
/**
|
|
895
1567
|
* Partendo dagli **EsTds** bindati genera, all'interno del dizionario **TMPRowTDs** tutti i contesti dei vari oggetti.
|
|
@@ -905,6 +1577,11 @@ export class EsTableComponent {
|
|
|
905
1577
|
if (tds.length == 0)
|
|
906
1578
|
return;
|
|
907
1579
|
let thsCache = {};
|
|
1580
|
+
let columnsCache = {};
|
|
1581
|
+
for (let coli = 0; coli < this.ColumnsList.length; coli++) {
|
|
1582
|
+
let col = this.ColumnsList[coli];
|
|
1583
|
+
columnsCache[col.id] = col;
|
|
1584
|
+
}
|
|
908
1585
|
for (let i = 0; i < ths.length; i++) {
|
|
909
1586
|
let th = ths[i];
|
|
910
1587
|
thsCache[this.isEsTh(th) ? th.ID : th.th] = th;
|
|
@@ -917,11 +1594,11 @@ export class EsTableComponent {
|
|
|
917
1594
|
if (this.isEsTd(td)) {
|
|
918
1595
|
let th = thsCache[td.ID];
|
|
919
1596
|
if (!!th)
|
|
920
|
-
th.
|
|
1597
|
+
th._referenced = true;
|
|
921
1598
|
else
|
|
922
1599
|
throw "ID dell'oggeto EsTd non compatibile con gli ID dicharati negli EsTh: " + td.ID;
|
|
923
|
-
let isFixed = (this.isEsTh(th) && th.Fixed) || (!this.isEsTh(th) && th.thFixed);
|
|
924
|
-
let itemToAdd = { ID: td.ID, Visible: td.Visible, Class: td.Class, Content: td.Content, RouterLink: td.RouterLink, Template: td.Template };
|
|
1600
|
+
let isFixed = (this.isEsTh(th) && th.Fixed) || (!this.isEsTh(th) && (th.thFixed || th.thGroup));
|
|
1601
|
+
let itemToAdd = { GroupAggregation: false, GroupHeader: false, Wraps: true, ID: td.ID, Visible: td.Visible, Class: td.Class, Content: td.Content, RouterLink: td.RouterLink, Template: td.Template };
|
|
925
1602
|
let ctx = td.Context;
|
|
926
1603
|
if (this.TMPRowTDs[ctx]) {
|
|
927
1604
|
if (isFixed)
|
|
@@ -936,22 +1613,27 @@ export class EsTableComponent {
|
|
|
936
1613
|
}
|
|
937
1614
|
}
|
|
938
1615
|
else {
|
|
939
|
-
for (let i = 0; i < this.
|
|
940
|
-
let
|
|
1616
|
+
for (let i = 0; i < this.boundSource.length; i++) {
|
|
1617
|
+
let item = this.boundSource[i];
|
|
1618
|
+
let ctx = item._hash;
|
|
941
1619
|
let key = td.td;
|
|
942
1620
|
let th = thsCache[td.td];
|
|
943
1621
|
if (!!th)
|
|
944
|
-
th.
|
|
1622
|
+
th._referenced = true;
|
|
945
1623
|
else
|
|
946
1624
|
throw "ID dell'oggeto EsTd non compatibile con gli ID dicharati negli EsTh: " + td.td;
|
|
947
|
-
if (td.tdIf) {
|
|
948
|
-
let
|
|
949
|
-
let
|
|
1625
|
+
if (td.tdIf || (!this.isEsTh(th) && th.thGroup)) {
|
|
1626
|
+
let thCasted = th;
|
|
1627
|
+
let isFixed = (this.isEsTh(th) && th.Fixed) || (!this.isEsTh(th) && (th.thFixed || th.thGroup || th.thPinned));
|
|
1628
|
+
let itemToAdd = item._item ?
|
|
1629
|
+
{ LeftBorder: thCasted._lbord, RightBorder: thCasted._rbord, ID: key, Pinned: columnsCache[td.td].pinned, PinnedWidth: thCasted.thPinnedWidth, GroupHeader: false, GroupAggregation: false, Visible: columnsCache[td.td].visible, Wraps: false, Class: td.tdClass, Template: thCasted.thGroup && !this.ShowItemGroupsColumns ? null : td.Template } :
|
|
1630
|
+
{ LeftBorder: thCasted._lbord, RightBorder: thCasted._rbord, ID: key, Pinned: columnsCache[td.td].pinned, PinnedWidth: thCasted.thPinnedWidth, GroupHeader: thCasted.thGroup, GroupAggregation: !!thCasted.thAggregation, Visible: columnsCache[td.td].visible, Wraps: false, Class: thCasted.thGroupClass || '', Content: this.getGroupCellDisplay(item, key, th) };
|
|
950
1631
|
if (this.TMPRowTDs[ctx]) {
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1632
|
+
// Non serve più grazie al metodo **oveFixedColumnsAtTheBeginning**
|
|
1633
|
+
//if (isFixed)
|
|
1634
|
+
// this.TMPRowTDs[ctx].splice(0 + (contextFixeds[ctx]++), 0, itemToAdd);
|
|
1635
|
+
//else
|
|
1636
|
+
this.TMPRowTDs[ctx].push(itemToAdd);
|
|
955
1637
|
}
|
|
956
1638
|
else {
|
|
957
1639
|
this.RowContexts.push(ctx);
|
|
@@ -968,7 +1650,7 @@ export class EsTableComponent {
|
|
|
968
1650
|
var errs = [];
|
|
969
1651
|
for (let i = 0; i < ths.length; i++) {
|
|
970
1652
|
let th = ths[i];
|
|
971
|
-
if (!th.
|
|
1653
|
+
if (!th._referenced)
|
|
972
1654
|
errs.push(this.isEsTh(th) ? th.ID : th.th);
|
|
973
1655
|
}
|
|
974
1656
|
if (errs.length > 0) {
|
|
@@ -988,44 +1670,231 @@ export class EsTableComponent {
|
|
|
988
1670
|
evaluateRowThs(ths) {
|
|
989
1671
|
if (ths.length == 0)
|
|
990
1672
|
return;
|
|
1673
|
+
let columnsListCache = {};
|
|
1674
|
+
let castedView = this.View;
|
|
1675
|
+
let groupingsUndefined = this.viewMode && (castedView && !castedView.groupings || castedView.groupings.length == 0);
|
|
1676
|
+
for (let i = 0; i < this.ColumnsList.length; i++) {
|
|
1677
|
+
let itm = this.ColumnsList[i];
|
|
1678
|
+
columnsListCache[itm.id] = itm;
|
|
1679
|
+
}
|
|
991
1680
|
this.TMPRowTHs = [];
|
|
992
1681
|
let fixed = 0;
|
|
993
1682
|
for (let i = 0; i < ths.length; i++) {
|
|
994
1683
|
let th = ths[i];
|
|
995
1684
|
let toAdd;
|
|
996
1685
|
if (this.isEsTh(th)) {
|
|
997
|
-
toAdd = {
|
|
1686
|
+
toAdd = { Pinned: false, ID: th.ID, Visible: th.Visible, Class: th.Class, Order: th.Order, Orderable: th.Orderable, Template: null, Content: th.Description, Wrap: false };
|
|
998
1687
|
if (th.Fixed)
|
|
999
1688
|
this.TMPRowTHs.splice(0 + (fixed++), 0, toAdd);
|
|
1000
1689
|
else
|
|
1001
1690
|
this.TMPRowTHs.push(toAdd);
|
|
1002
1691
|
}
|
|
1003
|
-
else if (th.thIf) {
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
this.
|
|
1692
|
+
else if (th.thIf || th.thGroup) {
|
|
1693
|
+
let thClass = (th.thClass || '') + (th.thGroup ? " est-col-min" : "");
|
|
1694
|
+
toAdd = { Pinned: columnsListCache[th.th].pinned, PinnedWidth: th.thPinnedWidth, ID: th.th, Visible: th.thVisible, Class: thClass, Order: th.thOrder, Orderable: th.thOrderable, Template: th.Template, Content: null, Wrap: false, LeftBorder: th._lbord, RightBorder: th._rbord };
|
|
1695
|
+
this.TMPRowTHs.push(toAdd);
|
|
1696
|
+
// Se ho un modello che deve funzionare a rowgrouping ma non è ancora stata effettuata nessuna ricerca sui gruppi principali (groupingsUndefined)
|
|
1697
|
+
// li genero e mando la prima ricerca che dev'essere spedita al backend per il primo caricamento dei gruppi
|
|
1698
|
+
if (groupingsUndefined && (th.thAggregation || th.thGroup)) {
|
|
1699
|
+
let groupAggregations = this.getGroupAggregations(th);
|
|
1700
|
+
if (!castedView.groupings)
|
|
1701
|
+
castedView.groupings = groupAggregations;
|
|
1702
|
+
else
|
|
1703
|
+
castedView.groupings.push(...groupAggregations);
|
|
1704
|
+
this.ResearchNeeded = true;
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
evaluateHeadersGroupingInfos(ths) {
|
|
1710
|
+
// Pregiro per trovare i parent
|
|
1711
|
+
let parentsCache = {};
|
|
1712
|
+
let thsCache = {};
|
|
1713
|
+
for (let i = 0; i < ths.length; i++) {
|
|
1714
|
+
let th = ths[i];
|
|
1715
|
+
if (this.isEsTh(th))
|
|
1716
|
+
continue;
|
|
1717
|
+
thsCache[th.th] = th;
|
|
1718
|
+
if (th.thParent && !parentsCache[th.thParent])
|
|
1719
|
+
parentsCache[th.thParent] = true;
|
|
1720
|
+
}
|
|
1721
|
+
// Secondo giro per beccare il livello massimo e la lista di foglie (th senza parent)
|
|
1722
|
+
let hMaxLevel = 0;
|
|
1723
|
+
let leafs = [];
|
|
1724
|
+
for (let i = 0; i < ths.length; i++) {
|
|
1725
|
+
let th = ths[i];
|
|
1726
|
+
if (this.isEsTh(th)) {
|
|
1727
|
+
leafs.push(th);
|
|
1728
|
+
continue;
|
|
1011
1729
|
}
|
|
1730
|
+
// Se sono una foglia vedo quanti livelli ci sono sopra
|
|
1731
|
+
if (!parentsCache[th.th]) {
|
|
1732
|
+
leafs.push(th);
|
|
1733
|
+
let tmp = this.jumpsToFinalParent(th, thsCache);
|
|
1734
|
+
hMaxLevel = tmp > hMaxLevel ? tmp : hMaxLevel;
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
return { leafs: leafs, groupingLevel: hMaxLevel, parentsCache: parentsCache, thsCache: thsCache };
|
|
1738
|
+
}
|
|
1739
|
+
/**
|
|
1740
|
+
* Genera gli header groups da una lista di info sui th all'interno della variabile **TMPRowThGroups**
|
|
1741
|
+
*/
|
|
1742
|
+
evaluateHeaderGroups(infos) {
|
|
1743
|
+
if (infos.groupingLevel == 0)
|
|
1744
|
+
return;
|
|
1745
|
+
// Giro 2.5, creo l'output dei raggruppamenti per header in modo da non dovermi preoccupare di celle non inizializzate
|
|
1746
|
+
let expandedGroups = [];
|
|
1747
|
+
let visibleUnpinnedLeafs = infos.leafs.filter((t) => t.thVisible && !t.thPinned);
|
|
1748
|
+
for (let l = 0; l < infos.groupingLevel; l++) {
|
|
1749
|
+
expandedGroups.push([]);
|
|
1750
|
+
for (let i = 0; i < visibleUnpinnedLeafs.length; i++)
|
|
1751
|
+
expandedGroups[l].push("");
|
|
1752
|
+
}
|
|
1753
|
+
// Ordino le foglie in base agli ordinamenti delle colonne
|
|
1754
|
+
let orderedLeafs = [];
|
|
1755
|
+
for (let i = 0; i < this.OrderDirectives.length; i++) {
|
|
1756
|
+
let leaf = infos.thsCache[this.OrderDirectives[i]];
|
|
1757
|
+
if (leaf.thVisible && !leaf.thPinned)
|
|
1758
|
+
orderedLeafs.push(leaf);
|
|
1759
|
+
}
|
|
1760
|
+
// Terzo giro per creare l'array group con tutti i riferimenti del caso
|
|
1761
|
+
let currentParent = "";
|
|
1762
|
+
for (let i = 0; i < orderedLeafs.length; i++) {
|
|
1763
|
+
let refTh = orderedLeafs[i];
|
|
1764
|
+
let prevTh = i - 1 >= 0 ? orderedLeafs[i - 1] : null;
|
|
1765
|
+
// Parent diverso da prima, metto il bordo a sinistra e a destra della cella precedente (se c'è)
|
|
1766
|
+
// All'ultimo giro metto il bordo a destra. Tutto questo lo rieseguo per ogni cella in modo da ripulire eventuali a cui avevo assegnato tag precedentemente
|
|
1767
|
+
refTh._lbord = refTh.thParent != currentParent;
|
|
1768
|
+
refTh._rbord = visibleUnpinnedLeafs.length == i + 1;
|
|
1769
|
+
if (prevTh)
|
|
1770
|
+
prevTh._rbord = refTh.thParent != currentParent;
|
|
1771
|
+
currentParent = refTh.thParent;
|
|
1772
|
+
// Per ogni gruppo srotolo il parent nella matrice dei raggruppamenti
|
|
1773
|
+
for (let l = 0; l < infos.groupingLevel; l++) {
|
|
1774
|
+
let parent = refTh.thParent;
|
|
1775
|
+
if (parent && !refTh.thPinned) {
|
|
1776
|
+
expandedGroups[l][i] = parent;
|
|
1777
|
+
refTh = infos.thsCache[parent];
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
// Quarto giro per compattarlo nell'elemento finale su cui bindarmi
|
|
1782
|
+
currentParent = "";
|
|
1783
|
+
let currentSpan = 0;
|
|
1784
|
+
this.TMPRowThGroups = [];
|
|
1785
|
+
for (let l = 0; l < expandedGroups.length; l++) {
|
|
1786
|
+
let levelArray = [];
|
|
1787
|
+
this.TMPRowThGroups.push(levelArray);
|
|
1788
|
+
if (this.Selection || this.HasPinnedColumns)
|
|
1789
|
+
levelArray.push({ Span: 1, Template: null, Pinned: this.HasPinnedColumns });
|
|
1790
|
+
for (let h = 0; h < expandedGroups[l].length; h++) {
|
|
1791
|
+
let item = expandedGroups[l][h];
|
|
1792
|
+
if (item == currentParent)
|
|
1793
|
+
currentSpan++;
|
|
1794
|
+
else {
|
|
1795
|
+
if (currentSpan > 0)
|
|
1796
|
+
levelArray.push({ Span: currentSpan, Template: (currentParent ? infos.thsCache[currentParent].Template : null), Borders: !!currentParent });
|
|
1797
|
+
currentSpan = 1;
|
|
1798
|
+
currentParent = item;
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
// Ultima aggiunta che altrimenti mi rimarrebbe in cache
|
|
1802
|
+
levelArray.push({ Span: currentSpan, Template: (currentParent ? infos.thsCache[currentParent].Template : null), Borders: !!currentParent });
|
|
1803
|
+
if (this.Removal)
|
|
1804
|
+
levelArray.push({ Span: 1, Template: null });
|
|
1805
|
+
if (this.Export || this.HiddenColumns || this.ColumnsOrdering || this.CornerMenuOptions)
|
|
1806
|
+
levelArray.push({ Span: 1, Template: null });
|
|
1807
|
+
currentSpan = 0;
|
|
1808
|
+
currentParent = "";
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
/**
|
|
1812
|
+
* Calcola il numero di salti da un header foglia all'ultimo parent della catena
|
|
1813
|
+
*/
|
|
1814
|
+
jumpsToFinalParent(th, thsCache) {
|
|
1815
|
+
let jumps = 0;
|
|
1816
|
+
let parent = null;
|
|
1817
|
+
do {
|
|
1818
|
+
parent = th.thParent;
|
|
1819
|
+
if (parent)
|
|
1820
|
+
jumps++;
|
|
1821
|
+
th = thsCache[parent];
|
|
1822
|
+
} while (parent);
|
|
1823
|
+
return jumps;
|
|
1824
|
+
}
|
|
1825
|
+
/**
|
|
1826
|
+
* Data una direttiva EsTh restituisce la lista delle aggregazioni richiesta per questa colonna o il gruppo che rappresenta
|
|
1827
|
+
*
|
|
1828
|
+
* @param {EsThDirective} th Direttiva
|
|
1829
|
+
*
|
|
1830
|
+
* @returns {GroupOrAggregation[]} Lista dei gruppi o aggregazioni relativi alla Direttiva passata
|
|
1831
|
+
*/
|
|
1832
|
+
getGroupAggregations(th) {
|
|
1833
|
+
let ret = [];
|
|
1834
|
+
// Es: '{min:dd/MM/yyyy} - {max:dd/MM/yyyy}'
|
|
1835
|
+
if (th.thAggregation) {
|
|
1836
|
+
this.getEsThDirectiveListOfAggregations(th).forEach((agg) => {
|
|
1837
|
+
let isdate = agg.format && ['small', 'long', 'verylong'].includes(agg.format);
|
|
1838
|
+
let isnumber = agg.format && agg.format.startsWith("F") && !Number.isNaN(agg.format.charAt(1)) && agg.format.length == 2;
|
|
1839
|
+
if (!isdate && !isnumber && agg.format)
|
|
1840
|
+
throw "Le aggergazioni supportate dall'es-table sono solo 'small', 'long', 'verylong' per le date e 'F0-9' per i numeri";
|
|
1841
|
+
ret.push(new GroupOrAggregation(th.th, agg.func, isdate ? 'date' : isnumber ? 'number' : 'string'));
|
|
1842
|
+
});
|
|
1012
1843
|
}
|
|
1844
|
+
else if (th.thGroup)
|
|
1845
|
+
ret.push(new GroupOrAggregation(th.th, null));
|
|
1846
|
+
return ret;
|
|
1847
|
+
}
|
|
1848
|
+
/**
|
|
1849
|
+
* Data una direttiva con un formato restituisce tutte le coppie Funzione di Aggregazione - Formato
|
|
1850
|
+
*
|
|
1851
|
+
* @param {EsThDirective} th Direttiva EsTh di cui calcolare le funzioni di aggregazione usate
|
|
1852
|
+
*
|
|
1853
|
+
* @returns {{ func: string, format: string }[]} Lista delle funzioni di aggregazione rilevate
|
|
1854
|
+
*/
|
|
1855
|
+
getEsThDirectiveListOfAggregations(th) {
|
|
1856
|
+
if (!th.thAggregation)
|
|
1857
|
+
return [];
|
|
1858
|
+
// Se ho già effettuato questo calcolo per questo th restituisco la versione in cache
|
|
1859
|
+
if (th._thAggregations)
|
|
1860
|
+
return th._thAggregations;
|
|
1861
|
+
let ret = [];
|
|
1862
|
+
let display = th.thAggregation;
|
|
1863
|
+
var matches = display.match(/{[a-zA-Z0-9\/:]*}/gi);
|
|
1864
|
+
if (!matches)
|
|
1865
|
+
return [];
|
|
1866
|
+
matches.forEach(m => {
|
|
1867
|
+
let split = m.split(":");
|
|
1868
|
+
let func = m, format = "";
|
|
1869
|
+
if (split.length > 0) {
|
|
1870
|
+
// Escludo primo e ultimo carattere (le graffe)
|
|
1871
|
+
func = split[0].substr(1);
|
|
1872
|
+
format = split[1].substr(0, split[1].length - 1);
|
|
1873
|
+
}
|
|
1874
|
+
ret.push({ func: func, format: format, match: m });
|
|
1875
|
+
});
|
|
1876
|
+
th._thAggregations = ret;
|
|
1877
|
+
return ret;
|
|
1013
1878
|
}
|
|
1014
1879
|
/**
|
|
1015
1880
|
* Metodo che genera l'ordine di default delle colonne
|
|
1016
1881
|
*
|
|
1017
1882
|
* @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
|
|
1018
1883
|
*/
|
|
1019
|
-
generateDefaultOrder(view) {
|
|
1020
|
-
if (
|
|
1884
|
+
generateDefaultOrder(ths, view) {
|
|
1885
|
+
if (ths.length == 0)
|
|
1021
1886
|
return;
|
|
1887
|
+
let orderings = this.viewMode ? view.column_ordering : this.arrayColumnOrdering;
|
|
1022
1888
|
// Genero ordinamento di default da 0 fino a dove deve arrivare. Situazione attuale senza hotpotato
|
|
1023
|
-
if (!
|
|
1024
|
-
for (let i = 0; i <
|
|
1025
|
-
|
|
1889
|
+
if (!orderings || orderings.length == 0) {
|
|
1890
|
+
for (let i = 0; i < ths.length; i++) {
|
|
1891
|
+
let th = ths[i];
|
|
1892
|
+
let order = this.isEsTh(th) ? th.ID : th.th;
|
|
1893
|
+
this.OrderDirectives.push(order);
|
|
1894
|
+
}
|
|
1026
1895
|
}
|
|
1027
1896
|
else
|
|
1028
|
-
this.OrderDirectives =
|
|
1897
|
+
this.OrderDirectives = orderings;
|
|
1029
1898
|
}
|
|
1030
1899
|
/**
|
|
1031
1900
|
* Applica l'ordine specificato alle varie colonne
|
|
@@ -1034,7 +1903,7 @@ export class EsTableComponent {
|
|
|
1034
1903
|
* @param {boolean} finalize Se **true** significa che non mi aspetto di dover effettuare altre operazioni e posso renderizzare la situazione in base ai RowContext
|
|
1035
1904
|
* Senza finalize significa che mi aspetto altre operazioni che prima o poi richiameranno questa funzione col finalize.
|
|
1036
1905
|
*
|
|
1037
|
-
* Ad esempio, una volta selezionato ordinamento fisico/logico delle colonne so che parte un altra ricerca che mi
|
|
1906
|
+
* Ad esempio, una volta selezionato ordinamento fisico/logico delle colonne so che parte un altra ricerca che mi rivalorizzerà da "writeValue", che già chiama questa funzione.
|
|
1038
1907
|
* Mettendo solo la chiamata da "writeValue" come "finalizzante" mi assicuro che smanattamenti a frontend non causino flickering fino a quando non servono
|
|
1039
1908
|
*/
|
|
1040
1909
|
applyOrdering(view, finalize) {
|
|
@@ -1058,10 +1927,188 @@ export class EsTableComponent {
|
|
|
1058
1927
|
this.TMPRowTDs[this.RowContexts[i]] = newContext;
|
|
1059
1928
|
}
|
|
1060
1929
|
}
|
|
1061
|
-
|
|
1930
|
+
if (this.viewMode)
|
|
1931
|
+
view.column_ordering = this.OrderDirectives;
|
|
1932
|
+
else
|
|
1933
|
+
this.arrayColumnOrdering = this.OrderDirectives;
|
|
1062
1934
|
this.changed();
|
|
1063
1935
|
}
|
|
1064
1936
|
// #endregion
|
|
1937
|
+
// #region Gestione raggruppamenti per riga
|
|
1938
|
+
/**
|
|
1939
|
+
* Ottiene un elemento di separazione fra Gruppi che serve per paginare le ricerche all'interno di ogni singolo gruppo
|
|
1940
|
+
*
|
|
1941
|
+
* @param {AppSearch<any>} view View utilizzata per la ricerca. Me ne salvo i parametri nel separatore attuale dato che ne ho bisogno per caricare altri elementi
|
|
1942
|
+
* facenti riferimento allo stesso contesto
|
|
1943
|
+
* @param {string} parent Parent path che rappresenta a quale gruppo è affibbiato questo separatore
|
|
1944
|
+
* @param {GroupRouteFragment[]} route Route path che rappresenta a quale gruppo è affibbiato questo separatore
|
|
1945
|
+
* @param {number} level Livello del gruppo di cui questo elemento è separatore, viene usato per applicare la classe "est-lvl-{{level}}"
|
|
1946
|
+
*
|
|
1947
|
+
* @returns {any} Elemento di separazione contenente tutti i bind per presentare una paginazione sotto questo gruppo lato interfaccia
|
|
1948
|
+
*/
|
|
1949
|
+
getGroupSeparator(view, parent, route, level, searches) {
|
|
1950
|
+
let item = new GroupPager(level, route, parent, Object.assign({}, view), searches);
|
|
1951
|
+
item.buttons = this.getPagesArray(6, view.page, view.pages);
|
|
1952
|
+
this.calculateHash([item]);
|
|
1953
|
+
return item;
|
|
1954
|
+
}
|
|
1955
|
+
/**
|
|
1956
|
+
* Sposta la ricerca di una pagina in avanti (o indietro)
|
|
1957
|
+
*
|
|
1958
|
+
* @param {number} page Numero di pagine da aggiungere (o sottrarre, se negativo) alla pagina attuale
|
|
1959
|
+
* @param {any} pager Elemento di separazione su cui è effettuata la ricerca
|
|
1960
|
+
*/
|
|
1961
|
+
addToPageGroup(page, pager) {
|
|
1962
|
+
this.goToPageGroup(pager.view.page + page, pager);
|
|
1963
|
+
}
|
|
1964
|
+
/**
|
|
1965
|
+
* Sposta la ricerca alla pagina specificata
|
|
1966
|
+
*
|
|
1967
|
+
* @param {number} page Pagina a cui navigare
|
|
1968
|
+
* @param {any} pager Elemento di separazione su cui è effettuata la ricerca
|
|
1969
|
+
*/
|
|
1970
|
+
goToPageGroup(page, pager) {
|
|
1971
|
+
let appSearchElement = pager.view;
|
|
1972
|
+
if (page === 0 || page > appSearchElement.pages)
|
|
1973
|
+
return;
|
|
1974
|
+
appSearchElement.page = page;
|
|
1975
|
+
pager.buttons = this.getPagesArray(6, appSearchElement.page, appSearchElement.pages);
|
|
1976
|
+
this.emitSearchRequest(false, appSearchElement);
|
|
1977
|
+
}
|
|
1978
|
+
/**
|
|
1979
|
+
* Data una colonna effettua la riemissione di tutte le ricerche relative.
|
|
1980
|
+
*
|
|
1981
|
+
* Es. Ho 2 campi di gruppo e ho espanso fino a vedere i valori fino ad un livello qualsiasi.
|
|
1982
|
+
* Clicco l'ordinamento sul secondo gruppo.
|
|
1983
|
+
* Tutte le ricerche relative ai primi gruppi devono essere rieseguite. Quando i risultati arriveranno ci penserà il metodo **bindDisplayToLoadedItemsOrGroups**
|
|
1984
|
+
* a tagliare via gli oggetti non più visualizzati
|
|
1985
|
+
*
|
|
1986
|
+
* @param {string} column Colonna su cui si è effettuata un'operazione di ordinamento
|
|
1987
|
+
* @param {AppOrdering[]} orderings Direttive di ordinamento da applicare alle varie sottoricerche
|
|
1988
|
+
*
|
|
1989
|
+
* @todo: Testare
|
|
1990
|
+
*/
|
|
1991
|
+
emitRowGroupingSearches(column, orderings) {
|
|
1992
|
+
// Per tutte le ricerche intermedie che devo rivalutare le re-emitto in modo da aggiornargli i dati
|
|
1993
|
+
var meaningfulAppSearches = this.groupSearchRequestsCache.filter(t => t.group_column == column).map(t => t.view);
|
|
1994
|
+
// Se non ne trovo significa che ho fatto l'ordinamento o sugli item, o su colonne relative a un sottogruppo non caricato
|
|
1995
|
+
if (!meaningfulAppSearches || meaningfulAppSearches.length == 0)
|
|
1996
|
+
meaningfulAppSearches = this.groupSearchRequestsCache.filter(t => !t.group_column).map(t => t.view);
|
|
1997
|
+
// Se non ne trovo qui significa che sto ordinando su colonne relative a un sottogruppo non caricato
|
|
1998
|
+
if (!meaningfulAppSearches || meaningfulAppSearches.length == 0)
|
|
1999
|
+
return;
|
|
2000
|
+
meaningfulAppSearches.forEach(as => {
|
|
2001
|
+
// Ovviamente gli oridnamenti devono essere quelli appena generati
|
|
2002
|
+
as.orders = orderings;
|
|
2003
|
+
as.savedstate = true;
|
|
2004
|
+
this.emitSearchRequest(false, as);
|
|
2005
|
+
});
|
|
2006
|
+
}
|
|
2007
|
+
/**
|
|
2008
|
+
* Helper che calcola il contenuto di una cella relativa a un gruppo riga, tenendo conto del formato delle eventuali aggregazioni
|
|
2009
|
+
*
|
|
2010
|
+
* @param {Group} grp Gruppo di cui mostrare le celle
|
|
2011
|
+
* @param {string} cell Cella attuale di cui calcolare il testo
|
|
2012
|
+
* @param {EsThDirective} header Header relativo alla cella attuale, utilizzata per identificare le informazioni di aggregazione
|
|
2013
|
+
*
|
|
2014
|
+
* @returns {string} Testo finale calcolato per la **cell** corrente, in base alle aggregazioni di **header**
|
|
2015
|
+
*/
|
|
2016
|
+
getGroupCellDisplay(grp, cell, header) {
|
|
2017
|
+
if (grp._sep)
|
|
2018
|
+
return "";
|
|
2019
|
+
let display = header.thAggregation;
|
|
2020
|
+
if (grp.column == cell) {
|
|
2021
|
+
let groupsPart = grp._groupscount ? " - " + grp._groupscount + " " + this.lc.loc("Groups") : "";
|
|
2022
|
+
return grp.value + " (" + grp.count + groupsPart + ")";
|
|
2023
|
+
}
|
|
2024
|
+
else {
|
|
2025
|
+
let agg = grp._aggregationsCache.get(cell);
|
|
2026
|
+
if (!agg)
|
|
2027
|
+
return "";
|
|
2028
|
+
this.getEsThDirectiveListOfAggregations(header).forEach((itm) => {
|
|
2029
|
+
display = display.replace(itm.match, this.formatAggregationValue(agg.get(itm.func), itm.format));
|
|
2030
|
+
});
|
|
2031
|
+
return display;
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
/**
|
|
2035
|
+
* Gestisce i click sulla tabella solo per le righe a gruppo.
|
|
2036
|
+
* O rimuove gli elementi attualmente presenti o carica il contenuto del gruppo
|
|
2037
|
+
*
|
|
2038
|
+
* @param {any} group Gruppo bindato su cui si è effettuato il click
|
|
2039
|
+
*
|
|
2040
|
+
* @returns {boolean} **true** se l'operaizone è andata a buon fine, **false** altrimenti
|
|
2041
|
+
*/
|
|
2042
|
+
handleGroupClick(group) {
|
|
2043
|
+
let casted = this.View;
|
|
2044
|
+
let anyG = group;
|
|
2045
|
+
anyG._expanded = !anyG._expanded;
|
|
2046
|
+
// Sono in modalità raggruppamento virtuale da array: Espandere significa rendere visibili tutti gli oggetti relativi a questo gruppo, viceversa il contrarre
|
|
2047
|
+
if (this.ArrayGrouping) {
|
|
2048
|
+
let allRelatives = this.boundSource.filter(t => (t._group && ((anyG._expanded && t._parent == anyG._thisKey) || (!anyG._expanded && t._parent && t._parent.startsWith(anyG._thisKey)))) ||
|
|
2049
|
+
(t._item && ((anyG._expanded && t._thisKey == anyG._thisKey) || (!anyG._expanded && t._thisKey.startsWith(anyG._thisKey)))));
|
|
2050
|
+
allRelatives.forEach(t => { t._visible = anyG._expanded; if (t._group)
|
|
2051
|
+
t._expanded = false; });
|
|
2052
|
+
return;
|
|
2053
|
+
}
|
|
2054
|
+
if (anyG._expanded) {
|
|
2055
|
+
// Resetto ipp
|
|
2056
|
+
casted.itemsperpageoverride = 15;
|
|
2057
|
+
if (!casted.requestedgroups)
|
|
2058
|
+
casted.requestedgroups = [new GroupFilter(group.column, group.value)];
|
|
2059
|
+
else {
|
|
2060
|
+
let level = anyG._grouplevel;
|
|
2061
|
+
// se il gruppo cliccato non ha un livello è il primo gruppo, quindi ordinamento unico
|
|
2062
|
+
// altrimenti devo rimuovere tutti i filtri su livelli superiori al level cliccato e aggiungere il level cliccato
|
|
2063
|
+
if (!level)
|
|
2064
|
+
casted.requestedgroups = [new GroupFilter(group.column, group.value)];
|
|
2065
|
+
else {
|
|
2066
|
+
casted.requestedgroups = [];
|
|
2067
|
+
anyG._parentRoute.forEach((step) => {
|
|
2068
|
+
casted.requestedgroups.push(new GroupFilter(step.column, step.value));
|
|
2069
|
+
});
|
|
2070
|
+
casted.requestedgroups.push(new GroupFilter(group.column, group.value));
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
this.changed();
|
|
2074
|
+
this.emitSearchRequest(true);
|
|
2075
|
+
}
|
|
2076
|
+
else {
|
|
2077
|
+
let path = (anyG._parent || '') + group.value;
|
|
2078
|
+
// Se ho chiuso un gruppo non mi serve rieffettuare ricerce, mi basta eliminare dagli oggetti bindati tutti gli elementi sottostanti a quel gruppo
|
|
2079
|
+
this.boundSource = this.boundSource.filter(t => !t._parent || !t._parent.startsWith(path));
|
|
2080
|
+
// devo però anche rimuovere eventuali cache relative
|
|
2081
|
+
this.groupSearchRequestsCache = this.groupSearchRequestsCache.filter(t => t.path != path);
|
|
2082
|
+
}
|
|
2083
|
+
return true;
|
|
2084
|
+
}
|
|
2085
|
+
/**
|
|
2086
|
+
* Funzione che dato un valore lo formatta in base al tipo
|
|
2087
|
+
*
|
|
2088
|
+
* @param {string} value Valore che generalemnte può essere una data o un numero
|
|
2089
|
+
* @param {string} fromat Formato su cui formattare il valore. Può essere ad esempio "small", "long" "verylong" per le date o F{0-9} per i numeri decimali
|
|
2090
|
+
*
|
|
2091
|
+
* @returns {string} Valore dell'aggregazione formattato come si deve
|
|
2092
|
+
*/
|
|
2093
|
+
formatAggregationValue(value, format) {
|
|
2094
|
+
if (!format)
|
|
2095
|
+
return value;
|
|
2096
|
+
let isNumber = !Number.isNaN(value) && (!format || format.startsWith("F"));
|
|
2097
|
+
if (isNumber && format.startsWith("F") && !Number.isNaN(format.substr(1)))
|
|
2098
|
+
return parseFloat(value).toFixed(parseInt(format.substr(1)));
|
|
2099
|
+
let date = null;
|
|
2100
|
+
// Alcune versione di extensions rischiano di crashare con cose non date... è stato risolto dopo quindi questo try - catch in realtà
|
|
2101
|
+
// torna utile solo con versioni vecchie/deprecate della libreria @esfaenza/extensions
|
|
2102
|
+
try {
|
|
2103
|
+
date = this.dateExts.getDateConvertion(value);
|
|
2104
|
+
}
|
|
2105
|
+
catch (_a) { }
|
|
2106
|
+
if (date)
|
|
2107
|
+
return this.dateExts.getFormatted(date, format == 'small', format == 'verylong');
|
|
2108
|
+
// Qui ci finisco sia per input che non sono né date né numeri, sia per formati non riconosciuti
|
|
2109
|
+
return value;
|
|
2110
|
+
}
|
|
2111
|
+
// #endregion
|
|
1065
2112
|
// #region Gestione Operaizoni dialog ordinamento/visibilità colonne
|
|
1066
2113
|
/**
|
|
1067
2114
|
* All'interno della dialog "Ordinamento e Visibilità Colonne" mette la colonna specificata prima della colonna precedente
|
|
@@ -1070,7 +2117,7 @@ export class EsTableComponent {
|
|
|
1070
2117
|
*/
|
|
1071
2118
|
sendUp(columnItem) {
|
|
1072
2119
|
let itemIndex = this.TMPColumnsList.indexOf(columnItem);
|
|
1073
|
-
if (this.TMPColumnsList[itemIndex - 1].fixed)
|
|
2120
|
+
if (this.TMPColumnsList[itemIndex - 1].fixed || this.TMPColumnsList[itemIndex - 1].pinned)
|
|
1074
2121
|
return;
|
|
1075
2122
|
this.utiExts.swap(this.TMPColumnsList, itemIndex, itemIndex - 1);
|
|
1076
2123
|
// Non posso fare JSON.parse(JSON.stringify(this.ColumnsList)) perché contiene riferimenti a TemplateRef
|
|
@@ -1091,6 +2138,25 @@ export class EsTableComponent {
|
|
|
1091
2138
|
this.TMPColumnsList.forEach(c => { tmp.push(Object.assign({}, c)); });
|
|
1092
2139
|
this.TMPColumnsList = tmp;
|
|
1093
2140
|
}
|
|
2141
|
+
/**
|
|
2142
|
+
* All'interno della dialog "Ordinamento e Visibilità Colonne" pinna la colonna specificata
|
|
2143
|
+
*
|
|
2144
|
+
* @param {EsTableColumn} columnItem Colonna da spostare
|
|
2145
|
+
*/
|
|
2146
|
+
pinOrUnpinColumn(columnItem) {
|
|
2147
|
+
let itemIndex = this.TMPColumnsList.indexOf(columnItem);
|
|
2148
|
+
// Sposto la colonna alla fine di tutte quelle pinnate. La cosa funziona in entrambi sensi:
|
|
2149
|
+
// 1) Se sto pinnando, devo metterla come ultima pinnata
|
|
2150
|
+
// 2) Se sto spinnando devo metterla come prima non pinnata
|
|
2151
|
+
// Coincidenza vuole che il punto 1 e 2 siano equivalenti
|
|
2152
|
+
for (let i = 0; i < this.TMPColumnsList.length; i++) {
|
|
2153
|
+
if (!this.TMPColumnsList[i].pinned) {
|
|
2154
|
+
this.arrayMove(this.TMPColumnsList, itemIndex, i);
|
|
2155
|
+
break;
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
columnItem.pinned = !columnItem.pinned;
|
|
2159
|
+
}
|
|
1094
2160
|
/**
|
|
1095
2161
|
* All'interno della dialog "Ordinamento e Visibilità Colonne" inverte le impostazioni di visibilità della colonna
|
|
1096
2162
|
*
|
|
@@ -1149,12 +2215,12 @@ export class EsTableComponent {
|
|
|
1149
2215
|
// Non permetto di non selezionare nulla
|
|
1150
2216
|
if (this.TMPColumnsList.every(t => !t.visible))
|
|
1151
2217
|
return false;
|
|
1152
|
-
let castedView = this.View;
|
|
2218
|
+
let castedView = this.viewMode ? this.View : null;
|
|
1153
2219
|
this.ColumnsList = [];
|
|
1154
2220
|
this.TMPColumnsList.forEach(c => { this.ColumnsList.push(Object.assign({}, c)); });
|
|
1155
2221
|
this.refreshColumnOrdering();
|
|
1156
|
-
this.refreshColumnsVisibility(null, null, castedView);
|
|
1157
2222
|
this.applyOrdering(castedView, false);
|
|
2223
|
+
this.refreshColumnsVisibility(null, null, castedView);
|
|
1158
2224
|
//Salvo le preferences di questa view
|
|
1159
2225
|
//Di default registro ordinamento e visibilità delle colonne nella vista. Solo le cose di UI
|
|
1160
2226
|
if (this.SavePreferences) {
|
|
@@ -1166,11 +2232,17 @@ export class EsTableComponent {
|
|
|
1166
2232
|
console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
|
|
1167
2233
|
return false;
|
|
1168
2234
|
}
|
|
1169
|
-
|
|
2235
|
+
let columns = this.arrayMode ? this.arrayColumns : castedView.columns;
|
|
2236
|
+
let columnsOrderings = this.arrayMode ? this.arrayColumnOrdering : castedView.column_ordering;
|
|
2237
|
+
var toStore = { columns: JSON.parse(JSON.stringify(columns)), column_ordering: JSON.parse(JSON.stringify(columnsOrderings)) };
|
|
1170
2238
|
this.prefService.store(this.ngControl.name, toStore);
|
|
1171
2239
|
}
|
|
2240
|
+
// Rieseguo l'ultima ricerca bindata alla tabella
|
|
1172
2241
|
// Mi assicuro di farlo dopo l'espansione del changed o rischio che la ricerca mi ridia colonne che in realtà non esistono
|
|
1173
|
-
|
|
2242
|
+
if (this.viewMode)
|
|
2243
|
+
setTimeout(() => { this.emitSearchRequest(false); });
|
|
2244
|
+
else if (this.arrayMode)
|
|
2245
|
+
setTimeout(() => { this.internalWriteValue(); });
|
|
1174
2246
|
// Lo vorrei mettere lato template ma no
|
|
1175
2247
|
this.lastSelectedItemID = null;
|
|
1176
2248
|
return true;
|
|
@@ -1179,7 +2251,8 @@ export class EsTableComponent {
|
|
|
1179
2251
|
* Sul click nella checkbox di selezione globale si scorrono tutte le colonne e si impostano al valore della check globale
|
|
1180
2252
|
*/
|
|
1181
2253
|
globalColVisCheckChanged() {
|
|
1182
|
-
this.TMPColumnsList.forEach(t => { t.
|
|
2254
|
+
this.TMPColumnsList.forEach(t => { if (!t.fixed)
|
|
2255
|
+
t.visible = this.globalColVisCheck; });
|
|
1183
2256
|
}
|
|
1184
2257
|
// #endregion
|
|
1185
2258
|
// #region Gestione data source gerarchici
|
|
@@ -1227,9 +2300,9 @@ export class EsTableComponent {
|
|
|
1227
2300
|
let obj = objs[i];
|
|
1228
2301
|
// Se la parentKey non è valorizzata, questo è il livello 0 (1... perché gli 0 son perciolosi)
|
|
1229
2302
|
if (!obj[this.ParentKey] && levelToAssign == 1) {
|
|
1230
|
-
obj.
|
|
1231
|
-
obj.
|
|
1232
|
-
obj.
|
|
2303
|
+
obj._level = 1;
|
|
2304
|
+
obj._visible = true;
|
|
2305
|
+
obj._expanded = this.StartsExpanded;
|
|
1233
2306
|
assigned++;
|
|
1234
2307
|
continue;
|
|
1235
2308
|
}
|
|
@@ -1239,13 +2312,13 @@ export class EsTableComponent {
|
|
|
1239
2312
|
for (let p = 0; p < objs.length; p++) {
|
|
1240
2313
|
let possibleParent = objs[p];
|
|
1241
2314
|
// Trovato il parent dell'item, assegno all'item il livello giusto
|
|
1242
|
-
if (possibleParent[this.OwnKey] == obj[this.ParentKey] && possibleParent.
|
|
1243
|
-
obj.
|
|
2315
|
+
if (possibleParent[this.OwnKey] == obj[this.ParentKey] && possibleParent._level == levelToAssign - 1) {
|
|
2316
|
+
obj._level = levelToAssign;
|
|
1244
2317
|
// So che questo item ha un parent. Ribadisco che il parent è espanso in base alle impostazione e stessa logica
|
|
1245
2318
|
// per la visibilità del figlio
|
|
1246
|
-
possibleParent.
|
|
2319
|
+
possibleParent._expanded = this.StartsExpanded;
|
|
1247
2320
|
possibleParent.parent = true;
|
|
1248
|
-
obj.
|
|
2321
|
+
obj._visible = this.StartsExpanded;
|
|
1249
2322
|
assigned++;
|
|
1250
2323
|
break;
|
|
1251
2324
|
}
|
|
@@ -1264,12 +2337,12 @@ export class EsTableComponent {
|
|
|
1264
2337
|
let obj = this.boundSource[i];
|
|
1265
2338
|
// Trovo il parent con quell'id e lo espando
|
|
1266
2339
|
if (obj[this.OwnKey] == key) {
|
|
1267
|
-
obj.
|
|
2340
|
+
obj._expanded = true;
|
|
1268
2341
|
for (let ic = 0; ic < this.boundSource.length; ic++) {
|
|
1269
2342
|
let child = this.boundSource[ic];
|
|
1270
2343
|
// Trovo tutti i child di quel parent e li rendo visibili
|
|
1271
2344
|
if (child[this.ParentKey] == key)
|
|
1272
|
-
child.
|
|
2345
|
+
child._visible = true;
|
|
1273
2346
|
}
|
|
1274
2347
|
return;
|
|
1275
2348
|
}
|
|
@@ -1285,7 +2358,7 @@ export class EsTableComponent {
|
|
|
1285
2358
|
let obj = this.boundSource[i];
|
|
1286
2359
|
// Trovo il parent con quell'id e lo collasso
|
|
1287
2360
|
if (obj[this.OwnKey] == key) {
|
|
1288
|
-
obj.
|
|
2361
|
+
obj._expanded = false;
|
|
1289
2362
|
// Collasso/nascondo tutti i child del parent
|
|
1290
2363
|
this.collapseChildOfParent(key);
|
|
1291
2364
|
return;
|
|
@@ -1303,23 +2376,123 @@ export class EsTableComponent {
|
|
|
1303
2376
|
// Trovo tutti i child di quel parent e li rendo invisibili. Se il child trovato è a sua volta un parent,
|
|
1304
2377
|
// lo collasso e vado in ricorsione sui figli
|
|
1305
2378
|
if (child[this.ParentKey] == parentKey && !child.parent)
|
|
1306
|
-
child.
|
|
2379
|
+
child._visible = false;
|
|
1307
2380
|
else if (child[this.ParentKey] == parentKey && child.parent) {
|
|
1308
|
-
child.
|
|
1309
|
-
child.
|
|
2381
|
+
child._expanded = false;
|
|
2382
|
+
child._visible = false;
|
|
1310
2383
|
this.collapseChildOfParent(child[this.OwnKey]);
|
|
1311
2384
|
}
|
|
1312
2385
|
}
|
|
1313
2386
|
}
|
|
1314
2387
|
// #endregion
|
|
1315
2388
|
// #region Gestione Selezione
|
|
2389
|
+
/**
|
|
2390
|
+
* Valuta quali elementi devono essere marcati come selezionati nella vista attuale. Si basa sull'oggetto **selection** interno all'AppSearch
|
|
2391
|
+
*
|
|
2392
|
+
* @param {any[]} items Oggetti di cui valutare la selezione
|
|
2393
|
+
* @param {ItemsSelection<any>} selectionItem Oggetti di selezione derivante dalla view o dall'oggetto per Array
|
|
2394
|
+
*/
|
|
2395
|
+
evaluateSelection(items, selectionItem) {
|
|
2396
|
+
if (!selectionItem)
|
|
2397
|
+
return;
|
|
2398
|
+
this.handleSelectionEvaluation(items, selectionItem);
|
|
2399
|
+
}
|
|
2400
|
+
/**
|
|
2401
|
+
* Valuta quali elementi devono essere marcati come selezionati nella vista attuale. Si basa sull'oggetto **arraymodeSelection** dell'es-table
|
|
2402
|
+
*
|
|
2403
|
+
* @param {any[]} array Lista di oggetti di cui valutare la selezione in modalità array
|
|
2404
|
+
*/
|
|
2405
|
+
arrayModeEvaluateSelection(array) {
|
|
2406
|
+
if (array.length == 0)
|
|
2407
|
+
return;
|
|
2408
|
+
this.handleSelectionEvaluation(array, this.arraymodeSelection);
|
|
2409
|
+
}
|
|
2410
|
+
/**
|
|
2411
|
+
* Implementazione agnostica della valutazione delle selezioni degli oggetti. Richiede gli oggetti della vista attuale e l'itemSelector
|
|
2412
|
+
*
|
|
2413
|
+
* @param {any[]} items Oggetti di cui aggiornare lo stato di selezione
|
|
2414
|
+
* @param {ItemsSelection<any>} selectionItem Oggetto contenente lo stato attuale di selezione
|
|
2415
|
+
*/
|
|
2416
|
+
handleSelectionEvaluation(items, selectionItem) {
|
|
2417
|
+
for (let i = 0; i < items.length; i++) {
|
|
2418
|
+
let itm = items[i];
|
|
2419
|
+
let hash = itm._hash;
|
|
2420
|
+
let itemGroup = itm._group ? null : this.getItemGroup(itm);
|
|
2421
|
+
// Reidrato la cache di selezione coi nuovi oggetti altrimenti non riuscirei a beccare gli indici giusti
|
|
2422
|
+
// Dopodiché la uso per calcolare istantaneamente se gli oggetti sono selezionati o no
|
|
2423
|
+
this.rehidrateCache(itm);
|
|
2424
|
+
if (itm._item) {
|
|
2425
|
+
if (selectionItem.all)
|
|
2426
|
+
itm._selected = !this.exclusionsCache.has(hash) && ((!this.groupsCache.has(itemGroup === null || itemGroup === void 0 ? void 0 : itemGroup._hash) && this.itemsCache.has(hash)) || !this.group_exclusionsCache.has(itemGroup === null || itemGroup === void 0 ? void 0 : itemGroup._hash));
|
|
2427
|
+
else
|
|
2428
|
+
itm._selected = !this.exclusionsCache.has(hash) && (this.groupsCache.has(itemGroup === null || itemGroup === void 0 ? void 0 : itemGroup._hash) || this.itemsCache.has(hash) || (this.parentTreeStatus(itemGroup) == 'included' && !this.group_exclusionsCache.has(itemGroup === null || itemGroup === void 0 ? void 0 : itemGroup._hash)));
|
|
2429
|
+
}
|
|
2430
|
+
else if (itm._group) {
|
|
2431
|
+
if (selectionItem.all)
|
|
2432
|
+
itm._selected = !this.group_exclusionsCache.has(hash) && this.parentTreeStatus(itm) != 'excluded';
|
|
2433
|
+
else
|
|
2434
|
+
itm._selected = this.groupsCache.has(hash) || (this.parentTreeStatus(itm) == 'included' && !this.group_exclusionsCache.has(hash));
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
// Se tutti gli oggetti di questa pagina sono solezionati allora posso mettere il global check a true
|
|
2438
|
+
// Se sono in situazione di all-select anche metto la global checkbox, nonostante ci possano essere delle esclusioni
|
|
2439
|
+
this.globalCheck = this.boundSource.filter(t => t._group || t._item).every(t => t._selected);
|
|
2440
|
+
this.canSelectAll = selectionItem.count > 0 && this.SelectAll;
|
|
2441
|
+
// Potrebbe cambiare qualora qualcuno inserisse dati a manazza in modalità Array e desse il refresh manuale alla tabella
|
|
2442
|
+
// Comunque costa 0 quindi mi permetto di refreshare
|
|
2443
|
+
if (this.arrayMode) {
|
|
2444
|
+
let prevSelected = this.selectedObjects;
|
|
2445
|
+
this.finalizeSelectionInformations(selectionItem);
|
|
2446
|
+
if (this.selectedObjects != prevSelected)
|
|
2447
|
+
this.onSelectionChanged.emit(selectionItem);
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2450
|
+
/**
|
|
2451
|
+
* Dato un oggetto trova la cella di cache in cui è registrato e aggiorna il contenuto
|
|
2452
|
+
*
|
|
2453
|
+
* @param {any} item Oggetto da aggiornare
|
|
2454
|
+
*/
|
|
2455
|
+
rehidrateCache(item) {
|
|
2456
|
+
let ctx = item._hash;
|
|
2457
|
+
if (this.itemsCache.has(ctx))
|
|
2458
|
+
this.itemsCache.set(ctx, item);
|
|
2459
|
+
if (this.group_exclusionsCache.has(ctx))
|
|
2460
|
+
this.group_exclusionsCache.set(ctx, item);
|
|
2461
|
+
if (this.groupsCache.has(ctx))
|
|
2462
|
+
this.groupsCache.set(ctx, item);
|
|
2463
|
+
if (this.exclusionsCache.has(ctx))
|
|
2464
|
+
this.exclusionsCache.set(ctx, item);
|
|
2465
|
+
}
|
|
2466
|
+
/**
|
|
2467
|
+
* Dato un gruppo controlla ricorsivamente l'albero di cui fa parte se c'è stata una inclusione o esclusione diretta
|
|
2468
|
+
*
|
|
2469
|
+
* @param {any} grp Gruppo da controllare
|
|
2470
|
+
*
|
|
2471
|
+
* @returns {'none' | 'excluded' | 'included'}
|
|
2472
|
+
* 'none' se non ci sono informazioni su inclusioni o esclusioni
|
|
2473
|
+
* 'included' se il gruppo controllato è stato incluso in maniera esplicita dall'albero dei gruppi padri
|
|
2474
|
+
* 'excluded' se il gruppo controllato è stato escluso in maniera esplicita dall'albero dei gruppi padri
|
|
2475
|
+
*/
|
|
2476
|
+
parentTreeStatus(grp) {
|
|
2477
|
+
if (!grp)
|
|
2478
|
+
return 'none';
|
|
2479
|
+
let parentGroup = this.rgGroupCache.get(grp._parent);
|
|
2480
|
+
if (!parentGroup)
|
|
2481
|
+
return 'none';
|
|
2482
|
+
if (this.group_exclusionsCache.has(parentGroup._hash))
|
|
2483
|
+
return 'excluded';
|
|
2484
|
+
if (this.groupsCache.has(parentGroup._hash))
|
|
2485
|
+
return 'included';
|
|
2486
|
+
return this.parentTreeStatus(parentGroup);
|
|
2487
|
+
}
|
|
1316
2488
|
/**
|
|
1317
2489
|
* Gestisce la selezione globale degli oggetti, sia per pagina che a livello di **SelectAll**
|
|
1318
2490
|
*
|
|
1319
2491
|
* @param {boolean} forcedVal Valore forzato di check da assegnare agli oggetti
|
|
1320
2492
|
*/
|
|
1321
2493
|
globalCheckChanged(forcedVal = null) {
|
|
1322
|
-
|
|
2494
|
+
// Prendo tutti gli elementi presenti in questa vista. Se ho gruppi prendo solo i gruppi a livello 0, altrimenti prendo tutti gli oggetti per selezionarli
|
|
2495
|
+
let items = this.boundSource.find(t => t._group) ? this.boundSource.filter(t => t._group && !t._parent) : this.boundSource;
|
|
1323
2496
|
var itemSelection = this.handleItemsSelection(items, forcedVal, this.globalCheck);
|
|
1324
2497
|
this.changed();
|
|
1325
2498
|
this.onSelectionChanged.emit(itemSelection);
|
|
@@ -1336,14 +2509,14 @@ export class EsTableComponent {
|
|
|
1336
2509
|
* @returns {ItemsSelection<any>} Oggetto di selezione aggiornato con le informazioni sull'ultima operazione effettuata
|
|
1337
2510
|
*/
|
|
1338
2511
|
handleItemsSelection(items, forcedVal = null, globalCheck = null) {
|
|
1339
|
-
var _a, _b;
|
|
1340
|
-
let
|
|
2512
|
+
var _a, _b, _c;
|
|
2513
|
+
let si = ((_a = this.View) === null || _a === void 0 ? void 0 : _a.selection) || this.arraymodeSelection;
|
|
1341
2514
|
// Se sono in modalità di selezione singola e devo selezionare un'oggetto, per prima cosa devo deselezionare tutti gli altri
|
|
1342
|
-
if (this.SingleSelection && ((_b = items[0]) === null || _b === void 0 ? void 0 : _b._selected)) {
|
|
2515
|
+
if (this.SingleSelection && ((_b = items[0]) === null || _b === void 0 ? void 0 : _b._selected) && !((_c = items[0]) === null || _c === void 0 ? void 0 : _c._group)) {
|
|
1343
2516
|
if (items.length > 1 && forcedVal == null)
|
|
1344
2517
|
throw "Tentativo di selezionare o deselezionare più di un elemento con SingleSelection attivo";
|
|
1345
2518
|
if (items.length == 1 && forcedVal == null) {
|
|
1346
|
-
|
|
2519
|
+
si = this.handleItemsSelection(this.boundSource.filter(t => !t._group), false, null);
|
|
1347
2520
|
items[0]._selected = true;
|
|
1348
2521
|
}
|
|
1349
2522
|
}
|
|
@@ -1353,59 +2526,343 @@ export class EsTableComponent {
|
|
|
1353
2526
|
// Se dev'essere overridato il valore di check effettuo l'override o col valore forzato o col valore globale
|
|
1354
2527
|
if (toChange && !item.locked)
|
|
1355
2528
|
item._selected = forcedVal != null ? forcedVal : this.globalCheck;
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
2529
|
+
// 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
|
|
2530
|
+
if (!toChange && globalCheck != null)
|
|
2531
|
+
continue;
|
|
2532
|
+
let allSelection = si.all;
|
|
2533
|
+
let isGroup = item._group;
|
|
2534
|
+
let isSelection = item._selected;
|
|
2535
|
+
let itemGroup = null, allItems = null, selectedItems = null, unselectedItems = null, allGroups = null, selectedGroups = null, unselectedGroups = null, parentGroupSelected = null, parentGroupUnselected = null;
|
|
2536
|
+
if (isGroup) {
|
|
2537
|
+
let pts = this.parentTreeStatus(item);
|
|
2538
|
+
parentGroupSelected = pts == 'included';
|
|
2539
|
+
parentGroupUnselected = pts == 'excluded';
|
|
2540
|
+
allItems = this.getGroupItems(si, item, null, true);
|
|
2541
|
+
selectedItems = this.getGroupItems(si, item, 'selected', true, allItems);
|
|
2542
|
+
unselectedItems = this.getGroupItems(si, item, 'unselected', true, allItems);
|
|
2543
|
+
allGroups = this.getGroupChildGroups(si, item, null, true);
|
|
2544
|
+
selectedGroups = this.getGroupChildGroups(si, item, 'selected', true, allGroups);
|
|
2545
|
+
unselectedGroups = this.getGroupChildGroups(si, item, 'unselected', true, allGroups);
|
|
1369
2546
|
}
|
|
1370
2547
|
else {
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
// Oggetto selezionato: lo aggiungo alla selezione attuale
|
|
1375
|
-
this.selOrDeselCache[item.hash] = item;
|
|
1376
|
-
selectionItem.items.push(item);
|
|
1377
|
-
}
|
|
1378
|
-
else if (!item._selected && this.selOrDeselCache[item.hash]) {
|
|
1379
|
-
// Oggetto deselezionato: lo rimuovo dalla selezione attuale
|
|
1380
|
-
selectionItem.items.splice(selectionItem.items.indexOf(this.selOrDeselCache[item.hash]), 1);
|
|
1381
|
-
delete this.selOrDeselCache[item.hash];
|
|
1382
|
-
}
|
|
2548
|
+
itemGroup = this.getItemGroup(item);
|
|
2549
|
+
parentGroupSelected = itemGroup == null ? null : itemGroup._selected;
|
|
2550
|
+
parentGroupUnselected = itemGroup == null ? null : !itemGroup._selected;
|
|
1383
2551
|
}
|
|
2552
|
+
if (!this.ArrayGrouping)
|
|
2553
|
+
this.performSelectionOperations(si, item, allSelection, isGroup, isSelection, selectedItems, selectedGroups, unselectedItems, unselectedGroups, allItems, allGroups, parentGroupSelected, parentGroupUnselected);
|
|
2554
|
+
else
|
|
2555
|
+
this.performSimpleSelectionOperations(si, item, isGroup, isSelection, itemGroup, selectedItems, unselectedItems, allItems, allGroups);
|
|
1384
2556
|
}
|
|
1385
2557
|
// Imposto il check globale in base a se tutti gli elementi sono selezionati o meno.
|
|
1386
2558
|
// Evito di fare queste operazioni se la selezione deriva proprio dal global Check
|
|
1387
|
-
// Non è ottimizzatissimo mettere 2 some ma scrivere questo codice a for sono tipo 25 righe....
|
|
1388
2559
|
if (globalCheck == null)
|
|
1389
|
-
this.globalCheck = !
|
|
1390
|
-
this.finalizeSelectionInformations(
|
|
1391
|
-
return
|
|
2560
|
+
this.globalCheck = !this.boundSource.some(t => !t._selected && !t._sep);
|
|
2561
|
+
this.finalizeSelectionInformations(si);
|
|
2562
|
+
return si;
|
|
2563
|
+
}
|
|
2564
|
+
/**
|
|
2565
|
+
* Dato L'oggetto di selezione, l'oggetto da selezionare/deselezionare e tutti i parametri del caso effettua le operazioni che servono.
|
|
2566
|
+
*
|
|
2567
|
+
* Logica semplificata rispetto all'originale **performSelectionOperations** per lavorare in una modalità in cui tutti gli elementi sono caricati (**ArrayGrouping** = true)
|
|
2568
|
+
*/
|
|
2569
|
+
performSimpleSelectionOperations(base, item, group, sel, itm_group, sel_itm, desel_itm, all_itms, all_grps) {
|
|
2570
|
+
let tripticItem = this.getTriptic('item', base);
|
|
2571
|
+
if (group) {
|
|
2572
|
+
if (sel) {
|
|
2573
|
+
all_grps.forEach(gr => { gr._selected = true; });
|
|
2574
|
+
if (desel_itm)
|
|
2575
|
+
desel_itm.forEach(el => { el._selected = true; this.addItem(el, tripticItem); });
|
|
2576
|
+
}
|
|
2577
|
+
else {
|
|
2578
|
+
all_grps.forEach(gr => { gr._selected = false; });
|
|
2579
|
+
if (sel_itm)
|
|
2580
|
+
sel_itm.forEach(el => { el._selected = false; this.removeItem(el, tripticItem); });
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2583
|
+
else {
|
|
2584
|
+
if (sel) {
|
|
2585
|
+
this.addItem(item, tripticItem);
|
|
2586
|
+
if (itm_group && all_itms && all_itms.every(t => t._selected))
|
|
2587
|
+
this.selectGroup(itm_group);
|
|
2588
|
+
}
|
|
2589
|
+
else {
|
|
2590
|
+
this.removeItem(item, tripticItem);
|
|
2591
|
+
if (itm_group)
|
|
2592
|
+
itm_group._selected = false;
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
}
|
|
2596
|
+
/**
|
|
2597
|
+
* Helper per selezionare un gruppo e, ricorsivamente, se tutti i gruppi sottostanti al parent sono selezionati, selezionare i gruppi padri
|
|
2598
|
+
*
|
|
2599
|
+
* @param {any} group Gruppo da selezionare
|
|
2600
|
+
*/
|
|
2601
|
+
selectGroup(group) {
|
|
2602
|
+
group._selected = true;
|
|
2603
|
+
let parent = this.getGroupParent(group);
|
|
2604
|
+
if (parent && this.getGroupChildGroups(null, parent, null, true).every(t => t._selected))
|
|
2605
|
+
this.selectGroup(parent);
|
|
2606
|
+
}
|
|
2607
|
+
/**
|
|
2608
|
+
* Dato L'oggetto di selezione, l'oggetto da selezionare/deselezionare e tutti i parametri del caso effettua le operazioni che servono.
|
|
2609
|
+
*
|
|
2610
|
+
* La logica di questa funzione è nata essenzialmente da spam di trial & error ed è stata testata solo fino a due livelli di raggruppamento,
|
|
2611
|
+
* qualsiasi cosa vada oltre non è 100% detto che funzioni...
|
|
2612
|
+
*/
|
|
2613
|
+
performSelectionOperations(base, item, all, group, sel, sel_itm, sel_grp, desel_itm, desel_grp, all_itms, all_grps, parent_incl, parent_excl) {
|
|
2614
|
+
let tripticGroup = this.getTriptic('group', base);
|
|
2615
|
+
let tripticItem = this.getTriptic('item', base);
|
|
2616
|
+
let tripticExcl = this.getTriptic('exclusion', base);
|
|
2617
|
+
let tripticgrpExcl = this.getTriptic('group_exclusion', base);
|
|
2618
|
+
if (group) {
|
|
2619
|
+
if (sel) {
|
|
2620
|
+
if (all || parent_incl)
|
|
2621
|
+
this.removeItem(item, tripticgrpExcl);
|
|
2622
|
+
else
|
|
2623
|
+
this.addItem(item, tripticGroup);
|
|
2624
|
+
if (sel_itm)
|
|
2625
|
+
sel_itm.forEach(el => this.removeItem(el, tripticItem));
|
|
2626
|
+
if (sel_grp)
|
|
2627
|
+
sel_grp.forEach(gr => this.removeItem(gr, tripticGroup));
|
|
2628
|
+
if (all_itms)
|
|
2629
|
+
all_itms.forEach(el => { el._selected = true; this.removeItem(el, tripticExcl); });
|
|
2630
|
+
if (all_grps)
|
|
2631
|
+
all_grps.forEach(gr => { gr._selected = true; this.removeItem(gr, tripticgrpExcl); });
|
|
2632
|
+
}
|
|
2633
|
+
else {
|
|
2634
|
+
if (all || parent_incl)
|
|
2635
|
+
this.addItem(item, tripticgrpExcl);
|
|
2636
|
+
else
|
|
2637
|
+
this.removeItem(item, tripticGroup);
|
|
2638
|
+
if (desel_itm)
|
|
2639
|
+
desel_itm.forEach(el => this.removeItem(el, tripticExcl));
|
|
2640
|
+
if (desel_grp)
|
|
2641
|
+
desel_grp.forEach(gr => this.removeItem(gr, tripticExcl));
|
|
2642
|
+
if (all_itms)
|
|
2643
|
+
all_itms.forEach(el => { el._selected = false; this.removeItem(el, tripticItem); });
|
|
2644
|
+
if (all_grps)
|
|
2645
|
+
all_grps.forEach(gr => { gr._selected = false; this.removeItem(gr, tripticGroup); });
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
else {
|
|
2649
|
+
if (sel) {
|
|
2650
|
+
if ((parent_excl == null && all) || parent_incl)
|
|
2651
|
+
this.removeItem(item, tripticExcl);
|
|
2652
|
+
else
|
|
2653
|
+
this.addItem(item, tripticItem);
|
|
2654
|
+
}
|
|
2655
|
+
else {
|
|
2656
|
+
if (parent_excl || (!all && parent_excl == null))
|
|
2657
|
+
this.removeItem(item, tripticItem);
|
|
2658
|
+
else
|
|
2659
|
+
this.addItem(item, tripticExcl);
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
/**
|
|
2664
|
+
* Helper per evitare di riscrivere ogni santa volta array.splice(array.indexof(item), 1);
|
|
2665
|
+
*/
|
|
2666
|
+
removeItem(item, triptic) {
|
|
2667
|
+
let index = triptic.index_cache.get(item._hash);
|
|
2668
|
+
if (index != null) {
|
|
2669
|
+
triptic.cache.delete(item._hash);
|
|
2670
|
+
triptic.index_cache.delete(item._hash);
|
|
2671
|
+
triptic.array[index] = null;
|
|
2672
|
+
}
|
|
2673
|
+
return !!index;
|
|
2674
|
+
}
|
|
2675
|
+
/**
|
|
2676
|
+
* Helper per evitare di riscrivere ogni santa volta array.push(item); e la gestione della
|
|
2677
|
+
*/
|
|
2678
|
+
addItem(item, triptic) {
|
|
2679
|
+
if (triptic.index_cache.get(item._hash) == null) {
|
|
2680
|
+
let i = triptic.array.push(item) - 1;
|
|
2681
|
+
triptic.cache.set(item._hash, item);
|
|
2682
|
+
triptic.index_cache.set(item._hash, i);
|
|
2683
|
+
return true;
|
|
2684
|
+
}
|
|
2685
|
+
return false;
|
|
2686
|
+
}
|
|
2687
|
+
/**
|
|
2688
|
+
* Ottiene il trittico di selezione: L'array degli oggetti e le due cache
|
|
2689
|
+
*/
|
|
2690
|
+
getTriptic(subject, base) {
|
|
2691
|
+
switch (subject) {
|
|
2692
|
+
case 'group':
|
|
2693
|
+
return new CacheTriptic(this.groupsCache, this.i_groupsCache, base.groups);
|
|
2694
|
+
case 'item':
|
|
2695
|
+
return new CacheTriptic(this.itemsCache, this.i_itemsCache, base.items);
|
|
2696
|
+
case 'group_exclusion':
|
|
2697
|
+
return new CacheTriptic(this.group_exclusionsCache, this.i_group_exclusionsCache, base.group_exclusions);
|
|
2698
|
+
case 'exclusion':
|
|
2699
|
+
return new CacheTriptic(this.exclusionsCache, this.i_exclusionsCache, base.exclusions);
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
/**
|
|
2703
|
+
* Dato un oggetto restituisce il gruppo di cui fa parte, se esiste
|
|
2704
|
+
*
|
|
2705
|
+
* @param {any} item Oggetto di cui trovare il gruppo
|
|
2706
|
+
*/
|
|
2707
|
+
getItemGroup(item) {
|
|
2708
|
+
let parent = this.rgGroupCache.get(item._thisKey);
|
|
2709
|
+
if (parent)
|
|
2710
|
+
return parent;
|
|
2711
|
+
return null;
|
|
2712
|
+
}
|
|
2713
|
+
/**
|
|
2714
|
+
* Data la chiave di un gruppo restituisce tutti gli oggetti con quella chiave
|
|
2715
|
+
*
|
|
2716
|
+
* @param {any} group Chiave da cercare
|
|
2717
|
+
* @param {'selected' | 'unselected'} status Stato degli elementi, selezionati o no
|
|
2718
|
+
* @param {boolean} recursive Indica se cercare solo gli elementi direttamente collegati o se prendere anche quelli dei gruppi figli
|
|
2719
|
+
*
|
|
2720
|
+
* @returns {any[]} Oggetti di tipo **_item** facenti capo alla chiave **groupKey**
|
|
2721
|
+
*/
|
|
2722
|
+
getGroupItems(sel, group, status, recursive = false, allbase = null) {
|
|
2723
|
+
let items = [];
|
|
2724
|
+
if (allbase)
|
|
2725
|
+
items = allbase;
|
|
2726
|
+
else {
|
|
2727
|
+
if (recursive) {
|
|
2728
|
+
// In modalità ricorsiva prendo gli oggetti di tutte le chiavi simili che trovo
|
|
2729
|
+
for (let key of this.rgItemCache.keys())
|
|
2730
|
+
if (key.startsWith(group._thisKey))
|
|
2731
|
+
items.push(...this.rgItemCache.get(key));
|
|
2732
|
+
}
|
|
2733
|
+
else
|
|
2734
|
+
items = this.rgItemCache.get(group._thisKey);
|
|
2735
|
+
}
|
|
2736
|
+
items = items.filter(t => !status || (t._selected && status == 'selected') || (!t._selected && status == 'unselected'));
|
|
2737
|
+
// Non trovo nessun oggetto, però magari di oggetti ne ho all'interno dell'oggetto di selezione.
|
|
2738
|
+
// Questo può essere vero solo se NON sono in modalità array, in caso contrario gli oggetti li devo per forza avere tutti
|
|
2739
|
+
if (items.length != 0 || !sel || this.arrayMode)
|
|
2740
|
+
return items;
|
|
2741
|
+
if (status == 'unselected')
|
|
2742
|
+
items = sel.exclusions.filter(t => t != null &&
|
|
2743
|
+
(!recursive && t._thisKey == group._thisKey) ||
|
|
2744
|
+
(recursive && t._thisKey.startsWith(group._thisKey)));
|
|
2745
|
+
else if (status == 'selected')
|
|
2746
|
+
items = sel.items.filter(t => t != null &&
|
|
2747
|
+
(!recursive && t._thisKey == group._thisKey) ||
|
|
2748
|
+
(recursive && t._thisKey.startsWith(group._thisKey)));
|
|
2749
|
+
return items;
|
|
2750
|
+
}
|
|
2751
|
+
/**
|
|
2752
|
+
* Data la chiave di un gruppo restituisce tutti gli oggetti con quella chiave
|
|
2753
|
+
*
|
|
2754
|
+
* @param {any} group Gruppo di cui cercare il parent
|
|
2755
|
+
*
|
|
2756
|
+
* @returns {any} Oggetto di tipo **_group** rappresentante il parent del **group** attuale
|
|
2757
|
+
*/
|
|
2758
|
+
getGroupParent(group) {
|
|
2759
|
+
let parent = this.rgGroupCache.get(group._parent);
|
|
2760
|
+
if (parent)
|
|
2761
|
+
return parent;
|
|
2762
|
+
return null;
|
|
2763
|
+
}
|
|
2764
|
+
/**
|
|
2765
|
+
* Data la chiave di un gruppo restituisce tutti i gruppi figli
|
|
2766
|
+
*
|
|
2767
|
+
* @param {string} group Gruppo che rappresenta il padre di cui cercare i figli
|
|
2768
|
+
* @param {'selected' | 'unselected'} status Stato dei gruppi, selezionati o no
|
|
2769
|
+
* @param {boolean} recursive Indica se cercare solo i gruppi direttamente collegati o se prendere anche quelli dei gruppi figli
|
|
2770
|
+
*
|
|
2771
|
+
* @returns {any[]} Oggetti di tipo **_group** facenti capo alla chiave **groupKey**
|
|
2772
|
+
*/
|
|
2773
|
+
getGroupChildGroups(sel, group, status, recursive = false, allbase = null) {
|
|
2774
|
+
let thisGroup = this.rgGroupCache.get(group._thisKey);
|
|
2775
|
+
let items = [];
|
|
2776
|
+
if (allbase)
|
|
2777
|
+
items = allbase;
|
|
2778
|
+
else {
|
|
2779
|
+
if (recursive) {
|
|
2780
|
+
// In modalità ricorsiva prendo gli oggetti di tutte le chiavi simili che trovo
|
|
2781
|
+
for (let key of this.rgChildGroupsCache.keys())
|
|
2782
|
+
if (key.startsWith(group._thisKey))
|
|
2783
|
+
items.push(...this.rgChildGroupsCache.get(key));
|
|
2784
|
+
}
|
|
2785
|
+
else
|
|
2786
|
+
items = this.rgChildGroupsCache.get(group._thisKey);
|
|
2787
|
+
}
|
|
2788
|
+
items = items.filter(t => !status || (t._selected && status == 'selected') || (!t._selected && status == 'unselected'));
|
|
2789
|
+
// Non trovo nessun oggetto, però magari di oggetti ne ho all'interno dell'oggetto di selezione
|
|
2790
|
+
if (items.length != 0 || !sel)
|
|
2791
|
+
return items;
|
|
2792
|
+
if (status == 'unselected')
|
|
2793
|
+
items = sel.group_exclusions.filter((t) => t != null && ((!recursive && t._thisRoute.length == thisGroup._thisRoute.length + 1 && t._thisRoute.startsWith(group._thisKey)) ||
|
|
2794
|
+
(recursive && t._thisKey.startsWith(group._thisKey))));
|
|
2795
|
+
else
|
|
2796
|
+
items = sel.groups.filter((t) => t != null && ((!recursive && t._thisRoute.length == thisGroup._thisRoute.length + 1 && t._thisRoute.startsWith(group._thisKey)) ||
|
|
2797
|
+
(recursive && t._thisKey.startsWith(group._thisKey))));
|
|
2798
|
+
return items;
|
|
1392
2799
|
}
|
|
1393
2800
|
/**
|
|
1394
2801
|
* Finalizza le informazioni di selezione del **ItemsSelection** corrente
|
|
1395
2802
|
*/
|
|
1396
2803
|
finalizeSelectionInformations(selectionItem) {
|
|
2804
|
+
// Dato che le delete sono logiche dato che tengo la cache degli indici devo renderle fisiche
|
|
2805
|
+
let tmpGrp = [], tmpItems = [], tmpExcl = [], tmpGrpExcl = [];
|
|
2806
|
+
let grpRemoved = false, itemsRemoved = false, exclRemoved = false, grpExclRemoved = false;
|
|
2807
|
+
for (let i = 0; i < selectionItem.items.length; i++)
|
|
2808
|
+
if (selectionItem.items[i] != null)
|
|
2809
|
+
tmpItems.push(selectionItem.items[i]);
|
|
2810
|
+
else
|
|
2811
|
+
itemsRemoved = true;
|
|
2812
|
+
for (let i = 0; i < selectionItem.groups.length; i++)
|
|
2813
|
+
if (selectionItem.groups[i] != null)
|
|
2814
|
+
tmpGrp.push(selectionItem.groups[i]);
|
|
2815
|
+
else
|
|
2816
|
+
grpRemoved = true;
|
|
2817
|
+
for (let i = 0; i < selectionItem.exclusions.length; i++)
|
|
2818
|
+
if (selectionItem.exclusions[i] != null)
|
|
2819
|
+
tmpExcl.push(selectionItem.exclusions[i]);
|
|
2820
|
+
else
|
|
2821
|
+
exclRemoved = true;
|
|
2822
|
+
for (let i = 0; i < selectionItem.group_exclusions.length; i++)
|
|
2823
|
+
if (selectionItem.group_exclusions[i] != null)
|
|
2824
|
+
tmpGrpExcl.push(selectionItem.group_exclusions[i]);
|
|
2825
|
+
else
|
|
2826
|
+
grpExclRemoved = true;
|
|
2827
|
+
selectionItem.items = tmpItems;
|
|
2828
|
+
selectionItem.group_exclusions = tmpGrpExcl;
|
|
2829
|
+
selectionItem.exclusions = tmpExcl;
|
|
2830
|
+
selectionItem.groups = tmpGrp;
|
|
2831
|
+
// Le cache degli indici potrebbero avere buchi, risolvo
|
|
2832
|
+
if (grpRemoved)
|
|
2833
|
+
this.i_groupsCache = this.compactIndexMap(this.i_groupsCache);
|
|
2834
|
+
if (itemsRemoved)
|
|
2835
|
+
this.i_itemsCache = this.compactIndexMap(this.i_itemsCache);
|
|
2836
|
+
if (exclRemoved)
|
|
2837
|
+
this.i_exclusionsCache = this.compactIndexMap(this.i_exclusionsCache);
|
|
2838
|
+
if (grpExclRemoved)
|
|
2839
|
+
this.i_group_exclusionsCache = this.compactIndexMap(this.i_group_exclusionsCache);
|
|
2840
|
+
// Poi riprendo a fare tutto in normalità
|
|
1397
2841
|
selectionItem.count = this.evaluateSelected();
|
|
1398
2842
|
// Se ho fatto selezione "all" ma poi mi sono messo a togliere tutti gli elementi fino a rimanerne 0 resetto l'oggetto di selezione
|
|
1399
|
-
if (selectionItem.count == 0
|
|
2843
|
+
if (selectionItem.count == 0) {
|
|
2844
|
+
this.boundSource.forEach(t => t._selected = false);
|
|
1400
2845
|
selectionItem.all = false;
|
|
1401
2846
|
selectionItem.exclusions = [];
|
|
1402
2847
|
selectionItem.items = [];
|
|
2848
|
+
selectionItem.groups = [];
|
|
2849
|
+
selectionItem.group_exclusions = [];
|
|
1403
2850
|
// Ripulisco la cache altrimenti mi rimane piena di tutte le esclusioni
|
|
1404
|
-
this.
|
|
2851
|
+
this.clearSelectionCaches();
|
|
1405
2852
|
}
|
|
1406
2853
|
// Se la possibilità di fare "Seleziona tutto" è abilitata allora la considero appena mi viene selezionato qualcosa
|
|
1407
2854
|
this.canSelectAll = selectionItem.count > 0 && this.SelectAll;
|
|
1408
2855
|
}
|
|
2856
|
+
/**
|
|
2857
|
+
* Compatta una cache di indici
|
|
2858
|
+
*/
|
|
2859
|
+
compactIndexMap(map) {
|
|
2860
|
+
let index = 0;
|
|
2861
|
+
let ret = new Map();
|
|
2862
|
+
for (let key of map.keys())
|
|
2863
|
+
ret.set(key, index++);
|
|
2864
|
+
return ret;
|
|
2865
|
+
}
|
|
1409
2866
|
/**
|
|
1410
2867
|
* Gestisce i click sulla tabella, gestendo eventualmente anche gli Shift + Click per selezionare un range di oggetti
|
|
1411
2868
|
*
|
|
@@ -1424,7 +2881,7 @@ export class EsTableComponent {
|
|
|
1424
2881
|
let selecteditems = [];
|
|
1425
2882
|
if (event.shiftKey && this.ShiftClick && !this.SingleSelection) {
|
|
1426
2883
|
let startSelecting = false;
|
|
1427
|
-
let items = this.
|
|
2884
|
+
let items = this.boundSource.filter(t => !t._group && !t._sep);
|
|
1428
2885
|
for (let i = 0; i < items.length; i++) {
|
|
1429
2886
|
let t = items[i];
|
|
1430
2887
|
if (startSelecting) {
|
|
@@ -1457,8 +2914,10 @@ export class EsTableComponent {
|
|
|
1457
2914
|
*/
|
|
1458
2915
|
evaluateSelected() {
|
|
1459
2916
|
var _a;
|
|
1460
|
-
let
|
|
1461
|
-
|
|
2917
|
+
let si = ((_a = this.View) === null || _a === void 0 ? void 0 : _a.selection) || this.arraymodeSelection;
|
|
2918
|
+
let excByGroup = si.group_exclusions.reduce((prev, curr) => prev + curr.count, 0);
|
|
2919
|
+
let incByGroup = si.groups.reduce((prev, curr) => prev + curr.count, 0);
|
|
2920
|
+
this.selectedObjects = (si.all ? this.BaseItemsCount : incByGroup) - excByGroup + si.items.length - si.exclusions.length;
|
|
1462
2921
|
return this.selectedObjects;
|
|
1463
2922
|
}
|
|
1464
2923
|
/**
|
|
@@ -1466,9 +2925,11 @@ export class EsTableComponent {
|
|
|
1466
2925
|
*/
|
|
1467
2926
|
selectAllOrResetSelection() {
|
|
1468
2927
|
let selectionItem = this.View.selection || this.arraymodeSelection;
|
|
1469
|
-
this.
|
|
2928
|
+
this.clearSelectionCaches();
|
|
1470
2929
|
selectionItem.all = !selectionItem.all;
|
|
1471
2930
|
selectionItem.exclusions = [];
|
|
2931
|
+
selectionItem.groups = [];
|
|
2932
|
+
selectionItem.group_exclusions = [];
|
|
1472
2933
|
selectionItem.items = [];
|
|
1473
2934
|
// Ripulisco gli stati UI di selezione globale se l'ho disattivata
|
|
1474
2935
|
if (!selectionItem.all) {
|
|
@@ -1478,7 +2939,7 @@ export class EsTableComponent {
|
|
|
1478
2939
|
this.finalizeSelectionInformations(selectionItem);
|
|
1479
2940
|
this.onSelectionChanged.emit(selectionItem);
|
|
1480
2941
|
// Dopo aver resettato direttamente il solo oggetto this.View.selection devo anche riallineare a tutti gli oggetti bindati
|
|
1481
|
-
this.evaluateSelection(this.
|
|
2942
|
+
this.evaluateSelection(this.boundSource, selectionItem);
|
|
1482
2943
|
}
|
|
1483
2944
|
// #endregion
|
|
1484
2945
|
// #region Gestione Paginazione
|
|
@@ -1488,9 +2949,9 @@ export class EsTableComponent {
|
|
|
1488
2949
|
* @param {number} page Numero di pagine da aggiungere (o sottrarre, se negativo) alla pagina attuale
|
|
1489
2950
|
*/
|
|
1490
2951
|
addToPage(page) {
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
this.goToPage((this.SearchView ||
|
|
2952
|
+
var _a;
|
|
2953
|
+
let view = this.MainGroupView ? this.MainGroupView : this.View;
|
|
2954
|
+
this.goToPage((((_a = (this.SearchView || view)) === null || _a === void 0 ? void 0 : _a.page) || 0) + page);
|
|
1494
2955
|
}
|
|
1495
2956
|
/**
|
|
1496
2957
|
* Sposta la ricerca alla pagina specificata
|
|
@@ -1498,21 +2959,35 @@ export class EsTableComponent {
|
|
|
1498
2959
|
* @param {number} page Pagina a cui navigare
|
|
1499
2960
|
*/
|
|
1500
2961
|
goToPage(page) {
|
|
1501
|
-
|
|
2962
|
+
let view = this.MainGroupView ? this.MainGroupView : this.View;
|
|
2963
|
+
if (!view.page || !view.pages)
|
|
1502
2964
|
return;
|
|
1503
|
-
let appSearchElement = this.SearchView ||
|
|
2965
|
+
let appSearchElement = this.SearchView || view;
|
|
1504
2966
|
if (page === 0 || page > appSearchElement.pages)
|
|
1505
2967
|
return;
|
|
1506
2968
|
appSearchElement.page = page;
|
|
1507
2969
|
this.arrayPulsanti = this.getPagesArray(6, appSearchElement.page, appSearchElement.pages);
|
|
1508
|
-
this.
|
|
2970
|
+
let hasGroupings = !!this.MainGroupView;
|
|
2971
|
+
this.emitSearchRequest(false, hasGroupings ? view : null);
|
|
1509
2972
|
}
|
|
1510
2973
|
/**
|
|
1511
2974
|
* Evento richiamato sul cambio della paginazione. Verrà richiamato l'evento **emitSearchRequest**
|
|
1512
2975
|
* per comunicare al componente che utilizza questa tabella che i dati sono da aggiornare
|
|
1513
2976
|
*/
|
|
1514
|
-
onItemsPerPageChanged() {
|
|
1515
|
-
this.
|
|
2977
|
+
onItemsPerPageChanged(newIpp) {
|
|
2978
|
+
this.PagerOptions.View.itemsperpageoverride = newIpp;
|
|
2979
|
+
this.changed();
|
|
2980
|
+
if (this.MainGroupView)
|
|
2981
|
+
this.emitSearchRequest(true, this.MainGroupView);
|
|
2982
|
+
else
|
|
2983
|
+
this.emitSearchRequest(true);
|
|
2984
|
+
}
|
|
2985
|
+
/**
|
|
2986
|
+
* Evento richiamato sul cambio della paginazione. Verrà richiamato l'evento **emitSearchRequest** con la vista del separatore
|
|
2987
|
+
*/
|
|
2988
|
+
onGroupItemsPerPageChanged(pager, newIpp) {
|
|
2989
|
+
pager.view.itemsperpageoverride = newIpp;
|
|
2990
|
+
this.emitSearchRequest(true, pager.view);
|
|
1516
2991
|
}
|
|
1517
2992
|
// #endregion
|
|
1518
2993
|
// #region Gestione Export
|
|
@@ -1530,6 +3005,10 @@ export class EsTableComponent {
|
|
|
1530
3005
|
this.ExportFunction((data, cancel = false) => {
|
|
1531
3006
|
if (cancel)
|
|
1532
3007
|
return;
|
|
3008
|
+
if (data.length == 0) {
|
|
3009
|
+
this.msgExts.simpleWarning(this.lc.loc("Cannot export an empty dataset"));
|
|
3010
|
+
return;
|
|
3011
|
+
}
|
|
1533
3012
|
this.setupExport(data);
|
|
1534
3013
|
this.cdr.detectChanges();
|
|
1535
3014
|
setTimeout(() => { this.exportDownloader.nativeElement.click(); });
|
|
@@ -1655,12 +3134,12 @@ export class EsTableComponent {
|
|
|
1655
3134
|
* @returns {any} Router link generato in base al parametri
|
|
1656
3135
|
*/
|
|
1657
3136
|
generateRouterLink(path, parameterProps, item) {
|
|
1658
|
-
if (this.DynamicTableRouterLinkCache[item.
|
|
1659
|
-
return this.DynamicTableRouterLinkCache[item.
|
|
3137
|
+
if (this.DynamicTableRouterLinkCache[item._hash + path]) {
|
|
3138
|
+
return this.DynamicTableRouterLinkCache[item._hash + path];
|
|
1660
3139
|
}
|
|
1661
3140
|
else {
|
|
1662
3141
|
let link = this.getRouterLink(path, parameterProps, item);
|
|
1663
|
-
this.DynamicTableRouterLinkCache[item.
|
|
3142
|
+
this.DynamicTableRouterLinkCache[item._hash + path] = link;
|
|
1664
3143
|
return link;
|
|
1665
3144
|
}
|
|
1666
3145
|
}
|
|
@@ -1758,6 +3237,14 @@ export class EsTableComponent {
|
|
|
1758
3237
|
}
|
|
1759
3238
|
// #endregion
|
|
1760
3239
|
// #region Metodi di utilità
|
|
3240
|
+
/** Helper che identifica se il td attuale è di tipo **EsTd**. In caso contrario è da considerarsi **EsTdDirective** */
|
|
3241
|
+
isEsTd(td) {
|
|
3242
|
+
return !td._directive;
|
|
3243
|
+
}
|
|
3244
|
+
/** Helper che identifica se il th attuale è di tipo **EsTh**. In caso contrario è da considerarsi **EsThDirective** */
|
|
3245
|
+
isEsTh(th) {
|
|
3246
|
+
return !th._directive;
|
|
3247
|
+
}
|
|
1761
3248
|
/** Impostazione modalità dell'EsTable */
|
|
1762
3249
|
setMode(mode) {
|
|
1763
3250
|
this.viewMode = mode == 'view';
|
|
@@ -1770,7 +3257,8 @@ export class EsTableComponent {
|
|
|
1770
3257
|
}
|
|
1771
3258
|
}
|
|
1772
3259
|
/**
|
|
1773
|
-
* Helper per effettuare chiamate interne di allineamento alla funzione **writeValue**,
|
|
3260
|
+
* Helper per effettuare chiamate interne di allineamento alla funzione **writeValue**,
|
|
3261
|
+
* impostando prima **internalWriteCall** in modo da non effettuare operazioni inutili
|
|
1774
3262
|
*/
|
|
1775
3263
|
internalWriteValue() {
|
|
1776
3264
|
this.internalWriteCall = true;
|
|
@@ -1834,11 +3322,13 @@ export class EsTableComponent {
|
|
|
1834
3322
|
for (let i = 0; i < items.length; i++) {
|
|
1835
3323
|
let item = items[i];
|
|
1836
3324
|
// Prima di calcolare l'hash rimuovo le proprietà interne prima che mi scompensino i calcoli successivi
|
|
1837
|
-
|
|
1838
|
-
delete
|
|
1839
|
-
|
|
3325
|
+
let tmp = Object.assign({}, items[i]);
|
|
3326
|
+
delete tmp._selected;
|
|
3327
|
+
delete tmp._visible;
|
|
3328
|
+
delete tmp._hash;
|
|
3329
|
+
let hash = this.hashExts.hashObject(tmp);
|
|
1840
3330
|
usedHashesCache[hash] = usedHashesCache[hash] ? usedHashesCache[hash] + 1 : 1;
|
|
1841
|
-
item.
|
|
3331
|
+
item._hash = hash + (usedHashesCache[hash] > 1 ? "_" + usedHashesCache[hash] : "");
|
|
1842
3332
|
}
|
|
1843
3333
|
}
|
|
1844
3334
|
/**
|
|
@@ -1866,18 +3356,22 @@ EsTableComponent.decorators = [
|
|
|
1866
3356
|
viewProviders: [{ provide: LocalizationService, useClass: EsTableLoc }],
|
|
1867
3357
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1868
3358
|
encapsulation: ViewEncapsulation.None,
|
|
1869
|
-
template: "<!-- Patacchino di autoaggiornamento -->\r\n<div class=\"w-100\" *ngIf=\"AutoUpdate\">\r\n <div class=\"pull-right\">\r\n {{'Update every' | localize : lc}} <input [readonly]=\"autoUpdate\" maxlength=\"3\" class=\"form-control est-custom-input\" type=\"text\" [(ngModel)]=\"seconds\" /> {{'second/s' | localize : lc}}\r\n </div>\r\n <div class=\"pull-right m-t-2\">\r\n <label class=\"est-switch\">\r\n <input type=\"checkbox\" [(ngModel)]=\"autoUpdate\" (ngModelChange)=\"autoUpdateChanged();\" />\r\n <div class=\"est-slider round\"></div>\r\n </label>\r\n </div>\r\n</div>\r\n\r\n<!--\r\nI TH sono contenuto statico, questo significa che senza condizione per RowTHs arriverebbero sia qui sia nell ng-container dell'header in fase non inizializzata, duplicando fisicamente le colonne.\r\nPer ovviare al problema, questo pezzo lo faccio apparire solo se ci sono gi\u00E0 dei RowTHs, quindi su valorizzazione della View succeder\u00E0:\r\n1) appaiono i th nell' ng-container dell'header, e NON qui\r\n2) i TH vengono presi, elaborati e trasformati in RowTHs\r\n3) l'ng-container dell'header sparisce (per la condizione !UseCustomCells || !RowTHs) e qui appaiono i nuovi TH (che poi sono gli stessi di prima che girano)\r\n4) Vengono presi i nuovi TH da qui e trasformati a loro volta in RowTHs\r\n-->\r\n<div hidden *ngIf=\"UseCustomCells && RowTHs\">\r\n <ng-container *ngIf=\"View\">\r\n <!--Qui invece ci sono tutti i TH-->\r\n <ng-container *ngTemplateOutlet=\"headerRef\"></ng-container>\r\n </ng-container>\r\n</div>\r\n\r\n<!--\r\nQuesta parte \u00E8 un po' pi\u00F9 semplice del sopra. Infatti i TD vengono s\u00EC bindati in entrambi i punti (qui e nell'ng-container del body), ma avr\u00F2 le TD statiche prima di generare la TMPBoundSource.\r\nQuesto significa che il workflow di binding sar\u00E0:\r\n1) Appaiono i TD statici nel body e NON qui, perch\u00E9 i TMPBoundSource non sono ancora stati emessi\r\n2) Contemporaneamente all'emissione dei TMPBoundSource vengono anche emessi i RowTds\r\n3) Considerando il punto 2, al giro dopo appariranno i TD qui, perch\u00E9 \u00E8 stata generata la TMPBoundSource, e spariranno contemporaneamente dall'ng-container del body (per la condizione !UseCustomCells || !RowTDs)\r\n-->\r\n<div hidden *ngIf=\"UseCustomCells && bodyRef\">\r\n <ng-container *ngIf=\"View\">\r\n <!--Tutti i TD che dopo verranno presi ed elaborati internamente-->\r\n <ng-container *ngFor=\"let item of TMPBoundSource\">\r\n <ng-container *ngTemplateOutlet=\"bodyRef; context : {$implicit: item}\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</div>\r\n\r\n<ng-container *ngIf=\"View\">\r\n <div *ngIf=\"FirstBind && ShowLoadingOnBootstrap\" class=\"est-loading-box\">\r\n <div class=\"est-loading-content\">\r\n <span class=\"fa fa-spinner fa-spin\"></span> {{'Performing Table bootstrap' | localize: lc}}...\r\n </div>\r\n </div>\r\n\r\n <div class=\"table-responsive datatable {{Class}}\" [class.est-scrollable]=\"UseEndlessscroll\" (scroll)=\"UseEndlessscroll && onScroll($event)\" [style.max-height.px]=\"MaxHeight\">\r\n <table class=\"{{ TableClass }}\" [class.est-high-density]=\"HighCellDensity\">\r\n <thead [hidden]=\"HeaderHidden || FirstBind\">\r\n\r\n <!-- Aggiungo il pezzo che gestisce la selezione di tutto se attivo da config -->\r\n <tr *ngIf=\"SelectAll\">\r\n <th colspan=\"42\" [class.est-hidden]=\"!canSelectAll && !(View?.selection || arraymodeSelection).all\">\r\n <span>{{ (selectedObjects || 0).toString() + ' ' + ((selectedObjects == 1 ? 'Object Selected' : 'Objects Selected') | localize : lc) }}</span> \r\n <span class=\"app-link app-inline\" (click)=\"selectAllOrResetSelection()\">{{ (View?.selection || arraymodeSelection).all ? ('Reset Selection' | localize : lc) : ('Select Everything' | localize : lc)}}</span>\r\n </th>\r\n </tr>\r\n\r\n <!-- Blocco header group -->\r\n <tr *ngIf=\"HasHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"headerGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n\r\n <!-- Blocco header group secondario -->\r\n <tr *ngIf=\"HasSecondaryHeaderGroup\">\r\n <ng-container *ngTemplateOutlet=\"secondaryHeaderGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n\r\n <!-- Blocco effettivo degli header -->\r\n <tr>\r\n <!-- Aggiungo una checkbox se la selezione \u00E8 attiva -->\r\n <th class=\"est-col-min\" *ngIf=\"Selection\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n\r\n <!-- Header che valgono per view mode e array mode -->\r\n <ng-container *ngIf=\"(viewMode || arrayMode)\">\r\n\r\n <!-- In una tabella base prendo semplicemente i th scritti dall'utente nell'HTML -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"headerRef\"></ng-container>\r\n </ng-container>\r\n\r\n <!-- Se ho un modello dinamico dell'oggetto creo le colonne in base alle propriet\u00E0 -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs) && DynamicRowColumnsDefinition\">\r\n <ng-container *ngFor=\"let operation of DynamicOperations\">\r\n <th class=\"est-col-min est-no-side-padding\"></th>\r\n </ng-container>\r\n \r\n <ng-container *ngFor=\"let rowHeader of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowHeader.visible\">\r\n <th *ngIf=\"OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowHeader.clss : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"thOrderChanged(rowHeader.propertyName, $event)\">{{rowHeader.description}}</th>\r\n <th *ngIf=\"!OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowHeader.clss : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\">{{rowHeader.description}}</th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Se non ho un modello dinamico ma invece delle celle custom, genero gli header in base ai row th -->\r\n <ng-container *ngIf=\"UseCustomCells && RowTHs\">\r\n <ng-container *ngFor=\"let rowHeader of RowTHs\">\r\n <ng-container *ngIf=\"rowHeader && rowHeader.Visible\">\r\n <th es-th=\"{{rowHeader.ID}}\" class=\"{{rowHeader.Class}}{{rowHeader.Wrap ? '' : ' est-nowrap'}}\" [Order]=\"rowHeader.Order\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"OrderByColumn && thOrderChanged(rowHeader.ID, $event)\">\r\n <ng-container *ngIf=\"rowHeader.Template\">\r\n <ng-container *ngTemplateOutlet=\"rowHeader.Template;\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowHeader.Template\">\r\n {{rowHeader.Content}}\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!--Casistica in cui ho il setup proveniente da un report. Gli header sono definiti da come \u00E8 fatto il report-->\r\n <ng-container *ngIf=\"reportMode\">\r\n <th [style.color]=\"clm.color\" *ngFor=\"let clm of ReportValues.columns\" class=\"app-no-selection app-pointer est-nowrap\" (click)=\"setupNextOrderAndSearch(clm)\">\r\n {{clm.description}}<span class=\"fa\" [class.fa-chevron-down]=\"clm.order == 'DESC'\" [class.fa-chevron-up]=\"clm.order == 'ASC'\"></span>\r\n </th>\r\n </ng-container>\r\n\r\n <!--Per l'eliminazione mi serve un header aggiuntivo-->\r\n <th *ngIf=\"Removal\" [class.app-right-10]=\"Export || HiddenColumns\" class=\"est-col-min app-sticky-last-column\"><span class=\"fa fa-trash\"></span></th>\r\n\r\n <!--Per l'esportazione mi serve l'header extra da cui faccio uscire i 3 pallocchi-->\r\n <th *ngIf=\"Export || HiddenColumns || ColumnsOrdering || CornerMenuOptions\" class=\"app-table-dotted-menu app-sticky-last-column est-col-min text-sm-center\">\r\n \r\n <!-- Link nascosto che serve a scaricare il file -->\r\n <a *ngIf=\"headers\" hidden #exportDownloader csvLink [data]=\"data\" [headers]=\"headers\" [delimiter]=\"';'\" [filename]=\"ExportFileName\"></a>\r\n\r\n <!-- Blocco con i 3 pallocchi che tira fuori il context menu delle operazioni -->\r\n <div class=\"btn-group\" container=\"body\" placement=\"bottom right\" dropdown #dropdown=\"bs-dropdown\" [autoClose]=\"true\">\r\n <span dropdownToggle class=\"fa fa-ellipsis-v app-fs-18 app-pointer app-padding-3\"></span>\r\n\r\n <div *dropdownMenu class=\"dropdown-menu dropdown-menu-right app-bring-to-front-strong\">\r\n <div class=\"est-pointer\">\r\n <a class=\"dropdown-item\" *ngIf=\"(HiddenColumns || ColumnsOrdering)\" (click)=\"resetColumnVisSelection(); changeColumnVisibilityModal.show();\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && CSVExport\" (click)=\"tryExport('CSV')\">{{'Export View' | localize : lc}} (CSV)</a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && XLSXExport\" (click)=\"tryExport('XLSX')\">{{'Export View' | localize : lc}} (XLSX)</a>\r\n <a class=\"dropdown-item\" *ngFor=\"let option of CornerMenuOptions\" (click)=\"cornerActionClicked(option.id)\">{{option.description}}</a>\r\n </div>\r\n </div>\r\n </div>\r\n </th>\r\n </tr>\r\n </thead>\r\n \r\n <!-- Valido per modalit\u00E0 View o Array. Se sono in report mode il body \u00E8 creato in altro modo -->\r\n <tbody [hidden]=\"BodyHidden || FirstBind\" *ngIf=\"(arrayMode || viewMode)\">\r\n <!--Con selection attiva richiamo il template che gestisce il context menu-->\r\n <ng-container *ngIf=\"Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBodySelection; context: { $implicit: { selDisabled: arrayMode ? false : SelectionDisabled, sel: Selection }}\"></ng-container>\r\n </ng-container>\r\n\r\n <!--Senza selection richiamo il template che NON gestisce il context menu-->\r\n <ng-container *ngIf=\"!Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBody\"></ng-container>\r\n </ng-container>\r\n </tbody>\r\n\r\n <!-- Per la modalit\u00E0 a report c'\u00E8 un body particolare semi-dinamico -->\r\n <tbody [hidden]=\"BodyHidden\" *ngIf=\"reportMode\">\r\n <tr *ngFor=\"let row of ReportValues.rows; let even = even;\">\r\n <td class=\"est-nowrap\" *ngFor=\"let val of row.values\">{{val}}</td>\r\n <td class=\"app-sticky-last-column{{even && !Hierarchy ? '-alt' : ''}}\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <ng-container *ngIf=\"ShowPaging && !FirstBind\">\r\n\r\n <!-- Paginatore dove appare la count e le opzioni di paginazione -->\r\n <div class=\"pull-left m-t-min-3\">\r\n <ng-container *ngIf=\"viewMode\">\r\n <ng-container *ngTemplateOutlet=\"pagerSelector; context: { $implicit: { ShowCount: !HidePagingCount || (View && View.objectcount && View.objectcount != -1), ShowPaging: !HidePaging, View: View, UsesView: true }}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"arrayMode && (!UseArrayModePaging || SearchView)\">\r\n <ng-container *ngTemplateOutlet=\"pagerSelector; context: { $implicit: { ShowCount: !HidePagingCount || (View && View.length) || (SearchView && SearchView.objectcount && SearchView.objectcount != -1), ShowPaging: !HidePaging && SearchView, View: SearchView, SecondaryView: View, UsesView: true }}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"arrayMode && (UseArrayModePaging && !SearchView)\">\r\n <ng-container *ngTemplateOutlet=\"pagerSelector; context: { $implicit: { ShowCount: !HidePagingCount, ShowPaging: !HidePaging && View.length > 10, View: View, UsesView: false }}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"reportMode\">\r\n <ng-container *ngTemplateOutlet=\"pagerSelector; context: { $implicit: { ShowCount: !HidePagingCount || (View && View.objectcount && View.objectcount != -1), ShowPaging: View.pagingavailable, MightBeNoPaging: true, View: View, Report: ReportValues, UsesView: true }}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n \r\n <!-- Pulsanti avanti-indietro di paginazione -->\r\n <div class=\"pull-right btn-toolbar\" *ngIf=\"ShowPaging && !HidePagingButtons\">\r\n <ng-container *ngIf=\"(!reportMode || View?.pagingavailable) && (!arrayMode || SearchView)\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { ATP: addToPage.bind(this), GTP: goToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"arrayMode && UseArrayModePaging && !SearchView\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { ATP: arrayAddToPage.bind(this), GTP: arrayGoToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n </ng-container>\r\n</ng-container>\r\n\r\n<!-- Template che contiene i pulsanti per cambiare pagina -->\r\n<ng-template #pagingButtons let-options>\r\n <a class=\"btn app-white-button app-no-margin\" (click)=\"options.ATP(-1)\"><span class=\"fa fa-chevron-left\"></span></a>\r\n <div *ngIf=\"options.Array\" class=\"app-inline\">\r\n <a *ngFor=\"let p of options.Array\" class=\"btn {{p.cssClass}} app-no-margin\" (click)=\"options.GTP(p.val)\">{{p.val}}</a>\r\n </div>\r\n <a class=\"btn app-white-button app-no-margin\" (click)=\"options.ATP(1)\"><span class=\"fa fa-chevron-right\"></span></a>\r\n</ng-template>\r\n\r\n<!-- Template che mostra le informazioni base di paginazione: conteggio oggetti, paginazione attuale e pulsanti per cambiarla -->\r\n<ng-template #pagerSelector let-options>\r\n <div *ngIf=\"options.ShowCount\">\r\n {{ CountLabel }}: \r\n <strong *ngIf=\"options.UsesView && !options.Report\">\r\n {{ options.View?.objectcount ? options.View.objectcount : options.SecondaryView && options.SecondaryView.length ? options.SecondaryView.length : \"0\" }}\r\n </strong>\r\n <strong *ngIf=\"!options.UsesView && !options.Report\">\r\n {{ options.View.length ? options.View.length : \"0\" }}\r\n </strong>\r\n <strong *ngIf=\"options.Report\">\r\n {{ options.Report.count && options.Report.count == -1 ? options.Report.rows.length : options.Report.count && options.Report.count > 0 ? options.Report.count : 0 }}\r\n </strong>\r\n </div>\r\n <div *ngIf=\"options.ShowPaging\">\r\n <app-paging *ngIf=\"!options.UsesView\" [Hidden]=\"!options.View || options.View.length == 0\" [WarnOnAll]=\"false\" [CurrentPageSize]=\"ArraymodeItemsPerPage\" (pagingSelected)=\"refreshPaging($event)\"></app-paging>\r\n <app-paging *ngIf=\"options.UsesView\" [AllSearch]=\"AllSearch\" [DefaultAll]=\"defaultAllPageOverride\" [View]=\"options.View\" (pagingSelected)=\"options.View.itemsperpageoverride = $event; changed(); onItemsPerPageChanged();\"></app-paging>\r\n </div>\r\n <div *ngIf=\"options.MightBeNoPaging && !options.ShowPaging\">\r\n <em>{{'Paging options are not available for this report' | localize: lc}}</em>\r\n </div>\r\n</ng-template>\r\n\r\n<!-- Questi due template rappresentano effettivamente il body della tabella. essendo il tr l'unica cosa che davvero cambia, il resto \u00E8 templatizzato -->\r\n<ng-template #TBodySelection let-templateOptions>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even; let i=index;\">\r\n <tr *ngIf=\"item.visible || !Hierarchy\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" [class.est-line-through]=\"item.removed || item.deleted\" [class.est-pointer]=\"!item.locked\" [class.est-white-selected]=\"item._selected && !item.locked\"\r\n [contextMenu]=\"!item.locked ? (ContextMenu || emptyMenu) : emptyMenu\" [contextMenuSubject]=\"item\"\r\n (click)=\"!item.locked && handleClick($event, item)\">\r\n \r\n <td *ngIf=\"!item.locked\"><input type=\"checkbox\" [disabled]=\"templateOptions.selDisabled\" [class.est-pointer]=\"!item.locked\" [(ngModel)]=\"item._selected\" name=\"check{{i}}\"></td>\r\n <td *ngIf=\"item.locked\"></td>\r\n\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n\r\n </tr>\r\n </ng-container>\r\n</ng-template> \r\n\r\n<ng-template #TBody>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even;\">\r\n <tr *ngIf=\"item.visible || !Hierarchy\" [class]=\"item._rowClass ? item._rowClass : ''\" [class.est-line-through]=\"item.removed || item.deleted\">\r\n\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle semplici, con header e body scritti a manazza -->\r\n<ng-template #basicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTDs) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"bodyRef; context : {$implicit: item}\"></ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle definite in maniera dinamica dal modello -->\r\n<ng-template #dynamicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTDs) && DynamicRowColumnsDefinition\">\r\n <ng-container *ngFor=\"let operation of DynamicOperations; let first = first; let last = last;\">\r\n <ng-container *ngIf=\"!operation.conditionField || (item.properties[operation.conditionField] == operation.conditionValue)\">\r\n <td [class.est-no-right-padding]=\"last\" [class.est-no-left-padding]=\"!first\" class=\"est-col-min\"><span title=\"{{operation.title}}\" class=\"{{operation.iconClass}} app-pointer\" (click)=\"dynamicOperation(item, operation.id)\">{{operation.text}}</span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"operation.conditionField && (item.properties[operation.conditionField] != operation.conditionValue)\">\r\n <td class=\"est-col-min est-no-side-padding\"></td>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngFor=\"let rowItem of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowItem.routePath && rowItem.visible\">\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\" [Internal]=\"false\">\r\n <a [routerLink]=\"generateRouterLink(rowItem.routePath, rowItem.routeParameterProperties, item)\" class=\"app-link\" [innerHTML]=\"item.properties[rowItem.propertyName]\"></a>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowItem.routePath && rowItem.visible\">\r\n <ng-container *ngTemplateOutlet=\"findEsTd(rowItem.propertyName) || defaultEsTd; context: { $implicit: item.properties[rowItem.propertyName], rowItem : rowItem, item : item }\"> </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #defaultEsTd let-value let-rowItem='rowItem' let-item='item'>\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\"\r\n [class.app-pointer]=\"UseCustomCellActions && CustomCellActionsOn.indexOf('$' + rowItem.propertyName + '$') != -1\"\r\n (click)=\"cellClicked(rowItem.propertyName, item) && !CellActionPropagates && $event.stopPropagation()\"\r\n [Internal]=\"false\">\r\n {{value}}\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale delle celle custom se configurate -->\r\n<ng-template #customCells let-item>\r\n <ng-container *ngIf=\"UseCustomCells && RowTDs\">\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item.hash]; let i = index\">\r\n <ng-container *ngIf=\"rowItem\">\r\n\r\n <ng-container *ngIf=\"!bodyRef && rowItem.Visible\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"rowItem.Template\">\r\n <ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <span *ngIf=\"!item.parent\" class=\"fa fa-chevron-down\" style=\"visibility:hidden\"></span>\r\n <span *ngIf=\"item.parent && item.expanded\" class=\"fa fa-chevron-down est-pointer app-no-selection\" (click)=\"collapseParent(item[this.OwnKey])\"></span>\r\n <span *ngIf=\"item.parent && !item.expanded\" class=\"fa fa-chevron-up est-pointer app-no-selection\" (click)=\"expandParent(item[this.OwnKey])\"></span>\r\n \r\n </ng-container>\r\n <a [routerLink]='rowItem.RouterLink' class=\"app-link\" [innerHTML]=\"rowItem.Content\"></a>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy\" [class.app-pointer]=\"UseCustomCellActions && CustomCellActionsOn.indexOf('$' + $any(rowItem).ID + '$') != -1\" (click)=\"cellClicked(rowItem.ID, item) && !CellActionPropagates && $event.stopPropagation()\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <span *ngIf=\"!item.parent\" class=\"fa fa-chevron-down\" style=\"visibility:hidden\"></span>\r\n <span *ngIf=\"item.parent && item.expanded\" class=\"fa fa-chevron-down est-pointer app-no-selection\" (click)=\"collapseParent(item[this.OwnKey])\"></span>\r\n <span *ngIf=\"item.parent && !item.expanded\" class=\"fa fa-chevron-up est-pointer app-no-selection\" (click)=\"expandParent(item[this.OwnKey])\"></span>\r\n \r\n </ng-container>\r\n <ng-container *ngIf=\"rowItem.Template\">\r\n <ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <span *ngIf=\"!rowItem.Template\" [innerHTML]=\"rowItem.Content\"></span>\r\n </td>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene i pulsanti di eliminazione/undo eliminazione ed esportazione che vanno in fondo ad un record edlla tabella -->\r\n<ng-template #bodyDeleteAndExport let-options>\r\n <ng-container *ngIf=\"Removal && !RemovalCondition\">\r\n <td class=\"app-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-10' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted)\"><span class=\"fa fa-remove app-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"app-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-10' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted)\"><span class=\"fa fa-undo text-warning app-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"Removal && RemovalCondition\">\r\n <td class=\"app-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-10' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-remove app-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"app-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-10' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-undo text-warning app-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n <td class=\"app-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-10' : ''}}\" *ngIf=\"!options.item[RemovalCondition]\"><span class=\"fa fa-remove app-hidden-view\"></span></td>\r\n </ng-container>\r\n <td *ngIf=\"Export || HiddenColumns || CornerMenuOptions\" class=\"app-sticky-last-column{{options.even && !Hierarchy ? '-alt' : ''}}\"></td>\r\n</ng-template>\r\n\r\n<!-- Context menu vuoto default per tutte le tabella che non ce l'hanno, in modo che al click destro appaia \"nessuna op disponibile\" -->\r\n<context-menu #emptyMenu>\r\n <ng-template contextMenuItem>\r\n <span>\r\n <em>{{'No operations available' | localize : lc}}...</em>\r\n </span>\r\n </ng-template>\r\n</context-menu>\r\n\r\n<!-- Modal per cambiare posizione e visibilit\u00E0 delle colonne dell'es-table -->\r\n<div bsModal #changeColumnVisibilityModal=\"bs-modal\" class=\"modal fade\" role=\"dialog\" aria-hidden=\"true\">\r\n <div class=\"modal-dialog modal-lg\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h5 class=\"modal-title pull-left\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </h5>\r\n <button type=\"button\" class=\"close pull-right\" (click)=\"changeColumnVisibilityModal.hide();\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\">×</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div *ngIf=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"card card-info app-padding-10 app-margin-bottom-0\">\r\n {{'There are no columns configured to be hidden/shown in this view' | localize : lc}}\r\n </div>\r\n <div *ngIf=\"TMPColumnsList && TMPColumnsList.length > 0\" style=\"max-height:500px; overflow-y:auto\">\r\n <!--Aaaaaaah la tristezza... qui mi servirebbe l'es-table per facilitare la selezione multipla ecc... peccato che se la linko qui entro in un loop impressionante-->\r\n <table class=\"table table-striped table-sm app-margin-bottom-0\">\r\n <thead>\r\n <tr>\r\n <th class=\"est-col-min\" *ngIf=\"HiddenColumns\">\r\n <input class=\"est-pointer\" type=\"checkbox\" [(ngModel)]=\"globalColVisCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalColVisCheckChanged();\">\r\n </th>\r\n <th class=\"est-col-min\" *ngIf=\"ColumnsOrdering\"></th>\r\n <th class=\"est-col-min est-nowrap\">{{'Column Name' | localize : lc}}</th>\r\n <!--Filler-->\r\n <th></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of TMPColumnsList; let i = index; let last = last\" class=\"est-pointer\" [class.est-white-selected]=\"lastSelectedItemID == item.id\" [class.est-no-selection]=\"!item.visible\" (click)=\"columnClicked(item);\">\r\n <td *ngIf=\"HiddenColumns\">\r\n <input type=\"checkbox\" [class.est-hidden-view]=\"item.fixed\" class=\"est-pointer\" [(ngModel)]=\"item.visible\" name=\"visible{{i}}\" (ngModelChange)=\"updateGlobalColVisCheck();\" />\r\n </td>\r\n <td class=\"est-nowrap\" *ngIf=\"ColumnsOrdering\">\r\n <span class=\"fa fa-arrow-up\" [class.est-hidden-view]=\"item.fixed\" (click)=\"lastSelectedItemID = item.id; i != 0 && !item.fixed && sendUp(item); $event.stopPropagation();\"></span>\r\n <span class=\"fa fa-arrow-down\" [class.est-hidden-view]=\"item.fixed\" (click)=\"lastSelectedItemID = item.id; !last && !item.fixed && sendDown(item); $event.stopPropagation();\"></span>\r\n </td>\r\n <td class=\"est-nowrap\">\r\n <ng-container *ngIf=\"item.template\">\r\n <ng-container *ngTemplateOutlet=\"item.template\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!item.template\">{{item.description}}</ng-container>\r\n </td>\r\n <!--Filler-->\r\n <td></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-secondary app-margin-right-10\" (click)=\"lastSelectedItemID = null; changeColumnVisibilityModal.hide();\">{{'Close' | localize : lc}}</button>\r\n <button type=\"button\" [disabled]=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"btn btn-primary\" (click)=\"confirmColumnVisibilitySelection() && changeColumnVisibilityModal.hide()\">{{'Confirm' | localize : lc}}</button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>",
|
|
1870
|
-
styles: [".est-loading-box{height:200px;text-align:center;position:relative;background:#ccc}.est-loading-content{margin:0;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:35px}.est-scrollable{max-height:600px;overflow:auto}.est-pointer{cursor:pointer}.est-high-density td,.est-high-density th{padding:0 .2rem}.est-no-selection{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.est-hidden-view{visibility:hidden}.est-nowrap{white-space:nowrap}.est-white-selected{background-color:#ddd!important}.est-line-through{text-decoration:line-through}.est-no-side-padding{padding-left:0;padding-right:0}.est-no-left-padding,.est-no-right-padding{padding-left:0}.est-col-min{width:1px}.est-switch{position:relative;display:inline-block;width:30px;height:17px;margin-bottom:0;margin-right:5px;margin-left:5px}.est-switch input{display:none}.est-slider{cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc}.est-slider,.est-slider:before{position:absolute;transition:.4s}.est-slider:before{content:\"\";height:13px;width:13px;left:3px;bottom:2px;background-color:#fff}input:checked+.est-slider{background-color:#2196f3}input:focus+.est-slider{box-shadow:0 0 1px #2196f3}input:checked+.est-slider:before{transform:translateX(11px)}.est-slider.round{border-radius:10px}.est-slider.round:before{border-radius:50%}.est-custom-input{width:30px;display:inline;padding:1px;height:20px}.est-row-lvl-1 td:first-child{padding-left:5px}.est-row-lvl-2 td:first-child{padding-left:20px}.est-row-lvl-3 td:first-child{padding-left:35px}.est-row-lvl-4 td:first-child{padding-left:50px}.est-row-lvl-5 td:first-child{padding-left:65px}.est-row-lvl-6 td:first-child{padding-left:80px}.est-row-lvl-7 td:first-child{padding-left:95px}.est-row-lvl-8 td:first-child{padding-left:110px}.est-row-lvl-9 td:first-child{padding-left:125px}.est-row-lvl-10 td:first-child{padding-left:140px}.est-row-lvl-11 td:first-child{padding-left:155px}.est-row-lvl-12 td:first-child{padding-left:170px}.est-row-lvl-13 td:first-child{padding-left:185px}.est-row-lvl-14 td:first-child{padding-left:200px}.est-row-lvl-15 td:first-child{padding-left:215px}.est-row-lvl-16 td:first-child{padding-left:230px}.est-row-lvl-17 td:first-child{padding-left:245px}.est-row-lvl-18 td:first-child{padding-left:260px}.est-row-lvl-19 td:first-child{padding-left:275px}.est-row-lvl-20 td:first-child{padding-left:290px}.est-row-lvl-21 td:first-child{padding-left:305px}.est-row-lvl-22 td:first-child{padding-left:320px}.est-row-lvl-23 td:first-child{padding-left:335px}.est-row-lvl-24 td:first-child{padding-left:350px}.est-row-lvl-25 td:first-child{padding-left:365px}.est-row-lvl-26 td:first-child{padding-left:380px}.est-row-lvl-27 td:first-child{padding-left:395px}.est-row-lvl-28 td:first-child{padding-left:410px}.est-row-lvl-29 td:first-child{padding-left:425px}.est-row-lvl-30 td:first-child{padding-left:440px}.est-row-lvl-31 td:first-child{padding-left:455px}.est-row-lvl-32 td:first-child{padding-left:470px}.est-row-lvl-33 td:first-child{padding-left:485px}.est-row-lvl-34 td:first-child{padding-left:500px}.est-row-lvl-35 td:first-child{padding-left:515px}.est-row-lvl-36 td:first-child{padding-left:530px}.est-row-lvl-37 td:first-child{padding-left:545px}.est-row-lvl-38 td:first-child{padding-left:560px}.est-row-lvl-39 td:first-child{padding-left:575px}.est-row-lvl-40 td:first-child{padding-left:590px}.est-row-lvl-41 td:first-child{padding-left:605px}.est-row-lvl-42 td:first-child{padding-left:620px}.est-row-lvl-43 td:first-child{padding-left:635px}.est-row-lvl-44 td:first-child{padding-left:650px}.est-row-lvl-45 td:first-child{padding-left:665px}.est-row-lvl-46 td:first-child{padding-left:680px}.est-row-lvl-47 td:first-child{padding-left:695px}.est-row-lvl-48 td:first-child{padding-left:710px}.est-row-lvl-49 td:first-child{padding-left:725px}.est-row-lvl-50 td:first-child{padding-left:740px}.est-row-lvl-51 td:first-child{padding-left:755px}.est-row-lvl-52 td:first-child{padding-left:770px}.est-row-lvl-53 td:first-child{padding-left:785px}.est-row-lvl-54 td:first-child{padding-left:800px}.est-row-lvl-55 td:first-child{padding-left:815px}.est-row-lvl-56 td:first-child{padding-left:830px}.est-row-lvl-57 td:first-child{padding-left:845px}.est-row-lvl-58 td:first-child{padding-left:860px}.est-row-lvl-59 td:first-child{padding-left:875px}.est-row-lvl-60 td:first-child{padding-left:890px}.est-row-lvl-61 td:first-child{padding-left:905px}.est-row-lvl-62 td:first-child{padding-left:920px}.est-row-lvl-63 td:first-child{padding-left:935px}.est-row-lvl-64 td:first-child{padding-left:950px}.est-row-lvl-65 td:first-child{padding-left:965px}.est-row-lvl-66 td:first-child{padding-left:980px}.est-row-lvl-67 td:first-child{padding-left:995px}.est-row-lvl-68 td:first-child{padding-left:1010px}.est-row-lvl-69 td:first-child{padding-left:1025px}.est-row-lvl-70 td:first-child{padding-left:1040px}.est-row-lvl-71 td:first-child{padding-left:1055px}.est-row-lvl-72 td:first-child{padding-left:1070px}.est-row-lvl-73 td:first-child{padding-left:1085px}.est-row-lvl-74 td:first-child{padding-left:1100px}.est-row-lvl-75 td:first-child{padding-left:1115px}.est-row-lvl-76 td:first-child{padding-left:1130px}.est-row-lvl-77 td:first-child{padding-left:1145px}.est-row-lvl-78 td:first-child{padding-left:1160px}.est-row-lvl-79 td:first-child{padding-left:1175px}.est-row-lvl-80 td:first-child{padding-left:1190px}.est-row-lvl-81 td:first-child{padding-left:1205px}.est-row-lvl-82 td:first-child{padding-left:1220px}.est-row-lvl-83 td:first-child{padding-left:1235px}.est-row-lvl-84 td:first-child{padding-left:1250px}.est-row-lvl-85 td:first-child{padding-left:1265px}.est-row-lvl-86 td:first-child{padding-left:1280px}.est-row-lvl-87 td:first-child{padding-left:1295px}.est-row-lvl-88 td:first-child{padding-left:1310px}.est-row-lvl-89 td:first-child{padding-left:1325px}.est-row-lvl-90 td:first-child{padding-left:1340px}.est-row-lvl-91 td:first-child{padding-left:1355px}.est-row-lvl-92 td:first-child{padding-left:1370px}.est-row-lvl-93 td:first-child{padding-left:1385px}.est-row-lvl-94 td:first-child{padding-left:1400px}.est-row-lvl-95 td:first-child{padding-left:1415px}.est-row-lvl-96 td:first-child{padding-left:1430px}.est-row-lvl-97 td:first-child{padding-left:1445px}.est-row-lvl-98 td:first-child{padding-left:1460px}.est-row-lvl-99 td:first-child{padding-left:1475px}.est-right-10{right:10px}.est-hidden{visibility:hidden}"]
|
|
3359
|
+
template: "<!-- Patacchino di autoaggiornamento -->\r\n<div class=\"w-100\" *ngIf=\"AutoUpdate\">\r\n <div class=\"pull-right\">\r\n {{'Update every' | localize : lc}} <input [readonly]=\"autoUpdate\" maxlength=\"3\" class=\"form-control est-custom-input\" type=\"text\" [(ngModel)]=\"seconds\" /> {{'second/s' | localize : lc}}\r\n </div>\r\n <div class=\"pull-right m-t-2\">\r\n <label class=\"est-switch\">\r\n <input type=\"checkbox\" [(ngModel)]=\"autoUpdate\" (ngModelChange)=\"autoUpdateChanged();\" />\r\n <div class=\"est-slider round\"></div>\r\n </label>\r\n </div>\r\n</div>\r\n\r\n<!--\r\nI TH sono contenuto statico, questo significa che senza condizione per RowTHs arriverebbero sia qui sia nell ng-container dell'header in fase non inizializzata, duplicando fisicamente le colonne.\r\nPer ovviare al problema, questo pezzo lo faccio apparire solo se ci sono gi\u00E0 dei RowTHs, quindi su valorizzazione della View succeder\u00E0:\r\n1) appaiono i th nell' ng-container dell'header, e NON qui\r\n2) i TH vengono presi, elaborati e trasformati in RowTHs\r\n3) l'ng-container dell'header sparisce (per la condizione !UseCustomCells || !RowTHs) e qui appaiono i nuovi TH (che poi sono gli stessi di prima che girano)\r\n4) Vengono presi i nuovi TH da qui e trasformati a loro volta in RowTHs\r\n-->\r\n<div hidden *ngIf=\"UseCustomCells && RowTHs\">\r\n <ng-container *ngIf=\"View\">\r\n <!--Qui invece ci sono tutti i TH-->\r\n <ng-container *ngTemplateOutlet=\"headerRef\"></ng-container>\r\n </ng-container>\r\n</div>\r\n\r\n<!--\r\nQuesta parte \u00E8 un po' pi\u00F9 semplice del sopra. Infatti i TD vengono s\u00EC bindati in entrambi i punti (qui e nell'ng-container del body), ma avr\u00F2 le TD statiche prima di generare la TMPBoundSource.\r\nQuesto significa che il workflow di binding sar\u00E0:\r\n1) Appaiono i TD statici nel body e NON qui, perch\u00E9 i TMPBoundSource non sono ancora stati emessi\r\n2) Contemporaneamente all'emissione dei TMPBoundSource vengono anche emessi i RowTds\r\n3) Considerando il punto 2, al giro dopo appariranno i TD qui, perch\u00E9 \u00E8 stata generata la TMPBoundSource, e spariranno contemporaneamente dall'ng-container del body (per la condizione !UseCustomCells || !RowTDs)\r\n-->\r\n<div hidden *ngIf=\"UseCustomCells && bodyRef\">\r\n <ng-container *ngIf=\"View\">\r\n <!--Tutti i TD che dopo verranno presi ed elaborati internamente-->\r\n <ng-container *ngFor=\"let item of TMPBoundSource\">\r\n <ng-container *ngTemplateOutlet=\"bodyRef; context : {$implicit: item}\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</div>\r\n\r\n<ng-container *ngIf=\"View\">\r\n <div *ngIf=\"FirstBind && ShowLoadingOnBootstrap\" class=\"est-loading-box\">\r\n <div class=\"est-loading-content\">\r\n <span class=\"fa fa-spinner fa-spin\"></span> {{'Performing Table bootstrap' | localize: lc}}...\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"PagingStyle == 'both' || PagingStyle == 'top'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n\r\n <div class=\"table-responsive datatable {{ContainerClass}}\" [class.est-scrollable]=\"UseEndlessscroll\" (scroll)=\"UseEndlessscroll && onScroll($event)\" [style.max-height.px]=\"MaxHeight\">\r\n <table class=\"{{ TableClass }} est-margin-bottom-10\" [class.est-high-density]=\"HighCellDensity\">\r\n <thead [hidden]=\"HeaderHidden || FirstBind\">\r\n <!-- Aggiungo il pezzo che gestisce la selezione di tutto se attivo da config -->\r\n <tr *ngIf=\"SelectAll\">\r\n <th class=\"est-no-selection\" [attr.colspan]=\"Columns.Global\" [class.est-hidden]=\"!canSelectAll && !(View?.selection || arraymodeSelection).all\">\r\n <span>{{ ((selectedObjects || 0) | number : '0.0-0' : locale) + ' ' + ((selectedObjects == 1 ? 'Object Selected' : 'Objects Selected') | localize : lc) }}</span> \r\n <span class=\"est-link est-inline\" (click)=\"selectAllOrResetSelection()\">{{ (View?.selection || arraymodeSelection).all ? ('Reset Selection' | localize : lc) : ('Select Everything' | localize : lc)}}</span>\r\n </th>\r\n </tr>\r\n\r\n <!-- Blocco header group -->\r\n <ng-container *ngIf=\"RowThGroups\">\r\n <tr *ngFor=\"let level of RowThGroups\">\r\n <th *ngFor=\"let cell of level\" [attr.colspan]=\"cell.Span\" \r\n [class.est-pinned-header]=\"cell.Pinned\" [class.est-col-min]=\"cell.Pinned\"\r\n [class.est-ltab-border]=\"cell.Borders\" [class.est-rtab-border]=\"cell.Borders\"\r\n class=\"est-text-center\">\r\n <ng-container *ngIf=\"cell.Pinned; Else: cell.Template\">\r\n <div class=\"est-pinned-border est-cell-group-padding\"></div>\r\n </ng-container>\r\n </th>\r\n </tr>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!RowThGroups\">\r\n <tr *ngIf=\"headerGroupRef\">\r\n <ng-container *ngTemplateOutlet=\"headerGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n \r\n <!-- Blocco header group secondario -->\r\n <tr *ngIf=\"secondaryHeaderGroupRef\">\r\n <ng-container *ngTemplateOutlet=\"secondaryHeaderGroupRef\"></ng-container>\r\n <th *ngIf=\"Export\"></th>\r\n </tr>\r\n </ng-container>\r\n\r\n <!-- Blocco effettivo degli header -->\r\n <tr>\r\n <!-- Aggiungo una checkbox se la selezione \u00E8 attiva -->\r\n <th class=\"est-col-min\" *ngIf=\"Selection && !HasPinnedColumns\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n\r\n <!-- Header che valgono per view mode e array mode -->\r\n <ng-container *ngIf=\"(viewMode || arrayMode)\">\r\n\r\n <!-- In una tabella base prendo semplicemente i th scritti dall'utente nell'HTML -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"headerRef\"></ng-container>\r\n </ng-container>\r\n\r\n <!-- Se ho un modello dinamico dell'oggetto creo le colonne in base alle propriet\u00E0 -->\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTHs) && DynamicRowColumnsDefinition\">\r\n <th *ngFor=\"let operation of DynamicOperations\" class=\"est-col-min est-no-side-padding\"></th>\r\n \r\n <ng-container *ngFor=\"let rowHeader of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowHeader.visible\">\r\n <th *ngIf=\"OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.clss || '') + (rowHeader.headerWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"thOrderChanged(rowHeader.propertyName, $event)\">{{rowHeader.description}}</th>\r\n <th *ngIf=\"!OrderByColumn\" es-th=\"{{rowHeader.propertyName}}\" class=\"{{UserDefinedDynamicCols ? ((rowHeader.clss || '') + (rowHeader.headerWraps ? '' : ' est-nowrap')) : ' est-nowrap'}}\" [Order]=\"rowHeader.dataOrder\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.orderable\" [OrderBy]=\"OrderByColumn\">{{rowHeader.description}}</th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Se non ho un modello dinamico ma invece delle celle custom, genero gli header in base ai row th -->\r\n <ng-container *ngIf=\"UseCustomCells && RowTHs\">\r\n <th *ngIf=\"HasPinnedColumns\" class=\"est-pinned-header est-col-min\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border\">\r\n <th class=\"est-col-min est-no-border\" *ngIf=\"Selection\">\r\n <input *ngIf=\"!SingleSelection\" class=\"est-pointer\" type=\"checkbox\" [disabled]=\"SelectionDisabled\" [(ngModel)]=\"globalCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalCheckChanged();\">\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs\">\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && rowHeader.Pinned\" [style.width.px]=\"rowHeader.PinnedWidth\" es-th=\"{{rowHeader.ID}}\" [class.est-no-border]=\"true\" [class.est-nowrap]=\"!rowHeader.Wrap\" class=\"{{rowHeader.Class || ''}}\" [Order]=\"rowHeader.Order\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"OrderByColumn && thOrderChanged(rowHeader.ID, $event)\">\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template;\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </div>\r\n </th>\r\n <ng-container *ngFor=\"let rowHeader of RowTHs\">\r\n <th *ngIf=\"rowHeader && rowHeader.Visible && !rowHeader.Pinned\" es-th=\"{{rowHeader.ID}}\" [class.est-ltab-border]=\"rowHeader.LeftBorder\" [class.est-rtab-border]=\"rowHeader.RightBorder\" [class.est-nowrap]=\"!rowHeader.Wrap\" class=\"{{rowHeader.Class || ''}}\" [Order]=\"rowHeader.Order\" [Resizable]=\"ColumnsResizable\" [Orderable]=\"rowHeader.Orderable\" [OrderBy]=\"OrderByColumn\" [SearchInProgress]=\"!!researchInProgress\" (onOrderChange)=\"OrderByColumn && thOrderChanged(rowHeader.ID, $event)\">\r\n <ng-container *ngIf=\"rowHeader.Template\"><ng-container *ngTemplateOutlet=\"rowHeader.Template;\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowHeader.Template\">{{rowHeader.Content}}</span>\r\n </th>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!--Casistica in cui ho il setup proveniente da un report. Gli header sono definiti da come \u00E8 fatto il report-->\r\n <ng-container *ngIf=\"reportMode\">\r\n <th [style.color]=\"clm.color\" *ngFor=\"let clm of ReportValues.columns\" class=\"est-no-selection est-pointer est-nowrap\" (click)=\"setupNextOrderAndSearch(clm)\">\r\n {{clm.description}}<span class=\"fa\" [class.fa-chevron-down]=\"clm.order == 'DESC'\" [class.fa-chevron-up]=\"clm.order == 'ASC'\"></span>\r\n </th>\r\n </ng-container>\r\n\r\n <!--Per l'eliminazione mi serve un header aggiuntivo-->\r\n <th *ngIf=\"Removal\" [class.est-right-10]=\"Export || HiddenColumns\" class=\"est-col-min est-sticky-last-column\"><span class=\"fa fa-trash\"></span></th>\r\n\r\n <!--Per l'esportazione mi serve l'header extra da cui faccio uscire i 3 pallocchi-->\r\n <th *ngIf=\"Export || HiddenColumns || ColumnsOrdering || CornerMenuOptions\" class=\"est-table-dotted-menu est-sticky-last-column est-col-min text-sm-center\">\r\n \r\n <!-- Link nascosto che serve a scaricare il file -->\r\n <a *ngIf=\"headers\" hidden #exportDownloader csvLink [data]=\"data\" [headers]=\"headers\" [delimiter]=\"';'\" [filename]=\"ExportFileName\"></a>\r\n\r\n <!-- Blocco con i 3 pallocchi che tira fuori il context menu delle operazioni -->\r\n <div class=\"btn-group\" container=\"body\" placement=\"bottom right\" dropdown #dropdown=\"bs-dropdown\" [autoClose]=\"true\">\r\n <span dropdownToggle class=\"fa fa-ellipsis-v est-fs-18 est-pointer est-padding-3\"></span>\r\n\r\n <div *dropdownMenu class=\"dropdown-menu dropdown-menu-right est-bring-to-front-strong\">\r\n <div class=\"est-pointer\">\r\n <a class=\"dropdown-item\" *ngIf=\"HiddenColumns || ColumnsOrdering\" (click)=\"resetColumnVisSelection(); changeColumnVisibilityModal.show();\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && CSVExport\" (click)=\"tryExport('CSV')\">{{'Export View' | localize : lc}} (CSV)</a>\r\n <a class=\"dropdown-item\" *ngIf=\"Export && XLSXExport\" (click)=\"tryExport('XLSX')\">{{'Export View' | localize : lc}} (XLSX)</a>\r\n <a class=\"dropdown-item\" *ngFor=\"let option of CornerMenuOptions\" (click)=\"cornerActionClicked(option.id)\">{{option.description}}</a>\r\n </div>\r\n </div>\r\n </div>\r\n </th>\r\n </tr>\r\n </thead>\r\n \r\n <!-- Valido per modalit\u00E0 View o Array. Se sono in report mode il body \u00E8 creato in altro modo -->\r\n <tbody [hidden]=\"BodyHidden || FirstBind\" *ngIf=\"(arrayMode || viewMode)\">\r\n <!--Con selection attiva richiamo il template che gestisce il context menu-->\r\n <ng-container *ngIf=\"Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBodySelection; context: { $implicit: { selDisabled: arrayMode ? false : SelectionDisabled, sel: Selection }}\"></ng-container>\r\n </ng-container>\r\n\r\n <!--Senza selection richiamo il template che NON gestisce il context menu-->\r\n <ng-container *ngIf=\"!Selection\">\r\n <ng-container *ngTemplateOutlet=\"TBody\"></ng-container>\r\n </ng-container>\r\n </tbody>\r\n\r\n <!-- Per la modalit\u00E0 a report c'\u00E8 un body particolare semi-dinamico -->\r\n <tbody [hidden]=\"BodyHidden\" *ngIf=\"reportMode\">\r\n <tr *ngFor=\"let row of ReportValues.rows; let even = even;\">\r\n <td class=\"est-nowrap\" *ngFor=\"let val of row.values\">{{val}}</td>\r\n <td class=\"est-sticky-last-column{{even && !Hierarchy ? '-alt' : ''}}\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div *ngIf=\"PagingStyle == 'both' || PagingStyle == 'bottom'\">\r\n <ng-container *ngTemplateOutlet=\"pagingElement\"></ng-container>\r\n </div>\r\n</ng-container>\r\n\r\n<!-- Template che contiene tutte le info di paginazione in modo da poterlo replicare anche sopra -->\r\n<ng-template #pagingElement>\r\n <ng-container *ngIf=\"!FirstBind\">\r\n <!-- Pulsanti avanti-indietro di paginazione -->\r\n <div *ngIf=\"PagerOptions.ShowPaging && !HidePagingButtons\" class=\"pull-right btn-toolbar\">\r\n <ng-container *ngIf=\"(!reportMode || View?.pagingavailable) && (!arrayMode || SearchView)\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { ATP: addToPage.bind(this), GTP: goToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"arrayMode && UseArrayModePaging && !SearchView\">\r\n <ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { ATP: arrayAddToPage.bind(this), GTP: arrayGoToPage.bind(this), Array: arrayPulsanti }}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n <!-- Paginatore dove appare la count e le opzioni di paginazione -->\r\n <div class=\"pull-right m-t-min-3 est-margin-right-50\">\r\n <div *ngIf=\"PagerOptions.ShowPaging && (PagerOptions.PagerCount > 10 || reportMode && View.pagingavailable)\">\r\n <app-paging *ngIf=\"!PagerOptions.UsesView\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [WarnOnAll]=\"false\" [CurrentPageSize]=\"ArraymodeItemsPerPage\" (pagingSelected)=\"refreshPaging($event)\"></app-paging>\r\n <app-paging *ngIf=\"PagerOptions.UsesView\" [ShowCount]=\"PagerOptions.ShowCount\" [PagerCount]=\"PagerOptions.PagerCount\" [GroupMode]=\"PagerOptions.Searches == 'groups'\" [AllSearch]=\"AllSearch\" [View]=\"PagerOptions.View\" (pagingSelected)=\"onItemsPerPageChanged($event);\"></app-paging>\r\n </div>\r\n <div *ngIf=\"reportMode && !PagerOptions.ShowPaging\"><em>{{'Paging options are not available for this report' | localize: lc}}</em></div>\r\n </div>\r\n <div class=\"clearfix\"></div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Template che contiene i pulsanti per cambiare pagina -->\r\n<ng-template #pagingButtons let-options>\r\n <a class=\"btn\" class=\"est-page-prev app-pointer\" (click)=\"options.ATP(-1, options.separator)\">\r\n <span class=\"fa fa-chevron-left\"></span>\r\n </a>\r\n <div *ngIf=\"options.Array\" class=\"est-inline\">\r\n <a *ngFor=\"let p of options.Array\" class=\"est-page-sel\" class=\"btn {{p.cssClass}}\"\r\n (click)=\"options.GTP(p.val, options.separator)\">{{p.val}}</a>\r\n </div>\r\n <a class=\"btn\" class=\"est-page-next app-pointer\" (click)=\"options.ATP(1, options.separator)\">\r\n <span class=\"fa fa-chevron-right\"></span>\r\n </a>\r\n</ng-template>\r\n\r\n<!-- Questi due template rappresentano effettivamente il body della tabella. essendo il tr l'unica cosa che davvero cambia, il resto \u00E8 templatizzato -->\r\n<ng-template #TBodySelection let-templateOptions>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even; let i=index;\">\r\n <tr *ngIf=\"item._visible || (!Hierarchy && !ArrayGrouping)\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\" \r\n [class.est-pointer]=\"!item.locked\" \r\n [class.est-white-selected]=\"item._selected && !item.locked\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n [contextMenu]=\"!item.locked ? (ContextMenu || emptyMenu) : emptyMenu\" [contextMenuSubject]=\"item\"\r\n (click)=\"(!item.locked && !item._sep && !item._group && handleClick($event, item)) || item._group && handleGroupClick(item)\">\r\n\r\n <td *ngIf=\"!item.locked && !item._sep && !HasPinnedColumns\">\r\n <input type=\"checkbox\" \r\n [disabled]=\"templateOptions.selDisabled\" \r\n [class.est-pointer]=\"!item.locked\"\r\n [(ngModel)]=\"item._selected\" name=\"check{{i}}\" \r\n (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td *ngIf=\"(item.locked || item._sep) && !HasPinnedColumns\"></td>\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container> </ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item, templateOptions: templateOptions }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #TBody>\r\n <ng-container *ngFor=\"let item of boundSource; let even = even;\">\r\n <tr *ngIf=\"item._visible || !Hierarchy\" \r\n [class]=\"item._rowClass ? item._rowClass : ''\" \r\n [class.est-line-through]=\"item.removed || item.deleted\"\r\n [class.est-rg]=\"item._group\"\r\n [class.est-rg-sep]=\"item._sep\"\r\n (click)=\"item._group && handleGroupClick(item)\">\r\n\r\n <ng-container *ngIf=\"item._sep\"><ng-container *ngTemplateOutlet=\"groupPager; context: { $implicit: item }\"></ng-container></ng-container>\r\n\r\n <ng-container *ngIf=\"!item._sep\">\r\n <ng-container *ngTemplateOutlet=\"basicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"dynamicColumns; context: { $implicit: item }\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"customCells; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"bodyDeleteAndExport; context: { $implicit: { even: even, item: item }}\"></ng-container>\r\n </tr>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #groupPager let-item>\r\n <td *ngIf=\"HasPinnedColumns\"></td>\r\n <td *ngIf=\"item._grouplevel > 1\" [attr.colspan]=\"item._grouplevel-1\"></td>\r\n <td [attr.colspan]=\"Columns.VisibleUnpinned - (item._grouplevel > 0 ? item._grouplevel - 1 : 0)\">\r\n <div class=\"est-rg-sep-flex-right\" *ngIf=\"RowGroupingPagingStyle == 'right'\">\r\n <div class=\"est-rg-page\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n <div class=\"est-rg-ipp\"><app-paging [AllSearch]=\"AllSearch\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n </div>\r\n\r\n <div class=\"est-rg-sep-flex-left\" *ngIf=\"RowGroupingPagingStyle == 'left'\">\r\n <div class=\"est-rg-ipp\"><app-paging [AllSearch]=\"AllSearch\" [GroupMode]=\"item.searches == 'groups'\" [PagerCount]=\"item.searches == 'groups' ? item.view.groupcount : item.view.objectcount\" [View]=\"item.view\" (pagingSelected)=\"onGroupItemsPerPageChanged(item, $event);\"></app-paging></div>\r\n <div class=\"est-rg-page\"><ng-container *ngTemplateOutlet=\"pagingButtons; context: { $implicit: { separator: item, ATP: addToPageGroup.bind(this), GTP: goToPageGroup.bind(this), Array: item.buttons }}\"></ng-container></div>\r\n </div>\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle semplici, con header e body scritti a manazza -->\r\n<ng-template #basicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTDs) && !DynamicRowColumnsDefinition\">\r\n <ng-container *ngTemplateOutlet=\"bodyRef; context : {$implicit: item}\"></ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale su tabelle definite in maniera dinamica dal modello -->\r\n<ng-template #dynamicColumns let-item>\r\n <ng-container *ngIf=\"(!UseCustomCells || !RowTDs) && DynamicRowColumnsDefinition\">\r\n <ng-container *ngFor=\"let operation of DynamicOperations; let first = first; let last = last;\">\r\n <ng-container *ngIf=\"!operation.conditionField || (item.properties[operation.conditionField] == operation.conditionValue)\">\r\n <td [class.est-no-right-padding]=\"last\" [class.est-no-left-padding]=\"!first\" class=\"est-col-min\"><span title=\"{{operation.title}}\" class=\"{{operation.iconClass}} est-pointer\" (click)=\"dynamicOperation(item, operation.id)\">{{operation.text}}</span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"operation.conditionField && (item.properties[operation.conditionField] != operation.conditionValue)\">\r\n <td class=\"est-col-min est-no-side-padding\"></td>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngFor=\"let rowItem of DynamicRowColumnsDefinition\">\r\n <ng-container *ngIf=\"rowItem.routePath && rowItem.visible\">\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\" [Internal]=\"false\" [Context]=\"item._hash\">\r\n <a [routerLink]=\"generateRouterLink(rowItem.routePath, rowItem.routeParameterProperties, item)\" class=\"est-link\" [innerHTML]=\"item.properties[rowItem.propertyName]\"></a>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowItem.routePath && rowItem.visible\">\r\n <ng-container *ngTemplateOutlet=\"findEsTd(rowItem.propertyName) || defaultEsTd; context: { $implicit: item.properties[rowItem.propertyName], rowItem : rowItem, item : item }\"> </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #defaultEsTd let-value let-rowItem='rowItem' let-item='item'>\r\n <td es-td=\"{{rowItem.propertyName}}\" class=\"{{UserDefinedDynamicCols ? rowItem.clss : 'est-nowrap'}}\"\r\n [class.est-pointer]=\"UseCustomCellActions && CustomCellActionsOn.indexOf('$' + rowItem.propertyName + '$') != -1\"\r\n (click)=\"cellClicked(rowItem.propertyName, item) && !CellActionPropagates && $event.stopPropagation()\"\r\n [Internal]=\"false\" [Context]=\"item._hash\">\r\n {{value}}\r\n </td>\r\n</ng-template>\r\n\r\n<!-- Questo template contiene la print condizionale delle celle custom se configurate -->\r\n<ng-template #customCells let-item let-opt=\"templateOptions\">\r\n <ng-container *ngIf=\"UseCustomCells && RowTDs\">\r\n\r\n <td *ngIf=\"HasPinnedColumns\" class=\"est-pinned-body est-col-min\" [class.est-white-selected]=\"item._selected\">\r\n <div [style.width.px]=\"PinnedContainerWidth\" class=\"est-pinned-border\">\r\n <td *ngIf=\"!item.locked && !item._sep && Selection\" class=\"est-no-border est-col-min\">\r\n <input type=\"checkbox\" [disabled]=\"opt.selDisabled\" [class.est-pointer]=\"!item.locked\" [(ngModel)]=\"item._selected\" name=\"check{{item._hash}}\" (click)=\"$event.stopPropagation(); handleClick($event, item);\">\r\n </td>\r\n <td class=\"est-no-border est-col-min\" *ngIf=\"(item.locked || item._sep) && Selection\"></td>\r\n\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item._hash]; let i = index\">\r\n <td *ngIf=\"rowItem && rowItem.Pinned\" [style.width.px]=\"rowItem.PinnedWidth\" es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-no-border]=\"true\" [class.est-rg-hdr]=\"rowItem.GroupHeader\" [class.est-rg-agg]=\"rowItem.GroupAggregation\" \r\n [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowItem.Template\">{{rowItem.Content}}</span>\r\n </td>\r\n </ng-container>\r\n </div>\r\n </td>\r\n\r\n <ng-container *ngFor=\"let rowItem of RowTDs[item._hash]; let i = index\">\r\n <ng-container *ngIf=\"rowItem && !rowItem.Pinned\">\r\n\r\n <!-- Casistica senza bodyRef, quindi con direttive per i td -->\r\n <ng-container *ngIf=\"!bodyRef && rowItem.Visible\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-ltab-border]=\"rowItem.LeftBorder\" [class.est-rtab-border]=\"rowItem.RightBorder\" [class.est-rg-hdr]=\"rowItem.GroupHeader\" [class.est-rg-agg]=\"rowItem.GroupAggregation\" \r\n [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\"><ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container></ng-container>\r\n <ng-container *ngIf=\"rowItem.Template\"><ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container></ng-container>\r\n <span *ngIf=\"!rowItem.Template\">{{rowItem.Content}}</span>\r\n </td>\r\n </ng-container>\r\n\r\n <!-- Casistica bodyRef, quindi con componenti per i td (RouterLink) DEPRECATO -->\r\n <ng-container *ngIf=\"rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <a [routerLink]='rowItem.RouterLink' class=\"est-link\" [innerHTML]=\"rowItem.Content\"></a>\r\n </td>\r\n </ng-container>\r\n\r\n <!-- Casistica bodyRef, quindi con componenti per i td (NON RouterLink) DEPRECATO -->\r\n <ng-container *ngIf=\"!rowItem.RouterLink && rowItem.Visible && bodyRef\">\r\n <td es-td=\"{{rowItem.ID}}\" class=\"{{rowItem.Class}}\" [class.est-nowrap]=\"Hierarchy || !rowItem.Wraps\" [class.est-pointer]=\"UseCustomCellActions && CustomCellActionsOn.indexOf('$' + $any(rowItem).ID + '$') != -1\" (click)=\"cellClicked(rowItem.ID, item) && !CellActionPropagates && $event.stopPropagation()\" [Internal]=\"true\">\r\n <ng-container *ngIf=\"Hierarchy && i == 0\">\r\n <ng-container *ngTemplateOutlet=\"HierarchyNavigator; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"rowItem.Template\">\r\n <ng-container *ngTemplateOutlet=\"rowItem.Template; context: { $implicit: item }\"></ng-container>\r\n </ng-container>\r\n <span *ngIf=\"!rowItem.Template\" [innerHTML]=\"rowItem.Content\"></span>\r\n </td>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n\r\n<ng-template #HierarchyNavigator let-item>\r\n <span *ngIf=\"!item.parent\" class=\"fa fa-chevron-down\" style=\"visibility:hidden\"></span>\r\n <span *ngIf=\"item.parent && item._expanded\" class=\"fa fa-chevron-down est-pointer est-no-selection\" (click)=\"collapseParent(item[this.OwnKey])\"></span>\r\n <span *ngIf=\"item.parent && !item._expanded\" class=\"fa fa-chevron-up est-pointer est-no-selection\" (click)=\"expandParent(item[this.OwnKey])\"></span>\r\n \r\n</ng-template>\r\n\r\n<!-- Questo template contiene i pulsanti di eliminazione/undo eliminazione ed esportazione che vanno in fondo ad un record edlla tabella -->\r\n<ng-template #bodyDeleteAndExport let-options>\r\n <ng-container *ngIf=\"Removal && !RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-10' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted)\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-10' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted)\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n </ng-container>\r\n <ng-container *ngIf=\"Removal && RemovalCondition\">\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-10' : ''}}\" *ngIf=\"!(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-remove est-pointer text-danger\" [hidden]=\"options.item.removable != undefined && !options.item.removable\" (click)=\"onRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-10' : ''}}\" *ngIf=\"(options.item.removed || options.item.deleted) && options.item[RemovalCondition]\"><span class=\"fa fa-undo text-warning est-pointer\" (click)=\"onAbortRemoval.emit(options.item)\"></span></td>\r\n <td class=\"est-sticky-last-column{{options.even? '-alt' : ''}} {{Export || HiddenColumns || CornerMenuOptions ? 'est-right-10' : ''}}\" *ngIf=\"!options.item[RemovalCondition]\"><span class=\"fa fa-remove est-hidden-view\"></span></td>\r\n </ng-container>\r\n <td *ngIf=\"Export || HiddenColumns || CornerMenuOptions\" class=\"est-sticky-last-column{{options.even && !Hierarchy ? '-alt' : ''}}\"></td>\r\n</ng-template>\r\n\r\n<!-- Context menu vuoto default per tutte le tabella che non ce l'hanno, in modo che al click destro appaia \"nessuna op disponibile\" -->\r\n<context-menu #emptyMenu>\r\n <ng-template contextMenuItem>\r\n <span>\r\n <em>{{'No operations available' | localize : lc}}...</em>\r\n </span>\r\n </ng-template>\r\n</context-menu>\r\n\r\n<!-- Modal per cambiare posizione e visibilit\u00E0 delle colonne dell'es-table -->\r\n<div bsModal #changeColumnVisibilityModal=\"bs-modal\" class=\"modal fade\" role=\"dialog\" aria-hidden=\"true\">\r\n <div class=\"modal-dialog modal-lg\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h5 class=\"modal-title pull-left\">\r\n <ng-container *ngIf=\"!HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Order' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && !ColumnsOrdering\">\r\n {{'Columns Visibility' | localize : lc}}\r\n </ng-container>\r\n <ng-container *ngIf=\"HiddenColumns && ColumnsOrdering\">\r\n {{'Columns Visibility and Order' | localize : lc}}\r\n </ng-container>\r\n </h5>\r\n <button type=\"button\" class=\"close pull-right\" (click)=\"changeColumnVisibilityModal.hide();\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\">×</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div *ngIf=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"card card-info est-padding-10 est-margin-bottom-0\">\r\n {{'There are no columns configured to be hidden/shown in this view' | localize : lc}}\r\n </div>\r\n <div *ngIf=\"TMPColumnsList && TMPColumnsList.length > 0\" style=\"max-height:500px; overflow-y:auto\">\r\n <!--Aaaaaaah la tristezza... qui mi servirebbe l'es-table per facilitare la selezione multipla ecc... peccato che se la linko qui entro in un loop impressionante-->\r\n <table class=\"table table-striped table-sm est-margin-bottom-0\">\r\n <thead>\r\n <tr>\r\n <th class=\"est-col-min\" *ngIf=\"HiddenColumns\">\r\n <input class=\"est-pointer\" type=\"checkbox\" [(ngModel)]=\"globalColVisCheck\" [ngModelOptions]=\"{'standalone': true}\" (ngModelChange)=\"globalColVisCheckChanged();\">\r\n </th>\r\n <th class=\"est-col-min\" *ngIf=\"ColumnsOrdering\"></th>\r\n <th class=\"est-col-min est-nowrap\">{{'Column Name' | localize : lc}}</th>\r\n <!--Filler-->\r\n <th></th>\r\n <!-- Pinner -->\r\n <th class=\"est-col-min\"></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let item of TMPColumnsList; let i = index; let last = last\" class=\"est-pointer\" [class.est-white-selected]=\"lastSelectedItemID == item.id\" [class.est-no-selection]=\"!item.visible\">\r\n <td *ngIf=\"HiddenColumns\">\r\n <input type=\"checkbox\" [class.est-hidden-view]=\"item.fixed\" class=\"est-pointer\" [(ngModel)]=\"item.visible\" name=\"visible{{i}}\" (ngModelChange)=\"updateGlobalColVisCheck();\" />\r\n </td>\r\n <td class=\"est-nowrap\" *ngIf=\"ColumnsOrdering\">\r\n <span class=\"fa fa-arrow-up\" [class.est-hidden-view]=\"item.fixed || item.pinned\" (click)=\"lastSelectedItemID = item.id; i != 0 && !item.fixed && sendUp(item); $event.stopPropagation();\"></span>\r\n <span class=\"fa fa-arrow-down\" [class.est-hidden-view]=\"item.fixed || item.pinned\" (click)=\"lastSelectedItemID = item.id; !last && !item.fixed && sendDown(item); $event.stopPropagation();\"></span>\r\n </td>\r\n <td class=\"est-nowrap\" (click)=\"columnClicked(item);\">\r\n <ng-container *ngIf=\"item.template\">\r\n <ng-container *ngTemplateOutlet=\"item.template\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!item.template\">{{item.description}}</ng-container>\r\n </td>\r\n <!--Filler-->\r\n <td (click)=\"columnClicked(item);\"></td>\r\n <!-- Pinner -->\r\n <td><span *ngIf=\"!item.fixed\" class=\"fa fa-thumb-tack\" [class.text-success]=\"item.pinned\" (click)=\"pinOrUnpinColumn(item)\"></span></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-secondary est-margin-right-10\" (click)=\"lastSelectedItemID = null; changeColumnVisibilityModal.hide();\">{{'Close' | localize : lc}}</button>\r\n <button type=\"button\" [disabled]=\"!TMPColumnsList || TMPColumnsList.length == 0\" class=\"btn btn-primary\" (click)=\"confirmColumnVisibilitySelection() && changeColumnVisibilityModal.hide()\">{{'Confirm' | localize : lc}}</button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>",
|
|
3360
|
+
styles: [".est-loading-box{height:200px;text-align:center;position:relative;background:#ccc}.est-loading-content{margin:0;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:35px}.est-scrollable{max-height:600px;overflow:auto}.est-pointer{cursor:pointer}.est-high-density td,.est-high-density th{padding:0 .2rem}.est-no-selection{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.est-hidden-view{visibility:hidden}.est-no-border{border:none!important}.est-nowrap{white-space:nowrap}.est-white-selected{background-color:#ddd!important}.est-line-through{text-decoration:line-through}.est-no-side-padding{padding-left:0;padding-right:0}.est-no-left-padding,.est-no-right-padding{padding-left:0}.est-col-min{width:1px}.est-margin-bottom-0{margin-bottom:0!important}.est-margin-right-10{margin-right:10px!important}.est-right-10{right:10px!important}.est-table-dotted-menu{padding:0 0 2px!important;color:#999}.est-fs-18{font-size:18px}.est-fs-14{font-size:14px}.est-padding-3{padding:3px!important}.est-page-container{position:relative}.est-bring-to-front-strong{z-index:99999999!important}.est-switch{position:relative;display:inline-block;width:30px;height:17px;margin-bottom:0;margin-right:5px;margin-left:5px}.est-switch input{display:none}.est-slider{cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc}.est-slider,.est-slider:before{position:absolute;transition:.4s}.est-slider:before{content:\"\";height:13px;width:13px;left:3px;bottom:2px;background-color:#fff}input:checked+.est-slider{background-color:#2196f3}input:focus+.est-slider{box-shadow:0 0 1px #2196f3}input:checked+.est-slider:before{transform:translateX(11px)}.est-slider.round{border-radius:10px}.est-slider.round:before{border-radius:50%}.est-custom-input{width:30px;display:inline;padding:1px;height:20px}.est-row-lvl-1 td:first-child{padding-left:5px}.est-row-lvl-2 td:first-child{padding-left:20px}.est-row-lvl-3 td:first-child{padding-left:35px}.est-row-lvl-4 td:first-child{padding-left:50px}.est-row-lvl-5 td:first-child{padding-left:65px}.est-row-lvl-6 td:first-child{padding-left:80px}.est-row-lvl-7 td:first-child{padding-left:95px}.est-row-lvl-8 td:first-child{padding-left:110px}.est-row-lvl-9 td:first-child{padding-left:125px}.est-row-lvl-10 td:first-child{padding-left:140px}.est-row-lvl-11 td:first-child{padding-left:155px}.est-row-lvl-12 td:first-child{padding-left:170px}.est-row-lvl-13 td:first-child{padding-left:185px}.est-row-lvl-14 td:first-child{padding-left:200px}.est-row-lvl-15 td:first-child{padding-left:215px}.est-row-lvl-16 td:first-child{padding-left:230px}.est-row-lvl-17 td:first-child{padding-left:245px}.est-row-lvl-18 td:first-child{padding-left:260px}.est-row-lvl-19 td:first-child{padding-left:275px}.est-row-lvl-20 td:first-child{padding-left:290px}.est-row-lvl-21 td:first-child{padding-left:305px}.est-row-lvl-22 td:first-child{padding-left:320px}.est-row-lvl-23 td:first-child{padding-left:335px}.est-row-lvl-24 td:first-child{padding-left:350px}.est-row-lvl-25 td:first-child{padding-left:365px}.est-row-lvl-26 td:first-child{padding-left:380px}.est-row-lvl-27 td:first-child{padding-left:395px}.est-row-lvl-28 td:first-child{padding-left:410px}.est-row-lvl-29 td:first-child{padding-left:425px}.est-row-lvl-30 td:first-child{padding-left:440px}.est-row-lvl-31 td:first-child{padding-left:455px}.est-row-lvl-32 td:first-child{padding-left:470px}.est-row-lvl-33 td:first-child{padding-left:485px}.est-row-lvl-34 td:first-child{padding-left:500px}.est-row-lvl-35 td:first-child{padding-left:515px}.est-row-lvl-36 td:first-child{padding-left:530px}.est-row-lvl-37 td:first-child{padding-left:545px}.est-row-lvl-38 td:first-child{padding-left:560px}.est-row-lvl-39 td:first-child{padding-left:575px}.est-row-lvl-40 td:first-child{padding-left:590px}.est-row-lvl-41 td:first-child{padding-left:605px}.est-row-lvl-42 td:first-child{padding-left:620px}.est-row-lvl-43 td:first-child{padding-left:635px}.est-row-lvl-44 td:first-child{padding-left:650px}.est-row-lvl-45 td:first-child{padding-left:665px}.est-row-lvl-46 td:first-child{padding-left:680px}.est-row-lvl-47 td:first-child{padding-left:695px}.est-row-lvl-48 td:first-child{padding-left:710px}.est-row-lvl-49 td:first-child{padding-left:725px}.est-row-lvl-50 td:first-child{padding-left:740px}.est-row-lvl-51 td:first-child{padding-left:755px}.est-row-lvl-52 td:first-child{padding-left:770px}.est-row-lvl-53 td:first-child{padding-left:785px}.est-row-lvl-54 td:first-child{padding-left:800px}.est-row-lvl-55 td:first-child{padding-left:815px}.est-row-lvl-56 td:first-child{padding-left:830px}.est-row-lvl-57 td:first-child{padding-left:845px}.est-row-lvl-58 td:first-child{padding-left:860px}.est-row-lvl-59 td:first-child{padding-left:875px}.est-row-lvl-60 td:first-child{padding-left:890px}.est-row-lvl-61 td:first-child{padding-left:905px}.est-row-lvl-62 td:first-child{padding-left:920px}.est-row-lvl-63 td:first-child{padding-left:935px}.est-row-lvl-64 td:first-child{padding-left:950px}.est-row-lvl-65 td:first-child{padding-left:965px}.est-row-lvl-66 td:first-child{padding-left:980px}.est-row-lvl-67 td:first-child{padding-left:995px}.est-row-lvl-68 td:first-child{padding-left:1010px}.est-row-lvl-69 td:first-child{padding-left:1025px}.est-row-lvl-70 td:first-child{padding-left:1040px}.est-row-lvl-71 td:first-child{padding-left:1055px}.est-row-lvl-72 td:first-child{padding-left:1070px}.est-row-lvl-73 td:first-child{padding-left:1085px}.est-row-lvl-74 td:first-child{padding-left:1100px}.est-row-lvl-75 td:first-child{padding-left:1115px}.est-row-lvl-76 td:first-child{padding-left:1130px}.est-row-lvl-77 td:first-child{padding-left:1145px}.est-row-lvl-78 td:first-child{padding-left:1160px}.est-row-lvl-79 td:first-child{padding-left:1175px}.est-row-lvl-80 td:first-child{padding-left:1190px}.est-row-lvl-81 td:first-child{padding-left:1205px}.est-row-lvl-82 td:first-child{padding-left:1220px}.est-row-lvl-83 td:first-child{padding-left:1235px}.est-row-lvl-84 td:first-child{padding-left:1250px}.est-row-lvl-85 td:first-child{padding-left:1265px}.est-row-lvl-86 td:first-child{padding-left:1280px}.est-row-lvl-87 td:first-child{padding-left:1295px}.est-row-lvl-88 td:first-child{padding-left:1310px}.est-row-lvl-89 td:first-child{padding-left:1325px}.est-row-lvl-90 td:first-child{padding-left:1340px}.est-row-lvl-91 td:first-child{padding-left:1355px}.est-row-lvl-92 td:first-child{padding-left:1370px}.est-row-lvl-93 td:first-child{padding-left:1385px}.est-row-lvl-94 td:first-child{padding-left:1400px}.est-row-lvl-95 td:first-child{padding-left:1415px}.est-row-lvl-96 td:first-child{padding-left:1430px}.est-row-lvl-97 td:first-child{padding-left:1445px}.est-row-lvl-98 td:first-child{padding-left:1460px}.est-row-lvl-99 td:first-child{padding-left:1475px}.est-right-10{right:10px}.est-hidden{visibility:hidden}.est-padding-10{padding:10px!important}.est-margin-right-50{margin-right:50px}.est-page-sel{color:#000;margin-left:3px;margin-right:3px;padding:0 5px;font-size:inherit}.est-page-next,.est-page-prev{color:#000;font-size:inherit;padding:3px 0 0}.est-pinned-header{background-color:#fff;left:0;top:0;position:sticky;z-index:1;border-bottom:1px solid #dee2e6!important;padding:0!important}.est-pinned-border{border-right:2px solid #dee2e6!important}.est-cell-padding{padding:.3rem}.est-pinned-body{background-color:#fff;left:0;position:sticky;z-index:1;border-top:1px solid #dee2e6!important;padding:0!important}.est-inline{display:inline!important}.est-inline-block{display:inline-block!important}.est-link{color:#0275d8!important;cursor:pointer;text-decoration:none;display:block}.est-link:hover{color:#23527c!important;cursor:pointer;text-decoration:underline!important}.est-sticky-last-column{right:-1px;position:sticky;z-index:0;background-color:#fff}.est-sticky-last-column-alt{right:-1px;position:sticky;z-index:0;background-color:#f2f2f2}.est-ltab-border{border-left:2px solid #bbb}.est-rtab-border{border-right:2px solid #bbb}.est-cell-group-padding{padding:calc(.3rem + 1px);position:absolute;top:0;left:0;height:100%;width:100%}.est-margin-bottom-10{margin-bottom:10px}.est-text-center{text-align:center}.est-rg-sep-flex-right{display:flex;flex-direction:row-reverse;width:100%;margin:-5px}.est-rg-sep-flex-left{display:flex;flex-direction:row;width:100%;margin:-5px}.est-rg-hdr{font-weight:700}.est-rg-agg{font-style:italic}.est-rg{background-color:hsla(0,0%,46.7%,.4666666666666667)!important}.est-rg-sep{font-size:12px;padding-right:20px!important;background-color:hsla(0,0%,73.3%,.7333333333333333)!important}.est-rg-ipp{text-align:left;display:inline-flex;margin-right:25px}.est-rg-page{text-align:right;display:inline-flex;font-size:inherit;padding-top:5px}"]
|
|
1871
3361
|
},] }
|
|
1872
3362
|
];
|
|
1873
3363
|
EsTableComponent.ctorParameters = () => [
|
|
1874
3364
|
{ type: NgControl, decorators: [{ type: Self }, { type: Optional }] },
|
|
1875
3365
|
{ type: PreferencesService, decorators: [{ type: Optional }] },
|
|
3366
|
+
{ type: EsTableDefaultable, decorators: [{ type: Optional }, { type: Inject, args: [EST_DEFAULTS,] }] },
|
|
3367
|
+
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [EST_LOCALE,] }] },
|
|
1876
3368
|
{ type: LocalizationService },
|
|
1877
3369
|
{ type: ChangeDetectorRef },
|
|
1878
3370
|
{ type: HashingService },
|
|
1879
3371
|
{ type: UtilityService },
|
|
1880
|
-
{ type: ExportService }
|
|
3372
|
+
{ type: ExportService },
|
|
3373
|
+
{ type: DateService },
|
|
3374
|
+
{ type: MessageService }
|
|
1881
3375
|
];
|
|
1882
3376
|
EsTableComponent.propDecorators = {
|
|
1883
3377
|
EsTdsDirective: [{ type: ContentChildren, args: [EsTdDirective,] }],
|
|
@@ -1896,7 +3390,7 @@ EsTableComponent.propDecorators = {
|
|
|
1896
3390
|
CellActionPropagates: [{ type: Input }],
|
|
1897
3391
|
UseCustomCells: [{ type: Input }],
|
|
1898
3392
|
MaxHeight: [{ type: Input }],
|
|
1899
|
-
|
|
3393
|
+
ContainerClass: [{ type: Input }],
|
|
1900
3394
|
XLSXExport: [{ type: Input }],
|
|
1901
3395
|
CSVExport: [{ type: Input }],
|
|
1902
3396
|
AllSearch: [{ type: Input }],
|
|
@@ -1907,14 +3401,12 @@ EsTableComponent.propDecorators = {
|
|
|
1907
3401
|
RemovalCondition: [{ type: Input }],
|
|
1908
3402
|
Export: [{ type: Input }],
|
|
1909
3403
|
ShiftClick: [{ type: Input }],
|
|
1910
|
-
ShowPaging: [{ type: Input }],
|
|
1911
3404
|
HidePaging: [{ type: Input }],
|
|
1912
3405
|
HidePagingCount: [{ type: Input }],
|
|
1913
3406
|
HidePagingButtons: [{ type: Input }],
|
|
1914
3407
|
ContextMenu: [{ type: Input }],
|
|
1915
3408
|
ExportFileName: [{ type: Input }],
|
|
1916
3409
|
TableClass: [{ type: Input }],
|
|
1917
|
-
CountLabel: [{ type: Input }],
|
|
1918
3410
|
ExportFunction: [{ type: Input }],
|
|
1919
3411
|
HasHeaderGroup: [{ type: Input }],
|
|
1920
3412
|
HasSecondaryHeaderGroup: [{ type: Input }],
|
|
@@ -1940,9 +3432,12 @@ EsTableComponent.propDecorators = {
|
|
|
1940
3432
|
OwnKey: [{ type: Input }],
|
|
1941
3433
|
StartsExpanded: [{ type: Input }],
|
|
1942
3434
|
SavePreferences: [{ type: Input }],
|
|
3435
|
+
PagingStyle: [{ type: Input }],
|
|
3436
|
+
RowGroupingPagingStyle: [{ type: Input }],
|
|
1943
3437
|
SecondarySource: [{ type: Input }],
|
|
1944
3438
|
TertiarySource: [{ type: Input }],
|
|
1945
3439
|
UseSelectionCache: [{ type: Input }],
|
|
3440
|
+
ShowItemGroupsColumns: [{ type: Input }],
|
|
1946
3441
|
onOrderChanged: [{ type: Output }],
|
|
1947
3442
|
onSearchRequest: [{ type: Output }],
|
|
1948
3443
|
onSelectionChanged: [{ type: Output }],
|
|
@@ -1955,4 +3450,4 @@ EsTableComponent.propDecorators = {
|
|
|
1955
3450
|
tableEmptyMenu: [{ type: ViewChild, args: ['emptyMenu', { static: true },] }],
|
|
1956
3451
|
ArraymodeItemsPerPage: [{ type: Input }]
|
|
1957
3452
|
};
|
|
1958
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXNfdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvZXMtdGFibGUvc3JjL2xpYi9lc190YWJsZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLFVBQVU7QUFDVixPQUFPLEVBQ0gsU0FBUyxFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQWEsaUJBQWlCLEVBQUUsdUJBQXVCLEVBQUUsS0FBSyxFQUNwRyxZQUFZLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBNEIsU0FBUyxFQUFjLGlCQUFpQixFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQ3pILE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFakUsaUJBQWlCO0FBQ2pCLE9BQU8sRUFBRSxjQUFjLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzlELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBSzNELFVBQVU7QUFDVixPQUFPLEVBQ1MsU0FBUyxFQUFFLFdBQVcsRUFBZSx3QkFBd0IsRUFDekUsZ0JBQWdCLEVBQWdCLFdBQVcsRUFBNEMsYUFBYSxFQUN2RyxNQUFNLFVBQVUsQ0FBQztBQUVsQiw4QkFBOEI7QUFDOUIsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzdELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN0RCxPQUFPLEVBQUUs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Szs2QkFHTCxLQUFLO3NDQUdMLEtBQUs7d0JBR0wsS0FBSzs0QkFHTCxLQUFLO3NDQUdMLEtBQUs7MkJBR0wsS0FBSzt5QkFHTCxLQUFLO2dDQU1MLEtBQUs7OEJBTUwsS0FBSzsrQkFHTCxLQUFLOzRCQUdMLEtBQUs7eUNBR0wsS0FBSzs0QkFHTCxLQUFLOzhCQUdMLEtBQUs7eUJBT0wsS0FBSzt3QkFHTCxLQUFLO2lDQUdMLEtBQUs7MENBR0wsS0FBSztnQ0FHTCxLQUFLO3dCQUdMLEtBQUs7d0JBR0wsS0FBSztxQkFHTCxLQUFLOzZCQUdMLEtBQUs7OEJBR0wsS0FBSzs4QkFPTCxLQUFLOzZCQU9MLEtBQUs7Z0NBR0wsS0FBSzs2QkFHTCxNQUFNOzhCQU1OLE1BQU07aUNBR04sTUFBTTt3QkFHTixNQUFNOzZCQUdOLE1BQU07MEJBTU4sTUFBTTs2QkFHTixNQUFNO2lDQUdOLE1BQU07K0JBT04sU0FBUyxTQUFDLGtCQUFrQixFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTs2QkFHL0MsU0FBUyxTQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7b0NBVXZDLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBBbmd1bGFyXHJcbmltcG9ydCB7XHJcbiAgICBDb21wb25lbnQsIGZvcndhcmRSZWYsIENvbnRlbnRDaGlsZHJlbiwgUXVlcnlMaXN0LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIElucHV0LFxyXG4gICAgRXZlbnRFbWl0dGVyLCBPdXRwdXQsIENvbnRlbnRDaGlsZCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYsIFZpZXdFbmNhcHN1bGF0aW9uLCBPcHRpb25hbCwgU2VsZiwgVGVtcGxhdGVSZWZcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5nQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuXHJcbi8vIENvbmZpZ3VyYXppb25pXHJcbmltcG9ydCB7IEhhc2hpbmdTZXJ2aWNlLCBVdGlsaXR5U2VydmljZSwgRXhwb3J0U2VydmljZSB9IGZyb20gJ0Blc2ZhZW56YS9leHRlbnNpb25zJztcclxuaW1wb3J0IHsgTG9jYWxpemF0aW9uU2VydmljZSB9IGZyb20gJ0Blc2ZhZW56YS9sb2NhbGl6YXRpb25zJztcclxuaW1wb3J0IHsgUHJlZmVyZW5jZXNTZXJ2aWNlIH0gZnJvbSAnQGVzZmFlbnphL3ByZWZlcmVuY2VzJztcclxuXHJcbi8vIFBsdWdpbnNcclxuaW1wb3J0IHsgQ29udGV4dE1lbnVDb21wb25lbnQgfSBmcm9tICdAZXNmYWVuemEvbmd4LWNvbnRleHRtZW51JztcclxuXHJcbi8vIE1vZGVsbGlcclxuaW1wb3J0IHtcclxuICAgIElBcHBTZWFyY2gsIEFwcFNlYXJjaCwgQXBwT3JkZXJpbmcsIEdlbmVyaWNJdGVtLCBFc1RhYmxlQ29sdW1uc0RlZmluaXRpb24sIENvcm5lck1lbnVPcHRpb24sXHJcbiAgICBSZXBvcnREZWZpbml0aW9uLCBSZXBvcnRSZXN1bHQsIFJlcG9ydE9yZGVyLCBSZXBvcnRDb2x1bW4sIEVzVGFibGVPcGVyYXRpb25EZWZpbml0aW9uLCBFc1RhYmxlQ29sdW1uXHJcbn0gZnJvbSAnLi9kb21haW4nO1xyXG5cclxuLy8gQ29tcG9uZW50aSBlIExvY2FsaXp6YXppb25lXHJcbmltcG9ydCB7IEVzVGQgfSBmcm9tICcuL2VzX3RkLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEVzVGggfSBmcm9tICcuL2VzX3RoLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEVzVGREaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZXMvZXNfdGQuZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgRXNUaERpcmVjdGl2ZSB9IGZyb20gJy4vZGlyZWN0aXZlcy9lc190aC5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBFc1RhYmxlTG9jIH0gZnJvbSAnLi9lc190YWJsZS5jb21wb25lbnQubG9jJztcclxuaW1wb3J0IHsgSXRlbXNTZWxlY3Rpb24gfSBmcm9tICcuL2RvbWFpbi9jbGFzc2VzL0l0ZW1zU2VsZWN0aW9uJztcclxuXHJcbi8qKiBDb21wb25lbnRlIGNoZSBwZXJtZXR0ZSBkaSByYXBwcmVzZW50YXJlIHVuYSBncmlnbGlhIGRpIHZhbG9yaSAqL1xyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnZXMtdGFibGUnLFxyXG4gICAgdmlld1Byb3ZpZGVyczogW3sgcHJvdmlkZTogTG9jYWxpemF0aW9uU2VydmljZSwgdXNlQ2xhc3M6IEVzVGFibGVMb2MgfV0sXHJcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9lc190YWJsZS5jb21wb25lbnQuc2NzcyddLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2VzX3RhYmxlLmNvbXBvbmVudC5odG1sJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgRXNUYWJsZUNvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkNoYW5nZXMge1xyXG5cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBjb25zdHJ1Y3RvcihAU2VsZigpIEBPcHRpb25hbCgpIHB1YmxpYyBuZ0NvbnRyb2w6IE5nQ29udHJvbCwgQE9wdGlvbmFsKCkgcHJpdmF0ZSBwcmVmU2VydmljZTogUHJlZmVyZW5jZXNTZXJ2aWNlLCBwdWJsaWMgbGM6IExvY2FsaXphdGlvblNlcnZpY2UsIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZiwgcHJpdmF0ZSBoYXNoRXh0czogSGFzaGluZ1NlcnZpY2UsIHByaXZhdGUgdXRpRXh0czogVXRpbGl0eVNlcnZpY2UsIHByaXZhdGUgZXhwRXh0czogRXhwb3J0U2VydmljZSkge1xyXG4gICAgICAgIGlmIChuZ0NvbnRyb2wpXHJcbiAgICAgICAgICAgIG5nQ29udHJvbC52YWx1ZUFjY2Vzc29yID0gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICAvKiogVmlldyBmaW5hbGUgc3UgY3VpIGJpbmRhcnNpIGxhdG8gRnJvbnRlbmQsIGlsIHRpcG8gcHXDsiBlc3NlcmUgSUFwcFNlYXJjaDxhbnk+IChwZXIgbGEgKip2aWV3TW9kZSoqKSwgYW55W10gKHBlciBsJyoqYXJyYXlNb2RlKiopIGUgUmVwb3J0RGVmaW5pdGlvbiBwZXIgbGEgKipyZXBvcnRNb2RlKiogKi9cclxuICAgIHB1YmxpYyBWaWV3OiBhbnkgPSBudWxsO1xyXG5cclxuICAgIC8qKiBNb2RlbGxvIGRhIGN1aSBsJ2VzLXRhYmxlIG1vc3RyYSBpIHB1bHNhbnRpIGRpIHBhZ2luYXppb25lIGluIGJhc3NvIGEgZGVzdHJhICovXHJcbiAgICBwdWJsaWMgYXJyYXlQdWxzYW50aTogYW55O1xyXG5cclxuICAgIC8qKiBJbmRpY2Egc2UgbCdlcy10YWJsZSBkZXZlIG1vc3RyYXJlIGlsIGNoZWNrIGdsb2JhbGUgbmVsbCdoZWFkZXIgcGVyIGZhcmUgaWwgXCJzZWxlemlvbmEgdHV0dG9cIiAqL1xyXG4gICAgcHVibGljIGdsb2JhbENoZWNrID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaWVuZSBkYSBjb250byBsJ3VsdGltbyBlbGVtZW50byBzZWxlemlvbmF0byBpbiBtb2RvIGRhIGZhcmUgcmFnaW9uYW1lbnRpIGRlbCB0aXBvXHJcbiAgICAgKiBcIkhvIHNlbGV6aW9uYXRvIHF1ZXN0bywgbCd1bHRpbW8gc2VsZXppb25hdG8gZXJhICoqbGFzdFNlbGVjdGVkKiosIGRldm8gc2VsZXppb25hcmUgdHV0dGkgcXVlbGxpIGluIG1lenpvXCIsIGFkIGVzZW1waW8gcGVyIGxhIHNlbGV6aW9uZSBtdWx0aXBsYVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGxhc3RTZWxlY3RlZDogYW55ID0gbnVsbDtcclxuXHJcbiAgICAvKiogQ29udGVnZ2lvIGludGVybm8gcGVyIGlsIG51bWVybyBkaSBlbGVtZW50aSBzZWxlemlvbmF0aSAqL1xyXG4gICAgcHVibGljIHNlbGVjdGVkT2JqZWN0cyA9IDA7XHJcblxyXG4gICAgLyoqIEluZGljYSBzZSDDqCBwb3NzaWJpbGUgZWZmZXR0dWFyZSB1bmEgc2VsZXppb25lIG1hc3NpdmEgKi9cclxuICAgIHB1YmxpYyBjYW5TZWxlY3RBbGwgPSBmYWxzZTtcclxuXHJcbiAgICAvKiogSW5kaWNhIHNlIGlsIGNvbXBvbmVudGUgc3RhIGdlc3RlbmRvIHVuIElBcHBTZWFyY2g8YW55PiAqL1xyXG4gICAgcHVibGljIHZpZXdNb2RlID0gZmFsc2U7XHJcblxyXG4gICAgLyoqIEluZGljYSBzZSBpbCBjb21wb25lbnRlIHN0YSBnZXN0ZW5kbyB1biBhbnlbXSAqL1xyXG4gICAgcHVibGljIGFycmF5TW9kZSA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiBJbmRpY2Egc2UgaWwgY29tcG9uZW50ZSBzdGEgZ2VzdGVuZG8gdW4gUmVwb3J0RGVmaW5pdGlvbiAqL1xyXG4gICAgcHVibGljIHJlcG9ydE1vZGUgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnRlbml0b3JlIGRlZ2xpIGVsZW1lbnRpIGRhIGxpc3RhcmUgbGF0byBpbnRlcmZhY2NpYSBkb3BvIHR1dHRlIGxlIGVsYWJvcmF6aW9uaSBkZWwgY2FzbyxcclxuICAgICAqIGdlbmVyYWxtZW50ZSBub24gc29ubyBhbHRybyBjaGUgdHV0dGkgZ2xpIG9nZ2V0dGkgZGEgcHJlc2VudGFyZSBjb24gaW4gcGnDuSBsJ2hhc2ggY2FsY29sYXRvIHBlciBpZGVudGlmaWNhcmUgMSBvZ2dldHRvIGNvbiBsYSBwcm9wcmlhIHJpZ2FcclxuICAgICAqL1xyXG4gICAgcHVibGljIGJvdW5kU291cmNlOiBhbnlbXSA9IFtdO1xyXG5cclxuICAgIC8qKiBTdGVzc2EgY29zYSBkZWxsYSAqKmJvdW5kU291cmNlKiosIHV0aWxpenphdGEgY29tZSBhcHBvZ2dpbyB0ZW1wb3JhbmVvIGludGVybm8gKi9cclxuICAgIHB1YmxpYyBUTVBCb3VuZFNvdXJjZTogYW55W10gPSBbXTtcclxuXHJcbiAgICAvKiogXCJGZXR0YVwiIGRpIG9nZ2V0dGkgdXRpbGl6emF0YSBuZWxsJ2VuZGxlc3Mgc2Nyb2xsLCBvZ25pIGVsZW1lbnRvIGRpIHF1ZXN0byBhcnJheSDDqCB1biBibG9jY2hldHRvIGRpIDEwMCBlbGVtZW50aSAqL1xyXG4gICAgcHVibGljIGJvdW5kU3ViU291cmNlczogYW55W10gPSBbXTtcclxuXHJcbiAgICAvKiogUXVlc3RhIGZ1bmdlIGRhIGluZGljYXRvcmUgcGVyIGdsaSBzbGljZSBpbnNlcml0aSwgbGEgbHVuZ2hlenphIGRvdnJlYmJlIGVzc2VyZSBjb3JyaXNwb25kZW50ZSBhICoqYm91bmRTdWJTb3VyY2VzKiogKi9cclxuICAgIHB1YmxpYyBhZGRlZFNsaWNlczogbnVtYmVyW10gPSBbXTtcclxuXHJcbiAgICAvKiogVmFyaWFiaWxlIGNoZSBpZGVudGlmaWNhIGlsIHZhbG9yZSBkZWwgXCJzZWxlemlvbmEgVHV0dG9cIiBuZWxsYSBwYWdpbmF6aW9uZSAqL1xyXG4gICAgcHVibGljIGRlZmF1bHRBbGxQYWdlT3ZlcnJpZGUgPSA5OTk5OTk7XHJcblxyXG4gICAgLyoqIEluZGljYSBzZSB1dGlsaXp6YXJlIGlsIHNpc3RlbWEgZGkgRW5kbGVzcyBTY3JvbGwgKi9cclxuICAgIHB1YmxpYyBVc2VFbmRsZXNzc2Nyb2xsOiBib29sZWFuO1xyXG5cclxuICAgIC8qKiBWYWxvcmkgZGVsbCdldmVudHVhbGUgcmVwb3J0IGluIHZpc3VhbGl6emF6aW9uZSAqL1xyXG4gICAgcHVibGljIFJlcG9ydFZhbHVlczogUmVwb3J0UmVzdWx0O1xyXG5cclxuICAgIC8qKiBTZXJ2ZSBwZXIgdGVuZXJlIGluIG1lbW9yaWEgaWwgY29udGVnZ2lvIHByZWNlZGVudGUgZSByZWN1cGVyYXJsbyBpbiBjYXNvIGRpdmVudGkgLTIgKHZlcmlmaWNhcmUgY29uIEFsZSBwZXJjaMOpIGxhIGxvZ2ljYSBkZWwgLTIpICovXHJcbiAgICBwdWJsaWMgcHJldmlvdXNDb3VudDogbnVtYmVyO1xyXG5cclxuICAgIC8qKiBJbmRpY2Egc2UgdXRpbGl6emFyZSBpbCBzaXN0ZW1hIGRpIGF1dG91cGRhdGUsIGNpb8OoIHVuIHRyaWdnZXIgdGltZS1penphdG8gaW4gYWx0byBhIGRlc3RyYSBkZWxsYSB0YWJlbGxhIGNoZSByaXBldGUgbGUgcmljZXJjaGUgb2duaSBYICoqc2Vjb25kcyoqICovXHJcbiAgICBwdWJsaWMgYXV0b1VwZGF0ZSA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiBOdW1lcm8gZGkgc2Vjb25kaSBkYSBmYXJlIHRyYXNjb3JyZXJlIGZyYSB1bmEgcmljZXJjYSBlIGwnYWx0cmEgKi9cclxuICAgIHB1YmxpYyBzZWNvbmRzID0gJzEwJztcclxuXHJcbiAgICAvKiogUmlmZXJpbWVudG8gYWxsJ0ludGVydmFsIGNoZSB2aWVuZSBnZW5lcmF0byBzZSAqKmF1dG9VcGRhdGUqKiDDqCBpbXBvc3RhdGEgYSB0cnVlIGluIG1vZG8gZGEgcG90ZXJsbyByaXB1bGlyZSAqL1xyXG4gICAgcHVibGljIHVwZGF0ZVRpbWVyOiBhbnk7XHJcblxyXG4gICAgLyoqIEltcG9zdGF0YSBhIHRydWUgb2duaSB2b2x0YSBjaGUgdmllbmUgYXZ2aWF0YSB1bmEgcmljZXJjYSwgZSBhIGZhbHNlIG9nbmkgdm9sdGEgY2hlIHVuIG51b3ZvIHZhbG9yZSB2aWVuZSByaWNldnV0byAqL1xyXG4gICAgcHVibGljIHJlc2VhcmNoSW5Qcm9ncmVzczogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiBNb2RlbGxvIHJhcHByZXNlbnRhbnRlIHVuIHNpbmdvbG8gdGQgZGVsbGEgdGFiZWxsYSwgZ2VuZXJhdG8gaW4gYmFzZSBhbGxlIGNvbmZpZ3VyYXppb25pIGUgYWdsaSBvZ2dldHRpIHJpY2V2dXRpICovXHJcbiAgICBwdWJsaWMgUm93VERzOiB7IFtjb250ZXh0OiBzdHJpbmddOiBFc1RkW10gfSA9IG51bGw7XHJcblxyXG4gICAgLyoqIE1vZGVsbG8gZGkgYXBwb2dnaW8gdGVtcG9yYW5lbyBwZXIgaSAqKlJvd1REcyoqICovXHJcbiAgICBwdWJsaWMgVE1QUm93VERzOiB7IFtjb250ZXh0OiBzdHJpbmddOiBFc1RkW10gfSA9IG51bGw7XHJcblxyXG4gICAgLyoqIE1vZGVsbG8gcmFwcHJlc2VudGFudGUgdW4gc2luZ29sbyB0aCBkZWxsYSB0YWJlbGxhLCBnZW5lcmF0byBpbiBiYXNlIGFsbGUgY29uZmlndXJhemlvbmkgZSBhZ2xpIG9nZ2V0dGkgcmljZXZ1dGkgKi9cclxuICAgIHB1YmxpYyBSb3dUSHM6IHsgSUQ6IHN0cmluZywgVmlzaWJsZTogYm9vbGVhbiwgQ2xhc3M6IHN0cmluZywgQ29udGVudDogc3RyaW5nLCBPcmRlcjogc3RyaW5nLCBPcmRlcmFibGU6IGJvb2xlYW4sIFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+LCBXcmFwOiBib29sZWFuIH1bXSA9IG51bGw7XHJcblxyXG4gICAgLyoqIE1vZGVsbG8gZGkgYXBwb2dnaW8gdGVtcG9yYW5lbyBwZXIgaSAqKlJvd1RIcyoqICovXHJcbiAgICBwdWJsaWMgVE1QUm93VEhzOiB7IEZpeGVkOiBib29sZWFuLCBJRDogc3RyaW5nLCBWaXNpYmxlOiBib29sZWFuLCBDbGFzczogc3RyaW5nLCBDb250ZW50OiBzdHJpbmcsIE9yZGVyOiBzdHJpbmcsIE9yZGVyYWJsZTogYm9vbGVhbiwgVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4sIFdyYXA6IGJvb2xlYW4gfVtdID0gbnVsbDtcclxuXHJcbiAgICAvKiogQ2FjaGUgcGVyIGkgcm91dGVyTGluayBnZW5lcmF0aSBuZWxsZSB0YWJlbGxlIGRpbmFtaWNoZSAqL1xyXG4gICAgcHVibGljIER5bmFtaWNUYWJsZVJvdXRlckxpbmtDYWNoZToge30gPSB7fTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIExpc3RhIGRlaSBjb250ZXN0aS4gVW4gY29udGVzdG8gbm9uIMOoIGFsdHJvIGNoZSB1biBoYXNoIHBhcnRpY29sYXJlIGNhbGNvbGF0byBzdSB1biBvZ2dldHRvIGNoZSBpZGVudGlmaWNhIHVuaXZvY2FtZW50ZSB0YWxlIG9nZ2V0dG8uXHJcbiAgICAgKlxyXG4gICAgICogT2dudW5vIGRpIHF1ZXN0aSBjb250ZXN0aSByYXBwcmVzZW50ZXLDoCBhIHN1YSB2b2x0YSwgdW5pdm9jYW1lbnRlLCB1bmEgcmlnYSBhbGwnaW50ZXJubyBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBSb3dDb250ZXh0czogYW55W10gPSBbXTtcclxuXHJcbiAgICAvKiogRGlyZXR0aXZlIGRpIG9yZGluYW1lbnRvIGRlbGxlIGNvbG9ubmUgKG5vbiBvcmRpbmFtZW50byBkZWkgZGF0aSBtYSBkZWxsZSBjb2xvbm5lIGluIHNlKSAqL1xyXG4gICAgcHVibGljIE9yZGVyRGlyZWN0aXZlczogc3RyaW5nW10gPSBbXTtcclxuXHJcbiAgICAvKiogQ29kaWNlIGRlbGwndWx0aW1vIG9nZ2V0dG8gc29sZXppb25hdG8gKi9cclxuICAgIHB1YmxpYyBsYXN0U2VsZWN0ZWRJdGVtSUQgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhIHNlIG9sdHJlIGFsbGUgY29sb25uZSBkaW5hbWljaGUgc3BlY2lmaWNoZSBkaSB1biB0aXBvIGRpIG9nZ2V0dG8gY2kgc29ubyBhbmNoZSBjb2xvbm5lIGRpbmFtaWNoZSBhZ2dpdW50ZSBkYWxsJ3V0ZW50ZVxyXG4gICAgICpcclxuICAgICAqIEVzLiB1bmEgY29sb25uYSBpbiBjdWkgbW9zdHJhcmUgc2VtcHJlIHVuIGljb25jaW5hXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBVc2VyRGVmaW5lZER5bmFtaWNDb2xzOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gICAgLyoqIEluZGljYSBjaGUgcXVlc3RvIMOoIGlsIHByaW1vIEJpbmQgZGVsbGEgdGFiZWxsYSwgdmllbmUgc2V0dGF0byBhIGZhbHNlIG5vbiBhcHBlbmEgaWwgcHJpbW8gYmluZCB2aWVuZSB0ZXJtaW5hdG8gY29uIHN1Y2Nlc3NvICovXHJcbiAgICBwdWJsaWMgRmlyc3RCaW5kOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgICAvKiogTGlzdGEgZGkgY29sb25uZSBjaGUgc2kgcG9zc29ubyB2aXN1YWxpenphcmUvb3JkaW5hcmUgZnJhIGRpIGxvcm8gKi9cclxuICAgIHB1YmxpYyBDb2x1bW5zTGlzdDogRXNUYWJsZUNvbHVtbltdID0gW107XHJcblxyXG4gICAgLyoqIFZhcmlhYmlsZSBkJ2FwcG9nZ2lvIHVzYXRhIGRhbGxhIGRpYWxvZyBkaSBzZWxlemlvbmUvbmFzY29uZGltZW50bywgcGVyIGV2aXRhcmUgZGkgZGFubmVnZ2lhcmUgKipDb2x1bW5zTGlzdCoqIGluIGNhc28gZGkgbW9kaWZpY2hlIHBvaSBhbm51bGxhdGUgKi9cclxuICAgIHB1YmxpYyBUTVBDb2x1bW5zTGlzdDogRXNUYWJsZUNvbHVtbltdID0gW107XHJcblxyXG4gICAgLyoqIFZhbG9yZSBkZWwgY2hlY2sgZ2xvYmFsZSBkaSB2aXNpYmlsaXTDoCB2YWxpZG8gcGVyIHR1dHRlIGxlIGNvbG9ubmUgaW4gKipDb2x1bW5zTGlzdCoqICovXHJcbiAgICBwdWJsaWMgZ2xvYmFsQ29sVmlzQ2hlY2sgPSBmYWxzZTtcclxuXHJcbiAgICAvKiogUXVlcnkgcGVyIHJlY3VwZXJhcmUgdHV0dGUgbGUgbnVvdmUgZGlyZXR0aXZlICBhc3NlZ25hdGkgYSBkaXJldHRpdmEgKFBlciBsYSBtb2RhbGl0w6AgZGluYW1pY2EgZGVsbCdlcy10YWJsZSkgKi9cclxuICAgIEBDb250ZW50Q2hpbGRyZW4oRXNUZERpcmVjdGl2ZSkgRXNUZHNEaXJlY3RpdmU6IFF1ZXJ5TGlzdDxFc1RkRGlyZWN0aXZlPjtcclxuXHJcbiAgICAvKiogUXVlcnkgcGVyIHJlY3VwZXJhcmUgdHV0dGkgZ2xpIGVzLXRkIGFzc2VnbmF0aSBhIGRpcmV0dGl2YSAoUGVyIGxhIG1vZGFsaXTDoCBkaW5hbWljYSBkZWxsJ2VzLXRhYmxlKSAqL1xyXG4gICAgQENvbnRlbnRDaGlsZHJlbihFc1RoRGlyZWN0aXZlKSBFc1Roc0RpcmVjdGl2ZTogUXVlcnlMaXN0PEVzVGhEaXJlY3RpdmU+O1xyXG5cclxuICAgIC8qKiBRdWVyeSBwZXIgcmVjdXBlcmFyZSB0dXR0aSBnbGkgZXMtdGggKi9cclxuICAgIEBDb250ZW50Q2hpbGRyZW4oZm9yd2FyZFJlZigoKSA9PiBFc1RoKSkgcHJpdmF0ZSBFc1RoczogUXVlcnlMaXN0PEVzVGg+O1xyXG5cclxuICAgIC8qKiBRdWVyeSBwZXIgcmVjdXBlcmFyZSB0dXR0aSBnbGkgZXMtdGQgKi9cclxuICAgIEBDb250ZW50Q2hpbGRyZW4oZm9yd2FyZFJlZigoKSA9PiBFc1RkKSkgcHJpdmF0ZSBFc1RkczogUXVlcnlMaXN0PEVzVGQ+O1xyXG5cclxuICAgIC8qKiBRdWVyeSBwZXIgcmVjdXBlcmFyZSBsZSBpbmZvcm1hemlvbmkgZGVsIGJvZHkgKHB1bnRvIGRlbGxhIHRhYmVsbGEgZG92ZSB2ZW5nb25vIG1vc3RyYXRlIGxlIHJpZ2hlKSAqL1xyXG4gICAgQENvbnRlbnRDaGlsZCgnYm9keScsIHsgc3RhdGljOiBmYWxzZSB9KSBwdWJsaWMgYm9keVJlZjogYW55O1xyXG5cclxuICAgIC8qKiBRdWVyeSBwZXIgcmVjdXBlcmFyZSBsZSBpbmZvcm1hemlvbmkgZGVsbCdoZWFkZXIgKHB1bnRvIGRlbGxhIHRhYmVsbGEgZG92ZSB2ZW5nb25vIG1vc3RyYXRlIGxlIGludGVzdGF6aW9uaSBkZWxsZSByaWdoZSkgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoJ2hlYWRlcicsIHsgc3RhdGljOiBmYWxzZSB9KSBwdWJsaWMgaGVhZGVyUmVmOiBhbnk7XHJcblxyXG4gICAgLyoqIFF1ZXJ5IHBlciByZWN1cGVyYXJlIGxlIGluZm9ybWF6aW9uaSBzdWwgcmFnZ3J1cHBhbWVudG8gZGVnbGkgaGVhZGVyICovXHJcbiAgICBAQ29udGVudENoaWxkKCdoZWFkZXJHcm91cCcsIHsgc3RhdGljOiBmYWxzZSB9KSBwdWJsaWMgaGVhZGVyR3JvdXBSZWY6IGFueTtcclxuXHJcbiAgICAvKiogUXVlcnkgcGVyIHJlY3VwZXJhcmUgbGUgaW5mb3JtYXppb25pIHN1bCByYWdncnVwcGFtZW50byBkaSBzZWNvbmRvIGxpdmVsbG8gZGVnbGkgaGVhZGVyICovXHJcbiAgICBAQ29udGVudENoaWxkKCdzZWNvbmRhcnlIZWFkZXJHcm91cCcsIHsgc3RhdGljOiBmYWxzZSB9KSBwdWJsaWMgc2Vjb25kYXJ5SGVhZGVyR3JvdXBSZWY6IGFueTtcclxuXHJcbiAgICAvKiogT3B6aW9uaSBleHRyYSBjaGUgZGV2b25vIGFwcGFyaXJlIG5lbCBNZW7DuSBjb250ZXN0dWFsZSBpbiBhbHRvIGEgZGVzdHJhLCByaWNoaWFtYXRvIGRhaSAzIHBhbGxpbmkgdmVydGljYWxpICovXHJcbiAgICBASW5wdXQoKSBDb3JuZXJNZW51T3B0aW9uczogQ29ybmVyTWVudU9wdGlvbltdID0gbnVsbDtcclxuXHJcbiAgICAvKiogSW5kaWNhIHNlIGRldidlc3NlcmUgcG9zc2liaWxlIGVmZmV0dHVhcmUgaWwgcmVzaXplIGRlbGxlIGNvbG9ubmUgKi9cclxuICAgIEBJbnB1dCgpIENvbHVtbnNSZXNpemFibGU6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKiBJbmRpY2Egc2UgZGV2J2Vzc2VyZSBkaXNwb25pYmlsZSBpbCBzaXN0ZW1hIGRpIGFnZ2lvcm5hbWVudG8gYXV0b21hdGljbyAqL1xyXG4gICAgQElucHV0KCkgQXV0b1VwZGF0ZTogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqIEluZGljYSBzZSBsYSB0YWJlbGxhIChjb25maWd1cmF0YSBjb24gKipVc2VDdXN0b21DZWxscyoqKSBkZXZlIG1ldHRlcnNpIGluIGFzY29sdG8gcGVyIGkgY2xpY2sgc3VsbGUgY2VsbGUgZGVzaWRlcmF0ZVxyXG4gICAgICogXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBVdGlsaXp6YXJlIGwnSW5wdXQgKipUZW1wbGF0ZSoqIGRlbGxlIGVzLXRkIGUgYXNzZWduYXJlIHVuIHRlbXBsYXRlIGNvbiB0dXR0aSBpIGJpbmRpbmcgY2hlIHNpIHZ1b2xlIGFpIGNsaWNrXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIFVzZUN1c3RvbUNlbGxBY3Rpb25zOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZGljYSBsZSBjZWxsZSBkZXNpZGVyYXRlIHN1IGN1aSBpbnRlcmNldHRhcmUgaSBjbGljay4gQXR0aXZhIHNvbG8gcXVhbmRvICoqVXNlQ3VzdG9tQ2VsbEFjdGlvbnMqKiDDqCB0cnVlLlxyXG4gICAgICogT2duaSBjZWxsYSBkZXYnZXNzZXJlIHNlcGFyYXRhIGRhbGxhIHN1Y2Nlc3NpdmEgZGFsIGNhcmF0dGVyZSBkZWwgU2ltb2xlb246XHJcbiAgICAgKlxyXG4gICAgICogRXMsIFwiTWlhQ2VsbGExwqdNaWFDZWxsYTJcIlxyXG4gICAgICogXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBVdGlsaXp6YXJlIGwnSW5wdXQgKipUZW1wbGF0ZSoqIGRlbGxlIGVzLXRkIGUgYXNzZWduYXJlIHVuIHRlbXBsYXRlIGNvbiB0dXR0aSBpIGJpbmRpbmcgY2hlIHNpIHZ1b2xlIGFpIGNsaWNrXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIEN1c3RvbUNlbGxBY3Rpb25zT24gPSAnJztcclxuXHJcbiAgICAvKiogU2VydmUgcGVyIGRlY2lkZXJlIGRpIGxhbmNpYXJlIG8gbWVubyBpbCAqKmV2ZW50LnN0b3BQcm9wYWdhdGlvbigpKiogYWwgdGVybWluZSBkZWxsYSBnZXN0aW9uZSBkZWxsJ2V2ZW50byAqL1xyXG4gICAgQElucHV0KCkgQ2VsbEFjdGlvblByb3BhZ2F0ZXMgPSB0cnVlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVjaWRlIHNlIHV0aWxpenphcmUgbyBtZW5vIGxlIEN1c3RvbUNlbGxzLiBJbXBvc3RhbmRvbG8gYSAqKnRydWUqKiBsJ2VzLXRhYmxlIGRpdmVudGEgaW4gZ3JhZG8gZGkgZ2VzdGlyZSBuYXRpdmFtZW50ZTpcclxuICAgICAqXHJcbiAgICAgKiAxKSBPcmRpbmFtZW50byBlIHZpc2liaWxpdMOgIGRlbGxlIGNvbG9ubmVcclxuICAgICAqXHJcbiAgICAgKiAyKSBPcmRpbmFtZW50byBkZWkgZGF0aVxyXG4gICAgICpcclxuICAgICAqIDMpIE1vZGFsaXTDoCBHZXJhcmNoaWNhXHJcbiAgICAgKlxyXG4gICAgICogZWNjLi4uXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIFVzZUN1c3RvbUNlbGxzOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKiogUGVybWV0dGUgZGkgaW1wb3N0YXJlIGwnYWx0ZXp6YSBtYXNzaW1hIGRlbGxhIHRhYmVsbGEuIFNlIG51bGwgbGEgZGltZW5zaW9uZSBzaSBhZGF0dGEgYWwgbnVtZXJvIGRpIGVsZW1lbnRpIGF0dHVhbG1lbnRlIGluIHZpc3VhbGl6emF6aW9uZSAqL1xyXG4gICAgQElucHV0KCkgTWF4SGVpZ2h0OiBudW1iZXIgPSBudWxsO1xyXG5cclxuICAgIC8qKiBDbGFzc2kgZGEgYXBwbGljYXJlIGFsbGEgdGFiZWxsYSBvbHRyZSBhIHF1ZWxsZSBnZXN0aXRlIGF1dG9ub21hbWVudGUgZGFsbGEgbGlicmVyaWEgKi9cclxuICAgIEBJbnB1dCgpIENsYXNzID0gJyc7XHJcblxyXG4gICAgLyoqIFBlcm1ldHRlIG8gbWVubyBsJ2V4cG9ydCBpbiBmb3JtYXRvIFhMU1ggKi9cclxuICAgIEBJbnB1dCgpIFhMU1hFeHBvcnQ6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKiBQZXJtZXR0ZSBvIG1lbm8gbCdleHBvcnQgaW4gZm9ybWF0byBDU1YgKi9cclxuICAgIEBJbnB1dCgpIENTVkV4cG9ydCA9IHRydWU7XHJcblxyXG4gICAgLyoqIFBlcm1ldHRlIGRpIHZpc3VhbGl6emFyZSBvIG1lbm8gbCdvcHppb25lIGRpIHBhZ2luYXppb25lIFwiVHV0dGlcIiAqL1xyXG4gICAgQElucHV0KCkgQWxsU2VhcmNoID0gdHJ1ZTtcclxuXHJcbiAgICAvKiogRGltaW51aXNjZSBnbGkgc3BhemkgZnJhIHVuYSBjZWxsYSBlIGwnYWx0cmEsIGUgaW50ZXJuYW1lbnRlIGlsIHBhZGRpbmcgZGVsIGZvbnQgaW4gbW9kbyBkYSBwcmVzZW50YXJlIG1vbHRpIHBpw7kgZGF0aSBpbiB1bid1bmljYSBwYWdpbmEgKi9cclxuICAgIEBJbnB1dCgpIEhpZ2hDZWxsRGVuc2l0eTogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqIEFiaWxpdGEgbyBtZW5vIGxhIHBvc3NpYmlsaXTDoCBkaSBzZWxlemlvbmFyZSBvZ2dldHRpICovXHJcbiAgICBASW5wdXQoKSBTZWxlY3Rpb246IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKiBNb3N0cmEgbyBtZW5vIHVuIG1lc3NhZ2dpbyBkaSBMb2FkaW5nIGFsIHByaW1vIGNhcmljYW1lbnRvIGRlbGxhIHRhYmVsbGEgKi9cclxuICAgIEBJbnB1dCgpIFNob3dMb2FkaW5nT25Cb290c3RyYXA6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKiBTZSBpbXBvc3RhdG8gYSAqKnRydWUqKiBhZ2dpdW5nZSB1bmEgY29sb25uYSBjb24gcHVsc2FudGUgZGkgZWxpbWluYXppb25lIHBlciBlZmZldHR1YXJlIGwnZWxpbWluYSBkZWxsJ29nZ2V0dG8gcmVsYXRpdm8gKi9cclxuICAgIEBJbnB1dCgpIFJlbW92YWw6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29uZGl6aW9uZSBjaGUgbmFzY29uZGUgbCdpY29uYSBkaSBlbGltaW5hemlvbmUgaW5zZXJpdGEgaW1wb3N0YW5kbyAqKlJlbW92YWwqKiBhIHRydWUgcXVhbG9yYSBsYSBjb25kaXppb25lIG5vbiB2ZW5pc3NlIHJpc3BldHRhdGFcclxuICAgICAqXHJcbiAgICAgKiBDb21lIGNvbmRpemlvbmUgc2kgY29uc2lkZXJhIHVuIHNlbXBsaWNlIGNhbXBvIHN1IGN1aSBlZmZldHR1YXJlIHVuIGNvbnRyb2xsbyBib29sZWFubywgY29tZSBhZCBlc2VtcGlvIFwiY2FucmVtb3ZlXCJcclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgUmVtb3ZhbENvbmRpdGlvbiA9ICcnO1xyXG5cclxuICAgIC8qKiBJbmRpY2Egc2UgYWJpbGl0YXJlIGxhIHBvc3NpYmlsaXTDoCBkaSBlc3BvcnRhcmUgbGEgdmlzdGEgZGF0aSBhdHR1YWxlICovXHJcbiAgICBASW5wdXQoKSBFeHBvcnQ6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKiBJbmRpY2Egc2UgcGVybWV0dGVyZSBsYSBzZWxlemlvbmUgbXVsdGlwbGEgV2luZG93cy1saWtlIGNsaWNjYW5kbyB1biBvZ2dldHRvIGUgZmFjZW5kbyBwb2kgU2hpZnQgKyBjbGljayBzdSB1biBvZ2dldHRvIHN1Y2Nlc3Npdm8gKi9cclxuICAgIEBJbnB1dCgpIFNoaWZ0Q2xpY2s6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKiBNb3N0cmEgbyBuYXNjb25kZSBsZSBpbmZvcm1hemlvbmkgZGkgcGFnaW5hemlvbmUsIHNpYSBpIHB1bHNhbnRpLCBzaWEgaWwgc2VsZXR0b3JlIGRlZ2xpIG9nZ2V0dGkgcGVyIHBhZ2luYSAqL1xyXG4gICAgQElucHV0KCkgU2hvd1BhZ2luZyA9IHRydWU7XHJcblxyXG4gICAgLyoqIEluZGljYSBzZSBuYXNjb25kZXJlIG8gbW9zdHJhcmUgaWwgY29tcG9uZW50ZSBkaSBwYWdpbmF6aW9uZSAqL1xyXG4gICAgQElucHV0KCkgSGlkZVBhZ2luZzogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqIEluZGljYSBzZSBuYXNjb25kZXJlIG8gbW9zdHJhcmUgaWwgY29udGVnZ2lvIGRlZ2xpIGVsZW1lbnRpIHRyb3ZhdGkgKi9cclxuICAgIEBJbnB1dCgpIEhpZGVQYWdpbmdDb3VudDogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqIEluZGljYSBzZSBuYXNjb25kZXJlIG8gbW9zdHJhcmUgaSBwdWxzYW50aSBkaSBwYWdpbmF6aW9uZSAqL1xyXG4gICAgQElucHV0KCkgSGlkZVBhZ2luZ0J1dHRvbnM6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKiBSaWZlcmltZW50byBhbCBDb250ZXh0TWVudSAobmd4LWNvbnRleHRtZW51KSBhc3NvY2lhdG8gYWwgY2xpY2sgZGVzdHJvIGRpIHVubyBvIHBpw7kgZWxlbWVudGkgc2VsZXppb25hdGkgbmVsbGEgdGFiZWxsYSAqL1xyXG4gICAgQElucHV0KCkgQ29udGV4dE1lbnU6IENvbnRleHRNZW51Q29tcG9uZW50ID0gbnVsbDtcclxuXHJcbiAgICAvKiogTm9tZSBkZWxsJ2VzcG9ydGF6aW9uZSBnZW5lcmF0YSBkYSBxdWVzdGEgdGFiZWxsYSAqL1xyXG4gICAgQElucHV0KCkgRXhwb3J0RmlsZU5hbWUgPSAnRXhwb3J0LmNzdic7XHJcblxyXG4gICAgLyoqIENsYXNzZSAoSFRNTCkgZGkgZGVmYXVsdCBkZWxsYSB0YWJlbGxhICovXHJcbiAgICBASW5wdXQoKSBUYWJsZUNsYXNzID0gJ3RhYmxlIHRhYmxlLXN0cmlwZWQgdGFibGUtaG92ZXIgdGFibGUtc20nO1xyXG5cclxuICAgIC8qKiBUZXN0byBkYSB2aXN1YWxpenphcmUgbmVsIGNvbnRlZ2dpby4gRGkgZGVmYXVsdDogXCJPZ2dldHRpIHNlbGV6aW9uYXRpXCIgKi9cclxuICAgIEBJbnB1dCgpIENvdW50TGFiZWw6IHN0cmluZyA9IHRoaXMubGMubG9jKCdGb3VuZCBvYmplY3RzJyk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGdW56aW9uZSBkYSB1dGlsaXp6YXJlIGluIGVzcG9ydGF6aW9uZS4gTmVsIGZvcm1hdG8gXCJSZXBvcnRcIiBhdnLDoCB1biB1bmljbyBwYXJhbWV0cm8gXCJGb3JtYXRvXCIgZSBuZXNzdW4gdmFsb3JlIGRpIHJpdG9ybm8uXHJcbiAgICAgKlxyXG4gICAgICogTmVsIGZvcm1hdG8gXCJWaWV3XCIgaGEgY29tZSBwYXJhbWV0cm8gdW5hIGNhbGxiYWNrIGNvbiBpIGRhdGkgY29tcGxldGkgZGEgZXNwb3J0YXJlIChkYXRvIGNoZSBkaSBkZWZhdWx0IGxhIHJpY2VyY2Egw6ggcGFnaW5hdGEpXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIEV4cG9ydEZ1bmN0aW9uOiBhbnk7XHJcblxyXG4gICAgLyoqIEluZGljYSBsYSBwcmVzZW56YSBkaSByYWdncnVwcGFtZW50aSBhIGxpdmVsbG8gZGkgaGVhZGVyICovXHJcbiAgICBASW5wdXQoKSBIYXNIZWFkZXJHcm91cDogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqIEluZGljYSBsYSBwcmVzZW56YSBkaSByYWdncnVwcGFtZW50aSBhIGxpdmVsbG8gZGVsIHJhZ2dydXBwYW1lbnRvIHByZWNlZGVudGVtZW50ZSBlc2lzdGVudGUsIGNoaWFyYW1lbnRlIMOoIGluc2Vuc2F0YSBzZW56YSAqKkhhc0hlYWRlckdyb3VwKiogKi9cclxuICAgIEBJbnB1dCgpIEhhc1NlY29uZGFyeUhlYWRlckdyb3VwOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKiogVXRpbGl6emF0byBwZXIgZGl2aWRlcmUgbGEgc29yZ2VudGUgaW4gbW9kYWxpdMOgIEVuZGxlc3NTY3JvbGwgKi9cclxuICAgIEBJbnB1dCgpIFNsaWNlU2l6ZSA9IDEwMDtcclxuXHJcbiAgICAvKiogRGVjaWRlIHNlIHV0aWxpenphcmUgbGEgbW9kYWxpdMOgIGRpIEVuZGxlc3NTY3JvbGwgKi9cclxuICAgIEBJbnB1dCgpIEVuZGxlc3NTY3JvbGw6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKiBRdWFsb3JhICoqRW5kbGVzc1Njcm9sbCoqIGZvc3NlIHRydWUsIGluZGljYSBzZSB1dGlsaXp6YXJlIHF1ZXN0YSBtb2RhbGl0w6Agc29sbyBxdWFuZG8gc2kgY2VyY2EgcGVyIFwiVHV0dGlcIiBvIGluIGdlbmVyYWxlICovXHJcbiAgICBASW5wdXQoKSBFbmRsZXNzU2Nyb2xsT25seUZvckFsbCA9IHRydWU7XHJcblxyXG4gICAgLyoqIEluZGljYSBzZSBuYXNjb25kZXJlIGdsaSBIZWFkZXIgZGVsbGEgdGFiZWxsYSAqL1xyXG4gICAgQElucHV0KCkgSGVhZGVySGlkZGVuOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKiogSW5kaWNhIHNlIG5hc2NvbmRlcmUgaWwgQm9keSBkZWxsYSB0YWJlbGxhICovXHJcbiAgICBASW5wdXQoKSBCb2R5SGlkZGVuOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZGljYSBzZSBsYSBzZWxlemlvbmUgw6ggdGVtcG9yYW5lYW1lbnRlIGRpc2FiaWxpdGF0YS4gUmlzcGV0dG8gYWxsJ0lucHV0ICoqU2VsZWN0aW9uKiogY2hlIHZpc2l2YW1lbnRlIGdlc3Rpc2NlIHNlIGNpIHNvbm8gbyBubyBnbGkgaW5wdXQgZGkgc2VsZXppb25lLFxyXG4gICAgICogcXVlc3RvIElucHV0IGdlc3Rpc2NlIHNlIHF1ZXN0aSBpbnB1dCBzb25vIGFiaWxpdGF0aSBvIG1lbm9cclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgU2VsZWN0aW9uRGlzYWJsZWQ6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhIHNlIGZvcnphcmUgaWwgc2lzdGVtYSBkaSBzZWxlemlvbmUgYSBnZXN0aXJlIHVuIGVsZW1lbnRvIHBlciB2b2x0YS5cclxuICAgICAqIFNlbGV6aW9uYXJlIHVuJ2FsdHJhIHJpZ2EgY29uIHVuYSBnacOgIHNlbGV6aW9uYXRhIGFwcGxpY2hlcsOgIGxhIHNlbGV6aW9uZSBhbGxhIG51b3ZhIHJpZ2EsIHJpbXVvdmVuZG9sYSBkYWxsJ2F0dHVhbGVcclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgU2luZ2xlU2VsZWN0aW9uOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKiogQ2FsbGJhY2sgY2hlIGRhdG8gdW4gb2dnZXR0byByZXNpdHVpc2NlIGwnZXZlbnR1YWxlIGNsYXNzZSBkYSBhcHBsaWNhcmUgYWxsYSByaWdhIGNvbGxlZ2F0YSBhbGwnb2dnZXR0byAqL1xyXG4gICAgQElucHV0KCkgUm93Q2xhc3NBc3NpZ25lcjogYW55ID0gbnVsbDtcclxuXHJcbiAgICAvKiogUGVybWV0dGUgZGkgb3JkaW5hcmUgaSBkYXRpIGluIG1hbmllcmEgZGlzY2VuZGVudGUgbyBhc2NlbmRlbnRlICovXHJcbiAgICBASW5wdXQoKSBPcmRlckJ5Q29sdW1uOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKiogUGVybWV0dGUgZGkgYXZlcmUgcGnDuSBkaXJldHRpdmUgZGkgb3JkaW5hbWVudG8gZGVpIGRhdGkgKi9cclxuICAgIEBJbnB1dCgpIE11bHRpcGxlT3JkZXJpbmdEaXJlY3RpdmVzID0gdHJ1ZTtcclxuXHJcbiAgICAvKiogUGVybWV0dGUgZGkgbmFzY29uZGVyZSBsZSBjb2xvbm5lIGluIGJhc2UgYWxsZSBzZWxlemlvbmkgZWZmZXR0dWF0ZSBkYWwgTWVuw7kgY29udGVzdHVhbGUgaW4gYWx0byBhIGRlc3RyYSAqL1xyXG4gICAgQElucHV0KCkgSGlkZGVuQ29sdW1uczogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqIFBlcm1ldHRlIGRpIHJpb3JkaW5hcmUgbGUgY29sb25uZSBpbiBiYXNlIGFsbGUgaW1wb3N0YXppb25pIGVmZmV0dHVhdGUgZGFsIE1lbsO5IGNvbnRlc3R1YWxlIGluIGFsdG8gYSBkZXN0cmEgKi9cclxuICAgIEBJbnB1dCgpIENvbHVtbnNPcmRlcmluZzogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFdmVudHVhbGUgc3VwcG9ydG8gYWxsZSByaWNlcmNoZSBhcHBsaWNhdGUgYWxsYSBtb2RhbGl0w6AgQXJyYXlcclxuICAgICAqXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBVdGlsaXp6YXRvIHNvbG8gcGVyIHVuIGNhc28gcGFydGljb2xhcmUgZGVsIE1ldGVyaW5nXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIFNlYXJjaFZpZXcgPSBudWxsIGFzIElBcHBTZWFyY2g8YW55PjtcclxuXHJcbiAgICAvKiogQWJpbGl0YSBvIGRpc2FiaWxpdGEgaWwgc2lzdGVtYSBjaGUgcGVybWV0dGUgZGkgc2VsZXppb25hcmUgdHV0dGkgZ2xpIGVsZW1lbnRpIG5lbGxhIHZpc3RhICovXHJcbiAgICBASW5wdXQoKSBTZWxlY3RBbGw6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKiBTaW11bGEgbGEgcGFnaW5hemlvbmUgYW5jaGUgcGVyIGxlIHRhYmVsbGUgY2hlIGZ1bnppb25hbm8gaW4gbW9kYWxpdMOgIEFycmF5ICovXHJcbiAgICBASW5wdXQoKSBVc2VBcnJheU1vZGVQYWdpbmcgPSB0cnVlO1xyXG5cclxuICAgIC8qKiBEZWZpbml6aW9uZSBkaSBjb2xvbm5lIGRpbmFtY2hlIHBlciBsYSBtb2RhbGl0w6AsIGFwcHVudG8sIGRpbmFtaWNhICovXHJcbiAgICBASW5wdXQoKSBEeW5hbWljUm93Q29sdW1uc0RlZmluaXRpb246IEVzVGFibGVDb2x1bW5zRGVmaW5pdGlvbltdID0gbnVsbDtcclxuXHJcbiAgICAvKiogSW5kaWNhIG9wZXJhemlvbmkgZGluYW1pY2hlIGdlbmVyaWNoZSBjaGUgcG9zc29ubyBlc3NlcmUgZWZmZXR0dWF0ZSBwZXIgcmlnYS4gQXBwYWlvbm8gY29tZSBjb2xvbm5lIGV4dHJhIHN1bCBsYXRvIHNpbmlzdHJvIGRlbGxhIHRhYmVsbGEgKi9cclxuICAgIEBJbnB1dCgpIER5bmFtaWNPcGVyYXRpb25zOiBFc1RhYmxlT3BlcmF0aW9uRGVmaW5pdGlvbltdID0gW107XHJcblxyXG4gICAgLyoqIEluZGljYSBzZSB2aXN1YWxpenphcmUgaSBkYXRpIGluIG1hbmllcmEgZ2VyYXJjaGljYSAqL1xyXG4gICAgQElucHV0KCkgSGllcmFyY2h5OiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKiogTm9tZSBkZWxsYSBwcm9wcmlldMOgIGNoZSBjb250aWVuZSBsJ0lEIGRlbCBwYWRyZS4gRGEgdXRpbGl6emFyZSBzZSAqKkhpZXJhcmNoeSoqIMOoIGltcG9zdGF0byAqL1xyXG4gICAgQElucHV0KCkgUGFyZW50S2V5ID0gJyc7XHJcblxyXG4gICAgLyoqIE5vbWUgZGVsbGEgcHJvcHJpZXTDoCBjaGUgY29udGllbmUgbCdJRCBkZWxsJ29nZ2V0dG8gYXR0dWFsZS4gRGEgdXRpbGl6emFyZSBzZSAqKkhpZXJhcmNoeSoqIMOoIGltcG9zdGF0byAqL1xyXG4gICAgQElucHV0KCkgT3duS2V5ID0gJyc7XHJcblxyXG4gICAgLyoqIEluZGljYSBzZSBwYXJ0aXJlIGNvbiB1biBhbGJlcm8gZXNwYW5zby4gRGEgdXRpbGl6emFyZSBzZSAqKkhpZXJhcmNoeSoqIMOoIGltcG9zdGF0byAqL1xyXG4gICAgQElucHV0KCkgU3RhcnRzRXhwYW5kZWQgPSB0cnVlO1xyXG5cclxuICAgIC8qKiBJbmRpY2Egc2UgZWZmZXR0dWFyZSBpbCBzYWx2YXRhZ2dpbyBkZWxsZSBwcmVmZXJlbnplIGRpIHJpY2VyY2EgKi9cclxuICAgIEBJbnB1dCgpIFNhdmVQcmVmZXJlbmNlczogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTb3JnZW50ZSBkYXRpIHNlY29uZGFyaWFcclxuICAgICAqXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBVdGlsaXp6YXRvIHNvbG8gcGVyIHVuIGNhc28gcGFydGljb2xhcmUgZGVsIE1ldGVyaW5nXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIFNlY29uZGFyeVNvdXJjZTogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTb3JnZW50ZSBkYXRpIHNlY29uZGFyaWFcclxuICAgICAqXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBVdGlsaXp6YXRvIHNvbG8gcGVyIHVuIGNhc28gcGFydGljb2xhcmUgZGVsIE1ldGVyaW5nXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIFRlcnRpYXJ5U291cmNlOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKiogSW5kaWNhIHNlIHV0aWxpenphcmUgbGEgY2FjaGUgZGkgc2VsZXppb25lIGNoZSBwZXJtZXR0ZSBkaSBtYW50ZW5lcmUgZ2xpIHN0YXRpIGRpIHNlbGV6aW9uZSBkZWkgdmFyaSBvZ2dldHRpIG5hdmlnYW5kbyBkYSB1bmEgcGFnaW5hIGFsbCdhbHRyYSAqL1xyXG4gICAgQElucHV0KCkgVXNlU2VsZWN0aW9uQ2FjaGUgPSB0cnVlO1xyXG5cclxuICAgIC8qKiBFdmVudG8gY2hlIHZpZW5lIHJpY2hpYW1hdG8gYWwgY2FtYmlvIGRpIG9yaWRuYW1lbnRvIGRpIHVuYSBjb2xvbm5hICovXHJcbiAgICBAT3V0cHV0KCkgb25PcmRlckNoYW5nZWQ6IEV2ZW50RW1pdHRlcjxBcHBPcmRlcmluZz4gPSBuZXcgRXZlbnRFbWl0dGVyPEFwcE9yZGVyaW5nPigpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXZlbnRvIGNoZSB2aWVuZSByaWNoaWFtYXRvIHF1YW5kbyBsJ2VzLXRhYmxlIHJpdGllbmUgc2lhIG5lY2Vzc2FyaW8gcmktZWZmZXR0dWFyZSBsYSByaWNlcmNhLlxyXG4gICAgICogSWwgYm9vbGVhbm8gZGVsbCdldmVudG8gaW5kaWNhIHNlIHZpZW5lIHN1Z2dlcml0byBkaSByZXNldHRhcmUgbGEgcGFnaW5hIG8gbWVub1xyXG4gICAgICovXHJcbiAgICBAT3V0cHV0KCkgb25TZWFyY2hSZXF1ZXN0OiBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4gPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XHJcblxyXG4gICAgLyoqIEV2ZW50byBjaGUgcGFydGUgYWQgb2duaSBtb2RpZmljYSBkaSBcImNoZWNrYWdnaW9cIiBpbiBmb3JtYSBkaSBjb21vZG8gYXJyYXkuIEVzcG9uZSBsJ29nZ2V0dG8gY29uIGxvIHN0YXRvIGRpIGNoZWNrIGF0dHVhbGUgKi9cclxuICAgIEBPdXRwdXQoKSBvblNlbGVjdGlvbkNoYW5nZWQ6IEV2ZW50RW1pdHRlcjxJdGVtc1NlbGVjdGlvbjxhbnk+PiA9IG5ldyBFdmVudEVtaXR0ZXI8SXRlbXNTZWxlY3Rpb248YW55Pj4oKTtcclxuXHJcbiAgICAvKiogRXZlbnRvIHJpY2hpYW1hdG8gYWxsJ2VsaW1pbmF6aW9uZSBkaSB1biBvZ2dldHRvICovXHJcbiAgICBAT3V0cHV0KCkgb25SZW1vdmFsOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICAgIC8qKiBFdmVudG8gcmljaGlhbWF0byBhbGwnYW5udWxsYW1lbnRvIGRpIHVuJ2VsaW1pbmF6aW9uZSAqL1xyXG4gICAgQE91dHB1dCgpIG9uQWJvcnRSZW1vdmFsOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICAgIC8qKiBFdmVudG8gcmljaGlhbWF0byBhbCBjbGljayBzdSB1bmEgY2VsbGEgcXVhbmRvICoqVXNlQ3VzdG9tQ2VsbEFjdGlvbnMqKiDDqCBhdHRpdm8gXHJcbiAgICAgKiBcclxuICAgICAqIEBkZXByZWNhdGVkIFV0aWxpenphcmUgbCdJbnB1dCAqKlRlbXBsYXRlKiogZGVsbGUgZXMtdGQgZSBhc3NlZ25hcmUgdW4gdGVtcGxhdGUgY29uIHR1dHRpIGkgYmluZGluZyBjaGUgc2kgdnVvbGUgYWkgY2xpY2tcclxuICAgICAqL1xyXG4gICAgQE91dHB1dCgpIG9uQ2VsbENsaWNrOiBFdmVudEVtaXR0ZXI8eyBjb2x1bW46IHN0cmluZywgbW9kZWw6IGFueSB9PiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBjb2x1bW46IHN0cmluZywgbW9kZWw6IGFueSB9PigpO1xyXG5cclxuICAgIC8qKiBFdmVudG8gcmljaGlhbWF0byBxdWFuZG8gc2kgY2xpY2NhIHN1IHVuIG9wemlvbmUgZGVmaW5pdGEgbmVsbGUgKipDb3JuZXJNZW51T3B0aW9ucyoqICovXHJcbiAgICBAT3V0cHV0KCkgb25Db3JuZXJBY3Rpb246IEV2ZW50RW1pdHRlcjx7IGlkOiBzdHJpbmcsIGVzdGFibGU6IGFueSB9PiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBpZDogc3RyaW5nLCBlc3RhYmxlOiBhbnkgfT4oKTtcclxuXHJcbiAgICAvKiogRXZlbnRvIHJpY2hpYW1hdG8gcXVhbmRvIHNpIGNsaWNjYSBzdSB1biBvcHppb25lIGRlZmluaXRhIG5lbGxlICoqRHluYW1pY09wZXJhdGlvbnMqKiAqL1xyXG4gICAgQE91dHB1dCgpIG9uRHluYW1pY09wZXJhdGlvbjogRXZlbnRFbWl0dGVyPHsgaWQ6IHN0cmluZywgaXRlbTogYW55IH0+ID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBzdHJpbmcsIGl0ZW06IGFueSB9PigpO1xyXG5cclxuICAgIC8qKiBEYXRpIGVzcG9ydGF0aSBkYSBuZ3gtY3N2ICovXHJcbiAgICBwdWJsaWMgZGF0YTogYW55W107XHJcbiAgICAvKiogSGVhZGVyIGRlaSBkYXRpIGVzcG9ydGF0aSBkYSBuZ3gtY3N2ICovXHJcbiAgICBwdWJsaWMgaGVhZGVyczogYW55W107XHJcbiAgICAvKiogRWxlbWVudG8gSFRNTCBkYSBjbGljY2FyZSBwZXIgbCdlc3BvcnRhemlvbmUgKi9cclxuICAgIEBWaWV3Q2hpbGQoJ2V4cG9ydERvd25sb2FkZXInLCB7IHN0YXRpYzogZmFsc2UgfSkgcHVibGljIGV4cG9ydERvd25sb2FkZXI6IEVsZW1lbnRSZWY7XHJcblxyXG4gICAgLyoqIFBsYWNlaG9sZGVyIGRpIG1lbsO5IGNvbnRlc3R1YWxlIHBlciBxdWFuZG8gbm9uIGNpIHNvbm8gb3B6aW9uaSBuZWwgcGxhY2Vob2xkZXIgXCJWZXJvXCIgICovXHJcbiAgICBAVmlld0NoaWxkKCdlbXB0eU1lbnUnLCB7IHN0YXRpYzogdHJ1ZSB9KSBwdWJsaWMgdGFibGVFbXB0eU1lbnU6IENvbnRleHRNZW51Q29tcG9uZW50O1xyXG5cclxuICAgIC8qKiBTdWJzY3JpcHRpb24gc3VsbCdhcGVydHVyYSBkZWwgY29udGV4dCBtZW51IGRhIHJpcHVsaXJlIGFsIGRlc3Ryb3kgZGVsbGEgY2xhc3NlICovXHJcbiAgICBwcml2YXRlIGN0eE1lbnVTdWJzY3JpcHRpb246IGFueTtcclxuXHJcbiAgICAvKiogUGFnaW5hIGluIHZpc3VhbGl6emF6aW9uZSAoZHVyYW50ZSBsYSBwYWdpbmF6aW9uZSBpbiBtb2RhbGl0w6AgQXJyYXkpICovXHJcbiAgICBwdWJsaWMgYXJyYXltb2RlUGFnZSA9IDE7XHJcbiAgICAvKiogTnVtZXJvIGRpIHBhZ2luZSAoZHVyYW50ZSBsYSBwYWdpbmF6aW9uZSBpbiBtb2RhbGl0w6AgQXJyYXkpICovXHJcbiAgICBwdWJsaWMgYXJyYXltb2RlUGFnZXMgPSAxO1xyXG4gICAgLyoqIE9nZ2V0dGkgcGVyIG9nbmkgcGFnaW5hIChkdXJhbnRlIGxhIHBhZ2luYXppb25lIGluIG1vZGFsaXTDoCBBcnJheSkgKi9cclxuICAgIEBJbnB1dCgpIEFycmF5bW9kZUl0ZW1zUGVyUGFnZSA9IDE1O1xyXG4gICAgLyoqIE9nZ2V0dG8gZGkgc2VsZXppb25lIHBlciBsYSBtb2RhbGl0w6AgQXJyYXksIGNoZSBkZXZlIGNvbXBvcnRhcnNpIGNvbWUgbGEgY29udHJvcGFydGUgaW4gbW9kYWxpdMOgIFZpZXcgKi9cclxuICAgIHB1YmxpYyBhcnJheW1vZGVTZWxlY3Rpb246IEl0ZW1zU2VsZWN0aW9uPGFueT47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBWYXJpYWJpbGUgY2hlIHNlcnZlIGEgZ2VzdGlyZSBpbCBtb21lbnRvIGluIGN1aSBsJ2VzLXRhYmxlIGFnZ2lvcm5hIGxhIHBhZ2luYXppb25lIChwdWxzYW50aSBlY2MpLlxyXG4gICAgICogRXNzZW5kbyBvcGVyYXppb25pIGNvbXVucXVlIGNvc3Rvc2UgbGUgZWZmZXR0dW8gc29sbyBzdSBiaW5kaW5nIGVzdGVybmksIG5vbiBzdSByZXdyaXRlIGdlbmVyYXRpIGludGVybmFtZW50ZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGludGVybmFsV3JpdGVDYWxsID0gZmFsc2U7XHJcblxyXG4gICAgLyoqIENhY2hlIGRpIHNlbGV6aW9uZSBIYXNoIC0gT2dnZXR0byAqL1xyXG4gICAgcHJpdmF0ZSBzZWxPckRlc2VsQ2FjaGU6IHsgW2hhc2g6IHN0cmluZ106IGFueSB9ID0ge307XHJcblxyXG4gICAgLyoqIEBpZ25vcmUgKi9cclxuICAgIHB1YmxpYyBuZ09uSW5pdCgpIHtcclxuICAgICAgICAvL1BlciBwb3RlciBjYW1iaWFyZSBpbCBsYXlvdXQgaW4gYmFzZSBhbCBsaXZlbGxvIGdlcmFyY2hpY28gaWwgY29tcG9uZW50ZSBkZXZhIGF2ZXJlIGlsIHBpZW5vIGNvbnRyb2xsbyBkaSBvZ25pIGNlbGxhLFxyXG4gICAgICAgIC8vY2hlIGNvbiBzb2xvIGxhIHByb2llemlvbmUgKHNlbnphIGNlbGxlIGN1c290bSkgbm9uIMOoIGRpc3BvbmliaWxlXHJcbiAgICAgICAgaWYgKHRoaXMuSGllcmFyY2h5ICYmICF0aGlzLlVzZUN1c3RvbUNlbGxzKVxyXG4gICAgICAgICAgICB0aHJvdyBcIkVzLXRhYmxlIGVycm9yOiBQZXIgcG90ZXIgdXRpbGl6emFyZSBsJ2VzLXRhYmxlIGNvbiBbSGllcmFyY2h5XT1cXFwidHJ1ZVxcXCIgw6ggcmljaGllc3RvIGFuY2hlIFtVc2VDdXN0b21DZWxsc109XFxcInRydWVcXFwiXCI7XHJcblxyXG4gICAgICAgIC8vIGNsaWNrIGRlc3RybyBzdSB1bmEgcmlnYSBjb24gc2VsZXppb25lIGF0dGl2YTogVGlybyBmdW9yaSBpbCBjb250ZXh0IG1lbnUgZSBzZWxlemlvbmUgbCdlbGVtZW50byBjb3JyZW50ZVxyXG4gICAgICAgIHRoaXMuY3R4TWVudVN1YnNjcmlwdGlvbiA9ICh0aGlzLkNvbnRleHRNZW51IHx8IHRoaXMudGFibGVFbXB0eU1lbnUpLm9wZW4uc3Vic2NyaWJlKHQgPT4ge1xyXG4gICAgICAgICAgICBsZXQgc2hvdWxkRW1pdCA9ICF0Lml0ZW0uX3NlbGVjdGVkO1xyXG5cclxuICAgICAgICAgICAgdC5pdGVtLl9zZWxlY3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHZhciBpdGVtU2VsZWN0aW9uID0gdGhpcy5oYW5kbGVJdGVtc1NlbGVjdGlvbihbdC5pdGVtXSk7XHJcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlZCgpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHNob3VsZEVtaXQpXHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZC5lbWl0KGl0ZW1TZWxlY3Rpb24pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgICAgIC8vIFNlIHV0aWxpenpvIGxhIG5ldyBzcGljeSBtb2RlIGRlZHVjbyB0dXR0aSBpIHBhcmFtZXRyaSBkaSBsYXZvcm8gcG9zc2liaWxpIGFsIGNhcmljYW1lbnRvIGRlbGxhIHRhYmVsbGFcclxuICAgICAgICAvLyBWZW5nb25vIHNvdnJhc2NyaXR0ZSBzb2xvIGxlIHByb3ByaWV0w6Agbm9uIGltcG9zdGF0ZSBkYWxsJ3V0ZW50ZVxyXG4gICAgICAgIGlmICh0aGlzLkVzVGRzRGlyZWN0aXZlICYmIHRoaXMuRXNUZHNEaXJlY3RpdmUubGVuZ3RoID4gMCAmJiB0aGlzLkVzVGhzRGlyZWN0aXZlICYmIHRoaXMuRXNUaHNEaXJlY3RpdmUubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5Vc2VDdXN0b21DZWxscyA9PSBudWxsKSB0aGlzLlVzZUN1c3RvbUNlbGxzID0gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuSGlkZGVuQ29sdW1ucyA9PSBudWxsICYmIHRoaXMuVXNlQ3VzdG9tQ2VsbHMpIHRoaXMuSGlkZGVuQ29sdW1ucyA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLkNvbHVtbnNPcmRlcmluZyA9PSBudWxsICYmIHRoaXMuVXNlQ3VzdG9tQ2VsbHMpIHRoaXMuQ29sdW1uc09yZGVyaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuT3JkZXJCeUNvbHVtbiA9PSBudWxsICYmIHRoaXMuVXNlQ3VzdG9tQ2VsbHMpIHRoaXMuT3JkZXJCeUNvbHVtbiA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLlNlbGVjdEFsbCA9PSBudWxsICYmIHRoaXMuU2VsZWN0aW9uKSB0aGlzLlNlbGVjdEFsbCA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLlNoaWZ0Q2xpY2sgPT0gbnVsbCAmJiB0aGlzLlNlbGVjdGlvbikgdGhpcy5TaGlmdENsaWNrID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpZ25vcmUgKi9cclxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcclxuICAgICAgICBpZiAodGhpcy5jdHhNZW51U3Vic2NyaXB0aW9uKVxyXG4gICAgICAgICAgICB0aGlzLmN0eE1lbnVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHVibGljIGFzeW5jIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcclxuICAgICAgICBsZXQgbmV3U2VhcmNoVmlldyA9IGNoYW5nZXNbJ1NlYXJjaFZpZXcnXTtcclxuICAgICAgICBpZiAobmV3U2VhcmNoVmlldyAmJiB0aGlzLlNlYXJjaFZpZXcpXHJcbiAgICAgICAgICAgIHRoaXMuYXJyYXlQdWxzYW50aSA9IHRoaXMuZ2V0UGFnZXNBcnJheSg2LCB0aGlzLlNlYXJjaFZpZXcucGFnZSwgdGhpcy5TZWFyY2hWaWV3LnBhZ2VzIHx8IDEpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vICNyZWdpb24gSW1wbGVtZW50YXppb25lIENvbnRyb2xWYWx1ZUFjY2Vzc29yIGlnbm9yYWJpbGVcclxuXHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHVibGljIHJlZ2lzdGVyT25DaGFuZ2UoZm4pOiB2b2lkIHsgdGhpcy5wcm9wYWdhdGVDaGFuZ2UgPSBmbjsgfVxyXG4gICAgLyoqIEBpZ25vcmUgKi9cclxuICAgIHB1YmxpYyByZWdpc3Rlck9uVG91Y2hlZChmbik6IHZvaWQgeyB9XHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgY2hhbmdlZCgpIHsgdGhpcy5wcm9wYWdhdGVDaGFuZ2UodGhpcy5WaWV3KTsgfVxyXG4gICAgLyoqIEBpZ25vcmUgKi9cclxuICAgIHByb3BhZ2F0ZUNoYW5nZSA9IChfOiBhbnkpID0+IHsgfTtcclxuXHJcbiAgICAvLyAjZW5kcmVnaW9uXHJcblxyXG4gICAgLyoqIEBpZ25vcmUgKi9cclxuICAgIHB1YmxpYyB3cml0ZVZhbHVlKG9iaik6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuVmlldyA9IG9iaiA/IG9iaiA6IG51bGw7XHJcblxyXG4gICAgICAgIC8vIE1pIMOoIGFycml2YXRhIGwnQXBwU2VhcmNoIHF1aW5kaSBkaSBzaWN1cm8gbm9uIGhvIHVuYSByaWNlcmNhIGluIHByb2dyZXNzXHJcbiAgICAgICAgdGhpcy5yZXNlYXJjaEluUHJvZ3Jlc3MgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLlZpZXcgJiYgIXRoaXMuU2VhcmNoVmlldykge1xyXG4gICAgICAgICAgICAvLyBTdSB2aWV3IG51bGxhIGV2aXRvIGRpIGZhcmUgcHJlc3NvY2jDqSBxdWFsc2lhc2kgY29zYS4gU2UgYXJyaXZhIHVuIG51bGwgZGV2byBhbmNoZSBhc3NpY3VyYXJtaSBkaSBub24gbW9zdHJhcmUgbnVsbGFcclxuICAgICAgICAgICAgdGhpcy5ib3VuZFNvdXJjZSA9IHRoaXMuVE1QQm91bmRTb3VyY2UgfHwgW107XHJcblxyXG4gICAgICAgICAgICAvLyBQZXIgZXNzZXJlIHNpY3VybyBjaGUgZG9wbyB1biBiaW5kIGRpIG9nZ2V0dGkgbGEgZXMtdGFibGUgYWdnaW9ybmkgbGEgZ3JhZmljYVxyXG4gICAgICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU2UgcGVyIHNiYWdsaW8gbCdvZ2dldHRvIGNoZSBtaSBhcnJpdmEgbm9uIMOoIHRpcGl6emF0byAoaW5zdGFuY2VvZiBBcHBTZWFyY2ggcmVzdGl0dWlzY2UgZmFsc2UgYW5jaGUgc2Ugw6ggZGVsIHRpcG8gZ2l1c3RvKVxyXG4gICAgICAgIC8vIGxvIGNvcnJlZ2dvLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAgICAgICBpZiAodGhpcy5WaWV3ICYmIHR5cGVvZiAodGhpcy5WaWV3IGFzIGFueSkucmVzdWx0ICE9ICd1bmRlZmluZWQnICYmICEodGhpcy5WaWV3IGluc3RhbmNlb2YgUmVwb3J0RGVmaW5pdGlvbikpIHtcclxuICAgICAgICAgICAgKHRoaXMuVmlldyBhcyBhbnkpLl9fcHJvdG9fXyA9IG5ldyBSZXBvcnREZWZpbml0aW9uKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuVmlldyAmJiB0eXBlb2YgKHRoaXMuVmlldyBhcyBhbnkpLml0ZW1zcGVycGFnZW92ZXJyaWRlICE9ICd1bmRlZmluZWQnICYmICEodGhpcy5WaWV3IGluc3RhbmNlb2YgQXBwU2VhcmNoKSkge1xyXG4gICAgICAgICAgICAodGhpcy5WaWV3IGFzIGFueSkuX19wcm90b19fID0gbmV3IEFwcFNlYXJjaCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0aGlzLlNlYXJjaFZpZXcgJiYgdHlwZW9mICh0aGlzLlNlYXJjaFZpZXcgYXMgYW55KS5pdGVtc3BlcnBhZ2VvdmVycmlkZSAhPSAndW5kZWZpbmVkJyAmJiAhKHRoaXMuU2VhcmNoVmlldyBpbnN0YW5jZW9mIEFwcFNlYXJjaCkpIHtcclxuICAgICAgICAgICAgKHRoaXMuU2VhcmNoVmlldyBhcyBhbnkpLl9fcHJvdG9fXyA9IG5ldyBBcHBTZWFyY2goKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuICAgICAgICBpZiAodGhpcy5WaWV3ICYmIHRoaXMuVmlldyBpbnN0YW5jZW9mIFJlcG9ydERlZmluaXRpb24pIHtcclxuICAgICAgICAgICAgLy8gU2UgbWkgYXJyaXZhIHVuYSByZXBvcnQgZGVmaW5pdGlvbiB2dW9sIGRpcmUgY2hlIHBvdHJlaSBhdmVyZSBkZWkgcmlzdWx0YXRpIGRhIHZpc3VhbGl6emFyZVxyXG4gICAgICAgICAgICB0aGlzLnNldE1vZGUoJ3JlcG9ydCcpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5SZXBvcnRWYWx1ZXMgPSB0aGlzLlZpZXcucmVzdWx0O1xyXG4gICAgICAgICAgICBpZiAodGhpcy5SZXBvcnRWYWx1ZXMpXHJcbiAgICAgICAgICAgICAgICB0aGlzLnJldmlld1JlcG9ydEJpbmRpbmdzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuVmlldyAmJiB0aGlzLlZpZXcgaW5zdGFuY2VvZiBBcHBTZWFyY2gpIHtcclxuICAgICAgICAgICAgLy8gU2UgY2FtYmlhIGwnb2dnZXR0byBpbnRlcm8gc2lnbmlmaWNhIGNoZSBobyByaW1hbmRhdG8gbGEgcmljZXJjYVxyXG4gICAgICAgICAgICB0aGlzLnNldE1vZGUoJ3ZpZXcnKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNlIHZlbmdvIGRhIHVuYSByaWNlcmNhIGludGVybmEgbWFudGVuZ28gbG8gc3RhdG8gZGkgc2VsZXppb25lIHByZWNlZGVudGUgKHF1aW5kaSBzdSBjYW1iaW8gcGFnaW5hLCBjYW1iaW8gaXBwLCBlY2MuLi4pXHJcbiAgICAgICAgICAgIC8vIHNlIGludmVjZSBsJ3V0ZW50ZSBoYSBmYXR0byB1bmEgcmljZXJjYSBsdWkgKHF1aW5kaSBjYW1iaWFuZG8gZmlsdHJpKSwgc2VjY28gbGUgaW5mbyBkaSBzZWxlemlvbmVcclxuICAgICAgICAgICAgaWYgKCF0aGlzLlZpZXcuc2VsZWN0aW9uIHx8ICF0aGlzLlZpZXcuaW50ZXJuYWxzZWFyY2hyZXF1ZXN0IHx8ICF0aGlzLlVzZVNlbGVjdGlvbkNhY2hlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNlbE9yRGVzZWxDYWNoZSA9IHt9O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5WaWV3LnNlbGVjdGlvbiA9IG5ldyBJdGVtc1NlbGVjdGlvbihbXSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZC5lbWl0KHRoaXMuVmlldy5zZWxlY3Rpb24pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLlZpZXcuaW50ZXJuYWxzZWFyY2hyZXF1ZXN0ID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAvLyBSZWN1cGVybyBQcmVmZXJlbmNlXHJcbiAgICAgICAgICAgIGlmICh0aGlzLlNhdmVQcmVmZXJlbmNlcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLm5nQ29udHJvbC5uYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJOb24gcG9zc28gdXRpbGl6emFyZSBsZSBwcmVmZXJlbmNlIHNlbnphIGF2ZXJlIHVuICduYW1lJyBwZXIgcXVlc3RhIHRhYmVsbGFcIik7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghdGhpcy5wcmVmU2VydmljZSlcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm9uIHBvc3NvIHV0aWxpenphcmUgbGUgcHJlZmVyZW5jZSBzZW56YSBjaGUgaWwgcGFjY2hldHRvIEBlc2ZhZW56YS9wcmVmZXJlbmNlcyBzaWEgaW5zdGFsbGF0b1wiKTtcclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwcmVmcyA9IHRoaXMucHJlZlNlcnZpY2UucmV0cmlldmU8eyBjb2x1bW5zOiBzdHJpbmdbXSwgY29sdW1uX29yZGVyaW5nOiBzdHJpbmdbXSB9Pig8c3RyaW5nPnRoaXMubmdDb250cm9sLm5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcmVmcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLlZpZXcuY29sdW1ucyA9IHByZWZzLmNvbHVtbnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuVmlldy5jb2x1bW5fb3JkZXJpbmcgPSBwcmVmcy5jb2x1bW5fb3JkZXJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmFycmF5UHVsc2FudGkgPSB0aGlzLmdldFBhZ2VzQXJyYXkoNiwgdGhpcy5WaWV3LnBhZ2UsIHRoaXMuVmlldy5wYWdlcyB8fCAxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5WaWV3ICYmICh0aGlzLlZpZXcubGVuZ3RoICE9IG51bGwgJiYgdGhpcy5WaWV3Lmxlbmd0aCAhPSB1bmRlZmluZWQpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0TW9kZSgnYXJyYXknKTtcclxuXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5Vc2VTZWxlY3Rpb25DYWNoZSB8fCAhdGhpcy5hcnJheW1vZGVTZWxlY3Rpb24pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2VsT3JEZXNlbENhY2hlID0ge307XHJcbiAgICAgICAgICAgICAgICB0aGlzLmFycmF5bW9kZVNlbGVjdGlvbiA9IG5ldyBJdGVtc1NlbGVjdGlvbihbXSk7O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZWQuZW1pdCh0aGlzLmFycmF5bW9kZVNlbGVjdGlvbik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLlNlYXJjaFZpZXcpXHJcbiAgICAgICAgICAgICAgICB0aGlzLmFycmF5UHVsc2FudGkgPSB0aGlzLmdldFBhZ2VzQXJyYXkoNiwgdGhpcy5TZWFyY2hWaWV3LnBhZ2UsIHRoaXMuU2VhcmNoVmlldy5wYWdlcyB8fCAxKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLlZpZXcgJiYgISh0aGlzLlZpZXcgaW5zdGFuY2VvZiBSZXBvcnREZWZpbml0aW9uKSkge1xyXG4gICAgICAgICAgICAvKlxyXG4gICAgICAgICAgICAgKlVzbyBsYSB0ZWNuaWNhIGRpIEVuZGxlc3NTY3JvbGwgc2UgbGEgdmFyaWFiaWxlIHJlbGF0aXZhIMOoIGF0dGl2YSBlIHNlXHJcbiAgICAgICAgICAgICAqIDEpIEhvIHVuIEFycmF5LCBvcHB1cmVcclxuICAgICAgICAgICAgICogMikgSG8gdW4gQXBwU2VhcmNoIGNoZSBzdGEgY2VyY2FuZG8gY29uIHBhZ2luYXppb25lIFwiVHV0dG9cIiwgb3BwdXJlXHJcbiAgICAgICAgICAgICAqIDMpIEhvIHVuIEFwcFNlYXJjaCBjaGUgc3RhIGNlcmNhbmRvIGNvbiBwYWdpbmF6aW9uZSBkaXZlcnNhIGRhIFwiVHV0dG9cIiBtYSBjb24gbGEgdmFyaWFiaWxlIEVuZGxlc3NTY3JvbGxPbmx5Rm9yQWxsIGEgZmFsc2VcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGxldCB2aWV3Q2FzdGVkID0gdGhpcy5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+O1xyXG4gICAgICAgICAgICBsZXQgaXNBcHBTZWFyY2hXaXRoSXBwTWF4ID0gdGhpcy52aWV3TW9kZSAmJiB2aWV3Q2FzdGVkLml0ZW1zcGVycGFnZW92ZXJyaWRlID09IHRoaXMuZGVmYXVsdEFsbFBhZ2VPdmVycmlkZTtcclxuICAgICAgICAgICAgbGV0IGlzQXBwU2VhcmNoTm9NYXhJcHAgPSB0aGlzLnZpZXdNb2RlICYmIHZpZXdDYXN0ZWQuaXRlbXNwZXJwYWdlb3ZlcnJpZGUgIT0gdGhpcy5kZWZhdWx0QWxsUGFnZU92ZXJyaWRlO1xyXG4gICAgICAgICAgICB0aGlzLlVzZUVuZGxlc3NzY3JvbGwgPSB0aGlzLkVuZGxlc3NTY3JvbGwgJiYgKHRoaXMuYXJyYXlNb2RlIHx8IGlzQXBwU2VhcmNoV2l0aElwcE1heCB8fCAoaXNBcHBTZWFyY2hOb01heElwcCAmJiAhdGhpcy5FbmRsZXNzU2Nyb2xsT25seUZvckFsbCkpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuVXNlRW5kbGVzc3Njcm9sbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRlZFNsaWNlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5ib3VuZFN1YlNvdXJjZXMgPSB0aGlzLmdldEl0ZW1TbGljZXMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLlRNUEJvdW5kU291cmNlID0gdGhpcy5ib3VuZFN1YlNvdXJjZXNbMF0gPyB0aGlzLmJvdW5kU3ViU291cmNlc1swXSA6IFtdO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuYm91bmRTdWJTb3VyY2VzWzBdKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkZWRTbGljZXMucHVzaCgwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICB0aGlzLlRNUEJvdW5kU291cmNlID0gdGhpcy5nZXRJdGVtc0J5TW9kZShmYWxzZSwgIXRoaXMuaW50ZXJuYWxXcml0ZUNhbGwpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuSGllcmFyY2h5KVxyXG4gICAgICAgICAgICAgICAgdGhpcy5hc3NpZ25IaWVyYXJjaHlMZXZlbHModGhpcy5UTVBCb3VuZFNvdXJjZSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmNhbGN1bGF0ZUhhc2godGhpcy5UTVBCb3VuZFNvdXJjZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBBc3NlZ25vIGEgdW5hIHZhcmlhYmlsZSBtaWEgbCdldmVudHVhbGUgb3ZlcnJpZGUgcGVyIGxhIGNsYXNzZSBkZWxsYSByaWdhXHJcbiAgICAgICAgICAgIC8vIFNlIHBvaSBzb25vIGluIG1vZGFsaXTDoCBnZXJhcmNoaWNhIGluaWV0dG8gYW5jaGUgbGEgY2xhc3NlIHBlciBsYSBjb25maWd1cmF6aW9uZSBkZWwgbGl2ZWxsbyBkZWxsYSByaWdhXHJcbiAgICAgICAgICAgIGlmICgodGhpcy5UTVBCb3VuZFNvdXJjZSAmJiB0aGlzLlJvd0NsYXNzQXNzaWduZXIpIHx8IHRoaXMuSGllcmFyY2h5KSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuVE1QQm91bmRTb3VyY2UubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgaXRlbSA9IHRoaXMuVE1QQm91bmRTb3VyY2VbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgaXRlbS5fcm93Q2xhc3MgPSB0aGlzLlJvd0NsYXNzQXNzaWduZXIgPyB0aGlzLlJvd0NsYXNzQXNzaWduZXIoaXRlbSkgOiBcIlwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGl0ZW0uX3Jvd0NsYXNzICs9IHRoaXMuSGllcmFyY2h5ID8gXCIgZXN0LXJvdy1sdmwtXCIgKyBpdGVtLmxldmVsIDogXCJcIjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5wb3N0Qm91bmRTb3VyY2VDYWxjdWxhdGlvbigpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vICNyZWdpb24gR2VzdGlvbmUgcmV0cmlldmUgZGVnbGkgb2dnZXR0aSBkYSBtb3N0cmFyZSBpbiB0YWJlbGxhLCBjb25zaWRlcmFuZG8gZXZlbnR1YWxpIEVuZGxlc3MgU2Nyb2xsc1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW4gYmFzZSBhbGxhIG1vZGFsaXTDoCBzcGVjaWZpY2F0YSAoQXJyYXlNb2RlLCBWaWV3TW9kZSwgZWNjLi4uKSBxdWVzdG8gbWV0b2RvIHJlY3VwZXJhIGwnYXJyYXkgZGkgb2dnZXR0aSBkYSBiaW5kYXJlIGFkIGludGVyZmFjY2lhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBvbmx5c2VsZWN0ZWQgW2ZhbHNlXSBJbmRpY2EgZGkgcHJlbmRlcmUgc29sbyBnbGkgb2dnZXR0aSBzZWxlemlvbmF0aVxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSByZWZyZXNoUGFnaW5nIFtmYWxzZV0gSW5kaWNhIHNlIGFnZ2lvcm5hcmUgbGUgaW5mb3JtYXppb25pIGRpIHBhZ2luYXppb25lIG8gbWVub1xyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBhbGxJZlBvc3NpYmxlIFtmYWxzZV0gSW5kaWNhIHNlIHByZW5kZXJlIHR1dHRpIGdsaSBvZ2dldHRpIHF1YW9yYSBwb3NzaWJpbGUsIHVzYXRvIHNvbG8gaW4gQXJyYXlNb2RlXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2FueVtdfSBMaXN0YSBkZWdsaSBvZ2dldHRpIHN1IGN1aSBlZmZldHR1YXJlIGlsIGJpbmQgbGF0byBpbnRlcmZhY2NpYVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldEl0ZW1zQnlNb2RlKG9ubHlzZWxlY3RlZDogYm9vbGVhbiA9IGZhbHNlLCByZWZyZXNoUGFnaW5nOiBib29sZWFuID0gZmFsc2UsIGFsbElmUG9zc2libGU6IGJvb2xlYW4gPSBmYWxzZSk6IGFueVtdIHtcclxuICAgICAgICBsZXQgaXRlbXM6IGFueVtdID0gW107XHJcblxyXG4gICAgICAgIGlmICgodGhpcy52aWV3TW9kZSAmJiB0aGlzLlZpZXcgaW5zdGFuY2VvZiBBcHBTZWFyY2gpKSB7XHJcbiAgICAgICAgICAgIGl0ZW1zID0gdGhpcy5nZXRWaWV3SXRlbXNCeVNvdXJjZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0aGlzLmFycmF5TW9kZSkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5Vc2VBcnJheU1vZGVQYWdpbmcgJiYgIWFsbElmUG9zc2libGUpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTZSBzb25vIGluIG1vZGFsaXTDoCBhcnJheSBtYSBsYSByaWNlcmNhIGRpcGVuZGUgZGEgdW5hIHZpZXcgZGV2byByaWFsbGluZWFyZSBnbGkgaXRlbXBlcnBhZ2VcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLlNlYXJjaFZpZXcpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5BcnJheW1vZGVJdGVtc1BlclBhZ2UgPSB0aGlzLlNlYXJjaFZpZXcuaXRlbXNwZXJwYWdlb3ZlcnJpZGU7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gRGV2byBjaGlhbWFyZSBpbCByZWZyZXNoIHBhZ2Ugc29sbyBzZSB2ZW5nbyByaWNoaWFtYXRvIGRhIHVuIGJpbmRpbmcgZXN0ZXJub1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlZnJlc2hQYWdpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWZyZXNoUGFnaW5nKHRoaXMuQXJyYXltb2RlSXRlbXNQZXJQYWdlKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpdGVtcyA9IHRoaXMuYWRhcHRWaWV3VG9QYWdpbmcoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGl0ZW1zID0gdGhpcy5WaWV3IGFzIGFueVtdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBTZSB2b2dsaW8gc29sbyBpIHNlbGV6aW9uYXRpIGZpbHRyb1xyXG4gICAgICAgIGlmIChvbmx5c2VsZWN0ZWQpXHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtcy5maWx0ZXIodCA9PiB0Ll9zZWxlY3RlZCk7XHJcblxyXG4gICAgICAgIHJldHVybiBpdGVtcztcclxuICAgIH1cclxuXHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHJpdmF0ZSBnZXRWaWV3SXRlbXNCeVNvdXJjZSgpOiBhbnlbXSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuU2Vjb25kYXJ5U291cmNlID8gKHRoaXMuVmlldyBhcyBhbnkpLml0ZW1zMiA6IHRoaXMuVGVydGlhcnlTb3VyY2UgPyAodGhpcy5WaWV3IGFzIGFueSkuaXRlbXMzIDogKHRoaXMuVmlldyBhcyBhbnkpLml0ZW1zO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGNoZSBwcmVuZGUgdHV0dGkgZ2xpIG9nZ2V0dGkgZGkgY3VpIGRpc3BvbmUgZGl2aXNpIGluIGJ1Y2tldCBkYSAxMDAgZWxlbWVudGlcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7YW55W11bXX0gTWF0cmljZSBkaSBhcnJheSBOeDEwMFxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldEl0ZW1TbGljZXMoKTogYW55W11bXSB7XHJcbiAgICAgICAgbGV0IGl0ZW1zID0gdGhpcy5nZXRJdGVtc0J5TW9kZSgpO1xyXG4gICAgICAgIGlmICghaXRlbXMpXHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICBsZXQgYXJyYXlCeTEwMCA9IFtdO1xyXG5cclxuICAgICAgICBsZXQgc2xpY2VzID0gTWF0aC5jZWlsKGl0ZW1zLmxlbmd0aCAvIHRoaXMuU2xpY2VTaXplKTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNsaWNlczsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBhcnJheVNsaWNlID0gaXRlbXMuc2xpY2UoaSAqIHRoaXMuU2xpY2VTaXplLCBpICogdGhpcy5TbGljZVNpemUgKyB0aGlzLlNsaWNlU2l6ZSk7XHJcbiAgICAgICAgICAgIGFycmF5QnkxMDAucHVzaChhcnJheVNsaWNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGFycmF5QnkxMDA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gY2hlIGdlc3Rpc2NlIGwnZW5kbGVzcyBzY3JvbGwgZSBpbiBiYXNlIGEgcXVhbnRvIGxhIHRhYmVsbGEgw6ggc3RhdGEgc2Nyb2xsYXRhIGFnZ2l1bmdlIGRlZ2xpIGVsZW1lbnRpIGV4dHJhIGEgKipUTVBCb3VuZFNvdXJjZSoqXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHthbnl9IGUgRXZlbnRvIGRpIHNjcm9sbCBkZWwgYnJvd3NlclxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25TY3JvbGwoZTogYW55KSB7XHJcbiAgICAgICAgbGV0IHRhYmxlVmlld0hlaWdodCA9IGUudGFyZ2V0Lm9mZnNldEhlaWdodDtcclxuICAgICAgICBsZXQgdGFibGVTY3JvbGxIZWlnaHQgPSBlLnRhcmdldC5zY3JvbGxIZWlnaHQ7XHJcbiAgICAgICAgbGV0IHNjcm9sbExvY2F0aW9uID0gZS50YXJnZXQuc2Nyb2xsVG9wO1xyXG4gICAgICAgIGxldCBidWZmZXIgPSAyMDA7XHJcblxyXG4gICAgICAgIGxldCBsaW1pdCA9IHRhYmxlU2Nyb2xsSGVpZ2h0IC0gdGFibGVWaWV3SGVpZ2h0IC0gYnVmZmVyO1xyXG4gICAgICAgIGlmIChzY3JvbGxMb2NhdGlvbiA+IGxpbWl0KSB7XHJcbiAgICAgICAgICAgIGxldCBpbmRleFRvQWRkID0gTWF0aC5mbG9vcih0aGlzLlRNUEJvdW5kU291cmNlLmxlbmd0aCAvIDEwMCk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmJvdW5kU3ViU291cmNlc1tpbmRleFRvQWRkXSAmJiB0aGlzLmFkZGVkU2xpY2VzLmluZGV4T2YoaW5kZXhUb0FkZCkgPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIC8vIERldm8gcmljb3JkYXJtaSBkaSBmYXJlIGwnaGFzaCBkZWwgbnVvdm8gcGV6em9cclxuICAgICAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlSGFzaCh0aGlzLmJvdW5kU3ViU291cmNlc1tpbmRleFRvQWRkXSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLlRNUEJvdW5kU291cmNlID0gdGhpcy5UTVBCb3VuZFNvdXJjZS5jb25jYXQodGhpcy5ib3VuZFN1YlNvdXJjZXNbaW5kZXhUb0FkZF0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRlZFNsaWNlcy5wdXNoKGluZGV4VG9BZGQpO1xyXG5cclxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4geyB0aGlzLnBvc3RCb3VuZFNvdXJjZUNhbGN1bGF0aW9uKCk7IH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vICNlbmRyZWdpb25cclxuXHJcbiAgICAvLyAjcmVnaW9uIEdlc3Rpb25lIGRpIHR1dHRvIGlsIGNpY2xvIGRpIHZpdGEgcG9zdCBiaW5kaW5nIG9nZ2V0dGlcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBsYW5jaWF0byBkb3BvIGNoZSBsYSBzb3JnZW50ZSBkYXRpIMOoIHN0YXRhIGNvcnJldHRhbWVudGUgYmluZGF0YSwgc2kgb2NjdXBhIGRpIHJpY2FsY29sYXJlIHR1dHRvIGNpw7IgY2hlIHNlcnZlXHJcbiAgICAgKiBhbGwnZXMtdGFibGUgcGVyIHJlbmRlcml6emFyZSBpIHZhbG9yaSBkYSBtb3N0cmFyZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHBvc3RCb3VuZFNvdXJjZUNhbGN1bGF0aW9uKCkge1xyXG4gICAgICAgIC8vIFJlc2V0dG8gdHV0dG8gdHJhbm5lIFJvd1REcyBlIFJvd1RIcyBwZXIgZXZpdGFyZSBmbGlja2VyaW5nLiBSb3dURHMgZSBSb3dUSHMgc2FyYW5ubyBtb2RpZmljYXRlIGFsbCdpbnRlcm5vIGRlbCBwcm9zc2ltbyBjaWNsbyBkaSBDRFxyXG4gICAgICAgIHRoaXMuUm93Q29udGV4dHMgPSBbXTtcclxuICAgICAgICB0aGlzLk9yZGVyRGlyZWN0aXZlcyA9IFtdO1xyXG4gICAgICAgIHRoaXMubGFzdFNlbGVjdGVkSXRlbUlEID0gbnVsbDtcclxuXHJcbiAgICAgICAgLy8gU2V0IHRpbWVvdXQgZSBiYXN0YSBmdW56aW9uZXJlYmJlIHBlciBsYSBtb2RhbGl0w6AgSklULCBtYSBwZXIgQU9UIHNlcnZvbm8gc2lhIHF1ZWxsbyBjaGUgZGV0ZWN0Q2hhbmdlc1xyXG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgLy8gU2Ugbm9uIGhvIGNvbG9ubmUgZGluYW1pY2hlIG1hIHNvbm8gaW4gbW9kYWxpdMOgIGRpbmFtaWNhIChsbyBjYXBpc2NvIHBlcmNow6kgYyfDqCB1bmEgdmlldyBwaWVuYSBkaSBnZW5lcmljaXRlbSkgbWV0dG8gaWwgZGVmYXVsdCBkZWxsZSBjb2xvbm5lXHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnR1YWxseVJldmlld0R5bmFtaWNDb2x1bW5zKCk7XHJcbiAgICAgICAgICAgIC8vIE1vbHRlIGNvc2Ugc29ubyBvdnZpYW1lbnRlIGRpc3BvbmliaWxpIHNvbG8gaW4gbW9kYWxpdMOgIFZpZXdcclxuICAgICAgICAgICAgaWYgKHRoaXMudmlld01vZGUgJiYgdGhpcy5Vc2VDdXN0b21DZWxscykge1xyXG4gICAgICAgICAgICAgICAgbGV0IHZpZXcgPSB0aGlzLlZpZXcgYXMgQXBwU2VhcmNoPGFueT5cclxuICAgICAgICAgICAgICAgIGxldCB0aHMgPSB0aGlzLkVzVGhzICYmIHRoaXMuRXNUaHMubGVuZ3RoID4gMCA/IHRoaXMuRXNUaHMudG9BcnJheSgpIDogdGhpcy5Fc1Roc0RpcmVjdGl2ZSAmJiB0aGlzLkVzVGhzRGlyZWN0aXZlLmxlbmd0aCA+IDAgP3RoaXMuRXNUaHNEaXJlY3RpdmUudG9BcnJheSgpIDogW107XHJcbiAgICAgICAgICAgICAgICBsZXQgdGRzID0gdGhpcy5Fc1RkcyAmJiB0aGlzLkVzVGRzLmxlbmd0aCA+IDAgPyB0aGlzLkVzVGRzLnRvQXJyYXkoKSA6IHRoaXMuRXNUZHNEaXJlY3RpdmUgJiYgdGhpcy5Fc1Rkc0RpcmVjdGl2ZS5sZW5ndGggPiAwID8gdGhpcy5Fc1Rkc0RpcmVjdGl2ZS50b0FycmF5KCkgOiBbXTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBOLkI6IFJpc3BldHRhcmUgbCdvcmRpbmUgZGkgcXVlc3RlIDMgbWFjcm9jYXRlZ29yaWUgw6ggVklUQUxFXHJcblxyXG4gICAgICAgICAgICAgICAgLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAgICAgICAgU2lzdGVtYXppb25pIGRpIFRILCBURCwgZSB2aXNpYmlsaXTDoCB2YXJpZSAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmFsaWduQ29sdW1uc0lmTG9hZGVkVmlldyh2aWV3KTsgICAgICAgICAgICAvLyBTZSBzdG8gY2FyaWNhbmRvIHVuYSBWaWV3IGRhIGhvdHBvdGF0byAocXVpbmRpIGNvbiBzYXZlZHN0YXRlID0gdHJ1ZSkgcmlhbGxpbmVvIGxhIHZpc2liaWxpdMOgIGRlbGxlIGNvbG9ubmUgZSBpbCBsb3JvIG9yZGluZS5cclxuICAgICAgICAgICAgICAgIHRoaXMucmVmcmVzaENvbHVtbnNWaXNpYmlsaXR5KHRocywgdGRzLCB2aWV3KTsgIC8vIExhdm9ybyBzdWkgVEggZWQgZXZlbnR1YWxtZW50ZSBtb2RpZmljbyBsYSB2aXNpYmlsaXTDoCBhbmNoZSBkZWkgVEQuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmFsaWduSGVhZGVyc09yZGVyaW5nKHRocywgdmlldyk7ICAgICAgICAgICAvLyBBbGxpbmVvIGdsaSBvcmRpbmFtZW50aSBhZ2xpIGhlYWRlclxyXG4gICAgICAgICAgICAgICAgdGhpcy5yZXZpZXdDb2x1bW5zTGlzdCh0aHMpOyAgICAgICAgICAgICAgICAgICAgLy8gQWdnaW9ybmEgbGEgbGlzdGEgZGVsbGUgY29sb25uZSBkYSBtb3N0cmFyZSBuZWxsYSBkaWFsb2cgcGVyIG9yZGluYW1lbnRvIGVjY1xyXG5cclxuICAgICAgICAgICAgICAgIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogICAgICAgIEdlbmVyYXppb25lIGJpbmRpbmcgcGVyIHJpZ2hlIGUgY29sb25uZSAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmV2YWx1YXRlUm93VGhzKHRocyk7ICAgICAgIC8vIFJhY2NvbGdvIGkgVEhcclxuICAgICAgICAgICAgICAgIHRoaXMuZXZhbHVhdGVSb3dUZHModGhzLCB0ZHMpOyAgLy8gUmFjY29sZ28gaSBURCBpbiBjb250ZXN0aSBzZXBhcmF0aSwgdW4gY29udGVzdG8gcGVyIG9nbmkgaXRlbVxyXG5cclxuICAgICAgICAgICAgICAgIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogICAgICAgIFVsdGltaSBhZ2dpdXN0bWFlbnRpIGRlaSBiaW5kaW5nICAgICAgICAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmdlbmVyYXRlRGVmYXVsdE9yZGVyKHZpZXcpOyAgICAgICAgICAgICAgICAgICAgLy8gR2VuZXJvIGxlIGRpcmV0dGl2ZSBkaSBvcmRpbmFtZW50bywgY2hlIHNpYW5vIGRlZmF1bHQgbyBkZXJpdmFudGkgZGFsbGEgQXBwU2VhcmNoXHJcbiAgICAgICAgICAgICAgICB0aGlzLmFwcGx5T3JkZXJpbmcodmlldywgdHJ1ZSk7ICAgICAgICAgICAgICAgICAgICAgLy8gQXBwbGljbyBsJ29yZGluYW1lbnRvIHN1bGxlIGNvbG9ubmUgKG5vbiBBU0MgREVTQywgbWEgXCJwcmltYSBxdWVzdGEgbyBxdWVsbGEgY29sb25uYVwiKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5Nb3ZlVGVtcG9yYXJ5VmFyaWFibGVzVG9SZWFsT25lcygpOyAgICAgICAgICAgIC8vIENvbGxlZ28gVEggZSBURCBhZ2dpdXN0YXRpIGZpbm8gYWQgb3JhIGFsbGUgdmFyaWFiaWxpIGRpIEJpbmRpbmcgSFRNTFxyXG4gICAgICAgICAgICAgICAgdGhpcy5ldmFsdWF0ZVNlbGVjdGlvbih2aWV3Lml0ZW1zLCB2aWV3LnNlbGVjdGlvbik7IC8vIFJpYWxsaW5lbyBsZSBpbmZvIGRpIHNlbGV6aW9uZSBkZWdsaSBlbGVtZW50aSBkZWxsYSBWaWV3XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy52aWV3TW9kZSAmJiAhdGhpcy5Vc2VDdXN0b21DZWxscykge1xyXG4gICAgICAgICAgICAgICAgLy8gUmlhbGxpbmVvIGxlIGluZm8gZGkgc2VsZXppb25lIGRlZ2xpIGVsZW1lbnRpIGRlbGxhIFZpZXdcclxuICAgICAgICAgICAgICAgIGxldCB2aWV3ID0gdGhpcy5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5ldmFsdWF0ZVNlbGVjdGlvbih2aWV3Lml0ZW1zLCB2aWV3LnNlbGVjdGlvbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5hcnJheU1vZGUpIHtcclxuICAgICAgICAgICAgICAgIC8vIFJpYWxsaW5lbyBsZSBpbmZvIGRpIHNlbGV6aW9uZSBkZWdsaSBlbGVtZW50aSBkZWxsJ2FycmF5XHJcbiAgICAgICAgICAgICAgICB0aGlzLmFycmF5TW9kZUV2YWx1YXRlU2VsZWN0aW9uKHRoaXMuVmlldyBhcyBhbnlbXSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIENvbGxlZ28gZ2xpIG9nZ2V0dGkgZGEgbW9zdHJhcmVcclxuICAgICAgICAgICAgdGhpcy5ib3VuZFNvdXJjZSA9IHRoaXMuVE1QQm91bmRTb3VyY2U7XHJcblxyXG4gICAgICAgICAgICAvLyBQZXIgZXNzZXJlIHNpY3VybyBjaGUgZG9wbyB1biBiaW5kIGRpIG9nZ2V0dGkgbGEgZXMtdGFibGUgYWdnaW9ybmkgbGEgZ3JhZmljYVxyXG4gICAgICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcclxuICAgICAgICAgICAgdGhpcy5GaXJzdEJpbmQgPSBmYWxzZTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyByaWNoaWFtYXRvIHNvbG8gcXVhbmRvICoqVE1QUm93VERzKiogZSAqKlRNUFJvd1RIcyoqIHNvbm8gY29tcGxldGFtZW50ZSBnZW5lcmF0aSBlZCBhZ2dpdXN0YXRpLiBTZXJ2ZSBwZXIgY29sbGVnYXJsaSBhbGxlIHZhcmlhYmlsaSB1c2F0ZSBsYXRvIGJpbmRpbmcgSFRNTFxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIE1vdmVUZW1wb3JhcnlWYXJpYWJsZXNUb1JlYWxPbmVzKCkge1xyXG4gICAgICAgIHRoaXMuUm93VERzID0gdGhpcy5UTVBSb3dURHM7XHJcbiAgICAgICAgdGhpcy5Sb3dUSHMgPSB0aGlzLlRNUFJvd1RIcztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFZhbHV0YSBxdWFsaSBlbGVtZW50aSBkZXZvbm8gZXNzZXJlIG1hcmNhdGkgY29tZSBzZWxlemlvbmF0aSBuZWxsYSB2aXN0YSBhdHR1YWxlLiBTaSBiYXNhIHN1bGwnb2dnZXR0byAqKnNlbGVjdGlvbioqIGludGVybm8gYWxsJ0FwcFNlYXJjaFxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55W119IGl0ZW1zIE9nZ2V0dGkgZGkgY3VpIHZhbHV0YXJlIGxhIHNlbGV6aW9uZVxyXG4gICAgICogQHBhcmFtIHtJdGVtc1NlbGVjdGlvbjxhbnk+fSBzZWxlY3Rpb25JdGVtIE9nZ2V0dGkgZGkgc2VsZXppb25lIGRlcml2YW50ZSBkYWxsYSB2aWV3IG8gZGFsbCdvZ2dldHRvIHBlciBBcnJheVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGV2YWx1YXRlU2VsZWN0aW9uKGl0ZW1zOiBhbnlbXSwgc2VsZWN0aW9uSXRlbTogSXRlbXNTZWxlY3Rpb248YW55Pikge1xyXG4gICAgICAgIGlmICghc2VsZWN0aW9uSXRlbSlcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICB0aGlzLmhhbmRsZVNlbGVjdGlvbkV2YWx1YXRpb24oaXRlbXMsIHNlbGVjdGlvbkl0ZW0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVmFsdXRhIHF1YWxpIGVsZW1lbnRpIGRldm9ubyBlc3NlcmUgbWFyY2F0aSBjb21lIHNlbGV6aW9uYXRpIG5lbGxhIHZpc3RhIGF0dHVhbGUuIFNpIGJhc2Egc3VsbCdvZ2dldHRvICoqYXJyYXltb2RlU2VsZWN0aW9uKiogZGVsbCdlcy10YWJsZVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55W119IGFycmF5IExpc3RhIGRpIG9nZ2V0dGkgZGkgY3VpIHZhbHV0YXJlIGxhIHNlbGV6aW9uZSBpbiBtb2RhbGl0w6AgYXJyYXlcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBhcnJheU1vZGVFdmFsdWF0ZVNlbGVjdGlvbihhcnJheTogYW55W10pIHtcclxuICAgICAgICBpZiAoYXJyYXkubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgdGhpcy5oYW5kbGVTZWxlY3Rpb25FdmFsdWF0aW9uKGFycmF5LCB0aGlzLmFycmF5bW9kZVNlbGVjdGlvbik7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbXBsZW1lbnRhemlvbmUgYWdub3N0aWNhIGRlbGxhIHZhbHV0YXppb25lIGRlbGxlIHNlbGV6aW9uaSBkZWdsaSBvZ2dldHRpLiBSaWNoaWVkZSBnbGkgb2dnZXR0aSBkZWxsYSB2aXN0YSBhdHR1YWxlIGUgbCdpdGVtU2VsZWN0b3JcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge2FueVtdfSBpdGVtcyBPZ2dldHRpIGRpIGN1aSBhZ2dpb3JuYXJlIGxvIHN0YXRvIGRpIHNlbGV6aW9uZVxyXG4gICAgICogQHBhcmFtIHtJdGVtc1NlbGVjdGlvbjxhbnk+fSBzZWxlY3Rpb25JdGVtIE9nZ2V0dG8gY29udGVuZW50ZSBsbyBzdGF0byBhdHR1YWxlIGRpIHNlbGV6aW9uZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGhhbmRsZVNlbGVjdGlvbkV2YWx1YXRpb24oaXRlbXM6IGFueVtdLCBzZWxlY3Rpb25JdGVtOiBJdGVtc1NlbGVjdGlvbjxhbnk+KSB7XHJcbiAgICAgICAgbGV0IGFsbFNlbGVjdGVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgaXRtID0gaXRlbXNbaV07XHJcblxyXG4gICAgICAgICAgICAvLyBSZWlkcmF0byBsYSBjYWNoZSBkaSBzZWxlemlvbmUgY29pIG51b3ZpIG9nZ2V0dGkgYWx0cmltZW50aSBub24gcml1c2NpcmVpIGEgYmVjY2FyZSBnbGkgaW5kaWNpIGdpdXN0aVxyXG4gICAgICAgICAgICAvLyBEb3BvZGljaMOpIGxhIHVzbyBwZXIgY2FsY29sYXJlIGlzdGFudGFuZWFtZW50ZSBzZSBnbGkgb2dnZXR0aSBzb25vIHNlbGV6aW9uYXRpIG8gbm9cclxuICAgICAgICAgICAgaWYgKHRoaXMuc2VsT3JEZXNlbENhY2hlW2l0bS5oYXNoXSlcclxuICAgICAgICAgICAgICAgIHRoaXMuc2VsT3JEZXNlbENhY2hlW2l0bS5oYXNoXSA9IGl0bTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzZWxlY3Rpb25JdGVtLmFsbClcclxuICAgICAgICAgICAgICAgIGl0bS5fc2VsZWN0ZWQgPSAhdGhpcy5zZWxPckRlc2VsQ2FjaGVbaXRtLmhhc2hdO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICBpdG0uX3NlbGVjdGVkID0gISF0aGlzLnNlbE9yRGVzZWxDYWNoZVtpdG0uaGFzaF07XHJcblxyXG4gICAgICAgICAgICBhbGxTZWxlY3RlZCA9IGFsbFNlbGVjdGVkICYmIGl0bS5fc2VsZWN0ZWQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBTZSB0dXR0aSBnbGkgb2dnZXR0aSBkaSBxdWVzdGEgcGFnaW5hIHNvbm8gc29sZXppb25hdGkgYWxsb3JhIHBvc3NvIG1ldHRlcmUgaWwgZ2xvYmFsIGNoZWNrIGEgdHJ1ZVxyXG4gICAgICAgIC8vIFNlIHNvbm8gaW4gc2l0dWF6aW9uZSBkaSBhbGwtc2VsZWN0IGFuY2hlIG1ldHRvIGxhIGdsb2JhbCBjaGVja2JveCwgbm9ub3N0YW50ZSBjaSBwb3NzYW5vIGVzc2VyZSBkZWxsZSBlc2NsdXNpb25pXHJcbiAgICAgICAgdGhpcy5nbG9iYWxDaGVjayA9IGFsbFNlbGVjdGVkIHx8IHNlbGVjdGlvbkl0ZW0uYWxsO1xyXG4gICAgICAgIHRoaXMuY2FuU2VsZWN0QWxsID0gc2VsZWN0aW9uSXRlbS5jb3VudCA+IDAgJiYgdGhpcy5TZWxlY3RBbGw7XHJcblxyXG4gICAgICAgIC8vIFBvdHJlYmJlIGNhbWJpYXJlIHF1YWxvcmEgcXVhbGN1bm8gaW5zZXJpc3NlIGRhdGkgYSBtYW5henphIGluIG1vZGFsaXTDoCBBcnJheSBlIGRlc3NlIGlsIHJlZnJlc2ggbWFudWFsZSBhbGxhIHRhYmVsbGFcclxuICAgICAgICAvLyBDb211bnF1ZSBjb3N0YSAwIHF1aW5kaSBtaSBwZXJtZXR0byBkaSByZWZyZXNoYXJlXHJcbiAgICAgICAgaWYgKHRoaXMuYXJyYXlNb2RlKSB7XHJcbiAgICAgICAgICAgIGxldCBwcmV2U2VsZWN0ZWQgPSB0aGlzLnNlbGVjdGVkT2JqZWN0cztcclxuICAgICAgICAgICAgdGhpcy5maW5hbGl6ZVNlbGVjdGlvbkluZm9ybWF0aW9ucyhzZWxlY3Rpb25JdGVtKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRPYmplY3RzICE9IHByZXZTZWxlY3RlZClcclxuICAgICAgICAgICAgICAgIHRoaXMub25TZWxlY3Rpb25DaGFuZ2VkLmVtaXQoc2VsZWN0aW9uSXRlbSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGVybWV0dGUgZGkgc2VsZXppb25hcmUgbyBkZXNlbGV6aW9uYXJlIGluIG1hbmllcmEgYXJiaXRyYXJpYSBkZWdsaSBvZ2dldHRpXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55W119IGl0ZW1zIE9nZ2V0dGkgZGEgc2VsZXppb25hcmUgbyBkZXNlbGV6aW9uYXJlXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHNlbGVjdCAqKnRydWUqKiBwZXIgc2VsZXppb25hcmxpLCAqKmZhbHNlKiogcGVyIG5vbiB0b2NjYXJsaVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0U2VsZWN0aW9uU3RhdHVzKGl0ZW1zOiBhbnlbXSwgc2VsZWN0OiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5oYW5kbGVJdGVtc1NlbGVjdGlvbihpdGVtcywgc2VsZWN0KTtcclxuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNlIG5vbiBobyBsJ0lucHV0ICoqRHluYW1pY1Jvd0NvbHVtbnNEZWZpbml0aW9uKiogaW4gbW9kYWxpdMOgIGRpbmFtaWNhIGxvIHJpZW1waW8gY29uIGlsIGRlZmF1bHQgbm9tZSBkZWxsYSBjb2xvbm5hID0gdGVzdG8gZGVsbGEgY29sb25uYVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGV2ZW50dWFsbHlSZXZpZXdEeW5hbWljQ29sdW1ucygpIHtcclxuICAgICAgICAvLyBTZW56YSBvZ2dldHRpIGVzY29cclxuICAgICAgICBpZiAoIXRoaXMuVE1QQm91bmRTb3VyY2UgfHwgdGhpcy5UTVBCb3VuZFNvdXJjZS5sZW5ndGggPT0gMClcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICB2YXIgdXNlR2VuZXJpY0l0ZW1zID0gISF0aGlzLlRNUEJvdW5kU291cmNlWzBdW1wicHJvcGVydGllc1wiXTtcclxuICAgICAgICBpZiAoIXVzZUdlbmVyaWNJdGVtcyB8fCAoIXRoaXMuRmlyc3RCaW5kICYmIHRoaXMuRHluYW1pY1Jvd0NvbHVtbnNEZWZpbml0aW9uICYmIHRoaXMuRHluYW1pY1Jvd0NvbHVtbnNEZWZpbml0aW9uLmxlbmd0aCA+IDApKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGlmICgoIXRoaXMuRHluYW1pY1Jvd0NvbHVtbnNEZWZpbml0aW9uIHx8IHRoaXMuRHluYW1pY1Jvd0NvbHVtbnNEZWZpbml0aW9uLmxlbmd0aCA9PSAwKSkge1xyXG4gICAgICAgICAgICB2YXIgcHJvcHMgPSA8UmVjb3JkPHN0cmluZywgc3RyaW5nPj50aGlzLlRNUEJvdW5kU291cmNlWzBdW1wicHJvcGVydGllc1wiXTtcclxuICAgICAgICAgICAgdGhpcy5EeW5hbWljUm93Q29sdW1uc0RlZmluaXRpb24gPSBbXTtcclxuICAgICAgICAgICAgZm9yIChsZXQga2V5IGluIHByb3BzKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5EeW5hbWljUm93Q29sdW1uc0RlZmluaXRpb24ucHVzaChuZXcgRXNUYWJsZUNvbHVtbnNEZWZpbml0aW9uKGtleSwga2V5KSlcclxuICAgICAgICAgICAgdGhpcy5Vc2VyRGVmaW5lZER5bmFtaWNDb2xzID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgdGhpcy5Vc2VyRGVmaW5lZER5bmFtaWNDb2xzID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBhcnRlbmRvIGRhZ2xpICoqRXNUaHMqKiBlc3RyYXBwb2xvIGxhIGxpc3RhIGRpICoqRXNUYWJsZUNvbHVtbioqIGNoZSBxdWVzdGEgdGFiZWxsYSBkb3Zyw6AgZXZlbnR1YWxtZW50ZSBnZXN0aXJlIHBlciBWaXNpYmlsaXTDoCBlIE9yZGluZVxyXG4gICAgICpcclxuICAgICAqIENvc3RvOiAxIHNjYW4gRXNUaHNcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXX0gdGhzIENvbG9ubmUgZGVsbGEgdGFiZWxsYVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHJldmlld0NvbHVtbnNMaXN0KHRoczogRXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdKSB7XHJcbiAgICAgICAgdGhpcy5Db2x1bW5zTGlzdCA9IFtdO1xyXG4gICAgICAgIGlmICh0aHMubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gQXBwZW5hIGlsIGNvbnRlbnRDaGlsZHJlbiDDqCB2YWxvcml6emF0byBzY29ycm8gdHV0dGkgZ2xpIGhlYWRlclxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzRXNUaCh0aCkpIHtcclxuICAgICAgICAgICAgICAgIC8vIFNlIG5vbiBobyB1biBpZCBpbCB0aCDDqCBjb25zaWRlcmF0byBpbmVydGVcclxuICAgICAgICAgICAgICAgIGlmICghdGguSUQpXHJcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcblxyXG4gICAgICAgICAgICAgICAgdGguT3JkZXJCeSA9IHRoaXMuT3JkZXJCeUNvbHVtbjtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTYWx2byBsZSBpbmZvcm1hemlvbmkgZGVsbCdoZWFkZXIgcGVyIGZhciBwYXJ0ZSBkZWxsYSBsaXN0YSBkYSBjdWkgc2NlZ2xpZXJlIHF1YWxpIGNvbG9ubmUgdmlzdWFsaXp6YXJlL25hc2NvbmRlcmVcclxuICAgICAgICAgICAgICAgIC8vIERpIGRlZmF1bHQgbGEgdmlzaWJpbGl0w6Agw6ggcXVlbGxhIGltcG9zdGF0YSBuZWwgY29tcG9uZW50ZVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuSGlkZGVuQ29sdW1ucyB8fCB0aC5WaXNpYmxlKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuQ29sdW1uc0xpc3QucHVzaChuZXcgRXNUYWJsZUNvbHVtbih0aC5JRCwgdGguRGVzY3JpcHRpb24sIHRoLlZpc2libGUsIHRoLkZpeGVkLCBudWxsKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBTZSBub24gaG8gdW4gaWQgaWwgdGggw6ggY29uc2lkZXJhdG8gaW5lcnRlXHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoLnRoKVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFNhbHZvIGxlIGluZm9ybWF6aW9uaSBkZWxsJ2hlYWRlciBwZXIgZmFyIHBhcnRlIGRlbGxhIGxpc3RhIGRhIGN1aSBzY2VnbGllcmUgcXVhbGkgY29sb25uZSB2aXN1YWxpenphcmUvbmFzY29uZGVyZVxyXG4gICAgICAgICAgICAgICAgLy8gRGkgZGVmYXVsdCBsYSB2aXNpYmlsaXTDoCDDqCBxdWVsbGEgaW1wb3N0YXRhIG5lbCBjb21wb25lbnRlXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5IaWRkZW5Db2x1bW5zIHx8IHRoLnRoVmlzaWJsZSlcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLkNvbHVtbnNMaXN0LnB1c2gobmV3IEVzVGFibGVDb2x1bW4odGgudGgsIG51bGwsIHRoLnRoVmlzaWJsZSwgdGgudGhGaXhlZCwgdGguVGVtcGxhdGUpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlcm1pbmF0byBpbCBiaW5kaW5nIGRlbGxlIGNvbG9ubmUgZGEgKipyZXZpZXdDb2x1bW5zTGlzdCoqIGUgZGVsbGEgKipWaWV3KiogZGFsICoqd3JpdGVWYWx1ZSoqIHF1ZXN0byBtZXRvZG8gc2kgb2NjdXBhXHJcbiAgICAgKiBkZWxsJ2FsbGluZWFtZW50byBkZWxsZSBpbmZvcm1hemlvbmkgZnJhIGxlIGNvbG9ubmUgY2FsY29sYXRlIGludGVybmFtZW50ZSBlIGxlIGluZm9ybWF6aW9uaSBzdWxsZSBjb2xvbm5lIGNoZSBhcnJpdmFubyBkYWxsJ0FwcFNlYXJjaFxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7QXBwU2VhcmNoPGFueT59IHZpZXcgQXBwU2VhcmNoIGRhIHV0aWxpenphcmUgcGVyIHF1ZXN0YSBvcGVyYXppb25lXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgYWxpZ25Db2x1bW5zSWZMb2FkZWRWaWV3KHZpZXc6IEFwcFNlYXJjaDxhbnk+KSB7XHJcbiAgICAgICAgbGV0IGVtaXRDaGFuZ2VkID0gdmlldy5zYXZlZHN0YXRlO1xyXG4gICAgICAgIGxldCBuZXdDb2xzZXQgPSBbXTtcclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLkNvbHVtbnNMaXN0IHx8IHRoaXMuQ29sdW1uc0xpc3QubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgdGhpcy5Db2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4ge1xyXG4gICAgICAgICAgICBsZXQgZXhDbCA9IHZpZXcuY29sdW1ucy5maWx0ZXIoY2MgPT4gY2MgPT0gYy5pZCk7XHJcblxyXG4gICAgICAgICAgICAvLyBTZSBsJ2FwcHNlYXJjaCB2aWVuZSBkYSB1bm8gc3RhdG8gcHJlY2VkZW50ZSwgdXNvIGxlIGluZm9ybWFpem9uaSBzdWxsZSBjb2xvbm5lIGNoZSBoYSBkZW50cm8sIGFsdHJpbWVudGkgc292cmFzY3Jpdm8gdHV0dG8gICoqXHJcbiAgICAgICAgICAgIGlmIChjLnZpc2libGUgJiYgdmlldy5jb2x1bW5zLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICAgICAgbmV3Q29sc2V0LnB1c2goYy5pZCk7XHJcblxyXG4gICAgICAgICAgICAvLyBTZSBobyB1bmEgY29sb25uYSBsYXRvIEFwcFNlYXJjaCBlIG5lbGxhIENvbHVtbkxpc3Qgbm9uIMOoIHZpc2liaWxlLCBhbGxpbmVvIGFsbCdBcHBTZWFyY2hcclxuICAgICAgICAgICAgZWxzZSBpZiAoZXhDbC5sZW5ndGggPT0gMSAmJiAhYy52aXNpYmxlKVxyXG4gICAgICAgICAgICAgICAgYy52aXNpYmxlID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIC8vIEFsbGluZWFtZW50byBzdWxsJ0FwcFNlYXJjaCBwZXIgY2FzaXN0aWNoZSBpbnZlcnNlIGFsIGRpIHNvcHJhXHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGV4Q2wubGVuZ3RoID09IDAgJiYgYy52aXNpYmxlKVxyXG4gICAgICAgICAgICAgICAgYy52aXNpYmxlID0gZmFsc2U7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIE5vbiBobyBjb2xvbm5lIG5lbGxhIGFwcHNlYXJjaCwgdnVvbCBkaXJlIGNoZSBzb25vIGFsIHByaW1vIGJpbmRpbmdcclxuICAgICAgICBpZiAodmlldy5jb2x1bW5zLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICB2aWV3LmNvbHVtbnMgPSBuZXdDb2xzZXQ7XHJcblxyXG4gICAgICAgIGlmICh2aWV3LnNhdmVkc3RhdGUgJiYgdGhpcy5Db2x1bW5zT3JkZXJpbmcgJiYgdmlldy5jb2x1bW5fb3JkZXJpbmcubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBsZXQgbmV3Q29sTGlzdCA9IFtdO1xyXG4gICAgICAgICAgICAvLyBTY29ycm8gZ2xpIG9yZGluYW1lbnRpIGNoZSBhdmV2byBzYWx2YXRvIGUgcmljcmVvIGxhIENvbHVtbnNMaXN0IGluIGJhc2UgYSBsb3JvXHJcbiAgICAgICAgICAgIHZpZXcuY29sdW1uX29yZGVyaW5nLmZvckVhY2goY28gPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5Db2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjLmlkID09IGNvKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdDb2xMaXN0LnB1c2goYyk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLkNvbHVtbnNMaXN0ID0gbmV3Q29sTGlzdDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEluIG9nbmkgY2FzbyBxdWVzdG8gbm9uIG1pIHNlcnZlIHBpw7ksIGxvIHJlc2V0dG8gICoqXHJcbiAgICAgICAgdmlldy5zYXZlZHN0YXRlID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGlmIChlbWl0Q2hhbmdlZClcclxuICAgICAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gY2hlIGdlc3Rpc2NlIGlsIGNhbWJpbyBkaSBPcmRpbmFtZW50byBkaSB1bmEgY29sb25uYVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBJRCBkZWxsYSBjb2xvbm5hIGlsIGN1aSBvcmlkbmFtZW50byDDqCBjYW1iaWF0b1xyXG4gICAgICogQHBhcmFtIHsnREVTQycgfCAnQVNDJ30gb3JkZXIgTnVvdm8gb3JkaW5lIHNlbGV6aW9uYXRvIHBlciBsYSBjb2xvbm5hXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB0aE9yZGVyQ2hhbmdlZChpZDogc3RyaW5nLCBvcmRlcj86ICdERVNDJyB8ICdBU0MnKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnZpZXdNb2RlKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignT3JkZXIgY2hhbmdlZCBvbiBhIHRhYmxlIG5vdCBpbiB2aWV3TW9kZS4gT3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQnKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLk9yZGVyQnlDb2x1bW4pXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgbGV0IGFwcFNlYXJjaCA9IHRoaXMuVmlldyBhcyBBcHBTZWFyY2g8YW55PjtcclxuICAgICAgICBsZXQgb3JkZXJUb0FkZCA9IHRydWU7XHJcbiAgICAgICAgbGV0IG9yZGVyVG9SZW1vdmU6IG51bWJlciA9IG51bGw7XHJcblxyXG4gICAgICAgIC8vIFNlIHBlciBxdWFsY2hlIG1vdGl2byBpbCBjb3N0cnV0dG9yZSBub24gw6ggcGFzc2F0byAoY2FjaGUgdGFycGF0ZSBvIHNpbWlsYSkgZml4b1xyXG4gICAgICAgIGlmICghYXBwU2VhcmNoLm9yZGVycylcclxuICAgICAgICAgICAgYXBwU2VhcmNoLm9yZGVycyA9IFtdO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFwcFNlYXJjaC5vcmRlcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHQgPSBhcHBTZWFyY2gub3JkZXJzW2ldO1xyXG4gICAgICAgICAgICBpZiAodC5pZCA9PSBpZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG9yZGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdC5vcmRlciA9IG9yZGVyO1xyXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyVG9BZGQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBvcmRlclRvUmVtb3ZlID0gaTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKG9yZGVyVG9SZW1vdmUgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICBhcHBTZWFyY2gub3JkZXJzLnNwbGljZShvcmRlclRvUmVtb3ZlLCAxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAob3JkZXJUb0FkZCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5NdWx0aXBsZU9yZGVyaW5nRGlyZWN0aXZlcylcclxuICAgICAgICAgICAgICAgIGFwcFNlYXJjaC5vcmRlcnMucHVzaChuZXcgQXBwT3JkZXJpbmcoaWQsIG9yZGVyKSk7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIGFwcFNlYXJjaC5vcmRlcnMgPSBbbmV3IEFwcE9yZGVyaW5nKGlkLCBvcmRlcildO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5vbk9yZGVyQ2hhbmdlZC5lbWl0KHsgaWQsIG9yZGVyIH0pO1xyXG4gICAgICAgIHRoaXMuZW1pdFNlYXJjaFJlcXVlc3QoZmFsc2UpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGRhIGNoaWFtYXJlIG9nbmkgdm9sdGEgY2hlIHNpIHZ1b2xlIGRhcmUgZXZpZGVuemEgYWxsJ2VzdGVybm8gZGVsIGJpc29nbm8gZGkgcmllZmZldHR1YXJlIGxhIHJpY2VyY2FcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBlbWl0U2VhcmNoUmVxdWVzdCh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgICAgIGlmICh0aGlzLnZpZXdNb2RlKSB7XHJcbiAgICAgICAgICAgICh0aGlzLlZpZXcgYXMgQXBwU2VhcmNoPGFueT4pLmludGVybmFsc2VhcmNocmVxdWVzdCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlZCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnJlc2VhcmNoSW5Qcm9ncmVzcyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5vblNlYXJjaFJlcXVlc3QuZW1pdCh2YWx1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbiBiYXNlIGFsbGEgdmlzaWJpbGl0w6AgcmVnaXN0cmF0YSBuZWxsZSAqKkNvbHVtbnNMaXN0KiogcXVlc3RvIG1ldG9kbyBzaSBvY2N1cGEgZGkgcHJlbmRlcmUgdHV0dGkgaSAqKkVzVGhzKiogZWQgKipFc1RkcyoqIHJlbGF0aXZpIGUgbmFzb25kZXJsaS9tb3N0cmFybGlcclxuICAgICAqXHJcbiAgICAgKiBDb3N0bzogMSBzY2FuIENvbHVtbnNMaXN0LCAxIHNjYW4gRXNUaHMsIDEgc2NhbiBFc1Rkc1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdfSB0aHMgSGVhZGVyIGRlbGxhIHRhYmVsbGFcclxuICAgICAqIEBwYXJhbSB7RXNUZFtdIHwgRXNUZERpcmVjdGl2ZVtdfSB0ZHMgQ2VsbGUgZGVsbGEgdGFiZWxsYVxyXG4gICAgICogQHBhcmFtIHtBcHBTZWFyY2g8YW55Pn0gdmlldyBBcHBTZWFyY2ggZGEgdXRpbGl6emFyZSBwZXIgcXVlc3RhIG9wZXJhemlvbmVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSByZWZyZXNoQ29sdW1uc1Zpc2liaWxpdHkodGhzOiBFc1RoW10gfCBFc1RoRGlyZWN0aXZlW10sIHRkczogRXNUZFtdIHwgRXNUZERpcmVjdGl2ZVtdLCB2aWV3OiBBcHBTZWFyY2g8YW55Pikge1xyXG4gICAgICAgIGxldCBjb2x1bW5zQ2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBFc1RhYmxlQ29sdW1uIH0gPSB7fTtcclxuICAgICAgICBsZXQgbmV3Q29sc2V0ID0gW107XHJcbiAgICAgICAgbGV0IGZpeGVkVGhzOiB7IFtpZDogc3RyaW5nXTogYm9vbGVhbiB9ID0ge307XHJcbiAgICAgICAgZm9yIChsZXQgY29saSA9IDA7IGNvbGkgPCB0aGlzLkNvbHVtbnNMaXN0Lmxlbmd0aDsgY29saSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBjb2wgPSB0aGlzLkNvbHVtbnNMaXN0W2NvbGldO1xyXG4gICAgICAgICAgICBjb2x1bW5zQ2FjaGVbY29sLmlkXSA9IGNvbDtcclxuICAgICAgICAgICAgaWYgKGNvbC52aXNpYmxlKSBuZXdDb2xzZXQucHVzaChjb2wuaWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2aWV3LmNvbHVtbnMgPSBuZXdDb2xzZXQ7XHJcblxyXG4gICAgICAgIC8vIERhIHF1aSBpbiBwb2kgZGV2b25vIGVzc2VyZSBlc2VndWl0aSBTT0xPIGluIGZhc2UgZGkgd3JpdGVWYWx1ZSBxdWluZGkgZGV2byBhc3NpY3VyYXJtaSBkaSBwYXNzYXJsaSBudWxsIGluIHR1dHRpIGkgcGFzc2FnZ2kgZGl2ZXJzaSBkYSBxdWVsbG9cclxuICAgICAgICBpZiAodGhzKSB7XHJcbiAgICAgICAgICAgIC8vIERlZmluaXNjbyBzZSBsYSBjb2xvbm5hIMOoIHZpc2liaWxlIGluIGJhc2UgYWxsYSBzdWEgcmFwcHJlc2VudGF6aW9uZSBsb2NhbGUgaW4gQ29sdW1uc0xpc3RcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNFc1RoKHRoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoLlZpc2libGUgPSB0aC5GaXhlZCB8fCAoY29sdW1uc0NhY2hlW3RoLklEXSA/IGNvbHVtbnNDYWNoZVt0aC5JRF0udmlzaWJsZSA6IHRoLlZpc2libGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aC5GaXhlZCkgZml4ZWRUaHNbdGguSURdID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoLnRoVmlzaWJsZSA9IHRoLnRoRml4ZWQgfHwgKGNvbHVtbnNDYWNoZVt0aC50aF0gPyBjb2x1bW5zQ2FjaGVbdGgudGhdLnZpc2libGUgOiB0aC50aFZpc2libGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aC50aEZpeGVkKSBmaXhlZFRoc1t0aC50aF0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGRzKSB7XHJcbiAgICAgICAgICAgIC8vIERlZmluaXNjbyBzZSBsYSBjZWxsYSDDqCB2aXNpYmlsZSBpbiBiYXNlIGFsbGEgc3VhIHJhcHByZXNlbnRhemlvbmUgbG9jYWxlIGluIENvbHVtbnNMaXN0XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgdGQgPSB0ZHNbaV07XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNFc1RkKHRkKSlcclxuICAgICAgICAgICAgICAgICAgICB0ZC5WaXNpYmxlID0gZml4ZWRUaHNbdGQuSURdIHx8IChjb2x1bW5zQ2FjaGVbdGQuSURdID8gY29sdW1uc0NhY2hlW3RkLklEXS52aXNpYmxlIDogdGQuVmlzaWJsZSk7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgdGQudGRWaXNpYmxlID0gZml4ZWRUaHNbdGQudGRdIHx8IChjb2x1bW5zQ2FjaGVbdGQudGRdID8gY29sdW1uc0NhY2hlW3RkLnRkXS52aXNpYmxlIDogdGQudGRWaXNpYmxlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBcclxuICAgICAqL1xyXG4gICAgaXNFc1RkKHRkOiBhbnkpOiB0ZCBpcyBFc1RkIHtcclxuICAgICAgICByZXR1cm4gIXRkLl9kaXJlY3RpdmU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBcclxuICAgICAqL1xyXG4gICAgaXNFc1RoKHRoOiBhbnkpOiB0aCBpcyBFc1RoIHtcclxuICAgICAgICByZXR1cm4gIXRoLl9kaXJlY3RpdmU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGxpbmVhIGdsaSBvcmRpbmFtZW50aSBkYXRpIGZyYSBsZSAqKkVzVGhzKiogZSBsZSBpbmZvcm1hemlvbmkgYWxsJ2ludGVybm8gZGVsbGEgVmlldyBiaW5kYXRhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtBcHBTZWFyY2g8YW55Pn0gdmlldyBBcHBTZWFyY2ggZGEgdXRpbGl6emFyZSBwZXIgcXVlc3RhIG9wZXJhemlvbmVcclxuICAgICAqIEBwYXJhbSB7RXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdfSB0aHMgQ29sb25uZSBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgYWxpZ25IZWFkZXJzT3JkZXJpbmcodGhzOiBFc1RoW10gfCBFc1RoRGlyZWN0aXZlW10sIHZpZXc6IEFwcFNlYXJjaDxhbnk+KSB7XHJcbiAgICAgICAgbGV0IHJlc2VhcmNoTmVlZGVkID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzRXNUaCh0aCkpIHtcclxuICAgICAgICAgICAgICAgIHRoLk9yZGVyID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBBc3NlZ25vIHR1dHRpIGdsaSBvcmRpbmFtZW50aSBjaGUgbWkgdmVuZ29ubyBkYSBBcHBTZWFyY2guIFNvbm8gaSBwacO5IGltcG9ydGFudGkuIE5vbiBmYWNjaW8gY2FjaGUgbyBjb3NlIHN0cmFubyBwZXJjaMOpIHRhbnRvIHF1ZXN0YVxyXG4gICAgICAgICAgICAgICAgLy8gdmFyaWFiaWxlIHNhcsOgIHNlbXByZSBtYXNzaW1vIDMgZWxlbWVudGlcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmlldy5vcmRlcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgb3IgPSB2aWV3Lm9yZGVyc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob3IuaWQgPT0gdGguSUQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoLk9yZGVyID0gb3Iub3JkZXI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aC50aE9yZGVyID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmlldy5vcmRlcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgb3IgPSB2aWV3Lm9yZGVyc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob3IuaWQgPT0gdGgudGgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoLnRoT3JkZXIgPSBvci5vcmRlcjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHJlc2VhcmNoTmVlZGVkKVxyXG4gICAgICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KGZhbHNlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBhcnRlbmRvIGRhZ2xpICoqRXNUZHMqKiBiaW5kYXRpIGdlbmVyYSwgYWxsJ2ludGVybm8gZGVsIGRpemlvbmFyaW8gKipUTVBSb3dURHMqKiB0dXR0aSBpIGNvbnRlc3RpIGRlaSB2YXJpIG9nZ2V0dGkuXHJcbiAgICAgKlxyXG4gICAgICogVmVuZ29ubyBlc2NsdXNpIGkgVEQgXCJJbnRlcm5pXCIgaW4gcXVhbnRvIHZlbmdvbm8gZ2VuZXJhdGkgZGFnbGkgb3JpZ2luYWxpIHF1aW5kaSBpbmNsdWRlcmxpIHZvcnJlYmJlIGRpcmUgcmllZmZldHR1YXJlIGxlIG9wZXJhemlvbmkgZHVlIHZvbHRlXHJcbiAgICAgKlxyXG4gICAgICogQ29zdG86IDIgc2NhbiBFc1RocywgMSBzY2FuIEVzVGRzXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RoW10gfCBFc1RoRGlyZWN0aXZlW119IHRocyBDb2xvbm5lIGRlbGxhIHRhYmVsbGFcclxuICAgICAqIEBwYXJhbSB7RXNUZFtdIHwgRXNUZERpcmVjdGl2ZVtdfSB0ZHMgQ2VsbGUgZGVsbGEgdGFiZWxsYVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGV2YWx1YXRlUm93VGRzKHRoczogRXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdLCB0ZHM6IEVzVGRbXSB8IEVzVGREaXJlY3RpdmVbXSkge1xyXG4gICAgICAgIGlmICh0ZHMubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgbGV0IHRoc0NhY2hlOiB7IFtpbmRleDogc3RyaW5nXTogRXNUaCB8IEVzVGhEaXJlY3RpdmUgfSA9IHt9O1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcbiAgICAgICAgICAgIHRoc0NhY2hlW3RoaXMuaXNFc1RoKHRoKSA/IHRoLklEIDogdGgudGhdID0gdGg7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLlRNUFJvd1REcyA9IHt9O1xyXG4gICAgICAgIC8vIFZhcmlhYmlsZSBkJ2FwcG9nZ2lvIHBlciBwZXJtZXR0ZXJtaSBkaSBpbnNlcmlyZSB0dXR0ZSBsZSBjb2xvbm5lIFwiRml4ZWRcIiBkYXZhbnRpXHJcbiAgICAgICAgbGV0IGNvbnRleHRGaXhlZHM6IHsgW2NvbnRleHQ6IHN0cmluZ106IG51bWJlciB9ID0ge307XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRkID0gdGRzW2ldO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuaXNFc1RkKHRkKSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IHRoID0gdGhzQ2FjaGVbdGQuSURdO1xyXG4gICAgICAgICAgICAgICAgaWYgKCEhdGgpXHJcbiAgICAgICAgICAgICAgICAgICAgdGguUmVmZXJlbmNlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgXCJJRCBkZWxsJ29nZ2V0byBFc1RkIG5vbiBjb21wYXRpYmlsZSBjb24gZ2xpIElEIGRpY2hhcmF0aSBuZWdsaSBFc1RoOiBcIiArIHRkLklEO1xyXG5cclxuICAgICAgICAgICAgICAgIGxldCBpc0ZpeGVkID0gKHRoaXMuaXNFc1RoKHRoKSAmJiB0aC5GaXhlZCkgfHwgKCF0aGlzLmlzRXNUaCh0aCkgJiYgdGgudGhGaXhlZCk7XHJcbiAgICAgICAgICAgICAgICBsZXQgaXRlbVRvQWRkID0gPGFueT57IElEOiB0ZC5JRCwgVmlzaWJsZTogdGQuVmlzaWJsZSwgQ2xhc3M6IHRkLkNsYXNzLCBDb250ZW50OiB0ZC5Db250ZW50LCBSb3V0ZXJMaW5rOiB0ZC5Sb3V0ZXJMaW5rLCBUZW1wbGF0ZTogdGQuVGVtcGxhdGUgfTtcclxuICAgICAgICAgICAgICAgIGxldCBjdHggPSB0ZC5Db250ZXh0O1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuVE1QUm93VERzW2N0eF0pIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNGaXhlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5UTVBSb3dURHNbY3R4XS5zcGxpY2UoMCArIChjb250ZXh0Rml4ZWRzW2N0eF0rKyksIDAsIGl0ZW1Ub0FkZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLlRNUFJvd1REc1tjdHhdLnB1c2goaXRlbVRvQWRkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuUm93Q29udGV4dHMucHVzaChjdHgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuVE1QUm93VERzW2N0eF0gPSBbaXRlbVRvQWRkXTtcclxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0Rml4ZWRzW2N0eF0gPSBpc0ZpeGVkID8gMSA6IDBcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5UTVBCb3VuZFNvdXJjZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBjdHggPSB0aGlzLlRNUEJvdW5kU291cmNlW2ldLmhhc2hcclxuICAgICAgICAgICAgICAgICAgICBsZXQga2V5ID0gdGQudGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRoID0gdGhzQ2FjaGVbdGQudGRdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghIXRoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aC5SZWZlcmVuY2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFwiSUQgZGVsbCdvZ2dldG8gRXNUZCBub24gY29tcGF0aWJpbGUgY29uIGdsaSBJRCBkaWNoYXJhdGkgbmVnbGkgRXNUaDogXCIgKyB0ZC50ZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRkLnRkSWYpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGlzRml4ZWQgPSAodGhpcy5pc0VzVGgodGgpICYmIHRoLkZpeGVkKSB8fCAoIXRoaXMuaXNFc1RoKHRoKSAmJiB0aC50aEZpeGVkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGl0ZW1Ub0FkZCA9IDxhbnk+eyBJRDoga2V5LCBWaXNpYmxlOiB0ZC50ZFZpc2libGUsIENsYXNzOiB0ZC50ZENsYXNzLCBUZW1wbGF0ZTogdGQuVGVtcGxhdGUgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuVE1QUm93VERzW2N0eF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0ZpeGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuVE1QUm93VERzW2N0eF0uc3BsaWNlKDAgKyAoY29udGV4dEZpeGVkc1tjdHhdKyspLCAwLCBpdGVtVG9BZGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuVE1QUm93VERzW2N0eF0ucHVzaChpdGVtVG9BZGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5Sb3dDb250ZXh0cy5wdXNoKGN0eCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLlRNUFJvd1REc1tjdHhdID0gW2l0ZW1Ub0FkZF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0Rml4ZWRzW2N0eF0gPSBpc0ZpeGVkID8gMSA6IDBcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU2Ugbm9uIGhvIG9nZ2V0dGkgw6ggaW51dGlsZSBjaGUgY29udHJvbGxvIGdsaSBlcnJvcmksIGRhdG8gY2hlIGdsaSBlcy10ZCBub24gZXNpc3RlcmFubm8gZGkgY2VydG8gZSBkaSBjb25zZWd1ZW56YSBnbGkgZXMtdGggbm9uIHNhcmFubm8gcmVmZXJlbnppYXRpXHJcbiAgICAgICAgaWYodGhpcy5UTVBCb3VuZFNvdXJjZS5sZW5ndGggPT0gMClcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICB2YXIgZXJyczogc3RyaW5nW10gPSBbXTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcbiAgICAgICAgICAgIGlmICghdGguUmVmZXJlbmNlZClcclxuICAgICAgICAgICAgICAgIGVycnMucHVzaCh0aGlzLmlzRXNUaCh0aCkgPyB0aC5JRCA6IHRoLnRoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChlcnJzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgdmFyIGVycklkcyA9IGVycnMuam9pbignLCAnKTtcclxuICAgICAgICAgICAgdGhyb3cgXCJMJ0lEIGRpIHVubyBvIHBpw7kgRXNUaCBub24gaGFubm8gYWxjdW4gRXNUZCBhc3NvY2lhdG86IFwiICsgZXJySWRzO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBhcnRlbmRvIGRhZ2xpICoqRXNUaHMqKiBiaW5kYXRpIGdlbmVyYSwgYWxsJ2ludGVybm8gZGVsIGRpemlvbmFyaW8gKipUTVBSb3dUSHMqKiB0dXR0aSBpIGNvbnRlc3RpIGRlaSB2YXJpIG9nZ2V0dGkuXHJcbiAgICAgKlxyXG4gICAgICogVmVuZ29ubyBlc2NsdXNpIGkgVEggXCJJbnRlcm5pXCIgaW4gcXVhbnRvIHZlbmdvbm8gZ2VuZXJhdGkgZGFnbGkgb3JpZ2luYWxpIHF1aW5kaSBpbmNsdWRlcmxpIHZvcnJlYmJlIGRpcmUgcmllZmZldHR1YXJlIGxlIG9wZXJhemlvbmkgZHVlIHZvbHRlXHJcbiAgICAgKlxyXG4gICAgICogQ29zdG86IDEgc2NhbiBFc1Roc1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdfSB0aHMgQ29sb25uZSBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZXZhbHVhdGVSb3dUaHModGhzOiBFc1RoW10gfCBFc1RoRGlyZWN0aXZlW10pIHtcclxuICAgICAgICBpZiAodGhzLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIHRoaXMuVE1QUm93VEhzID0gW107XHJcbiAgICAgICAgbGV0IGZpeGVkID0gMDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcbiAgICAgICAgICAgIGxldCB0b0FkZDtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzRXNUaCh0aCkpIHtcclxuICAgICAgICAgICAgICAgIHRvQWRkID0geyBGaXhlZDogdGguRml4ZWQsIElEOiB0aC5JRCwgVmlzaWJsZTogdGguVmlzaWJsZSwgQ2xhc3M6IHRoLkNsYXNzLCBPcmRlcjogdGguT3JkZXIsIE9yZGVyYWJsZTogdGguT3JkZXJhYmxlLCBUZW1wbGF0ZTogbnVsbCwgQ29udGVudDogdGguRGVzY3JpcHRpb24sIFdyYXA6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBpZiAodGguRml4ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5UTVBSb3dUSHMuc3BsaWNlKDAgKyAoZml4ZWQrKyksIDAsIHRvQWRkKTtcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLlRNUFJvd1RIcy5wdXNoKHRvQWRkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICh0aC50aElmKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBNZW50cmUgaW5zZXJpc2NvIG1pIGFzc2ljdXJvIGRpIG1ldHRlcmUgbCdlbGVtZW50byBwZXIgYmVuZSBpbiBvcmRpbmUgaW4gYmFzZSBhbGxhIHByb3ByaWV0w6AgXCJGaXhlZFwiLiBUdXR0ZSBsZSBjb2xvbm5lIEZpeGVkIGRldm9ubyBmaW5pcmUgYWxsJ2luaXppb1xyXG4gICAgICAgICAgICAgICAgLy8gKFF1ZXN0byBwcm9iYWJpbG1lbnRlIGRpdmVudGVyw6AgaWwgY29tcG9ydGFtZW50byBkaSBkZWZhdWx0IGFuY2hlIHBlciBsZSBjb2xvbm5lIFwiUGlubmVkXCIpXHJcbiAgICAgICAgICAgICAgICB0b0FkZCA9IHsgRml4ZWQ6IHRoLnRoRml4ZWQsIElEOiB0aC50aCwgVmlzaWJsZTogdGgudGhWaXNpYmxlLCBDbGFzczogdGgudGhDbGFzcywgT3JkZXI6IHRoLnRoT3JkZXIsIE9yZGVyYWJsZTogdGgudGhPcmRlcmFibGUsIFRlbXBsYXRlOiB0aC5UZW1wbGF0ZSwgQ29udGVudDogbnVsbCwgV3JhcDogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGlmICh0aC50aEZpeGVkKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuVE1QUm93VEhzLnNwbGljZSgwICsgKGZpeGVkKyspLCAwLCB0b0FkZCk7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5UTVBSb3dUSHMucHVzaCh0b0FkZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gY2hlIGdlbmVyYSBsJ29yZGluZSBkaSBkZWZhdWx0IGRlbGxlIGNvbG9ubmVcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0FwcFNlYXJjaDxhbnk+fSB2aWV3IEFwcFNlYXJjaCBkYSB1dGlsaXp6YXJlIHBlciBxdWVzdGEgb3BlcmF6aW9uZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdlbmVyYXRlRGVmYXVsdE9yZGVyKHZpZXc6IEFwcFNlYXJjaDxhbnk+KSB7XHJcbiAgICAgICAgaWYgKHRoaXMuVE1QUm93VEhzLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIC8vIEdlbmVybyBvcmRpbmFtZW50byBkaSBkZWZhdWx0IGRhIDAgZmlubyBhIGRvdmUgZGV2ZSBhcnJpdmFyZS4gU2l0dWF6aW9uZSBhdHR1YWxlIHNlbnphIGhvdHBvdGF0b1xyXG4gICAgICAgIGlmICghdmlldy5jb2x1bW5fb3JkZXJpbmcgfHwgdmlldy5jb2x1bW5fb3JkZXJpbmcubGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLlRNUFJvd1RIcy5sZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgICAgIHRoaXMuT3JkZXJEaXJlY3RpdmVzLnB1c2godGhpcy5UTVBSb3dUSHNbaV0uSUQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHRoaXMuT3JkZXJEaXJlY3RpdmVzID0gdmlldy5jb2x1bW5fb3JkZXJpbmc7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBcHBsaWNhIGwnb3JkaW5lIHNwZWNpZmljYXRvIGFsbGUgdmFyaWUgY29sb25uZVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7QXBwU2VhcmNoPGFueT59IHZpZXcgQXBwU2VhcmNoIGRhIHV0aWxpenphcmUgcGVyIHF1ZXN0YSBvcGVyYXppb25lXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGZpbmFsaXplIFNlICoqdHJ1ZSoqIHNpZ25pZmljYSBjaGUgbm9uIG1pIGFzcGV0dG8gZGkgZG92ZXIgZWZmZXR0dWFyZSBhbHRyZSBvcGVyYXppb25pIGUgcG9zc28gcmVuZGVyaXp6YXJlIGxhIHNpdHVhemlvbmUgaW4gYmFzZSBhaSBSb3dDb250ZXh0XHJcbiAgICAgKiBTZW56YSBmaW5hbGl6ZSBzaWduaWZpY2EgY2hlIG1pIGFzcGV0dG8gYWx0cmUgb3BlcmF6aW9uaSBjaGUgcHJpbWEgbyBwb2kgcmljaGlhbWVyYW5ubyBxdWVzdGEgZnVuemlvbmUgY29sIGZpbmFsaXplLlxyXG4gICAgICpcclxuICAgICAqIEFkIGVzZW1waW8sIHVuYSB2b2x0YSBzZWxlemlvbmF0byBvcmRpbmFtZW50byBmaXNpY28vbG9naWNvIGRlbGxlIGNvbG9ubmUgc28gY2hlIHBhcnRlIHVuIGFsdHJhIHJpY2VyY2EgY2hlIG1pIHJpdmFsb3JpenplcmEgZGEgXCJ3cml0ZVZhbHVlXCIsIGNoZSBnacOgIGNoaWFtYSBxdWVzdGEgZnVuemlvbmUuXHJcbiAgICAgKiBNZXR0ZW5kbyBzb2xvIGxhIGNoaWFtYXRhIGRhIFwid3JpdGVWYWx1ZVwiIGNvbWUgXCJmaW5hbGl6emFudGVcIiBtaSBhc3NpY3VybyBjaGUgc21hbmF0dGFtZW50aSBhIGZyb250ZW5kIG5vbiBjYXVzaW5vIGZsaWNrZXJpbmcgZmlubyBhIHF1YW5kbyBub24gc2Vydm9ub1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGFwcGx5T3JkZXJpbmcodmlldzogQXBwU2VhcmNoPGFueT4sIGZpbmFsaXplOiBib29sZWFuKSB7XHJcbiAgICAgICAgLy8gR2VuZXJvIG9yZGluYW1lbnRvIHBlciBnbGkgaGVhZGVyXHJcbiAgICAgICAgbGV0IG5ld0hlYWRlcnMgPSBbXTtcclxuXHJcbiAgICAgICAgLy8gU2UgZGV2byBmaW5hbGl6emFyZSBhZ2dhbmNpbyB0dXR0ZSBsZSB2YXJpYWJpbGkgZGkgYmluZFxyXG4gICAgICAgIGlmIChmaW5hbGl6ZSkge1xyXG4gICAgICAgICAgICB0aGlzLk9yZGVyRGlyZWN0aXZlcy5mb3JFYWNoKG8gPT4ge1xyXG4gICAgICAgICAgICAgICAgbGV0IGhlYWVkckl0ZW0gPSB0aGlzLlRNUFJvd1RIcy5maWx0ZXIodCA9PiB0LklEID09IG8pWzBdO1xyXG4gICAgICAgICAgICAgICAgbmV3SGVhZGVycy5wdXNoKGhlYWVkckl0ZW0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy5UTVBSb3dUSHMgPSBuZXdIZWFkZXJzO1xyXG5cclxuICAgICAgICAgICAgLy8gR2VuZXJvIG9yZGluYW1lbnRvIHBlciBsZSBjZWxsZVxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuUm93Q29udGV4dHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCBjb250ZXh0ID0gdGhpcy5UTVBSb3dURHNbdGhpcy5Sb3dDb250ZXh0c1tpXV07XHJcbiAgICAgICAgICAgICAgICBsZXQgbmV3Q29udGV4dCA9IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuT3JkZXJEaXJlY3RpdmVzLmZvckVhY2gobyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbnRleHRJdGVtID0gY29udGV4dC5maWx0ZXIodCA9PiB0LklEID09IG8pWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIG5ld0NvbnRleHQucHVzaChjb250ZXh0SXRlbSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLlRNUFJvd1REc1t0aGlzLlJvd0NvbnRleHRzW2ldXSA9IG5ld0NvbnRleHQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZpZXcuY29sdW1uX29yZGVyaW5nID0gdGhpcy5PcmRlckRpcmVjdGl2ZXM7XHJcbiAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gI2VuZHJlZ2lvblxyXG5cclxuICAgIC8vICNyZWdpb24gR2VzdGlvbmUgT3BlcmFpem9uaSBkaWFsb2cgb3JkaW5hbWVudG8vdmlzaWJpbGl0w6AgY29sb25uZVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsJ2ludGVybm8gZGVsbGEgZGlhbG9nIFwiT3JkaW5hbWVudG8gZSBWaXNpYmlsaXTDoCBDb2xvbm5lXCIgbWV0dGUgbGEgY29sb25uYSBzcGVjaWZpY2F0YSBwcmltYSBkZWxsYSBjb2xvbm5hIHByZWNlZGVudGVcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VzVGFibGVDb2x1bW59IGNvbHVtbkl0ZW0gQ29sb25uYSBkYSBzcG9zdGFyZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2VuZFVwKGNvbHVtbkl0ZW06IEVzVGFibGVDb2x1bW4pIHtcclxuICAgICAgICBsZXQgaXRlbUluZGV4ID0gdGhpcy5UTVBDb2x1bW5zTGlzdC5pbmRleE9mKGNvbHVtbkl0ZW0pO1xyXG4gICAgICAgIGlmICh0aGlzLlRNUENvbHVtbnNMaXN0W2l0ZW1JbmRleCAtIDFdLmZpeGVkKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgdGhpcy51dGlFeHRzLnN3YXAodGhpcy5UTVBDb2x1bW5zTGlzdCwgaXRlbUluZGV4LCBpdGVtSW5kZXggLSAxKTtcclxuXHJcbiAgICAgICAgLy8gTm9uIHBvc3NvIGZhcmUgSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLkNvbHVtbnNMaXN0KSkgcGVyY2jDqSBjb250aWVuZSByaWZlcmltZW50aSBhIFRlbXBsYXRlUmVmXHJcbiAgICAgICAgbGV0IHRtcCA9IFtdO1xyXG4gICAgICAgIHRoaXMuVE1QQ29sdW1uc0xpc3QuZm9yRWFjaChjID0+IHsgdG1wLnB1c2goT2JqZWN0LmFzc2lnbih7fSwgYykpOyB9KTtcclxuICAgICAgICB0aGlzLlRNUENvbHVtbnNMaXN0ID0gdG1wO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsJ2ludGVybm8gZGVsbGEgZGlhbG9nIFwiT3JkaW5hbWVudG8gZSBWaXNpYmlsaXTDoCBDb2xvbm5lXCIgbWV0dGUgbGEgY29sb25uYSBzcGVjaWZpY2F0YSBkb3BvIGxhIGNvbG9ubmEgc3VjY2Vzc2l2YVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUYWJsZUNvbHVtbn0gY29sdW1uSXRlbSBDb2xvbm5hIGRhIHNwb3N0YXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZW5kRG93bihjb2x1bW5JdGVtOiBFc1RhYmxlQ29sdW1uKSB7XHJcbiAgICAgICAgbGV0IGl0ZW1JbmRleCA9IHRoaXMuVE1QQ29sdW1uc0xpc3QuaW5kZXhPZihjb2x1bW5JdGVtKTtcclxuICAgICAgICB0aGlzLnV0aUV4dHMuc3dhcCh0aGlzLlRNUENvbHVtbnNMaXN0LCBpdGVtSW5kZXgsIGl0ZW1JbmRleCArIDEpO1xyXG5cclxuICAgICAgICAvLyBOb24gcG9zc28gZmFyZSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMuQ29sdW1uc0xpc3QpKSBwZXJjaMOpIGNvbnRpZW5lIHJpZmVyaW1lbnRpIGEgVGVtcGxhdGVSZWZcclxuICAgICAgICBsZXQgdG1wID0gW107XHJcbiAgICAgICAgdGhpcy5UTVBDb2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4geyB0bXAucHVzaChPYmplY3QuYXNzaWduKHt9LCBjKSk7IH0pO1xyXG4gICAgICAgIHRoaXMuVE1QQ29sdW1uc0xpc3QgPSB0bXA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGwnaW50ZXJubyBkZWxsYSBkaWFsb2cgXCJPcmRpbmFtZW50byBlIFZpc2liaWxpdMOgIENvbG9ubmVcIiBpbnZlcnRlIGxlIGltcG9zdGF6aW9uaSBkaSB2aXNpYmlsaXTDoCBkZWxsYSBjb2xvbm5hXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RhYmxlQ29sdW1ufSBjb2x1bW5JdGVtIENvbG9ubmEgZGEgc3Bvc3RhcmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvbHVtbkNsaWNrZWQoaXRlbTogRXNUYWJsZUNvbHVtbikge1xyXG4gICAgICAgIHRoaXMubGFzdFNlbGVjdGVkSXRlbUlEID0gaXRlbS5pZDtcclxuICAgICAgICBpZiAoIXRoaXMuSGlkZGVuQ29sdW1ucyB8fCBpdGVtLmZpeGVkKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGl0ZW0udmlzaWJsZSA9ICFpdGVtLnZpc2libGU7XHJcbiAgICAgICAgdGhpcy51cGRhdGVHbG9iYWxDb2xWaXNDaGVjaygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsJ2FwZXJ0dXJhIGRlbGxhIGRpYWxvZyBcIk9yZGluYW1lbnRvIGUgVmlzaWJpbGl0w6AgQ29sb25uZVwiIHJpY2FyaWNhIGxlIGluZm9ybWF6aW9uaSBhdHR1YWxpIHBlciBwZXJtZXR0ZXJlIGxhIG1vZGlmaWNhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZXNldENvbHVtblZpc1NlbGVjdGlvbigpIHtcclxuICAgICAgICB0aGlzLlRNUENvbHVtbnNMaXN0ID0gW107XHJcbiAgICAgICAgLy8gTm9uIHBvc3NvIGZhcmUgSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLkNvbHVtbnNMaXN0KSkgcGVyY2jDqSBjb250aWVuZSByaWZlcmltZW50aSBhIFRlbXBsYXRlUmVmXHJcblxyXG4gICAgICAgIHRoaXMuVE1QQ29sdW1uc0xpc3QgPSBbXTtcclxuICAgICAgICB0aGlzLkNvbHVtbnNMaXN0LmZvckVhY2goYyA9PiB7IHRoaXMuVE1QQ29sdW1uc0xpc3QucHVzaChPYmplY3QuYXNzaWduKHt9LCBjKSk7IH0pO1xyXG5cclxuICAgICAgICBsZXQgcmVvcmRlcmVkQ29sTGlzdCA9IFtdO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5Db2x1bW5zT3JkZXJpbmcpIHtcclxuICAgICAgICAgICAgdGhpcy5PcmRlckRpcmVjdGl2ZXMuZm9yRWFjaChvID0+IHtcclxuICAgICAgICAgICAgICAgIGxldCBjb2x1bW4gPSB0aGlzLlRNUENvbHVtbnNMaXN0LmZpbHRlcih0ID0+IHQuaWQgPT0gbylbMF07XHJcbiAgICAgICAgICAgICAgICAvLyBQb3RyZWkgbm9uIGF2ZXJuZSBuZWwgY2FzbyBjaSBzaWEgaWwgZmxhZyBIaWRkZW5Db2x1bW5zIGEgZmFsc2UsIGV2aXRvIGRpIGluc2VyaXJlIGRlZ2xpIHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICAgaWYgKGNvbHVtbilcclxuICAgICAgICAgICAgICAgICAgICByZW9yZGVyZWRDb2xMaXN0LnB1c2goY29sdW1uKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLlRNUENvbHVtbnNMaXN0ID0gcmVvcmRlcmVkQ29sTGlzdDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlR2xvYmFsQ29sVmlzQ2hlY2soKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJpYWdnaW9ybmEgbGUgKipPcmRlckRpcmVjdGl2ZXMqKiBjb24gbGUgaW5mb3JtYXppb25pIGluICAqKkNvbHVtbnNMaXN0KipcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSByZWZyZXNoQ29sdW1uT3JkZXJpbmcoKSB7XHJcbiAgICAgICAgdGhpcy5PcmRlckRpcmVjdGl2ZXMgPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgYyA9IDA7IGMgPCB0aGlzLkNvbHVtbnNMaXN0Lmxlbmd0aDsgYysrKVxyXG4gICAgICAgICAgICB0aGlzLk9yZGVyRGlyZWN0aXZlcy5wdXNoKHRoaXMuQ29sdW1uc0xpc3RbY10uaWQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRWZmZXR0dWEgbGEgc2VsZXppb25lIG8gbWVubyBkZWwgY2hlY2sgZ2xvYmFsZSAoKipnbG9iYWxDb2xWaXNDaGVjayoqKSBkaSB2aXNpYmlsaXTDoCBpbiBiYXNlIGEgc2UgdHV0dGUgbGUgKipUTVBDb2x1bW5zTGlzdCoqIHNvbm8gdmlzaWJpbGkgbyBub1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdXBkYXRlR2xvYmFsQ29sVmlzQ2hlY2soKSB7XHJcbiAgICAgICAgLy8gVE1QQ29sTGlzdCB2aWVuZSByaWVtcGl0YSBkaSB1bmRlZmluZWQgbmVsIGNhc28gaW4gY3VpIHNpYSBkaXNhdHRpdmF0YSBsYSBzZWxlemlvbmUgZGVsbGUgY29sb25uZSBuYXNjb3N0ZVxyXG4gICAgICAgIHRoaXMuZ2xvYmFsQ29sVmlzQ2hlY2sgPSB0aGlzLlRNUENvbHVtbnNMaXN0LmV2ZXJ5KHQgPT4gdC52aXNpYmxlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZ1bnppb25lIGNoZSBlZmZldHR1YSBsYSBjb25mZXJtYSBkZWxsYSB2aXNpYmlsaXTDoCBlIGRlbGwnb3JkaW5lIGRlbGxlIGNvbG9ubmUuXHJcbiAgICAgKlxyXG4gICAgICogUXVlc3RhIHNlbGV6aW9uZSB2aWVuZSBpbm9sdHJlIHNhbHZhdGEgbmVsbGUgcHJlZmVyZW56ZSAoKipAZXNmYWVuemEvcHJlZmVyZW5jZXMqKiksIHF1YWxvcmEgbCdJbnB1dCAqKlNhdmVQcmVmZXJlbmNlcyoqIGZvc3NlIHZhbG9yaXp6YXRvXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59ICoqdHJ1ZSoqIHNlIG5vbiBjaSBzb25vIHByb2JsZW1pLCAqKmZhbHNlKiogYWx0cmltZW50aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY29uZmlybUNvbHVtblZpc2liaWxpdHlTZWxlY3Rpb24oKTogYm9vbGVhbiB7XHJcbiAgICAgICAgLy8gTm9uIHBlcm1ldHRvIGRpIG5vbiBzZWxlemlvbmFyZSBudWxsYVxyXG4gICAgICAgIGlmICh0aGlzLlRNUENvbHVtbnNMaXN0LmV2ZXJ5KHQgPT4gIXQudmlzaWJsZSkpXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgbGV0IGNhc3RlZFZpZXcgPSB0aGlzLlZpZXcgYXMgQXBwU2VhcmNoPGFueT47XHJcbiAgICAgICAgdGhpcy5Db2x1bW5zTGlzdCA9IFtdO1xyXG4gICAgICAgIHRoaXMuVE1QQ29sdW1uc0xpc3QuZm9yRWFjaChjID0+IHsgdGhpcy5Db2x1bW5zTGlzdC5wdXNoKE9iamVjdC5hc3NpZ24oe30sIGMpKTsgfSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGhpcy5yZWZyZXNoQ29sdW1uT3JkZXJpbmcoKTtcclxuXHJcbiAgICAgICAgdGhpcy5yZWZyZXNoQ29sdW1uc1Zpc2liaWxpdHkobnVsbCwgbnVsbCwgY2FzdGVkVmlldyk7XHJcbiAgICAgICAgdGhpcy5hcHBseU9yZGVyaW5nKGNhc3RlZFZpZXcsIGZhbHNlKTtcclxuXHJcbiAgICAgICAgLy9TYWx2byBsZSBwcmVmZXJlbmNlcyBkaSBxdWVzdGEgdmlld1xyXG4gICAgICAgIC8vRGkgZGVmYXVsdCByZWdpc3RybyBvcmRpbmFtZW50byBlIHZpc2liaWxpdMOgIGRlbGxlIGNvbG9ubmUgbmVsbGEgdmlzdGEuIFNvbG8gbGUgY29zZSBkaSBVSVxyXG4gICAgICAgIGlmICh0aGlzLlNhdmVQcmVmZXJlbmNlcykge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMubmdDb250cm9sLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJOb24gcG9zc28gdXRpbGl6emFyZSBsZSBwcmVmZXJlbmNlIHNlbnphIGF2ZXJlIHVuICduYW1lJyBwZXIgbGEgdGFiZWxsYVwiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLnByZWZTZXJ2aWNlKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm9uIHBvc3NvIHV0aWxpenphcmUgbGUgcHJlZmVyZW5jZSBzZW56YSBjaGUgaWwgcGFjY2hldHRvIEBlc2ZhZW56YS9wcmVmZXJlbmNlcyBzaWEgaW5zdGFsbGF0b1wiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdmFyIHRvU3RvcmUgPSB7IGNvbHVtbnM6IDxzdHJpbmdbXT5KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGNhc3RlZFZpZXcuY29sdW1ucykpLCBjb2x1bW5fb3JkZXJpbmc6IDxzdHJpbmdbXT5KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGNhc3RlZFZpZXcuY29sdW1uX29yZGVyaW5nKSkgfTtcclxuICAgICAgICAgICAgdGhpcy5wcmVmU2VydmljZS5zdG9yZSg8c3RyaW5nPnRoaXMubmdDb250cm9sLm5hbWUsIHRvU3RvcmUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gTWkgYXNzaWN1cm8gZGkgZmFybG8gZG9wbyBsJ2VzcGFuc2lvbmUgZGVsIGNoYW5nZWQgbyByaXNjaGlvIGNoZSBsYSByaWNlcmNhIG1pIHJpZGlhIGNvbG9ubmUgY2hlIGluIHJlYWx0w6Agbm9uIGVzaXN0b25vXHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IHRoaXMuZW1pdFNlYXJjaFJlcXVlc3QoZmFsc2UpOyB9KTtcclxuXHJcbiAgICAgICAgLy8gTG8gdm9ycmVpIG1ldHRlcmUgbGF0byB0ZW1wbGF0ZSBtYSBub1xyXG4gICAgICAgIHRoaXMubGFzdFNlbGVjdGVkSXRlbUlEID0gbnVsbDtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFN1bCBjbGljayBuZWxsYSBjaGVja2JveCBkaSBzZWxlemlvbmUgZ2xvYmFsZSBzaSBzY29ycm9ubyB0dXR0ZSBsZSBjb2xvbm5lIGUgc2kgaW1wb3N0YW5vIGFsIHZhbG9yZSBkZWxsYSBjaGVjayBnbG9iYWxlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnbG9iYWxDb2xWaXNDaGVja0NoYW5nZWQoKSB7XHJcbiAgICAgICAgdGhpcy5UTVBDb2x1bW5zTGlzdC5mb3JFYWNoKHQgPT4geyB0LnZpc2libGUgPSB0aGlzLmdsb2JhbENvbFZpc0NoZWNrOyB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyAjZW5kcmVnaW9uXHJcblxyXG4gICAgLy8gI3JlZ2lvbiBHZXN0aW9uZSBkYXRhIHNvdXJjZSBnZXJhcmNoaWNpXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEYXRhIHVuYSBsaXN0YSBkaSBvZ2dldHRpIGFzc2Vnbm8gaWwgbGl2ZWxsbyBnZXJhcmNoaWNvIHJpc3BldHRvIGFsbGEgbGlzdGEgZGkgb2dnZXR0aSBwYXNzYXRhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHthbnlbXX0gb2JqcyBMaXN0YSBkaSBvZ2dldHRpIGEgY3VpIGFnZ2l1bmdlcmUgbCdpbmZvcm1hemlvbmUgZGVsIGxpdmVsbG8gZ2VyYXJjaGljb1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGFzc2lnbkhpZXJhcmNoeUxldmVscyhvYmpzOiBhbnlbXSkge1xyXG4gICAgICAgIC8vIENhc2lzdGljYSBpbnB1dCBudWxsb1xyXG4gICAgICAgIGlmICghb2JqcyB8fCAhb2Jqcy5sZW5ndGgpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy9TZSBtYW5jYW5vIGVudHJhbWJlIGxlIGluZm8gbGUgY2VyY28gZGkgdmFsb3JpenphcmUgaW4gYXV0b21hdGljbyBjb2kgZGVmYXVsdCBcInBhcmVudGlkXCIgZSBcImlkXCIgKHBvc3RvIGNoZSBsZSBwcm9wcyBlc2lzdGFubyBuZWxsJ29nZ2V0dG8pXHJcbiAgICAgICAgaWYgKCF0aGlzLlBhcmVudEtleSAmJiAhdGhpcy5Pd25LZXkpIHtcclxuICAgICAgICAgICAgaWYgKG9ianNbMF1bJ3BhcmVudGlkJ10gIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgIHRoaXMuUGFyZW50S2V5ID0gJ3BhcmVudGlkJztcclxuICAgICAgICAgICAgaWYgKG9ianNbMF1bJ2lkJ10gIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgIHRoaXMuT3duS2V5ID0gJ2lkJztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vQ2hlY2sgZmluYWxlIHBlciBhc3NpY3VyYXJtaSBjaGUgbGUgcHJvcHMgY2kgc2lhbm9cclxuICAgICAgICBpZiAoIXRoaXMuUGFyZW50S2V5IHx8ICF0aGlzLk93bktleSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdQZXIgdXRpbGl6emFyZSBpbCBzaXN0ZW1hIGluIG1vZGFsaXTDoCBnZXJhcmNoaWNhIMOoIG9iYmxpZ2F0b3JpbyBzcGVjaWZpY2FyZSBzaWEgUGFyZW50S2V5IGNoZSBPd25LZXkuIEZhbGxiYWNrIGEgc2lzdGVtYSBub24gZ2VyYXJjaGljbycpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBWYWxvcml6emF6aW9uZSBjYW1waSBsZXZlbCwgZXhwYW5kZWQsIGUgdmlzaWJsZSBwZXIgb2duaSBpdGVtXHJcbiAgICAgICAgbGV0IGN1cnJlbnRMZXZlbCA9IDE7XHJcbiAgICAgICAgbGV0IGFzc2lnbmVkID0gMDtcclxuICAgICAgICBkbyB7XHJcbiAgICAgICAgICAgIGFzc2lnbmVkID0gdGhpcy5hc3NpZ25MZXZlbChvYmpzLCBjdXJyZW50TGV2ZWwpO1xyXG4gICAgICAgICAgICBjdXJyZW50TGV2ZWwrKztcclxuICAgICAgICB9IHdoaWxlIChhc3NpZ25lZCA+IDApO1xyXG4gICAgICAgIC8vIGJ1dHRvIHN1IGxhdG8gaHRtbCBlIHBvaSBtZSBsYSBnaW9jbyBsw6AgY29uIHBhZGRpbmcgPSAyMCAqIChsZXZlbCAtIDEpIHBlciBmYXIgY2FwaXJlIGlsIGRpdmVyc28gbGl2ZWxsb1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGVyIG9nbnVubyBkZWdsaSBvZ2dldHRpIHBhc3NhdGkgZ2xpIGFzc2VnbmEgdW4gbGl2ZWxsbyBkaSBnZXJhcmNoaWEgaW4gYmFzZSBhICoqUGFyZW50S2V5KiogZSAqKk93bktleSoqXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHthbnlbXX0gb2JqcyBPZ2dldHRpIGEgY3VpIGFzc2VnbmFyZSBpbCBsaXZlbGxvIGRpIGdlcmFyY2hpYVxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxldmVsVG9Bc3NpZ24gTGl2ZWxsbyBjaGUgc3RhIGFzc2VnbmFuZG8gYXR0dWFsbWVudGUgcXVlc3RhIGl0ZXJhemlvbmUgKGRhdG8gY2hlIMOoIHJpY29yc2l2YSlcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1lcm8gZGkgb2dnZXR0aSBhIGN1aSDDqCBzdGF0byBhc3NlZ25hdG8gdW4gbGl2ZWxsbyBnZXJhcmNoaWNvXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgYXNzaWduTGV2ZWwob2JqczogYW55W10sIGxldmVsVG9Bc3NpZ246IG51bWJlcik6IG51bWJlciB7XHJcbiAgICAgICAgbGV0IGFzc2lnbmVkID0gMDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9ianMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IG9iaiA9IG9ianNbaV07XHJcblxyXG4gICAgICAgICAgICAvLyBTZSBsYSBwYXJlbnRLZXkgbm9uIMOoIHZhbG9yaXp6YXRhLCBxdWVzdG8gw6ggaWwgbGl2ZWxsbyAwICgxLi4uIHBlcmNow6kgZ2xpIDAgc29uIHBlcmNpb2xvc2kpXHJcbiAgICAgICAgICAgIGlmICghb2JqW3RoaXMuUGFyZW50S2V5XSAmJiBsZXZlbFRvQXNzaWduID09IDEpIHtcclxuICAgICAgICAgICAgICAgIG9iai5sZXZlbCA9IDE7XHJcbiAgICAgICAgICAgICAgICBvYmoudmlzaWJsZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBvYmouZXhwYW5kZWQgPSB0aGlzLlN0YXJ0c0V4cGFuZGVkO1xyXG4gICAgICAgICAgICAgICAgYXNzaWduZWQrKztcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBQZXIgaSBsaXZlbGxpIHN1cGVyaW9yZSBhbCBwcmltb1xyXG4gICAgICAgICAgICBpZiAob2JqW3RoaXMuUGFyZW50S2V5XSAmJiBsZXZlbFRvQXNzaWduID4gMSkge1xyXG4gICAgICAgICAgICAgICAgLy8gdHJvdm8gaWwgcGFyZW50XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBwID0gMDsgcCA8IG9ianMubGVuZ3RoOyBwKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcG9zc2libGVQYXJlbnQgPSBvYmpzW3BdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBUcm92YXRvIGlsIHBhcmVudCBkZWxsJ2l0ZW0sIGFzc2Vnbm8gYWxsJ2l0ZW0gaWwgbGl2ZWxsbyBnaXVzdG9cclxuICAgICAgICAgICAgICAgICAgICBpZiAocG9zc2libGVQYXJlbnRbdGhpcy5Pd25LZXldID09IG9ialt0aGlzLlBhcmVudEtleV0gJiYgcG9zc2libGVQYXJlbnQubGV2ZWwgPT0gbGV2ZWxUb0Fzc2lnbiAtIDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmxldmVsID0gbGV2ZWxUb0Fzc2lnbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNvIGNoZSBxdWVzdG8gaXRlbSBoYSB1biBwYXJlbnQuIFJpYmFkaXNjbyBjaGUgaWwgcGFyZW50IMOoIGVzcGFuc28gaW4gYmFzZSBhbGxlIGltcG9zdGF6aW9uZSBlIHN0ZXNzYSBsb2dpY2FcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcGVyIGxhIHZpc2liaWxpdMOgIGRlbCBmaWdsaW9cclxuICAgICAgICAgICAgICAgICAgICAgICAgcG9zc2libGVQYXJlbnQuZXhwYW5kZWQgPSB0aGlzLlN0YXJ0c0V4cGFuZGVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3NzaWJsZVBhcmVudC5wYXJlbnQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmoudmlzaWJsZSA9IHRoaXMuU3RhcnRzRXhwYW5kZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFzc2lnbmVkKys7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYXNzaWduZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGdW56aW9uZSBjaGUgcGVybWV0dGUgZGkgZWZmZXR0dWFyZSBsJ2VzcGFuc2lvbmUgZGkgdW4gcGFyZW50IHF1YW5kbyBsYSB0YWJlbGxhIGZ1bnppb25hIGluIG1vZGFsaXTDoCBnZXJhcmNoaWNhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBDaGlhdmUgZGVsIHBhcmVudCBkYSBlc3BhbmRlcmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGV4cGFuZFBhcmVudChrZXk6IHN0cmluZykge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ib3VuZFNvdXJjZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgb2JqID0gdGhpcy5ib3VuZFNvdXJjZVtpXTtcclxuXHJcbiAgICAgICAgICAgIC8vIFRyb3ZvIGlsIHBhcmVudCBjb24gcXVlbGwnaWQgZSBsbyBlc3BhbmRvXHJcbiAgICAgICAgICAgIGlmIChvYmpbdGhpcy5Pd25LZXldID09IGtleSkge1xyXG4gICAgICAgICAgICAgICAgb2JqLmV4cGFuZGVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpYyA9IDA7IGljIDwgdGhpcy5ib3VuZFNvdXJjZS5sZW5ndGg7IGljKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgY2hpbGQgPSB0aGlzLmJvdW5kU291cmNlW2ljXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVHJvdm8gdHV0dGkgaSBjaGlsZCBkaSBxdWVsIHBhcmVudCBlIGxpIHJlbmRvIHZpc2liaWxpXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkW3RoaXMuUGFyZW50S2V5XSA9PSBrZXkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnZpc2libGUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRnVuemlvbmUgY2hlIHBlcm1ldHRlIGRpIGVmZmV0dHVhcmUgaWwgY29sbGFwc2UgZGkgdW4gcGFyZW50IHF1YW5kbyBsYSB0YWJlbGxhIGZ1bnppb25hIGluIG1vZGFsaXTDoCBnZXJhcmNoaWNhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBDaGlhdmUgZGVsIHBhcmVudCBkYSBjb2xsYXNzYXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb2xsYXBzZVBhcmVudChrZXk6IHN0cmluZykge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ib3VuZFNvdXJjZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgb2JqID0gdGhpcy5ib3VuZFNvdXJjZVtpXTtcclxuXHJcbiAgICAgICAgICAgIC8vIFRyb3ZvIGlsIHBhcmVudCBjb24gcXVlbGwnaWQgZSBsbyBjb2xsYXNzb1xyXG4gICAgICAgICAgICBpZiAob2JqW3RoaXMuT3duS2V5XSA9PSBrZXkpIHtcclxuICAgICAgICAgICAgICAgIG9iai5leHBhbmRlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIENvbGxhc3NvL25hc2NvbmRvIHR1dHRpIGkgY2hpbGQgZGVsIHBhcmVudFxyXG4gICAgICAgICAgICAgICAgdGhpcy5jb2xsYXBzZUNoaWxkT2ZQYXJlbnQoa2V5KTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbGxhc3NhIHJpY29yc2l2YW1lbnRlIHR1dHRpIGkgZmlnbGkgZGkgdW4gcGFyZW50IGlkZW50aWZpY2F0byBkYWxsYSAqKnBhcmVudEtleSoqXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhcmVudEtleSBDaGlhdmUgZGVsIHBhcmVudCBkaSBjdWkgY29sbGFzc2FyZSBpIGZpZ2xpXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgY29sbGFwc2VDaGlsZE9mUGFyZW50KHBhcmVudEtleTogc3RyaW5nKSB7XHJcbiAgICAgICAgZm9yIChsZXQgaWMgPSAwOyBpYyA8IHRoaXMuYm91bmRTb3VyY2UubGVuZ3RoOyBpYysrKSB7XHJcbiAgICAgICAgICAgIGxldCBjaGlsZCA9IHRoaXMuYm91bmRTb3VyY2VbaWNdO1xyXG5cclxuICAgICAgICAgICAgLy8gVHJvdm8gdHV0dGkgaSBjaGlsZCBkaSBxdWVsIHBhcmVudCBlIGxpIHJlbmRvIGludmlzaWJpbGkuIFNlIGlsIGNoaWxkIHRyb3ZhdG8gw6ggYSBzdWEgdm9sdGEgdW4gcGFyZW50LFxyXG4gICAgICAgICAgICAvLyBsbyBjb2xsYXNzbyBlIHZhZG8gaW4gcmljb3JzaW9uZSBzdWkgZmlnbGlcclxuICAgICAgICAgICAgaWYgKGNoaWxkW3RoaXMuUGFyZW50S2V5XSA9PSBwYXJlbnRLZXkgJiYgIWNoaWxkLnBhcmVudClcclxuICAgICAgICAgICAgICAgIGNoaWxkLnZpc2libGUgPSBmYWxzZTtcclxuICAgICAgICAgICAgZWxzZSBpZiAoY2hpbGRbdGhpcy5QYXJlbnRLZXldID09IHBhcmVudEtleSAmJiBjaGlsZC5wYXJlbnQpIHtcclxuICAgICAgICAgICAgICAgIGNoaWxkLmV4cGFuZGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBjaGlsZC52aXNpYmxlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbGxhcHNlQ2hpbGRPZlBhcmVudChjaGlsZFt0aGlzLk93bktleV0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vICNlbmRyZWdpb25cclxuXHJcbiAgICAvLyAjcmVnaW9uIEdlc3Rpb25lIFNlbGV6aW9uZVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2VzdGlzY2UgbGEgc2VsZXppb25lIGdsb2JhbGUgZGVnbGkgb2dnZXR0aSwgc2lhIHBlciBwYWdpbmEgY2hlIGEgbGl2ZWxsbyBkaSAqKlNlbGVjdEFsbCoqXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBmb3JjZWRWYWwgVmFsb3JlIGZvcnphdG8gZGkgY2hlY2sgZGEgYXNzZWduYXJlIGFnbGkgb2dnZXR0aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2xvYmFsQ2hlY2tDaGFuZ2VkKGZvcmNlZFZhbDogYm9vbGVhbiA9IG51bGwpIHtcclxuXHJcbiAgICAgICAgbGV0IGl0ZW1zID0gdGhpcy5nZXRJdGVtc0J5TW9kZSgpO1xyXG4gICAgICAgIHZhciBpdGVtU2VsZWN0aW9uID0gdGhpcy5oYW5kbGVJdGVtc1NlbGVjdGlvbihpdGVtcywgZm9yY2VkVmFsLCB0aGlzLmdsb2JhbENoZWNrKTtcclxuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcclxuXHJcbiAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZWQuZW1pdChpdGVtU2VsZWN0aW9uKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhlbHBlciBwZXIgZ2VzdGlyZSBsYSBzZWxlemlvbmUgZGkgTiBlbGVtZW50aSB1dGlsaXp6YW5kbyBsYSBDYWNoZSBkaSBzZWxlemlvbmUgZWQgZXZlbnR1YWxtZW50ZSBhZ2dpb3JuYW5kbyBpbCBjb25jZXR0byBkaSBcImFsbCBzZWxlY3Rpb25cIlxyXG4gICAgICpcclxuICAgICAqIFZ1bnppb25hIHNpYSBpbiBtb2RhbGl0w6AgQXJyYXkgY2hlIGluIG1vZGFsaXTDoCBWaWV3IFNlbXBsaWNlIG8gVmlldyBBdmFuemF0YSAoY29uIGxlIEN1c3RvbSBDZWxscylcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge2FueVtdfSBpdGVtcyBPZ2dldHRpIGRhIHNlbGV6aW9uYXJlIG8gZGVzZWxlemlvbmFyZVxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBmb3JjZWRWYWwgVmFsb3JlIGZvcnphdG8gZGkgY2hlY2sgZGEgYXNzZWduYXJlIGFnbGkgb2dnZXR0aVxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBnbG9iYWxDaGVjayBWYWxvcmUgZGVsIGNoZWNrIGdsb2JhbGVcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7SXRlbXNTZWxlY3Rpb248YW55Pn0gT2dnZXR0byBkaSBzZWxlemlvbmUgYWdnaW9ybmF0byBjb24gbGUgaW5mb3JtYXppb25pIHN1bGwndWx0aW1hIG9wZXJhemlvbmUgZWZmZXR0dWF0YVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGhhbmRsZUl0ZW1zU2VsZWN0aW9uKGl0ZW1zOiBhbnlbXSwgZm9yY2VkVmFsOiBib29sZWFuID0gbnVsbCwgZ2xvYmFsQ2hlY2s6IGJvb2xlYW4gPSBudWxsKTogSXRlbXNTZWxlY3Rpb248YW55PiB7XHJcbiAgICAgICAgbGV0IHNlbGVjdGlvbkl0ZW0gPSAodGhpcy5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+KT8uc2VsZWN0aW9uIHx8IHRoaXMuYXJyYXltb2RlU2VsZWN0aW9uO1xyXG5cclxuICAgICAgICAvLyBTZSBzb25vIGluIG1vZGFsaXTDoCBkaSBzZWxlemlvbmUgc2luZ29sYSBlIGRldm8gc2VsZXppb25hcmUgdW4nb2dnZXR0bywgcGVyIHByaW1hIGNvc2EgZGV2byBkZXNlbGV6aW9uYXJlIHR1dHRpIGdsaSBhbHRyaVxyXG4gICAgICAgIGlmICh0aGlzLlNpbmdsZVNlbGVjdGlvbiAmJiBpdGVtc1swXT8uX3NlbGVjdGVkKSB7XHJcbiAgICAgICAgICAgIGlmIChpdGVtcy5sZW5ndGggPiAxICYmIGZvcmNlZFZhbCA9PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgXCJUZW50YXRpdm8gZGkgc2VsZXppb25hcmUgbyBkZXNlbGV6aW9uYXJlIHBpw7kgZGkgdW4gZWxlbWVudG8gY29uIFNpbmdsZVNlbGVjdGlvbiBhdHRpdm9cIjtcclxuXHJcbiAgICAgICAgICAgIGlmIChpdGVtcy5sZW5ndGggPT0gMSAmJiBmb3JjZWRWYWwgPT0gbnVsbCl7XHJcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25JdGVtID0gdGhpcy5oYW5kbGVJdGVtc1NlbGVjdGlvbih0aGlzLmdldEl0ZW1zQnlNb2RlKCksIGZhbHNlLCBudWxsKTtcclxuICAgICAgICAgICAgICAgIGl0ZW1zWzBdLl9zZWxlY3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IGl0ZW0gPSBpdGVtc1tpXTtcclxuICAgICAgICAgICAgbGV0IHRvQ2hhbmdlID0gZm9yY2VkVmFsICE9IG51bGwgPyBpdGVtLl9zZWxlY3RlZCAhPSBmb3JjZWRWYWwgOiBnbG9iYWxDaGVjayAhPSBudWxsID8gaXRlbS5fc2VsZWN0ZWQgIT0gdGhpcy5nbG9iYWxDaGVjayA6IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgLy8gU2UgZGV2J2Vzc2VyZSBvdmVycmlkYXRvIGlsIHZhbG9yZSBkaSBjaGVjayBlZmZldHR1byBsJ292ZXJyaWRlIG8gY29sIHZhbG9yZSBmb3J6YXRvIG8gY29sIHZhbG9yZSBnbG9iYWxlXHJcbiAgICAgICAgICAgIGlmICh0b0NoYW5nZSAmJiAhaXRlbS5sb2NrZWQpXHJcbiAgICAgICAgICAgICAgICBpdGVtLl9zZWxlY3RlZCA9IGZvcmNlZFZhbCAhPSBudWxsID8gZm9yY2VkVmFsIDogdGhpcy5nbG9iYWxDaGVjaztcclxuXHJcblxyXG4gICAgICAgICAgICBpZiAoc2VsZWN0aW9uSXRlbS5hbGwpIHtcclxuICAgICAgICAgICAgICAgIC8vIEluIGNhc28gZGkgXCJzZWxlemlvbmEgdHV0dG9cIi4uLlxyXG4gICAgICAgICAgICAgICAgLy8gTi5COiBsYSBzZWxPckRlc2VsQ2FjaGUgYWdpc2NlIGNvbWUgY2FjaGUgZGkgREVTRUxFWklPTkUgaW4gcXVlc3RvIGJsb2NjbyBkaSBjb2RpY2VcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoaXRlbS5fc2VsZWN0ZWQgJiYgdGhpcy5zZWxPckRlc2VsQ2FjaGVbaXRlbS5oYXNoXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIE9nZ2V0dG8gc2VsZXppb25hdG86IGxvIHJpbXVvdm8gZGFsbGUgZXNjbHVzaW9uaSBkaSBzZWxlemlvbmVcclxuICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb25JdGVtLmV4Y2x1c2lvbnMuc3BsaWNlKHNlbGVjdGlvbkl0ZW0uZXhjbHVzaW9ucy5pbmRleE9mKHRoaXMuc2VsT3JEZXNlbENhY2hlW2l0ZW0uaGFzaF0pLCAxKTtcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5zZWxPckRlc2VsQ2FjaGVbaXRlbS5oYXNoXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFpdGVtLl9zZWxlY3RlZCAmJiAhdGhpcy5zZWxPckRlc2VsQ2FjaGVbaXRlbS5oYXNoXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIE9nZ2V0dG8gZGVzZWxlemlvbmF0bzogbG8gYWdnaXVuZ28gYWxsZSBlc2NsdXNpb25pIGRpIHNlbGV6aW9uZVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsT3JEZXNlbENhY2hlW2l0ZW0uaGFzaF0gPSBpdGVtO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbkl0ZW0uZXhjbHVzaW9ucy5wdXNoKGl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy9JbiBjYXNvIGRpIG5vbiBcInNlbGV6aW9uYSB0dXR0b1wiLi4uXHJcbiAgICAgICAgICAgICAgICAvLyBOLkI6IGxhIHNlbE9yRGVzZWxDYWNoZSBhZ2lzY2UgY29tZSBjYWNoZSBkaSBTRUxFWklPTkUgaW4gcXVlc3RvIGJsb2NjbyBkaSBjb2RpY2VcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoaXRlbS5fc2VsZWN0ZWQgJiYgIXRoaXMuc2VsT3JEZXNlbENhY2hlW2l0ZW0uaGFzaF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBPZ2dldHRvIHNlbGV6aW9uYXRvOiBsbyBhZ2dpdW5nbyBhbGxhIHNlbGV6aW9uZSBhdHR1YWxlXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxPckRlc2VsQ2FjaGVbaXRlbS5oYXNoXSA9IGl0ZW07XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uSXRlbS5pdGVtcy5wdXNoKGl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoIWl0ZW0uX3NlbGVjdGVkICYmIHRoaXMuc2VsT3JEZXNlbENhY2hlW2l0ZW0uaGFzaF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBPZ2dldHRvIGRlc2VsZXppb25hdG86IGxvIHJpbXVvdm8gZGFsbGEgc2VsZXppb25lIGF0dHVhbGVcclxuICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb25JdGVtLml0ZW1zLnNwbGljZShzZWxlY3Rpb25JdGVtLml0ZW1zLmluZGV4T2YodGhpcy5zZWxPckRlc2VsQ2FjaGVbaXRlbS5oYXNoXSksIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNlbE9yRGVzZWxDYWNoZVtpdGVtLmhhc2hdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJbXBvc3RvIGlsIGNoZWNrIGdsb2JhbGUgaW4gYmFzZSBhIHNlIHR1dHRpIGdsaSBlbGVtZW50aSBzb25vIHNlbGV6aW9uYXRpIG8gbWVuby5cclxuICAgICAgICAvLyBFdml0byBkaSBmYXJlIHF1ZXN0ZSBvcGVyYXppb25pIHNlIGxhIHNlbGV6aW9uZSBkZXJpdmEgcHJvcHJpbyBkYWwgZ2xvYmFsIENoZWNrXHJcbiAgICAgICAgLy8gTm9uIMOoIG90dGltaXp6YXRpc3NpbW8gbWV0dGVyZSAyIHNvbWUgbWEgc2NyaXZlcmUgcXVlc3RvIGNvZGljZSBhIGZvciBzb25vIHRpcG8gMjUgcmlnaGUuLi4uXHJcbiAgICAgICAgaWYgKGdsb2JhbENoZWNrID09IG51bGwpXHJcbiAgICAgICAgICAgIHRoaXMuZ2xvYmFsQ2hlY2sgPSAhaXRlbXMuc29tZSh0ID0+ICF0Ll9zZWxlY3RlZCkgJiYgIXRoaXMuZ2V0SXRlbXNCeU1vZGUoKS5zb21lKHQgPT4gIXQuX3NlbGVjdGVkKTtcclxuXHJcbiAgICAgICAgdGhpcy5maW5hbGl6ZVNlbGVjdGlvbkluZm9ybWF0aW9ucyhzZWxlY3Rpb25JdGVtKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHNlbGVjdGlvbkl0ZW07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaW5hbGl6emEgbGUgaW5mb3JtYXppb25pIGRpIHNlbGV6aW9uZSBkZWwgKipJdGVtc1NlbGVjdGlvbioqIGNvcnJlbnRlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZmluYWxpemVTZWxlY3Rpb25JbmZvcm1hdGlvbnMoc2VsZWN0aW9uSXRlbTogSXRlbXNTZWxlY3Rpb248YW55Pikge1xyXG4gICAgICAgIHNlbGVjdGlvbkl0ZW0uY291bnQgPSB0aGlzLmV2YWx1YXRlU2VsZWN0ZWQoKTtcclxuXHJcbiAgICAgICAgLy8gU2UgaG8gZmF0dG8gc2VsZXppb25lIFwiYWxsXCIgbWEgcG9pIG1pIHNvbm8gbWVzc28gYSB0b2dsaWVyZSB0dXR0aSBnbGkgZWxlbWVudGkgZmlubyBhIHJpbWFuZXJuZSAwIHJlc2V0dG8gbCdvZ2dldHRvIGRpIHNlbGV6aW9uZVxyXG4gICAgICAgIGlmIChzZWxlY3Rpb25JdGVtLmNvdW50ID09IDAgJiYgc2VsZWN0aW9uSXRlbS5hbGwpIHtcclxuICAgICAgICAgICAgc2VsZWN0aW9uSXRlbS5hbGwgPSBmYWxzZTtcclxuICAgICAgICAgICAgc2VsZWN0aW9uSXRlbS5leGNsdXNpb25zID0gW107XHJcbiAgICAgICAgICAgIHNlbGVjdGlvbkl0ZW0uaXRlbXMgPSBbXTtcclxuXHJcbiAgICAgICAgICAgIC8vIFJpcHVsaXNjbyBsYSBjYWNoZSBhbHRyaW1lbnRpIG1pIHJpbWFuZSBwaWVuYSBkaSB0dXR0ZSBsZSBlc2NsdXNpb25pXHJcbiAgICAgICAgICAgIHRoaXMuc2VsT3JEZXNlbENhY2hlID0ge307XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBTZSBsYSBwb3NzaWJpbGl0w6AgZGkgZmFyZSBcIlNlbGV6aW9uYSB0dXR0b1wiIMOoIGFiaWxpdGF0YSBhbGxvcmEgbGEgY29uc2lkZXJvIGFwcGVuYSBtaSB2aWVuZSBzZWxlemlvbmF0byBxdWFsY29zYVxyXG4gICAgICAgIHRoaXMuY2FuU2VsZWN0QWxsID0gc2VsZWN0aW9uSXRlbS5jb3VudCA+IDAgJiYgdGhpcy5TZWxlY3RBbGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXN0aXNjZSBpIGNsaWNrIHN1bGxhIHRhYmVsbGEsIGdlc3RlbmRvIGV2ZW50dWFsbWVudGUgYW5jaGUgZ2xpIFNoaWZ0ICsgQ2xpY2sgcGVyIHNlbGV6aW9uYXJlIHVuIHJhbmdlIGRpIG9nZ2V0dGlcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gZXZlbnQgRXZlbnRvIG5hdGl2byBIVE1MIGRlbCBjbGlja1xyXG4gICAgICogQHBhcmFtIHthbnl9IGl0ZW0gT2dnZXR0byBiaW5kYXRvIHN1IGN1aSBzaSDDqCBlZmZldHR1YXRvIGlsIGNsaWNrXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59ICoqdHJ1ZSoqIHNlIGwnb3BlcmFpem9uZSDDqCBhbmRhdGEgYSBidW9uIGZpbmUsICoqZmFsc2UqKiBhbHRyaW1lbnRpXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBoYW5kbGVDbGljayhldmVudDogYW55LCBpdGVtOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICAvLyBTZWxlemlvbm8gZGVsIHRlc3RvIG1hIG5vbiBobyBzaGlmdCBwcmVtdXRvIC0+IGlnbm9ybyBsYSBzZWxlemlvbmVcclxuICAgICAgICBpZiAoKGV2ZW50LnZpZXcuZ2V0U2VsZWN0aW9uKCkudHlwZSA9PSAnUmFuZ2UnIHx8IGV2ZW50LnZpZXcuZ2V0U2VsZWN0aW9uKCkudG9TdHJpbmcoKS5sZW5ndGggPiAwKSAmJiAhZXZlbnQuc2hpZnRLZXkpXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgLy8gU2VsZXppb25vIGRlbCB0ZXN0byBlIGhvIHNoaWZ0IHByZW11dG8gLT4gYW5udWxsbyBsYSBzZWxlemlvbmUgZGVsIHRlc3RvXHJcbiAgICAgICAgaWYgKChldmVudC52aWV3LmdldFNlbGVjdGlvbigpLnR5cGUgPT0gJ1JhbmdlJyB8fCBldmVudC52aWV3LmdldFNlbGVjdGlvbigpLnRvU3RyaW5nKCkubGVuZ3RoID4gMCkgJiYgZXZlbnQuc2hpZnRLZXkpXHJcbiAgICAgICAgICAgIHRoaXMudXRpRXh0cy5jbGVhclRleHRTZWxlY3Rpb24oKTtcclxuXHJcbiAgICAgICAgbGV0IHNlbGVjdGVkaXRlbXM6IGFueVtdID0gW107XHJcbiAgICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5ICYmIHRoaXMuU2hpZnRDbGljayAmJiAhdGhpcy5TaW5nbGVTZWxlY3Rpb24pIHtcclxuICAgICAgICAgICAgbGV0IHN0YXJ0U2VsZWN0aW5nID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICBsZXQgaXRlbXMgPSB0aGlzLmdldEl0ZW1zQnlNb2RlKCk7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCB0ID0gaXRlbXNbaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhcnRTZWxlY3RpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICB0Ll9zZWxlY3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRpdGVtcy5wdXNoKHQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKCh0ID09IGl0ZW0gfHwgdCA9PSB0aGlzLmxhc3RTZWxlY3RlZCkgJiYgIXN0YXJ0U2VsZWN0aW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRTZWxlY3RpbmcgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHQuX3NlbGVjdGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZGl0ZW1zLnB1c2godCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCh0ID09IGl0ZW0gfHwgdCA9PSB0aGlzLmxhc3RTZWxlY3RlZCkgJiYgc3RhcnRTZWxlY3RpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRTZWxlY3RpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGl0ZW0uX3NlbGVjdGVkID0gIWl0ZW0uX3NlbGVjdGVkO1xyXG4gICAgICAgICAgICB0aGlzLmxhc3RTZWxlY3RlZCA9IGl0ZW07XHJcbiAgICAgICAgICAgIHNlbGVjdGVkaXRlbXMucHVzaChpdGVtKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBpdGVtU2VsZWN0aW9uID0gdGhpcy5oYW5kbGVJdGVtc1NlbGVjdGlvbihzZWxlY3RlZGl0ZW1zKTtcclxuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcclxuXHJcbiAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZWQuZW1pdChpdGVtU2VsZWN0aW9uKTtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFZhbHV0YSBsYSBxdWFudGl0w6AgZGkgb2dnZXR0aSBjaGUgc29ubyBzdGF0aSBzZWxlemlvbmF0aSBhbCB0ZXJtaW5lIGRpIHVuIGV2ZW50byBkaSBzZWxlemlvbmVcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1lcm8gZGkgb2dnZXR0aSBzZWxlemlvbmF0aVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGV2YWx1YXRlU2VsZWN0ZWQoKTogbnVtYmVyIHtcclxuICAgICAgICBsZXQgc2VsZWN0aW9uSXRlbSA9ICh0aGlzLlZpZXcgYXMgQXBwU2VhcmNoPGFueT4pPy5zZWxlY3Rpb24gfHwgdGhpcy5hcnJheW1vZGVTZWxlY3Rpb247XHJcbiAgICAgICAgdGhpcy5zZWxlY3RlZE9iamVjdHMgPSBzZWxlY3Rpb25JdGVtLmFsbCA/ICh0aGlzLlZpZXcub2JqZWN0Y291bnQgfHwgdGhpcy5WaWV3Lmxlbmd0aCkgIC0gc2VsZWN0aW9uSXRlbS5leGNsdXNpb25zLmxlbmd0aCA6IHNlbGVjdGlvbkl0ZW0uaXRlbXMubGVuZ3RoO1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNlbGVjdGVkT2JqZWN0cztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdlc3Rpc2NlIGlsIGNvbWFuZG8gZGkgXCJTZWxlemlvbmEgdHV0dG8gaW4gdHV0dGUgbGUgcGFnaW5lXCIgbyBpbCBzdW8gY29udHJhcmlvLCBjaW/DqCBcIlJlaW1wb3N0YSBzZWxlemlvbmVcIlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2VsZWN0QWxsT3JSZXNldFNlbGVjdGlvbigpIHtcclxuICAgICAgICBsZXQgc2VsZWN0aW9uSXRlbSA9IHRoaXMuVmlldy5zZWxlY3Rpb24gfHwgdGhpcy5hcnJheW1vZGVTZWxlY3Rpb247XHJcbiAgICAgICAgdGhpcy5zZWxPckRlc2VsQ2FjaGUgPSB7fTtcclxuICAgICAgICBzZWxlY3Rpb25JdGVtLmFsbCA9ICFzZWxlY3Rpb25JdGVtLmFsbDtcclxuICAgICAgICBzZWxlY3Rpb25JdGVtLmV4Y2x1c2lvbnMgPSBbXTtcclxuICAgICAgICBzZWxlY3Rpb25JdGVtLml0ZW1zID0gW107XHJcblxyXG4gICAgICAgIC8vIFJpcHVsaXNjbyBnbGkgc3RhdGkgVUkgZGkgc2VsZXppb25lIGdsb2JhbGUgc2UgbCdobyBkaXNhdHRpdmF0YVxyXG4gICAgICAgIGlmICghc2VsZWN0aW9uSXRlbS5hbGwpIHtcclxuICAgICAgICAgICAgdGhpcy5jYW5TZWxlY3RBbGwgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5nbG9iYWxDaGVjayA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5maW5hbGl6ZVNlbGVjdGlvbkluZm9ybWF0aW9ucyhzZWxlY3Rpb25JdGVtKTtcclxuXHJcbiAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZWQuZW1pdChzZWxlY3Rpb25JdGVtKTtcclxuXHJcbiAgICAgICAgLy8gRG9wbyBhdmVyIHJlc2V0dGF0byBkaXJldHRhbWVudGUgaWwgc29sbyBvZ2dldHRvIHRoaXMuVmlldy5zZWxlY3Rpb24gZGV2byBhbmNoZSByaWFsbGluZWFyZSBhIHR1dHRpIGdsaSBvZ2dldHRpIGJpbmRhdGlcclxuICAgICAgICB0aGlzLmV2YWx1YXRlU2VsZWN0aW9uKHRoaXMudmlld01vZGUgPyB0aGlzLlZpZXcuaXRlbXMgOiB0aGlzLlZpZXcsIHNlbGVjdGlvbkl0ZW0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vICNlbmRyZWdpb25cclxuXHJcbiAgICAvLyAjcmVnaW9uIEdlc3Rpb25lIFBhZ2luYXppb25lXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTcG9zdGEgbGEgcmljZXJjYSBkaSB1bmEgcGFnaW5hIGluIGF2YW50aSAobyBpbmRlaXRybylcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcGFnZSBOdW1lcm8gZGkgcGFnaW5lIGRhIGFnZ2l1bmdlcmUgKG8gc290dHJhcnJlLCBzZSBuZWdhdGl2bykgYWxsYSBwYWdpbmEgYXR0dWFsZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWRkVG9QYWdlKHBhZ2U6IG51bWJlcikge1xyXG4gICAgICAgIGlmICghKHRoaXMuVmlldyBpbnN0YW5jZW9mIEFwcFNlYXJjaCkgJiYgISh0aGlzLlNlYXJjaFZpZXcgaW5zdGFuY2VvZiBBcHBTZWFyY2gpICYmICEodGhpcy5WaWV3IGluc3RhbmNlb2YgUmVwb3J0RGVmaW5pdGlvbikpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgdGhpcy5nb1RvUGFnZSgodGhpcy5TZWFyY2hWaWV3IHx8IHRoaXMuVmlldykucGFnZSArIHBhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3Bvc3RhIGxhIHJpY2VyY2EgYWxsYSBwYWdpbmEgc3BlY2lmaWNhdGFcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcGFnZSBQYWdpbmEgYSBjdWkgbmF2aWdhcmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGdvVG9QYWdlKHBhZ2U6IG51bWJlcikge1xyXG5cclxuICAgICAgICBpZiAoISh0aGlzLlZpZXcgaW5zdGFuY2VvZiBBcHBTZWFyY2gpICYmICEodGhpcy5TZWFyY2hWaWV3IGluc3RhbmNlb2YgQXBwU2VhcmNoKSAmJiAhKHRoaXMuVmlldyBpbnN0YW5jZW9mIFJlcG9ydERlZmluaXRpb24pKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGxldCBhcHBTZWFyY2hFbGVtZW50ID0gdGhpcy5TZWFyY2hWaWV3IHx8IHRoaXMuVmlldztcclxuICAgICAgICBpZiAocGFnZSA9PT0gMCB8fCBwYWdlID4gYXBwU2VhcmNoRWxlbWVudC5wYWdlcylcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBhcHBTZWFyY2hFbGVtZW50LnBhZ2UgPSBwYWdlO1xyXG4gICAgICAgIHRoaXMuYXJyYXlQdWxzYW50aSA9IHRoaXMuZ2V0UGFnZXNBcnJheSg2LCBhcHBTZWFyY2hFbGVtZW50LnBhZ2UsIGFwcFNlYXJjaEVsZW1lbnQucGFnZXMpO1xyXG5cclxuICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KGZhbHNlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEV2ZW50byByaWNoaWFtYXRvIHN1bCBjYW1iaW8gZGVsbGEgcGFnaW5hemlvbmUuIFZlcnLDoCByaWNoaWFtYXRvIGwnZXZlbnRvICoqZW1pdFNlYXJjaFJlcXVlc3QqKlxyXG4gICAgICogcGVyIGNvbXVuaWNhcmUgYWwgY29tcG9uZW50ZSBjaGUgdXRpbGl6emEgcXVlc3RhIHRhYmVsbGEgY2hlIGkgZGF0aSBzb25vIGRhIGFnZ2lvcm5hcmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uSXRlbXNQZXJQYWdlQ2hhbmdlZCgpIHtcclxuICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vICNlbmRyZWdpb25cclxuXHJcbiAgICAvLyAjcmVnaW9uIEdlc3Rpb25lIEV4cG9ydFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRWZmZXR0dWEgbCdlc3BvcnRhemlvbmUgZGVpIGRhdGlcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0IEZvcm1hdG8gZGkgZXNwb3J0YXppb25lLiBMZXR0byBzb2xvIGluIG1vZGFsaXTDoCBSZXBvcnQgZGVsbGEgdGFiZWxsYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdHJ5RXhwb3J0KGZvcm1hdD86IHN0cmluZykge1xyXG4gICAgICAgIGlmICghdGhpcy5FeHBvcnRGdW5jdGlvbilcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5yZXBvcnRNb2RlKVxyXG4gICAgICAgICAgICB0aGlzLkV4cG9ydEZ1bmN0aW9uKGZvcm1hdCk7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICB0aGlzLkV4cG9ydEZ1bmN0aW9uKChkYXRhLCBjYW5jZWw6IGJvb2xlYW4gPSBmYWxzZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNhbmNlbClcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldHVwRXhwb3J0KGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IHRoaXMuZXhwb3J0RG93bmxvYWRlci5uYXRpdmVFbGVtZW50LmNsaWNrKCk7IH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBjaGUgZWZmZXR0aXZhbWVudGUgZ2VuZXJhIGdsaSBoZWFkZXIgZSBpIGRhdGkgcGVyIGwnZXNwb3J0YXppb25lIGNvbiAqKm5neC1jc3YqKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55W119IGl0ZW1zIE9nZ2V0dGkgZGEgZXNwb3J0YXJlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc2V0dXBFeHBvcnQoaXRlbXM6IGFueVtdKSB7XHJcbiAgICAgICAgbGV0IGRyY2QgPSB0aGlzLkR5bmFtaWNSb3dDb2x1bW5zRGVmaW5pdGlvbjtcclxuXHJcbiAgICAgICAgdGhpcy5oZWFkZXJzID0gZHJjZCAmJiBkcmNkLmxlbmd0aCA+IDAgPyB0aGlzLmV4cEV4dHMuc2V0dXBGb3JHZW5lcmljRXhwb3J0KGl0ZW1zLCBkcmNkLm1hcCh0ID0+IHsgcmV0dXJuIHsgbGFiZWw6IHQuZGVzY3JpcHRpb24sIGtleTogdC5wcm9wZXJ0eU5hbWUsIG9yZGVyOiB0LmNvbHVtbk9yZGVyIH0gfSkpIDogdGhpcy5leHBFeHRzLnNldHVwRm9yRXhwb3J0KGl0ZW1zKTtcclxuICAgICAgICB0aGlzLmRhdGEgPSBpdGVtcztcclxuICAgIH1cclxuXHJcbiAgICAvLyAjZW5kcmVnaW9uXHJcblxyXG4gICAgLy8gI3JlZ2lvbiBHZXN0aW9uZSBNb2RhbGl0w6AgUmVwb3J0XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTdWwgY2xpY2sgZGVsbCdIZWFkZXIgZGkgdW5hIGNvbG9ubmEgcXVlc3RvIG1ldG9kbyBzaSBvY2N1cGEgZGkgYXBwbGljYXJlIGwnb3JkaW5hbWVudG8gc3VjY2Vzc2l2byBlIGRpIG5vdGlmaWNhcmUgY29uICoqZW1pdFNlYXJjaFJlcXVlc3QqKlxyXG4gICAgICogaWwgYmlzb2dubyBkaSBhZ2dpb3JuYXJlIGkgZGF0aSBkYSBwYXJ0ZSBkZWwgY29tcG9uZW50ZSBjaGUgdXRpbGl6emEgbGEgdGFiZWxsYVxyXG4gICAgICpcclxuICAgICAqIFV0aWxpenphdG8gc29sbyBpbiBtb2RhbGl0w6AgUkVwb3J0XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtSZXBvcnRDb2x1bW59IGNsbSBDb2xvbm5hIGRlbCByZXBvcnQgcGVyIGN1aSBvcmRpbmFyZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0dXBOZXh0T3JkZXJBbmRTZWFyY2goY2xtOiBSZXBvcnRDb2x1bW4pIHtcclxuICAgICAgICBpZiAoISh0aGlzLlZpZXcgaW5zdGFuY2VvZiBSZXBvcnREZWZpbml0aW9uKSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdWaWV3IGRpdmVyc2EgZGEgcmVwb3J0ZGVmaW5pdGlvbiBlbnRyYXRhIG5lbCBtZXRvZG8gc2V0dXBOZXh0T3JkZXJBbmRTZWFyY2gnKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IG9yZGVyTmV4dCA9IHsgTk9ORTogJ0RFU0MnLCBERVNDOiAnQVNDJywgQVNDOiBudWxsIH07XHJcbiAgICAgICAgbGV0IG5leHRPcmRlciA9IG9yZGVyTmV4dFtjbG0ub3JkZXIgfHwgJ05PTkUnXTtcclxuICAgICAgICBjbG0ub3JkZXIgPSBuZXh0T3JkZXI7XHJcblxyXG4gICAgICAgIGxldCBvcmRlcjogUmVwb3J0T3JkZXI7XHJcbiAgICAgICAgbGV0IGNsbU9yZGVyID0gdGhpcy5WaWV3Lm9yZGVycyA/IHRoaXMuVmlldy5vcmRlcnMuZmlsdGVyKHQgPT4gdC5jb2x1bW4gPT0gY2xtLmlkKSA6IFtdO1xyXG4gICAgICAgIGlmIChjbG1PcmRlci5sZW5ndGggPT0gMCAmJiBjbG0ub3JkZXIpIHtcclxuICAgICAgICAgICAgb3JkZXIgPSBuZXcgUmVwb3J0T3JkZXIoKTtcclxuICAgICAgICAgICAgb3JkZXIuY29sdW1uID0gY2xtLmlkO1xyXG4gICAgICAgICAgICBvcmRlci5vcmRlciA9IGNsbS5vcmRlcjtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLlZpZXcub3JkZXJzKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5WaWV3Lm9yZGVycyA9IFtdO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5WaWV3Lm9yZGVycy5wdXNoKG9yZGVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoY2xtT3JkZXIubGVuZ3RoID09IDEpIHtcclxuICAgICAgICAgICAgLy8gUmltdW92byBsJ29yZGluYW1lbnRvIG8gYWdnaW9ybm8gcXVlbGxvIGdpw6AgZXNpc3RlbnRlXHJcbiAgICAgICAgICAgIGlmKCFjbG0ub3JkZXIpXHJcbiAgICAgICAgICAgICAgICBjbG1PcmRlciA9IFtdO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICBjbG1PcmRlclswXS5vcmRlciA9IGNsbS5vcmRlcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0ltcG9zc2liaWxlIHNldHRhcmUgb3JkaW5hbWVudG8uIENvbG9ubmEgJyArIGNsbS5pZCArICcgZGlyZXR0aXZlIGRpIG9yZGluYW1lbnRvICcgKyBjbG1PcmRlci5sZW5ndGggKyAnIG9yZGluYW1lbnRvIHNjZWx0byAnICsgY2xtLm9yZGVyKTtcclxuXHJcbiAgICAgICAgLy8gRG9wbyBhdmVyIGFnZ2lvcm5hdG8gbCdvcmRpbmFtZW50byByaWxhbmNpbyBsYSByaWNlcmNhXHJcbiAgICAgICAgdGhpcy5lbWl0U2VhcmNoUmVxdWVzdChmYWxzZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gY2hlIHNpIG9jY3VwYSBkaSBnZXN0aXJlIGxhIGdyYWZpY2EgZGVsbGEgdGFiZWxsYSBpbiBiYXNlIGFsbGUgaW5mb3JtYXppb25pIGRpIG9yZGluYW1lbnRvIGNvbG9ubmUgZSBwYWdpbmF6aW9uZSBjb250ZW51dGkgbmVsIG1vZGVsbG9cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSByZXZpZXdSZXBvcnRCaW5kaW5ncygpIHtcclxuICAgICAgICBpZiAoISh0aGlzLlZpZXcgaW5zdGFuY2VvZiBSZXBvcnREZWZpbml0aW9uKSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdWaWV3IGRpdmVyc2EgZGEgcmVwb3J0ZGVmaW5pdGlvbiBlbnRyYXRhIG5lbCBtZXRvZG8gcmV2aWV3UmVwb3J0QmluZGluZ3MnKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQWxsaW5lbyBsZSBpbmZvcm1hemlvbmkgc3UgZXZlbnR1YWxpIG9yZGluYW1lbnRpIGZhdHRpIHByZWNlZGVudGVtZW50ZVxyXG4gICAgICAgIGlmICh0aGlzLlZpZXcub3JkZXJzICYmIHRoaXMuVmlldy5vcmRlcnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICB0aGlzLlZpZXcub3JkZXJzLmZvckVhY2godCA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLlJlcG9ydFZhbHVlcy5jb2x1bW5zLmZpbHRlcihjID0+IGMuaWQgPT0gdC5jb2x1bW4pWzBdLm9yZGVyID0gdC5vcmRlcjtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBSZWN1cGVybyBpbCBjb3VudCBwcmVjZWRlbnRlIHNlIHNlcnZlXHJcbiAgICAgICAgaWYgKHRoaXMuUmVwb3J0VmFsdWVzLmNvdW50ICE9IC0yKVxyXG4gICAgICAgICAgICB0aGlzLnByZXZpb3VzQ291bnQgPSB0aGlzLlJlcG9ydFZhbHVlcy5jb3VudDtcclxuICAgICAgICBlbHNlIGlmICh0aGlzLlJlcG9ydFZhbHVlcy5jb3VudCA9PSAtMilcclxuICAgICAgICAgICAgdGhpcy5SZXBvcnRWYWx1ZXMuY291bnQgPSB0aGlzLnByZXZpb3VzQ291bnQ7XHJcblxyXG4gICAgICAgIGxldCBpcHAgPSAodGhpcy5WaWV3Lml0ZW1zcGVycGFnZW92ZXJyaWRlIHx8IDE1KTtcclxuICAgICAgICB0aGlzLlZpZXcucGFnZXMgPSBNYXRoLmNlaWwodGhpcy5SZXBvcnRWYWx1ZXMuY291bnQgLyBpcHApO1xyXG4gICAgICAgIHRoaXMuYXJyYXlQdWxzYW50aSA9IHRoaXMuZ2V0UGFnZXNBcnJheSg2LCB0aGlzLlZpZXcucGFnZSwgdGhpcy5WaWV3LnBhZ2VzKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyAjZW5kcmVnaW9uXHJcblxyXG4gICAgLy8gI3JlZ2lvbiBHZXN0aW9uZSB1cGRhdGUgYXV0b21hdGljb1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGNoZSBnZXN0aXNjZSBsYSBtb2RpZmljYSBkZWwgdGVtcG8gc3BlY2lmaWNhdG8gcGVyIGwnYWdnaW9ybmFtZW50byBhdXRvbWF0aWNvXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhdXRvVXBkYXRlQ2hhbmdlZCgpIHtcclxuICAgICAgICBpZiAoIS9eWzEtOV1cXGQqJC8udGVzdCh0aGlzLnNlY29uZHMpKVxyXG4gICAgICAgICAgICB0aGlzLnNlY29uZHMgPSAnMTAnO1xyXG5cclxuICAgICAgICBsZXQgc2Vjb25kc0luTXMgPSBwYXJzZUludCh0aGlzLnNlY29uZHMsIG51bGwpICogMTAwMDtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuYXV0b1VwZGF0ZSlcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVUaW1lciA9IHNldEludGVydmFsKCgpID0+IHsgdGhpcy5lbWl0U2VhcmNoUmVxdWVzdChmYWxzZSk7IH0sIHNlY29uZHNJbk1zKTtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy51cGRhdGVUaW1lcik7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gI2VuZHJlZ2lvblxyXG5cclxuICAgIC8vICNyZWdpb24gR2VzdGlvbmUgdGFiZWxsYSBkaW5hbWljYVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGNoaWFtYXRvIGRhbCBjbGljayBzdSB1bmEgZGVsbGUgY29sb25uZSBnZW5lcmF0ZSBkYWxsJ0lucHV0ICoqRHluYW1pY09wZXJhdGlvbnMqKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55fSBpdGVtIEwnb2dnZXR0byBzdSBjdWkgdmEgZWZmZXR0dWF0YSBsJ29wZXJhemlvbmVcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcGlkIENvZGljZSBpZGVudGlmaWNhdGl2byBkZWxsJ29wZXJhemlvbmUgZGEgZWZmZXR0dWFyc2lcclxuICAgICAqL1xyXG4gICAgcHVibGljIGR5bmFtaWNPcGVyYXRpb24oaXRlbTogYW55LCBvcGlkOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLm9uRHluYW1pY09wZXJhdGlvbi5lbWl0KHsgaWQ6IG9waWQsIGl0ZW06IGl0ZW0gfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPdHRpZW5lIGlsIGNvbnRlbnV0byBkZWxsJ0VzVGQgZGEgdXRpbGl6emFyZSBwZXIgbGEgY29sb25uYSBzcGVjaWZpY2F0YVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY29sdW1uIENvbG9ubmEgcGVyIGN1aSBjZXJjYXJlIGxhIGNlbGxhXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHtUZW1wbGF0ZVJlZjxhbnk+fSBUZW1wbGF0ZSBkYSB1c2FyZSBwZXIgbGEgY29sb25uYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZmluZEVzVGQoY29sdW1uOiBzdHJpbmcpOiBUZW1wbGF0ZVJlZjxhbnk+IHtcclxuICAgICAgICB2YXIgRXNUZCA9IHRoaXMuRXNUZHNEaXJlY3RpdmUuZmluZCgoaXRlbSkgPT4gaXRlbS50ZCA9PT0gY29sdW1uKTtcclxuICAgICAgICByZXR1cm4gRXNUZCA/IEVzVGQuVGVtcGxhdGUgOiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGRpIHN1cHBvcnRvIGFsbGEgY3JlYXppb25lIGRpIHVuIHJvdXRlciBsaW5rIHBhcmFtZXRyaXp6YXRvIGFsbCdvZ2dldHRvIGNvcnJlbnRlIHV0aWxpenphdG8gbmVsbGEgbW9kYWxpdMOgIGRpbmFtaWNhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggUGF0aCBzdSBjdWkgbmF2aWdhcmUgY29uIGV2ZW50dWFsaSBwYXJhbWV0cmkgcmlmZXJpdGkgYWxsJ29nZ2V0dG8gY290bmVzdHVhbGUgY29tZSB7MH0sIHsxfSwgZWNjLi4uXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBwYXJhbWV0ZXJQcm9wcyBMaXN0YSBwb3NpemlvbmFsZSBkZWxsZSBwcm9wcmlldMOgIGEgY3VpIGJpbmRhcmUgaSByaWZlcmltZW50aSBkZWwgcGFyYW1ldHJvICoqcGF0aCoqXHJcbiAgICAgKiBFcy4gSWwgdmFsb3JlIGRlbGEgcHJvcHJpZXTDoCBhbGwnaW5kaWNlIDAgZGkgcXVlc3RvIGFycmF5IHZlcnLDoCBzb3N0aXR1aXRhIGFsIHZhbG9yZSB7MH0gZGVsIHBhcmFtZXRybyAqKnBhdGgqKlxyXG4gICAgICogQHBhcmFtIHtHZW5lcmljSXRlbX0gaXRlbSBPZ2dldHRvIGdlbmVyaWNvIGNvbGxlZ2F0byBhIHF1ZXN0byBjb250ZXN0b1xyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHthbnl9IFJvdXRlciBsaW5rIGdlbmVyYXRvIGluIGJhc2UgYWwgcGFyYW1ldHJpXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZW5lcmF0ZVJvdXRlckxpbmsocGF0aDogc3RyaW5nLCBwYXJhbWV0ZXJQcm9wczogc3RyaW5nW10sIGl0ZW06IEdlbmVyaWNJdGVtKTogYW55IHtcclxuICAgICAgICBpZiAodGhpcy5EeW5hbWljVGFibGVSb3V0ZXJMaW5rQ2FjaGVbaXRlbS5oYXNoICsgcGF0aF0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuRHluYW1pY1RhYmxlUm91dGVyTGlua0NhY2hlW2l0ZW0uaGFzaCArIHBhdGhdO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGxldCBsaW5rID0gdGhpcy5nZXRSb3V0ZXJMaW5rKHBhdGgsIHBhcmFtZXRlclByb3BzLCBpdGVtKTtcclxuICAgICAgICAgICAgdGhpcy5EeW5hbWljVGFibGVSb3V0ZXJMaW5rQ2FjaGVbaXRlbS5oYXNoICsgcGF0aF0gPSBsaW5rO1xyXG4gICAgICAgICAgICByZXR1cm4gbGluaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhIHVuIHJvdXRlciBsaW5rXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggUGF0aCBzdSBjdWkgbmF2aWdhcmUgY29uIGV2ZW50dWFsaSBwYXJhbWV0cmkgcmlmZXJpdGkgYWxsJ29nZ2V0dG8gY290bmVzdHVhbGUgY29tZSB7MH0sIHsxfSwgZWNjLi4uXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBwYXJzIExpc3RhIHBvc2l6aW9uYWxlIGRlbGxlIHByb3ByaWV0w6AgYSBjdWkgYmluZGFyZSBpIHJpZmVyaW1lbnRpIGRlbCBwYXJhbWV0cm8gKipwYXRoKipcclxuICAgICAqIEVzLiBJbCB2YWxvcmUgZGVsYSBwcm9wcmlldMOgIGFsbCdpbmRpY2UgMCBkaSBxdWVzdG8gYXJyYXkgdmVycsOgIHNvc3RpdHVpdGEgYWwgdmFsb3JlIHswfSBkZWwgcGFyYW1ldHJvICoqcGF0aCoqXHJcbiAgICAgKiBAcGFyYW0ge0dlbmVyaWNJdGVtfSBpdGVtIE9nZ2V0dG8gZ2VuZXJpY28gY29sbGVnYXRvIGEgcXVlc3RvIGNvbnRlc3RvXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2FueX0gUm91dGVyIGxpbmsgZ2VuZXJhdG8gaW4gYmFzZSBhbCBwYXJhbWV0cmlcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZXRSb3V0ZXJMaW5rKHBhdGg6IHN0cmluZywgcGFyczogc3RyaW5nW10sIGl0ZW06IEdlbmVyaWNJdGVtKTogYW55IHtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICBwYXRoID0gcGF0aC5yZXBsYWNlKCd7JyArIGkgKyAnfScsIGl0ZW0ucHJvcGVydGllc1twYXJzW2ldXSk7XHJcblxyXG4gICAgICAgIHBhdGggPSBwYXRoLnJlcGxhY2UoLycvZywgJ1wiJykucmVwbGFjZSgvIC9nLCAnJyk7XHJcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UocGF0aCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gI2VuZHJlZ2lvblxyXG5cclxuICAgIC8vICNyZWdpb24gUGFnaW5hemlvbmUgaW4gbW9kYWxpdMOgIEFycmF5XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFcXVpdmFsZW50ZSBkZWwgbWV0b2RvICoqYWRkVG9QYWdlKiogcmlhZGF0dGF0byBwZXIgbGEgbW9kYWxpdMOgIGFycmF5XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2UgTnVtZXJvIGRpIHBhZ2luZSBkYSBhZ2dpdW5nZXJlIChvIHNvdHRyYXJyZSwgc2UgbmVnYXRpdm8pIGFsbGEgcGFnaW5hIGF0dHVhbGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGFycmF5QWRkVG9QYWdlKHBhZ2U6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMuYXJyYXlHb1RvUGFnZSh0aGlzLmFycmF5bW9kZVBhZ2UgKyBwYWdlKVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXF1aXZhbGVudGUgZGVsIG1ldG9kbyAqKmdvVG9QYWdlKiogcmlhZGF0dGF0byBwZXIgbGEgbW9kYWxpdMOgIGFycmF5XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2UgUGFnaW5hIGEgY3VpIG5hdmlnYXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhcnJheUdvVG9QYWdlKHBhZ2U6IG51bWJlcikge1xyXG4gICAgICAgIGlmIChwYWdlID09PSAwIHx8IHBhZ2UgPiB0aGlzLmFycmF5bW9kZVBhZ2VzKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgdGhpcy5hcnJheW1vZGVQYWdlID0gcGFnZTtcclxuXHJcbiAgICAgICAgLy8gUmlmb3J6byBpbCB3cml0ZXZhbHVlIGluIG1vZG8gY2hlIGlsIGNvZGljZSBwYXNzaSBkYWxsYSBnZXN0aW9uZSBjb21lIHNlIGZvc3NlIGZhdHRhIHJpcGFydGlyZSB1bmEgcmljZXJjYVxyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxXcml0ZVZhbHVlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gcGVyIGVmZmV0dHVhcmUgaWwgcmVmcmVzaCBkZWxsYSBwYWdpbmF6aW9uZSBzdWwgY2FtYmlhbWVudG8gZGVnbGkgb2dnZXR0aSBkYSB2aXN1YWxpenphcmUgaW4gdW5hIHNpbmdvbGEgcGFnaW5hLlxyXG4gICAgICpcclxuICAgICAqIFZhbGUgc29sbyBwZXIgbGEgbW9kYWxpdMOgIEFycmF5XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2VTaXplIERpbWVuc2lvbmUgZGVsbGEgcGFnaW5hXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWZyZXNoUGFnaW5nKHBhZ2VTaXplOiBudW1iZXIpIHtcclxuICAgICAgICB0aGlzLkFycmF5bW9kZUl0ZW1zUGVyUGFnZSA9IHBhZ2VTaXplO1xyXG4gICAgICAgIHRoaXMuYXJyYXltb2RlUGFnZXMgPSBNYXRoLmNlaWwoKHRoaXMuVmlldyBhcyBhbnlbXSkubGVuZ3RoIC8gdGhpcy5BcnJheW1vZGVJdGVtc1BlclBhZ2UpO1xyXG4gICAgICAgIHRoaXMuYXJyYXltb2RlUGFnZSA9IDE7XHJcblxyXG4gICAgICAgIC8vIFJpZm9yem8gaWwgd3JpdGV2YWx1ZSBpbiBtb2RvIGNoZSBpbCBjb2RpY2UgcGFzc2kgZGFsbGEgZ2VzdGlvbmUgY29tZSBzZSBmb3NzZSBmYXR0YSByaXBhcnRpcmUgdW5hIHJpY2VyY2FcclxuICAgICAgICB0aGlzLmludGVybmFsV3JpdGVWYWx1ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2VuZXJhIGxlIGluZm9ybWF6aW9uaSBkaSBwYWdpbmF6aW9uZSBlIHRhZ2xpYSBsYSBWaWV3IGluIG1vZGFsaXTDoCBhcnJheSBwZXIgbW9zdHJhcmUgc29sbyBnbGkgb2dnZXR0aSBkZWxsYSBwYWdpbmEgc3BlY2lmaWNhdGFcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBhZGFwdFZpZXdUb1BhZ2luZygpIHtcclxuICAgICAgICBsZXQgdG1wSXRlbXM6IGFueVtdID0gW107XHJcblxyXG4gICAgICAgIC8vIFNlIGhvIHVuYSBzZWFyY2ggdmlldyBsJ2FycmF5IHB1bHNhbnRpIHZpZW5lIGNhbGNvbGF0byBkYSBsZWksIG5vbiBkZXZvIHByZW5kZXJlIHF1ZWxsbyBkZWxsYSBtb2RhbGl0w6AgYXJyYXlcclxuICAgICAgICBpZighdGhpcy5TZWFyY2hWaWV3KVxyXG4gICAgICAgICAgICB0aGlzLmFycmF5UHVsc2FudGkgPSB0aGlzLmdldFBhZ2VzQXJyYXkoNiwgdGhpcy5hcnJheW1vZGVQYWdlLCB0aGlzLmFycmF5bW9kZVBhZ2VzKTtcclxuXHJcbiAgICAgICAgLy8gUG9pIHBlciB0dXR0aSBpIHZhbG9yaSBkb3BvIGNvbXByZXNpIGZyYSBsYSBwYWdpbmEgLSAxIGUgbGEgcGFnaW5hXHJcbiAgICAgICAgZm9yIChsZXQgaSA9ICgodGhpcy5hcnJheW1vZGVQYWdlIC0gMSkgKiB0aGlzLkFycmF5bW9kZUl0ZW1zUGVyUGFnZSk7IGkgPCB0aGlzLmFycmF5bW9kZVBhZ2UgKiB0aGlzLkFycmF5bW9kZUl0ZW1zUGVyUGFnZTsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChpIDw9ICh0aGlzLlZpZXcgYXMgYW55W10pLmxlbmd0aCAtIDEpXHJcbiAgICAgICAgICAgICAgICB0bXBJdGVtcy5wdXNoKCh0aGlzLlZpZXcgYXMgYW55W10pW2ldKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRtcEl0ZW1zO1xyXG4gICAgfVxyXG5cclxuICAgIC8vICNlbmRyZWdpb25cclxuXHJcbiAgICAvLyAjcmVnaW9uIEdlc3Rpb25lIGNsaWNrIHN1bGxlIGNlbGxlIGRpbmFtaWNoZSBlIG9wemlvbmkgbmVsIENvcm5lciBNZW51XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXN0b3JlIGRlaSBjbGljayBzdWxsZSBjZWxsZSBwZXIgbGUgcXVhbGkgZXJhIGltcG9zdGF0YSB1bmEgYXppb25lIGN1c3RvbSBkYSAqKkN1c3RvbUNlbGxBY3Rpb25zT24qKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIE5vbWUgZGVsbGEgY2VsbGEgc3UgY3VpIHNpIMOoIGZhdHRvIGNsaWNrXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gbW9kZWwgTW9kZWxsbyByZWxhdGl2byBhbGxhIGNlbGxhIGNsaWNjYXRhXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59ICoqdHJ1ZSoqIHNlIGlsIGNsaWNrIMOoIHN0YXRvIGZhdHRvIHN1IHVuYSBjZWxsYSBjbGljY2FiaWxlLCAqKmZhbHNlKiogYWx0cmltZW50aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY2VsbENsaWNrZWQobmFtZTogc3RyaW5nLCBtb2RlbDogYW55KTogYm9vbGVhbiB7XHJcbiAgICAgICAgaWYgKHRoaXMuVXNlQ3VzdG9tQ2VsbEFjdGlvbnMgJiYgdGhpcy5DdXN0b21DZWxsQWN0aW9uc09uLnNwbGl0KCckJykuaW5kZXhPZihuYW1lKSAhPSAtMSkge1xyXG4gICAgICAgICAgICB0aGlzLm9uQ2VsbENsaWNrLmVtaXQoeyBjb2x1bW46IG5hbWUsIG1vZGVsOiBtb2RlbCB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXN0aW9uZSBkZWkgY2xpY2sgc3VsbGUgb3B6aW9uaSBkZWwgbWVuw7kgY29udGVzdHVhbGUgaW4gYWx0byBhIGRlc3RyYSBnZW5lcmF0byBkYWxsJ0lucHV0ICoqQ29ybmVyTWVudU9wdGlvbnMqKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjb3JuZXJpZCBDb2RpY2UgZGVsbCdvcGVyYXppb25lIHNlbGV6aW9uYXRhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb3JuZXJBY3Rpb25DbGlja2VkKGNvcm5lcmlkOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLm9uQ29ybmVyQWN0aW9uLmVtaXQoeyBpZDogY29ybmVyaWQsIGVzdGFibGU6IHRoaXMgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gI2VuZHJlZ2lvblxyXG5cclxuICAgIC8vICNyZWdpb24gTWV0b2RpIGRpIHV0aWxpdMOgXHJcblxyXG4gICAgLyoqIEltcG9zdGF6aW9uZSBtb2RhbGl0w6AgZGVsbCdFc1RhYmxlICovXHJcbiAgICBwcml2YXRlIHNldE1vZGUobW9kZTogJ2FycmF5JyB8ICd2aWV3JyB8ICdyZXBvcnQnKSB7XHJcbiAgICAgICAgdGhpcy52aWV3TW9kZSA9IG1vZGUgPT0gJ3ZpZXcnO1xyXG4gICAgICAgIHRoaXMuYXJyYXlNb2RlID0gbW9kZSA9PSAnYXJyYXknO1xyXG4gICAgICAgIHRoaXMucmVwb3J0TW9kZSA9IG1vZGUgPT0gJ3JlcG9ydCc7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLnJlcG9ydE1vZGUpIHtcclxuICAgICAgICAgICAgLy8gSW4gbW9kYWxpdMOgIHJlcG9ydCBobyBkaSBzaWN1cm8gcXVlc3RlIGR1ZVxyXG4gICAgICAgICAgICB0aGlzLlhMU1hFeHBvcnQgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLkNTVkV4cG9ydCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhlbHBlciBwZXIgZWZmZXR0dWFyZSBjaGlhbWF0ZSBpbnRlcm5lIGRpIGFsbGluZWFtZW50byBhbGxhIGZ1bnppb25lICoqd3JpdGVWYWx1ZSoqLCBpbXBvc3RhbmRvIHByaW1hICoqaW50ZXJuYWxXcml0ZUNhbGwqKiBpbiBtb2RvIGRhIG5vbiBlZmZldHR1YXJlIG9wZXJhemlvbmkgaW51dGlsaVxyXG4gICAgICovXHJcbiAgICAgcHJpdmF0ZSBpbnRlcm5hbFdyaXRlVmFsdWUoKSB7XHJcbiAgICAgICAgdGhpcy5pbnRlcm5hbFdyaXRlQ2FsbCA9IHRydWU7XHJcbiAgICAgICAgdGhpcy53cml0ZVZhbHVlKHRoaXMuVmlldyk7XHJcbiAgICAgICAgdGhpcy5pbnRlcm5hbFdyaXRlQ2FsbCA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGF0ZSBsZSBpbmZvcm1hemlvbmkgZGkgcGFnaW5hemlvbmUgb3R0aWVuZSBsJ2FycmF5IGRlaSBwdWxzYW50aVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtYXhCdG5zIE51bWVybyBtYXNzaW1vIGRpIHB1bHNhbnRpIGRhIHZpc3VhbGl6emFyZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2UgUGFnaW5hIGNvcnJlbnRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbGFzdFBhZ2UgVWx0aW1hIHBhZ2luYSBkaXNwb25pYmlsZVxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHthbnlbXX0gUHNldWRvLWFycmF5IGRpIHB1bHNhbnRpIGEgY3VpIGNpIHNpIHB1w7IgYmluZGFyZSBsYXRvIEhUTUxcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZXRQYWdlc0FycmF5KG1heEJ0bnM6IG51bWJlciwgcGFnZTogbnVtYmVyLCBsYXN0UGFnZTogbnVtYmVyKTogYW55W10ge1xyXG4gICAgICAgIGxldCByZXN1bHQgPSBbXTtcclxuICAgICAgICBpZiAobGFzdFBhZ2UgPT0gLTEpXHJcbiAgICAgICAgICAgIGxhc3RQYWdlID0gcGFnZSArIDE7XHJcblxyXG4gICAgICAgIGxldCBtaW4sIG1heDtcclxuICAgICAgICBpZiAobGFzdFBhZ2UgPD0gbWF4QnRucykge1xyXG4gICAgICAgICAgICBtaW4gPSAxO1xyXG4gICAgICAgICAgICBtYXggPSBsYXN0UGFnZSAtIDE7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gdG9sZ28gbGEgcGFnaW5hIHNlbGVjdGVkIMOoIGwndWx0aW1hIHBhZ2luYSBjaGUgw6ggcXVlbGxhIGRlbGxlIHBhZ2luZSB0b3RhbGlcclxuICAgICAgICAgICAgbGV0IHJhbmdlT3V0c2lkZSA9IChtYXhCdG5zIC0gMikgLyAyO1xyXG5cclxuICAgICAgICAgICAgbWluID0gcGFnZSAtIHJhbmdlT3V0c2lkZTtcclxuICAgICAgICAgICAgbWF4ID0gcGFnZSArIHJhbmdlT3V0c2lkZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChtaW4gPCAxKSB7XHJcbiAgICAgICAgICAgICAgICBtaW4gPSAxO1xyXG4gICAgICAgICAgICAgICAgbWF4ID0gbWF4QnRucyAtIDE7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobWF4ID49IGxhc3RQYWdlKSB7XHJcbiAgICAgICAgICAgICAgICBtaW4gPSBsYXN0UGFnZSAtIG1heEJ0bnMgKyAxO1xyXG4gICAgICAgICAgICAgICAgbWF4ID0gbGFzdFBhZ2UgLSAxO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXN1bHQucHVzaCh7IHZhbDogMSwgY3NzQ2xhc3M6ICgxID09PSBwYWdlID8gJ2J0bi1tYWluIGFwcC13aGl0ZS10ZXh0JyA6ICdhcHAtd2hpdGUtYnV0dG9uJykgfSk7XHJcblxyXG4gICAgICAgIGlmIChtYXggPj0gbWluKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBtaW47IGkgPD0gbWF4OyBpKyspXHJcbiAgICAgICAgICAgICAgICBpZiAoaSAhPT0gMSlcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaCh7IHZhbDogaSwgY3NzQ2xhc3M6IChpID09PSBwYWdlID8gJ2J0bi1tYWluIGFwcC13aGl0ZS10ZXh0JyA6ICdhcHAtd2hpdGUtYnV0dG9uJykgfSk7XHJcblxyXG4gICAgICAgICAgICByZXN1bHQucHVzaCh7XHJcbiAgICAgICAgICAgICAgICB2YWw6IGxhc3RQYWdlLFxyXG4gICAgICAgICAgICAgICAgY3NzQ2xhc3M6IChsYXN0UGFnZSA9PT0gcGFnZSA/ICdidG4tbWFpbiBhcHAtd2hpdGUtdGV4dCcgOiAnYXBwLXdoaXRlLWJ1dHRvbicpXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsY29sYSBsJ2hhc2ggZGkgdW4gb2dnZXR0byBxdWFsc2lhc2lcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge2FueVtdfSBpdGVtcyBPZ2dldHRpIHBlciBjdWkgY2FsY29sYXJlIGwnaGFzaFxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGNhbGN1bGF0ZUhhc2goaXRlbXM6IGFueVtdKSB7XHJcbiAgICAgICAgaWYgKCFpdGVtcylcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAvLyBTdXBwb3J0byBhIGhhc2ggZHVwbGljYXRpIGRpIG9nZ2V0dGkgdWd1YWxpXHJcbiAgICAgICAgbGV0IHVzZWRIYXNoZXNDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IG51bWJlciB9ID0ge307XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgaXRlbSA9IGl0ZW1zW2ldO1xyXG5cclxuICAgICAgICAgICAgLy8gUHJpbWEgZGkgY2FsY29sYXJlIGwnaGFzaCByaW11b3ZvIGxlIHByb3ByaWV0w6AgaW50ZXJuZSBwcmltYSBjaGUgbWkgc2NvbXBlbnNpbm8gaSBjYWxjb2xpIHN1Y2Nlc3NpdmlcclxuICAgICAgICAgICAgZGVsZXRlIGl0ZW0uX3NlbGVjdGVkO1xyXG4gICAgICAgICAgICBkZWxldGUgaXRlbS5oYXNoO1xyXG5cclxuICAgICAgICAgICAgbGV0IGhhc2ggPSB0aGlzLmhhc2hFeHRzLmhhc2hPYmplY3QoaXRlbSk7XHJcbiAgICAgICAgICAgIHVzZWRIYXNoZXNDYWNoZVtoYXNoXSA9IHVzZWRIYXNoZXNDYWNoZVtoYXNoXSA/IHVzZWRIYXNoZXNDYWNoZVtoYXNoXSArIDEgOiAxO1xyXG4gICAgICAgICAgICBpdGVtLmhhc2ggPSBoYXNoICsgKHVzZWRIYXNoZXNDYWNoZVtoYXNoXSA+IDEgPyBcIl9cIiArIHVzZWRIYXNoZXNDYWNoZVtoYXNoXSA6IFwiXCIpXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGV2ZW50dWFsbWVudGUgcmljaGlhbWFiaWxlIGFuY2hlIGRhbCBjb21wb25lbnRlIGVzdGVybm8gY2hlIHBlcm1ldHRlIGRpIGZvcnphcmUgdW4gcmVmcmVzaCBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBmb3JjZVJlZnJlc2goKSB7XHJcblxyXG4gICAgICAgIC8vIFNlIHNvbm8gaW4gbW9kYWxpdMOgIFZpZXcgdmllbmUgbWFudGVudXRvIGluIGF1dG9tYXRpY28gaWwgbnVtZXJvIGRpIHBhZ2luYSwgbWEgcGVyIGxhIG1vZGFsaXTDoCBhcnJheSBkZXZvIHByZW5kZXJlIGxlIGluZm8gZGkgcGFnaW5hemlvbmUgcHJpbWEgZSByaWFwcGxpY2FybGUgZG9wb1xyXG4gICAgICAgIGxldCBhcnJheVBhZ2U6IG51bWJlcjtcclxuICAgICAgICBsZXQgYXJyYXlJcHA6IG51bWJlcjtcclxuICAgICAgICBpZiAodGhpcy5hcnJheU1vZGUpIHtcclxuICAgICAgICAgICAgYXJyYXlQYWdlID0gdGhpcy5hcnJheW1vZGVQYWdlO1xyXG4gICAgICAgICAgICBhcnJheUlwcCA9IHRoaXMuQXJyYXltb2RlSXRlbXNQZXJQYWdlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy53cml0ZVZhbHVlKHRoaXMuVmlldyk7XHJcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5hcnJheU1vZGUpIHtcclxuICAgICAgICAgICAgdGhpcy5BcnJheW1vZGVJdGVtc1BlclBhZ2UgPSBhcnJheUlwcDtcclxuICAgICAgICAgICAgdGhpcy5hcnJheUdvVG9QYWdlKGFycmF5UGFnZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vICNlbmRyZWdpb25cclxufSJdfQ==
|
|
3453
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXNfdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvZXMtdGFibGUvc3JjL2xpYi9lc190YWJsZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLFVBQVU7QUFDVixPQUFPLEVBQ0gsU0FBUyxFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQWEsaUJBQWlCLEVBQUUsdUJBQXVCLEVBQUUsS0FBSyxFQUNwRyxZQUFZLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBNEIsU0FBUyxFQUFjLGlCQUFpQixFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQWUsTUFBTSxFQUM5SSxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWpFLGlCQUFpQjtBQUNqQixPQUFPLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xILE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzlELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBSzNELFVBQVU7QUFDVixPQUFPLEVBQ0gsU0FBUyxFQUFFLFdBQVcsRUFBZSx3QkFBd0IsRUFBb0IsZ0JBQWdCLEVBQWdCLFdBQVcsRUFDaEcsYUFBYSxFQUFFLGdCQUFnQixFQUFFLFVBQVUsRUFBRSxrQkFBa0IsRUFBRSxZQUFZLEVBQzVHLE1BQU0sVUFBVSxDQUFDO0FBRWxCLDhCQUE4QjtBQUM5QixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDekMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1B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QUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO3dCQUMvRyxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7NEJBQ25CLEVBQUUsVUFBVSxFQUFRLFFBQVMsQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFRLFFBQVMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsWUFBWSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLFFBQVEsQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFlBQVksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7NEJBQ25XLEVBQUUsVUFBVSxFQUFRLFFBQVMsQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFRLFFBQVMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsWUFBWSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLFFBQVEsQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLFFBQVEsQ0FBQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFD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LEVBQUU7b0NBVXZDLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBBbmd1bGFyXHJcbmltcG9ydCB7XHJcbiAgICBDb21wb25lbnQsIGZvcndhcmRSZWYsIENvbnRlbnRDaGlsZHJlbiwgUXVlcnlMaXN0LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIElucHV0LFxyXG4gICAgRXZlbnRFbWl0dGVyLCBPdXRwdXQsIENvbnRlbnRDaGlsZCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYsIFZpZXdFbmNhcHN1bGF0aW9uLCBPcHRpb25hbCwgU2VsZiwgVGVtcGxhdGVSZWYsIEluamVjdFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTmdDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5cclxuLy8gQ29uZmlndXJhemlvbmlcclxuaW1wb3J0IHsgSGFzaGluZ1NlcnZpY2UsIFV0aWxpdHlTZXJ2aWNlLCBFeHBvcnRTZXJ2aWNlLCBNZXNzYWdlU2VydmljZSwgRGF0ZVNlcnZpY2UgfSBmcm9tICdAZXNmYWVuemEvZXh0ZW5zaW9ucyc7XHJcbmltcG9ydCB7IExvY2FsaXphdGlvblNlcnZpY2UgfSBmcm9tICdAZXNmYWVuemEvbG9jYWxpemF0aW9ucyc7XHJcbmltcG9ydCB7IFByZWZlcmVuY2VzU2VydmljZSB9IGZyb20gJ0Blc2ZhZW56YS9wcmVmZXJlbmNlcyc7XHJcblxyXG4vLyBQbHVnaW5zXHJcbmltcG9ydCB7IENvbnRleHRNZW51Q29tcG9uZW50IH0gZnJvbSAnQGVzZmFlbnphL25neC1jb250ZXh0bWVudSc7XHJcblxyXG4vLyBNb2RlbGxpXHJcbmltcG9ydCB7XHJcbiAgICBBcHBTZWFyY2gsIEFwcE9yZGVyaW5nLCBHZW5lcmljSXRlbSwgRXNUYWJsZUNvbHVtbnNEZWZpbml0aW9uLCBDb3JuZXJNZW51T3B0aW9uLCBSZXBvcnREZWZpbml0aW9uLCBSZXBvcnRSZXN1bHQsIFJlcG9ydE9yZGVyLCBSZXBvcnRDb2x1bW4sIFxyXG4gICAgRXNUYWJsZU9wZXJhdGlvbkRlZmluaXRpb24sIEVzVGFibGVDb2x1bW4sIEdyb3VwQWdncmVnYXRpb24sIEdyb3VwUGFnZXIsIEdyb3VwUm91dGVGcmFnbWVudCwgQ2FjaGVUcmlwdGljXHJcbn0gZnJvbSAnLi9kb21haW4nO1xyXG5cclxuLy8gQ29tcG9uZW50aSBlIExvY2FsaXp6YXppb25lXHJcbmltcG9ydCB7IEVzVGQgfSBmcm9tICcuL2VzX3RkLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEVzVGggfSBmcm9tICcuL2VzX3RoLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IEVzVGREaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZXMvZXNfdGQuZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgRXNUaERpcmVjdGl2ZSB9IGZyb20gJy4vZGlyZWN0aXZlcy9lc190aC5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBFc1RhYmxlTG9jIH0gZnJvbSAnLi9lc190YWJsZS5jb21wb25lbnQubG9jJztcclxuaW1wb3J0IHsgSXRlbXNTZWxlY3Rpb24gfSBmcm9tICcuL2RvbWFpbi9leHRlcm5hbHMvY2xhc3Nlcy9hcHBzZWFyY2gvSXRlbXNTZWxlY3Rpb24nO1xyXG5pbXBvcnQgeyBHcm91cE9yQWdncmVnYXRpb24gfSBmcm9tIFwiLi9kb21haW4vZXh0ZXJuYWxzL2NsYXNzZXMvYXBwc2VhcmNoL0dyb3VwT3JBZ2dyZWdhdGlvblwiO1xyXG5pbXBvcnQgeyBHcm91cEZpbHRlciB9IGZyb20gXCIuL2RvbWFpbi9leHRlcm5hbHMvY2xhc3Nlcy9hcHBzZWFyY2gvR3JvdXBGaWx0ZXJcIjtcclxuaW1wb3J0IHsgR3JvdXAgfSBmcm9tIFwiLi9kb21haW4vZXh0ZXJuYWxzL2NsYXNzZXMvYXBwc2VhcmNoL0dyb3VwXCI7XHJcbmltcG9ydCB7IFRoQWdncmVnYXRpb24gfSBmcm9tICcuL2RvbWFpbi9pbnRlcm5hbHMvY2xhc3Nlcy9UaEFnZ3JlZ2F0aW9uJztcclxuaW1wb3J0IHsgRXNUYWJsZURlZmF1bHRhYmxlIH0gZnJvbSAnLi9tb2RlbHMvRXNUYWJsZURlZmF1bHRhYmxlJztcclxuXHJcbmltcG9ydCB7IEVTVF9ERUZBVUxUUywgRVNUX0xPQ0FMRSB9IGZyb20gJy4vdG9rZW5zJztcclxuXHJcbi8qKiBDb21wb25lbnRlIGNoZSBwZXJtZXR0ZSBkaSByYXBwcmVzZW50YXJlIHVuYSBncmlnbGlhIGRpIHZhbG9yaSAqL1xyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnZXMtdGFibGUnLFxyXG4gICAgdmlld1Byb3ZpZGVyczogW3sgcHJvdmlkZTogTG9jYWxpemF0aW9uU2VydmljZSwgdXNlQ2xhc3M6IEVzVGFibGVMb2MgfV0sXHJcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9lc190YWJsZS5jb21wb25lbnQuc2NzcyddLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2VzX3RhYmxlLmNvbXBvbmVudC5odG1sJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgRXNUYWJsZUNvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkNoYW5nZXMge1xyXG5cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBjb25zdHJ1Y3RvcihAU2VsZigpIEBPcHRpb25hbCgpIHB1YmxpYyBuZ0NvbnRyb2w6IE5nQ29udHJvbCwgQE9wdGlvbmFsKCkgcHJpdmF0ZSBwcmVmU2VydmljZTogUHJlZmVyZW5jZXNTZXJ2aWNlLCBAT3B0aW9uYWwoKSBASW5qZWN0KEVTVF9ERUZBVUxUUykgcHJpdmF0ZSBkZWFmdWx0czogRXNUYWJsZURlZmF1bHRhYmxlLCBAT3B0aW9uYWwoKSBASW5qZWN0KEVTVF9MT0NBTEUpIHB1YmxpYyBsb2NhbGU6IHN0cmluZywgcHVibGljIGxjOiBMb2NhbGl6YXRpb25TZXJ2aWNlLCBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsIHByaXZhdGUgaGFzaEV4dHM6IEhhc2hpbmdTZXJ2aWNlLCBwcml2YXRlIHV0aUV4dHM6IFV0aWxpdHlTZXJ2aWNlLCBwcml2YXRlIGV4cEV4dHM6IEV4cG9ydFNlcnZpY2UsIHByaXZhdGUgZGF0ZUV4dHM6IERhdGVTZXJ2aWNlLCBwcml2YXRlIG1zZ0V4dHM6IE1lc3NhZ2VTZXJ2aWNlKSB7XHJcbiAgICAgICAgaWYgKG5nQ29udHJvbClcclxuICAgICAgICAgICAgbmdDb250cm9sLnZhbHVlQWNjZXNzb3IgPSB0aGlzO1xyXG5cclxuICAgICAgICAvLyBBc3NlZ25hemlvbmUgcGVyIHR1dHRpIGdsaSBJbnB1dCBkaSBkZWZhdWx0XHJcbiAgICAgICAgdGhpcy5Db2x1bW5zUmVzaXphYmxlID0gdGhpcy5JbnB1dE9yRGVmYXVsdCh0aGlzLkNvbHVtbnNSZXNpemFibGUsIHRoaXMuZGVhZnVsdHM/LkNvbHVtbnNSZXNpemFibGUpO1xyXG4gICAgICAgIHRoaXMuQXV0b1VwZGF0ZSA9IHRoaXMuSW5wdXRPckRlZmF1bHQodGhpcy5BdXRvVXBkYXRlLCB0aGlzLmRlYWZ1bHRzPy5BdXRvVXBkYXRlKTtcclxuICAgICAgICB0aGlzLkFsbFNlYXJjaCA9IHRoaXMuSW5wdXRPckRlZmF1bHQodGhpcy5BbGxTZWFyY2gsIHRoaXMuZGVhZnVsdHM/LkFsbFNlYXJjaCwgdHJ1ZSk7XHJcbiAgICAgICAgdGhpcy5FeHBvcnQgPSB0aGlzLklucHV0T3JEZWZhdWx0KHRoaXMuRXhwb3J0LCB0aGlzLmRlYWZ1bHRzPy5FeHBvcnQpO1xyXG4gICAgICAgIHRoaXMuSGlkZVBhZ2luZyA9IHRoaXMuSW5wdXRPckRlZmF1bHQodGhpcy5IaWRlUGFnaW5nLCB0aGlzLmRlYWZ1bHRzPy5IaWRlUGFnaW5nLCBmYWxzZSk7XHJcbiAgICAgICAgdGhpcy5IaWRlUGFnaW5nQ291bnQgPSB0aGlzLklucHV0T3JEZWZhdWx0KHRoaXMuSGlkZVBhZ2luZ0NvdW50LCB0aGlzLmRlYWZ1bHRzPy5IaWRlUGFnaW5nQ291bnQpO1xyXG4gICAgICAgIHRoaXMuSGlkZVBhZ2luZ0J1dHRvbnMgPSB0aGlzLklucHV0T3JEZWZhdWx0KHRoaXMuSGlkZVBhZ2luZ0J1dHRvbnMsIHRoaXMuZGVhZnVsdHM/LkhpZGVQYWdpbmdCdXR0b25zKTtcclxuICAgICAgICB0aGlzLkNvbnRhaW5lckNsYXNzID0gdGhpcy5JbnB1dE9yRGVmYXVsdCh0aGlzLkNvbnRhaW5lckNsYXNzLCB0aGlzLmRlYWZ1bHRzPy5Db250YWluZXJDbGFzcywgJycpO1xyXG4gICAgICAgIHRoaXMuVGFibGVDbGFzcyA9IHRoaXMuSW5wdXRPckRlZmF1bHQodGhpcy5UYWJsZUNsYXNzLCB0aGlzLmRlYWZ1bHRzPy5UYWJsZUNsYXNzLCAndGFibGUgdGFibGUtc3RyaXBlZCB0YWJsZS1ob3ZlciB0YWJsZS1zbScpO1xyXG4gICAgICAgIHRoaXMuU2VsZWN0aW9uID0gdGhpcy5JbnB1dE9yRGVmYXVsdCh0aGlzLlNlbGVjdGlvbiwgdGhpcy5kZWFmdWx0cz8uU2VsZWN0aW9uKTtcclxuICAgICAgICB0aGlzLlNhdmVQcmVmZXJlbmNlcyA9IHRoaXMuSW5wdXRPckRlZmF1bHQodGhpcy5TYXZlUHJlZmVyZW5jZXMsIHRoaXMuZGVhZnVsdHM/LlNhdmVQcmVmZXJlbmNlcyk7XHJcbiAgICAgICAgdGhpcy5QYWdpbmdTdHlsZSA9IHRoaXMuSW5wdXRPckRlZmF1bHQodGhpcy5QYWdpbmdTdHlsZSwgdGhpcy5kZWFmdWx0cz8uUGFnaW5nU3R5bGUsICdib3R0b20nKTtcclxuICAgICAgICB0aGlzLlJvd0dyb3VwaW5nUGFnaW5nU3R5bGUgPSB0aGlzLklucHV0T3JEZWZhdWx0KHRoaXMuUm93R3JvdXBpbmdQYWdpbmdTdHlsZSwgdGhpcy5kZWFmdWx0cz8uUm93R3JvdXBpbmdQYWdpbmdTdHlsZSwgJ2xlZnQnKTtcclxuICAgICAgICB0aGlzLlVzZVNlbGVjdGlvbkNhY2hlID0gdGhpcy5JbnB1dE9yRGVmYXVsdCh0aGlzLlVzZVNlbGVjdGlvbkNhY2hlLCB0aGlzLmRlYWZ1bHRzPy5Vc2VTZWxlY3Rpb25DYWNoZSwgdHJ1ZSk7XHJcbiAgICAgICAgdGhpcy5TaG93SXRlbUdyb3Vwc0NvbHVtbnMgPSB0aGlzLklucHV0T3JEZWZhdWx0KHRoaXMuU2hvd0l0ZW1Hcm91cHNDb2x1bW5zLCB0aGlzLmRlYWZ1bHRzPy5TaG93SXRlbUdyb3Vwc0NvbHVtbnMsIGZhbHNlKTtcclxuICAgICAgICB0aGlzLkFycmF5bW9kZUl0ZW1zUGVyUGFnZSA9IHRoaXMuSW5wdXRPckRlZmF1bHQodGhpcy5BcnJheW1vZGVJdGVtc1BlclBhZ2UsIHRoaXMuZGVhZnVsdHM/LkFycmF5bW9kZUl0ZW1zUGVyUGFnZSwgMTUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBWaWV3IGZpbmFsZSBzdSBjdWkgYmluZGFyc2kgbGF0byBGcm9udGVuZCwgaWwgdGlwbyBwdcOyIGVzc2VyZSBJQXBwU2VhcmNoPGFueT4gKHBlciBsYSAqKnZpZXdNb2RlKiopLCBhbnlbXSAocGVyIGwnKiphcnJheU1vZGUqKikgZSBSZXBvcnREZWZpbml0aW9uIHBlciBsYSAqKnJlcG9ydE1vZGUqKiAqL1xyXG4gICAgcHVibGljIFZpZXc6IGFueSA9IG51bGw7XHJcbiAgICAvKiogTW9kZWxsbyBkYSBjdWkgbCdlcy10YWJsZSBtb3N0cmEgaSBwdWxzYW50aSBkaSBwYWdpbmF6aW9uZSBpbiBiYXNzbyBhIGRlc3RyYSAqL1xyXG4gICAgcHVibGljIGFycmF5UHVsc2FudGk6IGFueTtcclxuICAgIC8qKiBJbmRpY2Egc2UgbCdlcy10YWJsZSBkZXZlIG1vc3RyYXJlIGlsIGNoZWNrIGdsb2JhbGUgbmVsbCdoZWFkZXIgcGVyIGZhcmUgaWwgXCJzZWxlemlvbmEgdHV0dG9cIiAqL1xyXG4gICAgcHVibGljIGdsb2JhbENoZWNrID0gZmFsc2U7XHJcbiAgICAvKiogVGllbmUgZGEgY29udG8gbCd1bHRpbW8gZWxlbWVudG8gc2VsZXppb25hdG8gaW4gbW9kbyBkYSBwb3RlciBlZmZldHR1YXJlIGlsIFNISUZUK0NMSUNLICovXHJcbiAgICBwcml2YXRlIGxhc3RTZWxlY3RlZDogYW55ID0gbnVsbDtcclxuICAgIC8qKiBDb250ZWdnaW8gaW50ZXJubyBwZXIgaWwgbnVtZXJvIGRpIGVsZW1lbnRpIHNlbGV6aW9uYXRpICovXHJcbiAgICBwdWJsaWMgc2VsZWN0ZWRPYmplY3RzID0gMDtcclxuICAgIC8qKiBJbmRpY2Egc2Ugw6ggcG9zc2liaWxlIGVmZmV0dHVhcmUgdW5hIHNlbGV6aW9uZSBtYXNzaXZhICovXHJcbiAgICBwdWJsaWMgY2FuU2VsZWN0QWxsID0gZmFsc2U7XHJcbiAgICAvKiogSW5kaWNhIHNlIGlsIGNvbXBvbmVudGUgc3RhIGdlc3RlbmRvIHVuIElBcHBTZWFyY2g8YW55PiAqL1xyXG4gICAgcHVibGljIHZpZXdNb2RlID0gZmFsc2U7XHJcbiAgICAvKiogSW5kaWNhIHNlIGlsIGNvbXBvbmVudGUgc3RhIGdlc3RlbmRvIHVuIGFueVtdICovXHJcbiAgICBwdWJsaWMgYXJyYXlNb2RlID0gZmFsc2U7XHJcbiAgICAvKiogSW5kaWNhIHNlIGlsIGNvbXBvbmVudGUgc3RhIGdlc3RlbmRvIHVuIFJlcG9ydERlZmluaXRpb24gKi9cclxuICAgIHB1YmxpYyByZXBvcnRNb2RlID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb250ZW5pdG9yZSBkZWdsaSBlbGVtZW50aSBkYSBsaXN0YXJlIGxhdG8gaW50ZXJmYWNjaWEgZG9wbyB0dXR0ZSBsZSBlbGFib3JhemlvbmkgZGVsIGNhc28sXHJcbiAgICAgKiBnZW5lcmFsbWVudGUgbm9uIHNvbm8gYWx0cm8gY2hlIHR1dHRpIGdsaSBvZ2dldHRpIGRhIHByZXNlbnRhcmUgY29uIGluIHBpw7kgbCdoYXNoIGNhbGNvbGF0byBwZXIgaWRlbnRpZmljYXJlIDEgb2dnZXR0byBjb24gbGEgcHJvcHJpYSByaWdhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBib3VuZFNvdXJjZTogYW55W10gPSBbXTtcclxuICAgIC8qKiBTdGVzc2EgY29zYSBkZWxsYSAqKmJvdW5kU291cmNlKiosIHV0aWxpenphdGEgY29tZSBhcHBvZ2dpbyB0ZW1wb3JhbmVvIGludGVybm8gKi9cclxuICAgIHB1YmxpYyBUTVBCb3VuZFNvdXJjZTogYW55W10gPSBbXTtcclxuICAgIC8qKiBcIkZldHRhXCIgZGkgb2dnZXR0aSB1dGlsaXp6YXRhIG5lbGwnZW5kbGVzcyBzY3JvbGwsIG9nbmkgZWxlbWVudG8gZGkgcXVlc3RvIGFycmF5IMOoIHVuIGJsb2NjaGV0dG8gZGkgMTAwIGVsZW1lbnRpICovXHJcbiAgICBwdWJsaWMgYm91bmRTdWJTb3VyY2VzOiBhbnlbXSA9IFtdO1xyXG4gICAgLyoqIFF1ZXN0YSBmdW5nZSBkYSBpbmRpY2F0b3JlIHBlciBnbGkgc2xpY2UgaW5zZXJpdGksIGxhIGx1bmdoZXp6YSBkb3ZyZWJiZSBlc3NlcmUgY29ycmlzcG9uZGVudGUgYSAqKmJvdW5kU3ViU291cmNlcyoqICovXHJcbiAgICBwdWJsaWMgYWRkZWRTbGljZXM6IG51bWJlcltdID0gW107XHJcbiAgICAvKiogVmFyaWFiaWxlIGNoZSBpZGVudGlmaWNhIGlsIHZhbG9yZSBkZWwgXCJzZWxlemlvbmEgVHV0dG9cIiBuZWxsYSBwYWdpbmF6aW9uZSAqL1xyXG4gICAgcHVibGljIGRlZmF1bHRBbGxQYWdlT3ZlcnJpZGUgPSA5OTk5OTk7XHJcbiAgICAvKiogSW5kaWNhIHNlIHV0aWxpenphcmUgaWwgc2lzdGVtYSBkaSBFbmRsZXNzIFNjcm9sbCAqL1xyXG4gICAgcHVibGljIFVzZUVuZGxlc3NzY3JvbGw6IGJvb2xlYW47XHJcbiAgICAvKiogVmFsb3JpIGRlbGwnZXZlbnR1YWxlIHJlcG9ydCBpbiB2aXN1YWxpenphemlvbmUgKi9cclxuICAgIHB1YmxpYyBSZXBvcnRWYWx1ZXM6IFJlcG9ydFJlc3VsdDtcclxuICAgIC8qKiBTZXJ2ZSBwZXIgdGVuZXJlIGluIG1lbW9yaWEgaWwgY29udGVnZ2lvIHByZWNlZGVudGUgZSByZWN1cGVyYXJsbyBpbiBjYXNvIGRpdmVudGkgLTIgKHZlcmlmaWNhcmUgY29uIEFsZSBwZXJjaMOpIGxhIGxvZ2ljYSBkZWwgLTIpICovXHJcbiAgICBwdWJsaWMgcHJldmlvdXNDb3VudDogbnVtYmVyO1xyXG4gICAgLyoqIEluZGljYSBzZSB1dGlsaXp6YXJlIGlsIHNpc3RlbWEgZGkgYXV0b3VwZGF0ZSwgY2lvw6ggdW4gdHJpZ2dlciB0aW1lLWl6emF0byBpbiBhbHRvIGEgZGVzdHJhIGRlbGxhIHRhYmVsbGEgY2hlIHJpcGV0ZSBsZSByaWNlcmNoZSBvZ25pIFggKipzZWNvbmRzKiogKi9cclxuICAgIHB1YmxpYyBhdXRvVXBkYXRlID0gZmFsc2U7XHJcbiAgICAvKiogTnVtZXJvIGRpIHNlY29uZGkgZGEgZmFyZSB0cmFzY29ycmVyZSBmcmEgdW5hIHJpY2VyY2EgZSBsJ2FsdHJhICovXHJcbiAgICBwdWJsaWMgc2Vjb25kcyA9ICcxMCc7XHJcbiAgICAvKiogUmlmZXJpbWVudG8gYWxsJ0ludGVydmFsIGNoZSB2aWVuZSBnZW5lcmF0byBzZSAqKmF1dG9VcGRhdGUqKiDDqCBpbXBvc3RhdGEgYSB0cnVlIGluIG1vZG8gZGEgcG90ZXJsbyByaXB1bGlyZSAqL1xyXG4gICAgcHVibGljIHVwZGF0ZVRpbWVyOiBhbnk7XHJcbiAgICAvKiogSW1wb3N0YXRhIGEgdHJ1ZSBvZ25pIHZvbHRhIGNoZSB2aWVuZSBhdnZpYXRhIHVuYSByaWNlcmNhLCBlIGEgZmFsc2Ugb2duaSB2b2x0YSBjaGUgdW4gbnVvdm8gdmFsb3JlIHZpZW5lIHJpY2V2dXRvICovXHJcbiAgICBwdWJsaWMgcmVzZWFyY2hJblByb2dyZXNzOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICAvKiogTW9kZWxsbyByYXBwcmVzZW50YW50ZSB1biBzaW5nb2xvIHRkIGRlbGxhIHRhYmVsbGEsIGdlbmVyYXRvIGluIGJhc2UgYWxsZSBjb25maWd1cmF6aW9uaSBlIGFnbGkgb2dnZXR0aSByaWNldnV0aSAqL1xyXG4gICAgcHVibGljIFJvd1REczogeyBbY29udGV4dDogc3RyaW5nXTogRXNUZFtdIH0gPSBudWxsO1xyXG4gICAgLyoqIE1vZGVsbG8gZGkgYXBwb2dnaW8gdGVtcG9yYW5lbyBwZXIgaSAqKlJvd1REcyoqICovXHJcbiAgICBwdWJsaWMgVE1QUm93VERzOiB7IFtjb250ZXh0OiBzdHJpbmddOiBFc1RkW10gfSA9IG51bGw7XHJcbiAgICAvKiogTW9kZWxsbyByYXBwcmVzZW50YW50ZSB1biBzaW5nb2xvIHRoIGRlbGxhIHRhYmVsbGEsIGdlbmVyYXRvIGluIGJhc2UgYWxsZSBjb25maWd1cmF6aW9uaSBlIGFnbGkgb2dnZXR0aSByaWNldnV0aSAqL1xyXG4gICAgcHVibGljIFJvd1RIczogeyBQaW5uZWQ6IGJvb2xlYW4sIEZpeGVkOiBib29sZWFuLCBJRDogc3RyaW5nLCBWaXNpYmxlOiBib29sZWFuLCBDbGFzczogc3RyaW5nLCBDb250ZW50OiBzdHJpbmcsIE9yZGVyOiBzdHJpbmcsIE9yZGVyYWJsZTogYm9vbGVhbiwgVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4sIFdyYXA6IGJvb2xlYW4gfVtdID0gbnVsbDtcclxuICAgIC8qKiBNb2RlbGxvIGRpIGFwcG9nZ2lvIHRlbXBvcmFuZW8gcGVyIGkgKipSb3dUSHMqKiAqL1xyXG4gICAgcHVibGljIFRNUFJvd1RIczogeyBQaW5uZWQ6IGJvb2xlYW4sIEZpeGVkOiBib29sZWFuLCBJRDogc3RyaW5nLCBWaXNpYmxlOiBib29sZWFuLCBDbGFzczogc3RyaW5nLCBDb250ZW50OiBzdHJpbmcsIE9yZGVyOiBzdHJpbmcsIE9yZGVyYWJsZTogYm9vbGVhbiwgVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4sIFdyYXA6IGJvb2xlYW4gfVtdID0gbnVsbDtcclxuICAgIC8qKiBNb2RlbGxvIGRpIGFwcG9nZ2lvIHRlbXBvcmFuZW8gcGVyIGkgKipSb3dUaEdyb3VwcyoqICovXHJcbiAgICBwdWJsaWMgVE1QUm93VGhHcm91cHM6IHsgU3BhbjogbnVtYmVyLCBUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB9W11bXSA9IG51bGw7XHJcbiAgICAvKiogTW9kZWxsbyByYXBwcmVzZW50YW50ZSB1biBzaW5nb2xvIGhlYWRlciBncm91cCBkZWxsYSB0YWJlbGxhLiBRdWVzdGEgbGlzdGEgw6ggZ2nDoCBvcmRpbmF0YSBlIHByb250YSBwZXIgZXNzZXJlIHV0aWxpenphdGEgaW4gbmdGb3IgKi9cclxuICAgIHB1YmxpYyBSb3dUaEdyb3VwczogeyBTcGFuOiBudW1iZXIsIFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IH1bXVtdID0gbnVsbDtcclxuICAgIC8qKiBDYWNoZSBwZXIgaSByb3V0ZXJMaW5rIGdlbmVyYXRpIG5lbGxlIHRhYmVsbGUgZGluYW1pY2hlICovXHJcbiAgICBwdWJsaWMgRHluYW1pY1RhYmxlUm91dGVyTGlua0NhY2hlOiB7fSA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTGlzdGEgZGVpIGNvbnRlc3RpLiBVbiBjb250ZXN0byBub24gw6ggYWx0cm8gY2hlIHVuIGhhc2ggcGFydGljb2xhcmUgY2FsY29sYXRvIHN1IHVuIG9nZ2V0dG8gY2hlIGlkZW50aWZpY2EgdW5pdm9jYW1lbnRlIHRhbGUgb2dnZXR0by5cclxuICAgICAqXHJcbiAgICAgKiBPZ251bm8gZGkgcXVlc3RpIGNvbnRlc3RpIHJhcHByZXNlbnRlcsOgIGEgc3VhIHZvbHRhLCB1bml2b2NhbWVudGUsIHVuYSByaWdhIGFsbCdpbnRlcm5vIGRlbGxhIHRhYmVsbGFcclxuICAgICAqL1xyXG4gICAgcHVibGljIFJvd0NvbnRleHRzOiBhbnlbXSA9IFtdO1xyXG4gICAgLyoqIERpcmV0dGl2ZSBkaSBvcmRpbmFtZW50byBkZWxsZSBjb2xvbm5lIChub24gb3JkaW5hbWVudG8gZGVpIGRhdGkgbWEgZGVsbGUgY29sb25uZSBpbiBzZSkgKi9cclxuICAgIHB1YmxpYyBPcmRlckRpcmVjdGl2ZXM6IHN0cmluZ1tdID0gW107XHJcbiAgICAvKiogQ29kaWNlIGRlbGwndWx0aW1vIG9nZ2V0dG8gc29sZXppb25hdG8gKi9cclxuICAgIHB1YmxpYyBsYXN0U2VsZWN0ZWRJdGVtSUQgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhIHNlIG9sdHJlIGFsbGUgY29sb25uZSBkaW5hbWljaGUgc3BlY2lmaWNoZSBkaSB1biB0aXBvIGRpIG9nZ2V0dG8gY2kgc29ubyBhbmNoZSBjb2xvbm5lIGRpbmFtaWNoZSBhZ2dpdW50ZSBkYWxsJ3V0ZW50ZVxyXG4gICAgICpcclxuICAgICAqIEVzLiB1bmEgY29sb25uYSBpbiBjdWkgbW9zdHJhcmUgc2VtcHJlIHVuIGljb25jaW5hXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBVc2VyRGVmaW5lZER5bmFtaWNDb2xzOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICAvKiogSW5kaWNhIGNoZSBxdWVzdG8gw6ggaWwgcHJpbW8gQmluZCBkZWxsYSB0YWJlbGxhLCB2aWVuZSBzZXR0YXRvIGEgZmFsc2Ugbm9uIGFwcGVuYSBpbCBwcmltbyBiaW5kIHZpZW5lIHRlcm1pbmF0byBjb24gc3VjY2Vzc28gKi9cclxuICAgIHB1YmxpYyBGaXJzdEJpbmQ6IGJvb2xlYW4gPSB0cnVlO1xyXG4gICAgLyoqIExpc3RhIGRpIGNvbG9ubmUgY2hlIHNpIHBvc3Nvbm8gdmlzdWFsaXp6YXJlL29yZGluYXJlIGZyYSBkaSBsb3JvICovXHJcbiAgICBwdWJsaWMgQ29sdW1uc0xpc3Q6IEVzVGFibGVDb2x1bW5bXSA9IFtdO1xyXG4gICAgLyoqIFZhcmlhYmlsZSBkJ2FwcG9nZ2lvIHVzYXRhIGRhbGxhIGRpYWxvZyBkaSBzZWxlemlvbmUvbmFzY29uZGltZW50bywgcGVyIGV2aXRhcmUgZGkgZGFubmVnZ2lhcmUgKipDb2x1bW5zTGlzdCoqIGluIGNhc28gZGkgbW9kaWZpY2hlIHBvaSBhbm51bGxhdGUgKi9cclxuICAgIHB1YmxpYyBUTVBDb2x1bW5zTGlzdDogRXNUYWJsZUNvbHVtbltdID0gW107XHJcbiAgICAvKiogVmFsb3JlIGRlbCBjaGVjayBnbG9iYWxlIGRpIHZpc2liaWxpdMOgIHZhbGlkbyBwZXIgdHV0dGUgbGUgY29sb25uZSBpbiAqKkNvbHVtbnNMaXN0KiogKi9cclxuICAgIHB1YmxpYyBnbG9iYWxDb2xWaXNDaGVjayA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiBRdWVyeSBwZXIgcmVjdXBlcmFyZSB0dXR0ZSBsZSBudW92ZSBkaXJldHRpdmUgIGFzc2VnbmF0aSBhIGRpcmV0dGl2YSAoUGVyIGxhIG1vZGFsaXTDoCBkaW5hbWljYSBkZWxsJ2VzLXRhYmxlKSAqL1xyXG4gICAgQENvbnRlbnRDaGlsZHJlbihFc1RkRGlyZWN0aXZlKSBFc1Rkc0RpcmVjdGl2ZTogUXVlcnlMaXN0PEVzVGREaXJlY3RpdmU+O1xyXG4gICAgLyoqIFF1ZXJ5IHBlciByZWN1cGVyYXJlIHR1dHRpIGdsaSBlcy10ZCBhc3NlZ25hdGkgYSBkaXJldHRpdmEgKFBlciBsYSBtb2RhbGl0w6AgZGluYW1pY2EgZGVsbCdlcy10YWJsZSkgKi9cclxuICAgIEBDb250ZW50Q2hpbGRyZW4oRXNUaERpcmVjdGl2ZSkgRXNUaHNEaXJlY3RpdmU6IFF1ZXJ5TGlzdDxFc1RoRGlyZWN0aXZlPjtcclxuICAgIC8qKiBAZGVwcmVjYXRlZCBRdWVyeSBwZXIgcmVjdXBlcmFyZSB0dXR0aSBnbGkgZXMtdGggKi9cclxuICAgIEBDb250ZW50Q2hpbGRyZW4oZm9yd2FyZFJlZigoKSA9PiBFc1RoKSkgcHJpdmF0ZSBFc1RoczogUXVlcnlMaXN0PEVzVGg+O1xyXG4gICAgLyoqIEBkZXByZWNhdGVkIFF1ZXJ5IHBlciByZWN1cGVyYXJlIHR1dHRpIGdsaSBlcy10ZCAqL1xyXG4gICAgQENvbnRlbnRDaGlsZHJlbihmb3J3YXJkUmVmKCgpID0+IEVzVGQpKSBwcml2YXRlIEVzVGRzOiBRdWVyeUxpc3Q8RXNUZD47XHJcbiAgICAvKiogQGRlcHJlY2F0ZWQgUXVlcnkgcGVyIHJlY3VwZXJhcmUgbGUgaW5mb3JtYXppb25pIGRlbCBib2R5IChwdW50byBkZWxsYSB0YWJlbGxhIGRvdmUgdmVuZ29ubyBtb3N0cmF0ZSBsZSByaWdoZSkgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoJ2JvZHknLCB7IHN0YXRpYzogZmFsc2UgfSkgcHVibGljIGJvZHlSZWY6IGFueTtcclxuICAgIC8qKiBAZGVwcmVjYXRlZCBRdWVyeSBwZXIgcmVjdXBlcmFyZSBsZSBpbmZvcm1hemlvbmkgZGVsbCdoZWFkZXIgKHB1bnRvIGRlbGxhIHRhYmVsbGEgZG92ZSB2ZW5nb25vIG1vc3RyYXRlIGxlIGludGVzdGF6aW9uaSBkZWxsZSByaWdoZSkgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoJ2hlYWRlcicsIHsgc3RhdGljOiBmYWxzZSB9KSBwdWJsaWMgaGVhZGVyUmVmOiBhbnk7XHJcbiAgICAvKiogUXVlcnkgcGVyIHJlY3VwZXJhcmUgbGUgaW5mb3JtYXppb25pIHN1bCByYWdncnVwcGFtZW50byBkZWdsaSBoZWFkZXIgKi9cclxuICAgIEBDb250ZW50Q2hpbGQoJ2hlYWRlckdyb3VwJywgeyBzdGF0aWM6IGZhbHNlIH0pIHB1YmxpYyBoZWFkZXJHcm91cFJlZjogYW55O1xyXG4gICAgLyoqIFF1ZXJ5IHBlciByZWN1cGVyYXJlIGxlIGluZm9ybWF6aW9uaSBzdWwgcmFnZ3J1cHBhbWVudG8gZGkgc2Vjb25kbyBsaXZlbGxvIGRlZ2xpIGhlYWRlciAqL1xyXG4gICAgQENvbnRlbnRDaGlsZCgnc2Vjb25kYXJ5SGVhZGVyR3JvdXAnLCB7IHN0YXRpYzogZmFsc2UgfSkgcHVibGljIHNlY29uZGFyeUhlYWRlckdyb3VwUmVmOiBhbnk7XHJcbiAgICAvKiogT3B6aW9uaSBleHRyYSBjaGUgZGV2b25vIGFwcGFyaXJlIG5lbCBNZW7DuSBjb250ZXN0dWFsZSBpbiBhbHRvIGEgZGVzdHJhLCByaWNoaWFtYXRvIGRhaSAzIHBhbGxpbmkgdmVydGljYWxpICovXHJcbiAgICBASW5wdXQoKSBDb3JuZXJNZW51T3B0aW9uczogQ29ybmVyTWVudU9wdGlvbltdID0gbnVsbDtcclxuICAgIC8qKiBJbmRpY2Egc2UgZGV2J2Vzc2VyZSBwb3NzaWJpbGUgZWZmZXR0dWFyZSBpbCByZXNpemUgZGVsbGUgY29sb25uZSAqL1xyXG4gICAgQElucHV0KCkgQ29sdW1uc1Jlc2l6YWJsZTogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogSW5kaWNhIHNlIGRldidlc3NlcmUgZGlzcG9uaWJpbGUgaWwgc2lzdGVtYSBkaSBhZ2dpb3JuYW1lbnRvIGF1dG9tYXRpY28gKi9cclxuICAgIEBJbnB1dCgpIEF1dG9VcGRhdGU6IGJvb2xlYW4gPSBudWxsO1xyXG5cclxuICAgIC8qKiBJbmRpY2Egc2UgbGEgdGFiZWxsYSAoY29uZmlndXJhdGEgY29uICoqVXNlQ3VzdG9tQ2VsbHMqKikgZGV2ZSBtZXR0ZXJzaSBpbiBhc2NvbHRvIHBlciBpIGNsaWNrIHN1bGxlIGNlbGxlIGRlc2lkZXJhdGVcclxuICAgICAqIFxyXG4gICAgICogQGRlcHJlY2F0ZWQgVXRpbGl6emFyZSBsJ0lucHV0ICoqVGVtcGxhdGUqKiBkZWxsZSBlcy10ZCBlIGFzc2VnbmFyZSB1biB0ZW1wbGF0ZSBjb24gdHV0dGkgaSBiaW5kaW5nIGNoZSBzaSB2dW9sZSBhaSBjbGlja1xyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSBVc2VDdXN0b21DZWxsQWN0aW9uczogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbmRpY2EgbGUgY2VsbGUgZGVzaWRlcmF0ZSBzdSBjdWkgaW50ZXJjZXR0YXJlIGkgY2xpY2suIEF0dGl2YSBzb2xvIHF1YW5kbyAqKlVzZUN1c3RvbUNlbGxBY3Rpb25zKiogw6ggdHJ1ZS5cclxuICAgICAqIE9nbmkgY2VsbGEgZGV2J2Vzc2VyZSBzZXBhcmF0YSBkYWxsYSBzdWNjZXNzaXZhIGRhbCBjYXJhdHRlcmUgZGVsIFNpbW9sZW9uOlxyXG4gICAgICpcclxuICAgICAqIEVzLCBcIk1pYUNlbGxhMcKnTWlhQ2VsbGEyXCJcclxuICAgICAqIFxyXG4gICAgICogQGRlcHJlY2F0ZWQgVXRpbGl6emFyZSBsJ0lucHV0ICoqVGVtcGxhdGUqKiBkZWxsZSBlcy10ZCBlIGFzc2VnbmFyZSB1biB0ZW1wbGF0ZSBjb24gdHV0dGkgaSBiaW5kaW5nIGNoZSBzaSB2dW9sZSBhaSBjbGlja1xyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSBDdXN0b21DZWxsQWN0aW9uc09uID0gJyc7XHJcblxyXG4gICAgLyoqIFxyXG4gICAgICogU2VydmUgcGVyIGRlY2lkZXJlIGRpIGxhbmNpYXJlIG8gbWVubyBpbCAqKmV2ZW50LnN0b3BQcm9wYWdhdGlvbigpKiogYWwgdGVybWluZSBkZWxsYSBnZXN0aW9uZSBkZWxsJ2V2ZW50byBcclxuICAgICAqIFxyXG4gICAgICogQGRlcHJlY2F0ZWQgVXRpbGl6emFyZSBsJ0lucHV0ICoqVGVtcGxhdGUqKiBkZWxsZSBlcy10ZCBlIGFzc2VnbmFyZSB1biB0ZW1wbGF0ZSBjb24gdHV0dGkgaSBiaW5kaW5nIGNoZSBzaSB2dW9sZSBhaSBjbGlja1xyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSBDZWxsQWN0aW9uUHJvcGFnYXRlcyA9IHRydWU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNpZGUgc2UgdXRpbGl6emFyZSBvIG1lbm8gbGUgQ3VzdG9tQ2VsbHMuIEltcG9zdGFuZG9sbyBhICoqdHJ1ZSoqIGwnZXMtdGFibGUgZGl2ZW50YSBpbiBncmFkbyBkaSBnZXN0aXJlIG5hdGl2YW1lbnRlOlxyXG4gICAgICpcclxuICAgICAqIDEpIE9yZGluYW1lbnRvIGUgdmlzaWJpbGl0w6AgZGVsbGUgY29sb25uZVxyXG4gICAgICpcclxuICAgICAqIDIpIE9yZGluYW1lbnRvIGRlaSBkYXRpXHJcbiAgICAgKlxyXG4gICAgICogMykgTW9kYWxpdMOgIEdlcmFyY2hpY2FcclxuICAgICAqXHJcbiAgICAgKiBlY2MuLi5cclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgVXNlQ3VzdG9tQ2VsbHM6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIFBlcm1ldHRlIGRpIGltcG9zdGFyZSBsJ2FsdGV6emEgbWFzc2ltYSBkZWxsYSB0YWJlbGxhLiBTZSBudWxsIGxhIGRpbWVuc2lvbmUgc2kgYWRhdHRhIGFsIG51bWVybyBkaSBlbGVtZW50aSBhdHR1YWxtZW50ZSBpbiB2aXN1YWxpenphemlvbmUgKi9cclxuICAgIEBJbnB1dCgpIE1heEhlaWdodDogbnVtYmVyID0gbnVsbDtcclxuICAgIC8qKiBDbGFzc2kgZGEgYXBwbGljYXJlIGFsIGNvbnRlbml0b3JlIGRlbGxhIHRhYmVsbGEgKi9cclxuICAgIEBJbnB1dCgpIENvbnRhaW5lckNsYXNzID0gbnVsbDtcclxuICAgIC8qKiBQZXJtZXR0ZSBvIG1lbm8gbCdleHBvcnQgaW4gZm9ybWF0byBYTFNYICovXHJcbiAgICBASW5wdXQoKSBYTFNYRXhwb3J0OiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBQZXJtZXR0ZSBvIG1lbm8gbCdleHBvcnQgaW4gZm9ybWF0byBDU1YgKi9cclxuICAgIEBJbnB1dCgpIENTVkV4cG9ydCA9IHRydWU7XHJcbiAgICAvKiogUGVybWV0dGUgZGkgdmlzdWFsaXp6YXJlIG8gbWVubyBsJ29wemlvbmUgZGkgcGFnaW5hemlvbmUgXCJUdXR0aVwiICovXHJcbiAgICBASW5wdXQoKSBBbGxTZWFyY2ggPSBudWxsO1xyXG4gICAgLyoqIERpbWludWlzY2UgZ2xpIHNwYXppIGZyYSB1bmEgY2VsbGEgZSBsJ2FsdHJhLCBlIGludGVybmFtZW50ZSBpbCBwYWRkaW5nIGRlbCBmb250IGluIG1vZG8gZGEgcHJlc2VudGFyZSBtb2x0aSBwacO5IGRhdGkgaW4gdW4ndW5pY2EgcGFnaW5hICovXHJcbiAgICBASW5wdXQoKSBIaWdoQ2VsbERlbnNpdHk6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIEFiaWxpdGEgbyBtZW5vIGxhIHBvc3NpYmlsaXTDoCBkaSBzZWxlemlvbmFyZSBvZ2dldHRpICovXHJcbiAgICBASW5wdXQoKSBTZWxlY3Rpb246IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIE1vc3RyYSBvIG1lbm8gdW4gbWVzc2FnZ2lvIGRpIExvYWRpbmcgYWwgcHJpbW8gY2FyaWNhbWVudG8gZGVsbGEgdGFiZWxsYSAqL1xyXG4gICAgQElucHV0KCkgU2hvd0xvYWRpbmdPbkJvb3RzdHJhcDogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogU2UgaW1wb3N0YXRvIGEgKip0cnVlKiogYWdnaXVuZ2UgdW5hIGNvbG9ubmEgY29uIHB1bHNhbnRlIGRpIGVsaW1pbmF6aW9uZSBwZXIgZWZmZXR0dWFyZSBsJ2VsaW1pbmEgZGVsbCdvZ2dldHRvIHJlbGF0aXZvICovXHJcbiAgICBASW5wdXQoKSBSZW1vdmFsOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbmRpemlvbmUgY2hlIG5hc2NvbmRlIGwnaWNvbmEgZGkgZWxpbWluYXppb25lIGluc2VyaXRhIGltcG9zdGFuZG8gKipSZW1vdmFsKiogYSB0cnVlIHF1YWxvcmEgbGEgY29uZGl6aW9uZSBub24gdmVuaXNzZSByaXNwZXR0YXRhXHJcbiAgICAgKlxyXG4gICAgICogQ29tZSBjb25kaXppb25lIHNpIGNvbnNpZGVyYSB1biBzZW1wbGljZSBjYW1wbyBzdSBjdWkgZWZmZXR0dWFyZSB1biBjb250cm9sbG8gYm9vbGVhbm8sIGNvbWUgYWQgZXNlbXBpbyBcImNhbnJlbW92ZVwiXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIFJlbW92YWxDb25kaXRpb24gPSAnJztcclxuICAgIC8qKiBJbmRpY2Egc2UgYWJpbGl0YXJlIGxhIHBvc3NpYmlsaXTDoCBkaSBlc3BvcnRhcmUgbGEgdmlzdGEgZGF0aSBhdHR1YWxlICovXHJcbiAgICBASW5wdXQoKSBFeHBvcnQ6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIEluZGljYSBzZSBwZXJtZXR0ZXJlIGxhIHNlbGV6aW9uZSBtdWx0aXBsYSBXaW5kb3dzLWxpa2UgY2xpY2NhbmRvIHVuIG9nZ2V0dG8gZSBmYWNlbmRvIHBvaSBTaGlmdCArIGNsaWNrIHN1IHVuIG9nZ2V0dG8gc3VjY2Vzc2l2byAqL1xyXG4gICAgQElucHV0KCkgU2hpZnRDbGljazogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogSW5kaWNhIHNlIG5hc2NvbmRlcmUgbyBtb3N0cmFyZSBpbCBjb21wb25lbnRlIGRpIHBhZ2luYXppb25lICovXHJcbiAgICBASW5wdXQoKSBIaWRlUGFnaW5nOiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBJbmRpY2Egc2UgbmFzY29uZGVyZSBvIG1vc3RyYXJlIGlsIGNvbnRlZ2dpbyBkZWdsaSBlbGVtZW50aSB0cm92YXRpICovXHJcbiAgICBASW5wdXQoKSBIaWRlUGFnaW5nQ291bnQ6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIEluZGljYSBzZSBuYXNjb25kZXJlIG8gbW9zdHJhcmUgaSBwdWxzYW50aSBkaSBwYWdpbmF6aW9uZSAqL1xyXG4gICAgQElucHV0KCkgSGlkZVBhZ2luZ0J1dHRvbnM6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIFJpZmVyaW1lbnRvIGFsIENvbnRleHRNZW51IChuZ3gtY29udGV4dG1lbnUpIGFzc29jaWF0byBhbCBjbGljayBkZXN0cm8gZGkgdW5vIG8gcGnDuSBlbGVtZW50aSBzZWxlemlvbmF0aSBuZWxsYSB0YWJlbGxhICovXHJcbiAgICBASW5wdXQoKSBDb250ZXh0TWVudTogQ29udGV4dE1lbnVDb21wb25lbnQgPSBudWxsO1xyXG4gICAgLyoqIE5vbWUgZGVsbCdlc3BvcnRhemlvbmUgZ2VuZXJhdGEgZGEgcXVlc3RhIHRhYmVsbGEgKi9cclxuICAgIEBJbnB1dCgpIEV4cG9ydEZpbGVOYW1lID0gJ0V4cG9ydC5jc3YnO1xyXG4gICAgLyoqIENsYXNzZSAoSFRNTCkgZGkgZGVmYXVsdCBkZWxsYSB0YWJlbGxhICovXHJcbiAgICBASW5wdXQoKSBUYWJsZUNsYXNzID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZ1bnppb25lIGRhIHV0aWxpenphcmUgaW4gZXNwb3J0YXppb25lLiBOZWwgZm9ybWF0byBcIlJlcG9ydFwiIGF2csOgIHVuIHVuaWNvIHBhcmFtZXRybyBcIkZvcm1hdG9cIiBlIG5lc3N1biB2YWxvcmUgZGkgcml0b3Juby5cclxuICAgICAqXHJcbiAgICAgKiBOZWwgZm9ybWF0byBcIlZpZXdcIiBoYSBjb21lIHBhcmFtZXRybyB1bmEgY2FsbGJhY2sgY29uIGkgZGF0aSBjb21wbGV0aSBkYSBlc3BvcnRhcmUgKGRhdG8gY2hlIGRpIGRlZmF1bHQgbGEgcmljZXJjYSDDqCBwYWdpbmF0YSlcclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgRXhwb3J0RnVuY3Rpb246IGFueTtcclxuICAgIC8qKiBAZGVwcmVjYXRlZCBJbmRpY2EgbGEgcHJlc2VuemEgZGkgcmFnZ3J1cHBhbWVudGkgYSBsaXZlbGxvIGRpIGhlYWRlciAqL1xyXG4gICAgQElucHV0KCkgSGFzSGVhZGVyR3JvdXA6IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIEBkZXByZWNhdGVkIEluZGljYSBsYSBwcmVzZW56YSBkaSByYWdncnVwcGFtZW50aSBhIGxpdmVsbG8gZGVsIHJhZ2dydXBwYW1lbnRvIHByZWNlZGVudGVtZW50ZSBlc2lzdGVudGUsIGNoaWFyYW1lbnRlIMOoIGluc2Vuc2F0YSBzZW56YSAqKkhhc0hlYWRlckdyb3VwKiogKi9cclxuICAgIEBJbnB1dCgpIEhhc1NlY29uZGFyeUhlYWRlckdyb3VwOiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBVdGlsaXp6YXRvIHBlciBkaXZpZGVyZSBsYSBzb3JnZW50ZSBpbiBtb2RhbGl0w6AgRW5kbGVzc1Njcm9sbCAqL1xyXG4gICAgQElucHV0KCkgU2xpY2VTaXplID0gMTAwO1xyXG4gICAgLyoqIERlY2lkZSBzZSB1dGlsaXp6YXJlIGxhIG1vZGFsaXTDoCBkaSBFbmRsZXNzU2Nyb2xsICovXHJcbiAgICBASW5wdXQoKSBFbmRsZXNzU2Nyb2xsOiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBRdWFsb3JhICoqRW5kbGVzc1Njcm9sbCoqIGZvc3NlIHRydWUsIGluZGljYSBzZSB1dGlsaXp6YXJlIHF1ZXN0YSBtb2RhbGl0w6Agc29sbyBxdWFuZG8gc2kgY2VyY2EgcGVyIFwiVHV0dGlcIiBvIGluIGdlbmVyYWxlICovXHJcbiAgICBASW5wdXQoKSBFbmRsZXNzU2Nyb2xsT25seUZvckFsbCA9IHRydWU7XHJcbiAgICAvKiogSW5kaWNhIHNlIG5hc2NvbmRlcmUgZ2xpIEhlYWRlciBkZWxsYSB0YWJlbGxhICovXHJcbiAgICBASW5wdXQoKSBIZWFkZXJIaWRkZW46IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIEluZGljYSBzZSBuYXNjb25kZXJlIGlsIEJvZHkgZGVsbGEgdGFiZWxsYSAqL1xyXG4gICAgQElucHV0KCkgQm9keUhpZGRlbjogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbmRpY2Egc2UgbGEgc2VsZXppb25lIMOoIHRlbXBvcmFuZWFtZW50ZSBkaXNhYmlsaXRhdGEuIFJpc3BldHRvIGFsbCdJbnB1dCAqKlNlbGVjdGlvbioqIGNoZSB2aXNpdmFtZW50ZSBnZXN0aXNjZSBzZSBjaSBzb25vIG8gbm8gZ2xpIGlucHV0IGRpIHNlbGV6aW9uZSxcclxuICAgICAqIHF1ZXN0byBJbnB1dCBnZXN0aXNjZSBzZSBxdWVzdGkgaW5wdXQgc29ubyBhYmlsaXRhdGkgbyBtZW5vXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIFNlbGVjdGlvbkRpc2FibGVkOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZGljYSBzZSBmb3J6YXJlIGlsIHNpc3RlbWEgZGkgc2VsZXppb25lIGEgZ2VzdGlyZSB1biBlbGVtZW50byBwZXIgdm9sdGEuXHJcbiAgICAgKiBTZWxlemlvbmFyZSB1bidhbHRyYSByaWdhIGNvbiB1bmEgZ2nDoCBzZWxlemlvbmF0YSBhcHBsaWNoZXLDoCBsYSBzZWxlemlvbmUgYWxsYSBudW92YSByaWdhLCByaW11b3ZlbmRvbGEgZGFsbCdhdHR1YWxlXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIFNpbmdsZVNlbGVjdGlvbjogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogQ2FsbGJhY2sgY2hlIGRhdG8gdW4gb2dnZXR0byByZXNpdHVpc2NlIGwnZXZlbnR1YWxlIGNsYXNzZSBkYSBhcHBsaWNhcmUgYWxsYSByaWdhIGNvbGxlZ2F0YSBhbGwnb2dnZXR0byAqL1xyXG4gICAgQElucHV0KCkgUm93Q2xhc3NBc3NpZ25lcjogYW55ID0gbnVsbDtcclxuICAgIC8qKiBQZXJtZXR0ZSBkaSBvcmRpbmFyZSBpIGRhdGkgaW4gbWFuaWVyYSBkaXNjZW5kZW50ZSBvIGFzY2VuZGVudGUgKi9cclxuICAgIEBJbnB1dCgpIE9yZGVyQnlDb2x1bW46IGJvb2xlYW4gPSBudWxsO1xyXG4gICAgLyoqIFBlcm1ldHRlIGRpIGF2ZXJlIHBpw7kgZGlyZXR0aXZlIGRpIG9yZGluYW1lbnRvIGRlaSBkYXRpICovXHJcbiAgICBASW5wdXQoKSBNdWx0aXBsZU9yZGVyaW5nRGlyZWN0aXZlcyA9IHRydWU7XHJcbiAgICAvKiogUGVybWV0dGUgZGkgbmFzY29uZGVyZSBsZSBjb2xvbm5lIGluIGJhc2UgYWxsZSBzZWxlemlvbmkgZWZmZXR0dWF0ZSBkYWwgTWVuw7kgY29udGVzdHVhbGUgaW4gYWx0byBhIGRlc3RyYSAqL1xyXG4gICAgQElucHV0KCkgSGlkZGVuQ29sdW1uczogYm9vbGVhbiA9IG51bGw7XHJcbiAgICAvKiogUGVybWV0dGUgZGkgcmlvcmRpbmFyZSBsZSBjb2xvbm5lIGluIGJhc2UgYWxsZSBpbXBvc3RhemlvbmkgZWZmZXR0dWF0ZSBkYWwgTWVuw7kgY29udGVzdHVhbGUgaW4gYWx0byBhIGRlc3RyYSAqL1xyXG4gICAgQElucHV0KCkgQ29sdW1uc09yZGVyaW5nOiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBFdmVudHVhbGUgc3VwcG9ydG8gYWxsZSByaWNlcmNoZSBhcHBsaWNhdGUgYWxsYSBtb2RhbGl0w6AgQXJyYXkgKi9cclxuICAgIEBJbnB1dCgpIFNlYXJjaFZpZXcgPSBudWxsIGFzIEFwcFNlYXJjaDxhbnk+O1xyXG4gICAgLyoqIEFiaWxpdGEgbyBkaXNhYmlsaXRhIGlsIHNpc3RlbWEgY2hlIHBlcm1ldHRlIGRpIHNlbGV6aW9uYXJlIHR1dHRpIGdsaSBlbGVtZW50aSBuZWxsYSB2aXN0YSAqL1xyXG4gICAgQElucHV0KCkgU2VsZWN0QWxsOiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBTaW11bGEgbGEgcGFnaW5hemlvbmUgYW5jaGUgcGVyIGxlIHRhYmVsbGUgY2hlIGZ1bnppb25hbm8gaW4gbW9kYWxpdMOgIEFycmF5ICovXHJcbiAgICBASW5wdXQoKSBVc2VBcnJheU1vZGVQYWdpbmcgPSB0cnVlO1xyXG4gICAgLyoqIERlZmluaXppb25lIGRpIGNvbG9ubmUgZGluYW1jaGUgcGVyIGxhIG1vZGFsaXTDoCwgYXBwdW50bywgZGluYW1pY2EgKi9cclxuICAgIEBJbnB1dCgpIER5bmFtaWNSb3dDb2x1bW5zRGVmaW5pdGlvbjogRXNUYWJsZUNvbHVtbnNEZWZpbml0aW9uW10gPSBudWxsO1xyXG4gICAgLyoqIEluZGljYSBvcGVyYXppb25pIGRpbmFtaWNoZSBnZW5lcmljaGUgY2hlIHBvc3Nvbm8gZXNzZXJlIGVmZmV0dHVhdGUgcGVyIHJpZ2EuIEFwcGFpb25vIGNvbWUgY29sb25uZSBleHRyYSBzdWwgbGF0byBzaW5pc3RybyBkZWxsYSB0YWJlbGxhICovXHJcbiAgICBASW5wdXQoKSBEeW5hbWljT3BlcmF0aW9uczogRXNUYWJsZU9wZXJhdGlvbkRlZmluaXRpb25bXSA9IFtdO1xyXG4gICAgLyoqIEluZGljYSBzZSB2aXN1YWxpenphcmUgaSBkYXRpIGluIG1hbmllcmEgZ2VyYXJjaGljYSAqL1xyXG4gICAgQElucHV0KCkgSGllcmFyY2h5OiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBOb21lIGRlbGxhIHByb3ByaWV0w6AgY2hlIGNvbnRpZW5lIGwnSUQgZGVsIHBhZHJlLiBEYSB1dGlsaXp6YXJlIHNlICoqSGllcmFyY2h5Kiogw6ggaW1wb3N0YXRvICovXHJcbiAgICBASW5wdXQoKSBQYXJlbnRLZXkgPSAnJztcclxuICAgIC8qKiBOb21lIGRlbGxhIHByb3ByaWV0w6AgY2hlIGNvbnRpZW5lIGwnSUQgZGVsbCdvZ2dldHRvIGF0dHVhbGUuIERhIHV0aWxpenphcmUgc2UgKipIaWVyYXJjaHkqKiDDqCBpbXBvc3RhdG8gKi9cclxuICAgIEBJbnB1dCgpIE93bktleSA9ICcnO1xyXG4gICAgLyoqIEluZGljYSBzZSBwYXJ0aXJlIGNvbiB1biBhbGJlcm8gZXNwYW5zby4gRGEgdXRpbGl6emFyZSBzZSAqKkhpZXJhcmNoeSoqIMOoIGltcG9zdGF0byAqL1xyXG4gICAgQElucHV0KCkgU3RhcnRzRXhwYW5kZWQgPSB0cnVlO1xyXG4gICAgLyoqIEluZGljYSBzZSBlZmZldHR1YXJlIGlsIHNhbHZhdGFnZ2lvIGRlbGxlIHByZWZlcmVuemUgZGkgcmljZXJjYSAqL1xyXG4gICAgQElucHV0KCkgU2F2ZVByZWZlcmVuY2VzOiBib29sZWFuID0gbnVsbDtcclxuXHJcbiAgICAvKiogSW5kaWNhIGRvdmUgdmlzdWFsaXp6YXJlIGxlIGluZm9ybWF6aW9uaSBkaSBwYWdpbmF6aW9uZSwgc2Ugc29wcmEsIHNvdHRvIG8gaW4gZW50cmFtYmkgKi9cclxuICAgIEBJbnB1dCgpIFBhZ2luZ1N0eWxlOiAnYm90aCcgfCAndG9wJyB8ICdib3R0b20nID0gbnVsbDtcclxuICAgIC8qKiBJbmRpY2EgZG92ZSB2aXN1YWxpenphcmUgbGUgaW5mb3JtYXppb25pIGRpIHBhZ2luYXppb25lLCBzZSBzb3ByYSwgc290dG8gbyBpbiBlbnRyYW1iaSAqL1xyXG4gICAgQElucHV0KCkgUm93R3JvdXBpbmdQYWdpbmdTdHlsZTogJ2xlZnQnIHwgJ3JpZ2h0JyA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTb3JnZW50ZSBkYXRpIHNlY29uZGFyaWFcclxuICAgICAqXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBVdGlsaXp6YXRvIHNvbG8gcGVyIHVuIGNhc28gcGFydGljb2xhcmUgZGVsIE1ldGVyaW5nXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIFNlY29uZGFyeVNvdXJjZTogYm9vbGVhbiA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTb3JnZW50ZSBkYXRpIHNlY29uZGFyaWFcclxuICAgICAqXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBVdGlsaXp6YXRvIHNvbG8gcGVyIHVuIGNhc28gcGFydGljb2xhcmUgZGVsIE1ldGVyaW5nXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIFRlcnRpYXJ5U291cmNlOiBib29sZWFuID0gbnVsbDtcclxuICAgIC8qKiBJbmRpY2Egc2UgdXRpbGl6emFyZSBsYSBjYWNoZSBkaSBzZWxlemlvbmUgY2hlIHBlcm1ldHRlIGRpIG1hbnRlbmVyZSBnbGkgc3RhdGkgZGkgc2VsZXppb25lIGRlaSB2YXJpIG9nZ2V0dGkgbmF2aWdhbmRvIGRhIHVuYSBwYWdpbmEgYWxsJ2FsdHJhICovXHJcbiAgICBASW5wdXQoKSBVc2VTZWxlY3Rpb25DYWNoZSA9IG51bGw7XHJcbiAgICAvKiogUGVybWV0dGUgZGkgZGVjaWRlcmUgc2UsIGluIG1vZGFsaXTDoCByYWdncnVwcGFtZW50bywgbW9zdHJhcmUgbyBtZW5vIGlsIHZhbG9yZSBkZWxsZSBjb2xvbm5lIGRpIGdydXBwbyBuZWdsaSBvZ2dldHRpIGZpbmFsaS4gRGkgZGVmYXVsdCBzb25vIG5hc2Nvc3RpICovXHJcbiAgICBASW5wdXQoKSBTaG93SXRlbUdyb3Vwc0NvbHVtbnMgPSBudWxsO1xyXG4gICAgLyoqIEV2ZW50byBjaGUgdmllbmUgcmljaGlhbWF0byBhbCBjYW1iaW8gZGkgb3JpZG5hbWVudG8gZGkgdW5hIGNvbG9ubmEgKi9cclxuICAgIEBPdXRwdXQoKSBvbk9yZGVyQ2hhbmdlZDogRXZlbnRFbWl0dGVyPEFwcE9yZGVyaW5nPiA9IG5ldyBFdmVudEVtaXR0ZXI8QXBwT3JkZXJpbmc+KCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFdmVudG8gY2hlIHZpZW5lIHJpY2hpYW1hdG8gcXVhbmRvIGwnZXMtdGFibGUgcml0aWVuZSBzaWEgbmVjZXNzYXJpbyByaS1lZmZldHR1YXJlIGxhIHJpY2VyY2EuXHJcbiAgICAgKiBJbCBib29sZWFubyBkZWxsJ2V2ZW50byBpbmRpY2Egc2UgdmllbmUgc3VnZ2VyaXRvIGRpIHJlc2V0dGFyZSBsYSBwYWdpbmEgbyBtZW5vLlxyXG4gICAgICogXHJcbiAgICAgKiBTb2xvIGluIGNhc28gdmVuZ2EgdXRpbGl6emF0YSBsYSBtb2RhbGl0w6AgYSByYWdncnVwcGFtZW50aSBkaSByaWdoZSBwdcOyIHN1Y2NlZGVyZSBjaGUgbCdlcy10YWJsZSBwYXNzaSB1biBpbnRlcm8gQXBwU2VhcmNoIGNvbWUgcGFyYW1ldHJvIGRpIHJpY2VyY2EsXHJcbiAgICAgKiBpbiBxdWVsIGNhc28gbCdhcHBsaWNhemlvbmUgcmljZXZlbnRlIGRvdnLDoCBvbm9yYXJlIGxhIHJpY2hpZXN0YSBzcGVkZW5kbyBhbCBiYWNrYW5kIGwnb2dnZXR0byBkaSByaWNlcmNhIEFTLUlTXHJcbiAgICAgKiBcclxuICAgICAqIGlsIHRpcG8gZGVsbCdFbWl0dGVyIGludmVjZSBkaSBlc3NlcmUgW2Jvb2xlYW4gfCBBcHBTZWFyY2g8YW55Pl0gw6ggc3RhdG8gaW1wb3N0YXRvIGEgXCJhbnlcIiBwZXIgZXZpdGFyZSBwcm9ibGVtaSBkaSByZXRyb2NvbXBhdGliaWxpdMOgXHJcbiAgICAgKi9cclxuICAgIEBPdXRwdXQoKSBvblNlYXJjaFJlcXVlc3Q6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcbiAgICAvKiogRXZlbnRvIGNoZSBwYXJ0ZSBhZCBvZ25pIG1vZGlmaWNhIGRpIFwiY2hlY2thZ2dpb1wiIGluIGZvcm1hIGRpIGNvbW9kbyBhcnJheS4gRXNwb25lIGwnb2dnZXR0byBjb24gbG8gc3RhdG8gZGkgY2hlY2sgYXR0dWFsZSAqL1xyXG4gICAgQE91dHB1dCgpIG9uU2VsZWN0aW9uQ2hhbmdlZDogRXZlbnRFbWl0dGVyPEl0ZW1zU2VsZWN0aW9uPGFueT4+ID0gbmV3IEV2ZW50RW1pdHRlcjxJdGVtc1NlbGVjdGlvbjxhbnk+PigpO1xyXG4gICAgLyoqIEV2ZW50byByaWNoaWFtYXRvIGFsbCdlbGltaW5hemlvbmUgZGkgdW4gb2dnZXR0byAqL1xyXG4gICAgQE91dHB1dCgpIG9uUmVtb3ZhbDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICAgIC8qKiBFdmVudG8gcmljaGlhbWF0byBhbGwnYW5udWxsYW1lbnRvIGRpIHVuJ2VsaW1pbmF6aW9uZSAqL1xyXG4gICAgQE91dHB1dCgpIG9uQWJvcnRSZW1vdmFsOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICAgIC8qKiBFdmVudG8gcmljaGlhbWF0byBhbCBjbGljayBzdSB1bmEgY2VsbGEgcXVhbmRvICoqVXNlQ3VzdG9tQ2VsbEFjdGlvbnMqKiDDqCBhdHRpdm8gXHJcbiAgICAgKiBcclxuICAgICAqIEBkZXByZWNhdGVkIFV0aWxpenphcmUgbCdJbnB1dCAqKlRlbXBsYXRlKiogZGVsbGUgZXMtdGQgZSBhc3NlZ25hcmUgdW4gdGVtcGxhdGUgY29uIHR1dHRpIGkgYmluZGluZyBjaGUgc2kgdnVvbGUgYWkgY2xpY2tcclxuICAgICAqL1xyXG4gICAgQE91dHB1dCgpIG9uQ2VsbENsaWNrOiBFdmVudEVtaXR0ZXI8eyBjb2x1bW46IHN0cmluZywgbW9kZWw6IGFueSB9PiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBjb2x1bW46IHN0cmluZywgbW9kZWw6IGFueSB9PigpO1xyXG4gICAgLyoqIEV2ZW50byByaWNoaWFtYXRvIHF1YW5kbyBzaSBjbGljY2Egc3UgdW4gb3B6aW9uZSBkZWZpbml0YSBuZWxsZSAqKkNvcm5lck1lbnVPcHRpb25zKiogKi9cclxuICAgIEBPdXRwdXQoKSBvbkNvcm5lckFjdGlvbjogRXZlbnRFbWl0dGVyPHsgaWQ6IHN0cmluZywgZXN0YWJsZTogYW55IH0+ID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBzdHJpbmcsIGVzdGFibGU6IGFueSB9PigpO1xyXG4gICAgLyoqIEV2ZW50byByaWNoaWFtYXRvIHF1YW5kbyBzaSBjbGljY2Egc3UgdW4gb3B6aW9uZSBkZWZpbml0YSBuZWxsZSAqKkR5bmFtaWNPcGVyYXRpb25zKiogKi9cclxuICAgIEBPdXRwdXQoKSBvbkR5bmFtaWNPcGVyYXRpb246IEV2ZW50RW1pdHRlcjx7IGlkOiBzdHJpbmcsIGl0ZW06IGFueSB9PiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBpZDogc3RyaW5nLCBpdGVtOiBhbnkgfT4oKTtcclxuXHJcbiAgICAvKiogRGF0aSBlc3BvcnRhdGkgZGEgbmd4LWNzdiAqL1xyXG4gICAgcHVibGljIGRhdGE6IGFueVtdO1xyXG4gICAgLyoqIEhlYWRlciBkZWkgZGF0aSBlc3BvcnRhdGkgZGEgbmd4LWNzdiAqL1xyXG4gICAgcHVibGljIGhlYWRlcnM6IGFueVtdO1xyXG4gICAgLyoqIEVsZW1lbnRvIEhUTUwgZGEgY2xpY2NhcmUgcGVyIGwnZXNwb3J0YXppb25lICovXHJcbiAgICBAVmlld0NoaWxkKCdleHBvcnREb3dubG9hZGVyJywgeyBzdGF0aWM6IGZhbHNlIH0pIHB1YmxpYyBleHBvcnREb3dubG9hZGVyOiBFbGVtZW50UmVmO1xyXG4gICAgLyoqIFBsYWNlaG9sZGVyIGRpIG1lbsO5IGNvbnRlc3R1YWxlIHBlciBxdWFuZG8gbm9uIGNpIHNvbm8gb3B6aW9uaSBuZWwgcGxhY2Vob2xkZXIgXCJWZXJvXCIgICovXHJcbiAgICBAVmlld0NoaWxkKCdlbXB0eU1lbnUnLCB7IHN0YXRpYzogdHJ1ZSB9KSBwdWJsaWMgdGFibGVFbXB0eU1lbnU6IENvbnRleHRNZW51Q29tcG9uZW50O1xyXG5cclxuICAgIC8qKiBTdWJzY3JpcHRpb24gc3VsbCdhcGVydHVyYSBkZWwgY29udGV4dCBtZW51IGRhIHJpcHVsaXJlIGFsIGRlc3Ryb3kgZGVsbGEgY2xhc3NlICovXHJcbiAgICBwcml2YXRlIGN0eE1lbnVTdWJzY3JpcHRpb246IGFueTtcclxuXHJcbiAgICAvKiogUGFnaW5hIGluIHZpc3VhbGl6emF6aW9uZSAoZHVyYW50ZSBsYSBwYWdpbmF6aW9uZSBpbiBtb2RhbGl0w6AgQXJyYXkpICovXHJcbiAgICBwdWJsaWMgYXJyYXltb2RlUGFnZSA9IDE7XHJcbiAgICAvKiogTnVtZXJvIGRpIHBhZ2luZSAoZHVyYW50ZSBsYSBwYWdpbmF6aW9uZSBpbiBtb2RhbGl0w6AgQXJyYXkpICovXHJcbiAgICBwdWJsaWMgYXJyYXltb2RlUGFnZXMgPSAxO1xyXG4gICAgLyoqIE9nZ2V0dGkgcGVyIG9nbmkgcGFnaW5hIChkdXJhbnRlIGxhIHBhZ2luYXppb25lIGluIG1vZGFsaXTDoCBBcnJheSkgKi9cclxuICAgIEBJbnB1dCgpIEFycmF5bW9kZUl0ZW1zUGVyUGFnZSA9IG51bGw7XHJcbiAgICAvKiogT2dnZXR0byBkaSBzZWxlemlvbmUgcGVyIGxhIG1vZGFsaXTDoCBBcnJheSwgY2hlIGRldmUgY29tcG9ydGFyc2kgY29tZSBsYSBjb250cm9wYXJ0ZSBpbiBtb2RhbGl0w6AgVmlldyAqL1xyXG4gICAgcHVibGljIGFycmF5bW9kZVNlbGVjdGlvbjogSXRlbXNTZWxlY3Rpb248YW55PjtcclxuICAgIC8qKiBDb2xvbm5lIGRhIHZpc3VhbGl6emFyZSBpbiBtb2RhbGl0w6AgYXJyYXkgKi9cclxuICAgIHB1YmxpYyBhcnJheUNvbHVtbnM6IHN0cmluZ1tdID0gW107XHJcbiAgICAvKiogT3JkaW5lIGRlbGxlIGNvbG9ubmUgZGEgdmlzdWFsaXp6YXJlIGluIG1vZGFsaXTDoCBhcnJheSAqL1xyXG4gICAgcHVibGljIGFycmF5Q29sdW1uT3JkZXJpbmc6IHN0cmluZ1tdID0gW107XHJcbiAgICAvKiogT3JkaW5hbWVudGkgQVNDLURFU0Mgc3VsbGUgY29sb25uZSBpbiBtb2RhbGl0w6AgYXJyYXkgKi9cclxuICAgIHB1YmxpYyBhcnJheU9yZGVyczogQXBwT3JkZXJpbmdbXSA9IFtdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVmFyaWFiaWxlIGNoZSBzZXJ2ZSBhIGdlc3RpcmUgaWwgbW9tZW50byBpbiBjdWkgbCdlcy10YWJsZSBhZ2dpb3JuYSBsYSBwYWdpbmF6aW9uZSAocHVsc2FudGkgZWNjKS5cclxuICAgICAqIEVzc2VuZG8gb3BlcmF6aW9uaSBjb211bnF1ZSBjb3N0b3NlIGxlIGVmZmV0dHVvIHNvbG8gc3UgYmluZGluZyBlc3Rlcm5pLCBub24gc3UgcmV3cml0ZSBnZW5lcmF0aSBpbnRlcm5hbWVudGVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBpbnRlcm5hbFdyaXRlQ2FsbCA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FjaGUgY2hlIGNvbnRlcnLDoCB0dXR0ZSBsZSByaWNlcmNoZSBlZmZldHR1YXRlIHN1IGdydXBwaSBkaXZlcnNpIGRhbCBwcmltbyBlIHN1IGVsZW1lbnRpIGNvbnRlbnV0aSBuZWkgZ3J1cHBpLlxyXG4gICAgICogSW4gY2FzbyBkaSBjYW1iaSBkaSBvcmRpbmFtZW50byBkZWxsZSBjb2xvbm5lIGRpdmVyc2UgZGFsbGEgcHJpbWEgdHV0dGUgbGUgY2hpYW1hdGUgZmF0dGUgZGFsIHNlY29uZG8gbGl2ZWxsbyBpbiBwb2kgZGV2b25vIGVzc2VyZSByaWVzZWd1aXRlIHNlY29uZG8gbGEgc2VndWVudGUgbG9naWNhOlxyXG4gICAgICogXHJcbiAgICAgKiBcclxuICAgICAqICoqQ2FtYmlvIG9yZGluYW1lbnRvIHN1bCBwcmltbyBncnVwcG8qKjogcmVsb2FkIGNvbXBsZXRvLCBub24gbWkgb2NjdXBvIGRpIHJpcHVsaXJlIGdsaSBlbGVtZW50aSBiaW5kYXRpIGluIGFsY3VuIG1vZG9cclxuICAgICAqIFxyXG4gICAgICogKipDYW1iaW8gb3JkaW5hbWVudG8gc3VsbGEgY29sb25uYSByZWxhdGl2YSBhbGwnTi1lc2ltbyBncnVwcG8qKjogcmVsb2FkIGNvbXBsZXRvIGRlbCBjb250ZW51dG8gZGVpIGdydXBwaSBwcmVjZWRlbnRpLCByaXB1bGVuZG8gcHJlY2VkZW50ZW1lbnRlIFxyXG4gICAgICogdHV0dGkgZ2xpIGVsZW1lbnRpIGNvbiAqKl9ncm91cGxldmVsKiogPSBOXHJcbiAgICAgKiBcclxuICAgICAqICoqQ2FtYmlvIG9yZGluYW1lbnRvIHN1IHVuYSBjb2xvbm5hIG5vbiByYWdncnVwcGF0YSoqOiByZWxvYWQgY29tcGxldG8gcGVyIHR1dHRpIGkgZ3J1cHBpIGZpbmFsaSBhcGVydGksIGRldm8gcHJlY2VkZW50ZW1lbnRlIHJpcHVsaXJlIHR1dHRpIGdsaSBlbGVtZW50aSBjb24gKipfaXRlbSoqID0gdHJ1ZVxyXG4gICAgICogXHJcbiAgICAgKiBBbHRyaSBldmVudGkgbm9uIGRvdnJlYmJlcm8gcmFwcHJlc2VudGFyZSBwcm9ibGVtaTpcclxuICAgICAqIC0gU2VsZXppb25lOiBub24gY2FtYmlhIG51bGxhXHJcbiAgICAgKiAtIFBhZ2luYXppb25lOiBjYW1iaWEgYSBsaXZlbGxvIHJvb3QgcXVpbmRpIHZpZW5lIHJpY2FyaWNhdG8gdHV0dG8gY29tdW5xdWUsIHN0ZXNzbyB2YWxlIHBlciBsZSBwYWdpbmF6aW9uaSBpbnRlcm5lXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ3JvdXBTZWFyY2hSZXF1ZXN0c0NhY2hlOiB7IHBhdGg6IHN0cmluZywgcm91dGU6IEdyb3VwUm91dGVGcmFnbWVudFtdLCB2aWV3OiBBcHBTZWFyY2g8YW55PiwgZ3JvdXBfY29sdW1uOiBzdHJpbmcgfVtdID0gW107XHJcblxyXG4gICAgLyoqIFZhcmlhYmlsZSBkJ2FwcG9nZ2lvIHBlciBjYXBpcmUgc2UgYyfDqCBiaXNvZ25vIGRpIHJpLWVmZmV0dHVhcmUgdW5hIHJpY2VyY2EgbyBtZW5vICovXHJcbiAgICBwcml2YXRlIFJlc2VhcmNoTmVlZGVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICAvKiogQ29sb25uZSB2aXNpYmlsaSBkZWxsYSB2aXN0YSBhdHR1YWxlLiBWYWxvcml6emF0byBkaSBkZWZhdWx0IGFsIG51bWVybyBtYXNzaW1vIGRpIGNvbG9ubmUgc3VwcG9ydGF0ZSBkYWxsYSB0YWJlbGxhIHBlciBsZSBjYXNpc3RpY2hlIGluIGFzc2VuemEgZGkgY3VzdG9tIGNlbGxzICovXHJcbiAgICBwdWJsaWMgQ29sdW1uczogeyBWaXNpYmlsZTogbnVtYmVyLCBWaXNpYmxlVW5waW5uZWQ6IG51bWJlciwgR2xvYmFsOiBudW1iZXIgfSA9IHsgVmlzaWJpbGU6IDEwMCwgVmlzaWJsZVVucGlubmVkOiAxMDAsIEdsb2JhbDogMTAwIH07XHJcbiAgICAvKiogSW4gY2FzbyBkaSBSb3cgR3JvdXBpbmcgcXVpIHZpZW5lIHNhbHZhdGEgbGEgdmlzdGEgcHJpbmNpcGFsZSBkZWkgZ3J1cHBpIGJhc2UgKi9cclxuICAgIHB1YmxpYyBNYWluR3JvdXBWaWV3OiBBcHBTZWFyY2g8YW55PiA9IG51bGw7XHJcbiAgICAvKiogQ29udGVnZ2lvIGJhc2UgZGVnbGkgb2dnZXR0aS4gSW4gbW9kYWxpdMOgIG5vcm1hbGUgdmllbmUgcmVzZXR0YXRvIGFkIG9nbmkgbnVvdmEgVmlldyBpbnNlcml0YSwgaW4gbW9kYWxpdMOgIFJvd0dyb3VwaW5nIHZpZW5lIHJlc2V0dGF0byBzb2xvIGFkIHVuYSBudW92YSBWaWV3IGRpIGxpdmVsbG8gXCIwXCIgKi9cclxuICAgIHByaXZhdGUgQmFzZUl0ZW1zQ291bnQgPSBudWxsO1xyXG5cclxuICAgIC8qKiBDYWNoZSBwZXIgc2FsdmFyZSBwZXIgb2duaSBjaGlhdmUgZGkgb2duaSBncnVwcG8gY2hpIMOoIGlsIGdydXBwbyByYXBwcmVzZW50YXRvICovXHJcbiAgICBwcml2YXRlIHJnR3JvdXBDYWNoZTogTWFwPHN0cmluZywgR3JvdXA+ID0gbmV3IE1hcDxzdHJpbmcsIEdyb3VwPigpO1xyXG4gICAgLyoqIENhY2hlIHBlciBzYWx2YXJlIHBlciBvZ25pIGNoaWF2ZSBkaSBvZ25pIGdydXBwbyBjaGkgc29ubyBnbGkgb2dnZXR0aSBzb3R0b3N0YW50aSwgbm9uIGRlaSBzb3R0b2dydXBwaSAqL1xyXG4gICAgcHJpdmF0ZSByZ0l0ZW1DYWNoZTogTWFwPHN0cmluZywgYW55W10+ID0gbmV3IE1hcDxzdHJpbmcsIGFueVtdPigpO1xyXG4gICAgLyoqIENhY2hlIHBlciBzYWx2YXJlIHBlciBvZ25pIGNoaWF2ZSBkaSBvZ25pIGdydXBwbyBjaGkgc29ubyBnbGkgb2dnZXR0aSBzb3R0b3N0YW50aSwgbm9uIGRlaSBzb3R0b2dydXBwaSAqL1xyXG4gICAgcHJpdmF0ZSByZ0NoaWxkR3JvdXBzQ2FjaGU6IE1hcDxzdHJpbmcsIEdyb3VwW10+ID0gbmV3IE1hcDxzdHJpbmcsIEdyb3VwW10+KCk7XHJcblxyXG4gICAgLyoqIENhY2hlIGRpIHNlbGV6aW9uZSBIYXNoIC0gT2dnZXR0byBwZXIgbGEgdmFyaWFiaWxlICoqaXRlbXMqKiBkZWxsJ2l0ZW1TZWxlY3Rvci4gRmFjaWxpdGEgbGUgb3BlcmF6aW9uaSBkaSBsb29rdXAgdmlhIGhhc2gqL1xyXG4gICAgcHJpdmF0ZSBpdGVtc0NhY2hlOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xyXG4gICAgLyoqIENhY2hlIGRpIHNlbGV6aW9uZSBIYXNoIC0gT2dnZXR0byBwZXIgbGEgdmFyaWFiaWxlICoqZ3JvdXBzKiogZGVsbCdpdGVtU2VsZWN0b3IuIEZhY2lsaXRhIGxlIG9wZXJhemlvbmkgZGkgbG9va3VwIHZpYSBoYXNoICovXHJcbiAgICBwcml2YXRlIGdyb3Vwc0NhY2hlOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xyXG4gICAgLyoqIENhY2hlIGRpIHNlbGV6aW9uZSBIYXNoIC0gT2dnZXR0byBwZXIgbGEgdmFyaWFiaWxlICoqZXhjbHVzaW9ucyoqIGRlbGwnaXRlbVNlbGVjdG9yLiBGYWNpbGl0YSBsZSBvcGVyYXppb25pIGRpIGxvb2t1cCB2aWEgaGFzaCAqL1xyXG4gICAgcHJpdmF0ZSBleGNsdXNpb25zQ2FjaGU6IE1hcDxzdHJpbmcsIGFueT4gPSBuZXcgTWFwKCk7XHJcbiAgICAvKiogQ2FjaGUgZGkgc2VsZXppb25lIEhhc2ggLSBPZ2dldHRvIHBlciBsYSB2YXJpYWJpbGUgKipncm91cF9leGNsdXNpb25zKiogZGVsbCdpdGVtU2VsZWN0b3IuIEZhY2lsaXRhIGxlIG9wZXJhemlvbmkgZGkgbG9va3VwIHZpYSBoYXNoICovXHJcbiAgICBwcml2YXRlIGdyb3VwX2V4Y2x1c2lvbnNDYWNoZTogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcclxuXHJcbiAgICAvKiogQ2FjaGUgZGkgc2VsZXppb25lIEhhc2ggLSBPZ2dldHRvIHBlciBsYSB2YXJpYWJpbGUgKippdGVtcyoqIGRlbGwnaXRlbVNlbGVjdG9yLiBGYWNpbGl0YSBsZSBvcGVyYXppb25pIGRpIGxvb2t1cCB2aWEgaW5kaWNlKi9cclxuICAgIHByaXZhdGUgaV9pdGVtc0NhY2hlOiBNYXA8c3RyaW5nLCBudW1iZXI+ID0gbmV3IE1hcCgpO1xyXG4gICAgLyoqIENhY2hlIGRpIHNlbGV6aW9uZSBIYXNoIC0gT2dnZXR0byBwZXIgbGEgdmFyaWFiaWxlICoqZ3JvdXBzKiogZGVsbCdpdGVtU2VsZWN0b3IuIEZhY2lsaXRhIGxlIG9wZXJhemlvbmkgZGkgbG9va3VwIHZpYSBpbmRpY2UgKi9cclxuICAgIHByaXZhdGUgaV9ncm91cHNDYWNoZTogTWFwPHN0cmluZywgbnVtYmVyPiA9IG5ldyBNYXAoKTtcclxuICAgIC8qKiBDYWNoZSBkaSBzZWxlemlvbmUgSGFzaCAtIE9nZ2V0dG8gcGVyIGxhIHZhcmlhYmlsZSAqKmV4Y2x1c2lvbnMqKiBkZWxsJ2l0ZW1TZWxlY3Rvci4gRmFjaWxpdGEgbGUgb3BlcmF6aW9uaSBkaSBsb29rdXAgdmlhIGluZGljZSAqL1xyXG4gICAgcHJpdmF0ZSBpX2V4Y2x1c2lvbnNDYWNoZTogTWFwPHN0cmluZywgbnVtYmVyPiA9IG5ldyBNYXAoKTtcclxuICAgIC8qKiBDYWNoZSBkaSBzZWxlemlvbmUgSGFzaCAtIE9nZ2V0dG8gcGVyIGxhIHZhcmlhYmlsZSAqKmdyb3VwX2V4Y2x1c2lvbnMqKiBkZWxsJ2l0ZW1TZWxlY3Rvci4gRmFjaWxpdGEgbGUgb3BlcmF6aW9uaSBkaSBsb29rdXAgdmlhIGluZGljZSAqL1xyXG4gICAgcHJpdmF0ZSBpX2dyb3VwX2V4Y2x1c2lvbnNDYWNoZTogTWFwPHN0cmluZywgbnVtYmVyPiA9IG5ldyBNYXAoKTtcclxuXHJcbiAgICAvKiogSW5kaWNhIHNlIGNpIHNvbm8gZGVsbGUgY29sb25uZSBwaW5uYXRlIGUgdmlzaWJpbGkuIFNlcnZlIHBlciBwb3RlciBzZXR0YXJlIHR1dHRlIGxlIGNvbG9ubmUgcHJpbWEgY2hlIGFycml2aW5vIGRhdGkgYSBwaW5uZWQqL1xyXG4gICAgcHVibGljIEhhc1Bpbm5lZENvbHVtbnM6IGJvb2xlYW5cclxuICAgIC8qKiBMYXJnaGV6emEgY2FsY29sYXRhIGRlbCBjb250YWluZXIgZGVsbGUgY29sb25uZSBwaW5uYXRlICovXHJcbiAgICBwdWJsaWMgUGlubmVkQ29udGFpbmVyV2lkdGg6IG51bWJlcjtcclxuICAgIC8qKiBJbmRpY2Egc2Ugbm9ub3N0YW50ZSBzaWFtbyBpbiBtb2RhbGl0w6AgYXJyYXkgc29ubyBzdGF0aSBpbmRpdmlkdWF0aSBkZWkgZ3J1cHBpLiBJbiB0YWwgY2FzbyBlcy10YWJsZSBzaSBjb21wb3J0YSBkYSBwc2V1ZG8gYmFja2VuZCBlZCBlZmZldHR1YSBsZSBhZ2dyZWdhemlvbmkgZSByYWdncnVwcGFtZW50aSBjb21wbGV0YW1lbnRlIGxhdG8gY2xpZW50ICovXHJcbiAgICBwdWJsaWMgQXJyYXlHcm91cGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIHB1YmxpYyBQYWdlck9wdGlvbnM6IHsgUGFnZXJDb3VudDogbnVtYmVyLCBTaG93Q291bnQ6IGJvb2xlYW4sIFNob3dQYWdpbmc6IGJvb2xlYW4sIFVzZXNWaWV3OiBib29sZWFuLCBWaWV3OiBhbnksIFJlYWR5OiBib29sZWFuLCBTZWFyY2hlczogJ2l0ZW1zJyB8ICdncm91cHMnIH0gPVxyXG4gICAgICAgIHsgUGFnZXJDb3VudDogbnVsbCwgU2hvd0NvdW50OiB0cnVlLCBTaG93UGFnaW5nOiB0cnVlLCBVc2VzVmlldzogdHJ1ZSwgVmlldzogbnVsbCwgUmVhZHk6IGZhbHNlLCBTZWFyY2hlczogJ2l0ZW1zJyB9O1xyXG5cclxuICAgIC8vICNyZWdpb24gQ2ljbG8gZGkgdml0YSBFUy1UYWJsZSAtIEluaXppYWxpenphemlvbmlcclxuXHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHVibGljIG5nT25Jbml0KCkge1xyXG4gICAgICAgIC8vUGVyIHBvdGVyIGNhbWJpYXJlIGlsIGxheW91dCBpbiBiYXNlIGFsIGxpdmVsbG8gZ2VyYXJjaGljbyBpbCBjb21wb25lbnRlIGRldmEgYXZlcmUgaWwgcGllbm8gY29udHJvbGxvIGRpIG9nbmkgY2VsbGEsXHJcbiAgICAgICAgLy9jaGUgY29uIHNvbG8gbGEgcHJvaWV6aW9uZSAoc2VuemEgY2VsbGUgY3Vzb3RtKSBub24gw6ggZGlzcG9uaWJpbGVcclxuICAgICAgICBpZiAodGhpcy5IaWVyYXJjaHkgJiYgIXRoaXMuVXNlQ3VzdG9tQ2VsbHMpXHJcbiAgICAgICAgICAgIHRocm93IFwiRXMtdGFibGUgZXJyb3I6IFBlciBwb3RlciB1dGlsaXp6YXJlIGwnZXMtdGFibGUgY29uIFtIaWVyYXJjaHldPVxcXCJ0cnVlXFxcIiDDqCByaWNoaWVzdG8gYW5jaGUgW1VzZUN1c3RvbUNlbGxzXT1cXFwidHJ1ZVxcXCJcIjtcclxuXHJcbiAgICAgICAgLy8gY2xpY2sgZGVzdHJvIHN1IHVuYSByaWdhIGNvbiBzZWxlemlvbmUgYXR0aXZhOiBUaXJvIGZ1b3JpIGlsIGNvbnRleHQgbWVudSBlIHNlbGV6aW9uZSBsJ2VsZW1lbnRvIGNvcnJlbnRlXHJcbiAgICAgICAgdGhpcy5jdHhNZW51U3Vic2NyaXB0aW9uID0gKHRoaXMuQ29udGV4dE1lbnUgfHwgdGhpcy50YWJsZUVtcHR5TWVudSkub3Blbi5zdWJzY3JpYmUodCA9PiB7XHJcbiAgICAgICAgICAgIC8vIEdydXBwaSB2YSBiZW5lLCBvZ2dldHRpIHB1cmUsIG1hIHNlcGFyYXRvcmkgZnJhIGdydXBwaSBwcm9wcmlvIG5vLi4uXHJcbiAgICAgICAgICAgIGlmKHQuaXRlbS5fc2VwKSByZXR1cm47XHJcblxyXG4gICAgICAgICAgICBsZXQgc2hvdWxkRW1pdCA9ICF0Lml0ZW0uX3NlbGVjdGVkO1xyXG5cclxuICAgICAgICAgICAgdC5pdGVtLl9zZWxlY3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHZhciBpdGVtU2VsZWN0aW9uID0gdGhpcy5oYW5kbGVJdGVtc1NlbGVjdGlvbihbdC5pdGVtXSk7XHJcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlZCgpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHNob3VsZEVtaXQpXHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZC5lbWl0KGl0ZW1TZWxlY3Rpb24pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgICAgIC8vIFNlIHV0aWxpenpvIGxhIG5ldyBzcGljeSBtb2RlIGRlZHVjbyB0dXR0aSBpIHBhcmFtZXRyaSBkaSBsYXZvcm8gcG9zc2liaWxpIGFsIGNhcmljYW1lbnRvIGRlbGxhIHRhYmVsbGFcclxuICAgICAgICAvLyBWZW5nb25vIHNvdnJhc2NyaXR0ZSBzb2xvIGxlIHByb3ByaWV0w6Agbm9uIGltcG9zdGF0ZSBkYWxsJ3V0ZW50ZVxyXG4gICAgICAgIGlmICh0aGlzLkVzVGRzRGlyZWN0aXZlICYmIHRoaXMuRXNUZHNEaXJlY3RpdmUubGVuZ3RoID4gMCAmJiB0aGlzLkVzVGhzRGlyZWN0aXZlICYmIHRoaXMuRXNUaHNEaXJlY3RpdmUubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5Vc2VDdXN0b21DZWxscyA9PSBudWxsKSB0aGlzLlVzZUN1c3RvbUNlbGxzID0gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuSGlkZGVuQ29sdW1ucyA9PSBudWxsICYmIHRoaXMuVXNlQ3VzdG9tQ2VsbHMpIHRoaXMuSGlkZGVuQ29sdW1ucyA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLkNvbHVtbnNPcmRlcmluZyA9PSBudWxsICYmIHRoaXMuVXNlQ3VzdG9tQ2VsbHMpIHRoaXMuQ29sdW1uc09yZGVyaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuT3JkZXJCeUNvbHVtbiA9PSBudWxsICYmIHRoaXMuVXNlQ3VzdG9tQ2VsbHMpIHRoaXMuT3JkZXJCeUNvbHVtbiA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLlNlbGVjdEFsbCA9PSBudWxsICYmIHRoaXMuU2VsZWN0aW9uKSB0aGlzLlNlbGVjdEFsbCA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLlNoaWZ0Q2xpY2sgPT0gbnVsbCAmJiB0aGlzLlNlbGVjdGlvbikgdGhpcy5TaGlmdENsaWNrID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZSBsJ0lucHV0IMOoIG51bGwgKHZhbG9yZSBub24gc2V0dGF0bykgdmVkZSBzZSBjJ8OoIHVuIGRlZmF1bHQgY29uIGN1aSB2YWxvcml6emFybG8uIFNlIG5vbiBjJ8OoIHV0aWxpenphIGlsIHZhbG9yZSBkaSBmYWxsYmFjayAocXVhbG9yYSBmb3JuaXRvKVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge1R9IGlucHV0VmFsdWUgVmFsb3JlIGRlbGwnSW5wdXRcclxuICAgICAqIEBwYXJhbSB7VH0gZGVmYXVsdFZhbHVlIFZhbG9yZSBkaSBkZWZhdWx0IGltcG9zdGF0byBkYSBjb25maWd1cmF6aW9uZVxyXG4gICAgICogQHBhcmFtIHtUfSBmYWxsYmFja1ZhbHVlIFZhbG9yZSBkZWxsJ0lucHV0IHBlciBxdWFuZG8gbm9uIMOoIHN0YXRvIGFzc2VnbmF0byBkYWwgcHJvZ3JhbW1hdG9yZSBlIG5vbiBoYSB1biBkZWZhdWx0XHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgSW5wdXRPckRlZmF1bHQ8VD4oaW5wdXRWYWx1ZTogVCwgZGVmYXVsdFZhbHVlOiBULCBmYWxsYmFja1ZhbHVlPzogVCkge1xyXG5cclxuICAgICAgICAvLyBJbnB1dCB2YWxvcml6emF0byBkYWwgcHJvZ3JhbW1hdG9yZVxyXG4gICAgICAgIGlmIChpbnB1dFZhbHVlICE9IG51bGwgJiYgaW5wdXRWYWx1ZSAhPSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgIHJldHVybiBpbnB1dFZhbHVlO1xyXG5cclxuICAgICAgICAvLyBJbnB1dCB2YWxvcml6emF0byBkYSBjb25maWd1cmF6aW9uZSBnbG9iYWxlXHJcbiAgICAgICAgaWYgKGRlZmF1bHRWYWx1ZSAhPSBudWxsICYmIGRlZmF1bHRWYWx1ZSAhPSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XHJcblxyXG4gICAgICAgIC8vSW5wdXQgbm9uIHZhbG9yaXp6YXRvIGRhIG5pZW50ZSBlIGRhIG5lc3N1bm9cclxuICAgICAgICBpZiAoZmFsbGJhY2tWYWx1ZSAhPSBudWxsICYmIGZhbGxiYWNrVmFsdWUgIT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsbGJhY2tWYWx1ZTtcclxuXHJcbiAgICAgICAgLy8gSSBjYXNpIGluIGN1aSBzaSBhcnJpdmEgcXVpIHNvbm8gaSBjYXNpIGRpIElucHV0IGNoZSBkaSBkZWZhdWx0IHZhIGJlbmUgY2hlIHNpYW5vIG51bGxpIGUgY2hlIG5lc3N1bm8gc2kgY2FnYVxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY3R4TWVudVN1YnNjcmlwdGlvbilcclxuICAgICAgICAgICAgdGhpcy5jdHhNZW51U3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBpZ25vcmUgKi9cclxuICAgIHB1YmxpYyBhc3luYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICAgICAgbGV0IG5ld1NlYXJjaFZpZXcgPSBjaGFuZ2VzWydTZWFyY2hWaWV3J107XHJcbiAgICAgICAgaWYgKG5ld1NlYXJjaFZpZXcgJiYgdGhpcy5TZWFyY2hWaWV3KVxyXG4gICAgICAgICAgICB0aGlzLmFycmF5UHVsc2FudGkgPSB0aGlzLmdldFBhZ2VzQXJyYXkoNiwgdGhpcy5TZWFyY2hWaWV3LnBhZ2UsIHRoaXMuU2VhcmNoVmlldy5wYWdlcyB8fCAxKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyAjZW5kcmVnaW9uXHJcblxyXG4gICAgLy8gI3JlZ2lvbiBJbXBsZW1lbnRhemlvbmUgQ29udHJvbFZhbHVlQWNjZXNzb3IgaWdub3JhYmlsZVxyXG5cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBwdWJsaWMgcmVnaXN0ZXJPbkNoYW5nZShmbik6IHZvaWQgeyB0aGlzLnByb3BhZ2F0ZUNoYW5nZSA9IGZuOyB9XHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHVibGljIHJlZ2lzdGVyT25Ub3VjaGVkKGZuKTogdm9pZCB7IH1cclxuICAgIC8qKiBAaWdub3JlICovXHJcbiAgICBjaGFuZ2VkKCkgeyB0aGlzLnByb3BhZ2F0ZUNoYW5nZSh0aGlzLlZpZXcpOyB9XHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHJvcGFnYXRlQ2hhbmdlID0gKF86IGFueSkgPT4geyB9O1xyXG5cclxuICAgIC8vICNlbmRyZWdpb25cclxuXHJcbiAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgcHVibGljIHdyaXRlVmFsdWUob2JqKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5WaWV3ID0gb2JqID8gb2JqIDogbnVsbDtcclxuXHJcbiAgICAgICAgLy8gTWkgw6ggYXJyaXZhdGEgbCdBcHBTZWFyY2ggcXVpbmRpIGRpIHNpY3VybyBub24gaG8gdW5hIHJpY2VyY2EgaW4gcHJvZ3Jlc3NcclxuICAgICAgICB0aGlzLnJlc2VhcmNoSW5Qcm9ncmVzcyA9IGZhbHNlO1xyXG5cclxuICAgICAgICBpZiAoIXRoaXMuVmlldyAmJiAhdGhpcy5TZWFyY2hWaWV3KSB7XHJcbiAgICAgICAgICAgIC8vIFN1IHZpZXcgbnVsbGEgZXZpdG8gZGkgZmFyZSBwcmVzc29jaMOpIHF1YWxzaWFzaSBjb3NhLiBTZSBhcnJpdmEgdW4gbnVsbCBkZXZvIGFuY2hlIGFzc2ljdXJhcm1pIGRpIG5vbiBtb3N0cmFyZSBudWxsYVxyXG4gICAgICAgICAgICB0aGlzLmJvdW5kU291cmNlID0gdGhpcy5UTVBCb3VuZFNvdXJjZSB8fCBbXTtcclxuXHJcbiAgICAgICAgICAgIC8vIFBlciBlc3NlcmUgc2ljdXJvIGNoZSBkb3BvIHVuIGJpbmQgZGkgb2dnZXR0aSBsYSBlcy10YWJsZSBhZ2dpb3JuaSBsYSBncmFmaWNhXHJcbiAgICAgICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBTZSBwZXIgc2JhZ2xpbyBsJ29nZ2V0dG8gY2hlIG1pIGFycml2YSBub24gw6ggdGlwaXp6YXRvIChpbnN0YW5jZW9mIEFwcFNlYXJjaCByZXN0aXR1aXNjZSBmYWxzZSBhbmNoZSBzZSDDqCBkZWwgdGlwbyBnaXVzdG8pXHJcbiAgICAgICAgLy8gbG8gY29ycmVnZ28tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgICAgIGlmICh0aGlzLlZpZXcgJiYgdHlwZW9mICh0aGlzLlZpZXcgYXMgYW55KS5yZXN1bHQgIT0gJ3VuZGVmaW5lZCcgJiYgISh0aGlzLlZpZXcgaW5zdGFuY2VvZiBSZXBvcnREZWZpbml0aW9uKSkge1xyXG4gICAgICAgICAgICAodGhpcy5WaWV3IGFzIGFueSkuX19wcm90b19fID0gbmV3IFJlcG9ydERlZmluaXRpb24oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5WaWV3ICYmIHR5cGVvZiAodGhpcy5WaWV3IGFzIGFueSkuaXRlbXNwZXJwYWdlb3ZlcnJpZGUgIT0gJ3VuZGVmaW5lZCcgJiYgISh0aGlzLlZpZXcgaW5zdGFuY2VvZiBBcHBTZWFyY2gpKSB7XHJcbiAgICAgICAgICAgICh0aGlzLlZpZXcgYXMgYW55KS5fX3Byb3RvX18gPSBuZXcgQXBwU2VhcmNoKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuU2VhcmNoVmlldyAmJiB0eXBlb2YgKHRoaXMuU2VhcmNoVmlldyBhcyBhbnkpLml0ZW1zcGVycGFnZW92ZXJyaWRlICE9ICd1bmRlZmluZWQnICYmICEodGhpcy5TZWFyY2hWaWV3IGluc3RhbmNlb2YgQXBwU2VhcmNoKSkge1xyXG4gICAgICAgICAgICAodGhpcy5TZWFyY2hWaWV3IGFzIGFueSkuX19wcm90b19fID0gbmV3IEFwcFNlYXJjaCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG4gICAgICAgIGlmICh0aGlzLlZpZXcgJiYgdGhpcy5WaWV3IGluc3RhbmNlb2YgUmVwb3J0RGVmaW5pdGlvbikge1xyXG4gICAgICAgICAgICAvLyBTZSBtaSBhcnJpdmEgdW5hIHJlcG9ydCBkZWZpbml0aW9uIHZ1b2wgZGlyZSBjaGUgcG90cmVpIGF2ZXJlIGRlaSByaXN1bHRhdGkgZGEgdmlzdWFsaXp6YXJlXHJcbiAgICAgICAgICAgIHRoaXMuc2V0TW9kZSgncmVwb3J0Jyk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLlJlcG9ydFZhbHVlcyA9IHRoaXMuVmlldy5yZXN1bHQ7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLlJlcG9ydFZhbHVlcylcclxuICAgICAgICAgICAgICAgIHRoaXMucmV2aWV3UmVwb3J0QmluZGluZ3MoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5WaWV3ICYmIHRoaXMuVmlldyBpbnN0YW5jZW9mIEFwcFNlYXJjaCkge1xyXG4gICAgICAgICAgICAvLyBTZSBjYW1iaWEgbCdvZ2dldHRvIGludGVybyBzaWduaWZpY2EgY2hlIGhvIHJpbWFuZGF0byBsYSByaWNlcmNhXHJcbiAgICAgICAgICAgIHRoaXMuc2V0TW9kZSgndmlldycpO1xyXG5cclxuICAgICAgICAgICAgbGV0IGZpcnN0SXRlbUdyb3VwT3JOb0dyb3VwaW5nID0gKHRoaXMuVmlldy5yZXF1ZXN0ZWRncm91cHM/Lmxlbmd0aCB8fCAwKSA9PSAwO1xyXG5cclxuICAgICAgICAgICAgLy8gU2UgdmVuZ28gZGEgdW5hIHJpY2VyY2EgaW50ZXJuYSBtYW50ZW5nbyBsbyBzdGF0byBkaSBzZWxlemlvbmUgcHJlY2VkZW50ZSAocXVpbmRpIHN1IGNhbWJpbyBwYWdpbmEsIGNhbWJpbyBpcHAsIGVjYy4uLilcclxuICAgICAgICAgICAgLy8gc2UgaW52ZWNlIGwndXRlbnRlIGhhIGZhdHRvIHVuYSByaWNlcmNhIGx1aSAocXVpbmRpIGNhbWJpYW5kbyBmaWx0cmkpLCBzZWNjbyBsZSBpbmZvIGRpIHNlbGV6aW9uZVxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuVmlldy5zZWxlY3Rpb24gfHwgKCF0aGlzLlZpZXcuaW50ZXJuYWxzZWFyY2hyZXF1ZXN0ICYmIGZpcnN0SXRlbUdyb3VwT3JOb0dyb3VwaW5nKSB8fCAhdGhpcy5Vc2VTZWxlY3Rpb25DYWNoZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclNlbGVjdGlvbkNhY2hlcygpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5WaWV3LnNlbGVjdGlvbiA9IG5ldyBJdGVtc1NlbGVjdGlvbihbXSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZC5lbWl0KHRoaXMuVmlldy5zZWxlY3Rpb24pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLlZpZXcuaW50ZXJuYWxzZWFyY2hyZXF1ZXN0ID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAvLyBSZWN1cGVybyBQcmVmZXJlbmNlXHJcbiAgICAgICAgICAgIGlmICh0aGlzLlNhdmVQcmVmZXJlbmNlcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLm5nQ29udHJvbC5uYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJOb24gcG9zc28gdXRpbGl6emFyZSBsZSBwcmVmZXJlbmNlIHNlbnphIGF2ZXJlIHVuICduYW1lJyBwZXIgcXVlc3RhIHRhYmVsbGFcIik7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghdGhpcy5wcmVmU2VydmljZSlcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm9uIHBvc3NvIHV0aWxpenphcmUgbGUgcHJlZmVyZW5jZSBzZW56YSBjaGUgaWwgcGFjY2hldHRvIEBlc2ZhZW56YS9wcmVmZXJlbmNlcyBzaWEgaW5zdGFsbGF0b1wiKTtcclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwcmVmcyA9IHRoaXMucHJlZlNlcnZpY2UucmV0cmlldmU8eyBjb2x1bW5zOiBzdHJpbmdbXSwgY29sdW1uX29yZGVyaW5nOiBzdHJpbmdbXSB9Pig8c3RyaW5nPnRoaXMubmdDb250cm9sLm5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcmVmcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLlZpZXcuY29sdW1ucyA9IHByZWZzLmNvbHVtbnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuVmlldy5jb2x1bW5fb3JkZXJpbmcgPSBwcmVmcy5jb2x1bW5fb3JkZXJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBMYSBwYWdpbmF6aW9uZSBkZXZvIGZhcmxhIHNvbGFtZW50ZSBxdWFuZG8gcmljaGllZG8gbyB1biBncnVwcG8gcHJpbmNpcGFsZSAoc2Ugc29ubyBpbiByb3cgZ3JvdXBpbmcpIG8gc2Ugbm9uIHJpY2hpZWRvIGdydXBwaSAoaW4gdHV0dGkgbGdpIGFsdHJpIGNhc2kpXHJcbiAgICAgICAgICAgIGlmIChmaXJzdEl0ZW1Hcm91cE9yTm9Hcm91cGluZylcclxuICAgICAgICAgICAgICAgIHRoaXMuYXJyYXlQdWxzYW50aSA9IHRoaXMuZ2V0UGFnZXNBcnJheSg2LCB0aGlzLlZpZXcucGFnZSwgdGhpcy5WaWV3LnBhZ2VzIHx8IDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0aGlzLlZpZXcgJiYgKHRoaXMuVmlldy5sZW5ndGggIT0gbnVsbCAmJiB0aGlzLlZpZXcubGVuZ3RoICE9IHVuZGVmaW5lZCkpIHtcclxuICAgICAgICAgICAgdGhpcy5zZXRNb2RlKCdhcnJheScpO1xyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLlVzZVNlbGVjdGlvbkNhY2hlIHx8ICF0aGlzLmFycmF5bW9kZVNlbGVjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclNlbGVjdGlvbkNhY2hlcygpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hcnJheW1vZGVTZWxlY3Rpb24gPSBuZXcgSXRlbXNTZWxlY3Rpb24oW10pOztcclxuICAgICAgICAgICAgICAgIHRoaXMub25TZWxlY3Rpb25DaGFuZ2VkLmVtaXQodGhpcy5hcnJheW1vZGVTZWxlY3Rpb24pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBSZWN1cGVybyBQcmVmZXJlbmNlXHJcbiAgICAgICAgICAgIGlmICh0aGlzLlNhdmVQcmVmZXJlbmNlcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLm5nQ29udHJvbC5uYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJOb24gcG9zc28gdXRpbGl6emFyZSBsZSBwcmVmZXJlbmNlIHNlbnphIGF2ZXJlIHVuICduYW1lJyBwZXIgcXVlc3RhIHRhYmVsbGFcIik7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghdGhpcy5wcmVmU2VydmljZSlcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm9uIHBvc3NvIHV0aWxpenphcmUgbGUgcHJlZmVyZW5jZSBzZW56YSBjaGUgaWwgcGFjY2hldHRvIEBlc2ZhZW56YS9wcmVmZXJlbmNlcyBzaWEgaW5zdGFsbGF0b1wiKTtcclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwcmVmcyA9IHRoaXMucHJlZlNlcnZpY2UucmV0cmlldmU8eyBjb2x1bW5zOiBzdHJpbmdbXSwgY29sdW1uX29yZGVyaW5nOiBzdHJpbmdbXSB9Pig8c3RyaW5nPnRoaXMubmdDb250cm9sLm5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcmVmcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFycmF5Q29sdW1ucyA9IHByZWZzLmNvbHVtbnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXJyYXlDb2x1bW5PcmRlcmluZyA9IHByZWZzLmNvbHVtbl9vcmRlcmluZztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLlNlYXJjaFZpZXcpXHJcbiAgICAgICAgICAgICAgICB0aGlzLmFycmF5UHVsc2FudGkgPSB0aGlzLmdldFBhZ2VzQXJyYXkoNiwgdGhpcy5TZWFyY2hWaWV3LnBhZ2UsIHRoaXMuU2VhcmNoVmlldy5wYWdlcyB8fCAxKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLlZpZXcgJiYgISh0aGlzLlZpZXcgaW5zdGFuY2VvZiBSZXBvcnREZWZpbml0aW9uKSlcclxuICAgICAgICAgICAgdGhpcy5maW5hbGl6ZUNvbnRleHQoKTtcclxuXHJcbiAgICAgICAgdGhpcy5wb3N0Qm91bmRTb3VyY2VDYWxjdWxhdGlvbigpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3VjY2Vzc2l2YW1lbnRlIGFsIGJpbmQgZGVsIG51b3ZvIGlucHV0IHF1ZXN0YSBmdW56aW9uZSBzaSBvY2N1cGEgZGkgZmluYWxpenphcmUgdHV0dGkgaSBwYXJhbWV0cmkgZGkgZnVuemlvbmFtZW50byBkZWxsJ2VzLXRhYmxlIFxyXG4gICAgICogaW4gYmFzZSBhIElucHV0IC0gTW9kZWxsbywgZSBxdWFsc2lhc2kgYWx0cmEgY29zYSBwb3NzYSBzZXJ2aXJlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZmluYWxpemVDb250ZXh0KCkge1xyXG4gICAgICAgIGxldCB2aWV3Q2FzdGVkID0gdGhpcy5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+O1xyXG5cclxuICAgICAgICAvKlxyXG4gICAgICAgICAqVXNvIGxhIHRlY25pY2EgZGkgRW5kbGVzc1Njcm9sbCBzZSBsYSB2YXJpYWJpbGUgcmVsYXRpdmEgw6ggYXR0aXZhIGUgc2VcclxuICAgICAgICAgKiAxKSBIbyB1biBBcnJheSwgb3BwdXJlXHJcbiAgICAgICAgICogMikgSG8gdW4gQXBwU2VhcmNoIGNoZSBzdGEgY2VyY2FuZG8gY29uIHBhZ2luYXppb25lIFwiVHV0dG9cIiwgb3BwdXJlXHJcbiAgICAgICAgICogMykgSG8gdW4gQXBwU2VhcmNoIGNoZSBzdGEgY2VyY2FuZG8gY29uIHBhZ2luYXppb25lIGRpdmVyc2EgZGEgXCJUdXR0b1wiIG1hIGNvbiBsYSB2YXJpYWJpbGUgRW5kbGVzc1Njcm9sbE9ubHlGb3JBbGwgYSBmYWxzZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGxldCBpc0FwcFNlYXJjaFdpdGhJcHBNYXggPSB0aGlzLnZpZXdNb2RlICYmIHZpZXdDYXN0ZWQuaXRlbXNwZXJwYWdlb3ZlcnJpZGUgPT0gdGhpcy5kZWZhdWx0QWxsUGFnZU92ZXJyaWRlO1xyXG4gICAgICAgIGxldCBpc0FwcFNlYXJjaE5vTWF4SXBwID0gdGhpcy52aWV3TW9kZSAmJiB2aWV3Q2FzdGVkLml0ZW1zcGVycGFnZW92ZXJyaWRlICE9IHRoaXMuZGVmYXVsdEFsbFBhZ2VPdmVycmlkZTtcclxuICAgICAgICB0aGlzLlVzZUVuZGxlc3NzY3JvbGwgPSB0aGlzLkVuZGxlc3NTY3JvbGwgJiYgKHRoaXMuYXJyYXlNb2RlIHx8IGlzQXBwU2VhcmNoV2l0aElwcE1heCB8fCAoaXNBcHBTZWFyY2hOb01heElwcCAmJiAhdGhpcy5FbmRsZXNzU2Nyb2xsT25seUZvckFsbCkpO1xyXG5cclxuICAgICAgICBsZXQgaGFzUm93R3JvdXBzID0gKHZpZXdDYXN0ZWQuZ3JvdXBpbmdzICYmIHZpZXdDYXN0ZWQuZ3JvdXBpbmdzLmZpbHRlcih0ID0+ICF0LmFnZ3JlZ2F0aW9uKS5sZW5ndGggPiAwKSB8fCAodGhpcy5hcnJheU1vZGUgJiYgdGhpcy5Fc1Roc0RpcmVjdGl2ZS5zb21lKHQgPT4gdC50aEdyb3VwKSk7XHJcblxyXG4gICAgICAgIC8vIFNlIGhvIGRlaSBncnVwcGkgaW4gbW9kYWxpdMOgIGFycmF5IGRldm8gc2lzdGVtYXJlIHVuIHBvJyBkaSB2YXJpYWJpbGkgY2hlIGRpdmVudGFubyBpbnNlbnNhdGVcclxuICAgICAgICBpZiAodGhpcy5hcnJheU1vZGUpIHtcclxuICAgICAgICAgICAgaWYgKGhhc1Jvd0dyb3VwcylcclxuICAgICAgICAgICAgICAgIHRoaXMuVXNlQXJyYXlNb2RlUGFnaW5nID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBSaWVtcGltZW50byBkZWxsYSBUTVBCb3VuZFNvdXJjZSBjb24gZ2xpIG9nZ2V0dGkgY2hlIHZlcnJhbm5vIHBvaSBtb3N0cmF0aSBhZCBpbnRlcmZhY2NpYVxyXG4gICAgICAgIGlmICh0aGlzLlVzZUVuZGxlc3NzY3JvbGwgJiYgIWhhc1Jvd0dyb3Vwcykge1xyXG4gICAgICAgICAgICB0aGlzLmFkZGVkU2xpY2VzID0gW107XHJcbiAgICAgICAgICAgIHRoaXMuYm91bmRTdWJTb3VyY2VzID0gdGhpcy5nZXRJdGVtU2xpY2VzKCk7XHJcbiAgICAgICAgICAgIGxldCBmaXJzdFN1YiA9IHRoaXMuYm91bmRTdWJTb3VyY2VzWzBdO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5UTVBCb3VuZFNvdXJjZSA9IGZpcnN0U3ViID8gZmlyc3RTdWIgOiBbXTtcclxuICAgICAgICAgICAgaWYgKGZpcnN0U3ViKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRlZFNsaWNlcy5wdXNoKDApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHRoaXMuVE1QQm91bmRTb3VyY2UgPSB0aGlzLmdldEl0ZW1zQnlNb2RlKGZhbHNlLCAhdGhpcy5pbnRlcm5hbFdyaXRlQ2FsbCk7XHJcblxyXG4gICAgICAgIC8vIFNlIGhvIHVuYSBnZXJhcmNoaWEsIGFzc2Vnbm8gaSBsaXZlbGxpIGdlcmFyY2hpY2kgYWxsYSBUTVBCb3VuZFNvdXJjZVxyXG4gICAgICAgIGlmICh0aGlzLkhpZXJhcmNoeSAmJiAhaGFzUm93R3JvdXBzKVxyXG4gICAgICAgICAgICB0aGlzLmFzc2lnbkhpZXJhcmNoeUxldmVscyh0aGlzLlRNUEJvdW5kU291cmNlKTtcclxuXHJcbiAgICAgICAgLy8gTCdoYXNoaW5nIGRlZ2xpIG9nZ2V0dGkgbG8gZmFjY2lvIGEgcHJlc2NpbmRlcmVcclxuICAgICAgICB0aGlzLmNhbGN1bGF0ZUhhc2godGhpcy5UTVBCb3VuZFNvdXJjZSk7XHJcblxyXG4gICAgICAgIC8vIEFzc2Vnbm8gYSB1bmEgdmFyaWFiaWxlIG1pYSBsJ2V2ZW50dWFsZSBvdmVycmlkZSBwZXIgbGEgY2xhc3NlIGRlbGxhIHJpZ2FcclxuICAgICAgICAvLyBTZSBwb2kgc29ubyBpbiBtb2RhbGl0w6AgZ2VyYXJjaGljYSBpbmlldHRvIGFuY2hlIGxhIGNsYXNzZSBwZXIgbGEgY29uZmlndXJhemlvbmUgZGVsIGxpdmVsbG8gZGVsbGEgcmlnYVxyXG4gICAgICAgIGlmICgodGhpcy5UTVBCb3VuZFNvdXJjZSAmJiB0aGlzLlJvd0NsYXNzQXNzaWduZXIpIHx8IHRoaXMuSGllcmFyY2h5KSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5UTVBCb3VuZFNvdXJjZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IGl0ZW0gPSB0aGlzLlRNUEJvdW5kU291cmNlW2ldO1xyXG4gICAgICAgICAgICAgICAgaXRlbS5fcm93Q2xhc3MgPSB0aGlzLlJvd0NsYXNzQXNzaWduZXIgPyB0aGlzLlJvd0NsYXNzQXNzaWduZXIoaXRlbSkgOiBcIlwiO1xyXG4gICAgICAgICAgICAgICAgaXRlbS5fcm93Q2xhc3MgKz0gdGhpcy5IaWVyYXJjaHkgPyBcIiBlc3Qtcm93LWx2bC1cIiArIGl0ZW0uX2xldmVsIDogXCJcIjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiogR2VuZXJhIGxlIGluZm9ybXppb25pIGRpIHBhZ2luYXppb25lIHBlciBsYSB2aXN0YSBnbG9iYWxlIGRlbGwnZXMtdGFibGUgKi9cclxuICAgIHByaXZhdGUgc2V0dXBQYWdpbmdJbmZvcm1hdGlvbnMoKSB7XHJcbiAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50ID0gIXRoaXMuSGlkZVBhZ2luZ0NvdW50O1xyXG4gICAgICAgIGlmICh0aGlzLmFycmF5TW9kZSAmJiB0aGlzLlVzZUFycmF5TW9kZVBhZ2luZyAmJiAhdGhpcy5TZWFyY2hWaWV3KSB7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlBhZ2VyQ291bnQgPSAoPGFueVtdPnRoaXMuVmlldykubGVuZ3RoIHx8IDA7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlNob3dQYWdpbmcgPSAhdGhpcy5IaWRlUGFnaW5nICYmIHRoaXMuVmlldy5sZW5ndGggPiAxMDtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuVmlldyA9IHRoaXMuVmlldztcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuVXNlc1ZpZXcgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5hcnJheU1vZGUgJiYgKCF0aGlzLlVzZUFycmF5TW9kZVBhZ2luZyB8fCB0aGlzLlNlYXJjaFZpZXcpKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLlNlYXJjaFZpZXcpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlZpZXcgPSB0aGlzLlNlYXJjaFZpZXdcclxuICAgICAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlBhZ2VyQ291bnQgPSB0aGlzLlNlYXJjaFZpZXcub2JqZWN0Y291bnQgfHwgMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICB0aGlzLlBhZ2VyT3B0aW9ucy5QYWdlckNvdW50ID0gKDxhbnlbXT50aGlzLlZpZXcpLmxlbmd0aCB8fCAwXHJcblxyXG4gICAgICAgICAgICB0aGlzLlBhZ2VyT3B0aW9ucy5TaG93Q291bnQgPSB0aGlzLlBhZ2VyT3B0aW9ucy5TaG93Q291bnQgfHwgKHRoaXMuVmlldyAmJiB0aGlzLlZpZXcubGVuZ3RoKSB8fCAodGhpcy5TZWFyY2hWaWV3ICYmIHRoaXMuU2VhcmNoVmlldy5vYmplY3Rjb3VudCAmJiB0aGlzLlNlYXJjaFZpZXcub2JqZWN0Y291bnQgIT0gLTEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0aGlzLnZpZXdNb2RlKSB7XHJcbiAgICAgICAgICAgIGxldCB0bXBWaWV3ID0gdGhpcy5NYWluR3JvdXBWaWV3IHx8IHRoaXMuVmlldztcclxuICAgICAgICAgICAgbGV0IGNvdW50ID0gdG1wVmlldz8uZ3JvdXBjb3VudCB8fCB0bXBWaWV3Py5vYmplY3Rjb3VudDtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2VhcmNoZXMgPSB0bXBWaWV3Py5ncm91cGNvdW50ICE9IG51bGwgJiYgdG1wVmlldz8uZ3JvdXBjb3VudCAhPSB1bmRlZmluZWQgPyAnZ3JvdXBzJyA6ICdpdGVtcyc7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlBhZ2VyQ291bnQgPSBjb3VudCB8fCAwO1xyXG4gICAgICAgICAgICB0aGlzLlBhZ2VyT3B0aW9ucy5WaWV3ID0gdG1wVmlldztcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50ID0gdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50IHx8ICh0bXBWaWV3ICYmIGNvdW50ICYmIGNvdW50ICE9IC0xKTtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd1BhZ2luZyA9ICF0aGlzLkhpZGVQYWdpbmc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMucmVwb3J0TW9kZSkge1xyXG4gICAgICAgICAgICBsZXQgcnZjID0gdGhpcy5SZXBvcnRWYWx1ZXMuY291bnQ7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlZpZXcgPSB0aGlzLlZpZXc7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlBhZ2VyQ291bnQgPSBydmMgJiYgcnZjID09IC0xID8gdGhpcy5SZXBvcnRWYWx1ZXMucm93cy5sZW5ndGggOiBydmMgJiYgcnZjID4gMCA/IHRoaXMuUmVwb3J0VmFsdWVzLmNvdW50IDogMDtcclxuICAgICAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50ID0gdGhpcy5QYWdlck9wdGlvbnMuU2hvd0NvdW50IHx8ICh0aGlzLlZpZXcgJiYgdGhpcy5WaWV3Lm9iamVjdGNvdW50ICYmIHRoaXMuVmlldy5vYmplY3Rjb3VudCAhPSAtMSk7XHJcbiAgICAgICAgICAgIHRoaXMuUGFnZXJPcHRpb25zLlNob3dQYWdpbmcgPSAhdGhpcy5IaWRlUGFnaW5nICYmIHRoaXMuVmlldy5wYWdpbmdhdmFpbGFibGU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmlwdWxpc2NlIGxlIGNhY2hlIGRpIHNlbGV6aW9uZVxyXG4gICAgICogXHJcbiAgICAgKiBAdG9kbzogU0VMRUNUSU9OXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgY2xlYXJTZWxlY3Rpb25DYWNoZXMoKSB7XHJcbiAgICAgICAgdGhpcy5pdGVtc0NhY2hlLmNsZWFyKCk7XHJcbiAgICAgICAgdGhpcy5ncm91cHNDYWNoZS5jbGVhcigpO1xyXG4gICAgICAgIHRoaXMuZXhjbHVzaW9uc0NhY2hlLmNsZWFyKCk7XHJcbiAgICAgICAgdGhpcy5ncm91cF9leGNsdXNpb25zQ2FjaGUuY2xlYXIoKTtcclxuXHJcbiAgICAgICAgdGhpcy5pX2l0ZW1zQ2FjaGUuY2xlYXIoKTtcclxuICAgICAgICB0aGlzLmlfZ3JvdXBzQ2FjaGUuY2xlYXIoKTtcclxuICAgICAgICB0aGlzLmlfZXhjbHVzaW9uc0NhY2hlLmNsZWFyKCk7XHJcbiAgICAgICAgdGhpcy5pX2dyb3VwX2V4Y2x1c2lvbnNDYWNoZS5jbGVhcigpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW4gYmFzZSBhbGxhIG1vZGFsaXTDoCBzcGVjaWZpY2F0YSAoQXJyYXlNb2RlLCBWaWV3TW9kZSwgZWNjLi4uKSBxdWVzdG8gbWV0b2RvIHJlY3VwZXJhIGwnYXJyYXkgZGkgb2dnZXR0aSBkYSBiaW5kYXJlIGFkIGludGVyZmFjY2lhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBvbmx5c2VsZWN0ZWQgW2ZhbHNlXSBJbmRpY2EgZGkgcHJlbmRlcmUgc29sbyBnbGkgb2dnZXR0aSBzZWxlemlvbmF0aVxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSByZWZyZXNoUGFnaW5nIFtmYWxzZV0gSW5kaWNhIHNlIGFnZ2lvcm5hcmUgbGUgaW5mb3JtYXppb25pIGRpIHBhZ2luYXppb25lIG8gbWVub1xyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBhbGxJZlBvc3NpYmxlIFtmYWxzZV0gSW5kaWNhIHNlIHByZW5kZXJlIHR1dHRpIGdsaSBvZ2dldHRpIHF1YW9yYSBwb3NzaWJpbGUsIHVzYXRvIHNvbG8gaW4gQXJyYXlNb2RlXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2FueVtdfSBMaXN0YSBkZWdsaSBvZ2dldHRpIHN1IGN1aSBlZmZldHR1YXJlIGlsIGJpbmQgbGF0byBpbnRlcmZhY2NpYVxyXG4gICAgICogXHJcbiAgICAgKiBAdG9kbzogSVRFTVNcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZXRJdGVtc0J5TW9kZShvbmx5c2VsZWN0ZWQ6IGJvb2xlYW4gPSBmYWxzZSwgcmVmcmVzaFBhZ2luZzogYm9vbGVhbiA9IGZhbHNlLCBhbGxJZlBvc3NpYmxlOiBib29sZWFuID0gZmFsc2UpOiBhbnlbXSB7XHJcbiAgICAgICAgbGV0IGl0ZW1zOiBhbnlbXSA9IFtdO1xyXG5cclxuICAgICAgICBpZiAoKHRoaXMudmlld01vZGUgJiYgdGhpcy5WaWV3IGluc3RhbmNlb2YgQXBwU2VhcmNoKSkge1xyXG4gICAgICAgICAgICBpdGVtcyA9IHRoaXMuZ2V0Vmlld0l0ZW1zQnlTb3VyY2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5hcnJheU1vZGUpIHtcclxuICAgICAgICAgICAgdGhpcy5WaWV3LmZvckVhY2goaXRtID0+IHsgaXRtLl9pdGVtID0gdHJ1ZTsgfSk7XHJcblxyXG4gICAgICAgICAgICAvLyBTZSBmYWNjaW8gZGVpIHJhZ2dydXBwYW1lbnRpIGlnbm9ybyBsYSBwYWdpbmF6aW9uZVxyXG4gICAgICAgICAgICBpZiAodGhpcy5Vc2VBcnJheU1vZGVQYWdpbmcgJiYgIWFsbElmUG9zc2libGUpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTZSBzb25vIGluIG1vZGFsaXTDoCBhcnJheSBtYSBsYSByaWNlcmNhIGRpcGVuZGUgZGEgdW5hIHZpZXcgZGV2byByaWFsbGluZWFyZSBnbGkgaXRlbXBlcnBhZ2VcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLlNlYXJjaFZpZXcpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5BcnJheW1vZGVJdGVtc1BlclBhZ2UgPSB0aGlzLlNlYXJjaFZpZXcuaXRlbXNwZXJwYWdlb3ZlcnJpZGU7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gRGV2byBjaGlhbWFyZSBpbCByZWZyZXNoIHBhZ2Ugc29sbyBzZSB2ZW5nbyByaWNoaWFtYXRvIGRhIHVuIGJpbmRpbmcgZXN0ZXJub1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlZnJlc2hQYWdpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWZyZXNoUGFnaW5nKHRoaXMuQXJyYXltb2RlSXRlbXNQZXJQYWdlKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpdGVtcyA9IHRoaXMuYWRhcHRWaWV3VG9QYWdpbmcoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGl0ZW1zID0gdGhpcy5WaWV3IGFzIGFueVtdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBTZSB2b2dsaW8gc29sbyBpIHNlbGV6aW9uYXRpIGZpbHRyb1xyXG4gICAgICAgIGlmIChvbmx5c2VsZWN0ZWQpXHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtcy5maWx0ZXIodCA9PiB0Ll9zZWxlY3RlZCk7XHJcblxyXG4gICAgICAgIHJldHVybiBpdGVtcztcclxuICAgIH1cclxuXHJcbiAgICAvKiogIFxyXG4gICAgICogQGlnbm9yZSBcclxuICAgICAqIFxyXG4gICAgICogQHRvZG86IElURU1TXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0Vmlld0l0ZW1zQnlTb3VyY2UoKTogYW55W10ge1xyXG4gICAgICAgIGxldCBjYXN0ZWRWaWV3ID0gdGhpcy5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+O1xyXG4gICAgICAgIGxldCBncm91cEtleXMgPSBjYXN0ZWRWaWV3Lmdyb3VwaW5ncyA/IGNhc3RlZFZpZXcuZ3JvdXBpbmdzLmZpbHRlcih0ID0+ICF0LmFnZ3JlZ2F0aW9uKS5sZW5ndGggOiAwO1xyXG5cclxuICAgICAgICAvL0dydXBwaSBpbnRlcm1lZGlcclxuICAgICAgICBpZiAoKGNhc3RlZFZpZXcucmVxdWVzdGVkZ3JvdXBzPy5sZW5ndGggIT0gZ3JvdXBLZXlzIHx8IGNhc3RlZFZpZXcucmVxdWVzdGVkZ3JvdXBzPy5sZW5ndGggPT0gMCkgJiYgZ3JvdXBLZXlzID4gMCkge1xyXG4gICAgICAgICAgICBsZXQgcmV0ID0gY2FzdGVkVmlldy5ncm91cHM7XHJcbiAgICAgICAgICAgIHJldC5mb3JFYWNoKGl0bSA9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gU2V0dG8gdmFyaWFiaWxlIGludGVybmEgcGVyIGNhcGlyZSBjaGUgcXVlc3RvIMOoIGluIHJlYWx0w6AgdW4gZ3J1cHBvXHJcbiAgICAgICAgICAgICAgICAoPGFueT5pdG0pLl9ncm91cCA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gTGUgaW5mb3JtYXppb25pIHBhc3NhdGUgY29tZSBsaXN0YSBsZSBtZXR0byBkZW50cm8gYSB1bmEgY2FjaGUgcGVyIHZlbG9jaXp6YXJuZSBsJ2FjY2Vzc28gcXVhbmRvIGRldm8gdGlyYXJlIGZ1b3JpIGlsIGRpc3BsYXkgZGVsbGEgcHJvcHJpZXTDoFxyXG4gICAgICAgICAgICAgICAgdGhpcy5jYWNoZUFnZ3JlZ2F0aW9ucyhpdG0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIHJldDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGxldCByZXQgPSB0aGlzLlNlY29uZGFyeVNvdXJjZSA/ICh0aGlzLlZpZXcgYXMgYW55KS5pdGVtczIgOiB0aGlzLlRlcnRpYXJ5U291cmNlID8gKHRoaXMuVmlldyBhcyBhbnkpLml0ZW1zMyA6ICh0aGlzLlZpZXcgYXMgYW55KS5pdGVtcztcclxuICAgICAgICAgICAgLy8gU2V0dG8gdmFyaWFiaWxlIGludGVybmEgcGVyIHNwZWNpZmljYXJlIGNoZSBxdWVzdG8gw6ggdW4gZWxlbWVudG8gbm9ybWFsZSwgbm9uIHVuIGdydXBwbyBvIGFsdHJvXHJcbiAgICAgICAgICAgIHJldC5mb3JFYWNoKGl0bSA9PiB7ICg8YW55Pml0bSkuX2l0ZW0gPSB0cnVlOyB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIHJldDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIZWxwZXIgcGVyIGVmZmV0dHVhcmUgaWwgY2FjaGluZyBkZWxsZSBhZ2dyZWdhemlvbmkuIExlIHNwb3N0YSBkYSB1bmEgbGlzdGEgZGkgKipHcm91cEFnZ3JlZ2F0aW9uKiogYSB1bmEgKio8TWFwPHN0cmluZywgTWFwPHN0cmluZywgc3RyaW5nPj4qKlxyXG4gICAgICogXHJcbiAgICAgKiBAdG9kbzogUk9XR1JPVVBJTkdcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBjYWNoZUFnZ3JlZ2F0aW9ucyhncm91cDogYW55KSB7XHJcbiAgICAgICAgKDxhbnk+Z3JvdXApLl9hZ2dyZWdhdGlvbnNDYWNoZSA9IG5ldyBNYXAoKTtcclxuICAgICAgICBsZXQgY2FzdGVkQWdDYWNoZSA9ICg8TWFwPHN0cmluZywgTWFwPHN0cmluZywgc3RyaW5nPj4+KDxhbnk+Z3JvdXApLl9hZ2dyZWdhdGlvbnNDYWNoZSk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncm91cC5hZ2dyZWdhdGlvbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IGFnZyA9IGdyb3VwLmFnZ3JlZ2F0aW9uc1tpXTtcclxuICAgICAgICAgICAgaWYgKGNhc3RlZEFnQ2FjaGUuaGFzKGFnZy5jb2x1bW4pKVxyXG4gICAgICAgICAgICAgICAgY2FzdGVkQWdDYWNoZS5nZXQoYWdnLmNvbHVtbikuc2V0KGFnZy5hZ2dyZWdhdGlvbiwgYWdnLnZhbHVlKTtcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgdG1wOiBNYXA8c3RyaW5nLCBzdHJpbmc+ID0gbmV3IE1hcCgpO1xyXG4gICAgICAgICAgICAgICAgdG1wLnNldChhZ2cuYWdncmVnYXRpb24sIGFnZy52YWx1ZSlcclxuICAgICAgICAgICAgICAgIGNhc3RlZEFnQ2FjaGUuc2V0KGFnZy5jb2x1bW4sIHRtcCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gY2hlIHByZW5kZSB0dXR0aSBnbGkgb2dnZXR0aSBkaSBjdWkgZGlzcG9uZSBkaXZpc2kgaW4gYnVja2V0IGRhIDEwMCBlbGVtZW50aVxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHthbnlbXVtdfSBNYXRyaWNlIGRpIGFycmF5IE54MTAwXHJcbiAgICAgKiBcclxuICAgICAqIEB0b2RvOiBJVEVNU1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldEl0ZW1TbGljZXMoKTogYW55W11bXSB7XHJcbiAgICAgICAgLy8gU2Ugc29ubyBxdWkgZGkgc2ljdXJvIG5vbiBobyByb3dncm91cGluZ1xyXG4gICAgICAgIGxldCBpdGVtcyA9IHRoaXMuZ2V0SXRlbXNCeU1vZGUoKTtcclxuICAgICAgICBpZiAoIWl0ZW1zKVxyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgbGV0IGFycmF5QnkxMDAgPSBbXTtcclxuXHJcbiAgICAgICAgbGV0IHNsaWNlcyA9IE1hdGguY2VpbChpdGVtcy5sZW5ndGggLyB0aGlzLlNsaWNlU2l6ZSk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGljZXM7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgYXJyYXlTbGljZSA9IGl0ZW1zLnNsaWNlKGkgKiB0aGlzLlNsaWNlU2l6ZSwgaSAqIHRoaXMuU2xpY2VTaXplICsgdGhpcy5TbGljZVNpemUpO1xyXG4gICAgICAgICAgICBhcnJheUJ5MTAwLnB1c2goYXJyYXlTbGljZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBhcnJheUJ5MTAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGNoZSBnZXN0aXNjZSBsJ2VuZGxlc3Mgc2Nyb2xsIGUgaW4gYmFzZSBhIHF1YW50byBsYSB0YWJlbGxhIMOoIHN0YXRhIHNjcm9sbGF0YSBhZ2dpdW5nZSBkZWdsaSBlbGVtZW50aSBleHRyYSBhICoqVE1QQm91bmRTb3VyY2UqKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55fSBlIEV2ZW50byBkaSBzY3JvbGwgZGVsIGJyb3dzZXJcclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uU2Nyb2xsKGU6IGFueSkge1xyXG4gICAgICAgIGxldCB0YWJsZVZpZXdIZWlnaHQgPSBlLnRhcmdldC5vZmZzZXRIZWlnaHQ7XHJcbiAgICAgICAgbGV0IHRhYmxlU2Nyb2xsSGVpZ2h0ID0gZS50YXJnZXQuc2Nyb2xsSGVpZ2h0O1xyXG4gICAgICAgIGxldCBzY3JvbGxMb2NhdGlvbiA9IGUudGFyZ2V0LnNjcm9sbFRvcDtcclxuICAgICAgICBsZXQgYnVmZmVyID0gMjAwO1xyXG5cclxuICAgICAgICBsZXQgbGltaXQgPSB0YWJsZVNjcm9sbEhlaWdodCAtIHRhYmxlVmlld0hlaWdodCAtIGJ1ZmZlcjtcclxuICAgICAgICBpZiAoc2Nyb2xsTG9jYXRpb24gPiBsaW1pdCkge1xyXG4gICAgICAgICAgICBsZXQgaW5kZXhUb0FkZCA9IE1hdGguZmxvb3IodGhpcy5UTVBCb3VuZFNvdXJjZS5sZW5ndGggLyAxMDApO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5ib3VuZFN1YlNvdXJjZXNbaW5kZXhUb0FkZF0gJiYgdGhpcy5hZGRlZFNsaWNlcy5pbmRleE9mKGluZGV4VG9BZGQpID09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBEZXZvIHJpY29yZGFybWkgZGkgZmFyZSBsJ2hhc2ggZGVsIG51b3ZvIHBlenpvXHJcbiAgICAgICAgICAgICAgICB0aGlzLmNhbGN1bGF0ZUhhc2godGhpcy5ib3VuZFN1YlNvdXJjZXNbaW5kZXhUb0FkZF0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5UTVBCb3VuZFNvdXJjZSA9IHRoaXMuVE1QQm91bmRTb3VyY2UuY29uY2F0KHRoaXMuYm91bmRTdWJTb3VyY2VzW2luZGV4VG9BZGRdKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuYWRkZWRTbGljZXMucHVzaChpbmRleFRvQWRkKTtcclxuXHJcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgdGhpcy5wb3N0Qm91bmRTb3VyY2VDYWxjdWxhdGlvbigpOyB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBsYW5jaWF0byBkb3BvIGNoZSBsYSBzb3JnZW50ZSBkYXRpIMOoIHN0YXRhIGNvcnJldHRhbWVudGUgYmluZGF0YSwgc2kgb2NjdXBhIGRpIHJpY2FsY29sYXJlIHR1dHRvIGNpw7IgY2hlIHNlcnZlXHJcbiAgICAgKiBhbGwnZXMtdGFibGUgcGVyIHJlbmRlcml6emFyZSBpIHZhbG9yaSBkYSBtb3N0cmFyZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHBvc3RCb3VuZFNvdXJjZUNhbGN1bGF0aW9uKCkge1xyXG4gICAgICAgIC8vIFJlc2V0dG8gdHV0dG8gdHJhbm5lIFJvd1REcyBlIFJvd1RIcyBwZXIgZXZpdGFyZSBmbGlja2VyaW5nLiBSb3dURHMgZSBSb3dUSHMgc2FyYW5ubyBtb2RpZmljYXRlIGFsbCdpbnRlcm5vIGRlbCBwcm9zc2ltbyBjaWNsbyBkaSBDRFxyXG4gICAgICAgIHRoaXMuUm93Q29udGV4dHMgPSBbXTtcclxuICAgICAgICB0aGlzLk9yZGVyRGlyZWN0aXZlcyA9IFtdO1xyXG4gICAgICAgIHRoaXMubGFzdFNlbGVjdGVkSXRlbUlEID0gbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuRXNUaHNEaXJlY3RpdmUgJiYgdGhpcy5Fc1Roc0RpcmVjdGl2ZS5sZW5ndGggPiAwICYmIHRoaXMuRXNUZHNEaXJlY3RpdmUgJiYgdGhpcy5Fc1Rkc0RpcmVjdGl2ZS5sZW5ndGggPiAwKVxyXG4gICAgICAgICAgICB0aGlzLmludGVybmFsUG9zdEJvdW5kU291cmNlKCk7XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IHRoaXMuaW50ZXJuYWxQb3N0Qm91bmRTb3VyY2UoKTsgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGVyIHBvdGVyIGRpc3Rpbmd1ZXJlIGxlIGNoaWFtYXRlIGEgcXVlc3RvIG1ldG9kbzogRG9wbyBpbCBzZXRUaW1lb3V0IHNlIHVzbyBnbGkgRXNUZC9Fc1RoIHZlY2NoaSwgc2VuemEgaWwgc2V0VGltZW91dCBzZSB1c28gbGUgbnVvdmUgZGlyZXR0aXZlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgaW50ZXJuYWxQb3N0Qm91bmRTb3VyY2UoKSB7XHJcbiAgICAgICAgbGV0IFZpZXcgPSB0aGlzLlZpZXc7XHJcbiAgICAgICAgbGV0IHRocyA9IHRoaXMuRXNUaHMgJiYgdGhpcy5Fc1Rocy5sZW5ndGggPiAwID8gdGhpcy5Fc1Rocy50b0FycmF5KCkgOiB0aGlzLkVzVGhzRGlyZWN0aXZlICYmIHRoaXMuRXNUaHNEaXJlY3RpdmUubGVuZ3RoID4gMCA/IHRoaXMuRXNUaHNEaXJlY3RpdmUudG9BcnJheSgpIDogW107XHJcbiAgICAgICAgbGV0IHRkcyA9IHRoaXMuRXNUZHMgJiYgdGhpcy5Fc1Rkcy5sZW5ndGggPiAwID8gdGhpcy5Fc1Rkcy50b0FycmF5KCkgOiB0aGlzLkVzVGRzRGlyZWN0aXZlICYmIHRoaXMuRXNUZHNEaXJlY3RpdmUubGVuZ3RoID4gMCA/IHRoaXMuRXNUZHNEaXJlY3RpdmUudG9BcnJheSgpIDogW107XHJcblxyXG4gICAgICAgIC8vIFNlIG5vbiBobyBjb2xvbm5lIGRpbmFtaWNoZSBtYSBzb25vIGluIG1vZGFsaXTDoCBkaW5hbWljYSAobG8gY2FwaXNjbyBwZXJjaMOpIGMnw6ggdW5hIHZpZXcgcGllbmEgZGkgZ2VuZXJpY2l0ZW0pIG1ldHRvIGlsIGRlZmF1bHQgZGVsbGUgY29sb25uZVxyXG4gICAgICAgIHRoaXMuZXZlbnR1YWxseVJldmlld0R5bmFtaWNDb2x1bW5zKCk7XHJcbiAgICAgICAgdGhpcy5iaW5kRGlzcGxheVRvTG9hZGVkSXRlbXNPckdyb3VwcyhWaWV3KTtcclxuXHJcbiAgICAgICAgLy8gUXVlc3RvIGRldidlc3NlcmUgcGVyIGZvcnphIGxhbmNpYXRvIGRvcG8gKipiaW5kRGlzcGxheVRvTG9hZGVkSXRlbXNPckdyb3VwcyoqIGRhdG8gY2hlIMOoIGzDrCBjaGUgYWxjdW5lIGNvc2UgdmVuZ29ubyB2YWxvcml6emF0ZVxyXG4gICAgICAgIHRoaXMuc2V0dXBQYWdpbmdJbmZvcm1hdGlvbnMoKTtcclxuXHJcbiAgICAgICAgLy8gTW9sdGUgY29zZSBzb25vIG92dmlhbWVudGUgZGlzcG9uaWJpbGkgc29sbyBpbiBtb2RhbGl0w6AgVmlld1xyXG4gICAgICAgIGlmICgodGhpcy52aWV3TW9kZSB8fCB0aGlzLmFycmF5TW9kZSkgJiYgdGhpcy5Vc2VDdXN0b21DZWxscykge1xyXG4gICAgICAgICAgICBsZXQgdmlldyA9IHRoaXMudmlld01vZGUgPyBWaWV3IGFzIEFwcFNlYXJjaDxhbnk+IDogbnVsbDtcclxuICAgICAgICAgICAgbGV0IGl0ZW1zQW5kR3JvdXBzID0gdGhpcy52aWV3TW9kZSA/IFsuLi4odmlldy5pdGVtcyB8fCBbXSksIC4uLih2aWV3Lmdyb3VwcyB8fCBbXSldIDogVmlldyBhcyBhbnlbXTtcclxuICAgICAgICAgICAgbGV0IHNpID0gdGhpcy52aWV3TW9kZSA/IHZpZXcuc2VsZWN0aW9uIDogdGhpcy5hcnJheW1vZGVTZWxlY3Rpb247XHJcbiAgICAgICAgICAgIC8vIE4uQjogUmlzcGV0dGFyZSBsJ29yZGluZSBkaSBxdWVzdGUgMyBtYWNyb2NhdGVnb3JpZSDDqCBWSVRBTEVcclxuXHJcbiAgICAgICAgICAgIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogICAgICAgIFNpc3RlbWF6aW9uaSBkaSBUSCwgVEQsIGUgdmlzaWJpbGl0w6AgdmFyaWUgICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcblxyXG4gICAgICAgICAgICBsZXQgaEkgPSB0aGlzLmV2YWx1YXRlSGVhZGVyc0dyb3VwaW5nSW5mb3ModGhzKTsgICAgICAgIC8vIFByZXBhc3NhZ2dpbyBwZXIgdGlyYXJlIGZ1b3JpIHR1dHRlIGxlIGluZm8gdXRpbGkgc3VnbGkgaGVhZGVycyBpbiBtb2RvIGRhIG5vbiByaWNhY29sYXJzZWxpIHNlbXByZSBkb3BvXHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5hcnJheU1vZGUpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluIG1vZGFsaXTDoCBhcnJheSBub24gaG8gdW4gYmFja2VuZC4uLlxyXG4gICAgICAgICAgICAgICAgdGhpcy5hcnJheU1vZGVSZXZpZXdPcmRlcmluZ3MoKSAgICAgICAgICAgICAgICAgICAgIC8vIC4uLiBxdWluZGkgZ2xpIG9yZGluYW1lbnRpIGxpIGRldm8gZmFyZSBsYXRvIGNsaWVudCwgZSAuLi5cclxuICAgICAgICAgICAgICAgIHRoaXMuYXJyYXlNb2RlUmV2aWV3R3JvdXBpbmdzKGhJLmxlYWZzKTsgICAgICAgICAgICAvLyAuLi4gaSByYWdncnVwcGFtZW50aSBsaSBkZXZvIGZhcmUgbGF0byBjbGllbnRcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5yZXZpZXdDb2x1bW5zTGlzdChoSS5sZWFmcyk7ICAgICAgICAgICAgICAgICAgICAgICAvLyBBZ2dpb3JuYSBsYSBsaXN0YSBkZWxsZSBjb2xvbm5lIGRhIG1vc3RyYXJlIG5lbGxhIGRpYWxvZyBwZXIgb3JkaW5hbWVudG8gZWNjXHJcbiAgICAgICAgICAgIHRoaXMubW92ZUZpeGVkQ29sdW1uc0F0VGhlQmVnaW5uaW5nKGhJLmxlYWZzLCB0ZHMpOyAgICAgLy8gU3Bvc3RvIHR1dHRlIGxlIGNvc2UgZml4ZWQgYWxsJ2luaXppbyBpbiBtb2RvIGNoZSBsYSBjcmVhemlvbmUgZGkgdGggZSB0ZCBzaWEgcGnDuSBzbmVsbGEgKFV0aWxpenphIGxlIENvbHVtbnNMaXN0LCBxdWluZGkgZGV2J2Vzc2VyZSByaWNoaWFtYXRhIFBJUk1BIGRpIHJldmlld0NvbHVtbnNMaXN0KVxyXG4gICAgICAgICAgICB0aGlzLmFsaWduSGVhZGVyc09yZGVyaW5nKGhJLmxlYWZzLCB2aWV3KTsgICAgICAgICAgICAgIC8vIEFsbGluZW8gZ2xpIG9yZGluYW1lbnRpIGFnbGkgaGVhZGVyXHJcbiAgICAgICAgICAgIHRoaXMuYWxpZ25Db2x1bW5zSWZMb2FkZWRWaWV3KHZpZXcpOyAgICAgICAgICAgICAgICAgICAgLy8gU2Ugc3RvIGNhcmljYW5kbyB1bmEgVmlldyBkYSBob3Rwb3RhdG8gKHF1aW5kaSBjb24gc2F2ZWRzdGF0ZSA9IHRydWUpIHJpYWxsaW5lbyBsYSB2aXNpYmlsaXTDoCBkZWxsZSBjb2xvbm5lIGUgaWwgbG9ybyBvcmRpbmUuXHJcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaENvbHVtbnNWaXNpYmlsaXR5KGhJLmxlYWZzLCB0ZHMsIHZpZXcpOyAgICAgLy8gTGF2b3JvIHN1aSBUSCBlZCBldmVudHVhbG1lbnRlIG1vZGlmaWNvIGxhIHZpc2liaWxpdMOgIGFuY2hlIGRlaSBURC5cclxuICAgICAgICAgICAgdGhpcy5ldmFsdWF0ZVBpbm5lZENvbHVtbnNXaWR0aCgpOyAgICAgICAgICAgICAgICAgICAgICAvLyBTZSBzb25vIHByZXNlbnRpIGNvbG9ubmUgcGlubmF0ZSB2YWx1dGEgbGEgZGltZW5zaW9uZSBkZWwgY29udGVuaXRvcmVcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhdGVEZWZhdWx0T3JkZXIoaEkubGVhZnMsIHZpZXcpOyAgICAgICAgICAgICAgLy8gR2VuZXJvIGxlIGRpcmV0dGl2ZSBkaSBvcmRpbmFtZW50bywgY2hlIHNpYW5vIGRlZmF1bHQgbyBkZXJpdmFudGkgZGFsbGEgQXBwU2VhcmNoXHJcbiAgICAgICAgICAgIHRoaXMuZXZhbHVhdGVIZWFkZXJHcm91cHMoaEkpOyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmFsdXRvIGkgcmFnZ3J1cHBhbWVudGkgZGVnbGkgaGVhZGVyIHNlIHByZXNlbnRpXHJcblxyXG4gICAgICAgICAgICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICAgICAgICBHZW5lcmF6aW9uZSBiaW5kaW5nIHBlciByaWdoZSBlIGNvbG9ubmUgICAgICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcblxyXG4gICAgICAgICAgICB0aGlzLmV2YWx1YXRlUm93VGhzKGhJLmxlYWZzKTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJhY2NvbGdvIGkgVEhcclxuICAgICAgICAgICAgdGhpcy5ldmFsdWF0ZVJvd1RkcyhoSS5sZWFmcywgdGRzKTsgICAgICAgICAgICAgICAgICAgICAvLyBSYWNjb2xnbyBpIFREIGluIGNvbnRlc3RpIHNlcGFyYXRpLCB1biBjb250ZXN0byBwZXIgb2duaSBpdGVtIG8gZ3J1cHBvXHJcblxyXG4gICAgICAgICAgICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICAgICAgICBVbHRpbWkgYWdnaXVzdG1hZW50aSBkZWkgYmluZGluZyAgICAgICAgICAgICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcblxyXG4gICAgICAgICAgICB0aGlzLmFwcGx5T3JkZXJpbmcodmlldywgdHJ1ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFwcGxpY28gbCdvcmRpbmFtZW50byBzdWxsZSBjb2xvbm5lIChub24gQVNDIERFU0MsIG1hIFwicHJpbWEgcXVlc3RhIG8gcXVlbGxhIGNvbG9ubmFcIilcclxuICAgICAgICAgICAgdGhpcy5Nb3ZlVGVtcG9yYXJ5VmFyaWFibGVzVG9SZWFsT25lcygpOyAgICAgICAgICAgICAgICAvLyBDb2xsZWdvIFRIIGUgVEQgYWdnaXVzdGF0aSBmaW5vIGFkIG9yYSBhbGxlIHZhcmlhYmlsaSBkaSBCaW5kaW5nIEhUTUxcclxuICAgICAgICAgICAgdGhpcy5ldmFsdWF0ZVNlbGVjdGlvbihpdGVtc0FuZEdyb3Vwcywgc2kpOyAgICAgICAgICAgICAvLyBSaWFsbGluZW8gbGUgaW5mbyBkaSBzZWxlemlvbmUgZGVnbGkgZWxlbWVudGkgZGVsbGEgVmlld1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuUmVzZWFyY2hOZWVkZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0U2VhcmNoUmVxdWVzdChmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLlJlc2VhcmNoTmVlZGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoKHRoaXMudmlld01vZGUgfHwgdGhpcy5hcnJheU1vZGUpICYmICF0aGlzLlVzZUN1c3RvbUNlbGxzKSB7XHJcbiAgICAgICAgICAgIC8vIFJpYWxsaW5lbyBsZSBpbmZvIGRpIHNlbGV6aW9uZSBkZWdsaSBlbGVtZW50aSBkZWxsYSBWaWV3XHJcbiAgICAgICAgICAgIGxldCBpdGVtcyA9IHRoaXMudmlld01vZGUgPyAoVmlldyBhcyBBcHBTZWFyY2g8YW55PikuaXRlbXMgOiBWaWV3IGFzIGFueVtdO1xyXG4gICAgICAgICAgICBsZXQgc2kgPSB0aGlzLnZpZXdNb2RlID8gKFZpZXcgYXMgQXBwU2VhcmNoPGFueT4pLnNlbGVjdGlvbiA6IHRoaXMuYXJyYXltb2RlU2VsZWN0aW9uO1xyXG4gICAgICAgICAgICB0aGlzLmV2YWx1YXRlU2VsZWN0aW9uKGl0ZW1zLCBzaSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBQZXIgZXNzZXJlIHNpY3VybyBjaGUgZG9wbyB1biBiaW5kIGRpIG9nZ2V0dGkgbGEgZXMtdGFibGUgYWdnaW9ybmkgbGEgZ3JhZmljYVxyXG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICAgIHRoaXMuRmlyc3RCaW5kID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZSBpbiBtb2RhbGl0w6AgYXJyYXkgYXBwbGljYSBnbGkgb3JkaW5hbWVudGkgQVNDLURFU0MgZGVsbGUgY29sb25uZVxyXG4gICAgICogXHJcbiAgICAgKiBAdG9kbzogSU5URVJOQUxEQlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGFycmF5TW9kZVJldmlld09yZGVyaW5ncygpIHtcclxuICAgICAgICBpZiAodGhpcy5hcnJheU9yZGVycy5sZW5ndGggPiAwKVxyXG4gICAgICAgICAgICB0aGlzLmFycmF5T3JkZXJzLmZvckVhY2godCA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmJvdW5kU291cmNlID0gdGhpcy5ib3VuZFNvdXJjZS5zb3J0KChhLCBiKSA9PiAoYVt0LmlkXSA+IGJbdC5pZF0gPyAxIDogLTEpICogKHQub3JkZXIgPT0gJ0RFU0MnID8gLTEgOiAxKSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2UgaW4gbW9kYWxpdMOgIGFycmF5IGFwcGxpY2EgaSByYWdncnVwcGFtZW50aSBkZWZpbml0aSBsYXRvIHJvdy1ncm91cGluZ1xyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3RoczogRXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdfSB0aHMgSGVhZGVyXHJcbiAgICAgKiBcclxuICAgICAqIEB0b2RvOiBST1cgR1JPVVBJTkdcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBhcnJheU1vZGVSZXZpZXdHcm91cGluZ3ModGhzOiBFc1RoW10gfCBFc1RoRGlyZWN0aXZlW10pIHtcclxuICAgICAgICBpZiAodGhzLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmlzRXNUaCh0aHNbMF0pKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGxldCBoZWFkZXJHcm91cHM6IEdyb3VwW10gPSBbXTtcclxuICAgICAgICBsZXQgaGVhZGVyQWdncmVnYXRpb25zOiBHcm91cE9yQWdncmVnYXRpb25bXSA9IFtdO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV0gYXMgRXNUaERpcmVjdGl2ZTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aC50aEdyb3VwKVxyXG4gICAgICAgICAgICAgICAgaGVhZGVyR3JvdXBzLnB1c2gobmV3IEdyb3VwKHRoLnRoLCAwLCBcIlwiKSk7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHRoLnRoQWdncmVnYXRpb24pXHJcbiAgICAgICAgICAgICAgICBoZWFkZXJBZ2dyZWdhdGlvbnMgPSBbLi4uaGVhZGVyQWdncmVnYXRpb25zLCAuLi50aGlzLmdldEdyb3VwQWdncmVnYXRpb25zKHRoKV07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoaGVhZGVyR3JvdXBzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgLy8gUHVsaXppYSBkZWxsZSBjYWNoZVxyXG4gICAgICAgICAgICB0aGlzLnJnR3JvdXBDYWNoZS5jbGVhcigpO1xyXG4gICAgICAgICAgICB0aGlzLnJnSXRlbUNhY2hlLmNsZWFyKCk7XHJcbiAgICAgICAgICAgIHRoaXMucmdDaGlsZEdyb3Vwc0NhY2hlLmNsZWFyKCk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLkFycmF5R3JvdXBpbmcgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLmJvdW5kU291cmNlID0gdGhpcy5nZXRHcm91cHNSZWN1cnNpdmUoaGVhZGVyR3JvdXBzLCAwLCB0aGlzLmJvdW5kU291cmNlLCBoZWFkZXJBZ2dyZWdhdGlvbnMsIG51bGwpXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGF0YSBsYSBkZWZpbml6aW9uZSBkZWkgZ3J1cHBpIGRhIGdlbmVyYXJlIGRhIHVuYSBsaXN0YSBkaSBvZ2dldHRpLCBzdWRkaXZpZGUgZ2xpIG9nZ2V0dGkgcGFzc2F0aSBpbiBncnVwcGkgZSBzb3R0b2dydXBwaVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0dyb3VwW119IGdycHMgRGVmaW5pemlvbmUgZGVpIGdydXBwaVxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGN1cnJlbnRJbmRleCBJbmRpY2UgZGkgZWxhYm9yYXppb25lLiBBbCBsaXZlbGxvIDAgaG8gdHV0dGkgZ2xpIG9nZ2V0dGkgZSBkZXZvIGdlbmVyYXJlIGkgcHJpbWkgZ3J1cHBpLCBhIGxpdmVsbG8gMSBobyB0dXR0aSBpIGdydXBwaSBwcmluY2lwYWxpIGUgZGV2b1xyXG4gICAgICogZWxhYm9yYXJlIGkgc290dG9ncnVwcGksIGUgY29zw6wgdmlhIHJpY29yc2l2YW1lbnRlLi4uXHJcbiAgICAgKiBAcGFyYW0ge2FueVtdfSBpdGVtcyBPZ2dldHRpIGRhIHJhZ2dydXBwYXJlXHJcbiAgICAgKiBAcGFyYW0ge0dyb3VwT3JBZ2dyZWdhdGlvbltdfSBhZ2dyZWdhdGlvbnMgSW5mbyBkaSBhZ2dyZWdhemlvbmVcclxuICAgICAqIEBwYXJhbSB7YW55fSBwYXJlbnQgUmlmZXJpbWVudG8gYWwgZ3J1cHBvIHBhZHJlXHJcbiAgICAgKiBcclxuICAgICAqIEB0b2RvOiBJTlRFUk5BTERCXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0R3JvdXBzUmVjdXJzaXZlKGdycHM6IEdyb3VwW10sIGN1cnJlbnRJbmRleDogbnVtYmVyLCBpdGVtczogYW55W10sIGFnZ3JlZ2F0aW9uczogR3JvdXBPckFnZ3JlZ2F0aW9uW10sIHBhcmVudD86IGFueSk6IGFueVtdIHtcclxuICAgICAgICAvLyBTZSBsJ2luZGljZSDDqCAwIGRldm8gc2ljdXJhbWVudGUgbmFzY29uZGVyZSB0dXR0aSBnbGkgb2dnZXR0aS4gU29sbyBpIGdydXBwaSBzYXJhbm5vIHZpc3VhbGl6emF0aVxyXG4gICAgICAgIGlmIChjdXJyZW50SW5kZXggPT0gMClcclxuICAgICAgICAgICAgaXRlbXMuZm9yRWFjaChpID0+IGkuX3Zpc2libGUgPSBmYWxzZSk7XHJcblxyXG4gICAgICAgIGxldCBncnAgPSBncnBzW2N1cnJlbnRJbmRleF07XHJcbiAgICAgICAgbGV0IHJldDogYW55W10gPSBbXTtcclxuICAgICAgICBsZXQgbGFzdCA9IGdycHMubGVuZ3RoID09IGN1cnJlbnRJbmRleCArIDE7XHJcbiAgICAgICAgbGV0IGdyb3VwcyA9IHRoaXMuZ3JvdXBCeShpdGVtcywgZ3JwLmNvbHVtbik7XHJcbiAgICAgICAgZm9yIChsZXQgcHJvcCBpbiBncm91cHMpIHtcclxuICAgICAgICAgICAgbGV0IGl0bXMgPSBncm91cHNbcHJvcF07XHJcbiAgICAgICAgICAgIGxldCBncCA9IG5ldyBHcm91cChncnAuY29sdW1uLCBpdG1zLmxlbmd0aCwgcHJvcCk7XHJcbiAgICAgICAgICAgIGdwLmFnZ3JlZ2F0aW9ucyA9IHRoaXMuZ2VuZXJhdGVBZ2dyZWdhdGlvbnMoaXRtcywgYWdncmVnYXRpb25zKTtcclxuXHJcbiAgICAgICAgICAgIGxldCBhbnlncCA9ICg8YW55PmdwKTtcclxuICAgICAgICAgICAgYW55Z3AuX2dyb3VwID0gdHJ1ZTtcclxuICAgICAgICAgICAgYW55Z3AuX2V4cGFuZGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGlmICghcGFyZW50KSB7XHJcbiAgICAgICAgICAgICAgICBhbnlncC5fdGhpc1JvdXRlID0gW3sgY29sdW1uOiBncC5jb2x1bW4sIHZhbHVlOiBncC52YWx1ZSB9XTtcclxuICAgICAgICAgICAgICAgIGFueWdwLl90aGlzS2V5ID0gZ3AudmFsdWU7XHJcbiAgICAgICAgICAgICAgICBhbnlncC5fZ3JvdXBsZXZlbCA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBhbnlncC5fcGFyZW50ID0gcGFyZW50Ll90aGlzS2V5O1xyXG4gICAgICAgICAgICAgICAgYW55Z3AuX3BhcmVudFJvdXRlID0gcGFyZW50Ll90aGlzUm91dGU7XHJcbiAgICAgICAgICAgICAgICBhbnlncC5fdGhpc1JvdXRlID0gWy4uLnBhcmVudC5fdGhpc1JvdXRlLCB7IGNvbHVtbjogZ3AuY29sdW1uLCB2YWx1ZTogZ3AudmFsdWUgfV07XHJcbiAgICAgICAgICAgICAgICBhbnlncC5fdGhpc0tleSA9IHBhcmVudC5fdGhpc0tleSArIGdwLnZhbHVlO1xyXG4gICAgICAgICAgICAgICAgYW55Z3AuX2dyb3VwbGV2ZWwgPSBwYXJlbnQuX2dyb3VwbGV2ZWwgKyAxO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBQdXNobyBpbCBncnVwcG8sIHR1dHRpIGkgZ3J1cHBpIGRlbCBsaXZlbGxvIHNvdHRvLCBvIGdsaSBpdGVtIHNlIGlvIHNvbm8gbCd1bHRpbW8gZ3J1cHBvLiBcclxuICAgICAgICAgICAgLy8gTGEgdmlzaWJpbGl0w6Agw6ggc29sbyBwZXIgaWwgZ3J1cHBvIGEgbGl2ZWxsbyAwLCB0dXR0aSBnbGkgYWx0cmkgZ3J1cHBpIHNhcmFubm8gbW9zdHJhdGkgbyBuYXNjb3N0aSBkaSBjb25zZWd1ZW56YVxyXG5cclxuICAgICAgICAgICAgaWYgKGN1cnJlbnRJbmRleCA9PSAwKVxyXG4gICAgICAgICAgICAgICAgYW55Z3AuX3Zpc2libGUgPSB0cnVlO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgdGhpcy5jYWxjdWxhdGVIYXNoKFthbnlncF0pO1xyXG4gICAgICAgICAgICB0aGlzLmNhY2hlQWdncmVnYXRpb25zKGFueWdwKTtcclxuXHJcbiAgICAgICAgICAgIC8vIEFnZ2l1bmdvIGlsIGdydXBwbyBwYWRyZVxyXG4gICAgICAgICAgICByZXQucHVzaChhbnlncCk7XHJcbiAgICAgICAgICAgIHRoaXMucmdHcm91cENhY2hlLnNldChhbnlncC5fdGhpc0tleSwgYW55Z3ApO1xyXG4gICAgICAgICAgICBpZiAoIWxhc3QpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvL0RhbCBncnVwcG8gcGFkcmUsIHNlIG5vbiDDqCBsJ3VsdGltbyBncnVwcG8gZGVsbGEgY2F0ZW5hLCBjYWxjb2xvIHJpY29yc2l2YW1lbnRlIHR1dHRhIGxhIGNhdGVuYSBzb3R0b1xyXG4gICAgICAgICAgICAgICAgbGV0IHN1Ykdyb3Vwc0FuZEl0ZW1zID0gdGhpcy5nZXRHcm91cHNSZWN1cnNpdmUoZ3JwcywgY3VycmVudEluZGV4ICsgMSwgaXRtcywgYWdncmVnYXRpb25zLCBhbnlncCk7XHJcbiAgICAgICAgICAgICAgICBsZXQgY2hpbGRncm91cHMgPSBzdWJHcm91cHNBbmRJdGVtcy5maWx0ZXIodCA9PiB0Ll9ncm91cCAmJiB0Ll9wYXJlbnQgPT0gYW55Z3AuX3RoaXNLZXkpO1xyXG4gICAgICAgICAgICAgICAgYW55Z3AuX2dyb3Vwc2NvdW50ID0gY2hpbGRncm91cHMubGVuZ3RoO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIEFnZ2l1bmdvIGxhIGNhdGVuYSBkZWwgZ3J1cHBvIHNvdHRvLCBhZ2dpdW5nZW5kbyBhbGxhIGNhY2hlIHNvbG8gaSBncnVwcGkgcGFkcmVcclxuICAgICAgICAgICAgICAgIHJldC5wdXNoKC4uLnN1Ykdyb3Vwc0FuZEl0ZW1zKTtcclxuICAgICAgICAgICAgICAgIHRoaXMucmdDaGlsZEdyb3Vwc0NhY2hlLnNldChhbnlncC5fdGhpc0tleSwgY2hpbGRncm91cHMpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gQWwgZ3J1cHBvIHBhZHJlLCBzZSDDqCBsJ3VsdGltbyBhc3NlZ25vIHR1dHRlIGxlIGZvZ2xpZSBhc3NlZ25hbmRvZ2xpIGFuY2hlIGxhIGNoaWF2ZSBkZWwgZ3J1cHBvXHJcbiAgICAgICAgICAgICAgICBpdG1zLmZvckVhY2goaSA9PiBpLl90aGlzS2V5ID0gYW55Z3AuX3RoaXNLZXkpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldC5wdXNoKC4uLml0bXMpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5yZ0l0ZW1DYWNoZS5zZXQoYW55Z3AuX3RoaXNLZXksIGl0bXMpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEYXRhIHVuYSBsaXN0YSBkaSBvZ2dldHRpIGdlbmVyYSBsZSBhZ2dyZWdhemlvbmkgc3BlY2lmaWNhdGUuIFNpIGNvbnNpZGVyYSBkaSBhdmVyZSB0dXR0aSBnbGkgb2dnZXR0aVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge2FueVtdfSBpdGVtcyBPZ2dldHRpIGRpIGN1aSBjYWxjb2xhcmUgbGUgYWdncmVnYXppb25lXHJcbiAgICAgKiBAcGFyYW0ge0dyb3VwT3JBZ2dyZWdhdGlvbltdfSBhZ2dyZWdhdGlvbnMgQWdnZXJnYXppb25pIGRhIGdlbmVyYXJlXHJcbiAgICAgKiBcclxuICAgICAqIEB0b2RvOiBJTlRFUk5BTERCXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2VuZXJhdGVBZ2dyZWdhdGlvbnMoaXRlbXM6IGFueVtdLCBhZ2dyZWdhdGlvbnM6IEdyb3VwT3JBZ2dyZWdhdGlvbltdKTogR3JvdXBBZ2dyZWdhdGlvbltdIHtcclxuICAgICAgICBsZXQgcmV0czogR3JvdXBBZ2dyZWdhdGlvbltdID0gW11cclxuICAgICAgICBsZXQgYWdncmVnYXRpb25WYWx1ZSA9IFwiXCIsIGZlRmllbGQgPSBudWxsLCBzdHJpbmdBZ2cgPSBudWxsLCBkYXRlQWdnID0gbnVsbCwgbnVtYmVyQWdnID0gbnVsbDtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhZ2dyZWdhdGlvbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IGFnZyA9IGFnZ3JlZ2F0aW9uc1tpXTtcclxuICAgICAgICAgICAgZmVGaWVsZCA9IGFnZy5jb2x1bW47XHJcbiAgICAgICAgICAgIGlmICghZmVGaWVsZClcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgc3dpdGNoIChhZ2cuZGF0YXR5cGUpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgJ3N0cmluZyc6IHN0cmluZ0FnZyA9IGl0ZW1zLm1hcChpID0+IGlbZmVGaWVsZF0udG9TdHJpbmcoKSk7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnZGF0ZSc6IGRhdGVBZ2cgPSBpdGVtcy5tYXAoaSA9PiBuZXcgRGF0ZShpW2ZlRmllbGRdKS5nZXRUaW1lKCkpOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJ251bWJlcic6IG51bWJlckFnZyA9IGl0ZW1zLm1hcChpID0+IHBhcnNlRmxvYXQoaVtmZUZpZWxkXSkpOyBicmVhaztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgc3dpdGNoIChhZ2cuYWdncmVnYXRpb24pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgJ21heCc6XHJcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChhZ2cuZGF0YXR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnc3RyaW5nJzogYWdncmVnYXRpb25WYWx1ZSA9IHN0cmluZ0FnZy5zb3J0KCkucmV2ZXJzZSgpWzBdOyBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnZGF0ZSc6IGFnZ3JlZ2F0aW9uVmFsdWUgPSBuZXcgRGF0ZShNYXRoLm1heCguLi5kYXRlQWdnKSkudG9TdHJpbmcoKTsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ251bWJlcic6IGFnZ3JlZ2F0aW9uVmFsdWUgPSBNYXRoLm1heCguLi5udW1iZXJBZ2cpLnRvU3RyaW5nKCk7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJ21pbic6XHJcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChhZ2cuZGF0YXR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnc3RyaW5nJzogYWdncmVnYXRpb25WYWx1ZSA9IHN0cmluZ0FnZy5zb3J0KClbMF07IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdkYXRlJzogYWdncmVnYXRpb25WYWx1ZSA9IG5ldyBEYXRlKE1hdGgubWluKC4uLmRhdGVBZ2cpKS50b1N0cmluZygpOyBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnbnVtYmVyJzogYWdncmVnYXRpb25WYWx1ZSA9IE1hdGgubWluKC4uLm51bWJlckFnZykudG9TdHJpbmcoKTsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnc3VtJzpcclxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGFnZy5kYXRhdHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdzdHJpbmcnOiBhZ2dyZWdhdGlvblZhbHVlID0gc3RyaW5nQWdnLmpvaW4oXCIsIFwiKTsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2RhdGUnOiBhZ2dyZWdhdGlvblZhbHVlID0gXCJcIjsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ251bWJlcic6IGFnZ3JlZ2F0aW9uVmFsdWUgPSBudW1iZXJBZ2cucmVkdWNlKChwcmUsIGN1cnIpID0+IHByZSArIGN1cnIsIDApLnRvU3RyaW5nKCk7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXRzLnB1c2gobmV3IEdyb3VwQWdncmVnYXRpb24oYWdnLmNvbHVtbiwgYWdnLmFnZ3JlZ2F0aW9uLCBhZ2dyZWdhdGlvblZhbHVlKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcmV0cztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERhdGEgdW5hIGxpc3RhIGRpIG9nZ2V0dGkgZWZmZXR0dWEgZGVpIHJhZ2dydXBwYW1lbnRpIGluIGJhc2UgYWxsYSBwcm9wcmlldMOgICoqZmllbGQqKiwgcmVzdGl0dWVuZG8gdW4gb2dnZXR0byBkZWwgdGlwbyB7IEdydXBwbzE6IG9nZ2V0dGlbXSwgR3J1cHBvMjogb2dnZXR0aVtdLCBlY2MuLi4gfVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge2FueVtdfSBhcnJheSBMaXN0YSBkZWdsaSBvZ2dldHRpIGRhIHJhZ2dydXBwYXJlXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZmllbGQgQ2FtcG8gc3UgY3VpIGVmZmV0dHVhcmUgaSByYWdncnVwcGFtZW50aVxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7eyBbaWQ6IHN0cmluZ106IGFueVtdIH19IERpemlvbmFyaW8gZGVpIGdydXBwaVxyXG4gICAgICogXHJcbiAgICAgKiBAdG9kbzogSU5URVJOQUxEQlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdyb3VwQnkoYXJyYXk6IGFueVtdLCBmaWVsZDogc3RyaW5nKTogeyBbaWQ6IHN0cmluZ106IGFueVtdIH0ge1xyXG4gICAgICAgIGxldCByZXQgPSB7fTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB4ID0gYXJyYXlbaV07XHJcbiAgICAgICAgICAgIChyZXRbeFtmaWVsZF1dID0gcmV0W3hbZmllbGRdXSB8fCBbXSkucHVzaCh4KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJldDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFZmZldHR1YSBpbCBiaW5kaW5nIGRlZ2xpIG9nZ2V0dGkgcGVydmVudXRpIGRhIHF1ZXN0YSBjaGlhbWF0YSBjb24gZ2xpIG9nZ2V0dGkgZWZmZXR0aXZhbWVudGUgZGEgZ3JhZmljYXJlXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55fSB2aWV3IFZpZXcgZGEgY3VpIHNvbm8gYXJyaXZhdGkgZ2xpIG9nZ2V0dGkuIFB1w7IgZXNzZXJlIG8gdW4gYXJyYXkgc2Ugc29ubyBpbiAqKmFycmF5TW9kZSoqIG8gdW5hIEFwcFNlYXJjaDxUPiBzZSBzb25vIGluICoqdmlld01vZGUqKlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGJpbmREaXNwbGF5VG9Mb2FkZWRJdGVtc09yR3JvdXBzKHZpZXc6IGFueSkge1xyXG4gICAgICAgIGlmICh0aGlzLlRNUEJvdW5kU291cmNlLmxlbmd0aCA9PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuQmFzZUl0ZW1zQ291bnQgPSAwO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5hcnJheU1vZGUgfHwgIXRoaXMuVXNlQ3VzdG9tQ2VsbHMpIHtcclxuICAgICAgICAgICAgdGhpcy5ib3VuZFNvdXJjZSA9IHRoaXMuVE1QQm91bmRTb3VyY2U7XHJcbiAgICAgICAgICAgIHRoaXMuQmFzZUl0ZW1zQ291bnQgPSB2aWV3Py5vYmplY3Rjb3VudCB8fCB2aWV3Lmxlbmd0aDtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGdyb3VwaW5nS2V5cyA9IHZpZXcuZ3JvdXBpbmdzPy5maWx0ZXIodCA9PiAhdC5hZ2dyZWdhdGlvbik/Lmxlbmd0aCB8fCAwO1xyXG4gICAgICAgIGlmIChncm91cGluZ0tleXMgPT0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLmJvdW5kU291cmNlID0gdGhpcy5UTVBCb3VuZFNvdXJjZTtcclxuICAgICAgICAgICAgdGhpcy5CYXNlSXRlbXNDb3VudCA9IHZpZXcub2JqZWN0Y291bnQ7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuaGFuZGxlTmV3RGF0YU9uUm93R3JvdXBpbmcodmlldywgZ3JvdXBpbmdLZXlzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEluIG1vZGFsaXTDoCByb3dncm91cGluZyBxdWFuZG8gbWkgYXJyaXZhIHVuIG51b3ZvIGJsb2NjbyBkaSBvZ2dldHRpIGRldm8gYWdnaXVuZ2VybG8gYWxsYSB2aXN0YSBhdHR1YWxlOlxyXG4gICAgICogXHJcbiAgICAgKiAxKSBTZSBub24gdmllbmUgcmljaGllc3RvIGlsIGRldHRhZ2xpbyBkaSBhbGN1biBncnVwcG8gc2lnbmlmaWNhIGNoZSBkZXZvIGNvbnNpZGVyYXJlIG1pIHNpYW5vIGFycml2YXRpIHR1dHRpIGkgZ3J1cHBpIHByaW5jaXBhbGlcclxuICAgICAqIDIpIFNlIHZpZW5lIHJpY2hpZXN0byBpbCBkZXR0YWdsaW8gZGkgdW4gZ3J1cHBvIGRpdmVyc28gZGFsbCd1bHRpbW8gZGV2byBhZ2dpdW5nZXJlIGRvcG8gYWwgZ3J1cHBvIGNsaWNjYXRvIGxhIGxpc3RhIGRlaSBzb3R0b2dydXBwaVxyXG4gICAgICogMikgU2UgdmllbmUgcmljaGllc3RvIGlsIGRldHRhZ2xpbyBkZWxsJ3VsdGltbyBncnVwcG8gZGV2byBhZ2dpdW5nZXJlIGRvcG8gYWwgZ3J1cHBvIGNsaWNjYXRvIGxhIGxpc3RhIGRlZ2xpIG9nZ2V0dGlcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IHZpZXcgQXBwU2VhcmNoPFQ+IGRhIGN1aSBzb25vIGFycml2YXRpIGdsaSBvZ2dldHRpXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZ3JvdXBpbmdLZXlzIExpdmVsbGkgZGkgcmFnZ3J1cHBhbWVudG8gZGEgYXNwZXR0YXJzaSBzdWkgZGF0aVxyXG4gICAgICogXHJcbiAgICAgKiBAdG9kbzogUk9XR1JPVVBJTkdcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBoYW5kbGVOZXdEYXRhT25Sb3dHcm91cGluZyh2aWV3OiBBcHBTZWFyY2g8YW55PiwgZ3JvdXBpbmdLZXlzOiBudW1iZXIpe1xyXG4gICAgICAgIC8vIDEpIFNlIG5vbiB2aWVuZSByaWNoaWVzdG8gaWwgZGV0dGFnbGlvIGRpIGFsY3VuIGdydXBwbyBzaWduaWZpY2EgY2hlIGxhIGNoaWFtYXRhIHJlc3RpdHVpc2NlIGxhIGxpc3RhIHBhZ2luYXRhIGRlaSBncnVwcGkgcHJpbmNpcGFsaS5cclxuICAgICAgICAvLyAgICBMaSB0cmF0dG8gY29tZSBzZSBmb3NzZSB1bmEgcXVhbHNpYXNpIGFsdHJhIHF1ZXJ5IHBhZ2luYXRhIHN1IE4gZWxlbWVudGlcclxuICAgICAgICBpZiAoKHZpZXcucmVxdWVzdGVkZ3JvdXBzPy5sZW5ndGggfHwgMCkgPT0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLmJvdW5kU291cmNlID0gdGhpcy5UTVBCb3VuZFNvdXJjZTtcclxuICAgICAgICAgICAgdGhpcy5yZ0dyb3VwQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgR3JvdXA+KCk7XHJcbiAgICAgICAgICAgIHRoaXMucmdJdGVtQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgYW55W10+KCk7XHJcbiAgICAgICAgICAgIHRoaXMucmdDaGlsZEdyb3Vwc0NhY2hlID0gbmV3IE1hcDxzdHJpbmcsIEdyb3VwW10+KCk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLlRNUEJvdW5kU291cmNlLmZvckVhY2goaXRtID0+IHtcclxuICAgICAgICAgICAgICAgIGl0bS5fdGhpc1JvdXRlID0gaXRtLl9ncm91cCA/IFt7IGNvbHVtbjogKDxHcm91cD5pdG0pLmNvbHVtbiwgdmFsdWU6ICg8R3JvdXA+aXRtKS52YWx1ZSB9XSA6IFtdO1xyXG4gICAgICAgICAgICAgICAgaXRtLl90aGlzS2V5ID0gaXRtLl9ncm91cCA/ICg8R3JvdXA+aXRtKS52YWx1ZSA6IG51bGw7XHJcbiAgICAgICAgICAgICAgICBpdG0uX2dyb3VwbGV2ZWwgPSAwO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMucmdHcm91cENhY2hlLnNldChpdG0uX3RoaXNLZXksIGl0bSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgLy8gUmVzZXR0byBsYSByaWNlcmNhIGFsbGEgY2FjaGUgZGkgcXVlc3RhIFwic2Vzc2lvbmVcIlxyXG4gICAgICAgICAgICBsZXQgZmlyc3RJdGVtID0gdGhpcy5UTVBCb3VuZFNvdXJjZVswXTtcclxuICAgICAgICAgICAgdGhpcy5NYWluR3JvdXBWaWV3ID0gT2JqZWN0LmFzc2lnbih7fSwgdmlldyk7XHJcbiAgICAgICAgICAgIHRoaXMuZ3JvdXBTZWFyY2hSZXF1ZXN0c0NhY2hlID0gW3sgcGF0aDogJycsIHJvdXRlOiBbeyBjb2x1bW46ICg8R3JvdXA+Zmlyc3RJdGVtKS5jb2x1bW4sIHZhbHVlOiAoPEdyb3VwPmZpcnN0SXRlbSkudmFsdWUgfV0sIHZpZXc6IHRoaXMuTWFpbkdyb3VwVmlldywgZ3JvdXBfY29sdW1uOiAoPEdyb3VwPnRoaXMuVE1QQm91bmRTb3VyY2VbMF0pLmNvbHVtbiB9XTtcclxuICAgICAgICAgICAgdGhpcy5CYXNlSXRlbXNDb3VudCA9IHZpZXcub2JqZWN0Y291bnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyAyKSBTZSB2aWVuZSByaWNoaWVzdG8gaWwgZGV0dGFnbGlvIGRpIHVuIHF1YWxzaWFzaSBncnVwcG8gZGl2ZXJzbyBkYWxsJ3VsdGltbyB2dW9sIGRpcmUgY2hlIGRldm8gYWdnaXVuZ2VyZSBcclxuICAgICAgICAgICAgLy8gICAgZG9wbyBhbCBncnVwcG8gY2hlIGhvIGNsaWNjYXRvIGxhIGxpc3RhIGRlaSBncnVwcGkgdGlyYXRhIGZ1b3JpIHF1ZXN0YSB2b2x0YSAoaW50ZXJtZWRpYXRlR3JvdXAgPSB0cnVlKVxyXG4gICAgICAgICAgICAvKlxyXG4gICAgICAgICAgICAqICAgR3J1cHBvQSAgICAgICAgICAgICAgICAgICAgICBHcnVwcG9BXHJcbiAgICAgICAgICAgICogICBHcnVwcG9CICAgICAgICAgICAgICAgICAgICAgIEdydXBwb0JcclxuICAgICAgICAgICAgKiAgIEdydXBwb0MgPC0gQ2xpY2NvIHF1aSAgICAgICAgR3J1cHBvQ1xyXG4gICAgICAgICAgICAqICAgR3J1cHBvRCAgICAgICAgICAgICAgICAgICAgICAgICAgR3J1cHBvQzFcclxuICAgICAgICAgICAgKiAgIEdydXBwb0UgICAgICAgICAgICAgICAgICAgICAgICAgIEdydXBwb0MyXHJcbiAgICAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdydXBwb0RcclxuICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR3J1cHBvRVxyXG4gICAgICAgICAgICAqL1xyXG5cclxuICAgICAgICAgICAgLy8gMykgc2UgaSBncnVwcGkgcmljaGllc3RpIGRhbGxhIHZpZXcgc29ubyB1Z3VhbGkgYWkgZ3J1cHBpIHByZXNlbnRpIHZ1b2wgZGlyZSBjaGUgc3RvIHByZW5kZW5kbyBnbGkgb2dnZXR0aSB2ZXJpIGUgcHJvcHJpLCBzb25vIGluIFxyXG4gICAgICAgICAgICAvLyB2aWV3Lml0ZW1zIGUgcXVpbmRpIGluIFRNUEJvdW5kU291cmNlLCBobyBpbm9sdHJlIGxlIGluZm9ybWF6aW9uaSBkaSBwYWdpbmF6aW9uZSAqKnBlciBpbCBzaW5nb2xvIHNvdHRvZ3J1cHBvKiogKGludGVybWVkaWF0ZUdyb3VwID0gZmFsc2UpXHJcbiAgICAgICAgICAgIC8qXHJcbiAgICAgICAgICAgICogICBHcnVwcG9BICAgICAgICAgICAgICAgICAgICAgICAgIEdydXBwb0FcclxuICAgICAgICAgICAgKiAgICAgICBHcnVwcG9DMSAgICAgICAgICAgICAgICAgICAgICAgIEdydXBwb0MxICAgICAgXHJcbiAgICAgICAgICAgICogICBHcnVwcG9CICAgICAgICAgICAgICAgICAgICAgICAgIEdydXBwb0JcclxuICAgICAgICAgICAgKiAgIEdydXBwb0MgICAgICAgICAgICAgICAgICAgICAgICAgR3J1cHBvQ1xyXG4gICAgICAgICAgICAqICAgICAgIEdydXBwb0MxIDwtLSBDbGljY28gcXVpICAgICAgICAgR3J1cHBvQzFcclxuICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPZ2dldHRvMVxyXG4gICAgICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9nZ2V0dG8yXHJcbiAgICAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2dnZXR0bzNcclxuICAgICAgICAgICAgKiAgICAgICBHcnVwcG9DMiAgICAgICAgICAgICAgICAgICAgICAgIEdydXBwb0MyXHJcbiAgICAgICAgICAgICogICBHcnVwcG9EICAgICAgICAgICAgICAgICAgICAgICAgIEdydXBwb0RcclxuICAgICAgICAgICAgKiAgIEdydXBwb0UgICAgICAgICAgICAgICAgICAgICAgICAgR3J1cHBvRVxyXG4gICAgICAgICAgICAqL1xyXG5cclxuICAgICAgICAgICAgbGV0IGludGVybWVkaWF0ZUdyb3VwID0gdmlldy5yZXF1ZXN0ZWRncm91cHMubGVuZ3RoICE9IGdyb3VwaW5nS2V5cztcclxuXHJcbiAgICAgICAgICAgIGxldCBpdGVtcyA9IHRoaXMuYm91bmRTb3VyY2U7XHJcbiAgICAgICAgICAgIGxldCBpbnNlcnRJbmRleCA9IDA7XHJcbiAgICAgICAgICAgIGxldCBncm91cEtleTogc3RyaW5nID0gXCJcIjtcclxuICAgICAgICAgICAgbGV0IGdyb3VwUm91dGU6IEdyb3VwUm91dGVGcmFnbWVudFtdID0gW107XHJcbiAgICAgICAgICAgIC8vIE5hdmlnbyBsYSBzdHV0dHVyYSBkZWkgZ3J1cHBpIGlnbm9yYW5kbyByaWNvcnNpdmFtZW50ZSB0dXR0aSBnbGkgaW5kaWNpIGZpbm8gYWkgZ3J1cHBpIGNoZSBtaSBpbnRlcmVzc2FubyBpbiBtb2RvIGRhIG5vbiBiZWNjYXJlIGlsIHByaW1vIFwiR3J1cHBvQzFcIiBkZWwgY2FzbyBzb3ByYVxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZpZXcucmVxdWVzdGVkZ3JvdXBzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgcmcgPSB2aWV3LnJlcXVlc3RlZGdyb3Vwc1tpXTtcclxuICAgICAgICAgICAgICAgIGdyb3VwS2V5ICs9IHJnLnZhbHVlO1xyXG4gICAgICAgICAgICAgICAgZ3JvdXBSb3V0ZS5wdXNoKHsgY29sdW1uOiByZy5jb2x1bW4sIHZhbHVlOiByZy52YWx1ZSB9KTtcclxuICAgICAgICAgICAgICAgIGluc2VydEluZGV4ID0gaXRlbXMuZmluZEluZGV4KCh0LCBpKSA9PiBpID49IGluc2VydEluZGV4ICYmIHQuX2dyb3VwICYmIHQuY29sdW1uID09IHJnLmNvbHVtbiAmJiB0LnZhbHVlID09IHJnLnZhbHVlKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGV0IGl0ZW1zQ2FjaGVSZWZlcmVuY2U7XHJcbiAgICAgICAgICAgIGxldCBjaGlsZEdyb3Vwc0NhY2hlUmVmZXJlbmNlO1xyXG5cclxuICAgICAgICAgICAgLy8gU2Ugbm9uIMOoIHVuIGdydXBwbyBpbnRlcm1lZGlvIGRldm8gcmlwdWxpcmUgbGEgY2FjaGUgZGVsIGdydXBwbyBzdSBjdWkgaG8gYXR0dWFsbWVudGUgY2xpY2NhdG8uIEdsaSBvZ2dldHRpIHNhcmFubm8gcmlhZ2dpdW50aSBkb3BvXHJcbiAgICAgICAgICAgIGlmICghaW50ZXJtZWRpYXRlR3JvdXApIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmdJdGVtQ2FjaGUuc2V0KGdyb3VwS2V5LCBbXSk7XHJcbiAgICAgICAgICAgICAgICBpdGVtc0NhY2hlUmVmZXJlbmNlID0gdGhpcy5yZ0l0ZW1DYWNoZS5nZXQoZ3JvdXBLZXkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gU2UgaW52ZWNlIMOoIHVuIGdydXBwbyBpbnRlcm1lZGlvIGRldm8gcmlwdWxpcmUgc2lhIHR1dHRpIGkgY2hpbGQgZ3JvdXAgcmljb3JzaXZhbWVudGUsIHNpYSB0dXR0aSBnbGkgaXRlbVxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQga2V5IG9mIHRoaXMucmdDaGlsZEdyb3Vwc0NhY2hlLmtleXMoKSlcclxuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoZ3JvdXBLZXkpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJnQ2hpbGRHcm91cHNDYWNoZS5kZWxldGUoa2V5KTtcclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBrZXkgb2YgdGhpcy5yZ0l0ZW1DYWNoZS5rZXlzKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGtleS5zdGFydHNXaXRoKGdyb3VwS2V5KSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZ0l0ZW1DYWNoZS5kZWxldGUoa2V5KTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLnJnQ2hpbGRHcm91cHNDYWNoZS5zZXQoZ3JvdXBLZXksIFtdKTtcclxuICAgICAgICAgICAgICAgIGNoaWxkR3JvdXBzQ2FjaGVSZWZlcmVuY2UgPSB0aGlzLnJnQ2hpbGRHcm91cHNDYWNoZS5nZXQoZ3JvdXBLZXkpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBBc3NlZ25vIHVuIGxpdmVsbG8gYWkgdmFsb3JpIGNoZSBhcnJpdmFubyBkYSB1c2FyZSBwZXIgZm9ybWF0dGFyZSBsYSBwYXJ0ZSBncmFmaWNhLiBJbCBwcmltbyBncnVwcG8gY2xpY2NhdG8gc2Fyw6AgYSBsaXZlbGxvIDEsXHJcbiAgICAgICAgICAgIC8vIGlsIHNlY29uZG8gc2Fyw6AgYSBsaXZlbGxvIDIgZSBjb3PDrCB2aWEuLi5cclxuICAgICAgICAgICAgLy8gTGkgbWFyY28gaW5vbHRyZSBjb24gaWwgcGFyZW50IGluIG1vZG8gZGEgcG90ZXIgZWxpbWluYXJlIGkgdmVjY2hpIHF1YWxvcmEgc2Vydmlzc2VcclxuICAgICAgICAgICAgdGhpcy5UTVBCb3VuZFNvdXJjZS5mb3JFYWNoKGl0bSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpdG0uX3BhcmVudCA9IGdyb3VwS2V5O1xyXG4gICAgICAgICAgICAgICAgaXRtLl9wYXJlbnRSb3V0ZSA9IGdyb3VwUm91dGU7XHJcbiAgICAgICAgICAgICAgICBpdG0uX3RoaXNSb3V0ZSA9IGl0bS5fZ3JvdXAgPyBbLi4uZ3JvdXBSb3V0ZSwgbmV3IEdyb3VwUm91dGVGcmFnbWVudCgoPEdyb3VwPml0bSkuY29sdW1uLCAoPEdyb3VwPml0bSkudmFsdWUpXSA6IFtdO1xyXG4gICAgICAgICAgICAgICAgaXRtLl90aGlzS2V5ID0gaXRtLl9ncm91cCA/IGdyb3VwS2V5ICsgKDxHcm91cD5pdG0pLnZhbHVlIDogZ3JvdXBLZXk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gUGVyIGxlIHJpY2VyY2EgaW50ZXJtZWRpZSBtZXR0byBpIGdydXBwaSBuZWxsYSBjYWNoZSBkZWkgZ3J1cHBpXHJcbiAgICAgICAgICAgICAgICBpZiAoaW50ZXJtZWRpYXRlR3JvdXApIHtcclxuICAgICAgICAgICAgICAgICAgICBpdG0uX2dyb3VwbGV2ZWwgPSB2aWV3LnJlcXVlc3RlZGdyb3Vwcy5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZ0dyb3VwQ2FjaGUuc2V0KGl0bS5fdGhpc0tleSwgaXRtKTtcclxuICAgICAgICAgICAgICAgICAgICBjaGlsZEdyb3Vwc0NhY2hlUmVmZXJlbmNlLnB1c2goaXRtKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIE1ldHRvIGFuY2hlIGdsaSBvZ2dldHRpIG5lbGxhIGNhY2hlIG5vbiByaWNvcnNpdmFcclxuICAgICAgICAgICAgICAgICAgICBpdGVtc0NhY2hlUmVmZXJlbmNlLnB1c2goaXRtKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAvLyBFbGltaW5vIGdsaSBvZ2dldHRpIHZlY2NoaSBcclxuICAgICAgICAgICAgLy8gMSkgUmljZXJjYSBpbnRlcm1lZGlhLCBzdGF0byBzYWx2YXRvIC0gRWxpbWlubyB0dXR0aSBnbGkgaXRlbSBlIHR1dHRpIGkgZ3J1cHBpIGxhIGN1aSByb3V0ZSDDqCBwacO5IGx1bmdhIGRlbGxhIGNvcnJlbnRlLCB0dXR0aSBnbGkgaXRlbSByZWxhdGl2aSBhbGxhIHBhdGggY29ycmVudGUsIGUgdHV0dGVcclxuICAgICAgICAgICAgLy8gICAgbGUgY2FjaGUgZGkgcmljZXJjYSBlZmZldHR1YXRlIHN1IHVuYSBwYXRoIHBpw7kgcHJvZm9uZGEgZGVsbCdhdHR1YWxlXHJcbiAgICAgICAgICAgIC8vIDIpIFJpY2VyY2EgZmluYWxlIG8gcmljZXJjYSBpbnRlcm1lZGlhIHNlbnphIHN0YXRvIHNhbHZhdG8gLSBFbGltaW5vIHR1dHRpIGdsaSBpdGVtIHJlbGF0aXZpIGFsbGEgcGF0aCBjb3JyZW50ZVxyXG4gICAgICAgICAgICAvLyBQZXIgXCJzdGF0byBzYWx2YXRvXCIgc2kgaW50ZW5kb25vIHJpY2VyY2hlIHZlY2NoaWUgc2FsdmF0ZSBwZXIgcG90ZXIgZXNzZXJlIHJpZWZmZXR0dWF0ZSBpbiBjYXNvIGRpIG9yZGluYW1lbnRpIHN1IGNvbG9ubmUgZGkgaW50ZXJlc3NlIFxyXG4gICAgICAgICAgICBpZiAoaW50ZXJtZWRpYXRlR3JvdXAgJiYgdmlldy5zYXZlZHN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmJvdW5kU291cmNlID0gdGhpcy5ib3VuZFNvdXJjZS5maWx0ZXIodCA9PiAhKHQuX2l0ZW0gfHwgdC5fdGhpc1JvdXRlLmxlbmd0aCA+IGdyb3VwUm91dGUubGVuZ3RoKSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdyb3VwU2VhcmNoUmVxdWVzdHNDYWNoZSA9IHRoaXMuZ3JvdXBTZWFyY2hSZXF1ZXN0c0NhY2hlLmZpbHRlcih0ID0+ICEodC5yb3V0ZS5sZW5ndGggPiBncm91cFJvdXRlLmxlbmd0aCkpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmJvdW5kU291cmNlID0gdGhpcy5ib3VuZFNvdXJjZS5maWx0ZXIodCA9PiAhKHQuX3BhcmVudCA9PSBncm91cEtleSkpO1xyXG5cclxuICAgICAgICAgICAgbGV0IHRoaXNHcm91cCA9IHRoaXMuYm91bmRTb3VyY2VbaW5zZXJ0SW5kZXhdO1xyXG4gICAgICAgICAgICBpZihpbnRlcm1lZGlhdGVHcm91cClcclxuICAgICAgICAgICAgICAgIHRoaXNHcm91cC5fZ3JvdXBzY291bnQgPSAoPEFwcFNlYXJjaDxhbnk+PnRoaXMuVmlldyk/Lmdyb3VwY291bnRcclxuXHJcbiAgICAgICAgICAgIC8vIExpIHNvc3RpdHVpc2NvIGNvaSBudW92aSBkaSBxdWVzdGEgcmljZXJjYVxyXG4gICAgICAgICAgICB0aGlzLmJvdW5kU291cmNlLnNwbGljZShpbnNlcnRJbmRleCArIDEsIDAsIC4uLnRoaXMuVE1QQm91bmRTb3VyY2UpO1xyXG5cclxuICAgICAgICAgICAgLy8gQWdnaXVuZ28gdW4gc2VwYXJhdG9yZSBhbGxhIGZpbmUgbyBhbGwnaW5pemlvIGRpIHF1ZXN0aSBncnVwcGkgY2hlIGRvdnLDoCBvY2N1cGFyc2kgZGkgY2FyaWNhcmUgQUxUUkkgZ3J1cHBpIG8gb2dnZXR0aSAoc2Ugc29ubyBhbGwndWx0aW1vIGdydXBwbylcclxuICAgICAgICAgICAgbGV0IGFkZExhc3QgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5ib3VuZFNvdXJjZS5zcGxpY2UoaW5zZXJ0SW5kZXggKyAxICsgKGFkZExhc3QgPyB0aGlzLlRNUEJvdW5kU291cmNlLmxlbmd0aCA6IDApLCAwLCB0aGlzLmdldEdyb3VwU2VwYXJhdG9yKHZpZXcsIGdyb3VwS2V5LCBncm91cFJvdXRlLCB2aWV3LnJlcXVlc3RlZGdyb3Vwcy5sZW5ndGgsIGludGVybWVkaWF0ZUdyb3VwID8gJ2dyb3VwcycgOiAnaXRlbXMnKSk7XHJcblxyXG4gICAgICAgICAgICAvLyBBZ2dpdW5nbyBsYSByaWNlcmNhIGFsbGEgY2FjaGUgZGkgcXVlc3RhIFwic2Vzc2lvbmVcIlxyXG4gICAgICAgICAgICBsZXQgdG9BZGQgPSB7IHBhdGg6IGdyb3VwS2V5LCByb3V0ZTogZ3JvdXBSb3V0ZSwgdmlldzogT2JqZWN0LmFzc2lnbih7fSwgdmlldyksIGdyb3VwX2NvbHVtbjogaW50ZXJtZWRpYXRlR3JvdXAgPyAoPEdyb3VwPnRoaXMuVE1QQm91bmRTb3VyY2VbMF0pLmNvbHVtbiA6ICcnIH07XHJcbiAgICAgICAgICAgIGxldCBwcmV2ID0gdGhpcy5ncm91cFNlYXJjaFJlcXVlc3RzQ2FjaGUuZmluZEluZGV4KHQgPT4gdC5wYXRoID09IHRvQWRkLnBhdGggJiYgdC5ncm91cF9jb2x1bW4gPT0gdG9BZGQuZ3JvdXBfY29sdW1uKTtcclxuICAgICAgICAgICAgaWYgKHByZXYgPT0gLTEpXHJcbiAgICAgICAgICAgICAgICB0aGlzLmdyb3VwU2VhcmNoUmVxdWVzdHNDYWNoZS5wdXNoKHRvQWRkKTtcclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgdGhpcy5ncm91cFNlYXJjaFJlcXVlc3RzQ2FjaGUuc3BsaWNlKHByZXYsIDEsIHRvQWRkKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gcmljaGlhbWF0byBzb2xvIHF1YW5kbyAqKlRNUFJvd1REcyoqIGUgKipUTVBSb3dUSHMqKiBzb25vIGNvbXBsZXRhbWVudGUgZ2VuZXJhdGkgZWQgYWdnaXVzdGF0aS4gU2VydmUgcGVyIGNvbGxlZ2FybGkgYWxsZSB2YXJpYWJpbGkgdXNhdGUgbGF0byBiaW5kaW5nIEhUTUxcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBNb3ZlVGVtcG9yYXJ5VmFyaWFibGVzVG9SZWFsT25lcygpIHtcclxuICAgICAgICB0aGlzLlJvd1REcyA9IHRoaXMuVE1QUm93VERzO1xyXG4gICAgICAgIHRoaXMuUm93VEhzID0gdGhpcy5UTVBSb3dUSHM7XHJcbiAgICAgICAgdGhpcy5Sb3dUaEdyb3VwcyA9IHRoaXMuVE1QUm93VGhHcm91cHMgPyB0aGlzLlRNUFJvd1RoR3JvdXBzLnJldmVyc2UoKSA6IG51bGw7XHJcblxyXG4gICAgICAgIHRoaXMuQ29sdW1ucy5WaXNpYmlsZSA9IHRoaXMuUm93VEhzLmZpbHRlcih0ID0+IHQuVmlzaWJsZSkubGVuZ3RoO1xyXG4gICAgICAgIHRoaXMuQ29sdW1ucy5WaXNpYmxlVW5waW5uZWQgPSB0aGlzLlJvd1RIcy5maWx0ZXIodCA9PiB0LlZpc2libGUgJiYgIXQuUGlubmVkKS5sZW5ndGg7XHJcbiAgICAgICAgdGhpcy5Db2x1bW5zLkdsb2JhbCA9IHRoaXMuQ29sdW1ucy5WaXNpYmxlVW5waW5uZWQgKyAodGhpcy5IYXNQaW5uZWRDb2x1bW5zID8gMSA6IDApICsgKHRoaXMuU2VsZWN0aW9uID8gMSA6IDApICsgKHRoaXMuUmVtb3ZhbCA/IDEgOiAwKSArICh0aGlzLkV4cG9ydCB8fCB0aGlzLkhpZGRlbkNvbHVtbnMgfHwgdGhpcy5Db2x1bW5zT3JkZXJpbmcgfHwgdGhpcy5Db3JuZXJNZW51T3B0aW9ucyA/IDEgOiAwKVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGVybWV0dGUgZGkgc2VsZXppb25hcmUgbyBkZXNlbGV6aW9uYXJlIGluIG1hbmllcmEgYXJiaXRyYXJpYSBkZWdsaSBvZ2dldHRpXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55W119IGl0ZW1zIE9nZ2V0dGkgZGEgc2VsZXppb25hcmUgbyBkZXNlbGV6aW9uYXJlXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHNlbGVjdCAqKnRydWUqKiBwZXIgc2VsZXppb25hcmxpLCAqKmZhbHNlKiogcGVyIG5vbiB0b2NjYXJsaVxyXG4gICAgICogXHJcbiAgICAgKiBAdG9kbzogU0VMRUNUSU9OXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXRTZWxlY3Rpb25TdGF0dXMoaXRlbXM6IGFueVtdLCBzZWxlY3Q6IGJvb2xlYW4pIHtcclxuICAgICAgICB0aGlzLmhhbmRsZUl0ZW1zU2VsZWN0aW9uKGl0ZW1zLCBzZWxlY3QpO1xyXG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2Ugbm9uIGhvIGwnSW5wdXQgKipEeW5hbWljUm93Q29sdW1uc0RlZmluaXRpb24qKiBpbiBtb2RhbGl0w6AgZGluYW1pY2EgbG8gcmllbXBpbyBjb24gaWwgZGVmYXVsdCBub21lIGRlbGxhIGNvbG9ubmEgPSB0ZXN0byBkZWxsYSBjb2xvbm5hXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZXZlbnR1YWxseVJldmlld0R5bmFtaWNDb2x1bW5zKCkge1xyXG4gICAgICAgIC8vIFNlbnphIG9nZ2V0dGkgZXNjb1xyXG4gICAgICAgIGlmICghdGhpcy5UTVBCb3VuZFNvdXJjZSB8fCB0aGlzLlRNUEJvdW5kU291cmNlLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIHZhciB1c2VHZW5lcmljSXRlbXMgPSAhIXRoaXMuVE1QQm91bmRTb3VyY2VbMF1bXCJwcm9wZXJ0aWVzXCJdO1xyXG4gICAgICAgIGlmICghdXNlR2VuZXJpY0l0ZW1zIHx8ICghdGhpcy5GaXJzdEJpbmQgJiYgdGhpcy5EeW5hbWljUm93Q29sdW1uc0RlZmluaXRpb24gJiYgdGhpcy5EeW5hbWljUm93Q29sdW1uc0RlZmluaXRpb24ubGVuZ3RoID4gMCkpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgaWYgKCghdGhpcy5EeW5hbWljUm93Q29sdW1uc0RlZmluaXRpb24gfHwgdGhpcy5EeW5hbWljUm93Q29sdW1uc0RlZmluaXRpb24ubGVuZ3RoID09IDApKSB7XHJcbiAgICAgICAgICAgIHZhciBwcm9wcyA9IDxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PnRoaXMuVE1QQm91bmRTb3VyY2VbMF1bXCJwcm9wZXJ0aWVzXCJdO1xyXG4gICAgICAgICAgICB0aGlzLkR5bmFtaWNSb3dDb2x1bW5zRGVmaW5pdGlvbiA9IFtdO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBrZXkgaW4gcHJvcHMpXHJcbiAgICAgICAgICAgICAgICB0aGlzLkR5bmFtaWNSb3dDb2x1bW5zRGVmaW5pdGlvbi5wdXNoKG5ldyBFc1RhYmxlQ29sdW1uc0RlZmluaXRpb24oa2V5LCBrZXkpKVxyXG4gICAgICAgICAgICB0aGlzLlVzZXJEZWZpbmVkRHluYW1pY0NvbHMgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICB0aGlzLlVzZXJEZWZpbmVkRHluYW1pY0NvbHMgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGFydGVuZG8gZGFnbGkgKipFc1RocyoqIGVzdHJhcHBvbG8gbGEgbGlzdGEgZGkgKipFc1RhYmxlQ29sdW1uKiogY2hlIHF1ZXN0YSB0YWJlbGxhIGRvdnLDoCBldmVudHVhbG1lbnRlIGdlc3RpcmUgcGVyIFZpc2liaWxpdMOgIGUgT3JkaW5lXHJcbiAgICAgKlxyXG4gICAgICogQ29zdG86IDEgc2NhbiBFc1Roc1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdfSB0aHMgQ29sb25uZSBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgcmV2aWV3Q29sdW1uc0xpc3QodGhzOiBFc1RoW10gfCBFc1RoRGlyZWN0aXZlW10pIHtcclxuICAgICAgICB0aGlzLlRNUENvbHVtbnNMaXN0ID0gW107XHJcbiAgICAgICAgaWYgKHRocy5sZW5ndGggPT0gMClcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAvLyBBcHBlbmEgaWwgY29udGVudENoaWxkcmVuIMOoIHZhbG9yaXp6YXRvIHNjb3JybyB0dXR0aSBnbGkgaGVhZGVyXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuaXNFc1RoKHRoKSkge1xyXG4gICAgICAgICAgICAgICAgLy8gU2Ugbm9uIGhvIHVuIGlkIGlsIHRoIMOoIGNvbnNpZGVyYXRvIGluZXJ0ZVxyXG4gICAgICAgICAgICAgICAgaWYgKCF0aC5JRClcclxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aC5PcmRlckJ5ID0gdGhpcy5PcmRlckJ5Q29sdW1uO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFNhbHZvIGxlIGluZm9ybWF6aW9uaSBkZWxsJ2hlYWRlciBwZXIgZmFyIHBhcnRlIGRlbGxhIGxpc3RhIGRhIGN1aSBzY2VnbGllcmUgcXVhbGkgY29sb25uZSB2aXN1YWxpenphcmUvbmFzY29uZGVyZVxyXG4gICAgICAgICAgICAgICAgLy8gRGkgZGVmYXVsdCBsYSB2aXNpYmlsaXTDoCDDqCBxdWVsbGEgaW1wb3N0YXRhIG5lbCBjb21wb25lbnRlXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5IaWRkZW5Db2x1bW5zIHx8IHRoLlZpc2libGUpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5UTVBDb2x1bW5zTGlzdC5wdXNoKG5ldyBFc1RhYmxlQ29sdW1uKHRoLklELCB0aC5EZXNjcmlwdGlvbiwgdGguVmlzaWJsZSwgdGguRml4ZWQsIG51bGwsIG51bGwsIG51bGwpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGxldCBjb2x1bW4gPSB0aC50aDtcclxuICAgICAgICAgICAgICAgIC8vIFNlIG5vbiBobyB1biBpZCBpbCB0aCDDqCBjb25zaWRlcmF0byBpbmVydGVcclxuICAgICAgICAgICAgICAgIGlmICghY29sdW1uKVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFNhbHZvIGxlIGluZm9ybWF6aW9uaSBkZWxsJ2hlYWRlciBwZXIgZmFyIHBhcnRlIGRlbGxhIGxpc3RhIGRhIGN1aSBzY2VnbGllcmUgcXVhbGkgY29sb25uZSB2aXN1YWxpenphcmUvbmFzY29uZGVyZVxyXG4gICAgICAgICAgICAgICAgLy8gRGkgZGVmYXVsdCBsYSB2aXNpYmlsaXTDoCDDqCBxdWVsbGEgaW1wb3N0YXRhIG5lbCBjb21wb25lbnRlXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5IaWRkZW5Db2x1bW5zIHx8IHRoLnRoVmlzaWJsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBwcmV2aW91c2x5UGlubmVkID0gIXRoaXMuQ29sdW1uc0xpc3QgfHwgdGhpcy5Db2x1bW5zTGlzdC5sZW5ndGggPT0gMCB8fCAhdGhpcy5Db2x1bW5zTGlzdC5maW5kKHQgPT4gdC5pZCA9PSBjb2x1bW4pID8gbnVsbCA6IHRoaXMuQ29sdW1uc0xpc3QuZmluZCh0ID0+IHQuaWQgPT0gY29sdW1uKS5waW5uZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5UTVBDb2x1bW5zTGlzdC5wdXNoKG5ldyBFc1RhYmxlQ29sdW1uKGNvbHVtbiwgbnVsbCwgdGgudGhWaXNpYmxlLCAodGgudGhGaXhlZCB8fCB0aC50aEdyb3VwKSwgcHJldmlvdXNseVBpbm5lZCA9PSBudWxsID8gdGgudGhQaW5uZWQgOiBwcmV2aW91c2x5UGlubmVkLCB0aC50aFBpbm5lZFdpZHRoLCB0aC5UZW1wbGF0ZSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuQ29sdW1uc0xpc3QgPSBbXTtcclxuICAgICAgICB0aGlzLlRNUENvbHVtbnNMaXN0LmZvckVhY2goYyA9PiB7IHRoaXMuQ29sdW1uc0xpc3QucHVzaChPYmplY3QuYXNzaWduKHt9LCBjKSk7IH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHJlbmRlIGkgdGggZSBpIHRkIGluIG1vZGFsaXTDoCBkaXJldGl2ZSBlIGxpIG9yZGluYSBpbiBiYXNlIGEgc2UgY2kgc29ubyBjb2xvbm5lIGZpeGVkIG8gbWVub1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIG1vdmVGaXhlZENvbHVtbnNBdFRoZUJlZ2lubmluZyh0aHM6IEVzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXSwgdGRzOiBFc1RkW10gfCBFc1RkRGlyZWN0aXZlW10pIHtcclxuXHJcbiAgICAgICAgbGV0IHRoc0NhY2hlOiB7IFtpbmRleDogc3RyaW5nXTogYW55IH0gPSB7fTtcclxuICAgICAgICBsZXQgZml4ZWRzID0gMCwgcGlubmVkcyA9IDA7XHJcbiAgICAgICAgbGV0IGNvbHVtbnNDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IEVzVGFibGVDb2x1bW4gfSA9IHt9O1xyXG4gICAgICAgIGxldCBjb2x1bW5zSW5kZXhDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IG51bWJlciB9ID0ge307XHJcblxyXG4gICAgICAgIC8vIENyZW8gbGEgY2FjaGUgZGVsbGUgY29sb25uZVxyXG4gICAgICAgIGZvciAobGV0IGNvbGkgPSAwOyBjb2xpIDwgdGhpcy5Db2x1bW5zTGlzdC5sZW5ndGg7IGNvbGkrKykge1xyXG4gICAgICAgICAgICBsZXQgY29sID0gdGhpcy5Db2x1bW5zTGlzdFtjb2xpXTtcclxuICAgICAgICAgICAgY29sdW1uc0NhY2hlW2NvbC5pZF0gPSBjb2w7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBTcG9zdG8gdHV0dGkgZ2xpIGhlYWRlciBmaXhlZCBvIHBpbm5lZCBhbGwnaW5pemlvXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pc0VzVGgodGgpKSB7XHJcbiAgICAgICAgICAgICAgICB0aHNDYWNoZVt0aC5JRF0gPSB0aDtcclxuICAgICAgICAgICAgICAgIGlmICh0aC5GaXhlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpICE9IHBpbm5lZHMgKyBmaXhlZHMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXJyYXlNb3ZlKHRocywgaSwgcGlubmVkcyArIGZpeGVkcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgZml4ZWRzKytcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuXHJcbiAgICAgICAgICAgICAgICB0aHNDYWNoZVt0aC50aF0gPSB0aDtcclxuICAgICAgICAgICAgICAgIC8vIFJpYXNzZWdubyBzZW1wcmUgcGVyIHJpcHVsaXJlIHZhbG9yaSBkaSBwYXJ0ZW56YSBvIHBlciBhZ2dpb3JuYXJsaSBpbiBjYXNvIGRpIG1vZGlmaWNoZSB1dGVudGVcclxuICAgICAgICAgICAgICAgIHRoLnRoUGlubmVkID0gKCFjb2x1bW5zQ2FjaGVbdGgudGhdICYmIHRoLnRoUGlubmVkKSB8fCAoY29sdW1uc0NhY2hlW3RoLnRoXSAmJiBjb2x1bW5zQ2FjaGVbdGgudGhdLnBpbm5lZCk7XHJcbiAgICAgICAgICAgICAgICBpZiAodGgudGhQaW5uZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaSAhPSBwaW5uZWRzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFycmF5TW92ZSh0aHMsIGksIHBpbm5lZHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHBpbm5lZHMrK1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vSW4gcXVlc3RvIGNhc28gc29ubyBpbmZvcm1hemlvbmkgc3RhdGljaGUgaW52ZWNlLCBub24gbW9kaWZpY2FiaWxpIGRhbGwndXRlbnRlLCBxdWluZGkgbm9uIG1pIGTDsiBwcmVvY2N1cGF6aW9uaVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoLnRoRml4ZWQgfHwgdGgudGhHcm91cCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpICE9IHBpbm5lZHMgKyBmaXhlZHMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXJyYXlNb3ZlKHRocywgaSwgcGlubmVkcyArIGZpeGVkcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgZml4ZWRzKytcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaXNFc1RoKHRoc1swXSkgfHwgdGhpcy5pc0VzVGQodGRzWzBdKSlcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAvLyBDYWNoZSBkZWdsaSBpbmRpY2kgcGVyIHJpcG9zaXppb25hcmUgaSB0ZCBjb21lIGkgdGhcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgY29sdW1uc0luZGV4Q2FjaGVbKDxFc1RoRGlyZWN0aXZlPnRoc1tpXSkudGhdID0gaTtcclxuXHJcbiAgICAgICAgLy8gUmlvcmRpbm8gbGUgY2VsbGUgcGVyIGZhcmdsaSBtYW50ZW5lcmUgbGEgc3Rlc3NhIHN0cnV0dHVyYSBkZWkgdGhcclxuICAgICAgICBsZXQgbmV3VGRzID0gbmV3IEFycmF5KHRocy5sZW5ndGgpO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRkcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgaXRlbSA9IHRkc1tpXSBhcyBFc1RkRGlyZWN0aXZlO1xyXG4gICAgICAgICAgICBuZXdUZHNbY29sdW1uc0luZGV4Q2FjaGVbaXRlbS50ZF1dID0gaXRlbTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuSGFzUGlubmVkQ29sdW1ucyA9IHBpbm5lZHMgPiAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW4gYmFzZSBhbGxhIGNvbmZpZ3VyYXppb25lIGRlbGxlIGNvbG9ubmUgY2FsY29sYSBsZSBkaW1lbmlvbmkgZGVsbGUgY29sb25uZSBwaW5uYXRlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZXZhbHVhdGVQaW5uZWRDb2x1bW5zV2lkdGgoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLkhhc1Bpbm5lZENvbHVtbnMpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgdGhpcy5QaW5uZWRDb250YWluZXJXaWR0aCA9IDA7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLkNvbHVtbnNMaXN0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBjb2wgPSB0aGlzLkNvbHVtbnNMaXN0W2ldO1xyXG4gICAgICAgICAgICBpZiAoY29sLnBpbm5lZCAmJiBjb2wudmlzaWJsZSlcclxuICAgICAgICAgICAgICAgIHRoaXMuUGlubmVkQ29udGFpbmVyV2lkdGggKz0gY29sLnBpbm5lZFdpZHRoO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLlBpbm5lZENvbnRhaW5lcldpZHRoICs9IHRoaXMuU2VsZWN0aW9uID8gMjUgOiAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGVscGVyIHBlciBzcG9zdGFyZSB1biBvZ2dldHRvIGRpIHVuIGFycmF5IGRhIHVuIGluZGljZSBhbGwnYWx0cm8sIGluIHBsYWNlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgYXJyYXlNb3ZlKGFycmF5OiBhbnlbXSwgb2xkSTogbnVtYmVyLCBuZXdJOiBudW1iZXIpIHtcclxuICAgICAgICBpZiAobmV3SSA+IGFycmF5Lmxlbmd0aCAtIDEgfHwgb2xkSSA+IGFycmF5Lmxlbmd0aCAtIDEgfHwgbmV3SSA8IDAgfHwgb2xkSSA8IDApXHJcbiAgICAgICAgICAgIHRocm93IFwiR2xpIGluZGljaSBwYXNzYXRpIG5vbiBmYW5ubyByaWZlcmltZW50byBhIHVuYSBwb3NpemlvbmUgZGVsbCdhcnJheS4gTGVuZ3RoOiBcIiArIGFycmF5Lmxlbmd0aCArIFwiIE9sZDpcIiArIG9sZEkgKyBcIiBOZXc6IFwiICsgbmV3STtcclxuXHJcbiAgICAgICAgYXJyYXkuc3BsaWNlKG5ld0ksIDAsIGFycmF5LnNwbGljZShvbGRJLCAxKVswXSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXJtaW5hdG8gaWwgYmluZGluZyBkZWxsZSBjb2xvbm5lIGRhICoqcmV2aWV3Q29sdW1uc0xpc3QqKiBlIGRlbGxhICoqVmlldyoqIGRhbCAqKndyaXRlVmFsdWUqKiBxdWVzdG8gbWV0b2RvIHNpIG9jY3VwYVxyXG4gICAgICogZGVsbCdhbGxpbmVhbWVudG8gZGVsbGUgaW5mb3JtYXppb25pIGZyYSBsZSBjb2xvbm5lIGNhbGNvbGF0ZSBpbnRlcm5hbWVudGUgZSBsZSBpbmZvcm1hemlvbmkgc3VsbGUgY29sb25uZSBjaGUgYXJyaXZhbm8gZGFsbCdBcHBTZWFyY2hcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0FwcFNlYXJjaDxhbnk+fSB2aWV3IEFwcFNlYXJjaCBkYSB1dGlsaXp6YXJlIHBlciBxdWVzdGEgb3BlcmF6aW9uZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGFsaWduQ29sdW1uc0lmTG9hZGVkVmlldyh2aWV3OiBBcHBTZWFyY2g8YW55Pikge1xyXG4gICAgICAgIGxldCBlbWl0Q2hhbmdlZCA9IHRoaXMudmlld01vZGUgJiYgdmlldy5zYXZlZHN0YXRlO1xyXG4gICAgICAgIGxldCBuZXdDb2xzZXQgPSBbXTtcclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLkNvbHVtbnNMaXN0IHx8IHRoaXMuQ29sdW1uc0xpc3QubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgbGV0IGNvbHVtbnMgPSB0aGlzLnZpZXdNb2RlID8gdmlldy5jb2x1bW5zIDogdGhpcy5hcnJheUNvbHVtbnM7XHJcbiAgICAgICAgdGhpcy5Db2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4ge1xyXG4gICAgICAgICAgICAvLyBTZSBsYSBjb2xvbm5hIMOoIHBpbm5hdGEgbWkgYXJyaXZhIGNvbCBzaW1vbGVvblxyXG4gICAgICAgICAgICBsZXQgZXhDbCA9IGNvbHVtbnMuZmlsdGVyKGNjID0+IGNjLnJlcGxhY2UoJ8KnJywgJycpID09IGMuaWQpO1xyXG5cclxuICAgICAgICAgICAgLy8gU2UgbGEgY29sb25uYSDDqCBwaW5uYXRhIGFnZ2lvcm5vIGwnaW5mb3JtYXppb25lIG5lbGxhIHZpZXdcclxuICAgICAgICAgICAgaWYgKGV4Q2wubGVuZ3RoID09IDEpXHJcbiAgICAgICAgICAgICAgICBjLnBpbm5lZCA9IGV4Q2xbMF0uc3RhcnRzV2l0aCgnwqcnKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNlIGwnYXBwc2VhcmNoIHZpZW5lIGRhIHVubyBzdGF0byBwcmVjZWRlbnRlLCB1c28gbGUgaW5mb3JtYXppb25pIHN1bGxlIGNvbG9ubmUgY2hlIGhhIGRlbnRybywgYWx0cmltZW50aSBzb3ZyYXNjcml2byB0dXR0byAgKipcclxuICAgICAgICAgICAgaWYgKGMudmlzaWJsZSAmJiBjb2x1bW5zLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICAgICAgbmV3Q29sc2V0LnB1c2goYy5pZCk7XHJcbiAgICAgICAgICAgIC8vIFNlIGhvIHVuYSBjb2xvbm5hIGxhdG8gQXBwU2VhcmNoIGUgbmVsbGEgQ29sdW1uTGlzdCBub24gw6ggdmlzaWJpbGUsIGFsbGluZW8gYWxsJ0FwcFNlYXJjaFxyXG4gICAgICAgICAgICBlbHNlIGlmIChleENsLmxlbmd0aCA9PSAxICYmICFjLnZpc2libGUpXHJcbiAgICAgICAgICAgICAgICBjLnZpc2libGUgPSB0cnVlO1xyXG4gICAgICAgICAgICAvLyBBbGxpbmVhbWVudG8gc3VsbCdBcHBTZWFyY2ggcGVyIGNhc2lzdGljaGUgaW52ZXJzZSBhbCBkaSBzb3ByYVxyXG4gICAgICAgICAgICBlbHNlIGlmIChleENsLmxlbmd0aCA9PSAwICYmIGMudmlzaWJsZSlcclxuICAgICAgICAgICAgICAgIGMudmlzaWJsZSA9IGZhbHNlO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBOb24gaG8gY29sb25uZSBuZWxsYSBhcHBzZWFyY2gsIHZ1b2wgZGlyZSBjaGUgc29ubyBhbCBwcmltbyBiaW5kaW5nXHJcbiAgICAgICAgaWYgKGNvbHVtbnMubGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMudmlld01vZGUpIHZpZXcuY29sdW1ucyA9IG5ld0NvbHNldDtcclxuICAgICAgICAgICAgZWxzZSB0aGlzLmFycmF5Q29sdW1ucyA9IG5ld0NvbHNldFxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCh0aGlzLnZpZXdNb2RlICYmIHZpZXcuc2F2ZWRzdGF0ZSkgJiYgdGhpcy5Db2x1bW5zT3JkZXJpbmcgJiYgdmlldy5jb2x1bW5fb3JkZXJpbmcubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAvLyBTY29ycm8gZ2xpIG9yZGluYW1lbnRpIGNoZSBhdmV2byBzYWx2YXRvIGUgcmljcmVvIGxhIENvbHVtbnNMaXN0IGluIGJhc2UgYSBsb3JvXHJcbiAgICAgICAgICAgIGxldCBuZXdDb2xMaXN0ID0gW107XHJcbiAgICAgICAgICAgIHZpZXcuY29sdW1uX29yZGVyaW5nLmZvckVhY2goY28gPT4geyB0aGlzLkNvbHVtbnNMaXN0LmZvckVhY2goYyA9PiB7IGlmIChjLmlkID09IGNvKSBuZXdDb2xMaXN0LnB1c2goYyk7IH0pOyB9KTtcclxuICAgICAgICAgICAgdGhpcy5Db2x1bW5zTGlzdCA9IG5ld0NvbExpc3Q7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJbiBvZ25pIGNhc28gcXVlc3RvIG5vbiBtaSBzZXJ2ZSBwacO5LCBsbyByZXNldHRvICAqKlxyXG4gICAgICAgIGlmICh0aGlzLnZpZXdNb2RlKVxyXG4gICAgICAgICAgICB2aWV3LnNhdmVkc3RhdGUgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgaWYgKGVtaXRDaGFuZ2VkKVxyXG4gICAgICAgICAgICB0aGlzLmNoYW5nZWQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBjaGUgZ2VzdGlzY2UgaWwgY2FtYmlvIGRpIE9yZGluYW1lbnRvIGRpIHVuYSBjb2xvbm5hXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlkIElEIGRlbGxhIGNvbG9ubmEgaWwgY3VpIG9yaWRuYW1lbnRvIMOoIGNhbWJpYXRvXHJcbiAgICAgKiBAcGFyYW0geydERVNDJyB8ICdBU0MnfSBvcmRlciBOdW92byBvcmRpbmUgc2VsZXppb25hdG8gcGVyIGxhIGNvbG9ubmFcclxuICAgICAqL1xyXG4gICAgcHVibGljIHRoT3JkZXJDaGFuZ2VkKGlkOiBzdHJpbmcsIG9yZGVyPzogJ0RFU0MnIHwgJ0FTQycpIHtcclxuICAgICAgICBpZiAoIXRoaXMudmlld01vZGUgJiYgIXRoaXMuYXJyYXlNb2RlKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignT3JkZXIgY2hhbmdlZCBvbiBhIHRhYmxlIG5vdCBpbiB2aWV3TW9kZSBvciBBcnJheSBtb2RlLiBPcGVyYXRpb24gbm90IHN1cHBvcnRlZCcpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXRoaXMuT3JkZXJCeUNvbHVtbilcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBsZXQgb3JkZXJzID0gdGhpcy52aWV3TW9kZSA/ICh0aGlzLlZpZXcgYXMgQXBwU2VhcmNoPGFueT4pLm9yZGVycyA6IHRoaXMuYXJyYXlPcmRlcnM7XHJcbiAgICAgICAgbGV0IG9yZGVyVG9BZGQgPSB0cnVlO1xyXG4gICAgICAgIGxldCBvcmRlclRvUmVtb3ZlOiBudW1iZXIgPSBudWxsO1xyXG5cclxuICAgICAgICAvLyBTZSBwZXIgcXVhbGNoZSBtb3Rpdm8gaWwgY29zdHJ1dHRvcmUgbm9uIMOoIHBhc3NhdG8gKGNhY2hlIHRhcnBhdGUgbyBzaW1pbGEpIGZpeG9cclxuICAgICAgICBpZiAoIW9yZGVycyAmJiB0aGlzLnZpZXdNb2RlKVxyXG4gICAgICAgICAgICAodGhpcy5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+KS5vcmRlcnMgPSBbXTtcclxuICAgICAgICBlbHNlIGlmICghb3JkZXJzICYmIHRoaXMuYXJyYXlNb2RlKVxyXG4gICAgICAgICAgICB0aGlzLmFycmF5T3JkZXJzID0gW107XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JkZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0ID0gb3JkZXJzW2ldO1xyXG4gICAgICAgICAgICBpZiAodC5pZCA9PSBpZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG9yZGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdC5vcmRlciA9IG9yZGVyO1xyXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyVG9BZGQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBvcmRlclRvUmVtb3ZlID0gaTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKG9yZGVyVG9SZW1vdmUgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICBvcmRlcnMuc3BsaWNlKG9yZGVyVG9SZW1vdmUsIDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChvcmRlclRvQWRkKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLk11bHRpcGxlT3JkZXJpbmdEaXJlY3RpdmVzKVxyXG4gICAgICAgICAgICAgICAgb3JkZXJzLnB1c2gobmV3IEFwcE9yZGVyaW5nKGlkLCBvcmRlcikpO1xyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnZpZXdNb2RlKVxyXG4gICAgICAgICAgICAgICAgICAgICh0aGlzLlZpZXcgYXMgQXBwU2VhcmNoPGFueT4pLm9yZGVycyA9IFtuZXcgQXBwT3JkZXJpbmcoaWQsIG9yZGVyKV07XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLmFycmF5TW9kZSlcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFycmF5T3JkZXJzID0gW25ldyBBcHBPcmRlcmluZyhpZCwgb3JkZXIpXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5vbk9yZGVyQ2hhbmdlZC5lbWl0KHsgaWQsIG9yZGVyIH0pO1xyXG5cclxuICAgICAgICBpZiAodGhpcy52aWV3TW9kZSkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5ncm91cFNlYXJjaFJlcXVlc3RzQ2FjaGUubGVuZ3RoID4gMClcclxuICAgICAgICAgICAgICAgIHRoaXMuZW1pdFJvd0dyb3VwaW5nU2VhcmNoZXMoaWQsIG9yZGVycyk7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHRoaXMuZW1pdFNlYXJjaFJlcXVlc3QoZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0aGlzLmFycmF5TW9kZSlcclxuICAgICAgICAgICAgdGhpcy5pbnRlcm5hbFdyaXRlVmFsdWUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBkYSBjaGlhbWFyZSBvZ25pIHZvbHRhIGNoZSBzaSB2dW9sZSBkYXJlIGV2aWRlbnphIGFsbCdlc3Rlcm5vIGRlbCBiaXNvZ25vIGRpIHJpZWZmZXR0dWFyZSBsYSByaWNlcmNhXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gcmVzZXRzUGFnZSBJbmRpY2EgYWwgbGlzdGVuZXIgY2hlIGRldmUgcmVzZXR0YXJlIGlsIG51bWVybyBkaSBwYWdpbmFcclxuICAgICAqIEBwYXJhbSB7QXBwU2VhcmNoPGFueT59IHZpZXdPdmVycmlkZSBPdmVycmlkZSBkZWxsYSB2aWV3IGRhIGVtZXR0ZXJlIHBlciBxdWVzdGEgcmljZXJjYVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGVtaXRTZWFyY2hSZXF1ZXN0KHJlc2V0c1BhZ2U6IGJvb2xlYW4sIHZpZXdPdmVycmlkZT86IEFwcFNlYXJjaDxhbnk+KSB7XHJcbiAgICAgICAgaWYgKHRoaXMudmlld01vZGUgJiYgIXZpZXdPdmVycmlkZSkge1xyXG4gICAgICAgICAgICAodGhpcy5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+KS5pbnRlcm5hbHNlYXJjaHJlcXVlc3QgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLmNoYW5nZWQoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh2aWV3T3ZlcnJpZGUpIHtcclxuICAgICAgICAgICAgaWYgKHJlc2V0c1BhZ2UpXHJcbiAgICAgICAgICAgICAgICB2aWV3T3ZlcnJpZGUucGFnZSA9IDE7XHJcbiAgICAgICAgICAgIHZpZXdPdmVycmlkZS5pbnRlcm5hbHNlYXJjaHJlcXVlc3QgPSB0cnVlXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnJlc2VhcmNoSW5Qcm9ncmVzcyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5vblNlYXJjaFJlcXVlc3QuZW1pdCh2aWV3T3ZlcnJpZGUgPyB2aWV3T3ZlcnJpZGUgOiByZXNldHNQYWdlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEluIGJhc2UgYWxsYSB2aXNpYmlsaXTDoCByZWdpc3RyYXRhIG5lbGxlICoqQ29sdW1uc0xpc3QqKiBxdWVzdG8gbWV0b2RvIHNpIG9jY3VwYSBkaSBwcmVuZGVyZSB0dXR0aSBpICoqRXNUaHMqKiBlZCAqKkVzVGRzKiogcmVsYXRpdmkgZSBuYXNvbmRlcmxpL21vc3RyYXJsaVxyXG4gICAgICpcclxuICAgICAqIENvc3RvOiAxIHNjYW4gQ29sdW1uc0xpc3QsIDEgc2NhbiBFc1RocywgMSBzY2FuIEVzVGRzXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RoW10gfCBFc1RoRGlyZWN0aXZlW119IHRocyBIZWFkZXIgZGVsbGEgdGFiZWxsYVxyXG4gICAgICogQHBhcmFtIHtFc1RkW10gfCBFc1RkRGlyZWN0aXZlW119IHRkcyBDZWxsZSBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKiBAcGFyYW0ge0FwcFNlYXJjaDxhbnk+fSB2aWV3IEFwcFNlYXJjaCBkYSB1dGlsaXp6YXJlIHBlciBxdWVzdGEgb3BlcmF6aW9uZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHJlZnJlc2hDb2x1bW5zVmlzaWJpbGl0eSh0aHM6IEVzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXSwgdGRzOiBFc1RkW10gfCBFc1RkRGlyZWN0aXZlW10sIHZpZXc6IEFwcFNlYXJjaDxhbnk+KSB7XHJcbiAgICAgICAgbGV0IG5ld0NvbHNldCA9IFtdO1xyXG4gICAgICAgIGxldCBmaXhlZFRoczogeyBbaWQ6IHN0cmluZ106IGJvb2xlYW4gfSA9IHt9O1xyXG4gICAgICAgIGxldCBjb2x1bW5zQ2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBFc1RhYmxlQ29sdW1uIH0gPSB7fTtcclxuICAgICAgICBmb3IgKGxldCBjb2xpID0gMDsgY29saSA8IHRoaXMuQ29sdW1uc0xpc3QubGVuZ3RoOyBjb2xpKyspIHtcclxuICAgICAgICAgICAgbGV0IGNvbCA9IHRoaXMuQ29sdW1uc0xpc3RbY29saV07XHJcbiAgICAgICAgICAgIGNvbHVtbnNDYWNoZVtjb2wuaWRdID0gY29sO1xyXG4gICAgICAgICAgICBpZiAoY29sLnZpc2libGUpIG5ld0NvbHNldC5wdXNoKChjb2wucGlubmVkID8gXCLCp1wiIDogXCJcIikgKyBjb2wuaWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZih2aWV3KVxyXG4gICAgICAgICAgICB2aWV3LmNvbHVtbnMgPSBuZXdDb2xzZXQ7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICB0aGlzLmFycmF5Q29sdW1ucyA9IG5ld0NvbHNldDtcclxuXHJcbiAgICAgICAgLy8gRGEgcXVpIGluIHBvaSBkZXZvbm8gZXNzZXJlIGVzZWd1aXRpIFNPTE8gaW4gZmFzZSBkaSB3cml0ZVZhbHVlIHF1aW5kaSBkZXZvIGFzc2ljdXJhcm1pIGRpIHBhc3NhcmxpIG51bGwgaW4gdHV0dGkgaSBwYXNzYWdnaSBkaXZlcnNpIGRhIHF1ZWxsb1xyXG4gICAgICAgIGlmICh0aHMpIHtcclxuICAgICAgICAgICAgLy8gRGVmaW5pc2NvIHNlIGxhIGNvbG9ubmEgw6ggdmlzaWJpbGUgaW4gYmFzZSBhbGxhIHN1YSByYXBwcmVzZW50YXppb25lIGxvY2FsZSBpbiBDb2x1bW5zTGlzdFxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0VzVGgodGgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGguVmlzaWJsZSA9IHRoLkZpeGVkIHx8IChjb2x1bW5zQ2FjaGVbdGguSURdID8gY29sdW1uc0NhY2hlW3RoLklEXS52aXNpYmxlIDogdGguVmlzaWJsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoLkZpeGVkKSBmaXhlZFRoc1t0aC5JRF0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGgudGhWaXNpYmxlID0gdGgudGhGaXhlZCB8fCAoY29sdW1uc0NhY2hlW3RoLnRoXSA/IGNvbHVtbnNDYWNoZVt0aC50aF0udmlzaWJsZSA6IHRoLnRoVmlzaWJsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoLnRoRml4ZWQgfHwgdGgudGhHcm91cCkgZml4ZWRUaHNbdGgudGhdID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRkcykge1xyXG4gICAgICAgICAgICAvLyBEZWZpbmlzY28gc2UgbGEgY2VsbGEgw6ggdmlzaWJpbGUgaW4gYmFzZSBhbGxhIHN1YSByYXBwcmVzZW50YXppb25lIGxvY2FsZSBpbiBDb2x1bW5zTGlzdFxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRkcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IHRkID0gdGRzW2ldO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzRXNUZCh0ZCkpXHJcbiAgICAgICAgICAgICAgICAgICAgdGQuVmlzaWJsZSA9IGZpeGVkVGhzW3RkLklEXSB8fCAoY29sdW1uc0NhY2hlW3RkLklEXSA/IGNvbHVtbnNDYWNoZVt0ZC5JRF0udmlzaWJsZSA6IHRkLlZpc2libGUpO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIHRkLnRkVmlzaWJsZSA9IGZpeGVkVGhzW3RkLnRkXSB8fCAoY29sdW1uc0NhY2hlW3RkLnRkXSA/IGNvbHVtbnNDYWNoZVt0ZC50ZF0udmlzaWJsZSA6IHRkLnRkVmlzaWJsZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsaW5lYSBnbGkgb3JkaW5hbWVudGkgZGF0aSBmcmEgbGUgKipFc1RocyoqIGUgbGUgaW5mb3JtYXppb25pIGFsbCdpbnRlcm5vIGRlbGxhIFZpZXcgYmluZGF0YVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7QXBwU2VhcmNoPGFueT59IHZpZXcgQXBwU2VhcmNoIGRhIHV0aWxpenphcmUgcGVyIHF1ZXN0YSBvcGVyYXppb25lXHJcbiAgICAgKiBAcGFyYW0ge0VzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXX0gdGhzIENvbG9ubmUgZGVsbGEgdGFiZWxsYVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGFsaWduSGVhZGVyc09yZGVyaW5nKHRoczogRXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdLCB2aWV3OiBBcHBTZWFyY2g8YW55Pikge1xyXG4gICAgICAgIGxldCBvcmRlcnMgPSB2aWV3ID8gdmlldy5vcmRlcnMgOiB0aGlzLmFycmF5T3JkZXJzO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzRXNUaCh0aCkpIHtcclxuICAgICAgICAgICAgICAgIHRoLk9yZGVyID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBBc3NlZ25vIHR1dHRpIGdsaSBvcmRpbmFtZW50aSBjaGUgbWkgdmVuZ29ubyBkYSBBcHBTZWFyY2guIFNvbm8gaSBwacO5IGltcG9ydGFudGkuIE5vbiBmYWNjaW8gY2FjaGUgbyBjb3NlIHN0cmFubyBwZXJjaMOpIHRhbnRvIHF1ZXN0YVxyXG4gICAgICAgICAgICAgICAgLy8gdmFyaWFiaWxlIHNhcsOgIHNlbXByZSBtYXNzaW1vIDMgZWxlbWVudGlcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JkZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9yID0gb3JkZXJzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvci5pZCA9PSB0aC5JRClcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGguT3JkZXIgPSBvci5vcmRlcjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoLnRoT3JkZXIgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcmRlcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgb3IgPSBvcmRlcnNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9yLmlkID09IHRoLnRoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aC50aE9yZGVyID0gb3Iub3JkZXI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQYXJ0ZW5kbyBkYWdsaSAqKkVzVGRzKiogYmluZGF0aSBnZW5lcmEsIGFsbCdpbnRlcm5vIGRlbCBkaXppb25hcmlvICoqVE1QUm93VERzKiogdHV0dGkgaSBjb250ZXN0aSBkZWkgdmFyaSBvZ2dldHRpLlxyXG4gICAgICpcclxuICAgICAqIFZlbmdvbm8gZXNjbHVzaSBpIFREIFwiSW50ZXJuaVwiIGluIHF1YW50byB2ZW5nb25vIGdlbmVyYXRpIGRhZ2xpIG9yaWdpbmFsaSBxdWluZGkgaW5jbHVkZXJsaSB2b3JyZWJiZSBkaXJlIHJpZWZmZXR0dWFyZSBsZSBvcGVyYXppb25pIGR1ZSB2b2x0ZVxyXG4gICAgICpcclxuICAgICAqIENvc3RvOiAyIHNjYW4gRXNUaHMsIDEgc2NhbiBFc1Rkc1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdfSB0aHMgQ29sb25uZSBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKiBAcGFyYW0ge0VzVGRbXSB8IEVzVGREaXJlY3RpdmVbXX0gdGRzIENlbGxlIGRlbGxhIHRhYmVsbGFcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBldmFsdWF0ZVJvd1Rkcyh0aHM6IEVzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXSwgdGRzOiBFc1RkW10gfCBFc1RkRGlyZWN0aXZlW10pIHtcclxuICAgICAgICBpZiAodGRzLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGxldCB0aHNDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IEVzVGggfCBFc1RoRGlyZWN0aXZlIH0gPSB7fTtcclxuICAgICAgICBsZXQgY29sdW1uc0NhY2hlOiB7IFtpbmRleDogc3RyaW5nXTogRXNUYWJsZUNvbHVtbiB9ID0ge307XHJcblxyXG4gICAgICAgIGZvciAobGV0IGNvbGkgPSAwOyBjb2xpIDwgdGhpcy5Db2x1bW5zTGlzdC5sZW5ndGg7IGNvbGkrKykge1xyXG4gICAgICAgICAgICBsZXQgY29sID0gdGhpcy5Db2x1bW5zTGlzdFtjb2xpXTtcclxuICAgICAgICAgICAgY29sdW1uc0NhY2hlW2NvbC5pZF0gPSBjb2w7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcbiAgICAgICAgICAgIHRoc0NhY2hlW3RoaXMuaXNFc1RoKHRoKSA/IHRoLklEIDogdGgudGhdID0gdGg7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLlRNUFJvd1REcyA9IHt9O1xyXG4gICAgICAgIC8vIFZhcmlhYmlsZSBkJ2FwcG9nZ2lvIHBlciBwZXJtZXR0ZXJtaSBkaSBpbnNlcmlyZSB0dXR0ZSBsZSBjb2xvbm5lIFwiRml4ZWRcIiBkYXZhbnRpXHJcbiAgICAgICAgbGV0IGNvbnRleHRGaXhlZHM6IHsgW2NvbnRleHQ6IHN0cmluZ106IG51bWJlciB9ID0ge307XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRkID0gdGRzW2ldO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuaXNFc1RkKHRkKSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IHRoID0gdGhzQ2FjaGVbdGQuSURdO1xyXG4gICAgICAgICAgICAgICAgaWYgKCEhdGgpXHJcbiAgICAgICAgICAgICAgICAgICAgdGguX3JlZmVyZW5jZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFwiSUQgZGVsbCdvZ2dldG8gRXNUZCBub24gY29tcGF0aWJpbGUgY29uIGdsaSBJRCBkaWNoYXJhdGkgbmVnbGkgRXNUaDogXCIgKyB0ZC5JRDtcclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgaXNGaXhlZCA9ICh0aGlzLmlzRXNUaCh0aCkgJiYgdGguRml4ZWQpIHx8ICghdGhpcy5pc0VzVGgodGgpICYmICh0aC50aEZpeGVkIHx8IHRoLnRoR3JvdXApKTtcclxuICAgICAgICAgICAgICAgIGxldCBpdGVtVG9BZGQgPSA8YW55PnsgR3JvdXBBZ2dyZWdhdGlvbjogZmFsc2UsIEdyb3VwSGVhZGVyOiBmYWxzZSwgV3JhcHM6IHRydWUsIElEOiB0ZC5JRCwgVmlzaWJsZTogdGQuVmlzaWJsZSwgQ2xhc3M6IHRkLkNsYXNzLCBDb250ZW50OiB0ZC5Db250ZW50LCBSb3V0ZXJMaW5rOiB0ZC5Sb3V0ZXJMaW5rLCBUZW1wbGF0ZTogdGQuVGVtcGxhdGUgfTtcclxuICAgICAgICAgICAgICAgIGxldCBjdHggPSB0ZC5Db250ZXh0O1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuVE1QUm93VERzW2N0eF0pIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNGaXhlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5UTVBSb3dURHNbY3R4XS5zcGxpY2UoMCArIChjb250ZXh0Rml4ZWRzW2N0eF0rKyksIDAsIGl0ZW1Ub0FkZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLlRNUFJvd1REc1tjdHhdLnB1c2goaXRlbVRvQWRkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuUm93Q29udGV4dHMucHVzaChjdHgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuVE1QUm93VERzW2N0eF0gPSBbaXRlbVRvQWRkXTtcclxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0Rml4ZWRzW2N0eF0gPSBpc0ZpeGVkID8gMSA6IDBcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ib3VuZFNvdXJjZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBpdGVtID0gdGhpcy5ib3VuZFNvdXJjZVtpXTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgY3R4ID0gaXRlbS5faGFzaDtcclxuICAgICAgICAgICAgICAgICAgICBsZXQga2V5ID0gdGQudGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRoID0gdGhzQ2FjaGVbdGQudGRdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghIXRoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aC5fcmVmZXJlbmNlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBcIklEIGRlbGwnb2dnZXRvIEVzVGQgbm9uIGNvbXBhdGliaWxlIGNvbiBnbGkgSUQgZGljaGFyYXRpIG5lZ2xpIEVzVGg6IFwiICsgdGQudGQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ZC50ZElmIHx8ICghdGhpcy5pc0VzVGgodGgpICYmIHRoLnRoR3JvdXApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB0aENhc3RlZCA9IDxFc1RoRGlyZWN0aXZlPnRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgaXNGaXhlZCA9ICh0aGlzLmlzRXNUaCh0aCkgJiYgdGguRml4ZWQpIHx8ICghdGhpcy5pc0VzVGgodGgpICYmICh0aC50aEZpeGVkIHx8IHRoLnRoR3JvdXAgfHwgdGgudGhQaW5uZWQpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGl0ZW1Ub0FkZCA9IGl0ZW0uX2l0ZW0gP1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGFueT57IExlZnRCb3JkZXI6ICg8YW55PnRoQ2FzdGVkKS5fbGJvcmQsIFJpZ2h0Qm9yZGVyOiAoPGFueT50aENhc3RlZCkuX3Jib3JkLCBJRDoga2V5LCBQaW5uZWQ6IGNvbHVtbnNDYWNoZVt0ZC50ZF0ucGlubmVkLCBQaW5uZWRXaWR0aDogdGhDYXN0ZWQudGhQaW5uZWRXaWR0aCwgR3JvdXBIZWFkZXI6IGZhbHNlLCBHcm91cEFnZ3JlZ2F0aW9uOiBmYWxzZSwgVmlzaWJsZTogY29sdW1uc0NhY2hlW3RkLnRkXS52aXNpYmxlLCBXcmFwczogZmFsc2UsIENsYXNzOiB0ZC50ZENsYXNzLCBUZW1wbGF0ZTogdGhDYXN0ZWQudGhHcm91cCAmJiAhdGhpcy5TaG93SXRlbUdyb3Vwc0NvbHVtbnMgPyBudWxsIDogdGQuVGVtcGxhdGUgfSA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YW55PnsgTGVmdEJvcmRlcjogKDxhbnk+dGhDYXN0ZWQpLl9sYm9yZCwgUmlnaHRCb3JkZXI6ICg8YW55PnRoQ2FzdGVkKS5fcmJvcmQsIElEOiBrZXksIFBpbm5lZDogY29sdW1uc0NhY2hlW3RkLnRkXS5waW5uZWQsIFBpbm5lZFdpZHRoOiB0aENhc3RlZC50aFBpbm5lZFdpZHRoLCBHcm91cEhlYWRlcjogdGhDYXN0ZWQudGhHcm91cCwgR3JvdXBBZ2dyZWdhdGlvbjogISF0aENhc3RlZC50aEFnZ3JlZ2F0aW9uLCBWaXNpYmxlOiBjb2x1bW5zQ2FjaGVbdGQudGRdLnZpc2libGUsIFdyYXBzOiBmYWxzZSwgQ2xhc3M6IHRoQ2FzdGVkLnRoR3JvdXBDbGFzcyB8fCAnJywgQ29udGVudDogdGhpcy5nZXRHcm91cENlbGxEaXNwbGF5KDxHcm91cD5pdGVtLCBrZXksIDxFc1RoRGlyZWN0aXZlPnRoKSB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuVE1QUm93VERzW2N0eF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vbiBzZXJ2ZSBwacO5IGdyYXppZSBhbCBtZXRvZG8gKipvdmVGaXhlZENvbHVtbnNBdFRoZUJlZ2lubmluZyoqXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIChpc0ZpeGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgdGhpcy5UTVBSb3dURHNbY3R4XS5zcGxpY2UoMCArIChjb250ZXh0Rml4ZWRzW2N0eF0rKyksIDAsIGl0ZW1Ub0FkZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2Vsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuVE1QUm93VERzW2N0eF0ucHVzaChpdGVtVG9BZGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5Sb3dDb250ZXh0cy5wdXNoKGN0eCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLlRNUFJvd1REc1tjdHhdID0gW2l0ZW1Ub0FkZF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0Rml4ZWRzW2N0eF0gPSBpc0ZpeGVkID8gMSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFNlIG5vbiBobyBvZ2dldHRpIMOoIGludXRpbGUgY2hlIGNvbnRyb2xsbyBnbGkgZXJyb3JpLCBkYXRvIGNoZSBnbGkgZXMtdGQgbm9uIGVzaXN0ZXJhbm5vIGRpIGNlcnRvIGUgZGkgY29uc2VndWVuemEgZ2xpIGVzLXRoIG5vbiBzYXJhbm5vIHJlZmVyZW56aWF0aVxyXG4gICAgICAgIGlmKHRoaXMuVE1QQm91bmRTb3VyY2UubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgdmFyIGVycnM6IHN0cmluZ1tdID0gW107XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG4gICAgICAgICAgICBpZiAoIXRoLl9yZWZlcmVuY2VkKVxyXG4gICAgICAgICAgICAgICAgZXJycy5wdXNoKHRoaXMuaXNFc1RoKHRoKSA/IHRoLklEIDogdGgudGgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGVycnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICB2YXIgZXJySWRzID0gZXJycy5qb2luKCcsICcpO1xyXG4gICAgICAgICAgICB0aHJvdyBcIkwnSUQgZGkgdW5vIG8gcGnDuSBFc1RoIG5vbiBoYW5ubyBhbGN1biBFc1RkIGFzc29jaWF0bzogXCIgKyBlcnJJZHM7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGFydGVuZG8gZGFnbGkgKipFc1RocyoqIGJpbmRhdGkgZ2VuZXJhLCBhbGwnaW50ZXJubyBkZWwgZGl6aW9uYXJpbyAqKlRNUFJvd1RIcyoqIHR1dHRpIGkgY29udGVzdGkgZGVpIHZhcmkgb2dnZXR0aS5cclxuICAgICAqXHJcbiAgICAgKiBWZW5nb25vIGVzY2x1c2kgaSBUSCBcIkludGVybmlcIiBpbiBxdWFudG8gdmVuZ29ubyBnZW5lcmF0aSBkYWdsaSBvcmlnaW5hbGkgcXVpbmRpIGluY2x1ZGVybGkgdm9ycmViYmUgZGlyZSByaWVmZmV0dHVhcmUgbGUgb3BlcmF6aW9uaSBkdWUgdm9sdGVcclxuICAgICAqXHJcbiAgICAgKiBDb3N0bzogMSBzY2FuIEVzVGhzXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RoW10gfCBFc1RoRGlyZWN0aXZlW119IHRocyBDb2xvbm5lIGRlbGxhIHRhYmVsbGFcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBldmFsdWF0ZVJvd1Rocyh0aHM6IEVzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXSkge1xyXG4gICAgICAgIGlmICh0aHMubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgbGV0IGNvbHVtbnNMaXN0Q2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBFc1RhYmxlQ29sdW1uIH0gPSB7fTtcclxuICAgICAgICBsZXQgY2FzdGVkVmlldyA9IDxBcHBTZWFyY2g8YW55Pj50aGlzLlZpZXc7XHJcbiAgICAgICAgbGV0IGdyb3VwaW5nc1VuZGVmaW5lZCA9IHRoaXMudmlld01vZGUgJiYgKGNhc3RlZFZpZXcgJiYgIWNhc3RlZFZpZXcuZ3JvdXBpbmdzIHx8IGNhc3RlZFZpZXcuZ3JvdXBpbmdzLmxlbmd0aCA9PSAwKTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLkNvbHVtbnNMaXN0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBpdG0gPSB0aGlzLkNvbHVtbnNMaXN0W2ldO1xyXG4gICAgICAgICAgICBjb2x1bW5zTGlzdENhY2hlW2l0bS5pZF0gPSBpdG1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuVE1QUm93VEhzID0gW107XHJcbiAgICAgICAgbGV0IGZpeGVkID0gMDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcbiAgICAgICAgICAgIGxldCB0b0FkZDtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzRXNUaCh0aCkpIHtcclxuICAgICAgICAgICAgICAgIHRvQWRkID0geyBQaW5uZWQ6IGZhbHNlLCBJRDogdGguSUQsIFZpc2libGU6IHRoLlZpc2libGUsIENsYXNzOiB0aC5DbGFzcywgT3JkZXI6IHRoLk9yZGVyLCBPcmRlcmFibGU6IHRoLk9yZGVyYWJsZSwgVGVtcGxhdGU6IG51bGwsIENvbnRlbnQ6IHRoLkRlc2NyaXB0aW9uLCBXcmFwOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoLkZpeGVkKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuVE1QUm93VEhzLnNwbGljZSgwICsgKGZpeGVkKyspLCAwLCB0b0FkZCk7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5UTVBSb3dUSHMucHVzaCh0b0FkZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAodGgudGhJZiB8fCB0aC50aEdyb3VwKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IHRoQ2xhc3MgPSAodGgudGhDbGFzcyB8fCAnJykgKyAodGgudGhHcm91cCA/IFwiIGVzdC1jb2wtbWluXCIgOiBcIlwiKTtcclxuICAgICAgICAgICAgICAgIHRvQWRkID0geyBQaW5uZWQ6IGNvbHVtbnNMaXN0Q2FjaGVbdGgudGhdLnBpbm5lZCwgUGlubmVkV2lkdGg6IHRoLnRoUGlubmVkV2lkdGgsIElEOiB0aC50aCwgVmlzaWJsZTogdGgudGhWaXNpYmxlLCBDbGFzczogdGhDbGFzcywgT3JkZXI6IHRoLnRoT3JkZXIsIE9yZGVyYWJsZTogdGgudGhPcmRlcmFibGUsIFRlbXBsYXRlOiB0aC5UZW1wbGF0ZSwgQ29udGVudDogbnVsbCwgV3JhcDogZmFsc2UsIExlZnRCb3JkZXI6ICg8YW55PnRoKS5fbGJvcmQsIFJpZ2h0Qm9yZGVyOiAoPGFueT50aCkuX3Jib3JkIH07XHJcbiAgICAgICAgICAgICAgICB0aGlzLlRNUFJvd1RIcy5wdXNoKHRvQWRkKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTZSBobyB1biBtb2RlbGxvIGNoZSBkZXZlIGZ1bnppb25hcmUgYSByb3dncm91cGluZyBtYSBub24gw6ggYW5jb3JhIHN0YXRhIGVmZmV0dHVhdGEgbmVzc3VuYSByaWNlcmNhIHN1aSBncnVwcGkgcHJpbmNpcGFsaSAoZ3JvdXBpbmdzVW5kZWZpbmVkKVxyXG4gICAgICAgICAgICAgICAgLy8gbGkgZ2VuZXJvIGUgbWFuZG8gbGEgcHJpbWEgcmljZXJjYSBjaGUgZGV2J2Vzc2VyZSBzcGVkaXRhIGFsIGJhY2tlbmQgcGVyIGlsIHByaW1vIGNhcmljYW1lbnRvIGRlaSBncnVwcGlcclxuICAgICAgICAgICAgICAgIGlmIChncm91cGluZ3NVbmRlZmluZWQgJiYgKHRoLnRoQWdncmVnYXRpb24gfHwgdGgudGhHcm91cCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgZ3JvdXBBZ2dyZWdhdGlvbnM6IEdyb3VwT3JBZ2dyZWdhdGlvbltdID0gdGhpcy5nZXRHcm91cEFnZ3JlZ2F0aW9ucyh0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYXN0ZWRWaWV3Lmdyb3VwaW5ncylcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzdGVkVmlldy5ncm91cGluZ3MgPSBncm91cEFnZ3JlZ2F0aW9ucztcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc3RlZFZpZXcuZ3JvdXBpbmdzLnB1c2goLi4uZ3JvdXBBZ2dyZWdhdGlvbnMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLlJlc2VhcmNoTmVlZGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGV2YWx1YXRlSGVhZGVyc0dyb3VwaW5nSW5mb3ModGhzOiBFc1RoW10gfCBFc1RoRGlyZWN0aXZlW10pOiB7IGxlYWZzOiBFc1RoW10gfCBFc1RoRGlyZWN0aXZlW10sIGdyb3VwaW5nTGV2ZWw6IG51bWJlciwgcGFyZW50c0NhY2hlOiBhbnksIHRoc0NhY2hlOiBhbnkgfSB7XHJcbiAgICAgICAgLy8gUHJlZ2lybyBwZXIgdHJvdmFyZSBpIHBhcmVudFxyXG4gICAgICAgIGxldCBwYXJlbnRzQ2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBib29sZWFuIH0gPSB7fTtcclxuICAgICAgICBsZXQgdGhzQ2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBFc1RoRGlyZWN0aXZlIH0gPSB7fTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzRXNUaCh0aCkpIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgdGhzQ2FjaGVbdGgudGhdID0gdGg7XHJcbiAgICAgICAgICAgIGlmICh0aC50aFBhcmVudCAmJiAhcGFyZW50c0NhY2hlW3RoLnRoUGFyZW50XSlcclxuICAgICAgICAgICAgICAgIHBhcmVudHNDYWNoZVt0aC50aFBhcmVudF0gPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU2Vjb25kbyBnaXJvIHBlciBiZWNjYXJlIGlsIGxpdmVsbG8gbWFzc2ltbyBlIGxhIGxpc3RhIGRpIGZvZ2xpZSAodGggc2VuemEgcGFyZW50KVxyXG4gICAgICAgIGxldCBoTWF4TGV2ZWwgPSAwO1xyXG4gICAgICAgIGxldCBsZWFmczogYW55W10gPSBbXTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzRXNUaCh0aCkpIHsgbGVhZnMucHVzaCh0aCk7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgIC8vIFNlIHNvbm8gdW5hIGZvZ2xpYSB2ZWRvIHF1YW50aSBsaXZlbGxpIGNpIHNvbm8gc29wcmFcclxuICAgICAgICAgICAgaWYgKCFwYXJlbnRzQ2FjaGVbdGgudGhdKSB7XHJcbiAgICAgICAgICAgICAgICBsZWFmcy5wdXNoKHRoKTtcclxuICAgICAgICAgICAgICAgIGxldCB0bXAgPSB0aGlzLmp1bXBzVG9GaW5hbFBhcmVudCh0aCwgdGhzQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgaE1heExldmVsID0gdG1wID4gaE1heExldmVsID8gdG1wIDogaE1heExldmVsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4geyBsZWFmczogbGVhZnMsIGdyb3VwaW5nTGV2ZWw6IGhNYXhMZXZlbCwgcGFyZW50c0NhY2hlOiBwYXJlbnRzQ2FjaGUsIHRoc0NhY2hlOiB0aHNDYWNoZSB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2VuZXJhIGdsaSBoZWFkZXIgZ3JvdXBzIGRhIHVuYSBsaXN0YSBkaSBpbmZvIHN1aSB0aCBhbGwnaW50ZXJubyBkZWxsYSB2YXJpYWJpbGUgKipUTVBSb3dUaEdyb3VwcyoqXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZXZhbHVhdGVIZWFkZXJHcm91cHMoaW5mb3M6IHsgbGVhZnM6IEVzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXSwgZ3JvdXBpbmdMZXZlbDogbnVtYmVyLCBwYXJlbnRzQ2FjaGU6IGFueSwgdGhzQ2FjaGU6IGFueSB9KTogRXNUaFtdIHwgRXNUaERpcmVjdGl2ZVtdIHtcclxuICAgICAgICBpZiAoaW5mb3MuZ3JvdXBpbmdMZXZlbCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIC8vIEdpcm8gMi41LCBjcmVvIGwnb3V0cHV0IGRlaSByYWdncnVwcGFtZW50aSBwZXIgaGVhZGVyIGluIG1vZG8gZGEgbm9uIGRvdmVybWkgcHJlb2NjdXBhcmUgZGkgY2VsbGUgbm9uIGluaXppYWxpenphdGVcclxuICAgICAgICBsZXQgZXhwYW5kZWRHcm91cHMgPSBbXTtcclxuICAgICAgICBsZXQgdmlzaWJsZVVucGlubmVkTGVhZnM6IEVzVGhEaXJlY3RpdmVbXSA9ICg8YW55W10+aW5mb3MubGVhZnMpLmZpbHRlcigodDogRXNUaERpcmVjdGl2ZSkgPT4gdC50aFZpc2libGUgJiYgIXQudGhQaW5uZWQpO1xyXG4gICAgICAgIGZvciAobGV0IGwgPSAwOyBsIDwgaW5mb3MuZ3JvdXBpbmdMZXZlbDsgbCsrKSB7XHJcbiAgICAgICAgICAgIGV4cGFuZGVkR3JvdXBzLnB1c2goW10pO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZpc2libGVVbnBpbm5lZExlYWZzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgZXhwYW5kZWRHcm91cHNbbF0ucHVzaChcIlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIE9yZGlubyBsZSBmb2dsaWUgaW4gYmFzZSBhZ2xpIG9yZGluYW1lbnRpIGRlbGxlIGNvbG9ubmVcclxuICAgICAgICBsZXQgb3JkZXJlZExlYWZzID0gW107XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLk9yZGVyRGlyZWN0aXZlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgbGVhZjogRXNUaERpcmVjdGl2ZSA9IGluZm9zLnRoc0NhY2hlW3RoaXMuT3JkZXJEaXJlY3RpdmVzW2ldXTtcclxuICAgICAgICAgICAgaWYgKGxlYWYudGhWaXNpYmxlICYmICFsZWFmLnRoUGlubmVkKVxyXG4gICAgICAgICAgICAgICAgb3JkZXJlZExlYWZzLnB1c2gobGVhZik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBUZXJ6byBnaXJvIHBlciBjcmVhcmUgbCdhcnJheSBncm91cCBjb24gdHV0dGkgaSByaWZlcmltZW50aSBkZWwgY2Fzb1xyXG4gICAgICAgIGxldCBjdXJyZW50UGFyZW50ID0gXCJcIjtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9yZGVyZWRMZWFmcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgcmVmVGg6IEVzVGhEaXJlY3RpdmUgPSBvcmRlcmVkTGVhZnNbaV07XHJcbiAgICAgICAgICAgIGxldCBwcmV2VGg6IEVzVGhEaXJlY3RpdmUgPSBpIC0gMSA+PSAwID8gb3JkZXJlZExlYWZzW2ktMV0gOiBudWxsO1xyXG5cclxuICAgICAgICAgICAgLy8gUGFyZW50IGRpdmVyc28gZGEgcHJpbWEsIG1ldHRvIGlsIGJvcmRvIGEgc2luaXN0cmEgZSBhIGRlc3RyYSBkZWxsYSBjZWxsYSBwcmVjZWRlbnRlIChzZSBjJ8OoKVxyXG4gICAgICAgICAgICAvLyBBbGwndWx0aW1vIGdpcm8gbWV0dG8gaWwgYm9yZG8gYSBkZXN0cmEuIFR1dHRvIHF1ZXN0byBsbyByaWVzZWd1byBwZXIgb2duaSBjZWxsYSBpbiBtb2RvIGRhIHJpcHVsaXJlIGV2ZW50dWFsaSBhIGN1aSBhdmV2byBhc3NlZ25hdG8gdGFnIHByZWNlZGVudGVtZW50ZVxyXG4gICAgICAgICAgICAoPGFueT5yZWZUaCkuX2xib3JkID0gcmVmVGgudGhQYXJlbnQgIT0gY3VycmVudFBhcmVudDtcclxuICAgICAgICAgICAgKDxhbnk+cmVmVGgpLl9yYm9yZCA9IHZpc2libGVVbnBpbm5lZExlYWZzLmxlbmd0aCA9PSBpICsgMTtcclxuICAgICAgICAgICAgaWYgKHByZXZUaCkgKDxhbnk+cHJldlRoKS5fcmJvcmQgPSByZWZUaC50aFBhcmVudCAhPSBjdXJyZW50UGFyZW50O1xyXG5cclxuICAgICAgICAgICAgY3VycmVudFBhcmVudCA9IHJlZlRoLnRoUGFyZW50O1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gUGVyIG9nbmkgZ3J1cHBvIHNyb3RvbG8gaWwgcGFyZW50IG5lbGxhIG1hdHJpY2UgZGVpIHJhZ2dydXBwYW1lbnRpXHJcbiAgICAgICAgICAgIGZvciAobGV0IGwgPSAwOyBsIDwgaW5mb3MuZ3JvdXBpbmdMZXZlbDsgbCsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgcGFyZW50ID0gcmVmVGgudGhQYXJlbnQ7XHJcbiAgICAgICAgICAgICAgICBpZiAocGFyZW50ICYmICFyZWZUaC50aFBpbm5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4cGFuZGVkR3JvdXBzW2xdW2ldID0gcGFyZW50XHJcbiAgICAgICAgICAgICAgICAgICAgcmVmVGggPSBpbmZvcy50aHNDYWNoZVtwYXJlbnRdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBRdWFydG8gZ2lybyBwZXIgY29tcGF0dGFybG8gbmVsbCdlbGVtZW50byBmaW5hbGUgc3UgY3VpIGJpbmRhcm1pXHJcbiAgICAgICAgY3VycmVudFBhcmVudCA9IFwiXCI7XHJcbiAgICAgICAgbGV0IGN1cnJlbnRTcGFuID0gMDtcclxuICAgICAgICB0aGlzLlRNUFJvd1RoR3JvdXBzID0gW107XHJcbiAgICAgICAgZm9yIChsZXQgbCA9IDA7IGwgPCBleHBhbmRlZEdyb3Vwcy5sZW5ndGg7IGwrKykge1xyXG4gICAgICAgICAgICBsZXQgbGV2ZWxBcnJheTogeyBTcGFuOiBudW1iZXIsIFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+LCBQaW5uZWQ/OiBib29sZWFuLCBCb3JkZXJzPzogYm9vbGVhbiB9W10gPSBbXTtcclxuICAgICAgICAgICAgdGhpcy5UTVBSb3dUaEdyb3Vwcy5wdXNoKGxldmVsQXJyYXkpXHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5TZWxlY3Rpb24gfHwgdGhpcy5IYXNQaW5uZWRDb2x1bW5zKVxyXG4gICAgICAgICAgICAgICAgbGV2ZWxBcnJheS5wdXNoKHsgU3BhbjogMSwgVGVtcGxhdGU6IG51bGwsIFBpbm5lZCA6IHRoaXMuSGFzUGlubmVkQ29sdW1ucyB9KTtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGggPSAwOyBoIDwgZXhwYW5kZWRHcm91cHNbbF0ubGVuZ3RoOyBoKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCBpdGVtID0gZXhwYW5kZWRHcm91cHNbbF1baF07XHJcbiAgICAgICAgICAgICAgICBpZiAoaXRlbSA9PSBjdXJyZW50UGFyZW50KVxyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTcGFuKys7XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpZihjdXJyZW50U3BhbiA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsQXJyYXkucHVzaCh7IFNwYW46IGN1cnJlbnRTcGFuLCBUZW1wbGF0ZTogKGN1cnJlbnRQYXJlbnQgPyBpbmZvcy50aHNDYWNoZVtjdXJyZW50UGFyZW50XS5UZW1wbGF0ZSA6IG51bGwpLCBCb3JkZXJzOiAhIWN1cnJlbnRQYXJlbnQgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFNwYW4gPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRQYXJlbnQgPSBpdGVtO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBVbHRpbWEgYWdnaXVudGEgY2hlIGFsdHJpbWVudGkgbWkgcmltYXJyZWJiZSBpbiBjYWNoZVxyXG4gICAgICAgICAgICBsZXZlbEFycmF5LnB1c2goeyBTcGFuOiBjdXJyZW50U3BhbiwgVGVtcGxhdGU6IChjdXJyZW50UGFyZW50ID8gaW5mb3MudGhzQ2FjaGVbY3VycmVudFBhcmVudF0uVGVtcGxhdGUgOiBudWxsKSwgQm9yZGVyczogISFjdXJyZW50UGFyZW50IH0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuUmVtb3ZhbClcclxuICAgICAgICAgICAgICAgIGxldmVsQXJyYXkucHVzaCh7IFNwYW46IDEsIFRlbXBsYXRlOiBudWxsIH0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuRXhwb3J0IHx8IHRoaXMuSGlkZGVuQ29sdW1ucyB8fCB0aGlzLkNvbHVtbnNPcmRlcmluZyB8fCB0aGlzLkNvcm5lck1lbnVPcHRpb25zKVxyXG4gICAgICAgICAgICAgICAgbGV2ZWxBcnJheS5wdXNoKHsgU3BhbjogMSwgVGVtcGxhdGU6IG51bGwgfSk7XHJcblxyXG4gICAgICAgICAgICBjdXJyZW50U3BhbiA9IDA7XHJcbiAgICAgICAgICAgIGN1cnJlbnRQYXJlbnQgPSBcIlwiO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGNvbGEgaWwgbnVtZXJvIGRpIHNhbHRpIGRhIHVuIGhlYWRlciBmb2dsaWEgYWxsJ3VsdGltbyBwYXJlbnQgZGVsbGEgY2F0ZW5hXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUganVtcHNUb0ZpbmFsUGFyZW50KHRoOiBFc1RoRGlyZWN0aXZlLCB0aHNDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IEVzVGhEaXJlY3RpdmUgfSkge1xyXG4gICAgICAgIGxldCBqdW1wcyA9IDA7IGxldCBwYXJlbnQgPSBudWxsO1xyXG4gICAgICAgIGRvIHtcclxuICAgICAgICAgICAgcGFyZW50ID0gdGgudGhQYXJlbnRcclxuICAgICAgICAgICAgaWYgKHBhcmVudClcclxuICAgICAgICAgICAgICAgIGp1bXBzKys7XHJcbiAgICAgICAgICAgIHRoID0gdGhzQ2FjaGVbcGFyZW50XTtcclxuICAgICAgICB9IHdoaWxlIChwYXJlbnQpXHJcbiAgICAgICAgcmV0dXJuIGp1bXBzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGF0YSB1bmEgZGlyZXR0aXZhIEVzVGggcmVzdGl0dWlzY2UgbGEgbGlzdGEgZGVsbGUgYWdncmVnYXppb25pIHJpY2hpZXN0YSBwZXIgcXVlc3RhIGNvbG9ubmEgbyBpbCBncnVwcG8gY2hlIHJhcHByZXNlbnRhXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7RXNUaERpcmVjdGl2ZX0gdGggRGlyZXR0aXZhXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHtHcm91cE9yQWdncmVnYXRpb25bXX0gTGlzdGEgZGVpIGdydXBwaSBvIGFnZ3JlZ2F6aW9uaSByZWxhdGl2aSBhbGxhIERpcmV0dGl2YSBwYXNzYXRhXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0R3JvdXBBZ2dyZWdhdGlvbnModGg6IEVzVGhEaXJlY3RpdmUpOiBHcm91cE9yQWdncmVnYXRpb25bXSB7XHJcbiAgICAgICAgbGV0IHJldCA9IFtdO1xyXG4gICAgICAgIC8vIEVzOiAne21pbjpkZC9NTS95eXl5fSAtIHttYXg6ZGQvTU0veXl5eX0nXHJcbiAgICAgICAgaWYgKHRoLnRoQWdncmVnYXRpb24pIHtcclxuICAgICAgICAgICAgdGhpcy5nZXRFc1RoRGlyZWN0aXZlTGlzdE9mQWdncmVnYXRpb25zKHRoKS5mb3JFYWNoKChhZ2c6IFRoQWdncmVnYXRpb24pID0+IHtcclxuICAgICAgICAgICAgICAgIGxldCBpc2RhdGUgPSBhZ2cuZm9ybWF0ICYmIFsnc21hbGwnLCAnbG9uZycsICd2ZXJ5bG9uZyddLmluY2x1ZGVzKGFnZy5mb3JtYXQpO1xyXG4gICAgICAgICAgICAgICAgbGV0IGlzbnVtYmVyID0gYWdnLmZvcm1hdCAmJiBhZ2cuZm9ybWF0LnN0YXJ0c1dpdGgoXCJGXCIpICYmICFOdW1iZXIuaXNOYU4oYWdnLmZvcm1hdC5jaGFyQXQoMSkpICYmIGFnZy5mb3JtYXQubGVuZ3RoID09IDI7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCFpc2RhdGUgJiYgIWlzbnVtYmVyICYmIGFnZy5mb3JtYXQpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgXCJMZSBhZ2dlcmdhemlvbmkgc3VwcG9ydGF0ZSBkYWxsJ2VzLXRhYmxlIHNvbm8gc29sbyAnc21hbGwnLCAnbG9uZycsICd2ZXJ5bG9uZycgcGVyIGxlIGRhdGUgZSAnRjAtOScgcGVyIGkgbnVtZXJpXCI7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0LnB1c2gobmV3IEdyb3VwT3JBZ2dyZWdhdGlvbih0aC50aCwgYWdnLmZ1bmMsIGlzZGF0ZSA/ICdkYXRlJyA6IGlzbnVtYmVyID8gJ251bWJlcicgOiAnc3RyaW5nJykpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGgudGhHcm91cClcclxuICAgICAgICAgICAgcmV0LnB1c2gobmV3IEdyb3VwT3JBZ2dyZWdhdGlvbih0aC50aCwgbnVsbCkpXHJcblxyXG4gICAgICAgIHJldHVybiByZXQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEYXRhIHVuYSBkaXJldHRpdmEgY29uIHVuIGZvcm1hdG8gcmVzdGl0dWlzY2UgdHV0dGUgbGUgY29wcGllIEZ1bnppb25lIGRpIEFnZ3JlZ2F6aW9uZSAtIEZvcm1hdG9cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtFc1RoRGlyZWN0aXZlfSB0aCBEaXJldHRpdmEgRXNUaCBkaSBjdWkgY2FsY29sYXJlIGxlIGZ1bnppb25pIGRpIGFnZ3JlZ2F6aW9uZSB1c2F0ZVxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7eyBmdW5jOiBzdHJpbmcsIGZvcm1hdDogc3RyaW5nIH1bXX0gTGlzdGEgZGVsbGUgZnVuemlvbmkgZGkgYWdncmVnYXppb25lIHJpbGV2YXRlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0RXNUaERpcmVjdGl2ZUxpc3RPZkFnZ3JlZ2F0aW9ucyh0aDogRXNUaERpcmVjdGl2ZSk6IFRoQWdncmVnYXRpb25bXSB7XHJcbiAgICAgICAgaWYgKCF0aC50aEFnZ3JlZ2F0aW9uKVxyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcblxyXG4gICAgICAgIC8vIFNlIGhvIGdpw6AgZWZmZXR0dWF0byBxdWVzdG8gY2FsY29sbyBwZXIgcXVlc3RvIHRoIHJlc3RpdHVpc2NvIGxhIHZlcnNpb25lIGluIGNhY2hlXHJcbiAgICAgICAgaWYodGguX3RoQWdncmVnYXRpb25zKVxyXG4gICAgICAgICAgICByZXR1cm4gdGguX3RoQWdncmVnYXRpb25zO1xyXG5cclxuICAgICAgICBsZXQgcmV0ID0gW107XHJcbiAgICAgICAgbGV0IGRpc3BsYXkgPSB0aC50aEFnZ3JlZ2F0aW9uO1xyXG4gICAgICAgIHZhciBtYXRjaGVzID0gZGlzcGxheS5tYXRjaCgve1thLXpBLVowLTlcXC86XSp9L2dpKTtcclxuICAgICAgICBpZiAoIW1hdGNoZXMpIHJldHVybiBbXTtcclxuICAgICAgICBtYXRjaGVzLmZvckVhY2gobSA9PiB7XHJcbiAgICAgICAgICAgIGxldCBzcGxpdCA9IG0uc3BsaXQoXCI6XCIpO1xyXG4gICAgICAgICAgICBsZXQgZnVuYyA9IG0sIGZvcm1hdCA9IFwiXCI7XHJcbiAgICAgICAgICAgIGlmIChzcGxpdC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBFc2NsdWRvIHByaW1vIGUgdWx0aW1vIGNhcmF0dGVyZSAobGUgZ3JhZmZlKVxyXG4gICAgICAgICAgICAgICAgZnVuYyA9IHNwbGl0WzBdLnN1YnN0cigxKTtcclxuICAgICAgICAgICAgICAgIGZvcm1hdCA9IHNwbGl0WzFdLnN1YnN0cigwLCBzcGxpdFsxXS5sZW5ndGggLSAxKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0LnB1c2goeyBmdW5jOiA8J21pbicgfCAnbWF4JyB8ICdzdW0nID5mdW5jLCBmb3JtYXQ6IGZvcm1hdCwgbWF0Y2g6IG0gfSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoLl90aEFnZ3JlZ2F0aW9ucyA9IHJldDtcclxuICAgICAgICByZXR1cm4gcmV0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGNoZSBnZW5lcmEgbCdvcmRpbmUgZGkgZGVmYXVsdCBkZWxsZSBjb2xvbm5lXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtBcHBTZWFyY2g8YW55Pn0gdmlldyBBcHBTZWFyY2ggZGEgdXRpbGl6emFyZSBwZXIgcXVlc3RhIG9wZXJhemlvbmVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZW5lcmF0ZURlZmF1bHRPcmRlcih0aHM6IEVzVGhbXSB8IEVzVGhEaXJlY3RpdmVbXSwgdmlldzogQXBwU2VhcmNoPGFueT4pIHtcclxuICAgICAgICBpZiAodGhzLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGxldCBvcmRlcmluZ3MgPSB0aGlzLnZpZXdNb2RlID8gdmlldy5jb2x1bW5fb3JkZXJpbmcgOiB0aGlzLmFycmF5Q29sdW1uT3JkZXJpbmc7XHJcbiAgICAgICAgLy8gR2VuZXJvIG9yZGluYW1lbnRvIGRpIGRlZmF1bHQgZGEgMCBmaW5vIGEgZG92ZSBkZXZlIGFycml2YXJlLiBTaXR1YXppb25lIGF0dHVhbGUgc2VuemEgaG90cG90YXRvXHJcbiAgICAgICAgaWYgKCFvcmRlcmluZ3MgfHwgb3JkZXJpbmdzLmxlbmd0aCA9PSAwKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcbiAgICAgICAgICAgICAgICBsZXQgb3JkZXIgPSB0aGlzLmlzRXNUaCh0aCkgPyB0aC5JRCA6IHRoLnRoO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5PcmRlckRpcmVjdGl2ZXMucHVzaChvcmRlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICB0aGlzLk9yZGVyRGlyZWN0aXZlcyA9IG9yZGVyaW5ncztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGxpY2EgbCdvcmRpbmUgc3BlY2lmaWNhdG8gYWxsZSB2YXJpZSBjb2xvbm5lXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtBcHBTZWFyY2g8YW55Pn0gdmlldyBBcHBTZWFyY2ggZGEgdXRpbGl6emFyZSBwZXIgcXVlc3RhIG9wZXJhemlvbmVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZmluYWxpemUgU2UgKip0cnVlKiogc2lnbmlmaWNhIGNoZSBub24gbWkgYXNwZXR0byBkaSBkb3ZlciBlZmZldHR1YXJlIGFsdHJlIG9wZXJhemlvbmkgZSBwb3NzbyByZW5kZXJpenphcmUgbGEgc2l0dWF6aW9uZSBpbiBiYXNlIGFpIFJvd0NvbnRleHRcclxuICAgICAqIFNlbnphIGZpbmFsaXplIHNpZ25pZmljYSBjaGUgbWkgYXNwZXR0byBhbHRyZSBvcGVyYXppb25pIGNoZSBwcmltYSBvIHBvaSByaWNoaWFtZXJhbm5vIHF1ZXN0YSBmdW56aW9uZSBjb2wgZmluYWxpemUuXHJcbiAgICAgKlxyXG4gICAgICogQWQgZXNlbXBpbywgdW5hIHZvbHRhIHNlbGV6aW9uYXRvIG9yZGluYW1lbnRvIGZpc2ljby9sb2dpY28gZGVsbGUgY29sb25uZSBzbyBjaGUgcGFydGUgdW4gYWx0cmEgcmljZXJjYSBjaGUgbWkgcml2YWxvcml6emVyw6AgZGEgXCJ3cml0ZVZhbHVlXCIsIGNoZSBnacOgIGNoaWFtYSBxdWVzdGEgZnVuemlvbmUuXHJcbiAgICAgKiBNZXR0ZW5kbyBzb2xvIGxhIGNoaWFtYXRhIGRhIFwid3JpdGVWYWx1ZVwiIGNvbWUgXCJmaW5hbGl6emFudGVcIiBtaSBhc3NpY3VybyBjaGUgc21hbmF0dGFtZW50aSBhIGZyb250ZW5kIG5vbiBjYXVzaW5vIGZsaWNrZXJpbmcgZmlubyBhIHF1YW5kbyBub24gc2Vydm9ub1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGFwcGx5T3JkZXJpbmcodmlldzogQXBwU2VhcmNoPGFueT4sIGZpbmFsaXplOiBib29sZWFuKSB7XHJcbiAgICAgICAgLy8gR2VuZXJvIG9yZGluYW1lbnRvIHBlciBnbGkgaGVhZGVyXHJcbiAgICAgICAgbGV0IG5ld0hlYWRlcnMgPSBbXTtcclxuXHJcbiAgICAgICAgLy8gU2UgZGV2byBmaW5hbGl6emFyZSBhZ2dhbmNpbyB0dXR0ZSBsZSB2YXJpYWJpbGkgZGkgYmluZFxyXG4gICAgICAgIGlmIChmaW5hbGl6ZSkge1xyXG4gICAgICAgICAgICB0aGlzLk9yZGVyRGlyZWN0aXZlcy5mb3JFYWNoKG8gPT4ge1xyXG4gICAgICAgICAgICAgICAgbGV0IGhlYWVkckl0ZW0gPSB0aGlzLlRNUFJvd1RIcy5maWx0ZXIodCA9PiB0LklEID09IG8pWzBdO1xyXG4gICAgICAgICAgICAgICAgbmV3SGVhZGVycy5wdXNoKGhlYWVkckl0ZW0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy5UTVBSb3dUSHMgPSBuZXdIZWFkZXJzO1xyXG5cclxuICAgICAgICAgICAgLy8gR2VuZXJvIG9yZGluYW1lbnRvIHBlciBsZSBjZWxsZVxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuUm93Q29udGV4dHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCBjb250ZXh0ID0gdGhpcy5UTVBSb3dURHNbdGhpcy5Sb3dDb250ZXh0c1tpXV07XHJcbiAgICAgICAgICAgICAgICBsZXQgbmV3Q29udGV4dCA9IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuT3JkZXJEaXJlY3RpdmVzLmZvckVhY2gobyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbnRleHRJdGVtID0gY29udGV4dC5maWx0ZXIodCA9PiB0LklEID09IG8pWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIG5ld0NvbnRleHQucHVzaChjb250ZXh0SXRlbSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLlRNUFJvd1REc1t0aGlzLlJvd0NvbnRleHRzW2ldXSA9IG5ld0NvbnRleHQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLnZpZXdNb2RlKVxyXG4gICAgICAgICAgICB2aWV3LmNvbHVtbl9vcmRlcmluZyA9IHRoaXMuT3JkZXJEaXJlY3RpdmVzO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgdGhpcy5hcnJheUNvbHVtbk9yZGVyaW5nID0gdGhpcy5PcmRlckRpcmVjdGl2ZXM7XHJcblxyXG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vICNlbmRyZWdpb25cclxuXHJcbiAgICAvLyAjcmVnaW9uIEdlc3Rpb25lIHJhZ2dydXBwYW1lbnRpIHBlciByaWdhXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPdHRpZW5lIHVuIGVsZW1lbnRvIGRpIHNlcGFyYXppb25lIGZyYSBHcnVwcGkgY2hlIHNlcnZlIHBlciBwYWdpbmFyZSBsZSByaWNlcmNoZSBhbGwnaW50ZXJubyBkaSBvZ25pIHNpbmdvbG8gZ3J1cHBvXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7QXBwU2VhcmNoPGFueT59IHZpZXcgVmlldyB1dGlsaXp6YXRhIHBlciBsYSByaWNlcmNhLiBNZSBuZSBzYWx2byBpIHBhcmFtZXRyaSBuZWwgc2VwYXJhdG9yZSBhdHR1YWxlIGRhdG8gY2hlIG5lIGhvIGJpc29nbm8gcGVyIGNhcmljYXJlIGFsdHJpIGVsZW1lbnRpXHJcbiAgICAgKiBmYWNlbnRpIHJpZmVyaW1lbnRvIGFsbG8gc3Rlc3NvIGNvbnRlc3RvXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFyZW50IFBhcmVudCBwYXRoIGNoZSByYXBwcmVzZW50YSBhIHF1YWxlIGdydXBwbyDDqCBhZmZpYmJpYXRvIHF1ZXN0byBzZXBhcmF0b3JlXHJcbiAgICAgKiBAcGFyYW0ge0dyb3VwUm91dGVGcmFnbWVudFtdfSByb3V0ZSBSb3V0ZSBwYXRoIGNoZSByYXBwcmVzZW50YSBhIHF1YWxlIGdydXBwbyDDqCBhZmZpYmJpYXRvIHF1ZXN0byBzZXBhcmF0b3JlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbGV2ZWwgTGl2ZWxsbyBkZWwgZ3J1cHBvIGRpIGN1aSBxdWVzdG8gZWxlbWVudG8gw6ggc2VwYXJhdG9yZSwgdmllbmUgdXNhdG8gcGVyIGFwcGxpY2FyZSBsYSBjbGFzc2UgXCJlc3QtbHZsLXt7bGV2ZWx9fVwiXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHthbnl9IEVsZW1lbnRvIGRpIHNlcGFyYXppb25lIGNvbnRlbmVudGUgdHV0dGkgaSBiaW5kIHBlciBwcmVzZW50YXJlIHVuYSBwYWdpbmF6aW9uZSBzb3R0byBxdWVzdG8gZ3J1cHBvIGxhdG8gaW50ZXJmYWNjaWFcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZXRHcm91cFNlcGFyYXRvcih2aWV3OiBBcHBTZWFyY2g8YW55PiwgcGFyZW50OiBzdHJpbmcsIHJvdXRlOiBHcm91cFJvdXRlRnJhZ21lbnRbXSwgbGV2ZWw6IG51bWJlciwgc2VhcmNoZXM6ICdncm91cHMnIHwgJ2l0ZW1zJyk6IEdyb3VwUGFnZXIge1xyXG4gICAgICAgIGxldCBpdGVtID0gbmV3IEdyb3VwUGFnZXIobGV2ZWwsIHJvdXRlLCBwYXJlbnQsIE9iamVjdC5hc3NpZ24oe30sIHZpZXcpLCBzZWFyY2hlcyk7XHJcbiAgICAgICAgaXRlbS5idXR0b25zID0gdGhpcy5nZXRQYWdlc0FycmF5KDYsIHZpZXcucGFnZSwgdmlldy5wYWdlcyk7XHJcbiAgICAgICAgdGhpcy5jYWxjdWxhdGVIYXNoKFtpdGVtXSk7XHJcbiAgICAgICAgcmV0dXJuIGl0ZW07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTcG9zdGEgbGEgcmljZXJjYSBkaSB1bmEgcGFnaW5hIGluIGF2YW50aSAobyBpbmRpZXRybylcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcGFnZSBOdW1lcm8gZGkgcGFnaW5lIGRhIGFnZ2l1bmdlcmUgKG8gc290dHJhcnJlLCBzZSBuZWdhdGl2bykgYWxsYSBwYWdpbmEgYXR0dWFsZVxyXG4gICAgICogQHBhcmFtIHthbnl9IHBhZ2VyIEVsZW1lbnRvIGRpIHNlcGFyYXppb25lIHN1IGN1aSDDqCBlZmZldHR1YXRhIGxhIHJpY2VyY2FcclxuICAgICAqL1xyXG4gICAgcHVibGljIGFkZFRvUGFnZUdyb3VwKHBhZ2U6IG51bWJlciwgcGFnZXI6IEdyb3VwUGFnZXIpIHtcclxuICAgICAgICB0aGlzLmdvVG9QYWdlR3JvdXAocGFnZXIudmlldy5wYWdlICsgcGFnZSwgcGFnZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3Bvc3RhIGxhIHJpY2VyY2EgYWxsYSBwYWdpbmEgc3BlY2lmaWNhdGFcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcGFnZSBQYWdpbmEgYSBjdWkgbmF2aWdhcmVcclxuICAgICAqIEBwYXJhbSB7YW55fSBwYWdlciBFbGVtZW50byBkaSBzZXBhcmF6aW9uZSBzdSBjdWkgw6ggZWZmZXR0dWF0YSBsYSByaWNlcmNhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnb1RvUGFnZUdyb3VwKHBhZ2U6IG51bWJlciwgcGFnZXI6IEdyb3VwUGFnZXIpIHtcclxuXHJcbiAgICAgICAgbGV0IGFwcFNlYXJjaEVsZW1lbnQgPSBwYWdlci52aWV3O1xyXG4gICAgICAgIGlmIChwYWdlID09PSAwIHx8IHBhZ2UgPiBhcHBTZWFyY2hFbGVtZW50LnBhZ2VzKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGFwcFNlYXJjaEVsZW1lbnQucGFnZSA9IHBhZ2U7XHJcbiAgICAgICAgcGFnZXIuYnV0dG9ucyA9IHRoaXMuZ2V0UGFnZXNBcnJheSg2LCBhcHBTZWFyY2hFbGVtZW50LnBhZ2UsIGFwcFNlYXJjaEVsZW1lbnQucGFnZXMpO1xyXG5cclxuICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KGZhbHNlLCBhcHBTZWFyY2hFbGVtZW50KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERhdGEgdW5hIGNvbG9ubmEgZWZmZXR0dWEgbGEgcmllbWlzc2lvbmUgZGkgdHV0dGUgbGUgcmljZXJjaGUgcmVsYXRpdmUuXHJcbiAgICAgKiBcclxuICAgICAqIEVzLiBIbyAyIGNhbXBpIGRpIGdydXBwbyBlIGhvIGVzcGFuc28gZmlubyBhIHZlZGVyZSBpIHZhbG9yaSBmaW5vIGFkIHVuIGxpdmVsbG8gcXVhbHNpYXNpLlxyXG4gICAgICogQ2xpY2NvIGwnb3JkaW5hbWVudG8gc3VsIHNlY29uZG8gZ3J1cHBvLlxyXG4gICAgICogVHV0dGUgbGUgcmljZXJjaGUgcmVsYXRpdmUgYWkgcHJpbWkgZ3J1cHBpIGRldm9ubyBlc3NlcmUgcmllc2VndWl0ZS4gUXVhbmRvIGkgcmlzdWx0YXRpIGFycml2ZXJhbm5vIGNpIHBlbnNlcsOgIGlsIG1ldG9kbyAqKmJpbmREaXNwbGF5VG9Mb2FkZWRJdGVtc09yR3JvdXBzKipcclxuICAgICAqIGEgdGFnbGlhcmUgdmlhIGdsaSBvZ2dldHRpIG5vbiBwacO5IHZpc3VhbGl6emF0aVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY29sdW1uIENvbG9ubmEgc3UgY3VpIHNpIMOoIGVmZmV0dHVhdGEgdW4nb3BlcmF6aW9uZSBkaSBvcmRpbmFtZW50b1xyXG4gICAgICogQHBhcmFtIHtBcHBPcmRlcmluZ1tdfSBvcmRlcmluZ3MgRGlyZXR0aXZlIGRpIG9yZGluYW1lbnRvIGRhIGFwcGxpY2FyZSBhbGxlIHZhcmllIHNvdHRvcmljZXJjaGVcclxuICAgICAqIFxyXG4gICAgICogQHRvZG86IFRlc3RhcmVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBlbWl0Um93R3JvdXBpbmdTZWFyY2hlcyhjb2x1bW46IHN0cmluZywgb3JkZXJpbmdzOiBBcHBPcmRlcmluZ1tdKSB7XHJcbiAgICAgICAgLy8gUGVyIHR1dHRlIGxlIHJpY2VyY2hlIGludGVybWVkaWUgY2hlIGRldm8gcml2YWx1dGFyZSBsZSByZS1lbWl0dG8gaW4gbW9kbyBkYSBhZ2dpb3JuYXJnbGkgaSBkYXRpXHJcbiAgICAgICAgdmFyIG1lYW5pbmdmdWxBcHBTZWFyY2hlcyA9IHRoaXMuZ3JvdXBTZWFyY2hSZXF1ZXN0c0NhY2hlLmZpbHRlcih0ID0+IHQuZ3JvdXBfY29sdW1uID09IGNvbHVtbikubWFwKHQgPT4gdC52aWV3KTtcclxuXHJcbiAgICAgICAgLy8gU2Ugbm9uIG5lIHRyb3ZvIHNpZ25pZmljYSBjaGUgaG8gZmF0dG8gbCdvcmRpbmFtZW50byBvIHN1Z2xpIGl0ZW0sIG8gc3UgY29sb25uZSByZWxhdGl2ZSBhIHVuIHNvdHRvZ3J1cHBvIG5vbiBjYXJpY2F0b1xyXG4gICAgICAgIGlmKCFtZWFuaW5nZnVsQXBwU2VhcmNoZXMgfHwgbWVhbmluZ2Z1bEFwcFNlYXJjaGVzLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICBtZWFuaW5nZnVsQXBwU2VhcmNoZXMgPSB0aGlzLmdyb3VwU2VhcmNoUmVxdWVzdHNDYWNoZS5maWx0ZXIodCA9PiAhdC5ncm91cF9jb2x1bW4pLm1hcCh0ID0+IHQudmlldyk7XHJcblxyXG4gICAgICAgIC8vIFNlIG5vbiBuZSB0cm92byBxdWkgc2lnbmlmaWNhIGNoZSBzdG8gb3JkaW5hbmRvIHN1IGNvbG9ubmUgcmVsYXRpdmUgYSB1biBzb3R0b2dydXBwbyBub24gY2FyaWNhdG9cclxuICAgICAgICBpZighbWVhbmluZ2Z1bEFwcFNlYXJjaGVzIHx8IG1lYW5pbmdmdWxBcHBTZWFyY2hlcy5sZW5ndGggPT0gMClcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBtZWFuaW5nZnVsQXBwU2VhcmNoZXMuZm9yRWFjaChhcyA9PiB7XHJcbiAgICAgICAgICAgIC8vIE92dmlhbWVudGUgZ2xpIG9yaWRuYW1lbnRpIGRldm9ubyBlc3NlcmUgcXVlbGxpIGFwcGVuYSBnZW5lcmF0aVxyXG4gICAgICAgICAgICBhcy5vcmRlcnMgPSBvcmRlcmluZ3M7XHJcbiAgICAgICAgICAgIGFzLnNhdmVkc3RhdGUgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KGZhbHNlLCBhcyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIZWxwZXIgY2hlIGNhbGNvbGEgaWwgY29udGVudXRvIGRpIHVuYSBjZWxsYSByZWxhdGl2YSBhIHVuIGdydXBwbyByaWdhLCB0ZW5lbmRvIGNvbnRvIGRlbCBmb3JtYXRvIGRlbGxlIGV2ZW50dWFsaSBhZ2dyZWdhemlvbmlcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtHcm91cH0gZ3JwIEdydXBwbyBkaSBjdWkgbW9zdHJhcmUgbGUgY2VsbGVcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjZWxsIENlbGxhIGF0dHVhbGUgZGkgY3VpIGNhbGNvbGFyZSBpbCB0ZXN0b1xyXG4gICAgICogQHBhcmFtIHtFc1RoRGlyZWN0aXZlfSBoZWFkZXIgSGVhZGVyIHJlbGF0aXZvIGFsbGEgY2VsbGEgYXR0dWFsZSwgdXRpbGl6emF0YSBwZXIgaWRlbnRpZmljYXJlIGxlIGluZm9ybWF6aW9uaSBkaSBhZ2dyZWdhemlvbmVcclxuICAgICAqIFxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGVzdG8gZmluYWxlIGNhbGNvbGF0byBwZXIgbGEgKipjZWxsKiogY29ycmVudGUsIGluIGJhc2UgYWxsZSBhZ2dyZWdhemlvbmkgZGkgKipoZWFkZXIqKlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldEdyb3VwQ2VsbERpc3BsYXkoZ3JwOiBHcm91cCwgY2VsbDogc3RyaW5nLCBoZWFkZXI6IEVzVGhEaXJlY3RpdmUpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmICgoPGFueT5ncnApLl9zZXApXHJcbiAgICAgICAgICAgIHJldHVybiBcIlwiO1xyXG4gICAgICAgIGxldCBkaXNwbGF5ID0gaGVhZGVyLnRoQWdncmVnYXRpb247XHJcbiAgICAgICAgaWYgKGdycC5jb2x1bW4gPT0gY2VsbCkge1xyXG4gICAgICAgICAgICBsZXQgZ3JvdXBzUGFydCA9ICg8YW55PmdycCkuX2dyb3Vwc2NvdW50ID8gXCIgLSBcIiArICg8YW55PmdycCkuX2dyb3Vwc2NvdW50ICsgXCIgXCIgKyB0aGlzLmxjLmxvYyhcIkdyb3Vwc1wiKSA6IFwiXCI7XHJcbiAgICAgICAgICAgIHJldHVybiBncnAudmFsdWUgKyBcIiAoXCIgKyBncnAuY291bnQgKyBncm91cHNQYXJ0ICsgXCIpXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG5cclxuICAgICAgICAgICAgbGV0IGFnZyA9ICg8TWFwPHN0cmluZywgTWFwPHN0cmluZywgc3RyaW5nPj4+KDxhbnk+Z3JwKS5fYWdncmVnYXRpb25zQ2FjaGUpLmdldChjZWxsKTtcclxuICAgICAgICAgICAgaWYgKCFhZ2cpIHJldHVybiBcIlwiO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5nZXRFc1RoRGlyZWN0aXZlTGlzdE9mQWdncmVnYXRpb25zKGhlYWRlcikuZm9yRWFjaCgoaXRtOiBUaEFnZ3JlZ2F0aW9uKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5ID0gZGlzcGxheS5yZXBsYWNlKGl0bS5tYXRjaCwgdGhpcy5mb3JtYXRBZ2dyZWdhdGlvblZhbHVlKGFnZy5nZXQoaXRtLmZ1bmMpLCBpdG0uZm9ybWF0KSlcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gZGlzcGxheTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXN0aXNjZSBpIGNsaWNrIHN1bGxhIHRhYmVsbGEgc29sbyBwZXIgbGUgcmlnaGUgYSBncnVwcG8uIFxyXG4gICAgICogTyByaW11b3ZlIGdsaSBlbGVtZW50aSBhdHR1YWxtZW50ZSBwcmVzZW50aSBvIGNhcmljYSBpbCBjb250ZW51dG8gZGVsIGdydXBwb1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55fSBncm91cCBHcnVwcG8gYmluZGF0byBzdSBjdWkgc2kgw6ggZWZmZXR0dWF0byBpbCBjbGlja1xyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSAqKnRydWUqKiBzZSBsJ29wZXJhaXpvbmUgw6ggYW5kYXRhIGEgYnVvbiBmaW5lLCAqKmZhbHNlKiogYWx0cmltZW50aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlR3JvdXBDbGljayhncm91cDogR3JvdXApOiBib29sZWFuIHtcclxuICAgICAgICBsZXQgY2FzdGVkID0gdGhpcy5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+O1xyXG4gICAgICAgIGxldCBhbnlHID0gKDxhbnk+Z3JvdXApO1xyXG4gICAgICAgIGFueUcuX2V4cGFuZGVkID0gIWFueUcuX2V4cGFuZGVkXHJcblxyXG4gICAgICAgIC8vIFNvbm8gaW4gbW9kYWxpdMOgIHJhZ2dydXBwYW1lbnRvIHZpcnR1YWxlIGRhIGFycmF5OiBFc3BhbmRlcmUgc2lnbmlmaWNhIHJlbmRlcmUgdmlzaWJpbGkgdHV0dGkgZ2xpIG9nZ2V0dGkgcmVsYXRpdmkgYSBxdWVzdG8gZ3J1cHBvLCB2aWNldmVyc2EgaWwgY29udHJhcnJlXHJcbiAgICAgICAgaWYgKHRoaXMuQXJyYXlHcm91cGluZykge1xyXG4gICAgICAgICAgICBsZXQgYWxsUmVsYXRpdmVzID0gdGhpcy5ib3VuZFNvdXJjZS5maWx0ZXIodCA9PiBcclxuICAgICAgICAgICAgICAgICh0Ll9ncm91cCAmJiAoKGFueUcuX2V4cGFuZGVkICYmIHQuX3BhcmVudCA9PSBhbnlHLl90aGlzS2V5KSB8fCAoIWFueUcuX2V4cGFuZGVkICYmIHQuX3BhcmVudCAmJiB0Ll9wYXJlbnQuc3RhcnRzV2l0aChhbnlHLl90aGlzS2V5KSkpKSB8fCBcclxuICAgICAgICAgICAgICAgICh0Ll9pdGVtICYmICgoYW55Ry5fZXhwYW5kZWQgJiYgdC5fdGhpc0tleSA9PSBhbnlHLl90aGlzS2V5KSB8fCAoIWFueUcuX2V4cGFuZGVkICYmIHQuX3RoaXNLZXkuc3RhcnRzV2l0aChhbnlHLl90aGlzS2V5KSkpKSlcclxuICAgICAgICAgICAgYWxsUmVsYXRpdmVzLmZvckVhY2godCA9PiB7IHQuX3Zpc2libGUgPSBhbnlHLl9leHBhbmRlZDsgaWYodC5fZ3JvdXApIHQuX2V4cGFuZGVkID0gZmFsc2UgfSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChhbnlHLl9leHBhbmRlZCkge1xyXG4gICAgICAgICAgICAvLyBSZXNldHRvIGlwcFxyXG4gICAgICAgICAgICBjYXN0ZWQuaXRlbXNwZXJwYWdlb3ZlcnJpZGUgPSAxNTtcclxuICAgICAgICAgICAgaWYgKCFjYXN0ZWQucmVxdWVzdGVkZ3JvdXBzKVxyXG4gICAgICAgICAgICAgICAgY2FzdGVkLnJlcXVlc3RlZGdyb3VwcyA9IFtuZXcgR3JvdXBGaWx0ZXIoZ3JvdXAuY29sdW1uLCBncm91cC52YWx1ZSldO1xyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGxldCBsZXZlbCA9IGFueUcuX2dyb3VwbGV2ZWw7XHJcbiAgICAgICAgICAgICAgICAvLyBzZSBpbCBncnVwcG8gY2xpY2NhdG8gbm9uIGhhIHVuIGxpdmVsbG8gw6ggaWwgcHJpbW8gZ3J1cHBvLCBxdWluZGkgb3JkaW5hbWVudG8gdW5pY29cclxuICAgICAgICAgICAgICAgIC8vIGFsdHJpbWVudGkgZGV2byByaW11b3ZlcmUgdHV0dGkgaSBmaWx0cmkgc3UgbGl2ZWxsaSBzdXBlcmlvcmkgYWwgbGV2ZWwgY2xpY2NhdG8gZSBhZ2dpdW5nZXJlIGlsIGxldmVsIGNsaWNjYXRvXHJcbiAgICAgICAgICAgICAgICBpZiAoIWxldmVsKVxyXG4gICAgICAgICAgICAgICAgICAgIGNhc3RlZC5yZXF1ZXN0ZWRncm91cHMgPSBbbmV3IEdyb3VwRmlsdGVyKGdyb3VwLmNvbHVtbiwgZ3JvdXAudmFsdWUpXTtcclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc3RlZC5yZXF1ZXN0ZWRncm91cHMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICBhbnlHLl9wYXJlbnRSb3V0ZS5mb3JFYWNoKChzdGVwOiBHcm91cFJvdXRlRnJhZ21lbnQpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzdGVkLnJlcXVlc3RlZGdyb3Vwcy5wdXNoKG5ldyBHcm91cEZpbHRlcihzdGVwLmNvbHVtbiwgc3RlcC52YWx1ZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc3RlZC5yZXF1ZXN0ZWRncm91cHMucHVzaChuZXcgR3JvdXBGaWx0ZXIoZ3JvdXAuY29sdW1uLCBncm91cC52YWx1ZSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmNoYW5nZWQoKTtcclxuICAgICAgICAgICAgdGhpcy5lbWl0U2VhcmNoUmVxdWVzdCh0cnVlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGxldCBwYXRoID0gKGFueUcuX3BhcmVudCB8fCAnJykgKyBncm91cC52YWx1ZTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNlIGhvIGNoaXVzbyB1biBncnVwcG8gbm9uIG1pIHNlcnZlIHJpZWZmZXR0dWFyZSByaWNlcmNlLCBtaSBiYXN0YSBlbGltaW5hcmUgZGFnbGkgb2dnZXR0aSBiaW5kYXRpIHR1dHRpIGdsaSBlbGVtZW50aSBzb3R0b3N0YW50aSBhIHF1ZWwgZ3J1cHBvXHJcbiAgICAgICAgICAgIHRoaXMuYm91bmRTb3VyY2UgPSB0aGlzLmJvdW5kU291cmNlLmZpbHRlcih0ID0+ICF0Ll9wYXJlbnQgfHwgIXQuX3BhcmVudC5zdGFydHNXaXRoKHBhdGgpKTtcclxuXHJcbiAgICAgICAgICAgIC8vIGRldm8gcGVyw7IgYW5jaGUgcmltdW92ZXJlIGV2ZW50dWFsaSBjYWNoZSByZWxhdGl2ZVxyXG4gICAgICAgICAgICB0aGlzLmdyb3VwU2VhcmNoUmVxdWVzdHNDYWNoZSA9IHRoaXMuZ3JvdXBTZWFyY2hSZXF1ZXN0c0NhY2hlLmZpbHRlcih0ID0+IHQucGF0aCAhPSBwYXRoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRnVuemlvbmUgY2hlIGRhdG8gdW4gdmFsb3JlIGxvIGZvcm1hdHRhIGluIGJhc2UgYWwgdGlwb1xyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgVmFsb3JlIGNoZSBnZW5lcmFsZW1udGUgcHXDsiBlc3NlcmUgdW5hIGRhdGEgbyB1biBudW1lcm9cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBmcm9tYXQgRm9ybWF0byBzdSBjdWkgZm9ybWF0dGFyZSBpbCB2YWxvcmUuIFB1w7IgZXNzZXJlIGFkIGVzZW1waW8gXCJzbWFsbFwiLCBcImxvbmdcIiBcInZlcnlsb25nXCIgcGVyIGxlIGRhdGUgbyBGezAtOX0gcGVyIGkgbnVtZXJpIGRlY2ltYWxpXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFZhbG9yZSBkZWxsJ2FnZ3JlZ2F6aW9uZSBmb3JtYXR0YXRvIGNvbWUgc2kgZGV2ZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGZvcm1hdEFnZ3JlZ2F0aW9uVmFsdWUodmFsdWU6IHN0cmluZywgZm9ybWF0Pzogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBpZiAoIWZvcm1hdClcclxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG5cclxuICAgICAgICBsZXQgaXNOdW1iZXIgPSAhTnVtYmVyLmlzTmFOKHZhbHVlKSAmJiAoIWZvcm1hdCB8fCBmb3JtYXQuc3RhcnRzV2l0aChcIkZcIikpO1xyXG5cclxuICAgICAgICBpZiAoaXNOdW1iZXIgJiYgZm9ybWF0LnN0YXJ0c1dpdGgoXCJGXCIpICYmICFOdW1iZXIuaXNOYU4oZm9ybWF0LnN1YnN0cigxKSkpXHJcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUZsb2F0KHZhbHVlKS50b0ZpeGVkKHBhcnNlSW50KGZvcm1hdC5zdWJzdHIoMSkpKTtcclxuXHJcbiAgICAgICAgbGV0IGRhdGUgPSBudWxsO1xyXG4gICAgICAgIC8vIEFsY3VuZSB2ZXJzaW9uZSBkaSBleHRlbnNpb25zIHJpc2NoaWFubyBkaSBjcmFzaGFyZSBjb24gY29zZSBub24gZGF0ZS4uLiDDqCBzdGF0byByaXNvbHRvIGRvcG8gcXVpbmRpIHF1ZXN0byB0cnkgLSBjYXRjaCBpbiByZWFsdMOgXHJcbiAgICAgICAgLy8gdG9ybmEgdXRpbGUgc29sbyBjb24gdmVyc2lvbmkgdmVjY2hpZS9kZXByZWNhdGUgZGVsbGEgbGlicmVyaWEgQGVzZmFlbnphL2V4dGVuc2lvbnNcclxuICAgICAgICB0cnkgeyBkYXRlID0gdGhpcy5kYXRlRXh0cy5nZXREYXRlQ29udmVydGlvbih2YWx1ZSk7IH0gY2F0Y2ggeyB9XHJcblxyXG4gICAgICAgIGlmIChkYXRlKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kYXRlRXh0cy5nZXRGb3JtYXR0ZWQoZGF0ZSwgZm9ybWF0ID09ICdzbWFsbCcsIGZvcm1hdCA9PSAndmVyeWxvbmcnKTtcclxuXHJcbiAgICAgICAgLy8gUXVpIGNpIGZpbmlzY28gc2lhIHBlciBpbnB1dCBjaGUgbm9uIHNvbm8gbsOpIGRhdGUgbsOpIG51bWVyaSwgc2lhIHBlciBmb3JtYXRpIG5vbiByaWNvbm9zY2l1dGlcclxuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gI2VuZHJlZ2lvblxyXG5cclxuICAgIC8vICNyZWdpb24gR2VzdGlvbmUgT3BlcmFpem9uaSBkaWFsb2cgb3JkaW5hbWVudG8vdmlzaWJpbGl0w6AgY29sb25uZVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsJ2ludGVybm8gZGVsbGEgZGlhbG9nIFwiT3JkaW5hbWVudG8gZSBWaXNpYmlsaXTDoCBDb2xvbm5lXCIgbWV0dGUgbGEgY29sb25uYSBzcGVjaWZpY2F0YSBwcmltYSBkZWxsYSBjb2xvbm5hIHByZWNlZGVudGVcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VzVGFibGVDb2x1bW59IGNvbHVtbkl0ZW0gQ29sb25uYSBkYSBzcG9zdGFyZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2VuZFVwKGNvbHVtbkl0ZW06IEVzVGFibGVDb2x1bW4pIHtcclxuICAgICAgICBsZXQgaXRlbUluZGV4ID0gdGhpcy5UTVBDb2x1bW5zTGlzdC5pbmRleE9mKGNvbHVtbkl0ZW0pO1xyXG4gICAgICAgIGlmICh0aGlzLlRNUENvbHVtbnNMaXN0W2l0ZW1JbmRleCAtIDFdLmZpeGVkIHx8IHRoaXMuVE1QQ29sdW1uc0xpc3RbaXRlbUluZGV4IC0gMV0ucGlubmVkKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgdGhpcy51dGlFeHRzLnN3YXAodGhpcy5UTVBDb2x1bW5zTGlzdCwgaXRlbUluZGV4LCBpdGVtSW5kZXggLSAxKTtcclxuXHJcbiAgICAgICAgLy8gTm9uIHBvc3NvIGZhcmUgSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLkNvbHVtbnNMaXN0KSkgcGVyY2jDqSBjb250aWVuZSByaWZlcmltZW50aSBhIFRlbXBsYXRlUmVmXHJcbiAgICAgICAgbGV0IHRtcCA9IFtdO1xyXG4gICAgICAgIHRoaXMuVE1QQ29sdW1uc0xpc3QuZm9yRWFjaChjID0+IHsgdG1wLnB1c2goT2JqZWN0LmFzc2lnbih7fSwgYykpOyB9KTtcclxuICAgICAgICB0aGlzLlRNUENvbHVtbnNMaXN0ID0gdG1wO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsJ2ludGVybm8gZGVsbGEgZGlhbG9nIFwiT3JkaW5hbWVudG8gZSBWaXNpYmlsaXTDoCBDb2xvbm5lXCIgbWV0dGUgbGEgY29sb25uYSBzcGVjaWZpY2F0YSBkb3BvIGxhIGNvbG9ubmEgc3VjY2Vzc2l2YVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUYWJsZUNvbHVtbn0gY29sdW1uSXRlbSBDb2xvbm5hIGRhIHNwb3N0YXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZW5kRG93bihjb2x1bW5JdGVtOiBFc1RhYmxlQ29sdW1uKSB7XHJcbiAgICAgICAgbGV0IGl0ZW1JbmRleCA9IHRoaXMuVE1QQ29sdW1uc0xpc3QuaW5kZXhPZihjb2x1bW5JdGVtKTtcclxuICAgICAgICB0aGlzLnV0aUV4dHMuc3dhcCh0aGlzLlRNUENvbHVtbnNMaXN0LCBpdGVtSW5kZXgsIGl0ZW1JbmRleCArIDEpO1xyXG5cclxuICAgICAgICAvLyBOb24gcG9zc28gZmFyZSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMuQ29sdW1uc0xpc3QpKSBwZXJjaMOpIGNvbnRpZW5lIHJpZmVyaW1lbnRpIGEgVGVtcGxhdGVSZWZcclxuICAgICAgICBsZXQgdG1wID0gW107XHJcbiAgICAgICAgdGhpcy5UTVBDb2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4geyB0bXAucHVzaChPYmplY3QuYXNzaWduKHt9LCBjKSk7IH0pO1xyXG4gICAgICAgIHRoaXMuVE1QQ29sdW1uc0xpc3QgPSB0bXA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGwnaW50ZXJubyBkZWxsYSBkaWFsb2cgXCJPcmRpbmFtZW50byBlIFZpc2liaWxpdMOgIENvbG9ubmVcIiBwaW5uYSBsYSBjb2xvbm5hIHNwZWNpZmljYXRhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RhYmxlQ29sdW1ufSBjb2x1bW5JdGVtIENvbG9ubmEgZGEgc3Bvc3RhcmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIHBpbk9yVW5waW5Db2x1bW4oY29sdW1uSXRlbTogRXNUYWJsZUNvbHVtbikge1xyXG4gICAgICAgIGxldCBpdGVtSW5kZXggPSB0aGlzLlRNUENvbHVtbnNMaXN0LmluZGV4T2YoY29sdW1uSXRlbSk7XHJcblxyXG4gICAgICAgIC8vIFNwb3N0byBsYSBjb2xvbm5hIGFsbGEgZmluZSBkaSB0dXR0ZSBxdWVsbGUgcGlubmF0ZS4gTGEgY29zYSBmdW56aW9uYSBpbiBlbnRyYW1iaSBzZW5zaTpcclxuICAgICAgICAvLyAxKSBTZSBzdG8gcGlubmFuZG8sIGRldm8gbWV0dGVybGEgY29tZSB1bHRpbWEgcGlubmF0YVxyXG4gICAgICAgIC8vIDIpIFNlIHN0byBzcGlubmFuZG8gZGV2byBtZXR0ZXJsYSBjb21lIHByaW1hIG5vbiBwaW5uYXRhXHJcbiAgICAgICAgLy8gQ29pbmNpZGVuemEgdnVvbGUgY2hlIGlsIHB1bnRvIDEgZSAyIHNpYW5vIGVxdWl2YWxlbnRpXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLlRNUENvbHVtbnNMaXN0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5UTVBDb2x1bW5zTGlzdFtpXS5waW5uZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuYXJyYXlNb3ZlKHRoaXMuVE1QQ29sdW1uc0xpc3QsIGl0ZW1JbmRleCwgaSk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29sdW1uSXRlbS5waW5uZWQgPSAhY29sdW1uSXRlbS5waW5uZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGwnaW50ZXJubyBkZWxsYSBkaWFsb2cgXCJPcmRpbmFtZW50byBlIFZpc2liaWxpdMOgIENvbG9ubmVcIiBpbnZlcnRlIGxlIGltcG9zdGF6aW9uaSBkaSB2aXNpYmlsaXTDoCBkZWxsYSBjb2xvbm5hXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RhYmxlQ29sdW1ufSBjb2x1bW5JdGVtIENvbG9ubmEgZGEgc3Bvc3RhcmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvbHVtbkNsaWNrZWQoaXRlbTogRXNUYWJsZUNvbHVtbikge1xyXG4gICAgICAgIHRoaXMubGFzdFNlbGVjdGVkSXRlbUlEID0gaXRlbS5pZDtcclxuICAgICAgICBpZiAoIXRoaXMuSGlkZGVuQ29sdW1ucyB8fCBpdGVtLmZpeGVkKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGl0ZW0udmlzaWJsZSA9ICFpdGVtLnZpc2libGU7XHJcbiAgICAgICAgdGhpcy51cGRhdGVHbG9iYWxDb2xWaXNDaGVjaygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsJ2FwZXJ0dXJhIGRlbGxhIGRpYWxvZyBcIk9yZGluYW1lbnRvIGUgVmlzaWJpbGl0w6AgQ29sb25uZVwiIHJpY2FyaWNhIGxlIGluZm9ybWF6aW9uaSBhdHR1YWxpIHBlciBwZXJtZXR0ZXJlIGxhIG1vZGlmaWNhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZXNldENvbHVtblZpc1NlbGVjdGlvbigpIHtcclxuICAgICAgICB0aGlzLlRNUENvbHVtbnNMaXN0ID0gW107XHJcbiAgICAgICAgLy8gTm9uIHBvc3NvIGZhcmUgSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLkNvbHVtbnNMaXN0KSkgcGVyY2jDqSBjb250aWVuZSByaWZlcmltZW50aSBhIFRlbXBsYXRlUmVmXHJcblxyXG4gICAgICAgIHRoaXMuVE1QQ29sdW1uc0xpc3QgPSBbXTtcclxuICAgICAgICB0aGlzLkNvbHVtbnNMaXN0LmZvckVhY2goYyA9PiB7IHRoaXMuVE1QQ29sdW1uc0xpc3QucHVzaChPYmplY3QuYXNzaWduKHt9LCBjKSk7IH0pO1xyXG5cclxuICAgICAgICBsZXQgcmVvcmRlcmVkQ29sTGlzdCA9IFtdO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5Db2x1bW5zT3JkZXJpbmcpIHtcclxuICAgICAgICAgICAgdGhpcy5PcmRlckRpcmVjdGl2ZXMuZm9yRWFjaChvID0+IHtcclxuICAgICAgICAgICAgICAgIGxldCBjb2x1bW4gPSB0aGlzLlRNUENvbHVtbnNMaXN0LmZpbHRlcih0ID0+IHQuaWQgPT0gbylbMF07XHJcbiAgICAgICAgICAgICAgICAvLyBQb3RyZWkgbm9uIGF2ZXJuZSBuZWwgY2FzbyBjaSBzaWEgaWwgZmxhZyBIaWRkZW5Db2x1bW5zIGEgZmFsc2UsIGV2aXRvIGRpIGluc2VyaXJlIGRlZ2xpIHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICAgaWYgKGNvbHVtbilcclxuICAgICAgICAgICAgICAgICAgICByZW9yZGVyZWRDb2xMaXN0LnB1c2goY29sdW1uKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLlRNUENvbHVtbnNMaXN0ID0gcmVvcmRlcmVkQ29sTGlzdDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlR2xvYmFsQ29sVmlzQ2hlY2soKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJpYWdnaW9ybmEgbGUgKipPcmRlckRpcmVjdGl2ZXMqKiBjb24gbGUgaW5mb3JtYXppb25pIGluICAqKkNvbHVtbnNMaXN0KipcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSByZWZyZXNoQ29sdW1uT3JkZXJpbmcoKSB7XHJcbiAgICAgICAgdGhpcy5PcmRlckRpcmVjdGl2ZXMgPSBbXTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgYyA9IDA7IGMgPCB0aGlzLkNvbHVtbnNMaXN0Lmxlbmd0aDsgYysrKVxyXG4gICAgICAgICAgICB0aGlzLk9yZGVyRGlyZWN0aXZlcy5wdXNoKHRoaXMuQ29sdW1uc0xpc3RbY10uaWQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRWZmZXR0dWEgbGEgc2VsZXppb25lIG8gbWVubyBkZWwgY2hlY2sgZ2xvYmFsZSAoKipnbG9iYWxDb2xWaXNDaGVjayoqKSBkaSB2aXNpYmlsaXTDoCBpbiBiYXNlIGEgc2UgdHV0dGUgbGUgKipUTVBDb2x1bW5zTGlzdCoqIHNvbm8gdmlzaWJpbGkgbyBub1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdXBkYXRlR2xvYmFsQ29sVmlzQ2hlY2soKSB7XHJcbiAgICAgICAgLy8gVE1QQ29sTGlzdCB2aWVuZSByaWVtcGl0YSBkaSB1bmRlZmluZWQgbmVsIGNhc28gaW4gY3VpIHNpYSBkaXNhdHRpdmF0YSBsYSBzZWxlemlvbmUgZGVsbGUgY29sb25uZSBuYXNjb3N0ZVxyXG4gICAgICAgIHRoaXMuZ2xvYmFsQ29sVmlzQ2hlY2sgPSB0aGlzLlRNUENvbHVtbnNMaXN0LmV2ZXJ5KHQgPT4gdC52aXNpYmxlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZ1bnppb25lIGNoZSBlZmZldHR1YSBsYSBjb25mZXJtYSBkZWxsYSB2aXNpYmlsaXTDoCBlIGRlbGwnb3JkaW5lIGRlbGxlIGNvbG9ubmUuXHJcbiAgICAgKlxyXG4gICAgICogUXVlc3RhIHNlbGV6aW9uZSB2aWVuZSBpbm9sdHJlIHNhbHZhdGEgbmVsbGUgcHJlZmVyZW56ZSAoKipAZXNmYWVuemEvcHJlZmVyZW5jZXMqKiksIHF1YWxvcmEgbCdJbnB1dCAqKlNhdmVQcmVmZXJlbmNlcyoqIGZvc3NlIHZhbG9yaXp6YXRvXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59ICoqdHJ1ZSoqIHNlIG5vbiBjaSBzb25vIHByb2JsZW1pLCAqKmZhbHNlKiogYWx0cmltZW50aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY29uZmlybUNvbHVtblZpc2liaWxpdHlTZWxlY3Rpb24oKTogYm9vbGVhbiB7XHJcbiAgICAgICAgLy8gTm9uIHBlcm1ldHRvIGRpIG5vbiBzZWxlemlvbmFyZSBudWxsYVxyXG4gICAgICAgIGlmICh0aGlzLlRNUENvbHVtbnNMaXN0LmV2ZXJ5KHQgPT4gIXQudmlzaWJsZSkpXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgbGV0IGNhc3RlZFZpZXcgPSB0aGlzLnZpZXdNb2RlID8gdGhpcy5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+IDogbnVsbDtcclxuICAgICAgICB0aGlzLkNvbHVtbnNMaXN0ID0gW107XHJcbiAgICAgICAgdGhpcy5UTVBDb2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4geyB0aGlzLkNvbHVtbnNMaXN0LnB1c2goT2JqZWN0LmFzc2lnbih7fSwgYykpOyB9KTtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLnJlZnJlc2hDb2x1bW5PcmRlcmluZygpO1xyXG4gICAgICAgIHRoaXMuYXBwbHlPcmRlcmluZyhjYXN0ZWRWaWV3LCBmYWxzZSk7XHJcblxyXG4gICAgICAgIHRoaXMucmVmcmVzaENvbHVtbnNWaXNpYmlsaXR5KG51bGwsIG51bGwsIGNhc3RlZFZpZXcpO1xyXG5cclxuICAgICAgICAvL1NhbHZvIGxlIHByZWZlcmVuY2VzIGRpIHF1ZXN0YSB2aWV3XHJcbiAgICAgICAgLy9EaSBkZWZhdWx0IHJlZ2lzdHJvIG9yZGluYW1lbnRvIGUgdmlzaWJpbGl0w6AgZGVsbGUgY29sb25uZSBuZWxsYSB2aXN0YS4gU29sbyBsZSBjb3NlIGRpIFVJXHJcbiAgICAgICAgaWYgKHRoaXMuU2F2ZVByZWZlcmVuY2VzKSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5uZ0NvbnRyb2wubmFtZSkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIk5vbiBwb3NzbyB1dGlsaXp6YXJlIGxlIHByZWZlcmVuY2Ugc2VuemEgYXZlcmUgdW4gJ25hbWUnIHBlciBsYSB0YWJlbGxhXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRoaXMucHJlZlNlcnZpY2UpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJOb24gcG9zc28gdXRpbGl6emFyZSBsZSBwcmVmZXJlbmNlIHNlbnphIGNoZSBpbCBwYWNjaGV0dG8gQGVzZmFlbnphL3ByZWZlcmVuY2VzIHNpYSBpbnN0YWxsYXRvXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgY29sdW1ucyA9IHRoaXMuYXJyYXlNb2RlID8gdGhpcy5hcnJheUNvbHVtbnMgOiBjYXN0ZWRWaWV3LmNvbHVtbnM7XHJcbiAgICAgICAgICAgIGxldCBjb2x1bW5zT3JkZXJpbmdzID0gdGhpcy5hcnJheU1vZGUgPyB0aGlzLmFycmF5Q29sdW1uT3JkZXJpbmcgOiBjYXN0ZWRWaWV3LmNvbHVtbl9vcmRlcmluZztcclxuICAgICAgICAgICAgdmFyIHRvU3RvcmUgPSB7IGNvbHVtbnM6IDxzdHJpbmdbXT5KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGNvbHVtbnMpKSwgY29sdW1uX29yZGVyaW5nOiA8c3RyaW5nW10+SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShjb2x1bW5zT3JkZXJpbmdzKSkgfTtcclxuICAgICAgICAgICAgdGhpcy5wcmVmU2VydmljZS5zdG9yZSg8c3RyaW5nPnRoaXMubmdDb250cm9sLm5hbWUsIHRvU3RvcmUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUmllc2VndW8gbCd1bHRpbWEgcmljZXJjYSBiaW5kYXRhIGFsbGEgdGFiZWxsYVxyXG4gICAgICAgIC8vIE1pIGFzc2ljdXJvIGRpIGZhcmxvIGRvcG8gbCdlc3BhbnNpb25lIGRlbCBjaGFuZ2VkIG8gcmlzY2hpbyBjaGUgbGEgcmljZXJjYSBtaSByaWRpYSBjb2xvbm5lIGNoZSBpbiByZWFsdMOgIG5vbiBlc2lzdG9ub1xyXG4gICAgICAgIGlmICh0aGlzLnZpZXdNb2RlKVxyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgdGhpcy5lbWl0U2VhcmNoUmVxdWVzdChmYWxzZSk7IH0pO1xyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuYXJyYXlNb2RlKVxyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgdGhpcy5pbnRlcm5hbFdyaXRlVmFsdWUoKTsgfSk7XHJcblxyXG4gICAgICAgIC8vIExvIHZvcnJlaSBtZXR0ZXJlIGxhdG8gdGVtcGxhdGUgbWEgbm9cclxuICAgICAgICB0aGlzLmxhc3RTZWxlY3RlZEl0ZW1JRCA9IG51bGw7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTdWwgY2xpY2sgbmVsbGEgY2hlY2tib3ggZGkgc2VsZXppb25lIGdsb2JhbGUgc2kgc2NvcnJvbm8gdHV0dGUgbGUgY29sb25uZSBlIHNpIGltcG9zdGFubyBhbCB2YWxvcmUgZGVsbGEgY2hlY2sgZ2xvYmFsZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2xvYmFsQ29sVmlzQ2hlY2tDaGFuZ2VkKCkge1xyXG4gICAgICAgIHRoaXMuVE1QQ29sdW1uc0xpc3QuZm9yRWFjaCh0ID0+IHsgaWYgKCF0LmZpeGVkKSB0LnZpc2libGUgPSB0aGlzLmdsb2JhbENvbFZpc0NoZWNrOyB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyAjZW5kcmVnaW9uXHJcblxyXG4gICAgLy8gI3JlZ2lvbiBHZXN0aW9uZSBkYXRhIHNvdXJjZSBnZXJhcmNoaWNpXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEYXRhIHVuYSBsaXN0YSBkaSBvZ2dldHRpIGFzc2Vnbm8gaWwgbGl2ZWxsbyBnZXJhcmNoaWNvIHJpc3BldHRvIGFsbGEgbGlzdGEgZGkgb2dnZXR0aSBwYXNzYXRhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHthbnlbXX0gb2JqcyBMaXN0YSBkaSBvZ2dldHRpIGEgY3VpIGFnZ2l1bmdlcmUgbCdpbmZvcm1hemlvbmUgZGVsIGxpdmVsbG8gZ2VyYXJjaGljb1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGFzc2lnbkhpZXJhcmNoeUxldmVscyhvYmpzOiBhbnlbXSkge1xyXG4gICAgICAgIC8vIENhc2lzdGljYSBpbnB1dCBudWxsb1xyXG4gICAgICAgIGlmICghb2JqcyB8fCAhb2Jqcy5sZW5ndGgpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy9TZSBtYW5jYW5vIGVudHJhbWJlIGxlIGluZm8gbGUgY2VyY28gZGkgdmFsb3JpenphcmUgaW4gYXV0b21hdGljbyBjb2kgZGVmYXVsdCBcInBhcmVudGlkXCIgZSBcImlkXCIgKHBvc3RvIGNoZSBsZSBwcm9wcyBlc2lzdGFubyBuZWxsJ29nZ2V0dG8pXHJcbiAgICAgICAgaWYgKCF0aGlzLlBhcmVudEtleSAmJiAhdGhpcy5Pd25LZXkpIHtcclxuICAgICAgICAgICAgaWYgKG9ianNbMF1bJ3BhcmVudGlkJ10gIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgIHRoaXMuUGFyZW50S2V5ID0gJ3BhcmVudGlkJztcclxuICAgICAgICAgICAgaWYgKG9ianNbMF1bJ2lkJ10gIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgIHRoaXMuT3duS2V5ID0gJ2lkJztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vQ2hlY2sgZmluYWxlIHBlciBhc3NpY3VyYXJtaSBjaGUgbGUgcHJvcHMgY2kgc2lhbm9cclxuICAgICAgICBpZiAoIXRoaXMuUGFyZW50S2V5IHx8ICF0aGlzLk93bktleSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdQZXIgdXRpbGl6emFyZSBpbCBzaXN0ZW1hIGluIG1vZGFsaXTDoCBnZXJhcmNoaWNhIMOoIG9iYmxpZ2F0b3JpbyBzcGVjaWZpY2FyZSBzaWEgUGFyZW50S2V5IGNoZSBPd25LZXkuIEZhbGxiYWNrIGEgc2lzdGVtYSBub24gZ2VyYXJjaGljbycpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBWYWxvcml6emF6aW9uZSBjYW1waSBsZXZlbCwgZXhwYW5kZWQsIGUgdmlzaWJsZSBwZXIgb2duaSBpdGVtXHJcbiAgICAgICAgbGV0IGN1cnJlbnRMZXZlbCA9IDE7XHJcbiAgICAgICAgbGV0IGFzc2lnbmVkID0gMDtcclxuICAgICAgICBkbyB7XHJcbiAgICAgICAgICAgIGFzc2lnbmVkID0gdGhpcy5hc3NpZ25MZXZlbChvYmpzLCBjdXJyZW50TGV2ZWwpO1xyXG4gICAgICAgICAgICBjdXJyZW50TGV2ZWwrKztcclxuICAgICAgICB9IHdoaWxlIChhc3NpZ25lZCA+IDApO1xyXG4gICAgICAgIC8vIGJ1dHRvIHN1IGxhdG8gaHRtbCBlIHBvaSBtZSBsYSBnaW9jbyBsw6AgY29uIHBhZGRpbmcgPSAyMCAqIChsZXZlbCAtIDEpIHBlciBmYXIgY2FwaXJlIGlsIGRpdmVyc28gbGl2ZWxsb1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGVyIG9nbnVubyBkZWdsaSBvZ2dldHRpIHBhc3NhdGkgZ2xpIGFzc2VnbmEgdW4gbGl2ZWxsbyBkaSBnZXJhcmNoaWEgaW4gYmFzZSBhICoqUGFyZW50S2V5KiogZSAqKk93bktleSoqXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHthbnlbXX0gb2JqcyBPZ2dldHRpIGEgY3VpIGFzc2VnbmFyZSBpbCBsaXZlbGxvIGRpIGdlcmFyY2hpYVxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxldmVsVG9Bc3NpZ24gTGl2ZWxsbyBjaGUgc3RhIGFzc2VnbmFuZG8gYXR0dWFsbWVudGUgcXVlc3RhIGl0ZXJhemlvbmUgKGRhdG8gY2hlIMOoIHJpY29yc2l2YSlcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1lcm8gZGkgb2dnZXR0aSBhIGN1aSDDqCBzdGF0byBhc3NlZ25hdG8gdW4gbGl2ZWxsbyBnZXJhcmNoaWNvXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgYXNzaWduTGV2ZWwob2JqczogYW55W10sIGxldmVsVG9Bc3NpZ246IG51bWJlcik6IG51bWJlciB7XHJcbiAgICAgICAgbGV0IGFzc2lnbmVkID0gMDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9ianMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IG9iaiA9IG9ianNbaV07XHJcblxyXG4gICAgICAgICAgICAvLyBTZSBsYSBwYXJlbnRLZXkgbm9uIMOoIHZhbG9yaXp6YXRhLCBxdWVzdG8gw6ggaWwgbGl2ZWxsbyAwICgxLi4uIHBlcmNow6kgZ2xpIDAgc29uIHBlcmNpb2xvc2kpXHJcbiAgICAgICAgICAgIGlmICghb2JqW3RoaXMuUGFyZW50S2V5XSAmJiBsZXZlbFRvQXNzaWduID09IDEpIHtcclxuICAgICAgICAgICAgICAgIG9iai5fbGV2ZWwgPSAxO1xyXG4gICAgICAgICAgICAgICAgb2JqLl92aXNpYmxlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIG9iai5fZXhwYW5kZWQgPSB0aGlzLlN0YXJ0c0V4cGFuZGVkO1xyXG4gICAgICAgICAgICAgICAgYXNzaWduZWQrKztcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBQZXIgaSBsaXZlbGxpIHN1cGVyaW9yZSBhbCBwcmltb1xyXG4gICAgICAgICAgICBpZiAob2JqW3RoaXMuUGFyZW50S2V5XSAmJiBsZXZlbFRvQXNzaWduID4gMSkge1xyXG4gICAgICAgICAgICAgICAgLy8gdHJvdm8gaWwgcGFyZW50XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBwID0gMDsgcCA8IG9ianMubGVuZ3RoOyBwKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcG9zc2libGVQYXJlbnQgPSBvYmpzW3BdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBUcm92YXRvIGlsIHBhcmVudCBkZWxsJ2l0ZW0sIGFzc2Vnbm8gYWxsJ2l0ZW0gaWwgbGl2ZWxsbyBnaXVzdG9cclxuICAgICAgICAgICAgICAgICAgICBpZiAocG9zc2libGVQYXJlbnRbdGhpcy5Pd25LZXldID09IG9ialt0aGlzLlBhcmVudEtleV0gJiYgcG9zc2libGVQYXJlbnQuX2xldmVsID09IGxldmVsVG9Bc3NpZ24gLSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iai5fbGV2ZWwgPSBsZXZlbFRvQXNzaWduO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gU28gY2hlIHF1ZXN0byBpdGVtIGhhIHVuIHBhcmVudC4gUmliYWRpc2NvIGNoZSBpbCBwYXJlbnQgw6ggZXNwYW5zbyBpbiBiYXNlIGFsbGUgaW1wb3N0YXppb25lIGUgc3Rlc3NhIGxvZ2ljYVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBwZXIgbGEgdmlzaWJpbGl0w6AgZGVsIGZpZ2xpb1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3NzaWJsZVBhcmVudC5fZXhwYW5kZWQgPSB0aGlzLlN0YXJ0c0V4cGFuZGVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3NzaWJsZVBhcmVudC5wYXJlbnQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmouX3Zpc2libGUgPSB0aGlzLlN0YXJ0c0V4cGFuZGVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhc3NpZ25lZCsrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGFzc2lnbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRnVuemlvbmUgY2hlIHBlcm1ldHRlIGRpIGVmZmV0dHVhcmUgbCdlc3BhbnNpb25lIGRpIHVuIHBhcmVudCBxdWFuZG8gbGEgdGFiZWxsYSBmdW56aW9uYSBpbiBtb2RhbGl0w6AgZ2VyYXJjaGljYVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgQ2hpYXZlIGRlbCBwYXJlbnQgZGEgZXNwYW5kZXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBleHBhbmRQYXJlbnQoa2V5OiBzdHJpbmcpIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYm91bmRTb3VyY2UubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IG9iaiA9IHRoaXMuYm91bmRTb3VyY2VbaV07XHJcblxyXG4gICAgICAgICAgICAvLyBUcm92byBpbCBwYXJlbnQgY29uIHF1ZWxsJ2lkIGUgbG8gZXNwYW5kb1xyXG4gICAgICAgICAgICBpZiAob2JqW3RoaXMuT3duS2V5XSA9PSBrZXkpIHtcclxuICAgICAgICAgICAgICAgIG9iai5fZXhwYW5kZWQgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGljID0gMDsgaWMgPCB0aGlzLmJvdW5kU291cmNlLmxlbmd0aDsgaWMrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBjaGlsZCA9IHRoaXMuYm91bmRTb3VyY2VbaWNdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBUcm92byB0dXR0aSBpIGNoaWxkIGRpIHF1ZWwgcGFyZW50IGUgbGkgcmVuZG8gdmlzaWJpbGlcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRbdGhpcy5QYXJlbnRLZXldID09IGtleSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQuX3Zpc2libGUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRnVuemlvbmUgY2hlIHBlcm1ldHRlIGRpIGVmZmV0dHVhcmUgaWwgY29sbGFwc2UgZGkgdW4gcGFyZW50IHF1YW5kbyBsYSB0YWJlbGxhIGZ1bnppb25hIGluIG1vZGFsaXTDoCBnZXJhcmNoaWNhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBDaGlhdmUgZGVsIHBhcmVudCBkYSBjb2xsYXNzYXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb2xsYXBzZVBhcmVudChrZXk6IHN0cmluZykge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ib3VuZFNvdXJjZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgb2JqID0gdGhpcy5ib3VuZFNvdXJjZVtpXTtcclxuXHJcbiAgICAgICAgICAgIC8vIFRyb3ZvIGlsIHBhcmVudCBjb24gcXVlbGwnaWQgZSBsbyBjb2xsYXNzb1xyXG4gICAgICAgICAgICBpZiAob2JqW3RoaXMuT3duS2V5XSA9PSBrZXkpIHtcclxuICAgICAgICAgICAgICAgIG9iai5fZXhwYW5kZWQgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBDb2xsYXNzby9uYXNjb25kbyB0dXR0aSBpIGNoaWxkIGRlbCBwYXJlbnRcclxuICAgICAgICAgICAgICAgIHRoaXMuY29sbGFwc2VDaGlsZE9mUGFyZW50KGtleSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb2xsYXNzYSByaWNvcnNpdmFtZW50ZSB0dXR0aSBpIGZpZ2xpIGRpIHVuIHBhcmVudCBpZGVudGlmaWNhdG8gZGFsbGEgKipwYXJlbnRLZXkqKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXJlbnRLZXkgQ2hpYXZlIGRlbCBwYXJlbnQgZGkgY3VpIGNvbGxhc3NhcmUgaSBmaWdsaVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGNvbGxhcHNlQ2hpbGRPZlBhcmVudChwYXJlbnRLZXk6IHN0cmluZykge1xyXG4gICAgICAgIGZvciAobGV0IGljID0gMDsgaWMgPCB0aGlzLmJvdW5kU291cmNlLmxlbmd0aDsgaWMrKykge1xyXG4gICAgICAgICAgICBsZXQgY2hpbGQgPSB0aGlzLmJvdW5kU291cmNlW2ljXTtcclxuXHJcbiAgICAgICAgICAgIC8vIFRyb3ZvIHR1dHRpIGkgY2hpbGQgZGkgcXVlbCBwYXJlbnQgZSBsaSByZW5kbyBpbnZpc2liaWxpLiBTZSBpbCBjaGlsZCB0cm92YXRvIMOoIGEgc3VhIHZvbHRhIHVuIHBhcmVudCxcclxuICAgICAgICAgICAgLy8gbG8gY29sbGFzc28gZSB2YWRvIGluIHJpY29yc2lvbmUgc3VpIGZpZ2xpXHJcbiAgICAgICAgICAgIGlmIChjaGlsZFt0aGlzLlBhcmVudEtleV0gPT0gcGFyZW50S2V5ICYmICFjaGlsZC5wYXJlbnQpXHJcbiAgICAgICAgICAgICAgICBjaGlsZC5fdmlzaWJsZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICBlbHNlIGlmIChjaGlsZFt0aGlzLlBhcmVudEtleV0gPT0gcGFyZW50S2V5ICYmIGNoaWxkLnBhcmVudCkge1xyXG4gICAgICAgICAgICAgICAgY2hpbGQuX2V4cGFuZGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBjaGlsZC5fdmlzaWJsZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb2xsYXBzZUNoaWxkT2ZQYXJlbnQoY2hpbGRbdGhpcy5Pd25LZXldKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyAjZW5kcmVnaW9uXHJcblxyXG4gICAgLy8gI3JlZ2lvbiBHZXN0aW9uZSBTZWxlemlvbmVcclxuXHJcbiAgICAvKipcclxuICAgICAqIFZhbHV0YSBxdWFsaSBlbGVtZW50aSBkZXZvbm8gZXNzZXJlIG1hcmNhdGkgY29tZSBzZWxlemlvbmF0aSBuZWxsYSB2aXN0YSBhdHR1YWxlLiBTaSBiYXNhIHN1bGwnb2dnZXR0byAqKnNlbGVjdGlvbioqIGludGVybm8gYWxsJ0FwcFNlYXJjaFxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55W119IGl0ZW1zIE9nZ2V0dGkgZGkgY3VpIHZhbHV0YXJlIGxhIHNlbGV6aW9uZVxyXG4gICAgICogQHBhcmFtIHtJdGVtc1NlbGVjdGlvbjxhbnk+fSBzZWxlY3Rpb25JdGVtIE9nZ2V0dGkgZGkgc2VsZXppb25lIGRlcml2YW50ZSBkYWxsYSB2aWV3IG8gZGFsbCdvZ2dldHRvIHBlciBBcnJheVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGV2YWx1YXRlU2VsZWN0aW9uKGl0ZW1zOiBhbnlbXSwgc2VsZWN0aW9uSXRlbTogSXRlbXNTZWxlY3Rpb248YW55Pikge1xyXG4gICAgICAgIGlmICghc2VsZWN0aW9uSXRlbSlcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICB0aGlzLmhhbmRsZVNlbGVjdGlvbkV2YWx1YXRpb24oaXRlbXMsIHNlbGVjdGlvbkl0ZW0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVmFsdXRhIHF1YWxpIGVsZW1lbnRpIGRldm9ubyBlc3NlcmUgbWFyY2F0aSBjb21lIHNlbGV6aW9uYXRpIG5lbGxhIHZpc3RhIGF0dHVhbGUuIFNpIGJhc2Egc3VsbCdvZ2dldHRvICoqYXJyYXltb2RlU2VsZWN0aW9uKiogZGVsbCdlcy10YWJsZVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55W119IGFycmF5IExpc3RhIGRpIG9nZ2V0dGkgZGkgY3VpIHZhbHV0YXJlIGxhIHNlbGV6aW9uZSBpbiBtb2RhbGl0w6AgYXJyYXlcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBhcnJheU1vZGVFdmFsdWF0ZVNlbGVjdGlvbihhcnJheTogYW55W10pIHtcclxuICAgICAgICBpZiAoYXJyYXkubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgdGhpcy5oYW5kbGVTZWxlY3Rpb25FdmFsdWF0aW9uKGFycmF5LCB0aGlzLmFycmF5bW9kZVNlbGVjdGlvbik7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbXBsZW1lbnRhemlvbmUgYWdub3N0aWNhIGRlbGxhIHZhbHV0YXppb25lIGRlbGxlIHNlbGV6aW9uaSBkZWdsaSBvZ2dldHRpLiBSaWNoaWVkZSBnbGkgb2dnZXR0aSBkZWxsYSB2aXN0YSBhdHR1YWxlIGUgbCdpdGVtU2VsZWN0b3JcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge2FueVtdfSBpdGVtcyBPZ2dldHRpIGRpIGN1aSBhZ2dpb3JuYXJlIGxvIHN0YXRvIGRpIHNlbGV6aW9uZVxyXG4gICAgICogQHBhcmFtIHtJdGVtc1NlbGVjdGlvbjxhbnk+fSBzZWxlY3Rpb25JdGVtIE9nZ2V0dG8gY29udGVuZW50ZSBsbyBzdGF0byBhdHR1YWxlIGRpIHNlbGV6aW9uZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGhhbmRsZVNlbGVjdGlvbkV2YWx1YXRpb24oaXRlbXM6IGFueVtdLCBzZWxlY3Rpb25JdGVtOiBJdGVtc1NlbGVjdGlvbjxhbnk+KSB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgaXRtID0gaXRlbXNbaV07XHJcbiAgICAgICAgICAgIGxldCBoYXNoID0gaXRtLl9oYXNoO1xyXG4gICAgICAgICAgICBsZXQgaXRlbUdyb3VwID0gaXRtLl9ncm91cCA/IG51bGwgOiB0aGlzLmdldEl0ZW1Hcm91cChpdG0pO1xyXG4gICAgICAgICAgICAvLyBSZWlkcmF0byBsYSBjYWNoZSBkaSBzZWxlemlvbmUgY29pIG51b3ZpIG9nZ2V0dGkgYWx0cmltZW50aSBub24gcml1c2NpcmVpIGEgYmVjY2FyZSBnbGkgaW5kaWNpIGdpdXN0aVxyXG4gICAgICAgICAgICAvLyBEb3BvZGljaMOpIGxhIHVzbyBwZXIgY2FsY29sYXJlIGlzdGFudGFuZWFtZW50ZSBzZSBnbGkgb2dnZXR0aSBzb25vIHNlbGV6aW9uYXRpIG8gbm9cclxuICAgICAgICAgICAgdGhpcy5yZWhpZHJhdGVDYWNoZShpdG0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKGl0bS5faXRlbSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvbkl0ZW0uYWxsKVxyXG4gICAgICAgICAgICAgICAgICAgIGl0bS5fc2VsZWN0ZWQgPSAhdGhpcy5leGNsdXNpb25zQ2FjaGUuaGFzKGhhc2gpICYmICgoIXRoaXMuZ3JvdXBzQ2FjaGUuaGFzKGl0ZW1Hcm91cD8uX2hhc2gpICYmIHRoaXMuaXRlbXNDYWNoZS5oYXMoaGFzaCkpIHx8ICF0aGlzLmdyb3VwX2V4Y2x1c2lvbnNDYWNoZS5oYXMoaXRlbUdyb3VwPy5faGFzaCkpO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIGl0bS5fc2VsZWN0ZWQgPSAhdGhpcy5leGNsdXNpb25zQ2FjaGUuaGFzKGhhc2gpICYmICh0aGlzLmdyb3Vwc0NhY2hlLmhhcyhpdGVtR3JvdXA/Ll9oYXNoKSB8fCB0aGlzLml0ZW1zQ2FjaGUuaGFzKGhhc2gpIHx8ICh0aGlzLnBhcmVudFRyZWVTdGF0dXMoaXRlbUdyb3VwKSA9PSAnaW5jbHVkZWQnICYmICF0aGlzLmdyb3VwX2V4Y2x1c2lvbnNDYWNoZS5oYXMoaXRlbUdyb3VwPy5faGFzaCkpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChpdG0uX2dyb3VwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uSXRlbS5hbGwpXHJcbiAgICAgICAgICAgICAgICAgICAgaXRtLl9zZWxlY3RlZCA9ICF0aGlzLmdyb3VwX2V4Y2x1c2lvbnNDYWNoZS5oYXMoaGFzaCkgJiYgdGhpcy5wYXJlbnRUcmVlU3RhdHVzKGl0bSkgIT0gJ2V4Y2x1ZGVkJztcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBpdG0uX3NlbGVjdGVkID0gdGhpcy5ncm91cHNDYWNoZS5oYXMoaGFzaCkgfHwgKHRoaXMucGFyZW50VHJlZVN0YXR1cyhpdG0pID09ICdpbmNsdWRlZCcgJiYgIXRoaXMuZ3JvdXBfZXhjbHVzaW9uc0NhY2hlLmhhcyhoYXNoKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFNlIHR1dHRpIGdsaSBvZ2dldHRpIGRpIHF1ZXN0YSBwYWdpbmEgc29ubyBzb2xlemlvbmF0aSBhbGxvcmEgcG9zc28gbWV0dGVyZSBpbCBnbG9iYWwgY2hlY2sgYSB0cnVlXHJcbiAgICAgICAgLy8gU2Ugc29ubyBpbiBzaXR1YXppb25lIGRpIGFsbC1zZWxlY3QgYW5jaGUgbWV0dG8gbGEgZ2xvYmFsIGNoZWNrYm94LCBub25vc3RhbnRlIGNpIHBvc3Nhbm8gZXNzZXJlIGRlbGxlIGVzY2x1c2lvbmlcclxuICAgICAgICB0aGlzLmdsb2JhbENoZWNrID0gdGhpcy5ib3VuZFNvdXJjZS5maWx0ZXIodCA9PiB0Ll9ncm91cCB8fCB0Ll9pdGVtKS5ldmVyeSh0ID0+IHQuX3NlbGVjdGVkKTtcclxuICAgICAgICB0aGlzLmNhblNlbGVjdEFsbCA9IHNlbGVjdGlvbkl0ZW0uY291bnQgPiAwICYmIHRoaXMuU2VsZWN0QWxsO1xyXG5cclxuICAgICAgICAvLyBQb3RyZWJiZSBjYW1iaWFyZSBxdWFsb3JhIHF1YWxjdW5vIGluc2VyaXNzZSBkYXRpIGEgbWFuYXp6YSBpbiBtb2RhbGl0w6AgQXJyYXkgZSBkZXNzZSBpbCByZWZyZXNoIG1hbnVhbGUgYWxsYSB0YWJlbGxhXHJcbiAgICAgICAgLy8gQ29tdW5xdWUgY29zdGEgMCBxdWluZGkgbWkgcGVybWV0dG8gZGkgcmVmcmVzaGFyZVxyXG4gICAgICAgIGlmICh0aGlzLmFycmF5TW9kZSkge1xyXG4gICAgICAgICAgICBsZXQgcHJldlNlbGVjdGVkID0gdGhpcy5zZWxlY3RlZE9iamVjdHM7XHJcbiAgICAgICAgICAgIHRoaXMuZmluYWxpemVTZWxlY3Rpb25JbmZvcm1hdGlvbnMoc2VsZWN0aW9uSXRlbSk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGVkT2JqZWN0cyAhPSBwcmV2U2VsZWN0ZWQpXHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZC5lbWl0KHNlbGVjdGlvbkl0ZW0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERhdG8gdW4gb2dnZXR0byB0cm92YSBsYSBjZWxsYSBkaSBjYWNoZSBpbiBjdWkgw6ggcmVnaXN0cmF0byBlIGFnZ2lvcm5hIGlsIGNvbnRlbnV0b1xyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gaXRlbSBPZ2dldHRvIGRhIGFnZ2lvcm5hcmVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSByZWhpZHJhdGVDYWNoZShpdGVtOiBhbnkpIHtcclxuICAgICAgICBsZXQgY3R4ID0gaXRlbS5faGFzaDtcclxuICAgICAgICBpZiAodGhpcy5pdGVtc0NhY2hlLmhhcyhjdHgpKVxyXG4gICAgICAgICAgICB0aGlzLml0ZW1zQ2FjaGUuc2V0KGN0eCwgaXRlbSk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmdyb3VwX2V4Y2x1c2lvbnNDYWNoZS5oYXMoY3R4KSlcclxuICAgICAgICAgICAgdGhpcy5ncm91cF9leGNsdXNpb25zQ2FjaGUuc2V0KGN0eCwgaXRlbSk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmdyb3Vwc0NhY2hlLmhhcyhjdHgpKVxyXG4gICAgICAgICAgICB0aGlzLmdyb3Vwc0NhY2hlLnNldChjdHgsIGl0ZW0pO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5leGNsdXNpb25zQ2FjaGUuaGFzKGN0eCkpXHJcbiAgICAgICAgICAgIHRoaXMuZXhjbHVzaW9uc0NhY2hlLnNldChjdHgsIGl0ZW0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGF0byB1biBncnVwcG8gY29udHJvbGxhIHJpY29yc2l2YW1lbnRlIGwnYWxiZXJvIGRpIGN1aSBmYSBwYXJ0ZSBzZSBjJ8OoIHN0YXRhIHVuYSBpbmNsdXNpb25lIG8gZXNjbHVzaW9uZSBkaXJldHRhXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55fSBncnAgR3J1cHBvIGRhIGNvbnRyb2xsYXJlXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHsnbm9uZScgfCAnZXhjbHVkZWQnIHwgJ2luY2x1ZGVkJ30gXHJcbiAgICAgKiAnbm9uZScgc2Ugbm9uIGNpIHNvbm8gaW5mb3JtYXppb25pIHN1IGluY2x1c2lvbmkgbyBlc2NsdXNpb25pIFxyXG4gICAgICogJ2luY2x1ZGVkJyBzZSBpbCBncnVwcG8gY29udHJvbGxhdG8gw6ggc3RhdG8gaW5jbHVzbyBpbiBtYW5pZXJhIGVzcGxpY2l0YSBkYWxsJ2FsYmVybyBkZWkgZ3J1cHBpIHBhZHJpXHJcbiAgICAgKiAnZXhjbHVkZWQnIHNlIGlsIGdydXBwbyBjb250cm9sbGF0byDDqCBzdGF0byBlc2NsdXNvIGluIG1hbmllcmEgZXNwbGljaXRhIGRhbGwnYWxiZXJvIGRlaSBncnVwcGkgcGFkcmlcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBwYXJlbnRUcmVlU3RhdHVzKGdycDogYW55KTogJ25vbmUnIHwgJ2V4Y2x1ZGVkJyB8ICdpbmNsdWRlZCcge1xyXG4gICAgICAgIGlmICghZ3JwKVxyXG4gICAgICAgICAgICByZXR1cm4gJ25vbmUnO1xyXG5cclxuICAgICAgICBsZXQgcGFyZW50R3JvdXA6IGFueSA9IHRoaXMucmdHcm91cENhY2hlLmdldChncnAuX3BhcmVudCk7XHJcblxyXG4gICAgICAgIGlmICghcGFyZW50R3JvdXApXHJcbiAgICAgICAgICAgIHJldHVybiAnbm9uZSc7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmdyb3VwX2V4Y2x1c2lvbnNDYWNoZS5oYXMocGFyZW50R3JvdXAuX2hhc2gpKVxyXG4gICAgICAgICAgICByZXR1cm4gJ2V4Y2x1ZGVkJztcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuZ3JvdXBzQ2FjaGUuaGFzKHBhcmVudEdyb3VwLl9oYXNoKSlcclxuICAgICAgICAgICAgcmV0dXJuICdpbmNsdWRlZCc7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLnBhcmVudFRyZWVTdGF0dXMocGFyZW50R3JvdXApO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2VzdGlzY2UgbGEgc2VsZXppb25lIGdsb2JhbGUgZGVnbGkgb2dnZXR0aSwgc2lhIHBlciBwYWdpbmEgY2hlIGEgbGl2ZWxsbyBkaSAqKlNlbGVjdEFsbCoqXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBmb3JjZWRWYWwgVmFsb3JlIGZvcnphdG8gZGkgY2hlY2sgZGEgYXNzZWduYXJlIGFnbGkgb2dnZXR0aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2xvYmFsQ2hlY2tDaGFuZ2VkKGZvcmNlZFZhbDogYm9vbGVhbiA9IG51bGwpIHtcclxuXHJcbiAgICAgICAgLy8gUHJlbmRvIHR1dHRpIGdsaSBlbGVtZW50aSBwcmVzZW50aSBpbiBxdWVzdGEgdmlzdGEuIFNlIGhvIGdydXBwaSBwcmVuZG8gc29sbyBpIGdydXBwaSBhIGxpdmVsbG8gMCwgYWx0cmltZW50aSBwcmVuZG8gdHV0dGkgZ2xpIG9nZ2V0dGkgcGVyIHNlbGV6aW9uYXJsaVxyXG4gICAgICAgIGxldCBpdGVtcyA9IHRoaXMuYm91bmRTb3VyY2UuZmluZCh0ID0+IHQuX2dyb3VwKSA/IHRoaXMuYm91bmRTb3VyY2UuZmlsdGVyKHQgPT4gdC5fZ3JvdXAgJiYgIXQuX3BhcmVudCkgOiB0aGlzLmJvdW5kU291cmNlO1xyXG4gICAgICAgIHZhciBpdGVtU2VsZWN0aW9uID0gdGhpcy5oYW5kbGVJdGVtc1NlbGVjdGlvbihpdGVtcywgZm9yY2VkVmFsLCB0aGlzLmdsb2JhbENoZWNrKTtcclxuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcclxuXHJcbiAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZWQuZW1pdChpdGVtU2VsZWN0aW9uKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhlbHBlciBwZXIgZ2VzdGlyZSBsYSBzZWxlemlvbmUgZGkgTiBlbGVtZW50aSB1dGlsaXp6YW5kbyBsYSBDYWNoZSBkaSBzZWxlemlvbmUgZWQgZXZlbnR1YWxtZW50ZSBhZ2dpb3JuYW5kbyBpbCBjb25jZXR0byBkaSBcImFsbCBzZWxlY3Rpb25cIlxyXG4gICAgICpcclxuICAgICAqIFZ1bnppb25hIHNpYSBpbiBtb2RhbGl0w6AgQXJyYXkgY2hlIGluIG1vZGFsaXTDoCBWaWV3IFNlbXBsaWNlIG8gVmlldyBBdmFuemF0YSAoY29uIGxlIEN1c3RvbSBDZWxscylcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge2FueVtdfSBpdGVtcyBPZ2dldHRpIGRhIHNlbGV6aW9uYXJlIG8gZGVzZWxlemlvbmFyZVxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBmb3JjZWRWYWwgVmFsb3JlIGZvcnphdG8gZGkgY2hlY2sgZGEgYXNzZWduYXJlIGFnbGkgb2dnZXR0aVxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBnbG9iYWxDaGVjayBWYWxvcmUgZGVsIGNoZWNrIGdsb2JhbGVcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7SXRlbXNTZWxlY3Rpb248YW55Pn0gT2dnZXR0byBkaSBzZWxlemlvbmUgYWdnaW9ybmF0byBjb24gbGUgaW5mb3JtYXppb25pIHN1bGwndWx0aW1hIG9wZXJhemlvbmUgZWZmZXR0dWF0YVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlSXRlbXNTZWxlY3Rpb24oaXRlbXM6IGFueVtdLCBmb3JjZWRWYWw6IGJvb2xlYW4gPSBudWxsLCBnbG9iYWxDaGVjazogYm9vbGVhbiA9IG51bGwpOiBJdGVtc1NlbGVjdGlvbjxhbnk+IHtcclxuICAgICAgICBsZXQgc2kgPSAodGhpcy5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+KT8uc2VsZWN0aW9uIHx8IHRoaXMuYXJyYXltb2RlU2VsZWN0aW9uO1xyXG5cclxuICAgICAgICAvLyBTZSBzb25vIGluIG1vZGFsaXTDoCBkaSBzZWxlemlvbmUgc2luZ29sYSBlIGRldm8gc2VsZXppb25hcmUgdW4nb2dnZXR0bywgcGVyIHByaW1hIGNvc2EgZGV2byBkZXNlbGV6aW9uYXJlIHR1dHRpIGdsaSBhbHRyaVxyXG4gICAgICAgIGlmICh0aGlzLlNpbmdsZVNlbGVjdGlvbiAmJiBpdGVtc1swXT8uX3NlbGVjdGVkICYmICFpdGVtc1swXT8uX2dyb3VwKSB7XHJcbiAgICAgICAgICAgIGlmIChpdGVtcy5sZW5ndGggPiAxICYmIGZvcmNlZFZhbCA9PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgXCJUZW50YXRpdm8gZGkgc2VsZXppb25hcmUgbyBkZXNlbGV6aW9uYXJlIHBpw7kgZGkgdW4gZWxlbWVudG8gY29uIFNpbmdsZVNlbGVjdGlvbiBhdHRpdm9cIjtcclxuXHJcbiAgICAgICAgICAgIGlmIChpdGVtcy5sZW5ndGggPT0gMSAmJiBmb3JjZWRWYWwgPT0gbnVsbCl7XHJcbiAgICAgICAgICAgICAgICBzaSA9IHRoaXMuaGFuZGxlSXRlbXNTZWxlY3Rpb24odGhpcy5ib3VuZFNvdXJjZS5maWx0ZXIodCA9PiAhdC5fZ3JvdXApLCBmYWxzZSwgbnVsbCk7XHJcbiAgICAgICAgICAgICAgICBpdGVtc1swXS5fc2VsZWN0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBpdGVtID0gaXRlbXNbaV07XHJcbiAgICAgICAgICAgIGxldCB0b0NoYW5nZSA9IGZvcmNlZFZhbCAhPSBudWxsID8gaXRlbS5fc2VsZWN0ZWQgIT0gZm9yY2VkVmFsIDogZ2xvYmFsQ2hlY2sgIT0gbnVsbCA/IGl0ZW0uX3NlbGVjdGVkICE9IHRoaXMuZ2xvYmFsQ2hlY2sgOiBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNlIGRldidlc3NlcmUgb3ZlcnJpZGF0byBpbCB2YWxvcmUgZGkgY2hlY2sgZWZmZXR0dW8gbCdvdmVycmlkZSBvIGNvbCB2YWxvcmUgZm9yemF0byBvIGNvbCB2YWxvcmUgZ2xvYmFsZVxyXG4gICAgICAgICAgICBpZiAodG9DaGFuZ2UgJiYgIWl0ZW0ubG9ja2VkKVxyXG4gICAgICAgICAgICAgICAgaXRlbS5fc2VsZWN0ZWQgPSBmb3JjZWRWYWwgIT0gbnVsbCA/IGZvcmNlZFZhbCA6IHRoaXMuZ2xvYmFsQ2hlY2s7XHJcblxyXG4gICAgICAgICAgICAvLyBTZSBpbCB2YWxvcmUgbm9uIGRldidlc3NlcmUgdmFyaWF0byBlIHZlbmdvIGRhIHVuYSBzZWxlemlvbmUgZ2xvYmFsZSBzZW1wbGljZW1lbnRlIGV2aXRvIGRpIGVmZmV0dHVhcmUgb3BlcmFpem9uaSBpbnV0aWxpLiBMJ2l0ZW0vZ3J1cHBvIMOoIGdpw6AgbmVsbG8gc3RhdG8gZ2l1c3RvXHJcbiAgICAgICAgICAgIGlmKCF0b0NoYW5nZSAmJiBnbG9iYWxDaGVjayAhPSBudWxsKVxyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcblxyXG4gICAgICAgICAgICBsZXQgYWxsU2VsZWN0aW9uID0gc2kuYWxsO1xyXG4gICAgICAgICAgICBsZXQgaXNHcm91cCA9IGl0ZW0uX2dyb3VwO1xyXG4gICAgICAgICAgICBsZXQgaXNTZWxlY3Rpb24gPSBpdGVtLl9zZWxlY3RlZDtcclxuICAgICAgICAgICAgbGV0IGl0ZW1Hcm91cCA9IG51bGwsIGFsbEl0ZW1zID0gbnVsbCwgc2VsZWN0ZWRJdGVtcyA9IG51bGwsIHVuc2VsZWN0ZWRJdGVtcyA9IG51bGwsIGFsbEdyb3VwcyA9IG51bGwsIHNlbGVjdGVkR3JvdXBzID0gbnVsbCwgdW5zZWxlY3RlZEdyb3VwcyA9IG51bGwsIHBhcmVudEdyb3VwU2VsZWN0ZWQgPSBudWxsLCBwYXJlbnRHcm91cFVuc2VsZWN0ZWQgPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgaWYgKGlzR3JvdXApIHtcclxuICAgICAgICAgICAgICAgIGxldCBwdHMgPSB0aGlzLnBhcmVudFRyZWVTdGF0dXMoaXRlbSk7XHJcbiAgICAgICAgICAgICAgICBwYXJlbnRHcm91cFNlbGVjdGVkID0gcHRzID09ICdpbmNsdWRlZCc7XHJcbiAgICAgICAgICAgICAgICBwYXJlbnRHcm91cFVuc2VsZWN0ZWQgPSBwdHMgPT0gJ2V4Y2x1ZGVkJztcclxuICAgICAgICAgICAgICAgIGFsbEl0ZW1zID0gdGhpcy5nZXRHcm91cEl0ZW1zKHNpLCBpdGVtLCBudWxsLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgIHNlbGVjdGVkSXRlbXMgPSB0aGlzLmdldEdyb3VwSXRlbXMoc2ksIGl0ZW0sICdzZWxlY3RlZCcsIHRydWUsIGFsbEl0ZW1zKTtcclxuICAgICAgICAgICAgICAgIHVuc2VsZWN0ZWRJdGVtcyA9IHRoaXMuZ2V0R3JvdXBJdGVtcyhzaSwgaXRlbSwgJ3Vuc2VsZWN0ZWQnLCB0cnVlLCBhbGxJdGVtcyk7XHJcbiAgICAgICAgICAgICAgICBhbGxHcm91cHMgPSB0aGlzLmdldEdyb3VwQ2hpbGRHcm91cHMoc2ksIGl0ZW0sIG51bGwsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRHcm91cHMgPSB0aGlzLmdldEdyb3VwQ2hpbGRHcm91cHMoc2ksIGl0ZW0sICdzZWxlY3RlZCcsIHRydWUsIGFsbEdyb3Vwcyk7XHJcbiAgICAgICAgICAgICAgICB1bnNlbGVjdGVkR3JvdXBzID0gdGhpcy5nZXRHcm91cENoaWxkR3JvdXBzKHNpLCBpdGVtLCAndW5zZWxlY3RlZCcsIHRydWUsIGFsbEdyb3Vwcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpdGVtR3JvdXAgPSB0aGlzLmdldEl0ZW1Hcm91cChpdGVtKTtcclxuICAgICAgICAgICAgICAgIHBhcmVudEdyb3VwU2VsZWN0ZWQgPSBpdGVtR3JvdXAgPT0gbnVsbCA/IG51bGwgOiBpdGVtR3JvdXAuX3NlbGVjdGVkO1xyXG4gICAgICAgICAgICAgICAgcGFyZW50R3JvdXBVbnNlbGVjdGVkID0gaXRlbUdyb3VwID09IG51bGwgPyBudWxsIDogIWl0ZW1Hcm91cC5fc2VsZWN0ZWQ7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5BcnJheUdyb3VwaW5nKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5wZXJmb3JtU2VsZWN0aW9uT3BlcmF0aW9ucyhzaSwgaXRlbSwgYWxsU2VsZWN0aW9uLCBpc0dyb3VwLCBpc1NlbGVjdGlvbiwgc2VsZWN0ZWRJdGVtcywgc2VsZWN0ZWRHcm91cHMsIHVuc2VsZWN0ZWRJdGVtcywgdW5zZWxlY3RlZEdyb3VwcywgYWxsSXRlbXMsIGFsbEdyb3VwcywgcGFyZW50R3JvdXBTZWxlY3RlZCwgcGFyZW50R3JvdXBVbnNlbGVjdGVkKTtcclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgdGhpcy5wZXJmb3JtU2ltcGxlU2VsZWN0aW9uT3BlcmF0aW9ucyhzaSwgaXRlbSwgaXNHcm91cCwgaXNTZWxlY3Rpb24sIGl0ZW1Hcm91cCwgc2VsZWN0ZWRJdGVtcywgdW5zZWxlY3RlZEl0ZW1zLCBhbGxJdGVtcywgYWxsR3JvdXBzKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEltcG9zdG8gaWwgY2hlY2sgZ2xvYmFsZSBpbiBiYXNlIGEgc2UgdHV0dGkgZ2xpIGVsZW1lbnRpIHNvbm8gc2VsZXppb25hdGkgbyBtZW5vLlxyXG4gICAgICAgIC8vIEV2aXRvIGRpIGZhcmUgcXVlc3RlIG9wZXJhemlvbmkgc2UgbGEgc2VsZXppb25lIGRlcml2YSBwcm9wcmlvIGRhbCBnbG9iYWwgQ2hlY2tcclxuICAgICAgICBpZiAoZ2xvYmFsQ2hlY2sgPT0gbnVsbClcclxuICAgICAgICAgICAgdGhpcy5nbG9iYWxDaGVjayA9ICF0aGlzLmJvdW5kU291cmNlLnNvbWUodCA9PiAhdC5fc2VsZWN0ZWQgJiYgIXQuX3NlcCk7XHJcblxyXG4gICAgICAgIHRoaXMuZmluYWxpemVTZWxlY3Rpb25JbmZvcm1hdGlvbnMoc2kpO1xyXG5cclxuICAgICAgICByZXR1cm4gc2k7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEYXRvIEwnb2dnZXR0byBkaSBzZWxlemlvbmUsIGwnb2dnZXR0byBkYSBzZWxlemlvbmFyZS9kZXNlbGV6aW9uYXJlIGUgdHV0dGkgaSBwYXJhbWV0cmkgZGVsIGNhc28gZWZmZXR0dWEgbGUgb3BlcmF6aW9uaSBjaGUgc2Vydm9uby5cclxuICAgICAqIFxyXG4gICAgICogTG9naWNhIHNlbXBsaWZpY2F0YSByaXNwZXR0byBhbGwnb3JpZ2luYWxlICoqcGVyZm9ybVNlbGVjdGlvbk9wZXJhdGlvbnMqKiBwZXIgbGF2b3JhcmUgaW4gdW5hIG1vZGFsaXTDoCBpbiBjdWkgdHV0dGkgZ2xpIGVsZW1lbnRpIHNvbm8gY2FyaWNhdGkgKCoqQXJyYXlHcm91cGluZyoqID0gdHJ1ZSlcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBwZXJmb3JtU2ltcGxlU2VsZWN0aW9uT3BlcmF0aW9ucyhiYXNlOiBJdGVtc1NlbGVjdGlvbjxhbnk+LCBpdGVtOiBhbnksIGdyb3VwOiBib29sZWFuLCBzZWw6IGJvb2xlYW4sIGl0bV9ncm91cDogYW55LCBzZWxfaXRtOiBhbnlbXSwgZGVzZWxfaXRtOiBhbnlbXSwgYWxsX2l0bXM6IGFueVtdLCBhbGxfZ3JwczogYW55W10pIHtcclxuICAgICAgICBsZXQgdHJpcHRpY0l0ZW0gPSB0aGlzLmdldFRyaXB0aWMoJ2l0ZW0nLCBiYXNlKTtcclxuXHJcbiAgICAgICAgaWYgKGdyb3VwKSB7XHJcbiAgICAgICAgICAgIGlmIChzZWwpIHtcclxuICAgICAgICAgICAgICAgIGFsbF9ncnBzLmZvckVhY2goZ3IgPT4geyBnci5fc2VsZWN0ZWQgPSB0cnVlOyB9KTtcclxuICAgICAgICAgICAgICAgIGlmIChkZXNlbF9pdG0pXHJcbiAgICAgICAgICAgICAgICAgICAgZGVzZWxfaXRtLmZvckVhY2goZWwgPT4geyBlbC5fc2VsZWN0ZWQgPSB0cnVlOyB0aGlzLmFkZEl0ZW0oZWwsIHRyaXB0aWNJdGVtKSB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGFsbF9ncnBzLmZvckVhY2goZ3IgPT4geyBnci5fc2VsZWN0ZWQgPSBmYWxzZTsgfSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsX2l0bSlcclxuICAgICAgICAgICAgICAgICAgICBzZWxfaXRtLmZvckVhY2goZWwgPT4geyBlbC5fc2VsZWN0ZWQgPSBmYWxzZTsgdGhpcy5yZW1vdmVJdGVtKGVsLCB0cmlwdGljSXRlbSkgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChzZWwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuYWRkSXRlbShpdGVtLCB0cmlwdGljSXRlbSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoaXRtX2dyb3VwICYmIGFsbF9pdG1zICYmIGFsbF9pdG1zLmV2ZXJ5KHQgPT4gdC5fc2VsZWN0ZWQpKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0R3JvdXAoaXRtX2dyb3VwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlSXRlbShpdGVtLCB0cmlwdGljSXRlbSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoaXRtX2dyb3VwKVxyXG4gICAgICAgICAgICAgICAgICAgIGl0bV9ncm91cC5fc2VsZWN0ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhlbHBlciBwZXIgc2VsZXppb25hcmUgdW4gZ3J1cHBvIGUsIHJpY29yc2l2YW1lbnRlLCBzZSB0dXR0aSBpIGdydXBwaSBzb3R0b3N0YW50aSBhbCBwYXJlbnQgc29ubyBzZWxlemlvbmF0aSwgc2VsZXppb25hcmUgaSBncnVwcGkgcGFkcmlcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IGdyb3VwIEdydXBwbyBkYSBzZWxlemlvbmFyZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHNlbGVjdEdyb3VwKGdyb3VwOiBhbnkpIHtcclxuICAgICAgICBncm91cC5fc2VsZWN0ZWQgPSB0cnVlO1xyXG4gICAgICAgIGxldCBwYXJlbnQgPSB0aGlzLmdldEdyb3VwUGFyZW50KGdyb3VwKTtcclxuICAgICAgICBpZihwYXJlbnQgJiYgdGhpcy5nZXRHcm91cENoaWxkR3JvdXBzKG51bGwsIHBhcmVudCwgbnVsbCwgdHJ1ZSkuZXZlcnkodCA9PiB0Ll9zZWxlY3RlZCkpXHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0R3JvdXAocGFyZW50KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERhdG8gTCdvZ2dldHRvIGRpIHNlbGV6aW9uZSwgbCdvZ2dldHRvIGRhIHNlbGV6aW9uYXJlL2Rlc2VsZXppb25hcmUgZSB0dXR0aSBpIHBhcmFtZXRyaSBkZWwgY2FzbyBlZmZldHR1YSBsZSBvcGVyYXppb25pIGNoZSBzZXJ2b25vLlxyXG4gICAgICogXHJcbiAgICAgKiBMYSBsb2dpY2EgZGkgcXVlc3RhIGZ1bnppb25lIMOoIG5hdGEgZXNzZW56aWFsbWVudGUgZGEgc3BhbSBkaSB0cmlhbCAmIGVycm9yIGVkIMOoIHN0YXRhIHRlc3RhdGEgc29sbyBmaW5vIGEgZHVlIGxpdmVsbGkgZGkgcmFnZ3J1cHBhbWVudG8sXHJcbiAgICAgKiBxdWFsc2lhc2kgY29zYSB2YWRhIG9sdHJlIG5vbiDDqCAxMDAlIGRldHRvIGNoZSBmdW56aW9uaS4uLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHBlcmZvcm1TZWxlY3Rpb25PcGVyYXRpb25zKGJhc2U6IEl0ZW1zU2VsZWN0aW9uPGFueT4sIGl0ZW06IGFueSwgYWxsOiBib29sZWFuLCBncm91cDogYm9vbGVhbiwgc2VsOiBib29sZWFuLCBzZWxfaXRtOiBhbnlbXSwgc2VsX2dycDogYW55W10sIGRlc2VsX2l0bTogYW55W10sIGRlc2VsX2dycDogYW55W10sIGFsbF9pdG1zOiBhbnlbXSwgYWxsX2dycHM6IGFueVtdLCBwYXJlbnRfaW5jbDogYm9vbGVhbiwgcGFyZW50X2V4Y2w6IGJvb2xlYW4pIHtcclxuICAgICAgICBsZXQgdHJpcHRpY0dyb3VwID0gdGhpcy5nZXRUcmlwdGljKCdncm91cCcsIGJhc2UpO1xyXG4gICAgICAgIGxldCB0cmlwdGljSXRlbSA9IHRoaXMuZ2V0VHJpcHRpYygnaXRlbScsIGJhc2UpO1xyXG4gICAgICAgIGxldCB0cmlwdGljRXhjbCA9IHRoaXMuZ2V0VHJpcHRpYygnZXhjbHVzaW9uJywgYmFzZSk7XHJcbiAgICAgICAgbGV0IHRyaXB0aWNncnBFeGNsID0gdGhpcy5nZXRUcmlwdGljKCdncm91cF9leGNsdXNpb24nLCBiYXNlKTtcclxuXHJcbiAgICAgICAgaWYgKGdyb3VwKSB7XHJcbiAgICAgICAgICAgIGlmIChzZWwpIHtcclxuICAgICAgICAgICAgICAgIGlmIChhbGwgfHwgcGFyZW50X2luY2wpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVJdGVtKGl0ZW0sIHRyaXB0aWNncnBFeGNsKTtcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZEl0ZW0oaXRlbSwgdHJpcHRpY0dyb3VwKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsX2l0bSkgc2VsX2l0bS5mb3JFYWNoKGVsID0+IHRoaXMucmVtb3ZlSXRlbShlbCwgdHJpcHRpY0l0ZW0pKTtcclxuICAgICAgICAgICAgICAgIGlmIChzZWxfZ3JwKSBzZWxfZ3JwLmZvckVhY2goZ3IgPT4gdGhpcy5yZW1vdmVJdGVtKGdyLCB0cmlwdGljR3JvdXApKTtcclxuICAgICAgICAgICAgICAgIGlmIChhbGxfaXRtcykgYWxsX2l0bXMuZm9yRWFjaChlbCA9PiB7IGVsLl9zZWxlY3RlZCA9IHRydWU7IHRoaXMucmVtb3ZlSXRlbShlbCwgdHJpcHRpY0V4Y2wpOyB9KTtcclxuICAgICAgICAgICAgICAgIGlmIChhbGxfZ3JwcykgYWxsX2dycHMuZm9yRWFjaChnciA9PiB7IGdyLl9zZWxlY3RlZCA9IHRydWU7IHRoaXMucmVtb3ZlSXRlbShnciwgdHJpcHRpY2dycEV4Y2wpOyB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmIChhbGwgfHwgcGFyZW50X2luY2wpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRJdGVtKGl0ZW0sIHRyaXB0aWNncnBFeGNsKTtcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUl0ZW0oaXRlbSwgdHJpcHRpY0dyb3VwKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoZGVzZWxfaXRtKSBkZXNlbF9pdG0uZm9yRWFjaChlbCA9PiB0aGlzLnJlbW92ZUl0ZW0oZWwsIHRyaXB0aWNFeGNsKSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGVzZWxfZ3JwKSBkZXNlbF9ncnAuZm9yRWFjaChnciA9PiB0aGlzLnJlbW92ZUl0ZW0oZ3IsIHRyaXB0aWNFeGNsKSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoYWxsX2l0bXMpIGFsbF9pdG1zLmZvckVhY2goZWwgPT4geyBlbC5fc2VsZWN0ZWQgPSBmYWxzZTsgdGhpcy5yZW1vdmVJdGVtKGVsLCB0cmlwdGljSXRlbSk7IH0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKGFsbF9ncnBzKSBhbGxfZ3Jwcy5mb3JFYWNoKGdyID0+IHsgZ3IuX3NlbGVjdGVkID0gZmFsc2U7IHRoaXMucmVtb3ZlSXRlbShnciwgdHJpcHRpY0dyb3VwKTsgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChzZWwpIHtcclxuICAgICAgICAgICAgICAgIGlmICgocGFyZW50X2V4Y2wgPT0gbnVsbCAmJiBhbGwpIHx8IHBhcmVudF9pbmNsKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlSXRlbShpdGVtLCB0cmlwdGljRXhjbCk7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRJdGVtKGl0ZW0sIHRyaXB0aWNJdGVtKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmIChwYXJlbnRfZXhjbCB8fCAoIWFsbCAmJiBwYXJlbnRfZXhjbCA9PSBudWxsKSlcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUl0ZW0oaXRlbSwgdHJpcHRpY0l0ZW0pO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkSXRlbShpdGVtLCB0cmlwdGljRXhjbCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgXHJcbiAgICAvKipcclxuICAgICAqIEhlbHBlciBwZXIgZXZpdGFyZSBkaSByaXNjcml2ZXJlIG9nbmkgc2FudGEgdm9sdGEgYXJyYXkuc3BsaWNlKGFycmF5LmluZGV4b2YoaXRlbSksIDEpO1xyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHJlbW92ZUl0ZW0oaXRlbTogYW55LCB0cmlwdGljPzogQ2FjaGVUcmlwdGljKSB7XHJcbiAgICAgICAgbGV0IGluZGV4ID0gdHJpcHRpYy5pbmRleF9jYWNoZS5nZXQoaXRlbS5faGFzaCk7XHJcbiAgICAgICAgaWYgKGluZGV4ICE9IG51bGwpIHtcclxuICAgICAgICAgICAgdHJpcHRpYy5jYWNoZS5kZWxldGUoaXRlbS5faGFzaCk7XHJcbiAgICAgICAgICAgIHRyaXB0aWMuaW5kZXhfY2FjaGUuZGVsZXRlKGl0ZW0uX2hhc2gpO1xyXG4gICAgICAgICAgICB0cmlwdGljLmFycmF5W2luZGV4XSA9IG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gISFpbmRleDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhlbHBlciBwZXIgZXZpdGFyZSBkaSByaXNjcml2ZXJlIG9nbmkgc2FudGEgdm9sdGEgYXJyYXkucHVzaChpdGVtKTsgZSBsYSBnZXN0aW9uZSBkZWxsYSBcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBhZGRJdGVtKGl0ZW06IGFueSwgdHJpcHRpYz86IENhY2hlVHJpcHRpYyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICh0cmlwdGljLmluZGV4X2NhY2hlLmdldChpdGVtLl9oYXNoKSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIGxldCBpID0gdHJpcHRpYy5hcnJheS5wdXNoKGl0ZW0pIC0gMTtcclxuICAgICAgICAgICAgdHJpcHRpYy5jYWNoZS5zZXQoaXRlbS5faGFzaCwgaXRlbSk7XHJcbiAgICAgICAgICAgIHRyaXB0aWMuaW5kZXhfY2FjaGUuc2V0KGl0ZW0uX2hhc2gsIGkpO1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE90dGllbmUgaWwgdHJpdHRpY28gZGkgc2VsZXppb25lOiBMJ2FycmF5IGRlZ2xpIG9nZ2V0dGkgZSBsZSBkdWUgY2FjaGVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZXRUcmlwdGljKHN1YmplY3Q6ICdncm91cCcgfCAnaXRlbScgfCAnZ3JvdXBfZXhjbHVzaW9uJyB8ICdleGNsdXNpb24nLCBiYXNlOiBJdGVtc1NlbGVjdGlvbjxhbnk+KTogQ2FjaGVUcmlwdGljIHtcclxuICAgICAgICBzd2l0Y2ggKHN1YmplY3QpIHtcclxuICAgICAgICAgICAgY2FzZSAnZ3JvdXAnOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDYWNoZVRyaXB0aWModGhpcy5ncm91cHNDYWNoZSwgdGhpcy5pX2dyb3Vwc0NhY2hlLCBiYXNlLmdyb3Vwcyk7XHJcbiAgICAgICAgICAgIGNhc2UgJ2l0ZW0nOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDYWNoZVRyaXB0aWModGhpcy5pdGVtc0NhY2hlLCB0aGlzLmlfaXRlbXNDYWNoZSwgYmFzZS5pdGVtcyk7XHJcbiAgICAgICAgICAgIGNhc2UgJ2dyb3VwX2V4Y2x1c2lvbic6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENhY2hlVHJpcHRpYyh0aGlzLmdyb3VwX2V4Y2x1c2lvbnNDYWNoZSwgdGhpcy5pX2dyb3VwX2V4Y2x1c2lvbnNDYWNoZSwgYmFzZS5ncm91cF9leGNsdXNpb25zKTtcclxuICAgICAgICAgICAgY2FzZSAnZXhjbHVzaW9uJzpcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ2FjaGVUcmlwdGljKHRoaXMuZXhjbHVzaW9uc0NhY2hlLCB0aGlzLmlfZXhjbHVzaW9uc0NhY2hlLCBiYXNlLmV4Y2x1c2lvbnMpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERhdG8gdW4gb2dnZXR0byByZXN0aXR1aXNjZSBpbCBncnVwcG8gZGkgY3VpIGZhIHBhcnRlLCBzZSBlc2lzdGVcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IGl0ZW0gT2dnZXR0byBkaSBjdWkgdHJvdmFyZSBpbCBncnVwcG9cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZXRJdGVtR3JvdXAoaXRlbTogYW55KTogYW55IHtcclxuICAgICAgICBsZXQgcGFyZW50ID0gdGhpcy5yZ0dyb3VwQ2FjaGUuZ2V0KGl0ZW0uX3RoaXNLZXkpXHJcbiAgICAgICAgaWYgKHBhcmVudClcclxuICAgICAgICAgICAgcmV0dXJuIHBhcmVudDtcclxuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEYXRhIGxhIGNoaWF2ZSBkaSB1biBncnVwcG8gcmVzdGl0dWlzY2UgdHV0dGkgZ2xpIG9nZ2V0dGkgY29uIHF1ZWxsYSBjaGlhdmVcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHthbnl9IGdyb3VwIENoaWF2ZSBkYSBjZXJjYXJlXHJcbiAgICAgKiBAcGFyYW0geydzZWxlY3RlZCcgfCAndW5zZWxlY3RlZCd9IHN0YXR1cyBTdGF0byBkZWdsaSBlbGVtZW50aSwgc2VsZXppb25hdGkgbyBub1xyXG4gICAgICogQHBhcmFtIHtib29sZWFufSByZWN1cnNpdmUgSW5kaWNhIHNlIGNlcmNhcmUgc29sbyBnbGkgZWxlbWVudGkgZGlyZXR0YW1lbnRlIGNvbGxlZ2F0aSBvIHNlIHByZW5kZXJlIGFuY2hlIHF1ZWxsaSBkZWkgZ3J1cHBpIGZpZ2xpXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHthbnlbXX0gT2dnZXR0aSBkaSB0aXBvICoqX2l0ZW0qKiBmYWNlbnRpIGNhcG8gYWxsYSBjaGlhdmUgKipncm91cEtleSoqXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0R3JvdXBJdGVtcyhzZWwgOkl0ZW1zU2VsZWN0aW9uPGFueT4sIGdyb3VwOiBhbnksIHN0YXR1cz86ICdzZWxlY3RlZCcgfCAndW5zZWxlY3RlZCcsIHJlY3Vyc2l2ZTogYm9vbGVhbiA9IGZhbHNlLCBhbGxiYXNlOiBhbnlbXSA9IG51bGwpOiBhbnlbXSB7XHJcbiAgICAgICAgbGV0IGl0ZW1zID0gW107XHJcblxyXG4gICAgICAgIGlmIChhbGxiYXNlKVxyXG4gICAgICAgICAgICBpdGVtcyA9IGFsbGJhc2U7XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChyZWN1cnNpdmUpIHtcclxuICAgICAgICAgICAgICAgIC8vIEluIG1vZGFsaXTDoCByaWNvcnNpdmEgcHJlbmRvIGdsaSBvZ2dldHRpIGRpIHR1dHRlIGxlIGNoaWF2aSBzaW1pbGkgY2hlIHRyb3ZvXHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBrZXkgb2YgdGhpcy5yZ0l0ZW1DYWNoZS5rZXlzKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGtleS5zdGFydHNXaXRoKGdyb3VwLl90aGlzS2V5KSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMucHVzaCguLi50aGlzLnJnSXRlbUNhY2hlLmdldChrZXkpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICBpdGVtcyA9IHRoaXMucmdJdGVtQ2FjaGUuZ2V0KGdyb3VwLl90aGlzS2V5KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGl0ZW1zID0gaXRlbXMuZmlsdGVyKHQgPT4gIXN0YXR1cyB8fCAodC5fc2VsZWN0ZWQgJiYgc3RhdHVzID09ICdzZWxlY3RlZCcpIHx8ICghdC5fc2VsZWN0ZWQgJiYgc3RhdHVzID09ICd1bnNlbGVjdGVkJykpO1xyXG5cclxuICAgICAgICAvLyBOb24gdHJvdm8gbmVzc3VuIG9nZ2V0dG8sIHBlcsOyIG1hZ2FyaSBkaSBvZ2dldHRpIG5lIGhvIGFsbCdpbnRlcm5vIGRlbGwnb2dnZXR0byBkaSBzZWxlemlvbmUuIFxyXG4gICAgICAgIC8vIFF1ZXN0byBwdcOyIGVzc2VyZSB2ZXJvIHNvbG8gc2UgTk9OIHNvbm8gaW4gbW9kYWxpdMOgIGFycmF5LCBpbiBjYXNvIGNvbnRyYXJpbyBnbGkgb2dnZXR0aSBsaSBkZXZvIHBlciBmb3J6YSBhdmVyZSB0dXR0aVxyXG4gICAgICAgIGlmIChpdGVtcy5sZW5ndGggIT0gMCB8fCAhc2VsIHx8IHRoaXMuYXJyYXlNb2RlKVxyXG4gICAgICAgICAgICByZXR1cm4gaXRlbXM7XHJcblxyXG4gICAgICAgIGlmIChzdGF0dXMgPT0gJ3Vuc2VsZWN0ZWQnKVxyXG4gICAgICAgICAgICBpdGVtcyA9IHNlbC5leGNsdXNpb25zLmZpbHRlcih0ID0+IHQgIT0gbnVsbCAmJlxyXG4gICAgICAgICAgICAgICAgKCFyZWN1cnNpdmUgJiYgdC5fdGhpc0tleSA9PSBncm91cC5fdGhpc0tleSkgfHxcclxuICAgICAgICAgICAgICAgIChyZWN1cnNpdmUgJiYgdC5fdGhpc0tleS5zdGFydHNXaXRoKGdyb3VwLl90aGlzS2V5KSkpO1xyXG4gICAgICAgIGVsc2UgaWYgKHN0YXR1cyA9PSAnc2VsZWN0ZWQnKVxyXG4gICAgICAgICAgICBpdGVtcyA9IHNlbC5pdGVtcy5maWx0ZXIodCA9PiB0ICE9IG51bGwgJiZcclxuICAgICAgICAgICAgICAgICghcmVjdXJzaXZlICYmIHQuX3RoaXNLZXkgPT0gZ3JvdXAuX3RoaXNLZXkpIHx8XHJcbiAgICAgICAgICAgICAgICAocmVjdXJzaXZlICYmIHQuX3RoaXNLZXkuc3RhcnRzV2l0aChncm91cC5fdGhpc0tleSkpKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGl0ZW1zO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGF0YSBsYSBjaGlhdmUgZGkgdW4gZ3J1cHBvIHJlc3RpdHVpc2NlIHR1dHRpIGdsaSBvZ2dldHRpIGNvbiBxdWVsbGEgY2hpYXZlXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55fSBncm91cCBHcnVwcG8gZGkgY3VpIGNlcmNhcmUgaWwgcGFyZW50XHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHthbnl9IE9nZ2V0dG8gZGkgdGlwbyAqKl9ncm91cCoqIHJhcHByZXNlbnRhbnRlIGlsIHBhcmVudCBkZWwgKipncm91cCoqIGF0dHVhbGVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZXRHcm91cFBhcmVudChncm91cDogYW55KTogYW55IHtcclxuICAgICAgICBsZXQgcGFyZW50ID0gdGhpcy5yZ0dyb3VwQ2FjaGUuZ2V0KGdyb3VwLl9wYXJlbnQpXHJcbiAgICAgICAgaWYgKHBhcmVudClcclxuICAgICAgICAgICAgcmV0dXJuIHBhcmVudDtcclxuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEYXRhIGxhIGNoaWF2ZSBkaSB1biBncnVwcG8gcmVzdGl0dWlzY2UgdHV0dGkgaSBncnVwcGkgZmlnbGlcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGdyb3VwIEdydXBwbyBjaGUgcmFwcHJlc2VudGEgaWwgcGFkcmUgZGkgY3VpIGNlcmNhcmUgaSBmaWdsaVxyXG4gICAgICogQHBhcmFtIHsnc2VsZWN0ZWQnIHwgJ3Vuc2VsZWN0ZWQnfSBzdGF0dXMgU3RhdG8gZGVpIGdydXBwaSwgc2VsZXppb25hdGkgbyBub1xyXG4gICAgICogQHBhcmFtIHtib29sZWFufSByZWN1cnNpdmUgSW5kaWNhIHNlIGNlcmNhcmUgc29sbyBpIGdydXBwaSBkaXJldHRhbWVudGUgY29sbGVnYXRpIG8gc2UgcHJlbmRlcmUgYW5jaGUgcXVlbGxpIGRlaSBncnVwcGkgZmlnbGlcclxuICAgICAqIFxyXG4gICAgICogQHJldHVybnMge2FueVtdfSBPZ2dldHRpIGRpIHRpcG8gKipfZ3JvdXAqKiBmYWNlbnRpIGNhcG8gYWxsYSBjaGlhdmUgKipncm91cEtleSoqXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0R3JvdXBDaGlsZEdyb3VwcyhzZWw6IEl0ZW1zU2VsZWN0aW9uPGFueT4sIGdyb3VwOiBhbnksIHN0YXR1cz86ICdzZWxlY3RlZCcgfCAndW5zZWxlY3RlZCcsIHJlY3Vyc2l2ZTogYm9vbGVhbiA9IGZhbHNlLCBhbGxiYXNlOiBhbnlbXSA9IG51bGwpIHtcclxuICAgICAgICBsZXQgdGhpc0dyb3VwOiBhbnkgPSB0aGlzLnJnR3JvdXBDYWNoZS5nZXQoZ3JvdXAuX3RoaXNLZXkpO1xyXG4gICAgICAgIGxldCBpdGVtcyA9IFtdO1xyXG5cclxuICAgICAgICBpZiAoYWxsYmFzZSlcclxuICAgICAgICAgICAgaXRlbXMgPSBhbGxiYXNlO1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAocmVjdXJzaXZlKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBJbiBtb2RhbGl0w6Agcmljb3JzaXZhIHByZW5kbyBnbGkgb2dnZXR0aSBkaSB0dXR0ZSBsZSBjaGlhdmkgc2ltaWxpIGNoZSB0cm92b1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQga2V5IG9mIHRoaXMucmdDaGlsZEdyb3Vwc0NhY2hlLmtleXMoKSlcclxuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoZ3JvdXAuX3RoaXNLZXkpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtcy5wdXNoKC4uLnRoaXMucmdDaGlsZEdyb3Vwc0NhY2hlLmdldChrZXkpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICBpdGVtcyA9IHRoaXMucmdDaGlsZEdyb3Vwc0NhY2hlLmdldChncm91cC5fdGhpc0tleSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpdGVtcyA9IGl0ZW1zLmZpbHRlcih0ID0+ICFzdGF0dXMgfHwgKHQuX3NlbGVjdGVkICYmIHN0YXR1cyA9PSAnc2VsZWN0ZWQnKSB8fCAoIXQuX3NlbGVjdGVkICYmIHN0YXR1cyA9PSAndW5zZWxlY3RlZCcpKTtcclxuXHJcbiAgICAgICAgLy8gTm9uIHRyb3ZvIG5lc3N1biBvZ2dldHRvLCBwZXLDsiBtYWdhcmkgZGkgb2dnZXR0aSBuZSBobyBhbGwnaW50ZXJubyBkZWxsJ29nZ2V0dG8gZGkgc2VsZXppb25lXHJcbiAgICAgICAgaWYgKGl0ZW1zLmxlbmd0aCAhPSAwIHx8ICFzZWwpXHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtcztcclxuXHJcbiAgICAgICAgaWYgKHN0YXR1cyA9PSAndW5zZWxlY3RlZCcpXHJcbiAgICAgICAgICAgIGl0ZW1zID0gc2VsLmdyb3VwX2V4Y2x1c2lvbnMuZmlsdGVyKCh0OiBhbnkpID0+IHQgIT0gbnVsbCAmJiAoXHJcbiAgICAgICAgICAgICAgICAoIXJlY3Vyc2l2ZSAmJiB0Ll90aGlzUm91dGUubGVuZ3RoID09IHRoaXNHcm91cC5fdGhpc1JvdXRlLmxlbmd0aCArIDEgJiYgdC5fdGhpc1JvdXRlLnN0YXJ0c1dpdGgoZ3JvdXAuX3RoaXNLZXkpKSB8fCBcclxuICAgICAgICAgICAgICAgIChyZWN1cnNpdmUgJiYgdC5fdGhpc0tleS5zdGFydHNXaXRoKGdyb3VwLl90aGlzS2V5KSkpKTtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIGl0ZW1zID0gc2VsLmdyb3Vwcy5maWx0ZXIoKHQ6IGFueSkgPT4gdCAhPSBudWxsICYmIChcclxuICAgICAgICAgICAgICAgICghcmVjdXJzaXZlICYmIHQuX3RoaXNSb3V0ZS5sZW5ndGggPT0gdGhpc0dyb3VwLl90aGlzUm91dGUubGVuZ3RoICsgMSAmJiB0Ll90aGlzUm91dGUuc3RhcnRzV2l0aChncm91cC5fdGhpc0tleSkpIHx8IFxyXG4gICAgICAgICAgICAgICAgKHJlY3Vyc2l2ZSAmJiB0Ll90aGlzS2V5LnN0YXJ0c1dpdGgoZ3JvdXAuX3RoaXNLZXkpKSkpO1xyXG5cclxuICAgICAgICByZXR1cm4gaXRlbXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaW5hbGl6emEgbGUgaW5mb3JtYXppb25pIGRpIHNlbGV6aW9uZSBkZWwgKipJdGVtc1NlbGVjdGlvbioqIGNvcnJlbnRlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZmluYWxpemVTZWxlY3Rpb25JbmZvcm1hdGlvbnMoc2VsZWN0aW9uSXRlbTogSXRlbXNTZWxlY3Rpb248YW55Pikge1xyXG4gICAgICAgIC8vIERhdG8gY2hlIGxlIGRlbGV0ZSBzb25vIGxvZ2ljaGUgZGF0byBjaGUgdGVuZ28gbGEgY2FjaGUgZGVnbGkgaW5kaWNpIGRldm8gcmVuZGVybGUgZmlzaWNoZVxyXG4gICAgICAgIGxldCB0bXBHcnAgPSBbXSwgdG1wSXRlbXMgPSBbXSwgdG1wRXhjbCA9IFtdLCB0bXBHcnBFeGNsID0gW107XHJcbiAgICAgICAgbGV0IGdycFJlbW92ZWQgPSBmYWxzZSwgaXRlbXNSZW1vdmVkID0gZmFsc2UsIGV4Y2xSZW1vdmVkID0gZmFsc2UsIGdycEV4Y2xSZW1vdmVkID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZWN0aW9uSXRlbS5pdGVtcy5sZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgaWYgKHNlbGVjdGlvbkl0ZW0uaXRlbXNbaV0gIT0gbnVsbCkgdG1wSXRlbXMucHVzaChzZWxlY3Rpb25JdGVtLml0ZW1zW2ldKTtcclxuICAgICAgICAgICAgZWxzZSBpdGVtc1JlbW92ZWQgPSB0cnVlO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZWN0aW9uSXRlbS5ncm91cHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgIGlmIChzZWxlY3Rpb25JdGVtLmdyb3Vwc1tpXSAhPSBudWxsKSB0bXBHcnAucHVzaChzZWxlY3Rpb25JdGVtLmdyb3Vwc1tpXSk7XHJcbiAgICAgICAgICAgIGVsc2UgZ3JwUmVtb3ZlZCA9IHRydWU7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxlY3Rpb25JdGVtLmV4Y2x1c2lvbnMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgIGlmIChzZWxlY3Rpb25JdGVtLmV4Y2x1c2lvbnNbaV0gIT0gbnVsbCkgdG1wRXhjbC5wdXNoKHNlbGVjdGlvbkl0ZW0uZXhjbHVzaW9uc1tpXSk7XHJcbiAgICAgICAgICAgIGVsc2UgZXhjbFJlbW92ZWQgPSB0cnVlO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZWN0aW9uSXRlbS5ncm91cF9leGNsdXNpb25zLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICBpZiAoc2VsZWN0aW9uSXRlbS5ncm91cF9leGNsdXNpb25zW2ldICE9IG51bGwpIHRtcEdycEV4Y2wucHVzaChzZWxlY3Rpb25JdGVtLmdyb3VwX2V4Y2x1c2lvbnNbaV0pO1xyXG4gICAgICAgICAgICBlbHNlIGdycEV4Y2xSZW1vdmVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgc2VsZWN0aW9uSXRlbS5pdGVtcyA9IHRtcEl0ZW1zO1xyXG4gICAgICAgIHNlbGVjdGlvbkl0ZW0uZ3JvdXBfZXhjbHVzaW9ucyA9IHRtcEdycEV4Y2w7XHJcbiAgICAgICAgc2VsZWN0aW9uSXRlbS5leGNsdXNpb25zID0gdG1wRXhjbDtcclxuICAgICAgICBzZWxlY3Rpb25JdGVtLmdyb3VwcyA9IHRtcEdycDtcclxuXHJcbiAgICAgICAgLy8gTGUgY2FjaGUgZGVnbGkgaW5kaWNpIHBvdHJlYmJlcm8gYXZlcmUgYnVjaGksIHJpc29sdm9cclxuICAgICAgICBpZiAoZ3JwUmVtb3ZlZClcclxuICAgICAgICAgICAgdGhpcy5pX2dyb3Vwc0NhY2hlID0gdGhpcy5jb21wYWN0SW5kZXhNYXAodGhpcy5pX2dyb3Vwc0NhY2hlKTtcclxuICAgICAgICBpZiAoaXRlbXNSZW1vdmVkKVxyXG4gICAgICAgICAgICB0aGlzLmlfaXRlbXNDYWNoZSA9IHRoaXMuY29tcGFjdEluZGV4TWFwKHRoaXMuaV9pdGVtc0NhY2hlKTtcclxuICAgICAgICBpZiAoZXhjbFJlbW92ZWQpXHJcbiAgICAgICAgICAgIHRoaXMuaV9leGNsdXNpb25zQ2FjaGUgPSB0aGlzLmNvbXBhY3RJbmRleE1hcCh0aGlzLmlfZXhjbHVzaW9uc0NhY2hlKTtcclxuICAgICAgICBpZiAoZ3JwRXhjbFJlbW92ZWQpXHJcbiAgICAgICAgICAgIHRoaXMuaV9ncm91cF9leGNsdXNpb25zQ2FjaGUgPSB0aGlzLmNvbXBhY3RJbmRleE1hcCh0aGlzLmlfZ3JvdXBfZXhjbHVzaW9uc0NhY2hlKTtcclxuXHJcbiAgICAgICAgLy8gUG9pIHJpcHJlbmRvIGEgZmFyZSB0dXR0byBpbiBub3JtYWxpdMOgXHJcbiAgICAgICAgc2VsZWN0aW9uSXRlbS5jb3VudCA9IHRoaXMuZXZhbHVhdGVTZWxlY3RlZCgpO1xyXG5cclxuICAgICAgICAvLyBTZSBobyBmYXR0byBzZWxlemlvbmUgXCJhbGxcIiBtYSBwb2kgbWkgc29ubyBtZXNzbyBhIHRvZ2xpZXJlIHR1dHRpIGdsaSBlbGVtZW50aSBmaW5vIGEgcmltYW5lcm5lIDAgcmVzZXR0byBsJ29nZ2V0dG8gZGkgc2VsZXppb25lXHJcbiAgICAgICAgaWYgKHNlbGVjdGlvbkl0ZW0uY291bnQgPT0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLmJvdW5kU291cmNlLmZvckVhY2godCA9PiB0Ll9zZWxlY3RlZCA9IGZhbHNlKTtcclxuICAgICAgICAgICAgc2VsZWN0aW9uSXRlbS5hbGwgPSBmYWxzZTtcclxuICAgICAgICAgICAgc2VsZWN0aW9uSXRlbS5leGNsdXNpb25zID0gW107XHJcbiAgICAgICAgICAgIHNlbGVjdGlvbkl0ZW0uaXRlbXMgPSBbXTtcclxuICAgICAgICAgICAgc2VsZWN0aW9uSXRlbS5ncm91cHMgPSBbXTtcclxuICAgICAgICAgICAgc2VsZWN0aW9uSXRlbS5ncm91cF9leGNsdXNpb25zID0gW107XHJcblxyXG4gICAgICAgICAgICAvLyBSaXB1bGlzY28gbGEgY2FjaGUgYWx0cmltZW50aSBtaSByaW1hbmUgcGllbmEgZGkgdHV0dGUgbGUgZXNjbHVzaW9uaVxyXG4gICAgICAgICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uQ2FjaGVzKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBTZSBsYSBwb3NzaWJpbGl0w6AgZGkgZmFyZSBcIlNlbGV6aW9uYSB0dXR0b1wiIMOoIGFiaWxpdGF0YSBhbGxvcmEgbGEgY29uc2lkZXJvIGFwcGVuYSBtaSB2aWVuZSBzZWxlemlvbmF0byBxdWFsY29zYVxyXG4gICAgICAgIHRoaXMuY2FuU2VsZWN0QWxsID0gc2VsZWN0aW9uSXRlbS5jb3VudCA+IDAgJiYgdGhpcy5TZWxlY3RBbGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb21wYXR0YSB1bmEgY2FjaGUgZGkgaW5kaWNpXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgY29tcGFjdEluZGV4TWFwKG1hcDogTWFwPHN0cmluZywgbnVtYmVyPik6IE1hcDxzdHJpbmcsIG51bWJlcj4ge1xyXG4gICAgICAgIGxldCBpbmRleCA9IDA7XHJcbiAgICAgICAgbGV0IHJldCA9IG5ldyBNYXAoKTtcclxuICAgICAgICBmb3IgKGxldCBrZXkgb2YgbWFwLmtleXMoKSlcclxuICAgICAgICAgICAgcmV0LnNldChrZXksIGluZGV4KyspO1xyXG5cclxuICAgICAgICByZXR1cm4gcmV0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2VzdGlzY2UgaSBjbGljayBzdWxsYSB0YWJlbGxhLCBnZXN0ZW5kbyBldmVudHVhbG1lbnRlIGFuY2hlIGdsaSBTaGlmdCArIENsaWNrIHBlciBzZWxlemlvbmFyZSB1biByYW5nZSBkaSBvZ2dldHRpXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHthbnl9IGV2ZW50IEV2ZW50byBuYXRpdm8gSFRNTCBkZWwgY2xpY2tcclxuICAgICAqIEBwYXJhbSB7YW55fSBpdGVtIE9nZ2V0dG8gYmluZGF0byBzdSBjdWkgc2kgw6ggZWZmZXR0dWF0byBpbCBjbGlja1xyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSAqKnRydWUqKiBzZSBsJ29wZXJhaXpvbmUgw6ggYW5kYXRhIGEgYnVvbiBmaW5lLCAqKmZhbHNlKiogYWx0cmltZW50aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlQ2xpY2soZXZlbnQ6IGFueSwgaXRlbTogYW55KTogYm9vbGVhbiB7XHJcbiAgICAgICAgLy8gU2VsZXppb25vIGRlbCB0ZXN0byBtYSBub24gaG8gc2hpZnQgcHJlbXV0byAtPiBpZ25vcm8gbGEgc2VsZXppb25lXHJcbiAgICAgICAgaWYgKChldmVudC52aWV3LmdldFNlbGVjdGlvbigpLnR5cGUgPT0gJ1JhbmdlJyB8fCBldmVudC52aWV3LmdldFNlbGVjdGlvbigpLnRvU3RyaW5nKCkubGVuZ3RoID4gMCkgJiYgIWV2ZW50LnNoaWZ0S2V5KVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgICAgIC8vIFNlbGV6aW9ubyBkZWwgdGVzdG8gZSBobyBzaGlmdCBwcmVtdXRvIC0+IGFubnVsbG8gbGEgc2VsZXppb25lIGRlbCB0ZXN0b1xyXG4gICAgICAgIGlmICgoZXZlbnQudmlldy5nZXRTZWxlY3Rpb24oKS50eXBlID09ICdSYW5nZScgfHwgZXZlbnQudmlldy5nZXRTZWxlY3Rpb24oKS50b1N0cmluZygpLmxlbmd0aCA+IDApICYmIGV2ZW50LnNoaWZ0S2V5KVxyXG4gICAgICAgICAgICB0aGlzLnV0aUV4dHMuY2xlYXJUZXh0U2VsZWN0aW9uKCk7XHJcblxyXG4gICAgICAgIGxldCBzZWxlY3RlZGl0ZW1zOiBhbnlbXSA9IFtdO1xyXG4gICAgICAgIGlmIChldmVudC5zaGlmdEtleSAmJiB0aGlzLlNoaWZ0Q2xpY2sgJiYgIXRoaXMuU2luZ2xlU2VsZWN0aW9uKSB7XHJcbiAgICAgICAgICAgIGxldCBzdGFydFNlbGVjdGluZyA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgbGV0IGl0ZW1zID0gdGhpcy5ib3VuZFNvdXJjZS5maWx0ZXIodCA9PiAhdC5fZ3JvdXAgJiYgIXQuX3NlcCk7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCB0ID0gaXRlbXNbaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhcnRTZWxlY3RpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICB0Ll9zZWxlY3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRpdGVtcy5wdXNoKHQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKCh0ID09IGl0ZW0gfHwgdCA9PSB0aGlzLmxhc3RTZWxlY3RlZCkgJiYgIXN0YXJ0U2VsZWN0aW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRTZWxlY3RpbmcgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHQuX3NlbGVjdGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZGl0ZW1zLnB1c2godCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCh0ID09IGl0ZW0gfHwgdCA9PSB0aGlzLmxhc3RTZWxlY3RlZCkgJiYgc3RhcnRTZWxlY3RpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRTZWxlY3RpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGl0ZW0uX3NlbGVjdGVkID0gIWl0ZW0uX3NlbGVjdGVkO1xyXG4gICAgICAgICAgICB0aGlzLmxhc3RTZWxlY3RlZCA9IGl0ZW07XHJcbiAgICAgICAgICAgIHNlbGVjdGVkaXRlbXMucHVzaChpdGVtKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBpdGVtU2VsZWN0aW9uID0gdGhpcy5oYW5kbGVJdGVtc1NlbGVjdGlvbihzZWxlY3RlZGl0ZW1zKTtcclxuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcclxuXHJcbiAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZWQuZW1pdChpdGVtU2VsZWN0aW9uKTtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFZhbHV0YSBsYSBxdWFudGl0w6AgZGkgb2dnZXR0aSBjaGUgc29ubyBzdGF0aSBzZWxlemlvbmF0aSBhbCB0ZXJtaW5lIGRpIHVuIGV2ZW50byBkaSBzZWxlemlvbmVcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1lcm8gZGkgb2dnZXR0aSBzZWxlemlvbmF0aVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGV2YWx1YXRlU2VsZWN0ZWQoKTogbnVtYmVyIHtcclxuICAgICAgICBsZXQgc2kgPSAodGhpcy5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+KT8uc2VsZWN0aW9uIHx8IHRoaXMuYXJyYXltb2RlU2VsZWN0aW9uO1xyXG5cclxuICAgICAgICBsZXQgZXhjQnlHcm91cCA9IHNpLmdyb3VwX2V4Y2x1c2lvbnMucmVkdWNlKChwcmV2LCBjdXJyKSA9PiBwcmV2ICsgY3Vyci5jb3VudCwgMCk7XHJcbiAgICAgICAgbGV0IGluY0J5R3JvdXAgPSBzaS5ncm91cHMucmVkdWNlKChwcmV2LCBjdXJyKSA9PiBwcmV2ICsgY3Vyci5jb3VudCwgMCk7XHJcblxyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRPYmplY3RzID0gKHNpLmFsbCA/IHRoaXMuQmFzZUl0ZW1zQ291bnQgOiBpbmNCeUdyb3VwKSAtIGV4Y0J5R3JvdXAgKyBzaS5pdGVtcy5sZW5ndGggLSBzaS5leGNsdXNpb25zLmxlbmd0aDtcclxuICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3RlZE9iamVjdHM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXN0aXNjZSBpbCBjb21hbmRvIGRpIFwiU2VsZXppb25hIHR1dHRvIGluIHR1dHRlIGxlIHBhZ2luZVwiIG8gaWwgc3VvIGNvbnRyYXJpbywgY2lvw6ggXCJSZWltcG9zdGEgc2VsZXppb25lXCJcclxuICAgICAqL1xyXG4gICAgcHVibGljIHNlbGVjdEFsbE9yUmVzZXRTZWxlY3Rpb24oKSB7XHJcbiAgICAgICAgbGV0IHNlbGVjdGlvbkl0ZW0gPSB0aGlzLlZpZXcuc2VsZWN0aW9uIHx8IHRoaXMuYXJyYXltb2RlU2VsZWN0aW9uO1xyXG4gICAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb25DYWNoZXMoKTtcclxuICAgICAgICBzZWxlY3Rpb25JdGVtLmFsbCA9ICFzZWxlY3Rpb25JdGVtLmFsbDtcclxuICAgICAgICBzZWxlY3Rpb25JdGVtLmV4Y2x1c2lvbnMgPSBbXTtcclxuICAgICAgICBzZWxlY3Rpb25JdGVtLmdyb3VwcyA9IFtdO1xyXG4gICAgICAgIHNlbGVjdGlvbkl0ZW0uZ3JvdXBfZXhjbHVzaW9ucyA9IFtdO1xyXG4gICAgICAgIHNlbGVjdGlvbkl0ZW0uaXRlbXMgPSBbXTtcclxuXHJcbiAgICAgICAgLy8gUmlwdWxpc2NvIGdsaSBzdGF0aSBVSSBkaSBzZWxlemlvbmUgZ2xvYmFsZSBzZSBsJ2hvIGRpc2F0dGl2YXRhXHJcbiAgICAgICAgaWYgKCFzZWxlY3Rpb25JdGVtLmFsbCkge1xyXG4gICAgICAgICAgICB0aGlzLmNhblNlbGVjdEFsbCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLmdsb2JhbENoZWNrID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmZpbmFsaXplU2VsZWN0aW9uSW5mb3JtYXRpb25zKHNlbGVjdGlvbkl0ZW0pO1xyXG5cclxuICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlZC5lbWl0KHNlbGVjdGlvbkl0ZW0pO1xyXG5cclxuICAgICAgICAvLyBEb3BvIGF2ZXIgcmVzZXR0YXRvIGRpcmV0dGFtZW50ZSBpbCBzb2xvIG9nZ2V0dG8gdGhpcy5WaWV3LnNlbGVjdGlvbiBkZXZvIGFuY2hlIHJpYWxsaW5lYXJlIGEgdHV0dGkgZ2xpIG9nZ2V0dGkgYmluZGF0aVxyXG4gICAgICAgIHRoaXMuZXZhbHVhdGVTZWxlY3Rpb24odGhpcy5ib3VuZFNvdXJjZSwgc2VsZWN0aW9uSXRlbSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gI2VuZHJlZ2lvblxyXG5cclxuICAgIC8vICNyZWdpb24gR2VzdGlvbmUgUGFnaW5hemlvbmVcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNwb3N0YSBsYSByaWNlcmNhIGRpIHVuYSBwYWdpbmEgaW4gYXZhbnRpIChvIGluZGVpdHJvKVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBwYWdlIE51bWVybyBkaSBwYWdpbmUgZGEgYWdnaXVuZ2VyZSAobyBzb3R0cmFycmUsIHNlIG5lZ2F0aXZvKSBhbGxhIHBhZ2luYSBhdHR1YWxlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhZGRUb1BhZ2UocGFnZTogbnVtYmVyKSB7XHJcbiAgICAgICAgbGV0IHZpZXcgPSB0aGlzLk1haW5Hcm91cFZpZXcgPyB0aGlzLk1haW5Hcm91cFZpZXcgOiB0aGlzLlZpZXc7XHJcblxyXG4gICAgICAgIHRoaXMuZ29Ub1BhZ2UoKCh0aGlzLlNlYXJjaFZpZXcgfHwgdmlldyk/LnBhZ2UgfHwgMCkgKyBwYWdlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNwb3N0YSBsYSByaWNlcmNhIGFsbGEgcGFnaW5hIHNwZWNpZmljYXRhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2UgUGFnaW5hIGEgY3VpIG5hdmlnYXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnb1RvUGFnZShwYWdlOiBudW1iZXIpIHtcclxuICAgICAgICBsZXQgdmlldyA9IHRoaXMuTWFpbkdyb3VwVmlldyA/IHRoaXMuTWFpbkdyb3VwVmlldyA6IHRoaXMuVmlldztcclxuICAgICAgICBpZiAoIXZpZXcucGFnZSB8fCAhdmlldy5wYWdlcylcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBsZXQgYXBwU2VhcmNoRWxlbWVudCA9IHRoaXMuU2VhcmNoVmlldyB8fCB2aWV3O1xyXG4gICAgICAgIGlmIChwYWdlID09PSAwIHx8IHBhZ2UgPiBhcHBTZWFyY2hFbGVtZW50LnBhZ2VzKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGFwcFNlYXJjaEVsZW1lbnQucGFnZSA9IHBhZ2U7XHJcbiAgICAgICAgdGhpcy5hcnJheVB1bHNhbnRpID0gdGhpcy5nZXRQYWdlc0FycmF5KDYsIGFwcFNlYXJjaEVsZW1lbnQucGFnZSwgYXBwU2VhcmNoRWxlbWVudC5wYWdlcyk7XHJcblxyXG4gICAgICAgIGxldCBoYXNHcm91cGluZ3MgPSAhIXRoaXMuTWFpbkdyb3VwVmlldztcclxuICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KGZhbHNlLCBoYXNHcm91cGluZ3MgPyB2aWV3IDogbnVsbCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFdmVudG8gcmljaGlhbWF0byBzdWwgY2FtYmlvIGRlbGxhIHBhZ2luYXppb25lLiBWZXJyw6AgcmljaGlhbWF0byBsJ2V2ZW50byAqKmVtaXRTZWFyY2hSZXF1ZXN0KipcclxuICAgICAqIHBlciBjb211bmljYXJlIGFsIGNvbXBvbmVudGUgY2hlIHV0aWxpenphIHF1ZXN0YSB0YWJlbGxhIGNoZSBpIGRhdGkgc29ubyBkYSBhZ2dpb3JuYXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkl0ZW1zUGVyUGFnZUNoYW5nZWQobmV3SXBwKSB7XHJcbiAgICAgICAgdGhpcy5QYWdlck9wdGlvbnMuVmlldy5pdGVtc3BlcnBhZ2VvdmVycmlkZSA9IG5ld0lwcDtcclxuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcclxuICAgICAgICBpZiAodGhpcy5NYWluR3JvdXBWaWV3KVxyXG4gICAgICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KHRydWUsIHRoaXMuTWFpbkdyb3VwVmlldyk7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXZlbnRvIHJpY2hpYW1hdG8gc3VsIGNhbWJpbyBkZWxsYSBwYWdpbmF6aW9uZS4gVmVycsOgIHJpY2hpYW1hdG8gbCdldmVudG8gKiplbWl0U2VhcmNoUmVxdWVzdCoqIGNvbiBsYSB2aXN0YSBkZWwgc2VwYXJhdG9yZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25Hcm91cEl0ZW1zUGVyUGFnZUNoYW5nZWQocGFnZXI6IEdyb3VwUGFnZXIsIG5ld0lwcDogbnVtYmVyKSB7XHJcbiAgICAgICAgcGFnZXIudmlldy5pdGVtc3BlcnBhZ2VvdmVycmlkZSA9IG5ld0lwcDtcclxuICAgICAgICB0aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KHRydWUsIHBhZ2VyLnZpZXcpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vICNlbmRyZWdpb25cclxuXHJcbiAgICAvLyAjcmVnaW9uIEdlc3Rpb25lIEV4cG9ydFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRWZmZXR0dWEgbCdlc3BvcnRhemlvbmUgZGVpIGRhdGlcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0IEZvcm1hdG8gZGkgZXNwb3J0YXppb25lLiBMZXR0byBzb2xvIGluIG1vZGFsaXTDoCBSZXBvcnQgZGVsbGEgdGFiZWxsYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdHJ5RXhwb3J0KGZvcm1hdD86IHN0cmluZykge1xyXG4gICAgICAgIGlmICghdGhpcy5FeHBvcnRGdW5jdGlvbilcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5yZXBvcnRNb2RlKVxyXG4gICAgICAgICAgICB0aGlzLkV4cG9ydEZ1bmN0aW9uKGZvcm1hdCk7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICB0aGlzLkV4cG9ydEZ1bmN0aW9uKChkYXRhOiBhbnlbXSwgY2FuY2VsOiBib29sZWFuID0gZmFsc2UpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChjYW5jZWwpXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tc2dFeHRzLnNpbXBsZVdhcm5pbmcodGhpcy5sYy5sb2MoXCJDYW5ub3QgZXhwb3J0IGFuIGVtcHR5IGRhdGFzZXRcIikpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldHVwRXhwb3J0KGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IHRoaXMuZXhwb3J0RG93bmxvYWRlci5uYXRpdmVFbGVtZW50LmNsaWNrKCk7IH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBjaGUgZWZmZXR0aXZhbWVudGUgZ2VuZXJhIGdsaSBoZWFkZXIgZSBpIGRhdGkgcGVyIGwnZXNwb3J0YXppb25lIGNvbiAqKm5neC1jc3YqKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55W119IGl0ZW1zIE9nZ2V0dGkgZGEgZXNwb3J0YXJlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc2V0dXBFeHBvcnQoaXRlbXM6IGFueVtdKSB7XHJcbiAgICAgICAgbGV0IGRyY2QgPSB0aGlzLkR5bmFtaWNSb3dDb2x1bW5zRGVmaW5pdGlvbjtcclxuXHJcbiAgICAgICAgdGhpcy5oZWFkZXJzID0gZHJjZCAmJiBkcmNkLmxlbmd0aCA+IDAgPyB0aGlzLmV4cEV4dHMuc2V0dXBGb3JHZW5lcmljRXhwb3J0KGl0ZW1zLCBkcmNkLm1hcCh0ID0+IHsgcmV0dXJuIHsgbGFiZWw6IHQuZGVzY3JpcHRpb24sIGtleTogdC5wcm9wZXJ0eU5hbWUsIG9yZGVyOiB0LmNvbHVtbk9yZGVyIH0gfSkpIDogdGhpcy5leHBFeHRzLnNldHVwRm9yRXhwb3J0KGl0ZW1zKTtcclxuICAgICAgICB0aGlzLmRhdGEgPSBpdGVtcztcclxuICAgIH1cclxuXHJcbiAgICAvLyAjZW5kcmVnaW9uXHJcblxyXG4gICAgLy8gI3JlZ2lvbiBHZXN0aW9uZSBNb2RhbGl0w6AgUmVwb3J0XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTdWwgY2xpY2sgZGVsbCdIZWFkZXIgZGkgdW5hIGNvbG9ubmEgcXVlc3RvIG1ldG9kbyBzaSBvY2N1cGEgZGkgYXBwbGljYXJlIGwnb3JkaW5hbWVudG8gc3VjY2Vzc2l2byBlIGRpIG5vdGlmaWNhcmUgY29uICoqZW1pdFNlYXJjaFJlcXVlc3QqKlxyXG4gICAgICogaWwgYmlzb2dubyBkaSBhZ2dpb3JuYXJlIGkgZGF0aSBkYSBwYXJ0ZSBkZWwgY29tcG9uZW50ZSBjaGUgdXRpbGl6emEgbGEgdGFiZWxsYVxyXG4gICAgICpcclxuICAgICAqIFV0aWxpenphdG8gc29sbyBpbiBtb2RhbGl0w6AgUkVwb3J0XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtSZXBvcnRDb2x1bW59IGNsbSBDb2xvbm5hIGRlbCByZXBvcnQgcGVyIGN1aSBvcmRpbmFyZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0dXBOZXh0T3JkZXJBbmRTZWFyY2goY2xtOiBSZXBvcnRDb2x1bW4pIHtcclxuICAgICAgICBpZiAoISh0aGlzLlZpZXcgaW5zdGFuY2VvZiBSZXBvcnREZWZpbml0aW9uKSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdWaWV3IGRpdmVyc2EgZGEgcmVwb3J0ZGVmaW5pdGlvbiBlbnRyYXRhIG5lbCBtZXRvZG8gc2V0dXBOZXh0T3JkZXJBbmRTZWFyY2gnKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IG9yZGVyTmV4dCA9IHsgTk9ORTogJ0RFU0MnLCBERVNDOiAnQVNDJywgQVNDOiBudWxsIH07XHJcbiAgICAgICAgbGV0IG5leHRPcmRlciA9IG9yZGVyTmV4dFtjbG0ub3JkZXIgfHwgJ05PTkUnXTtcclxuICAgICAgICBjbG0ub3JkZXIgPSBuZXh0T3JkZXI7XHJcblxyXG4gICAgICAgIGxldCBvcmRlcjogUmVwb3J0T3JkZXI7XHJcbiAgICAgICAgbGV0IGNsbU9yZGVyID0gdGhpcy5WaWV3Lm9yZGVycyA/IHRoaXMuVmlldy5vcmRlcnMuZmlsdGVyKHQgPT4gdC5jb2x1bW4gPT0gY2xtLmlkKSA6IFtdO1xyXG4gICAgICAgIGlmIChjbG1PcmRlci5sZW5ndGggPT0gMCAmJiBjbG0ub3JkZXIpIHtcclxuICAgICAgICAgICAgb3JkZXIgPSBuZXcgUmVwb3J0T3JkZXIoKTtcclxuICAgICAgICAgICAgb3JkZXIuY29sdW1uID0gY2xtLmlkO1xyXG4gICAgICAgICAgICBvcmRlci5vcmRlciA9IGNsbS5vcmRlcjtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLlZpZXcub3JkZXJzKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5WaWV3Lm9yZGVycyA9IFtdO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5WaWV3Lm9yZGVycy5wdXNoKG9yZGVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoY2xtT3JkZXIubGVuZ3RoID09IDEpIHtcclxuICAgICAgICAgICAgLy8gUmltdW92byBsJ29yZGluYW1lbnRvIG8gYWdnaW9ybm8gcXVlbGxvIGdpw6AgZXNpc3RlbnRlXHJcbiAgICAgICAgICAgIGlmKCFjbG0ub3JkZXIpXHJcbiAgICAgICAgICAgICAgICBjbG1PcmRlciA9IFtdO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICBjbG1PcmRlclswXS5vcmRlciA9IGNsbS5vcmRlcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0ltcG9zc2liaWxlIHNldHRhcmUgb3JkaW5hbWVudG8uIENvbG9ubmEgJyArIGNsbS5pZCArICcgZGlyZXR0aXZlIGRpIG9yZGluYW1lbnRvICcgKyBjbG1PcmRlci5sZW5ndGggKyAnIG9yZGluYW1lbnRvIHNjZWx0byAnICsgY2xtLm9yZGVyKTtcclxuXHJcbiAgICAgICAgLy8gRG9wbyBhdmVyIGFnZ2lvcm5hdG8gbCdvcmRpbmFtZW50byByaWxhbmNpbyBsYSByaWNlcmNhXHJcbiAgICAgICAgdGhpcy5lbWl0U2VhcmNoUmVxdWVzdChmYWxzZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gY2hlIHNpIG9jY3VwYSBkaSBnZXN0aXJlIGxhIGdyYWZpY2EgZGVsbGEgdGFiZWxsYSBpbiBiYXNlIGFsbGUgaW5mb3JtYXppb25pIGRpIG9yZGluYW1lbnRvIGNvbG9ubmUgZSBwYWdpbmF6aW9uZSBjb250ZW51dGkgbmVsIG1vZGVsbG9cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSByZXZpZXdSZXBvcnRCaW5kaW5ncygpIHtcclxuICAgICAgICBpZiAoISh0aGlzLlZpZXcgaW5zdGFuY2VvZiBSZXBvcnREZWZpbml0aW9uKSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdWaWV3IGRpdmVyc2EgZGEgcmVwb3J0ZGVmaW5pdGlvbiBlbnRyYXRhIG5lbCBtZXRvZG8gcmV2aWV3UmVwb3J0QmluZGluZ3MnKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQWxsaW5lbyBsZSBpbmZvcm1hemlvbmkgc3UgZXZlbnR1YWxpIG9yZGluYW1lbnRpIGZhdHRpIHByZWNlZGVudGVtZW50ZVxyXG4gICAgICAgIGlmICh0aGlzLlZpZXcub3JkZXJzICYmIHRoaXMuVmlldy5vcmRlcnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICB0aGlzLlZpZXcub3JkZXJzLmZvckVhY2godCA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLlJlcG9ydFZhbHVlcy5jb2x1bW5zLmZpbHRlcihjID0+IGMuaWQgPT0gdC5jb2x1bW4pWzBdLm9yZGVyID0gdC5vcmRlcjtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBSZWN1cGVybyBpbCBjb3VudCBwcmVjZWRlbnRlIHNlIHNlcnZlXHJcbiAgICAgICAgaWYgKHRoaXMuUmVwb3J0VmFsdWVzLmNvdW50ICE9IC0yKVxyXG4gICAgICAgICAgICB0aGlzLnByZXZpb3VzQ291bnQgPSB0aGlzLlJlcG9ydFZhbHVlcy5jb3VudDtcclxuICAgICAgICBlbHNlIGlmICh0aGlzLlJlcG9ydFZhbHVlcy5jb3VudCA9PSAtMilcclxuICAgICAgICAgICAgdGhpcy5SZXBvcnRWYWx1ZXMuY291bnQgPSB0aGlzLnByZXZpb3VzQ291bnQ7XHJcblxyXG4gICAgICAgIGxldCBpcHAgPSAodGhpcy5WaWV3Lml0ZW1zcGVycGFnZW92ZXJyaWRlIHx8IDE1KTtcclxuICAgICAgICB0aGlzLlZpZXcucGFnZXMgPSBNYXRoLmNlaWwodGhpcy5SZXBvcnRWYWx1ZXMuY291bnQgLyBpcHApO1xyXG4gICAgICAgIHRoaXMuYXJyYXlQdWxzYW50aSA9IHRoaXMuZ2V0UGFnZXNBcnJheSg2LCB0aGlzLlZpZXcucGFnZSwgdGhpcy5WaWV3LnBhZ2VzKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyAjZW5kcmVnaW9uXHJcblxyXG4gICAgLy8gI3JlZ2lvbiBHZXN0aW9uZSB1cGRhdGUgYXV0b21hdGljb1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGNoZSBnZXN0aXNjZSBsYSBtb2RpZmljYSBkZWwgdGVtcG8gc3BlY2lmaWNhdG8gcGVyIGwnYWdnaW9ybmFtZW50byBhdXRvbWF0aWNvXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhdXRvVXBkYXRlQ2hhbmdlZCgpIHtcclxuICAgICAgICBpZiAoIS9eWzEtOV1cXGQqJC8udGVzdCh0aGlzLnNlY29uZHMpKVxyXG4gICAgICAgICAgICB0aGlzLnNlY29uZHMgPSAnMTAnO1xyXG5cclxuICAgICAgICBsZXQgc2Vjb25kc0luTXMgPSBwYXJzZUludCh0aGlzLnNlY29uZHMsIG51bGwpICogMTAwMDtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuYXV0b1VwZGF0ZSlcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVUaW1lciA9IHNldEludGVydmFsKCgpID0+IHsgdGhpcy5lbWl0U2VhcmNoUmVxdWVzdChmYWxzZSk7IH0sIHNlY29uZHNJbk1zKTtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy51cGRhdGVUaW1lcik7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gI2VuZHJlZ2lvblxyXG5cclxuICAgIC8vICNyZWdpb24gR2VzdGlvbmUgdGFiZWxsYSBkaW5hbWljYVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGNoaWFtYXRvIGRhbCBjbGljayBzdSB1bmEgZGVsbGUgY29sb25uZSBnZW5lcmF0ZSBkYWxsJ0lucHV0ICoqRHluYW1pY09wZXJhdGlvbnMqKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7YW55fSBpdGVtIEwnb2dnZXR0byBzdSBjdWkgdmEgZWZmZXR0dWF0YSBsJ29wZXJhemlvbmVcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcGlkIENvZGljZSBpZGVudGlmaWNhdGl2byBkZWxsJ29wZXJhemlvbmUgZGEgZWZmZXR0dWFyc2lcclxuICAgICAqL1xyXG4gICAgcHVibGljIGR5bmFtaWNPcGVyYXRpb24oaXRlbTogYW55LCBvcGlkOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLm9uRHluYW1pY09wZXJhdGlvbi5lbWl0KHsgaWQ6IG9waWQsIGl0ZW06IGl0ZW0gfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPdHRpZW5lIGlsIGNvbnRlbnV0byBkZWxsJ0VzVGQgZGEgdXRpbGl6emFyZSBwZXIgbGEgY29sb25uYSBzcGVjaWZpY2F0YVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY29sdW1uIENvbG9ubmEgcGVyIGN1aSBjZXJjYXJlIGxhIGNlbGxhXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm5zIHtUZW1wbGF0ZVJlZjxhbnk+fSBUZW1wbGF0ZSBkYSB1c2FyZSBwZXIgbGEgY29sb25uYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZmluZEVzVGQoY29sdW1uOiBzdHJpbmcpOiBUZW1wbGF0ZVJlZjxhbnk+IHtcclxuICAgICAgICB2YXIgRXNUZCA9IHRoaXMuRXNUZHNEaXJlY3RpdmUuZmluZCgoaXRlbSkgPT4gaXRlbS50ZCA9PT0gY29sdW1uKTtcclxuICAgICAgICByZXR1cm4gRXNUZCA/IEVzVGQuVGVtcGxhdGUgOiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGRpIHN1cHBvcnRvIGFsbGEgY3JlYXppb25lIGRpIHVuIHJvdXRlciBsaW5rIHBhcmFtZXRyaXp6YXRvIGFsbCdvZ2dldHRvIGNvcnJlbnRlIHV0aWxpenphdG8gbmVsbGEgbW9kYWxpdMOgIGRpbmFtaWNhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggUGF0aCBzdSBjdWkgbmF2aWdhcmUgY29uIGV2ZW50dWFsaSBwYXJhbWV0cmkgcmlmZXJpdGkgYWxsJ29nZ2V0dG8gY290bmVzdHVhbGUgY29tZSB7MH0sIHsxfSwgZWNjLi4uXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBwYXJhbWV0ZXJQcm9wcyBMaXN0YSBwb3NpemlvbmFsZSBkZWxsZSBwcm9wcmlldMOgIGEgY3VpIGJpbmRhcmUgaSByaWZlcmltZW50aSBkZWwgcGFyYW1ldHJvICoqcGF0aCoqXHJcbiAgICAgKiBFcy4gSWwgdmFsb3JlIGRlbGEgcHJvcHJpZXTDoCBhbGwnaW5kaWNlIDAgZGkgcXVlc3RvIGFycmF5IHZlcnLDoCBzb3N0aXR1aXRhIGFsIHZhbG9yZSB7MH0gZGVsIHBhcmFtZXRybyAqKnBhdGgqKlxyXG4gICAgICogQHBhcmFtIHtHZW5lcmljSXRlbX0gaXRlbSBPZ2dldHRvIGdlbmVyaWNvIGNvbGxlZ2F0byBhIHF1ZXN0byBjb250ZXN0b1xyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHthbnl9IFJvdXRlciBsaW5rIGdlbmVyYXRvIGluIGJhc2UgYWwgcGFyYW1ldHJpXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZW5lcmF0ZVJvdXRlckxpbmsocGF0aDogc3RyaW5nLCBwYXJhbWV0ZXJQcm9wczogc3RyaW5nW10sIGl0ZW06IEdlbmVyaWNJdGVtKTogYW55IHtcclxuICAgICAgICBpZiAodGhpcy5EeW5hbWljVGFibGVSb3V0ZXJMaW5rQ2FjaGVbaXRlbS5faGFzaCArIHBhdGhdKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLkR5bmFtaWNUYWJsZVJvdXRlckxpbmtDYWNoZVtpdGVtLl9oYXNoICsgcGF0aF07XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbGV0IGxpbmsgPSB0aGlzLmdldFJvdXRlckxpbmsocGF0aCwgcGFyYW1ldGVyUHJvcHMsIGl0ZW0pO1xyXG4gICAgICAgICAgICB0aGlzLkR5bmFtaWNUYWJsZVJvdXRlckxpbmtDYWNoZVtpdGVtLl9oYXNoICsgcGF0aF0gPSBsaW5rO1xyXG4gICAgICAgICAgICByZXR1cm4gbGluaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhIHVuIHJvdXRlciBsaW5rXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggUGF0aCBzdSBjdWkgbmF2aWdhcmUgY29uIGV2ZW50dWFsaSBwYXJhbWV0cmkgcmlmZXJpdGkgYWxsJ29nZ2V0dG8gY290bmVzdHVhbGUgY29tZSB7MH0sIHsxfSwgZWNjLi4uXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBwYXJzIExpc3RhIHBvc2l6aW9uYWxlIGRlbGxlIHByb3ByaWV0w6AgYSBjdWkgYmluZGFyZSBpIHJpZmVyaW1lbnRpIGRlbCBwYXJhbWV0cm8gKipwYXRoKipcclxuICAgICAqIEVzLiBJbCB2YWxvcmUgZGVsYSBwcm9wcmlldMOgIGFsbCdpbmRpY2UgMCBkaSBxdWVzdG8gYXJyYXkgdmVycsOgIHNvc3RpdHVpdGEgYWwgdmFsb3JlIHswfSBkZWwgcGFyYW1ldHJvICoqcGF0aCoqXHJcbiAgICAgKiBAcGFyYW0ge0dlbmVyaWNJdGVtfSBpdGVtIE9nZ2V0dG8gZ2VuZXJpY28gY29sbGVnYXRvIGEgcXVlc3RvIGNvbnRlc3RvXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2FueX0gUm91dGVyIGxpbmsgZ2VuZXJhdG8gaW4gYmFzZSBhbCBwYXJhbWV0cmlcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBnZXRSb3V0ZXJMaW5rKHBhdGg6IHN0cmluZywgcGFyczogc3RyaW5nW10sIGl0ZW06IEdlbmVyaWNJdGVtKTogYW55IHtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICBwYXRoID0gcGF0aC5yZXBsYWNlKCd7JyArIGkgKyAnfScsIGl0ZW0ucHJvcGVydGllc1twYXJzW2ldXSk7XHJcblxyXG4gICAgICAgIHBhdGggPSBwYXRoLnJlcGxhY2UoLycvZywgJ1wiJykucmVwbGFjZSgvIC9nLCAnJyk7XHJcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UocGF0aCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gI2VuZHJlZ2lvblxyXG5cclxuICAgIC8vICNyZWdpb24gUGFnaW5hemlvbmUgaW4gbW9kYWxpdMOgIEFycmF5XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFcXVpdmFsZW50ZSBkZWwgbWV0b2RvICoqYWRkVG9QYWdlKiogcmlhZGF0dGF0byBwZXIgbGEgbW9kYWxpdMOgIGFycmF5XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2UgTnVtZXJvIGRpIHBhZ2luZSBkYSBhZ2dpdW5nZXJlIChvIHNvdHRyYXJyZSwgc2UgbmVnYXRpdm8pIGFsbGEgcGFnaW5hIGF0dHVhbGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGFycmF5QWRkVG9QYWdlKHBhZ2U6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMuYXJyYXlHb1RvUGFnZSh0aGlzLmFycmF5bW9kZVBhZ2UgKyBwYWdlKVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXF1aXZhbGVudGUgZGVsIG1ldG9kbyAqKmdvVG9QYWdlKiogcmlhZGF0dGF0byBwZXIgbGEgbW9kYWxpdMOgIGFycmF5XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2UgUGFnaW5hIGEgY3VpIG5hdmlnYXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhcnJheUdvVG9QYWdlKHBhZ2U6IG51bWJlcikge1xyXG4gICAgICAgIGlmIChwYWdlID09PSAwIHx8IHBhZ2UgPiB0aGlzLmFycmF5bW9kZVBhZ2VzKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgdGhpcy5hcnJheW1vZGVQYWdlID0gcGFnZTtcclxuXHJcbiAgICAgICAgLy8gUmlmb3J6byBpbCB3cml0ZXZhbHVlIGluIG1vZG8gY2hlIGlsIGNvZGljZSBwYXNzaSBkYWxsYSBnZXN0aW9uZSBjb21lIHNlIGZvc3NlIGZhdHRhIHJpcGFydGlyZSB1bmEgcmljZXJjYVxyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxXcml0ZVZhbHVlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gcGVyIGVmZmV0dHVhcmUgaWwgcmVmcmVzaCBkZWxsYSBwYWdpbmF6aW9uZSBzdWwgY2FtYmlhbWVudG8gZGVnbGkgb2dnZXR0aSBkYSB2aXN1YWxpenphcmUgaW4gdW5hIHNpbmdvbGEgcGFnaW5hLlxyXG4gICAgICpcclxuICAgICAqIFZhbGUgc29sbyBwZXIgbGEgbW9kYWxpdMOgIEFycmF5XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhZ2VTaXplIERpbWVuc2lvbmUgZGVsbGEgcGFnaW5hXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWZyZXNoUGFnaW5nKHBhZ2VTaXplOiBudW1iZXIpIHtcclxuICAgICAgICB0aGlzLkFycmF5bW9kZUl0ZW1zUGVyUGFnZSA9IHBhZ2VTaXplO1xyXG4gICAgICAgIHRoaXMuYXJyYXltb2RlUGFnZXMgPSBNYXRoLmNlaWwoKHRoaXMuVmlldyBhcyBhbnlbXSkubGVuZ3RoIC8gdGhpcy5BcnJheW1vZGVJdGVtc1BlclBhZ2UpO1xyXG4gICAgICAgIHRoaXMuYXJyYXltb2RlUGFnZSA9IDE7XHJcblxyXG4gICAgICAgIC8vIFJpZm9yem8gaWwgd3JpdGV2YWx1ZSBpbiBtb2RvIGNoZSBpbCBjb2RpY2UgcGFzc2kgZGFsbGEgZ2VzdGlvbmUgY29tZSBzZSBmb3NzZSBmYXR0YSByaXBhcnRpcmUgdW5hIHJpY2VyY2FcclxuICAgICAgICB0aGlzLmludGVybmFsV3JpdGVWYWx1ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2VuZXJhIGxlIGluZm9ybWF6aW9uaSBkaSBwYWdpbmF6aW9uZSBlIHRhZ2xpYSBsYSBWaWV3IGluIG1vZGFsaXTDoCBhcnJheSBwZXIgbW9zdHJhcmUgc29sbyBnbGkgb2dnZXR0aSBkZWxsYSBwYWdpbmEgc3BlY2lmaWNhdGFcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBhZGFwdFZpZXdUb1BhZ2luZygpIHtcclxuICAgICAgICBsZXQgdG1wSXRlbXM6IGFueVtdID0gW107XHJcblxyXG4gICAgICAgIC8vIFNlIGhvIHVuYSBzZWFyY2ggdmlldyBsJ2FycmF5IHB1bHNhbnRpIHZpZW5lIGNhbGNvbGF0byBkYSBsZWksIG5vbiBkZXZvIHByZW5kZXJlIHF1ZWxsbyBkZWxsYSBtb2RhbGl0w6AgYXJyYXlcclxuICAgICAgICBpZighdGhpcy5TZWFyY2hWaWV3KVxyXG4gICAgICAgICAgICB0aGlzLmFycmF5UHVsc2FudGkgPSB0aGlzLmdldFBhZ2VzQXJyYXkoNiwgdGhpcy5hcnJheW1vZGVQYWdlLCB0aGlzLmFycmF5bW9kZVBhZ2VzKTtcclxuXHJcbiAgICAgICAgLy8gUG9pIHBlciB0dXR0aSBpIHZhbG9yaSBkb3BvIGNvbXByZXNpIGZyYSBsYSBwYWdpbmEgLSAxIGUgbGEgcGFnaW5hXHJcbiAgICAgICAgZm9yIChsZXQgaSA9ICgodGhpcy5hcnJheW1vZGVQYWdlIC0gMSkgKiB0aGlzLkFycmF5bW9kZUl0ZW1zUGVyUGFnZSk7IGkgPCB0aGlzLmFycmF5bW9kZVBhZ2UgKiB0aGlzLkFycmF5bW9kZUl0ZW1zUGVyUGFnZTsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChpIDw9ICh0aGlzLlZpZXcgYXMgYW55W10pLmxlbmd0aCAtIDEpXHJcbiAgICAgICAgICAgICAgICB0bXBJdGVtcy5wdXNoKCh0aGlzLlZpZXcgYXMgYW55W10pW2ldKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRtcEl0ZW1zO1xyXG4gICAgfVxyXG5cclxuICAgIC8vICNlbmRyZWdpb25cclxuXHJcbiAgICAvLyAjcmVnaW9uIEdlc3Rpb25lIGNsaWNrIHN1bGxlIGNlbGxlIGRpbmFtaWNoZSBlIG9wemlvbmkgbmVsIENvcm5lciBNZW51XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXN0b3JlIGRlaSBjbGljayBzdWxsZSBjZWxsZSBwZXIgbGUgcXVhbGkgZXJhIGltcG9zdGF0YSB1bmEgYXppb25lIGN1c3RvbSBkYSAqKkN1c3RvbUNlbGxBY3Rpb25zT24qKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIE5vbWUgZGVsbGEgY2VsbGEgc3UgY3VpIHNpIMOoIGZhdHRvIGNsaWNrXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gbW9kZWwgTW9kZWxsbyByZWxhdGl2byBhbGxhIGNlbGxhIGNsaWNjYXRhXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59ICoqdHJ1ZSoqIHNlIGlsIGNsaWNrIMOoIHN0YXRvIGZhdHRvIHN1IHVuYSBjZWxsYSBjbGljY2FiaWxlLCAqKmZhbHNlKiogYWx0cmltZW50aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY2VsbENsaWNrZWQobmFtZTogc3RyaW5nLCBtb2RlbDogYW55KTogYm9vbGVhbiB7XHJcbiAgICAgICAgaWYgKHRoaXMuVXNlQ3VzdG9tQ2VsbEFjdGlvbnMgJiYgdGhpcy5DdXN0b21DZWxsQWN0aW9uc09uLnNwbGl0KCckJykuaW5kZXhPZihuYW1lKSAhPSAtMSkge1xyXG4gICAgICAgICAgICB0aGlzLm9uQ2VsbENsaWNrLmVtaXQoeyBjb2x1bW46IG5hbWUsIG1vZGVsOiBtb2RlbCB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXN0aW9uZSBkZWkgY2xpY2sgc3VsbGUgb3B6aW9uaSBkZWwgbWVuw7kgY29udGVzdHVhbGUgaW4gYWx0byBhIGRlc3RyYSBnZW5lcmF0byBkYWxsJ0lucHV0ICoqQ29ybmVyTWVudU9wdGlvbnMqKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjb3JuZXJpZCBDb2RpY2UgZGVsbCdvcGVyYXppb25lIHNlbGV6aW9uYXRhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb3JuZXJBY3Rpb25DbGlja2VkKGNvcm5lcmlkOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLm9uQ29ybmVyQWN0aW9uLmVtaXQoeyBpZDogY29ybmVyaWQsIGVzdGFibGU6IHRoaXMgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gI2VuZHJlZ2lvblxyXG5cclxuICAgIC8vICNyZWdpb24gTWV0b2RpIGRpIHV0aWxpdMOgXHJcblxyXG4gICAgLyoqIEhlbHBlciBjaGUgaWRlbnRpZmljYSBzZSBpbCB0ZCBhdHR1YWxlIMOoIGRpIHRpcG8gKipFc1RkKiouIEluIGNhc28gY29udHJhcmlvIMOoIGRhIGNvbnNpZGVyYXJzaSAqKkVzVGREaXJlY3RpdmUqKiAqL1xyXG4gICAgcHJpdmF0ZSBpc0VzVGQodGQ6IGFueSk6IHRkIGlzIEVzVGQge1xyXG4gICAgICAgIHJldHVybiAhdGQuX2RpcmVjdGl2ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogIEhlbHBlciBjaGUgaWRlbnRpZmljYSBzZSBpbCB0aCBhdHR1YWxlIMOoIGRpIHRpcG8gKipFc1RoKiouIEluIGNhc28gY29udHJhcmlvIMOoIGRhIGNvbnNpZGVyYXJzaSAqKkVzVGhEaXJlY3RpdmUqKiAqL1xyXG4gICAgcHJpdmF0ZSBpc0VzVGgodGg6IGFueSk6IHRoIGlzIEVzVGgge1xyXG4gICAgICAgIHJldHVybiAhdGguX2RpcmVjdGl2ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogSW1wb3N0YXppb25lIG1vZGFsaXTDoCBkZWxsJ0VzVGFibGUgKi9cclxuICAgIHByaXZhdGUgc2V0TW9kZShtb2RlOiAnYXJyYXknIHwgJ3ZpZXcnIHwgJ3JlcG9ydCcpIHtcclxuICAgICAgICB0aGlzLnZpZXdNb2RlID0gbW9kZSA9PSAndmlldyc7XHJcbiAgICAgICAgdGhpcy5hcnJheU1vZGUgPSBtb2RlID09ICdhcnJheSc7XHJcbiAgICAgICAgdGhpcy5yZXBvcnRNb2RlID0gbW9kZSA9PSAncmVwb3J0JztcclxuXHJcbiAgICAgICAgaWYgKHRoaXMucmVwb3J0TW9kZSkge1xyXG4gICAgICAgICAgICAvLyBJbiBtb2RhbGl0w6AgcmVwb3J0IGhvIGRpIHNpY3VybyBxdWVzdGUgZHVlXHJcbiAgICAgICAgICAgIHRoaXMuWExTWEV4cG9ydCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuQ1NWRXhwb3J0ID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGVscGVyIHBlciBlZmZldHR1YXJlIGNoaWFtYXRlIGludGVybmUgZGkgYWxsaW5lYW1lbnRvIGFsbGEgZnVuemlvbmUgKip3cml0ZVZhbHVlKiosIFxyXG4gICAgICogaW1wb3N0YW5kbyBwcmltYSAqKmludGVybmFsV3JpdGVDYWxsKiogaW4gbW9kbyBkYSBub24gZWZmZXR0dWFyZSBvcGVyYXppb25pIGludXRpbGlcclxuICAgICAqL1xyXG4gICAgIHByaXZhdGUgaW50ZXJuYWxXcml0ZVZhbHVlKCkge1xyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxXcml0ZUNhbGwgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMud3JpdGVWYWx1ZSh0aGlzLlZpZXcpO1xyXG4gICAgICAgIHRoaXMuaW50ZXJuYWxXcml0ZUNhbGwgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERhdGUgbGUgaW5mb3JtYXppb25pIGRpIHBhZ2luYXppb25lIG90dGllbmUgbCdhcnJheSBkZWkgcHVsc2FudGlcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWF4QnRucyBOdW1lcm8gbWFzc2ltbyBkaSBwdWxzYW50aSBkYSB2aXN1YWxpenphcmVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBwYWdlIFBhZ2luYSBjb3JyZW50ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxhc3RQYWdlIFVsdGltYSBwYWdpbmEgZGlzcG9uaWJpbGVcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7YW55W119IFBzZXVkby1hcnJheSBkaSBwdWxzYW50aSBhIGN1aSBjaSBzaSBwdcOyIGJpbmRhcmUgbGF0byBIVE1MXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0UGFnZXNBcnJheShtYXhCdG5zOiBudW1iZXIsIHBhZ2U6IG51bWJlciwgbGFzdFBhZ2U6IG51bWJlcik6IGFueVtdIHtcclxuICAgICAgICBsZXQgcmVzdWx0ID0gW107XHJcbiAgICAgICAgaWYgKGxhc3RQYWdlID09IC0xKVxyXG4gICAgICAgICAgICBsYXN0UGFnZSA9IHBhZ2UgKyAxO1xyXG5cclxuICAgICAgICBsZXQgbWluLCBtYXg7XHJcbiAgICAgICAgaWYgKGxhc3RQYWdlIDw9IG1heEJ0bnMpIHtcclxuICAgICAgICAgICAgbWluID0gMTtcclxuICAgICAgICAgICAgbWF4ID0gbGFzdFBhZ2UgLSAxO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIHRvbGdvIGxhIHBhZ2luYSBzZWxlY3RlZCDDqCBsJ3VsdGltYSBwYWdpbmEgY2hlIMOoIHF1ZWxsYSBkZWxsZSBwYWdpbmUgdG90YWxpXHJcbiAgICAgICAgICAgIGxldCByYW5nZU91dHNpZGUgPSAobWF4QnRucyAtIDIpIC8gMjtcclxuXHJcbiAgICAgICAgICAgIG1pbiA9IHBhZ2UgLSByYW5nZU91dHNpZGU7XHJcbiAgICAgICAgICAgIG1heCA9IHBhZ2UgKyByYW5nZU91dHNpZGU7XHJcblxyXG4gICAgICAgICAgICBpZiAobWluIDwgMSkge1xyXG4gICAgICAgICAgICAgICAgbWluID0gMTtcclxuICAgICAgICAgICAgICAgIG1heCA9IG1heEJ0bnMgLSAxO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1heCA+PSBsYXN0UGFnZSkge1xyXG4gICAgICAgICAgICAgICAgbWluID0gbGFzdFBhZ2UgLSBtYXhCdG5zICsgMTtcclxuICAgICAgICAgICAgICAgIG1heCA9IGxhc3RQYWdlIC0gMTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmVzdWx0LnB1c2goeyB2YWw6IDEsIGNzc0NsYXNzOiAoMSA9PT0gcGFnZSA/ICdidG4tbWFpbiBhcHAtd2hpdGUtdGV4dCcgOiAnYXBwLXdoaXRlLWJ1dHRvbicpIH0pO1xyXG5cclxuICAgICAgICBpZiAobWF4ID49IG1pbikge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gbWluOyBpIDw9IG1heDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgaWYgKGkgIT09IDEpXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goeyB2YWw6IGksIGNzc0NsYXNzOiAoaSA9PT0gcGFnZSA/ICdidG4tbWFpbiBhcHAtd2hpdGUtdGV4dCcgOiAnYXBwLXdoaXRlLWJ1dHRvbicpIH0pO1xyXG5cclxuICAgICAgICAgICAgcmVzdWx0LnB1c2goe1xyXG4gICAgICAgICAgICAgICAgdmFsOiBsYXN0UGFnZSxcclxuICAgICAgICAgICAgICAgIGNzc0NsYXNzOiAobGFzdFBhZ2UgPT09IHBhZ2UgPyAnYnRuLW1haW4gYXBwLXdoaXRlLXRleHQnIDogJ2FwcC13aGl0ZS1idXR0b24nKVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGNvbGEgbCdoYXNoIGRpIHVuIG9nZ2V0dG8gcXVhbHNpYXNpXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHthbnlbXX0gaXRlbXMgT2dnZXR0aSBwZXIgY3VpIGNhbGNvbGFyZSBsJ2hhc2hcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBjYWxjdWxhdGVIYXNoKGl0ZW1zOiBhbnlbXSkge1xyXG4gICAgICAgIGlmICghaXRlbXMpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gU3VwcG9ydG8gYSBoYXNoIGR1cGxpY2F0aSBkaSBvZ2dldHRpIHVndWFsaVxyXG4gICAgICAgIGxldCB1c2VkSGFzaGVzQ2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBudW1iZXIgfSA9IHt9O1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IGl0ZW0gPSBpdGVtc1tpXTtcclxuXHJcbiAgICAgICAgICAgIC8vIFByaW1hIGRpIGNhbGNvbGFyZSBsJ2hhc2ggcmltdW92byBsZSBwcm9wcmlldMOgIGludGVybmUgcHJpbWEgY2hlIG1pIHNjb21wZW5zaW5vIGkgY2FsY29saSBzdWNjZXNzaXZpXHJcbiAgICAgICAgICAgIGxldCB0bXAgPSBPYmplY3QuYXNzaWduKHt9LCBpdGVtc1tpXSk7XHJcbiAgICAgICAgICAgIGRlbGV0ZSB0bXAuX3NlbGVjdGVkO1xyXG4gICAgICAgICAgICBkZWxldGUgdG1wLl92aXNpYmxlO1xyXG4gICAgICAgICAgICBkZWxldGUgdG1wLl9oYXNoO1xyXG4gICAgICAgICAgICBsZXQgaGFzaCA9IHRoaXMuaGFzaEV4dHMuaGFzaE9iamVjdCh0bXApO1xyXG5cclxuICAgICAgICAgICAgdXNlZEhhc2hlc0NhY2hlW2hhc2hdID0gdXNlZEhhc2hlc0NhY2hlW2hhc2hdID8gdXNlZEhhc2hlc0NhY2hlW2hhc2hdICsgMSA6IDE7XHJcbiAgICAgICAgICAgIGl0ZW0uX2hhc2ggPSBoYXNoICsgKHVzZWRIYXNoZXNDYWNoZVtoYXNoXSA+IDEgPyBcIl9cIiArIHVzZWRIYXNoZXNDYWNoZVtoYXNoXSA6IFwiXCIpXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGV2ZW50dWFsbWVudGUgcmljaGlhbWFiaWxlIGFuY2hlIGRhbCBjb21wb25lbnRlIGVzdGVybm8gY2hlIHBlcm1ldHRlIGRpIGZvcnphcmUgdW4gcmVmcmVzaCBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBmb3JjZVJlZnJlc2goKSB7XHJcblxyXG4gICAgICAgIC8vIFNlIHNvbm8gaW4gbW9kYWxpdMOgIFZpZXcgdmllbmUgbWFudGVudXRvIGluIGF1dG9tYXRpY28gaWwgbnVtZXJvIGRpIHBhZ2luYSwgbWEgcGVyIGxhIG1vZGFsaXTDoCBhcnJheSBkZXZvIHByZW5kZXJlIGxlIGluZm8gZGkgcGFnaW5hemlvbmUgcHJpbWEgZSByaWFwcGxpY2FybGUgZG9wb1xyXG4gICAgICAgIGxldCBhcnJheVBhZ2U6IG51bWJlcjtcclxuICAgICAgICBsZXQgYXJyYXlJcHA6IG51bWJlcjtcclxuICAgICAgICBpZiAodGhpcy5hcnJheU1vZGUpIHtcclxuICAgICAgICAgICAgYXJyYXlQYWdlID0gdGhpcy5hcnJheW1vZGVQYWdlO1xyXG4gICAgICAgICAgICBhcnJheUlwcCA9IHRoaXMuQXJyYXltb2RlSXRlbXNQZXJQYWdlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy53cml0ZVZhbHVlKHRoaXMuVmlldyk7XHJcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5hcnJheU1vZGUpIHtcclxuICAgICAgICAgICAgdGhpcy5BcnJheW1vZGVJdGVtc1BlclBhZ2UgPSBhcnJheUlwcDtcclxuICAgICAgICAgICAgdGhpcy5hcnJheUdvVG9QYWdlKGFycmF5UGFnZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vICNlbmRyZWdpb25cclxufSJdfQ==
|