@esfaenza/es-table 16.2.29 → 17.3.16

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.
Files changed (123) hide show
  1. package/esm2022/esfaenza-es-table.mjs +4 -4
  2. package/esm2022/lib/components/es-table/es_table.component.loc.mjs +38 -38
  3. package/esm2022/lib/components/es-table/es_table.component.mjs +1891 -1891
  4. package/esm2022/lib/components/es-td/es_td.component.mjs +40 -40
  5. package/esm2022/lib/components/es-th/es_th.component.mjs +176 -176
  6. package/esm2022/lib/components/pager/table_pager.component.loc.mjs +20 -20
  7. package/esm2022/lib/components/pager/table_pager.component.mjs +111 -111
  8. package/esm2022/lib/components/pipes/est-format.pipe.mjs +44 -44
  9. package/esm2022/lib/components/pipes/est-lookup.pipe.mjs +19 -19
  10. package/esm2022/lib/components/pipes/est-propinsensitive.pipe.mjs +19 -19
  11. package/esm2022/lib/components/pipes/est-renderer.pipe.mjs +36 -36
  12. package/esm2022/lib/components/pipes/est-routerlink.pipe.mjs +41 -41
  13. package/esm2022/lib/components/pipes/est_editor.pipe.mjs +36 -36
  14. package/esm2022/lib/core/CopyPasteDetector.mjs +27 -27
  15. package/esm2022/lib/core/Logger.mjs +25 -25
  16. package/esm2022/lib/core/handlers/ColumnMetadataHandler.mjs +835 -835
  17. package/esm2022/lib/core/handlers/DynamicModeHandler.mjs +109 -109
  18. package/esm2022/lib/core/handlers/ExportHandler.mjs +32 -32
  19. package/esm2022/lib/core/handlers/HierarchyModeHandler.mjs +136 -136
  20. package/esm2022/lib/core/handlers/ItemsHandler.mjs +119 -119
  21. package/esm2022/lib/core/handlers/ReportModeHandler.mjs +60 -60
  22. package/esm2022/lib/core/handlers/RowGroupingHandler.mjs +480 -480
  23. package/esm2022/lib/core/handlers/SelectionHandler.mjs +778 -778
  24. package/esm2022/lib/core/handlers/UtilitiesHandler.mjs +151 -151
  25. package/esm2022/lib/directives/es_td.directive.mjs +54 -54
  26. package/esm2022/lib/directives/es_td_editor.directive.mjs +24 -24
  27. package/esm2022/lib/directives/es_th.directive.mjs +130 -130
  28. package/esm2022/lib/directives/es_th_td_provider.directive.mjs +34 -34
  29. package/esm2022/lib/domain/configuration/EsTableDefaultable.mjs +3 -3
  30. package/esm2022/lib/domain/configuration/EsTableModuleConfig.mjs +3 -3
  31. package/esm2022/lib/domain/externals/CornerMenuOption.mjs +3 -3
  32. package/esm2022/lib/domain/externals/EsTableColumnsDefinition.mjs +47 -47
  33. package/esm2022/lib/domain/externals/EsTableModelChange.mjs +18 -18
  34. package/esm2022/lib/domain/externals/EsTableOperationDefinition.mjs +21 -21
  35. package/esm2022/lib/domain/externals/ItemPropEditableReference.mjs +3 -3
  36. package/esm2022/lib/domain/externals/appsearch/AppOrdering.mjs +15 -15
  37. package/esm2022/lib/domain/externals/appsearch/AppSearch.mjs +65 -65
  38. package/esm2022/lib/domain/externals/appsearch/EsTableMultiValue.mjs +24 -24
  39. package/esm2022/lib/domain/externals/appsearch/GenericItem.mjs +10 -10
  40. package/esm2022/lib/domain/externals/appsearch/Group.mjs +16 -16
  41. package/esm2022/lib/domain/externals/appsearch/GroupAggregation.mjs +15 -15
  42. package/esm2022/lib/domain/externals/appsearch/GroupFilter.mjs +13 -13
  43. package/esm2022/lib/domain/externals/appsearch/GroupOrAggregation.mjs +15 -15
  44. package/esm2022/lib/domain/externals/appsearch/ItemsSelection.mjs +22 -22
  45. package/esm2022/lib/domain/externals/report/ReportColumn.mjs +3 -3
  46. package/esm2022/lib/domain/externals/report/ReportParam.mjs +3 -3
  47. package/esm2022/lib/domain/externals/report/ReportRow.mjs +3 -3
  48. package/esm2022/lib/domain/internals/CacheTriptic.mjs +15 -15
  49. package/esm2022/lib/domain/internals/EsTableColumn.mjs +31 -31
  50. package/esm2022/lib/domain/internals/GroupPager.mjs +22 -22
  51. package/esm2022/lib/domain/internals/GroupRouteFragment.mjs +16 -16
  52. package/esm2022/lib/domain/internals/PagerInfos.mjs +14 -14
  53. package/esm2022/lib/domain/internals/TdElement.mjs +1 -1
  54. package/esm2022/lib/domain/internals/ThAggregation.mjs +15 -15
  55. package/esm2022/lib/domain/internals/ThElement.mjs +1 -1
  56. package/esm2022/lib/domain/internals/ThGroup.mjs +1 -1
  57. package/esm2022/lib/domain/types.mjs +1 -1
  58. package/esm2022/lib/es-table.module.mjs +125 -125
  59. package/esm2022/lib/tokens.mjs +5 -5
  60. package/esm2022/public-api.mjs +27 -27
  61. package/fesm2022/esfaenza-es-table.mjs +5777 -5777
  62. package/fesm2022/esfaenza-es-table.mjs.map +1 -1
  63. package/index.d.ts +5 -5
  64. package/lib/components/es-table/es_table.component.d.ts +738 -738
  65. package/lib/components/es-table/es_table.component.loc.d.ts +10 -10
  66. package/lib/components/es-td/es_td.component.d.ts +26 -26
  67. package/lib/components/es-th/es_th.component.d.ts +92 -92
  68. package/lib/components/pager/table_pager.component.d.ts +56 -56
  69. package/lib/components/pager/table_pager.component.loc.d.ts +10 -10
  70. package/lib/components/pipes/est-format.pipe.d.ts +10 -10
  71. package/lib/components/pipes/est-lookup.pipe.d.ts +13 -13
  72. package/lib/components/pipes/est-propinsensitive.pipe.d.ts +7 -7
  73. package/lib/components/pipes/est-renderer.pipe.d.ts +15 -15
  74. package/lib/components/pipes/est-routerlink.pipe.d.ts +20 -20
  75. package/lib/components/pipes/est_editor.pipe.d.ts +15 -15
  76. package/lib/core/CopyPasteDetector.d.ts +15 -15
  77. package/lib/core/Logger.d.ts +10 -10
  78. package/lib/core/handlers/ColumnMetadataHandler.d.ts +189 -189
  79. package/lib/core/handlers/DynamicModeHandler.d.ts +22 -22
  80. package/lib/core/handlers/ExportHandler.d.ts +18 -18
  81. package/lib/core/handlers/HierarchyModeHandler.d.ts +40 -40
  82. package/lib/core/handlers/ItemsHandler.d.ts +35 -35
  83. package/lib/core/handlers/ReportModeHandler.d.ts +27 -27
  84. package/lib/core/handlers/RowGroupingHandler.d.ts +118 -118
  85. package/lib/core/handlers/SelectionHandler.d.ts +230 -230
  86. package/lib/core/handlers/UtilitiesHandler.d.ts +57 -57
  87. package/lib/directives/es_td.directive.d.ts +42 -42
  88. package/lib/directives/es_td_editor.directive.d.ts +14 -14
  89. package/lib/directives/es_th.directive.d.ts +107 -107
  90. package/lib/directives/es_th_td_provider.directive.d.ts +15 -15
  91. package/lib/domain/configuration/EsTableDefaultable.d.ts +21 -21
  92. package/lib/domain/configuration/EsTableModuleConfig.d.ts +8 -8
  93. package/lib/domain/externals/CornerMenuOption.d.ts +7 -7
  94. package/lib/domain/externals/EsTableColumnsDefinition.d.ts +56 -56
  95. package/lib/domain/externals/EsTableModelChange.d.ts +17 -17
  96. package/lib/domain/externals/EsTableOperationDefinition.d.ts +20 -20
  97. package/lib/domain/externals/ItemPropEditableReference.d.ts +34 -34
  98. package/lib/domain/externals/appsearch/AppOrdering.d.ts +14 -14
  99. package/lib/domain/externals/appsearch/AppSearch.d.ts +100 -100
  100. package/lib/domain/externals/appsearch/EsTableMultiValue.d.ts +22 -22
  101. package/lib/domain/externals/appsearch/GenericItem.d.ts +13 -13
  102. package/lib/domain/externals/appsearch/Group.d.ts +17 -17
  103. package/lib/domain/externals/appsearch/GroupAggregation.d.ts +14 -14
  104. package/lib/domain/externals/appsearch/GroupFilter.d.ts +12 -12
  105. package/lib/domain/externals/appsearch/GroupOrAggregation.d.ts +14 -14
  106. package/lib/domain/externals/appsearch/ItemsSelection.d.ts +22 -22
  107. package/lib/domain/externals/report/ReportColumn.d.ts +19 -19
  108. package/lib/domain/externals/report/ReportParam.d.ts +40 -40
  109. package/lib/domain/externals/report/ReportRow.d.ts +9 -9
  110. package/lib/domain/internals/CacheTriptic.d.ts +14 -14
  111. package/lib/domain/internals/EsTableColumn.d.ts +41 -41
  112. package/lib/domain/internals/GroupPager.d.ts +26 -26
  113. package/lib/domain/internals/GroupRouteFragment.d.ts +15 -15
  114. package/lib/domain/internals/PagerInfos.d.ts +13 -13
  115. package/lib/domain/internals/TdElement.d.ts +57 -57
  116. package/lib/domain/internals/ThAggregation.d.ts +14 -14
  117. package/lib/domain/internals/ThElement.d.ts +24 -24
  118. package/lib/domain/internals/ThGroup.d.ts +10 -10
  119. package/lib/domain/types.d.ts +2 -2
  120. package/lib/es-table.module.d.ts +35 -35
  121. package/lib/tokens.d.ts +6 -6
  122. package/package.json +14 -14
  123. package/public-api.d.ts +27 -27
@@ -1,835 +1,835 @@
1
- // Angular
2
- import { moveItemInArray } from "@angular/cdk/drag-drop";
3
- import { EsTdDirective } from "../../directives/es_td.directive";
4
- import { EsThDirective } from "../../directives/es_th.directive";
5
- // Modelli
6
- import { AppOrdering } from "../../domain/externals/appsearch/AppOrdering";
7
- import { EsTableColumn } from "../../domain/internals/EsTableColumn";
8
- /** Classe che gestisce tutte le informaizoni relative alle colonne: visibilità, posizione, stato di pin/unpin, ecc ecc... */
9
- export class ColumnMetadataHandler {
10
- /** @ignore Costruttore*/
11
- constructor(est, utilities, utiExts, prefService, rgH) {
12
- this.est = est;
13
- this.utilities = utilities;
14
- this.utiExts = utiExts;
15
- this.prefService = prefService;
16
- this.rgH = rgH;
17
- }
18
- /**
19
- * Metodo che gestisce il cambio di Ordinamento di una colonna
20
- *
21
- * @param {string} id ID della colonna il cui oridnamento è cambiato
22
- * @param {'DESC' | 'ASC'} order Nuovo ordine selezionato per la colonna
23
- */
24
- handleTHOrderChange(id, order) {
25
- let orders = this.est.viewMode ? this.est.View.orders : this.est.arrayOrders;
26
- let orderToAdd = true;
27
- let orderToRemove = null;
28
- // Se per qualche motivo il costruttore non è passato (cache tarpate o simila) fixo
29
- if (!orders && this.est.viewMode)
30
- this.est.View.orders = [];
31
- else if (!orders && this.est.arrayMode)
32
- this.est.arrayOrders = [];
33
- for (let i = 0; i < orders.length; i++) {
34
- let t = orders[i];
35
- if (t.id == id) {
36
- if (order) {
37
- t.order = order;
38
- orderToAdd = false;
39
- }
40
- else
41
- orderToRemove = i;
42
- }
43
- }
44
- if (orderToRemove != null) {
45
- orders.splice(orderToRemove, 1);
46
- }
47
- else if (orderToAdd) {
48
- if (this.est.MultipleOrderingDirectives)
49
- orders.push(new AppOrdering(id, order));
50
- else {
51
- if (this.est.viewMode)
52
- this.est.View.orders = [new AppOrdering(id, order)];
53
- else if (this.est.arrayMode)
54
- this.est.arrayOrders = [new AppOrdering(id, order)];
55
- }
56
- }
57
- //Salvo le preferences di questa view
58
- //Di default registro ordinamento e visibilità delle colonne nella vista. Solo le cose di UI
59
- if (this.est.SavePreferences) {
60
- let castedView = this.est.viewMode ? (this.est.MainGroupView || this.est.View) : null;
61
- this.registerViewPreferences(castedView);
62
- }
63
- this.est.onOrderChanged.emit({ id, order });
64
- if (this.est.viewMode) {
65
- if (this.est.groupSearchRequestsCache.length > 0)
66
- this.rgH.emitRowGroupingSearches(id, orders);
67
- else
68
- this.est.emitSearchRequest(false);
69
- }
70
- else if (this.est.arrayMode)
71
- this.est.internalWriteValue();
72
- }
73
- /**
74
- * Registra le preference relative alla view passata come parametro
75
- *
76
- * @param {any} castedView View di cui salvare colonne e ordinamento colonne
77
- */
78
- registerViewPreferences(castedView) {
79
- if (!this.est.ngControl.name) {
80
- console.error("Non posso utilizzare le preference senza avere un 'name' per la tabella");
81
- return false;
82
- }
83
- if (!this.prefService) {
84
- console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
85
- return false;
86
- }
87
- let columns = this.est.arrayMode ? this.est.arrayColumns : castedView.columns;
88
- let columnsOrderings = this.est.arrayMode ? this.est.arrayColumnOrdering : castedView.column_ordering;
89
- let columnOrders = this.est.arrayMode ? [] : castedView.orders;
90
- var toStore = {
91
- columns: this.utiExts.deepClone(columns),
92
- column_ordering: this.utiExts.deepClone(columnsOrderings),
93
- orders: this.utiExts.deepClone(columnOrders)
94
- };
95
- this.prefService.setItem(this.est.ngControl.name, toStore).subscribe();
96
- }
97
- /**
98
- * Partendo dagli **EsThs** estrappolo la lista di **EsTableColumn** che questa tabella dovrà eventualmente gestire per Visibilità e Ordine
99
- *
100
- * Costo: 1 scan EsThs
101
- *
102
- * @param {EsThDirective[]} ths Colonne della tabella
103
- */
104
- reviewColumnsList(ths) {
105
- this.est.TMPColumnsList = [];
106
- if (ths.length == 0)
107
- return;
108
- // Appena il contentChildren è valorizzato scorro tutti gli header
109
- for (let i = 0; i < ths.length; i++) {
110
- let th = ths[i];
111
- let column = th.th;
112
- // Se non ho un id il th è considerato inerte
113
- if (!column)
114
- continue;
115
- // Salvo le informazioni dell'header per far parte della lista da cui scegliere quali colonne visualizzare/nascondere
116
- // Di default la visibilità è quella impostata nel componente
117
- if ((this.est.HiddenColumns || th.thVisible) && th.thIf) {
118
- let previouslyPinned = !this.est.ColumnsList || this.est.ColumnsList.length == 0 ? null : this.est.ColumnsList.find(t => t.id == column) || null;
119
- let toAdd = new EsTableColumn(column, th.thStaticContent, th.thVisible, (th.thFixed || th.thGroup), previouslyPinned == null ? th.thPinned : previouslyPinned.pinned, th.thPinnable, th.thPinnedWidth, th.Template, th._thParents, th._multi, th._multi_content);
120
- if (previouslyPinned)
121
- toAdd.prev_index = previouslyPinned.prev_index;
122
- this.est.TMPColumnsList.push(toAdd);
123
- }
124
- }
125
- this.est.ColumnsList = [];
126
- this.est.TMPColumnsList.forEach(c => { this.est.ColumnsList.push(Object.assign({}, c)); });
127
- }
128
- /** In caso siano configurati dei th "Multi" (vedere la descrizione del campo **thMulti** di **EsThDirective**) questo metodo li "srotola" in tutti i th/td che devono effettivamente diventare */
129
- expandMultiThsAndTds(ths, tds, items) {
130
- // Registro le info sui multiprovider
131
- let multiDefs = {};
132
- for (let i = 0; i < ths.length; i++) {
133
- let th = ths[i];
134
- if (!th.thMulti)
135
- continue;
136
- multiDefs[th.th] = { On: th.th, tdref: null, thref: th, thgen: {}, tdgen: {} };
137
- }
138
- // Assegno le info anche ai td
139
- for (let i = 0; i < tds.length; i++) {
140
- let td = tds[i];
141
- td._multi = !!multiDefs[td.td];
142
- if (td._multi)
143
- multiDefs[td.td].tdref = td;
144
- }
145
- // Rimuovo i multitemplate dalle balle
146
- // N.B: Dato che la prima operazione su th e td è questa il riferimento originale viene sovrascritto, questo significa che devo ri-emettere i due nuovi array
147
- ths = ths.filter(t => !t.thMulti);
148
- tds = tds.filter(t => !t._multi);
149
- let parentThs = {};
150
- let addedHeaders = {};
151
- let tdsToAdd = {};
152
- let thsToAdd = [];
153
- // Per ogni item vedo se ci sono dei multi per le proprietà che li definiscono
154
- for (let i = 0; i < items.length; i++) {
155
- let itm = items[i];
156
- for (let prop in multiDefs) {
157
- // Se la proprietà del multi esiste nell'oggetto ed ha una lunghezza
158
- if (itm[prop] && itm[prop].length) {
159
- let multiRef = multiDefs[prop];
160
- let reftd = multiRef.tdref;
161
- let refth = multiRef.thref;
162
- for (let ii = 0; ii < itm[prop].length; ii++) {
163
- // Header già aggiunto, non devo inserire altri template di header/colonna
164
- let estmv = itm[prop][ii];
165
- if (!estmv._headersHierarchy)
166
- estmv._headersHierarchy = estmv.header_group ? estmv.header_group.split(">").map(t => t.trim()) : [];
167
- let headerValue = estmv.header;
168
- let parent = estmv.header_group || null;
169
- let parentsHier = estmv._headersHierarchy;
170
- if (addedHeaders[`${parent}_${headerValue}`])
171
- continue;
172
- else
173
- addedHeaders[`${parent}_${headerValue}`] = true;
174
- // Per ogni valore diverso delle proprietà devo aggiungere un td e un th, quest'ultimo dev'essere eventualmente collegato ad un header
175
- let newtH = new EsThDirective(refth.Template);
176
- newtH._multi = true;
177
- newtH._multi_content = headerValue;
178
- newtH.th = `${prop}_${ii}`;
179
- newtH.thClass = refth.thClass;
180
- newtH.thShrink = refth.thShrink;
181
- newtH.thIf = refth.thIf;
182
- newtH.thVisible = refth.thVisible;
183
- newtH.thWrap = refth.thWrap;
184
- // Il parent è sempre l'ultimo nella gerarchia di padri
185
- newtH.thParent = parentsHier[parentsHier.length - 1];
186
- newtH.thOrderable = false;
187
- for (let i = 0; i < parentsHier.length; i++) {
188
- let par = parentsHier[i];
189
- if (!parentThs[par])
190
- parentThs[par] = true;
191
- else
192
- continue;
193
- let thParent = new EsThDirective(null);
194
- thParent.th = par;
195
- thParent._multi_content = par;
196
- thParent.thParent = i > 0 ? parentsHier[i - 1] : null;
197
- thsToAdd.push(thParent);
198
- }
199
- thsToAdd.push(newtH);
200
- let newTd = new EsTdDirective(reftd.Template);
201
- newTd._multi = true;
202
- newTd.td = `${prop}_${ii}`;
203
- newTd.tdClass = reftd.tdClass;
204
- newTd.tdIf = reftd.tdIf;
205
- newTd.tdVisible = reftd.tdVisible;
206
- tdsToAdd[newTd.td] = newTd;
207
- }
208
- }
209
- }
210
- }
211
- // Ordino gli header aggiunti in base al Parent, se presente, e li aggiungo alla lista dei th, dopodiché in base allo stesso ordinamento aggiungo i relativi td
212
- let orderedThs = [];
213
- // Prima metto tutti i th senza parent, poi per ogni parent prendo i th ordinati come li trovo nella lista
214
- for (let i = 0; i < thsToAdd.length; i++) {
215
- if (!thsToAdd[i].thParent)
216
- orderedThs.push(thsToAdd[i]);
217
- }
218
- for (let prop in parentThs) {
219
- for (let i = 0; i < thsToAdd.length; i++) {
220
- let th = thsToAdd[i];
221
- if (th.thParent && th.thParent == prop)
222
- orderedThs.push(th);
223
- }
224
- }
225
- ths = [...ths, ...thsToAdd];
226
- for (let i = 0; i < thsToAdd.length; i++) {
227
- // Se il th è un header td verrebbe undefined. Lo aggiungo solo se è effettivamente presente
228
- let td = tdsToAdd[thsToAdd[i].th];
229
- if (td)
230
- tds.push(td);
231
- }
232
- return { expTds: tds, expThs: ths };
233
- }
234
- /**
235
- * Prende i th e i td in modalità diretive e li ordina in base a se ci sono colonne fixed o meno
236
- */
237
- moveFixedColumnsAtTheBeginning(ths, tds) {
238
- let fixeds = 0, pinneds = 0;
239
- let columnsCache = {};
240
- let columnsIndexCache = {};
241
- // Creo la cache delle colonne
242
- for (let coli = 0; coli < this.est.ColumnsList.length; coli++) {
243
- let col = this.est.ColumnsList[coli];
244
- columnsCache[col.id] = col;
245
- // Anche per le columnslist sposto le pinnate o le fixed all'inizio
246
- if (col.pinned) {
247
- if (coli != pinneds)
248
- this.utilities.arrayMove(this.est.ColumnsList, coli, pinneds);
249
- pinneds++;
250
- }
251
- // Se una colonna è sia pinnata che fixata la considero unicamente pinnata
252
- if (col.fixed && !col.pinned) {
253
- if (coli != pinneds + fixeds)
254
- this.utilities.arrayMove(ths, coli, pinneds + fixeds);
255
- fixeds++;
256
- }
257
- }
258
- pinneds = fixeds = 0;
259
- // Sposto tutti gli header fixed o pinned all'inizio
260
- for (let i = 0; i < ths.length; i++) {
261
- let th = ths[i];
262
- // Riassegno sempre per ripulire valori di partenza o per aggiornarli in caso di modifiche utente
263
- th.thPinned = (!columnsCache[th.th] && th.thPinned) || (columnsCache[th.th] && columnsCache[th.th].pinned);
264
- if (th.thPinned) {
265
- if (i != pinneds)
266
- this.utilities.arrayMove(ths, i, pinneds);
267
- pinneds++;
268
- }
269
- //In questo caso sono informazioni statiche invece, non modificabili dall'utente, quindi non mi dò preoccupazioni
270
- if ((th.thFixed || th.thGroup) && !th.thPinned) {
271
- if (i != pinneds + fixeds)
272
- this.utilities.arrayMove(ths, i, pinneds + fixeds);
273
- fixeds++;
274
- }
275
- }
276
- // Cache degli indici per riposizionare i td come i th
277
- for (let i = 0; i < ths.length; i++)
278
- columnsIndexCache[ths[i].th] = i;
279
- // Riordino le celle per fargli mantenere la stessa struttura dei th
280
- let newTds = new Array(ths.length);
281
- for (let i = 0; i < tds.length; i++) {
282
- let item = tds[i];
283
- newTds[columnsIndexCache[item.td]] = item;
284
- }
285
- this.est.HasPinnedColumns = pinneds > 0;
286
- }
287
- /** In base alla configurazione delle colonne calcola le dimenioni delle colonne pinnate */
288
- evaluatePinnedColumnsWidth() {
289
- if (!this.est.HasPinnedColumns)
290
- return;
291
- this.est.PinnedContainerWidth = 0;
292
- for (let i = 0; i < this.est.ColumnsList.length; i++) {
293
- let col = this.est.ColumnsList[i];
294
- if (col.pinned && col.visible)
295
- this.est.PinnedContainerWidth += col.pinnedWidth;
296
- }
297
- this.est.PinnedContainerWidth += this.est.Selection ? 25 : 0;
298
- }
299
- /**
300
- * Terminato il binding delle colonne da **reviewColumnsList** e della **View** dal **writeValue** questo metodo si occupa
301
- * dell'allineamento delle informazioni fra le colonne calcolate internamente e le informazioni sulle colonne che arrivano dall'AppSearch
302
- *
303
- * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
304
- * @param {boolean} useLocalVisibility Indica di utilizzare le impostazioni di visibilità locali senza allinearle alla view
305
- */
306
- alignColumnsIfLoadedView(view) {
307
- let emitChanged = this.est.viewMode && view.savedstate;
308
- let newColset = [];
309
- if (!this.est.ColumnsList || this.est.ColumnsList.length == 0)
310
- return;
311
- let columns = [];
312
- // Modlaità view ->
313
- if (this.est.viewMode) {
314
- // colonne dinamiche -> prendo l'insieme delle colonne e operazioni dinamiche definite
315
- // standard -> prendo le colonne della view
316
- if (this.est.DynamicRowColumnsDefinition)
317
- columns = [...(this.est.DynamicRowColumnsDefinition?.map(t => t.PropertyName) || []), ...(this.est.DynamicOperations?.map(t => t.id) || [])];
318
- else
319
- columns = view.columns;
320
- }
321
- // Modalità array -> prendo le colonne array
322
- else
323
- columns = this.est.arrayColumns;
324
- this.est.ColumnsList.forEach(c => {
325
- // Se la colonna è pinnata mi arriva col simoleon, ma anche se è una composizione di più colonne
326
- let exCl = columns.filter(cc => (cc.startsWith('§') ? cc.substring(1) : cc) == c.id);
327
- // Se la colonna è pinnata aggiorno l'informazione nella view
328
- if (exCl.length == 1)
329
- c.pinned = exCl[0].startsWith('§');
330
- // Se l'appsearch viene da uno stato precedente, uso le informazioni sulle colonne che ha dentro, altrimenti sovrascrivo tutto **
331
- if (c.visible && columns.length == 0)
332
- newColset.push(c.id);
333
- // Se ho una colonna lato AppSearch e nella ColumnList non è visibile, allineo all'AppSearch
334
- else if (exCl.length == 1 && !c.visible && !this.est.useLocalVisibility)
335
- c.visible = true;
336
- // Allineamento sull'AppSearch per casistiche inverse al di sopra
337
- else if (exCl.length == 0 && c.visible && !this.est.useLocalVisibility)
338
- c.visible = false;
339
- });
340
- // Non ho colonne nella appsearch, vuol dire che sono al primo binding
341
- if (columns.length == 0) {
342
- if (this.est.viewMode)
343
- view.columns = newColset;
344
- else
345
- this.est.arrayColumns = newColset;
346
- }
347
- if ((this.est.viewMode && view.savedstate) && this.est.ColumnsOrdering && view.column_ordering.length > 0) {
348
- // Scorro gli ordinamenti che avevo salvato e ricreo la ColumnsList in base a loro
349
- let newColList = [];
350
- view.column_ordering.forEach(co => {
351
- this.est.ColumnsList.forEach(c => {
352
- if (c.id == co)
353
- newColList.push(c);
354
- });
355
- });
356
- // Recupero anche campi nuovi che nell'iterazione vecchia non c'erano (serve durante lo sviluppo in modo da non perdersi fra un EDIT + F5 e l'altro)
357
- this.est.ColumnsList.forEach(c => {
358
- if (!newColList.find(t => t == c.id))
359
- newColList.push(c);
360
- });
361
- this.est.ColumnsList = newColList;
362
- }
363
- // In ogni caso questo non mi serve più, lo resetto **
364
- if (this.est.viewMode)
365
- view.savedstate = false;
366
- // Reset di questa variabile usata one-bind
367
- if (this.est.useLocalVisibility)
368
- this.est.useLocalVisibility = false;
369
- if (emitChanged)
370
- this.est.changed();
371
- }
372
- /**
373
- * In base alla visibilità registrata nelle **ColumnsList** questo metodo si occupa di prendere tutti i **EsThDirective** ed **EsTdDirective** relativi e nasonderli/mostrarli
374
- *
375
- * Costo: 1 scan ColumnsList, 1 scan EsThDirectives, 1 scan EsTdDirectives
376
- *
377
- * @param {EsThDirective[]} ths Header della tabella
378
- * @param {EsTdDirective[]} tds Celle della tabella
379
- * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
380
- */
381
- refreshColumnsVisibility(ths, tds, view) {
382
- let newColset = [];
383
- let fixedThs = {};
384
- let columnsCache = {};
385
- for (let coli = 0; coli < this.est.ColumnsList.length; coli++) {
386
- let col = this.est.ColumnsList[coli];
387
- columnsCache[col.id] = col;
388
- if (col.visible)
389
- newColset.push((col.pinned ? "§" : "") + col.id);
390
- }
391
- if (view)
392
- view.columns = newColset;
393
- else
394
- this.est.arrayColumns = newColset;
395
- // 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
396
- if (ths) {
397
- // Definisco se la colonna è visibile in base alla sua rappresentazione locale in ColumnsList
398
- for (let i = 0; i < ths.length; i++) {
399
- let th = ths[i];
400
- th.thVisible = th.thFixed || (columnsCache[th.th] ? columnsCache[th.th].visible : th.thVisible);
401
- if (th.thFixed || th.thGroup)
402
- fixedThs[th.th] = true;
403
- }
404
- }
405
- if (tds) {
406
- // Definisco se la cella è visibile in base alla sua rappresentazione locale in ColumnsList
407
- for (let i = 0; i < tds.length; i++) {
408
- let td = tds[i];
409
- td.tdVisible = fixedThs[td.td] || (columnsCache[td.td] ? columnsCache[td.td].visible : td.tdVisible);
410
- }
411
- }
412
- this.est.changed();
413
- }
414
- /**
415
- * Allinea gli ordinamenti dati fra le **EsThs** e le informazioni all'interno della View bindata
416
- *
417
- * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
418
- * @param {EsThDirective[]} ths Colonne della tabella
419
- */
420
- alignHeadersOrdering(ths, view) {
421
- let orders = view ? view.orders : this.est.arrayOrders;
422
- for (let i = 0; i < ths.length; i++) {
423
- let th = ths[i];
424
- th.thOrder = null;
425
- for (let i = 0; i < orders.length; i++) {
426
- let or = orders[i];
427
- if (or.id == th.th)
428
- th.thOrder = or.order;
429
- }
430
- }
431
- }
432
- /**
433
- * Genera tutte le informazioni che servono per gestire il raggruppamento degli header
434
- *
435
- * @param {EsThDirective[]} ths Colonne della tabella
436
- *
437
- * @returns {{ leafs: EsThDirective[], groupingLevel: number, parentsCache: any, thsCache: any }} Oggetto contenente la lista delle foglie (header base), il livello
438
- * massimo di raggruppamento raggiunto, una cache in cui vengono indicati tutti i gruppi che sono "parent" (quindi che raggruppano almeno 1 header) e la cache degli header
439
- */
440
- evaluateHeadersGroupingInfos(ths) {
441
- // Pregiro per trovare i parent
442
- let parentsCache = {};
443
- let thsCache = {};
444
- for (let i = 0; i < ths.length; i++) {
445
- let th = ths[i];
446
- thsCache[th.th] = th;
447
- if (th.thParent && !parentsCache[th.thParent])
448
- parentsCache[th.thParent] = true;
449
- }
450
- // Secondo giro per beccare il livello massimo e la lista di foglie (th senza parent)
451
- let hMaxLevel = 0;
452
- let leafs = [];
453
- for (let i = 0; i < ths.length; i++) {
454
- let th = ths[i];
455
- // Se sono una foglia vedo quanti livelli ci sono sopra
456
- if (!parentsCache[th.th]) {
457
- leafs.push(th);
458
- let tmp = this.jumpsToFinalParent(th, thsCache);
459
- hMaxLevel = tmp > hMaxLevel ? tmp : hMaxLevel;
460
- }
461
- }
462
- return { leafs: leafs, groupingLevel: hMaxLevel, parentsCache: parentsCache, thsCache: thsCache };
463
- }
464
- /**
465
- * Genera gli header groups da una lista di info sui th all'interno della variabile **TMPRowThGroups**
466
- *
467
- * @param {{ leafs: EsThDirective[], groupingLevel: number, parentsCache: any, thsCache: any }} infos Informazioni di raggruppamento valutate precedentemente
468
- */
469
- evaluateHeaderGroups(infos) {
470
- if (infos.groupingLevel == 0)
471
- return;
472
- /****** STEP 1: Creo l'output dei raggruppamenti per header in modo da non dovermi preoccupare di celle non inizializzate ******/
473
- let expandedGroups = [];
474
- let visibleUnpinnedLeafs = infos.leafs.filter((t) => t.thVisible && t.thIf && !t.thPinned);
475
- for (let l = 0; l < infos.groupingLevel; l++) {
476
- expandedGroups.push([]);
477
- for (let i = 0; i < visibleUnpinnedLeafs.length; i++)
478
- expandedGroups[l].push("");
479
- }
480
- /****** STEP 2: Ordino le foglie in base agli ordinamenti delle colonne ******/
481
- let orderedLeafs = [];
482
- for (let i = 0; i < this.est.OrderDirectives.length; i++) {
483
- let leaf = infos.thsCache[this.est.OrderDirectives[i]];
484
- // Solo se la leaf è presente. Potrebbero esserci ordinamenti su colonne sparite
485
- if (leaf && leaf.thVisible && leaf.thIf && !leaf.thPinned)
486
- orderedLeafs.push(leaf);
487
- }
488
- /****** STEP 3: Creo l'array group con tutti i riferimenti del caso ******/
489
- let currentParent = "";
490
- for (let i = 0; i < orderedLeafs.length; i++) {
491
- let refTh = orderedLeafs[i];
492
- let prevTh = i - 1 >= 0 ? orderedLeafs[i - 1] : null;
493
- // Parent diverso da prima, metto il bordo a sinistra e a destra della cella precedente (se c'è)
494
- // 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
495
- refTh._lbord = refTh.thParent != currentParent;
496
- refTh._rbord = visibleUnpinnedLeafs.length == i + 1;
497
- if (prevTh)
498
- prevTh._rbord = refTh.thParent != currentParent;
499
- currentParent = refTh.thParent;
500
- // Per ogni gruppo srotolo il parent nella matrice dei raggruppamenti
501
- for (let l = 0; l < infos.groupingLevel; l++) {
502
- let parent = refTh.thParent;
503
- if (parent && !refTh.thPinned) {
504
- expandedGroups[l][i] = parent;
505
- refTh = infos.thsCache[parent];
506
- }
507
- }
508
- }
509
- /****** STEP 4: Compatto nell'elemento finale su cui bindarmi. L'ID assegnato è SOLO per ottimizzare gli ngFor ******/
510
- currentParent = "";
511
- let currentSpan = 0;
512
- let finalHeaders = [];
513
- for (let l = 0; l < expandedGroups.length; l++) {
514
- let levelArray = [];
515
- finalHeaders.push(levelArray);
516
- if (this.est.Selection || this.est.HasPinnedColumns)
517
- levelArray.push({ ID: "_base_sel_pinned", Span: 1, Template: null, Pinned: this.est.HasPinnedColumns });
518
- for (let h = 0; h < expandedGroups[l].length; h++) {
519
- let item = expandedGroups[l][h];
520
- if (item == currentParent)
521
- currentSpan++;
522
- else {
523
- if (currentSpan > 0)
524
- levelArray.push({ ID: `${currentParent ? infos.thsCache[currentParent].th : 'noth'}_${currentSpan}`, Span: currentSpan, Template: currentParent ? infos.thsCache[currentParent].Template : null, Content: currentParent ? infos.thsCache[currentParent]._multi_content : null, Borders: !!currentParent });
525
- currentSpan = 1;
526
- currentParent = item;
527
- }
528
- }
529
- // Ultima aggiunta che altrimenti mi rimarrebbe in cache
530
- levelArray.push({ ID: `${currentParent ? infos.thsCache[currentParent].th : 'noth'}_${currentSpan}`, Span: currentSpan, Template: currentParent ? infos.thsCache[currentParent].Template : null, Content: currentParent ? infos.thsCache[currentParent]._multi_content : null, Borders: !!currentParent });
531
- // Aggiungo i pezzettini per la rimozione e gli export, se presenti
532
- if (this.est.Removal)
533
- levelArray.push({ ID: "_base_removal", Span: 1, Template: null });
534
- if (this.est.Export || this.est.HiddenColumns || this.est.ColumnsOrdering || this.est.CornerMenuOptions)
535
- levelArray.push({ ID: "_base_extra_opts", Span: 1, Template: null });
536
- currentSpan = 0;
537
- currentParent = "";
538
- }
539
- /****** STEP 5: Secco le righe in cui non c'è nulla ******/
540
- this.est.TMPRowThGroups = [];
541
- for (let i = 0; i < finalHeaders.length; i++) {
542
- let level = finalHeaders[i];
543
- let empty = true;
544
- for (let j = 0; j < level.length; j++) {
545
- let item = level[j];
546
- if (item.Template || item.Content) {
547
- empty = false;
548
- break;
549
- }
550
- }
551
- if (!empty)
552
- this.est.TMPRowThGroups.push(level);
553
- }
554
- }
555
- /**
556
- * Calcola il numero di salti da un header foglia all'ultimo parent della catena
557
- *
558
- * @param {EsThDirective} th Header da cui scorrere i padri per capire quanti livelli ci sono sopra
559
- * @param {{ [index: string]: EsThDirective }} thsCache Cache degli header
560
- */
561
- jumpsToFinalParent(th, thsCache) {
562
- let jumps = 0;
563
- let parent = null;
564
- let parentsPrepend = [];
565
- let baseThRef = th;
566
- do {
567
- parent = th.thParent;
568
- if (parent) {
569
- th = thsCache[parent];
570
- if (!th.thEmpty && !th._multi_content)
571
- parentsPrepend.unshift({ id: th.th, tmpl: th.Template });
572
- else if (!th.thEmpty && th._multi_content)
573
- parentsPrepend.unshift({ id: th.th, content: th._multi_content });
574
- jumps++;
575
- }
576
- } while (parent);
577
- baseThRef._thParents = parentsPrepend;
578
- return jumps;
579
- }
580
- /**
581
- * Metodo che genera l'ordine di default delle colonne
582
- *
583
- * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
584
- */
585
- generateDefaultOrder(ths, view) {
586
- if (ths.length == 0)
587
- return;
588
- //*********************************************** Fix ordinamenti per colonne sparite ****************************** */
589
- // Considero solo gli ordinamenti per colonne effettivamente presenti all'interno della tabella
590
- if (this.est.viewMode)
591
- view.column_ordering = view.column_ordering.filter(ord => ths.find(t => t.th == ord));
592
- //*********************************************** Fix ordinamenti per colonne sparite ****************************** */
593
- let orderings = this.est.viewMode ? view.column_ordering : this.est.arrayColumnOrdering;
594
- // Genero ordinamento di default da 0 fino a dove deve arrivare. Situazione attuale senza hotpotato
595
- if (!orderings || orderings.length == 0) {
596
- for (let i = 0; i < ths.length; i++) {
597
- let th = ths[i];
598
- let order = th.th;
599
- this.est.OrderDirectives.push(order);
600
- }
601
- }
602
- else {
603
- this.est.OrderDirectives = orderings;
604
- for (let i = 0; i < ths.length; i++) {
605
- let th = ths[i];
606
- let thId = th.th;
607
- if (!this.est.OrderDirectives.find(o => o == thId))
608
- this.est.OrderDirectives.push(thId);
609
- }
610
- }
611
- }
612
- /**
613
- * Applica l'ordine specificato alle varie colonne
614
- *
615
- * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
616
- * @param {boolean} finalize Se **true** significa che non mi aspetto di dover effettuare altre operazioni e posso renderizzare la situazione in base ai RowContext
617
- * Senza finalize significa che mi aspetto altre operazioni che prima o poi richiameranno questa funzione col finalize.
618
- *
619
- * 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.
620
- * Mettendo solo la chiamata da "writeValue" come "finalizzante" mi assicuro che smanattamenti a frontend non causino flickering fino a quando non servono
621
- */
622
- applyOrdering(view, finalize) {
623
- // Genero ordinamento per gli header
624
- let newHeaders = [];
625
- // Se devo finalizzare aggancio tutte le variabili di bind
626
- if (finalize) {
627
- this.est.OrderDirectives.forEach(o => {
628
- let heaedrItem = this.est.TMPRowTHs.filter(t => t.ID == o)[0];
629
- if (heaedrItem)
630
- newHeaders.push(heaedrItem);
631
- });
632
- this.est.TMPRowTHs = newHeaders;
633
- // Genero ordinamento per le celle
634
- for (let i = 0; i < this.est.RowContexts.length; i++) {
635
- let context = this.est.TMPRowTDs[this.est.RowContexts[i]];
636
- let newContext = [];
637
- this.est.OrderDirectives.forEach(o => {
638
- let contextItem = context.filter(t => t.ID == o)[0];
639
- // potrebbe esser undefined nel caso ci fossero colonne sotto thIf
640
- if (contextItem)
641
- newContext.push(contextItem);
642
- });
643
- this.est.TMPRowTDs[this.est.RowContexts[i]] = newContext;
644
- }
645
- }
646
- if (this.est.viewMode)
647
- view.column_ordering = this.est.OrderDirectives;
648
- else
649
- this.est.arrayColumnOrdering = this.est.OrderDirectives;
650
- this.est.changed();
651
- }
652
- /**
653
- * All'interno della dialog "Ordinamento e Visibilità Colonne" mette la colonna specificata prima della colonna precedente
654
- *
655
- * @param {EsTableColumn} columnItem Colonna da spostare
656
- */
657
- sendUp(columnItem) {
658
- let itemIndex = this.est.TMPColumnsList.indexOf(columnItem);
659
- if (this.est.TMPColumnsList[itemIndex - 1].fixed || this.est.TMPColumnsList[itemIndex - 1].pinned)
660
- return;
661
- this.utiExts.swap(this.est.TMPColumnsList, itemIndex, itemIndex - 1);
662
- // Non posso fare JSON.parse(JSON.stringify(this.ColumnsList)) perché contiene riferimenti a TemplateRef
663
- let tmp = [];
664
- this.est.TMPColumnsList.forEach(c => { tmp.push(Object.assign({}, c)); });
665
- this.est.TMPColumnsList = tmp;
666
- }
667
- /**
668
- * All'interno della dialog "Ordinamento e Visibilità Colonne" mette la colonna specificata dopo la colonna successiva
669
- *
670
- * @param {EsTableColumn} columnItem Colonna da spostare
671
- */
672
- sendDown(columnItem) {
673
- let itemIndex = this.est.TMPColumnsList.indexOf(columnItem);
674
- this.utiExts.swap(this.est.TMPColumnsList, itemIndex, itemIndex + 1);
675
- // Non posso fare JSON.parse(JSON.stringify(this.ColumnsList)) perché contiene riferimenti a TemplateRef
676
- let tmp = [];
677
- this.est.TMPColumnsList.forEach(c => { tmp.push(Object.assign({}, c)); });
678
- this.est.TMPColumnsList = tmp;
679
- }
680
- /**
681
- * All'interno della dialog "Ordinamento e Visibilità Colonne" pinna la colonna specificata
682
- *
683
- * @param {EsTableColumn} columnItem Colonna da spostare
684
- */
685
- pinOrUnpinColumn(columnItem) {
686
- let itemIndex = this.est.TMPColumnsList.indexOf(columnItem);
687
- if (!columnItem.pinned) {
688
- columnItem.prev_index = itemIndex;
689
- //Quando pinno devo spostare l'elemento come ultima colonna pinnata o come prima colonna se non ce ne sono di pinnate
690
- for (let i = 0; i < this.est.TMPColumnsList.length; i++) {
691
- if (!this.est.TMPColumnsList[i].pinned) {
692
- this.utilities.arrayMove(this.est.TMPColumnsList, itemIndex, i);
693
- break;
694
- }
695
- }
696
- }
697
- else {
698
- //Quando spinno riporto l'elemento allo stesso indice in cui era prima (se sono stati fatti spostamenti nel mezzo cazzi dell'utente)
699
- if (columnItem.prev_index != null && columnItem.prev_index != undefined)
700
- this.utilities.arrayMove(this.est.TMPColumnsList, itemIndex, columnItem.prev_index);
701
- else {
702
- // Se spinno senza un prev_index vuol dire che la colonna era pinnata da configurazione. La sposto nel primo punto disponibile
703
- for (let i = 0; i < this.est.TMPColumnsList.length; i++) {
704
- if (!this.est.TMPColumnsList[i].pinned && !this.est.TMPColumnsList[i].fixed) {
705
- this.utilities.arrayMove(this.est.TMPColumnsList, itemIndex, i - 1);
706
- break;
707
- }
708
- }
709
- }
710
- }
711
- columnItem.pinned = !columnItem.pinned;
712
- }
713
- /**
714
- * All'interno della dialog "Ordinamento e Visibilità Colonne" inverte le impostazioni di visibilità della colonna
715
- *
716
- * @param {EsTableColumn} columnItem Colonna da spostare
717
- */
718
- columnClicked(item) {
719
- this.est.lastSelectedItemID = item.id;
720
- if (!this.est.HiddenColumns || item.fixed)
721
- return;
722
- item.visible = !item.visible;
723
- this.updateGlobalColVisCheck();
724
- }
725
- /** All'apertura della dialog "Ordinamento e Visibilità Colonne" ricarica le informazioni attuali per permettere la modifica */
726
- resetColumnVisSelection() {
727
- this.est.TMPColumnsList = [];
728
- // Non posso fare JSON.parse(JSON.stringify(this.ColumnsList)) perché contiene riferimenti a TemplateRef
729
- this.est.TMPColumnsList = [];
730
- this.est.ColumnsList.forEach(c => { this.est.TMPColumnsList.push(Object.assign({}, c)); });
731
- let reorderedColList = [];
732
- if (this.est.ColumnsOrdering) {
733
- this.est.OrderDirectives.forEach(o => {
734
- let column = this.est.TMPColumnsList.filter(t => t.id == o)[0];
735
- // Potrei non averne nel caso ci sia il flag HiddenColumns a false, evito di inserire degli undefined
736
- if (column)
737
- reorderedColList.push(column);
738
- });
739
- this.est.TMPColumnsList = reorderedColList;
740
- }
741
- this.updateGlobalColVisCheck();
742
- }
743
- /** Riaggiorna le **OrderDirectives** con le informazioni in **ColumnsList** */
744
- refreshColumnOrdering() {
745
- this.est.OrderDirectives = [];
746
- for (let c = 0; c < this.est.ColumnsList.length; c++)
747
- this.est.OrderDirectives.push(this.est.ColumnsList[c].id);
748
- }
749
- /** Effettua la selezione o meno del check globale (**globalColVisCheck**) di visibilità in base a se tutte le **TMPColumnsList** sono visibili o no */
750
- updateGlobalColVisCheck() {
751
- // TMPColList viene riempita di undefined nel caso in cui sia disattivata la selezione delle colonne nascoste
752
- this.est.globalColVisCheck = this.est.TMPColumnsList.every(t => t.visible);
753
- }
754
- /**
755
- * Chiamato quando una colonna viene riordinata all'interno della lista delle visibilità/posizioni colonne
756
- *
757
- * @param {CdkDragDrop<EsTableColumn[]>} event Evento di drop della lista
758
- */
759
- columnReordered(event) {
760
- moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
761
- }
762
- /**
763
- * Chiamato quando una colonna viene riordinata all'interno della lista delle visibilità/posizioni colonne
764
- *
765
- * @param {number} index Indice in cui voglio droppare l'elemento draggato
766
- * @param {CdkDrag<EsTableColumn>} item Oggetto che sto draggando
767
- *
768
- * @returns {boolean} **true** se la colonna può essere spostata sull'indice **index**, **false** altrimenti
769
- */
770
- sortPredicate(index, item) {
771
- let itemAtIndex = this.est.ColumnsList[index];
772
- return !itemAtIndex.fixed && !itemAtIndex.pinned && !item.data.pinned && !item.data.pinned;
773
- }
774
- /**
775
- * Funzione che effettua la conferma della visibilità e dell'ordine delle colonne.
776
- *
777
- * Questa selezione viene inoltre salvata nelle preferenze (**@esfaenza/preferences**), qualora l'Input **SavePreferences** fosse valorizzato
778
- *
779
- * @returns {boolean} **true** se non ci sono problemi, **false** altrimenti
780
- */
781
- confirmColumnVisibilitySelection() {
782
- // Non permetto di non selezionare nulla
783
- if (this.est.TMPColumnsList.every(t => !t.visible))
784
- return false;
785
- let castedView = this.est.viewMode ? (this.est.MainGroupView || this.est.View) : null;
786
- this.est.ColumnsList = [];
787
- this.est.TMPColumnsList.forEach(c => { this.est.ColumnsList.push(Object.assign({}, c)); });
788
- this.refreshColumnOrdering();
789
- this.applyOrdering(castedView, false);
790
- this.refreshColumnsVisibility(null, null, castedView);
791
- //Salvo le preferences di questa view
792
- //Di default registro ordinamento e visibilità delle colonne nella vista. Solo le cose di UI
793
- if (this.est.SavePreferences)
794
- this.registerViewPreferences(castedView);
795
- // Rieseguo l'ultima ricerca bindata alla tabella
796
- // Mi assicuro di farlo dopo l'espansione del changed o rischio che la ricerca mi ridia colonne che in realtà non esistono
797
- if (this.est.viewMode)
798
- setTimeout(() => {
799
- if (this.est.MainGroupView) {
800
- //this.emitSearchRequest(true, this.MainGroupView);
801
- for (let i = 0; i < this.est.groupSearchRequestsCache.length; i++) {
802
- let view = this.est.groupSearchRequestsCache[i].view;
803
- view.columns = this.est.MainGroupView.columns;
804
- view.column_ordering = this.est.MainGroupView.column_ordering;
805
- this.est.emitSearchRequest(true, this.est.groupSearchRequestsCache[i].view);
806
- }
807
- }
808
- else
809
- this.est.emitSearchRequest(true);
810
- });
811
- else if (this.est.arrayMode)
812
- setTimeout(() => { this.est.internalWriteValue(); });
813
- // Lo vorrei mettere lato template ma no
814
- this.est.lastSelectedItemID = null;
815
- return true;
816
- }
817
- /**
818
- * Effettuo l'unpinning di una colonna in maniera programmatica semplicemente eseguendo una per una le operazioni che verrebbero eseguite altrimenti
819
- *
820
- * @param {string} id Codice della colonna da spinnare
821
- */
822
- unpinColumn(id) {
823
- this.resetColumnVisSelection();
824
- this.pinOrUnpinColumn(this.est.TMPColumnsList.find(t => t.id == id));
825
- this.confirmColumnVisibilitySelection();
826
- }
827
- /** Sul click nella checkbox di selezione globale si scorrono tutte le colonne e si impostano al valore della check globale */
828
- globalColVisCheckChanged() {
829
- this.est.TMPColumnsList.forEach(t => {
830
- if (!t.fixed)
831
- t.visible = this.est.globalColVisCheck;
832
- });
833
- }
834
- }
835
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29sdW1uTWV0YWRhdGFIYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZXMtdGFibGUvc3JjL2xpYi9jb3JlL2hhbmRsZXJzL0NvbHVtbk1ldGFkYXRhSGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxVQUFVO0FBQ1YsT0FBTyxFQUF3QixlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQVMvRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDakUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBTWpFLFVBQVU7QUFDVixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sOENBQThDLENBQUM7QUFFM0UsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBR3JFLDZIQUE2SDtBQUM3SCxNQUFNLE9BQU8scUJBQXFCO0lBRTlCLHlCQUF5QjtJQUN6QixZQUFvQixHQUFxQixFQUFVLFNBQTJCLEVBQVUsT0FBdUIsRUFBVSxXQUErQixFQUFVLEdBQXVCO1FBQXJLLFFBQUcsR0FBSCxHQUFHLENBQWtCO1FBQVUsY0FBUyxHQUFULFNBQVMsQ0FBa0I7UUFBVSxZQUFPLEdBQVAsT0FBTyxDQUFnQjtRQUFVLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtRQUFVLFFBQUcsR0FBSCxHQUFHLENBQW9CO0lBQUksQ0FBQztJQUU5TDs7Ozs7T0FLRztJQUNJLG1CQUFtQixDQUFDLEVBQVUsRUFBRSxLQUFxQjtRQUN4RCxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUF1QixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUM7UUFDakcsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLElB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QUMsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7cUJBQy9FO2lCQUNKOztvQkFHRyxJQUFJLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3pDLENBQUMsQ0FBQyxDQUFDO2FBQ0YsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVM7WUFDdkIsVUFBVSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXpELHdDQUF3QztRQUN4QyxJQUFJLENBQUMsR0FBRyxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztRQUNuQyxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLFdBQVcsQ0FBQyxFQUFVO1FBQ3pCLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLGdDQUFnQyxFQUFFLENBQUM7SUFDNUMsQ0FBQztJQUVELDhIQUE4SDtJQUN2SCx3QkFBd0I7UUFDM0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ2hDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSztnQkFDUixDQUFDLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBBbmd1bGFyXHJcbmltcG9ydCB7IENka0RyYWcsIENka0RyYWdEcm9wLCBtb3ZlSXRlbUluQXJyYXkgfSBmcm9tIFwiQGFuZ3VsYXIvY2RrL2RyYWctZHJvcFwiO1xyXG5pbXBvcnQgeyBUZW1wbGF0ZVJlZiB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcblxyXG4vLyBMaWJzXHJcbmltcG9ydCB7IFV0aWxpdHlTZXJ2aWNlIH0gZnJvbSBcIkBlc2ZhZW56YS9leHRlbnNpb25zXCI7XHJcbmltcG9ydCB7IFByZWZlcmVuY2VzU2VydmljZSB9IGZyb20gXCJAZXNmYWVuemEvcHJlZmVyZW5jZXNcIjtcclxuXHJcbi8vIENvbXBvbmVudGkgLyBEaXJldHRpdmVcclxuaW1wb3J0IHsgRXNUYWJsZUNvbXBvbmVudCB9IGZyb20gXCIuLi8uLi9jb21wb25lbnRzL2VzLXRhYmxlL2VzX3RhYmxlLmNvbXBvbmVudFwiXHJcbmltcG9ydCB7IEVzVGREaXJlY3RpdmUgfSBmcm9tIFwiLi4vLi4vZGlyZWN0aXZlcy9lc190ZC5kaXJlY3RpdmVcIjtcclxuaW1wb3J0IHsgRXNUaERpcmVjdGl2ZSB9IGZyb20gXCIuLi8uLi9kaXJlY3RpdmVzL2VzX3RoLmRpcmVjdGl2ZVwiO1xyXG5cclxuLy8gSGFuZGxlcnNcclxuaW1wb3J0IHsgVXRpbGl0aWVzSGFuZGxlciB9IGZyb20gXCIuL1V0aWxpdGllc0hhbmRsZXJcIjtcclxuaW1wb3J0IHsgUm93R3JvdXBpbmdIYW5kbGVyIH0gZnJvbSBcIi4vUm93R3JvdXBpbmdIYW5kbGVyXCI7XHJcblxyXG4vLyBNb2RlbGxpXHJcbmltcG9ydCB7IEFwcE9yZGVyaW5nIH0gZnJvbSBcIi4uLy4uL2RvbWFpbi9leHRlcm5hbHMvYXBwc2VhcmNoL0FwcE9yZGVyaW5nXCI7XHJcbmltcG9ydCB7IEFwcFNlYXJjaCB9IGZyb20gXCIuLi8uLi9kb21haW4vZXh0ZXJuYWxzL2FwcHNlYXJjaC9BcHBTZWFyY2hcIjtcclxuaW1wb3J0IHsgRXNUYWJsZUNvbHVtbiB9IGZyb20gXCIuLi8uLi9kb21haW4vaW50ZXJuYWxzL0VzVGFibGVDb2x1bW5cIjtcclxuaW1wb3J0IHsgRXNUYWJsZU11bHRpVmFsdWUgfSBmcm9tIFwiLi4vLi4vZG9tYWluL2V4dGVybmFscy9hcHBzZWFyY2gvRXNUYWJsZU11bHRpVmFsdWVcIjtcclxuXHJcbi8qKiBDbGFzc2UgY2hlIGdlc3Rpc2NlIHR1dHRlIGxlIGluZm9ybWFpem9uaSByZWxhdGl2ZSBhbGxlIGNvbG9ubmU6IHZpc2liaWxpdMOgLCBwb3NpemlvbmUsIHN0YXRvIGRpIHBpbi91bnBpbiwgZWNjIGVjYy4uLiAqL1xyXG5leHBvcnQgY2xhc3MgQ29sdW1uTWV0YWRhdGFIYW5kbGVyIHtcclxuXHJcbiAgICAvKiogQGlnbm9yZSBDb3N0cnV0dG9yZSovXHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVzdDogRXNUYWJsZUNvbXBvbmVudCwgcHJpdmF0ZSB1dGlsaXRpZXM6IFV0aWxpdGllc0hhbmRsZXIsIHByaXZhdGUgdXRpRXh0czogVXRpbGl0eVNlcnZpY2UsIHByaXZhdGUgcHJlZlNlcnZpY2U6IFByZWZlcmVuY2VzU2VydmljZSwgcHJpdmF0ZSByZ0g6IFJvd0dyb3VwaW5nSGFuZGxlcikgeyB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRvZG8gY2hlIGdlc3Rpc2NlIGlsIGNhbWJpbyBkaSBPcmRpbmFtZW50byBkaSB1bmEgY29sb25uYVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBJRCBkZWxsYSBjb2xvbm5hIGlsIGN1aSBvcmlkbmFtZW50byDDqCBjYW1iaWF0b1xyXG4gICAgICogQHBhcmFtIHsnREVTQycgfCAnQVNDJ30gb3JkZXIgTnVvdm8gb3JkaW5lIHNlbGV6aW9uYXRvIHBlciBsYSBjb2xvbm5hXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBoYW5kbGVUSE9yZGVyQ2hhbmdlKGlkOiBzdHJpbmcsIG9yZGVyOiAnREVTQycgfCAnQVNDJykge1xyXG4gICAgICAgIGxldCBvcmRlcnMgPSB0aGlzLmVzdC52aWV3TW9kZSA/ICh0aGlzLmVzdC5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+KS5vcmRlcnMgOiB0aGlzLmVzdC5hcnJheU9yZGVycztcclxuICAgICAgICBsZXQgb3JkZXJUb0FkZCA9IHRydWU7XHJcbiAgICAgICAgbGV0IG9yZGVyVG9SZW1vdmU6IG51bWJlciA9IG51bGw7XHJcblxyXG4gICAgICAgIC8vIFNlIHBlciBxdWFsY2hlIG1vdGl2byBpbCBjb3N0cnV0dG9yZSBub24gw6ggcGFzc2F0byAoY2FjaGUgdGFycGF0ZSBvIHNpbWlsYSkgZml4b1xyXG4gICAgICAgIGlmICghb3JkZXJzICYmIHRoaXMuZXN0LnZpZXdNb2RlKVxyXG4gICAgICAgICAgICAodGhpcy5lc3QuVmlldyBhcyBBcHBTZWFyY2g8YW55Pikub3JkZXJzID0gW107XHJcbiAgICAgICAgZWxzZSBpZiAoIW9yZGVycyAmJiB0aGlzLmVzdC5hcnJheU1vZGUpXHJcbiAgICAgICAgICAgIHRoaXMuZXN0LmFycmF5T3JkZXJzID0gW107XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JkZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0ID0gb3JkZXJzW2ldO1xyXG4gICAgICAgICAgICBpZiAodC5pZCA9PSBpZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG9yZGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdC5vcmRlciA9IG9yZGVyO1xyXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyVG9BZGQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBvcmRlclRvUmVtb3ZlID0gaTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKG9yZGVyVG9SZW1vdmUgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICBvcmRlcnMuc3BsaWNlKG9yZGVyVG9SZW1vdmUsIDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChvcmRlclRvQWRkKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVzdC5NdWx0aXBsZU9yZGVyaW5nRGlyZWN0aXZlcylcclxuICAgICAgICAgICAgICAgIG9yZGVycy5wdXNoKG5ldyBBcHBPcmRlcmluZyhpZCwgb3JkZXIpKTtcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5lc3Qudmlld01vZGUpXHJcbiAgICAgICAgICAgICAgICAgICAgKHRoaXMuZXN0LlZpZXcgYXMgQXBwU2VhcmNoPGFueT4pLm9yZGVycyA9IFtuZXcgQXBwT3JkZXJpbmcoaWQsIG9yZGVyKV07XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLmVzdC5hcnJheU1vZGUpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lc3QuYXJyYXlPcmRlcnMgPSBbbmV3IEFwcE9yZGVyaW5nKGlkLCBvcmRlcildO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvL1NhbHZvIGxlIHByZWZlcmVuY2VzIGRpIHF1ZXN0YSB2aWV3XHJcbiAgICAgICAgLy9EaSBkZWZhdWx0IHJlZ2lzdHJvIG9yZGluYW1lbnRvIGUgdmlzaWJpbGl0w6AgZGVsbGUgY29sb25uZSBuZWxsYSB2aXN0YS4gU29sbyBsZSBjb3NlIGRpIFVJXHJcbiAgICAgICAgaWYgKHRoaXMuZXN0LlNhdmVQcmVmZXJlbmNlcykge1xyXG4gICAgICAgICAgICBsZXQgY2FzdGVkVmlldyA9IHRoaXMuZXN0LnZpZXdNb2RlID8gKHRoaXMuZXN0Lk1haW5Hcm91cFZpZXcgfHwgdGhpcy5lc3QuVmlldyBhcyBBcHBTZWFyY2g8YW55PikgOiBudWxsO1xyXG4gICAgICAgICAgICB0aGlzLnJlZ2lzdGVyVmlld1ByZWZlcmVuY2VzKGNhc3RlZFZpZXcpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5lc3Qub25PcmRlckNoYW5nZWQuZW1pdCh7IGlkLCBvcmRlciB9KTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuZXN0LnZpZXdNb2RlKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVzdC5ncm91cFNlYXJjaFJlcXVlc3RzQ2FjaGUubGVuZ3RoID4gMClcclxuICAgICAgICAgICAgICAgIHRoaXMucmdILmVtaXRSb3dHcm91cGluZ1NlYXJjaGVzKGlkLCBvcmRlcnMpO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICB0aGlzLmVzdC5lbWl0U2VhcmNoUmVxdWVzdChmYWxzZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuZXN0LmFycmF5TW9kZSlcclxuICAgICAgICAgICAgdGhpcy5lc3QuaW50ZXJuYWxXcml0ZVZhbHVlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWdpc3RyYSBsZSBwcmVmZXJlbmNlIHJlbGF0aXZlIGFsbGEgdmlldyBwYXNzYXRhIGNvbWUgcGFyYW1ldHJvXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7YW55fSBjYXN0ZWRWaWV3IFZpZXcgZGkgY3VpIHNhbHZhcmUgY29sb25uZSBlIG9yZGluYW1lbnRvIGNvbG9ubmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIHJlZ2lzdGVyVmlld1ByZWZlcmVuY2VzKGNhc3RlZFZpZXc6IEFwcFNlYXJjaDxhbnk+KSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmVzdC5uZ0NvbnRyb2wubmFtZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm9uIHBvc3NvIHV0aWxpenphcmUgbGUgcHJlZmVyZW5jZSBzZW56YSBhdmVyZSB1biAnbmFtZScgcGVyIGxhIHRhYmVsbGFcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5wcmVmU2VydmljZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiTm9uIHBvc3NvIHV0aWxpenphcmUgbGUgcHJlZmVyZW5jZSBzZW56YSBjaGUgaWwgcGFjY2hldHRvIEBlc2ZhZW56YS9wcmVmZXJlbmNlcyBzaWEgaW5zdGFsbGF0b1wiKTtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGNvbHVtbnMgPSB0aGlzLmVzdC5hcnJheU1vZGUgPyB0aGlzLmVzdC5hcnJheUNvbHVtbnMgOiBjYXN0ZWRWaWV3LmNvbHVtbnM7XHJcbiAgICAgICAgbGV0IGNvbHVtbnNPcmRlcmluZ3MgPSB0aGlzLmVzdC5hcnJheU1vZGUgPyB0aGlzLmVzdC5hcnJheUNvbHVtbk9yZGVyaW5nIDogY2FzdGVkVmlldy5jb2x1bW5fb3JkZXJpbmc7XHJcbiAgICAgICAgbGV0IGNvbHVtbk9yZGVycyA9IHRoaXMuZXN0LmFycmF5TW9kZSA/IFtdIDogY2FzdGVkVmlldy5vcmRlcnM7XHJcbiAgICAgICAgdmFyIHRvU3RvcmUgPSB7XHJcbiAgICAgICAgICAgIGNvbHVtbnM6IHRoaXMudXRpRXh0cy5kZWVwQ2xvbmUoY29sdW1ucykgYXMgc3RyaW5nW10sXHJcbiAgICAgICAgICAgIGNvbHVtbl9vcmRlcmluZzogdGhpcy51dGlFeHRzLmRlZXBDbG9uZShjb2x1bW5zT3JkZXJpbmdzKSBhcyBzdHJpbmdbXSxcclxuICAgICAgICAgICAgb3JkZXJzOiB0aGlzLnV0aUV4dHMuZGVlcENsb25lKGNvbHVtbk9yZGVycykgYXMgc3RyaW5nW11cclxuICAgICAgICB9O1xyXG4gICAgICAgIHRoaXMucHJlZlNlcnZpY2Uuc2V0SXRlbSg8c3RyaW5nPnRoaXMuZXN0Lm5nQ29udHJvbC5uYW1lLCB0b1N0b3JlKS5zdWJzY3JpYmUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBhcnRlbmRvIGRhZ2xpICoqRXNUaHMqKiBlc3RyYXBwb2xvIGxhIGxpc3RhIGRpICoqRXNUYWJsZUNvbHVtbioqIGNoZSBxdWVzdGEgdGFiZWxsYSBkb3Zyw6AgZXZlbnR1YWxtZW50ZSBnZXN0aXJlIHBlciBWaXNpYmlsaXTDoCBlIE9yZGluZVxyXG4gICAgICpcclxuICAgICAqIENvc3RvOiAxIHNjYW4gRXNUaHNcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VzVGhEaXJlY3RpdmVbXX0gdGhzIENvbG9ubmUgZGVsbGEgdGFiZWxsYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmV2aWV3Q29sdW1uc0xpc3QodGhzOiBFc1RoRGlyZWN0aXZlW10pIHtcclxuICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdCA9IFtdO1xyXG4gICAgICAgIGlmICh0aHMubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gQXBwZW5hIGlsIGNvbnRlbnRDaGlsZHJlbiDDqCB2YWxvcml6emF0byBzY29ycm8gdHV0dGkgZ2xpIGhlYWRlclxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuXHJcbiAgICAgICAgICAgIGxldCBjb2x1bW4gPSB0aC50aDtcclxuICAgICAgICAgICAgLy8gU2Ugbm9uIGhvIHVuIGlkIGlsIHRoIMOoIGNvbnNpZGVyYXRvIGluZXJ0ZVxyXG4gICAgICAgICAgICBpZiAoIWNvbHVtbilcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgLy8gU2Fsdm8gbGUgaW5mb3JtYXppb25pIGRlbGwnaGVhZGVyIHBlciBmYXIgcGFydGUgZGVsbGEgbGlzdGEgZGEgY3VpIHNjZWdsaWVyZSBxdWFsaSBjb2xvbm5lIHZpc3VhbGl6emFyZS9uYXNjb25kZXJlXHJcbiAgICAgICAgICAgIC8vIERpIGRlZmF1bHQgbGEgdmlzaWJpbGl0w6Agw6ggcXVlbGxhIGltcG9zdGF0YSBuZWwgY29tcG9uZW50ZVxyXG4gICAgICAgICAgICBpZiAoKHRoaXMuZXN0LkhpZGRlbkNvbHVtbnMgfHwgdGgudGhWaXNpYmxlKSAmJiB0aC50aElmKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgcHJldmlvdXNseVBpbm5lZCA9ICF0aGlzLmVzdC5Db2x1bW5zTGlzdCB8fCB0aGlzLmVzdC5Db2x1bW5zTGlzdC5sZW5ndGggPT0gMCA/IG51bGwgOiB0aGlzLmVzdC5Db2x1bW5zTGlzdC5maW5kKHQgPT4gdC5pZCA9PSBjb2x1bW4pIHx8IG51bGw7XHJcbiAgICAgICAgICAgICAgICBsZXQgdG9BZGQgPSBuZXcgRXNUYWJsZUNvbHVtbihjb2x1bW4sIHRoLnRoU3RhdGljQ29udGVudCwgdGgudGhWaXNpYmxlLCAodGgudGhGaXhlZCB8fCB0aC50aEdyb3VwKSwgcHJldmlvdXNseVBpbm5lZCA9PSBudWxsID8gdGgudGhQaW5uZWQgOiBwcmV2aW91c2x5UGlubmVkLnBpbm5lZCwgdGgudGhQaW5uYWJsZSwgdGgudGhQaW5uZWRXaWR0aCwgdGguVGVtcGxhdGUsIHRoLl90aFBhcmVudHMsIHRoLl9tdWx0aSwgdGguX211bHRpX2NvbnRlbnQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzbHlQaW5uZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgdG9BZGQucHJldl9pbmRleCA9IHByZXZpb3VzbHlQaW5uZWQucHJldl9pbmRleDtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LnB1c2godG9BZGQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZXN0LkNvbHVtbnNMaXN0ID0gW107XHJcbiAgICAgICAgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QuZm9yRWFjaChjID0+IHsgdGhpcy5lc3QuQ29sdW1uc0xpc3QucHVzaChPYmplY3QuYXNzaWduKHt9LCBjKSk7IH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBJbiBjYXNvIHNpYW5vIGNvbmZpZ3VyYXRpIGRlaSB0aCBcIk11bHRpXCIgKHZlZGVyZSBsYSBkZXNjcml6aW9uZSBkZWwgY2FtcG8gKip0aE11bHRpKiogZGkgKipFc1RoRGlyZWN0aXZlKiopIHF1ZXN0byBtZXRvZG8gbGkgXCJzcm90b2xhXCIgaW4gdHV0dGkgaSB0aC90ZCBjaGUgZGV2b25vIGVmZmV0dGl2YW1lbnRlIGRpdmVudGFyZSAqL1xyXG4gICAgcHVibGljIGV4cGFuZE11bHRpVGhzQW5kVGRzKHRoczogRXNUaERpcmVjdGl2ZVtdLCB0ZHM6IEVzVGREaXJlY3RpdmVbXSwgaXRlbXM6IGFueVtdKToge2V4cFRoczogRXNUaERpcmVjdGl2ZVtdLCBleHBUZHM6IEVzVGREaXJlY3RpdmVbXX0ge1xyXG5cclxuICAgICAgICAvLyBSZWdpc3RybyBsZSBpbmZvIHN1aSBtdWx0aXByb3ZpZGVyXHJcbiAgICAgICAgbGV0IG11bHRpRGVmczogeyBbaWQ6IHN0cmluZ106IHsgT24/OiBzdHJpbmcsIHRocmVmOiBFc1RoRGlyZWN0aXZlLCB0ZHJlZjogRXNUZERpcmVjdGl2ZSwgdGhnZW46IHsgW2lkOiBzdHJpbmddOiBFc1RoRGlyZWN0aXZlIH0sIHRkZ2VuOiB7IFtpZDogc3RyaW5nXTogRXNUZERpcmVjdGl2ZSB9IH0gfSA9IHsgfTtcclxuICAgICAgICBcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcbiAgICAgICAgICAgIGlmICghdGgudGhNdWx0aSlcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgbXVsdGlEZWZzW3RoLnRoXSA9IHsgT246IHRoLnRoLCB0ZHJlZjogbnVsbCwgdGhyZWY6IHRoLCB0aGdlbjoge30sIHRkZ2VuOiB7fSB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQXNzZWdubyBsZSBpbmZvIGFuY2hlIGFpIHRkXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRkID0gdGRzW2ldO1xyXG4gICAgICAgICAgICB0ZC5fbXVsdGkgPSAhIW11bHRpRGVmc1t0ZC50ZF07XHJcbiAgICAgICAgICAgIGlmKHRkLl9tdWx0aSlcclxuICAgICAgICAgICAgICAgIG11bHRpRGVmc1t0ZC50ZF0udGRyZWYgPSB0ZDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFJpbXVvdm8gaSBtdWx0aXRlbXBsYXRlIGRhbGxlIGJhbGxlXHJcbiAgICAgICAgLy8gTi5COiBEYXRvIGNoZSBsYSBwcmltYSBvcGVyYXppb25lIHN1IHRoIGUgdGQgw6ggcXVlc3RhIGlsIHJpZmVyaW1lbnRvIG9yaWdpbmFsZSB2aWVuZSBzb3ZyYXNjcml0dG8sIHF1ZXN0byBzaWduaWZpY2EgY2hlIGRldm8gcmktZW1ldHRlcmUgaSBkdWUgbnVvdmkgYXJyYXlcclxuICAgICAgICB0aHMgPSB0aHMuZmlsdGVyKHQgPT4gIXQudGhNdWx0aSk7XHJcbiAgICAgICAgdGRzID0gdGRzLmZpbHRlcih0ID0+ICF0Ll9tdWx0aSk7XHJcblxyXG4gICAgICAgIGxldCBwYXJlbnRUaHM6IHsgW2lkOiBzdHJpbmddOiBib29sZWFuOyB9ID0geyB9O1xyXG4gICAgICAgIGxldCBhZGRlZEhlYWRlcnM6IHsgW2lkOiBzdHJpbmddOiBib29sZWFuOyB9ID0geyB9O1xyXG4gICAgICAgIGxldCB0ZHNUb0FkZDogeyBbaWQ6IHN0cmluZ10gOiBFc1RkRGlyZWN0aXZlfSA9IHsgfTtcclxuICAgICAgICBsZXQgdGhzVG9BZGQ6IEVzVGhEaXJlY3RpdmVbXSA9IFtdO1xyXG5cclxuICAgICAgICAvLyBQZXIgb2duaSBpdGVtIHZlZG8gc2UgY2kgc29ubyBkZWkgbXVsdGkgcGVyIGxlIHByb3ByaWV0w6AgY2hlIGxpIGRlZmluaXNjb25vXHJcbiAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgaSsrKXtcclxuICAgICAgICAgICAgbGV0IGl0bSA9IGl0ZW1zW2ldO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgZm9yIChsZXQgcHJvcCBpbiBtdWx0aURlZnMpIHtcclxuICAgICAgICAgICAgICAgIC8vIFNlIGxhIHByb3ByaWV0w6AgZGVsIG11bHRpIGVzaXN0ZSBuZWxsJ29nZ2V0dG8gZWQgaGEgdW5hIGx1bmdoZXp6YVxyXG4gICAgICAgICAgICAgICAgaWYgKGl0bVtwcm9wXSAmJiBpdG1bcHJvcF0ubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IG11bHRpUmVmID0gbXVsdGlEZWZzW3Byb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCByZWZ0ZCA9IG11bHRpUmVmLnRkcmVmO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCByZWZ0aCA9IG11bHRpUmVmLnRocmVmO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpaSA9IDA7IGlpIDwgaXRtW3Byb3BdLmxlbmd0aDsgaWkrKykge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSGVhZGVyIGdpw6AgYWdnaXVudG8sIG5vbiBkZXZvIGluc2VyaXJlIGFsdHJpIHRlbXBsYXRlIGRpIGhlYWRlci9jb2xvbm5hXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlc3RtdiA9IDxFc1RhYmxlTXVsdGlWYWx1ZT5pdG1bcHJvcF1baWldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWVzdG12Ll9oZWFkZXJzSGllcmFyY2h5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXN0bXYuX2hlYWRlcnNIaWVyYXJjaHkgPSBlc3Rtdi5oZWFkZXJfZ3JvdXAgPyBlc3Rtdi5oZWFkZXJfZ3JvdXAuc3BsaXQoXCI+XCIpLm1hcCh0ID0+IHQudHJpbSgpKSA6IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGhlYWRlclZhbHVlID0gZXN0bXYuaGVhZGVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcGFyZW50ID0gZXN0bXYuaGVhZGVyX2dyb3VwIHx8IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBwYXJlbnRzSGllciA9IGVzdG12Ll9oZWFkZXJzSGllcmFyY2h5O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFkZGVkSGVhZGVyc1tgJHtwYXJlbnR9XyR7aGVhZGVyVmFsdWV9YF0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkZWRIZWFkZXJzW2Ake3BhcmVudH1fJHtoZWFkZXJWYWx1ZX1gXSA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBQZXIgb2duaSB2YWxvcmUgZGl2ZXJzbyBkZWxsZSBwcm9wcmlldMOgIGRldm8gYWdnaXVuZ2VyZSB1biB0ZCBlIHVuIHRoLCBxdWVzdCd1bHRpbW8gZGV2J2Vzc2VyZSBldmVudHVhbG1lbnRlIGNvbGxlZ2F0byBhZCB1biBoZWFkZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG5ld3RIID0gbmV3IEVzVGhEaXJlY3RpdmUocmVmdGguVGVtcGxhdGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXd0SC5fbXVsdGkgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXd0SC5fbXVsdGlfY29udGVudCA9IGhlYWRlclZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXd0SC50aCA9IGAke3Byb3B9XyR7aWl9YDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3dEgudGhDbGFzcyA9IHJlZnRoLnRoQ2xhc3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld3RILnRoU2hyaW5rID0gcmVmdGgudGhTaHJpbms7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld3RILnRoSWYgPSByZWZ0aC50aElmO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXd0SC50aFZpc2libGUgPSByZWZ0aC50aFZpc2libGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld3RILnRoV3JhcCA9IHJlZnRoLnRoV3JhcDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWwgcGFyZW50IMOoIHNlbXByZSBsJ3VsdGltbyBuZWxsYSBnZXJhcmNoaWEgZGkgcGFkcmlcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3dEgudGhQYXJlbnQgPSBwYXJlbnRzSGllcltwYXJlbnRzSGllci5sZW5ndGggLSAxXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3dEgudGhPcmRlcmFibGUgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyZW50c0hpZXIubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBwYXIgPSBwYXJlbnRzSGllcltpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcGFyZW50VGhzW3Bhcl0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50VGhzW3Bhcl0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCB0aFBhcmVudCA9IG5ldyBFc1RoRGlyZWN0aXZlKG51bGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhQYXJlbnQudGggPSBwYXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aFBhcmVudC5fbXVsdGlfY29udGVudCA9IHBhcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoUGFyZW50LnRoUGFyZW50ID0gaSA+IDAgPyBwYXJlbnRzSGllcltpIC0gMV0gOiBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhzVG9BZGQucHVzaCh0aFBhcmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoc1RvQWRkLnB1c2gobmV3dEgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG5ld1RkID0gbmV3IEVzVGREaXJlY3RpdmUocmVmdGQuVGVtcGxhdGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdUZC5fbXVsdGkgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdUZC50ZCA9IGAke3Byb3B9XyR7aWl9YDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3VGQudGRDbGFzcyA9IHJlZnRkLnRkQ2xhc3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1RkLnRkSWYgPSByZWZ0ZC50ZElmO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdUZC50ZFZpc2libGUgPSByZWZ0ZC50ZFZpc2libGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRkc1RvQWRkW25ld1RkLnRkXSA9IG5ld1RkO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gT3JkaW5vIGdsaSBoZWFkZXIgYWdnaXVudGkgaW4gYmFzZSBhbCBQYXJlbnQsIHNlIHByZXNlbnRlLCBlIGxpIGFnZ2l1bmdvIGFsbGEgbGlzdGEgZGVpIHRoLCBkb3BvZGljaMOpIGluIGJhc2UgYWxsbyBzdGVzc28gb3JkaW5hbWVudG8gYWdnaXVuZ28gaSByZWxhdGl2aSB0ZFxyXG4gICAgICAgIGxldCBvcmRlcmVkVGhzID0gW107XHJcblxyXG4gICAgICAgIC8vIFByaW1hIG1ldHRvIHR1dHRpIGkgdGggc2VuemEgcGFyZW50LCBwb2kgcGVyIG9nbmkgcGFyZW50IHByZW5kbyBpIHRoIG9yZGluYXRpIGNvbWUgbGkgdHJvdm8gbmVsbGEgbGlzdGFcclxuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgdGhzVG9BZGQubGVuZ3RoOyBpKyspe1xyXG4gICAgICAgICAgICBpZighdGhzVG9BZGRbaV0udGhQYXJlbnQpXHJcbiAgICAgICAgICAgICAgICBvcmRlcmVkVGhzLnB1c2godGhzVG9BZGRbaV0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmb3IobGV0IHByb3AgaW4gcGFyZW50VGhzKXtcclxuICAgICAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IHRoc1RvQWRkLmxlbmd0aDsgaSsrKXtcclxuICAgICAgICAgICAgICAgIGxldCB0aCA9IHRoc1RvQWRkW2ldO1xyXG4gICAgICAgICAgICAgICAgaWYodGgudGhQYXJlbnQgJiYgdGgudGhQYXJlbnQgPT0gcHJvcClcclxuICAgICAgICAgICAgICAgICAgICBvcmRlcmVkVGhzLnB1c2godGgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aHMgPSBbLi4udGhzLCAuLi50aHNUb0FkZF07XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHNUb0FkZC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAvLyBTZSBpbCB0aCDDqCB1biBoZWFkZXIgdGQgdmVycmViYmUgdW5kZWZpbmVkLiBMbyBhZ2dpdW5nbyBzb2xvIHNlIMOoIGVmZmV0dGl2YW1lbnRlIHByZXNlbnRlXHJcbiAgICAgICAgICAgIGxldCB0ZCA9IHRkc1RvQWRkW3Roc1RvQWRkW2ldLnRoXTtcclxuICAgICAgICAgICAgaWYgKHRkKVxyXG4gICAgICAgICAgICAgICAgdGRzLnB1c2godGQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHsgZXhwVGRzOiB0ZHMsIGV4cFRoczogdGhzIH07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQcmVuZGUgaSB0aCBlIGkgdGQgaW4gbW9kYWxpdMOgIGRpcmV0aXZlIGUgbGkgb3JkaW5hIGluIGJhc2UgYSBzZSBjaSBzb25vIGNvbG9ubmUgZml4ZWQgbyBtZW5vXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBtb3ZlRml4ZWRDb2x1bW5zQXRUaGVCZWdpbm5pbmcodGhzOiBFc1RoRGlyZWN0aXZlW10sIHRkczogRXNUZERpcmVjdGl2ZVtdKSB7XHJcblxyXG4gICAgICAgIGxldCBmaXhlZHMgPSAwLCBwaW5uZWRzID0gMDtcclxuICAgICAgICBsZXQgY29sdW1uc0NhY2hlOiB7IFtpbmRleDogc3RyaW5nXTogRXNUYWJsZUNvbHVtbjsgfSA9IHt9O1xyXG4gICAgICAgIGxldCBjb2x1bW5zSW5kZXhDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IG51bWJlcjsgfSA9IHt9O1xyXG5cclxuICAgICAgICAvLyBDcmVvIGxhIGNhY2hlIGRlbGxlIGNvbG9ubmVcclxuICAgICAgICBmb3IgKGxldCBjb2xpID0gMDsgY29saSA8IHRoaXMuZXN0LkNvbHVtbnNMaXN0Lmxlbmd0aDsgY29saSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBjb2wgPSB0aGlzLmVzdC5Db2x1bW5zTGlzdFtjb2xpXTtcclxuICAgICAgICAgICAgY29sdW1uc0NhY2hlW2NvbC5pZF0gPSBjb2w7XHJcblxyXG4gICAgICAgICAgICAvLyBBbmNoZSBwZXIgbGUgY29sdW1uc2xpc3Qgc3Bvc3RvIGxlIHBpbm5hdGUgbyBsZSBmaXhlZCBhbGwnaW5pemlvXHJcbiAgICAgICAgICAgIGlmIChjb2wucGlubmVkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29saSAhPSBwaW5uZWRzKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbGl0aWVzLmFycmF5TW92ZSh0aGlzLmVzdC5Db2x1bW5zTGlzdCwgY29saSwgcGlubmVkcyk7XHJcbiAgICAgICAgICAgICAgICBwaW5uZWRzKys7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIFNlIHVuYSBjb2xvbm5hIMOoIHNpYSBwaW5uYXRhIGNoZSBmaXhhdGEgbGEgY29uc2lkZXJvIHVuaWNhbWVudGUgcGlubmF0YVxyXG4gICAgICAgICAgICBpZiAoY29sLmZpeGVkICYmICFjb2wucGlubmVkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29saSAhPSBwaW5uZWRzICsgZml4ZWRzKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbGl0aWVzLmFycmF5TW92ZSh0aHMsIGNvbGksIHBpbm5lZHMgKyBmaXhlZHMpO1xyXG4gICAgICAgICAgICAgICAgZml4ZWRzKys7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHBpbm5lZHMgPSBmaXhlZHMgPSAwO1xyXG5cclxuICAgICAgICAvLyBTcG9zdG8gdHV0dGkgZ2xpIGhlYWRlciBmaXhlZCBvIHBpbm5lZCBhbGwnaW5pemlvXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG5cclxuICAgICAgICAgICAgLy8gUmlhc3NlZ25vIHNlbXByZSBwZXIgcmlwdWxpcmUgdmFsb3JpIGRpIHBhcnRlbnphIG8gcGVyIGFnZ2lvcm5hcmxpIGluIGNhc28gZGkgbW9kaWZpY2hlIHV0ZW50ZVxyXG4gICAgICAgICAgICB0aC50aFBpbm5lZCA9ICghY29sdW1uc0NhY2hlW3RoLnRoXSAmJiB0aC50aFBpbm5lZCkgfHwgKGNvbHVtbnNDYWNoZVt0aC50aF0gJiYgY29sdW1uc0NhY2hlW3RoLnRoXS5waW5uZWQpO1xyXG4gICAgICAgICAgICBpZiAodGgudGhQaW5uZWQpIHtcclxuICAgICAgICAgICAgICAgIGlmIChpICE9IHBpbm5lZHMpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51dGlsaXRpZXMuYXJyYXlNb3ZlKHRocywgaSwgcGlubmVkcyk7XHJcbiAgICAgICAgICAgICAgICBwaW5uZWRzKys7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vSW4gcXVlc3RvIGNhc28gc29ubyBpbmZvcm1hemlvbmkgc3RhdGljaGUgaW52ZWNlLCBub24gbW9kaWZpY2FiaWxpIGRhbGwndXRlbnRlLCBxdWluZGkgbm9uIG1pIGTDsiBwcmVvY2N1cGF6aW9uaVxyXG4gICAgICAgICAgICBpZiAoKHRoLnRoRml4ZWQgfHwgdGgudGhHcm91cCkgJiYgIXRoLnRoUGlubmVkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaSAhPSBwaW5uZWRzICsgZml4ZWRzKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbGl0aWVzLmFycmF5TW92ZSh0aHMsIGksIHBpbm5lZHMgKyBmaXhlZHMpO1xyXG4gICAgICAgICAgICAgICAgZml4ZWRzKys7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIENhY2hlIGRlZ2xpIGluZGljaSBwZXIgcmlwb3NpemlvbmFyZSBpIHRkIGNvbWUgaSB0aFxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICBjb2x1bW5zSW5kZXhDYWNoZVsoPEVzVGhEaXJlY3RpdmU+dGhzW2ldKS50aF0gPSBpO1xyXG5cclxuICAgICAgICAvLyBSaW9yZGlubyBsZSBjZWxsZSBwZXIgZmFyZ2xpIG1hbnRlbmVyZSBsYSBzdGVzc2Egc3RydXR0dXJhIGRlaSB0aFxyXG4gICAgICAgIGxldCBuZXdUZHMgPSBuZXcgQXJyYXkodGhzLmxlbmd0aCk7XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBpdGVtID0gdGRzW2ldIGFzIEVzVGREaXJlY3RpdmU7XHJcbiAgICAgICAgICAgIG5ld1Rkc1tjb2x1bW5zSW5kZXhDYWNoZVtpdGVtLnRkXV0gPSBpdGVtO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5lc3QuSGFzUGlubmVkQ29sdW1ucyA9IHBpbm5lZHMgPiAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBJbiBiYXNlIGFsbGEgY29uZmlndXJhemlvbmUgZGVsbGUgY29sb25uZSBjYWxjb2xhIGxlIGRpbWVuaW9uaSBkZWxsZSBjb2xvbm5lIHBpbm5hdGUgKi9cclxuICAgIHB1YmxpYyBldmFsdWF0ZVBpbm5lZENvbHVtbnNXaWR0aCgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuZXN0Lkhhc1Bpbm5lZENvbHVtbnMpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgdGhpcy5lc3QuUGlubmVkQ29udGFpbmVyV2lkdGggPSAwO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5lc3QuQ29sdW1uc0xpc3QubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IGNvbCA9IHRoaXMuZXN0LkNvbHVtbnNMaXN0W2ldO1xyXG4gICAgICAgICAgICBpZiAoY29sLnBpbm5lZCAmJiBjb2wudmlzaWJsZSlcclxuICAgICAgICAgICAgICAgIHRoaXMuZXN0LlBpbm5lZENvbnRhaW5lcldpZHRoICs9IGNvbC5waW5uZWRXaWR0aDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5lc3QuUGlubmVkQ29udGFpbmVyV2lkdGggKz0gdGhpcy5lc3QuU2VsZWN0aW9uID8gMjUgOiAwO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVybWluYXRvIGlsIGJpbmRpbmcgZGVsbGUgY29sb25uZSBkYSAqKnJldmlld0NvbHVtbnNMaXN0KiogZSBkZWxsYSAqKlZpZXcqKiBkYWwgKip3cml0ZVZhbHVlKiogcXVlc3RvIG1ldG9kbyBzaSBvY2N1cGFcclxuICAgICAqIGRlbGwnYWxsaW5lYW1lbnRvIGRlbGxlIGluZm9ybWF6aW9uaSBmcmEgbGUgY29sb25uZSBjYWxjb2xhdGUgaW50ZXJuYW1lbnRlIGUgbGUgaW5mb3JtYXppb25pIHN1bGxlIGNvbG9ubmUgY2hlIGFycml2YW5vIGRhbGwnQXBwU2VhcmNoXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtBcHBTZWFyY2g8YW55Pn0gdmlldyBBcHBTZWFyY2ggZGEgdXRpbGl6emFyZSBwZXIgcXVlc3RhIG9wZXJhemlvbmVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gdXNlTG9jYWxWaXNpYmlsaXR5IEluZGljYSBkaSB1dGlsaXp6YXJlIGxlIGltcG9zdGF6aW9uaSBkaSB2aXNpYmlsaXTDoCBsb2NhbGkgc2VuemEgYWxsaW5lYXJsZSBhbGxhIHZpZXdcclxuICAgICAqL1xyXG4gICAgcHVibGljIGFsaWduQ29sdW1uc0lmTG9hZGVkVmlldyh2aWV3OiBBcHBTZWFyY2g8YW55Pikge1xyXG4gICAgICAgIGxldCBlbWl0Q2hhbmdlZCA9IHRoaXMuZXN0LnZpZXdNb2RlICYmIHZpZXcuc2F2ZWRzdGF0ZTtcclxuICAgICAgICBsZXQgbmV3Q29sc2V0ID0gW107XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5lc3QuQ29sdW1uc0xpc3QgfHwgdGhpcy5lc3QuQ29sdW1uc0xpc3QubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgbGV0IGNvbHVtbnMgPSBbXTtcclxuXHJcbiAgICAgICAgLy8gTW9kbGFpdMOgIHZpZXcgLT5cclxuICAgICAgICBpZiAodGhpcy5lc3Qudmlld01vZGUpIHtcclxuICAgICAgICAgICAgLy8gY29sb25uZSBkaW5hbWljaGUgLT4gcHJlbmRvIGwnaW5zaWVtZSBkZWxsZSBjb2xvbm5lIGUgb3BlcmF6aW9uaSBkaW5hbWljaGUgZGVmaW5pdGVcclxuICAgICAgICAgICAgLy8gc3RhbmRhcmQgLT4gcHJlbmRvIGxlIGNvbG9ubmUgZGVsbGEgdmlld1xyXG4gICAgICAgICAgICBpZiAodGhpcy5lc3QuRHluYW1pY1Jvd0NvbHVtbnNEZWZpbml0aW9uKVxyXG4gICAgICAgICAgICAgICAgY29sdW1ucyA9IFsuLi4odGhpcy5lc3QuRHluYW1pY1Jvd0NvbHVtbnNEZWZpbml0aW9uPy5tYXAodCA9PiB0LlByb3BlcnR5TmFtZSkgfHwgW10pLCAuLi4odGhpcy5lc3QuRHluYW1pY09wZXJhdGlvbnM/Lm1hcCh0ID0+IHQuaWQpIHx8IFtdKV07XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIGNvbHVtbnMgPSB2aWV3LmNvbHVtbnM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIE1vZGFsaXTDoCBhcnJheSAtPiBwcmVuZG8gbGUgY29sb25uZSBhcnJheVxyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgY29sdW1ucyA9IHRoaXMuZXN0LmFycmF5Q29sdW1uc1xyXG5cclxuICAgICAgICB0aGlzLmVzdC5Db2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4ge1xyXG4gICAgICAgICAgICAvLyBTZSBsYSBjb2xvbm5hIMOoIHBpbm5hdGEgbWkgYXJyaXZhIGNvbCBzaW1vbGVvbiwgbWEgYW5jaGUgc2Ugw6ggdW5hIGNvbXBvc2l6aW9uZSBkaSBwacO5IGNvbG9ubmVcclxuICAgICAgICAgICAgbGV0IGV4Q2wgPSBjb2x1bW5zLmZpbHRlcihjYyA9PiAoY2Muc3RhcnRzV2l0aCgnwqcnKSA/IGNjLnN1YnN0cmluZygxKSA6IGNjKSA9PSBjLmlkKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNlIGxhIGNvbG9ubmEgw6ggcGlubmF0YSBhZ2dpb3JubyBsJ2luZm9ybWF6aW9uZSBuZWxsYSB2aWV3XHJcbiAgICAgICAgICAgIGlmIChleENsLmxlbmd0aCA9PSAxKVxyXG4gICAgICAgICAgICAgICAgYy5waW5uZWQgPSBleENsWzBdLnN0YXJ0c1dpdGgoJ8KnJyk7XHJcblxyXG4gICAgICAgICAgICAvLyBTZSBsJ2FwcHNlYXJjaCB2aWVuZSBkYSB1bm8gc3RhdG8gcHJlY2VkZW50ZSwgdXNvIGxlIGluZm9ybWF6aW9uaSBzdWxsZSBjb2xvbm5lIGNoZSBoYSBkZW50cm8sIGFsdHJpbWVudGkgc292cmFzY3Jpdm8gdHV0dG8gICoqXHJcbiAgICAgICAgICAgIGlmIChjLnZpc2libGUgJiYgY29sdW1ucy5sZW5ndGggPT0gMClcclxuICAgICAgICAgICAgICAgIG5ld0NvbHNldC5wdXNoKGMuaWQpO1xyXG5cclxuICAgICAgICAgICAgLy8gU2UgaG8gdW5hIGNvbG9ubmEgbGF0byBBcHBTZWFyY2ggZSBuZWxsYSBDb2x1bW5MaXN0IG5vbiDDqCB2aXNpYmlsZSwgYWxsaW5lbyBhbGwnQXBwU2VhcmNoXHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGV4Q2wubGVuZ3RoID09IDEgJiYgIWMudmlzaWJsZSAmJiAhdGhpcy5lc3QudXNlTG9jYWxWaXNpYmlsaXR5KVxyXG4gICAgICAgICAgICAgICAgYy52aXNpYmxlID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIC8vIEFsbGluZWFtZW50byBzdWxsJ0FwcFNlYXJjaCBwZXIgY2FzaXN0aWNoZSBpbnZlcnNlIGFsIGRpIHNvcHJhXHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGV4Q2wubGVuZ3RoID09IDAgJiYgYy52aXNpYmxlICAmJiAhdGhpcy5lc3QudXNlTG9jYWxWaXNpYmlsaXR5KVxyXG4gICAgICAgICAgICAgICAgYy52aXNpYmxlID0gZmFsc2U7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIE5vbiBobyBjb2xvbm5lIG5lbGxhIGFwcHNlYXJjaCwgdnVvbCBkaXJlIGNoZSBzb25vIGFsIHByaW1vIGJpbmRpbmdcclxuICAgICAgICBpZiAoY29sdW1ucy5sZW5ndGggPT0gMCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5lc3Qudmlld01vZGUpXHJcbiAgICAgICAgICAgICAgICB2aWV3LmNvbHVtbnMgPSBuZXdDb2xzZXQ7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHRoaXMuZXN0LmFycmF5Q29sdW1ucyA9IG5ld0NvbHNldDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICgodGhpcy5lc3Qudmlld01vZGUgJiYgdmlldy5zYXZlZHN0YXRlKSAmJiB0aGlzLmVzdC5Db2x1bW5zT3JkZXJpbmcgJiYgdmlldy5jb2x1bW5fb3JkZXJpbmcubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAvLyBTY29ycm8gZ2xpIG9yZGluYW1lbnRpIGNoZSBhdmV2byBzYWx2YXRvIGUgcmljcmVvIGxhIENvbHVtbnNMaXN0IGluIGJhc2UgYSBsb3JvXHJcbiAgICAgICAgICAgIGxldCBuZXdDb2xMaXN0ID0gW107XHJcbiAgICAgICAgICAgIHZpZXcuY29sdW1uX29yZGVyaW5nLmZvckVhY2goY28gPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5lc3QuQ29sdW1uc0xpc3QuZm9yRWFjaChjID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYy5pZCA9PSBjbylcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3Q29sTGlzdC5wdXNoKGMpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgLy8gUmVjdXBlcm8gYW5jaGUgY2FtcGkgbnVvdmkgY2hlIG5lbGwnaXRlcmF6aW9uZSB2ZWNjaGlhIG5vbiBjJ2VyYW5vIChzZXJ2ZSBkdXJhbnRlIGxvIHN2aWx1cHBvIGluIG1vZG8gZGEgbm9uIHBlcmRlcnNpIGZyYSB1biBFRElUICsgRjUgZSBsJ2FsdHJvKVxyXG4gICAgICAgICAgICB0aGlzLmVzdC5Db2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFuZXdDb2xMaXN0LmZpbmQodCA9PiB0ID09IGMuaWQpKVxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0NvbExpc3QucHVzaChjKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmVzdC5Db2x1bW5zTGlzdCA9IG5ld0NvbExpc3Q7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJbiBvZ25pIGNhc28gcXVlc3RvIG5vbiBtaSBzZXJ2ZSBwacO5LCBsbyByZXNldHRvICAqKlxyXG4gICAgICAgIGlmICh0aGlzLmVzdC52aWV3TW9kZSlcclxuICAgICAgICAgICAgdmlldy5zYXZlZHN0YXRlID0gZmFsc2U7XHJcblxyXG4gICAgICAgIC8vIFJlc2V0IGRpIHF1ZXN0YSB2YXJpYWJpbGUgdXNhdGEgb25lLWJpbmRcclxuICAgICAgICBpZiAodGhpcy5lc3QudXNlTG9jYWxWaXNpYmlsaXR5KVxyXG4gICAgICAgICAgICB0aGlzLmVzdC51c2VMb2NhbFZpc2liaWxpdHkgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgaWYgKGVtaXRDaGFuZ2VkKVxyXG4gICAgICAgICAgICB0aGlzLmVzdC5jaGFuZ2VkKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbiBiYXNlIGFsbGEgdmlzaWJpbGl0w6AgcmVnaXN0cmF0YSBuZWxsZSAqKkNvbHVtbnNMaXN0KiogcXVlc3RvIG1ldG9kbyBzaSBvY2N1cGEgZGkgcHJlbmRlcmUgdHV0dGkgaSAqKkVzVGhEaXJlY3RpdmUqKiBlZCAqKkVzVGREaXJlY3RpdmUqKiByZWxhdGl2aSBlIG5hc29uZGVybGkvbW9zdHJhcmxpXHJcbiAgICAgKlxyXG4gICAgICogQ29zdG86IDEgc2NhbiBDb2x1bW5zTGlzdCwgMSBzY2FuIEVzVGhEaXJlY3RpdmVzLCAxIHNjYW4gRXNUZERpcmVjdGl2ZXNcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VzVGhEaXJlY3RpdmVbXX0gdGhzIEhlYWRlciBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKiBAcGFyYW0ge0VzVGREaXJlY3RpdmVbXX0gdGRzIENlbGxlIGRlbGxhIHRhYmVsbGFcclxuICAgICAqIEBwYXJhbSB7QXBwU2VhcmNoPGFueT59IHZpZXcgQXBwU2VhcmNoIGRhIHV0aWxpenphcmUgcGVyIHF1ZXN0YSBvcGVyYXppb25lXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWZyZXNoQ29sdW1uc1Zpc2liaWxpdHkodGhzOiBFc1RoRGlyZWN0aXZlW10sIHRkczogRXNUZERpcmVjdGl2ZVtdLCB2aWV3OiBBcHBTZWFyY2g8YW55Pikge1xyXG4gICAgICAgIGxldCBuZXdDb2xzZXQgPSBbXTtcclxuICAgICAgICBsZXQgZml4ZWRUaHM6IHsgW2lkOiBzdHJpbmddOiBib29sZWFuOyB9ID0ge307XHJcbiAgICAgICAgbGV0IGNvbHVtbnNDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IEVzVGFibGVDb2x1bW47IH0gPSB7fTtcclxuICAgICAgICBmb3IgKGxldCBjb2xpID0gMDsgY29saSA8IHRoaXMuZXN0LkNvbHVtbnNMaXN0Lmxlbmd0aDsgY29saSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBjb2wgPSB0aGlzLmVzdC5Db2x1bW5zTGlzdFtjb2xpXTtcclxuICAgICAgICAgICAgY29sdW1uc0NhY2hlW2NvbC5pZF0gPSBjb2w7XHJcbiAgICAgICAgICAgIGlmIChjb2wudmlzaWJsZSlcclxuICAgICAgICAgICAgICAgIG5ld0NvbHNldC5wdXNoKChjb2wucGlubmVkID8gXCLCp1wiIDogXCJcIikgKyBjb2wuaWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodmlldylcclxuICAgICAgICAgICAgdmlldy5jb2x1bW5zID0gbmV3Q29sc2V0O1xyXG5cclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHRoaXMuZXN0LmFycmF5Q29sdW1ucyA9IG5ld0NvbHNldDtcclxuXHJcbiAgICAgICAgLy8gRGEgcXVpIGluIHBvaSBkZXZvbm8gZXNzZXJlIGVzZWd1aXRpIFNPTE8gaW4gZmFzZSBkaSB3cml0ZVZhbHVlIHF1aW5kaSBkZXZvIGFzc2ljdXJhcm1pIGRpIHBhc3NhcmxpIG51bGwgaW4gdHV0dGkgaSBwYXNzYWdnaSBkaXZlcnNpIGRhIHF1ZWxsb1xyXG4gICAgICAgIGlmICh0aHMpIHtcclxuICAgICAgICAgICAgLy8gRGVmaW5pc2NvIHNlIGxhIGNvbG9ubmEgw6ggdmlzaWJpbGUgaW4gYmFzZSBhbGxhIHN1YSByYXBwcmVzZW50YXppb25lIGxvY2FsZSBpbiBDb2x1bW5zTGlzdFxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoLnRoVmlzaWJsZSA9IHRoLnRoRml4ZWQgfHwgKGNvbHVtbnNDYWNoZVt0aC50aF0gPyBjb2x1bW5zQ2FjaGVbdGgudGhdLnZpc2libGUgOiB0aC50aFZpc2libGUpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoLnRoRml4ZWQgfHwgdGgudGhHcm91cClcclxuICAgICAgICAgICAgICAgICAgICBmaXhlZFRoc1t0aC50aF0gPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGRzKSB7XHJcbiAgICAgICAgICAgIC8vIERlZmluaXNjbyBzZSBsYSBjZWxsYSDDqCB2aXNpYmlsZSBpbiBiYXNlIGFsbGEgc3VhIHJhcHByZXNlbnRhemlvbmUgbG9jYWxlIGluIENvbHVtbnNMaXN0XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgdGQgPSB0ZHNbaV07XHJcbiAgICAgICAgICAgICAgICB0ZC50ZFZpc2libGUgPSBmaXhlZFRoc1t0ZC50ZF0gfHwgKGNvbHVtbnNDYWNoZVt0ZC50ZF0gPyBjb2x1bW5zQ2FjaGVbdGQudGRdLnZpc2libGUgOiB0ZC50ZFZpc2libGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmVzdC5jaGFuZ2VkKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGxpbmVhIGdsaSBvcmRpbmFtZW50aSBkYXRpIGZyYSBsZSAqKkVzVGhzKiogZSBsZSBpbmZvcm1hemlvbmkgYWxsJ2ludGVybm8gZGVsbGEgVmlldyBiaW5kYXRhXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtBcHBTZWFyY2g8YW55Pn0gdmlldyBBcHBTZWFyY2ggZGEgdXRpbGl6emFyZSBwZXIgcXVlc3RhIG9wZXJhemlvbmVcclxuICAgICAqIEBwYXJhbSB7RXNUaERpcmVjdGl2ZVtdfSB0aHMgQ29sb25uZSBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhbGlnbkhlYWRlcnNPcmRlcmluZyh0aHM6IEVzVGhEaXJlY3RpdmVbXSwgdmlldzogQXBwU2VhcmNoPGFueT4pIHtcclxuICAgICAgICBsZXQgb3JkZXJzID0gdmlldyA/IHZpZXcub3JkZXJzIDogdGhpcy5lc3QuYXJyYXlPcmRlcnM7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG5cclxuICAgICAgICAgICAgdGgudGhPcmRlciA9IG51bGw7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JkZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgb3IgPSBvcmRlcnNbaV07XHJcbiAgICAgICAgICAgICAgICBpZiAob3IuaWQgPT0gdGgudGgpXHJcbiAgICAgICAgICAgICAgICAgICAgdGgudGhPcmRlciA9IG9yLm9yZGVyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2VuZXJhIHR1dHRlIGxlIGluZm9ybWF6aW9uaSBjaGUgc2Vydm9ubyBwZXIgZ2VzdGlyZSBpbCByYWdncnVwcGFtZW50byBkZWdsaSBoZWFkZXJcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VzVGhEaXJlY3RpdmVbXX0gdGhzIENvbG9ubmUgZGVsbGEgdGFiZWxsYVxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHt7IGxlYWZzOiBFc1RoRGlyZWN0aXZlW10sIGdyb3VwaW5nTGV2ZWw6IG51bWJlciwgcGFyZW50c0NhY2hlOiBhbnksIHRoc0NhY2hlOiBhbnkgfX0gT2dnZXR0byBjb250ZW5lbnRlIGxhIGxpc3RhIGRlbGxlIGZvZ2xpZSAoaGVhZGVyIGJhc2UpLCBpbCBsaXZlbGxvXHJcbiAgICAgKiBtYXNzaW1vIGRpIHJhZ2dydXBwYW1lbnRvIHJhZ2dpdW50bywgdW5hIGNhY2hlIGluIGN1aSB2ZW5nb25vIGluZGljYXRpIHR1dHRpIGkgZ3J1cHBpIGNoZSBzb25vIFwicGFyZW50XCIgKHF1aW5kaSBjaGUgcmFnZ3J1cHBhbm8gYWxtZW5vIDEgaGVhZGVyKSBlIGxhIGNhY2hlIGRlZ2xpIGhlYWRlclxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZXZhbHVhdGVIZWFkZXJzR3JvdXBpbmdJbmZvcyh0aHM6IEVzVGhEaXJlY3RpdmVbXSk6IHsgbGVhZnM6IEVzVGhEaXJlY3RpdmVbXTsgZ3JvdXBpbmdMZXZlbDogbnVtYmVyOyBwYXJlbnRzQ2FjaGU6IGFueTsgdGhzQ2FjaGU6IGFueTsgfSB7XHJcbiAgICAgICAgLy8gUHJlZ2lybyBwZXIgdHJvdmFyZSBpIHBhcmVudFxyXG4gICAgICAgIGxldCBwYXJlbnRzQ2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBib29sZWFuOyB9ID0ge307XHJcbiAgICAgICAgbGV0IHRoc0NhY2hlOiB7IFtpbmRleDogc3RyaW5nXTogRXNUaERpcmVjdGl2ZTsgfSA9IHt9O1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuXHJcbiAgICAgICAgICAgIHRoc0NhY2hlW3RoLnRoXSA9IHRoO1xyXG4gICAgICAgICAgICBpZiAodGgudGhQYXJlbnQgJiYgIXBhcmVudHNDYWNoZVt0aC50aFBhcmVudF0pXHJcbiAgICAgICAgICAgICAgICBwYXJlbnRzQ2FjaGVbdGgudGhQYXJlbnRdID0gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFNlY29uZG8gZ2lybyBwZXIgYmVjY2FyZSBpbCBsaXZlbGxvIG1hc3NpbW8gZSBsYSBsaXN0YSBkaSBmb2dsaWUgKHRoIHNlbnphIHBhcmVudClcclxuICAgICAgICBsZXQgaE1heExldmVsID0gMDtcclxuICAgICAgICBsZXQgbGVhZnM6IGFueVtdID0gW107XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG5cclxuICAgICAgICAgICAgLy8gU2Ugc29ubyB1bmEgZm9nbGlhIHZlZG8gcXVhbnRpIGxpdmVsbGkgY2kgc29ubyBzb3ByYVxyXG4gICAgICAgICAgICBpZiAoIXBhcmVudHNDYWNoZVt0aC50aF0pIHtcclxuICAgICAgICAgICAgICAgIGxlYWZzLnB1c2godGgpO1xyXG4gICAgICAgICAgICAgICAgbGV0IHRtcCA9IHRoaXMuanVtcHNUb0ZpbmFsUGFyZW50KHRoLCB0aHNDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICBoTWF4TGV2ZWwgPSB0bXAgPiBoTWF4TGV2ZWwgPyB0bXAgOiBoTWF4TGV2ZWw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB7IGxlYWZzOiBsZWFmcywgZ3JvdXBpbmdMZXZlbDogaE1heExldmVsLCBwYXJlbnRzQ2FjaGU6IHBhcmVudHNDYWNoZSwgdGhzQ2FjaGU6IHRoc0NhY2hlIH07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZW5lcmEgZ2xpIGhlYWRlciBncm91cHMgZGEgdW5hIGxpc3RhIGRpIGluZm8gc3VpIHRoIGFsbCdpbnRlcm5vIGRlbGxhIHZhcmlhYmlsZSAqKlRNUFJvd1RoR3JvdXBzKipcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge3sgbGVhZnM6IEVzVGhEaXJlY3RpdmVbXSwgZ3JvdXBpbmdMZXZlbDogbnVtYmVyLCBwYXJlbnRzQ2FjaGU6IGFueSwgdGhzQ2FjaGU6IGFueSB9fSBpbmZvcyBJbmZvcm1hemlvbmkgZGkgcmFnZ3J1cHBhbWVudG8gdmFsdXRhdGUgcHJlY2VkZW50ZW1lbnRlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBldmFsdWF0ZUhlYWRlckdyb3VwcyhpbmZvczogeyBsZWFmczogRXNUaERpcmVjdGl2ZVtdOyBncm91cGluZ0xldmVsOiBudW1iZXI7IHBhcmVudHNDYWNoZTogYW55OyB0aHNDYWNoZTogeyBbaW5kZXg6c3RyaW5nXTogRXNUaERpcmVjdGl2ZX07IH0pIHtcclxuICAgICAgICBpZiAoaW5mb3MuZ3JvdXBpbmdMZXZlbCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIC8qKioqKiogU1RFUCAxOiBDcmVvIGwnb3V0cHV0IGRlaSByYWdncnVwcGFtZW50aSBwZXIgaGVhZGVyIGluIG1vZG8gZGEgbm9uIGRvdmVybWkgcHJlb2NjdXBhcmUgZGkgY2VsbGUgbm9uIGluaXppYWxpenphdGUgKioqKioqL1xyXG5cclxuICAgICAgICBsZXQgZXhwYW5kZWRHcm91cHMgPSBbXTtcclxuICAgICAgICBsZXQgdmlzaWJsZVVucGlubmVkTGVhZnM6IEVzVGhEaXJlY3RpdmVbXSA9ICg8YW55W10+aW5mb3MubGVhZnMpLmZpbHRlcigodDogRXNUaERpcmVjdGl2ZSkgPT4gdC50aFZpc2libGUgJiYgdC50aElmICYmICF0LnRoUGlubmVkKTtcclxuICAgICAgICBmb3IgKGxldCBsID0gMDsgbCA8IGluZm9zLmdyb3VwaW5nTGV2ZWw7IGwrKykge1xyXG4gICAgICAgICAgICBleHBhbmRlZEdyb3Vwcy5wdXNoKFtdKTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2aXNpYmxlVW5waW5uZWRMZWFmcy5sZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgICAgIGV4cGFuZGVkR3JvdXBzW2xdLnB1c2goXCJcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKioqKioqIFNURVAgMjogT3JkaW5vIGxlIGZvZ2xpZSBpbiBiYXNlIGFnbGkgb3JkaW5hbWVudGkgZGVsbGUgY29sb25uZSAqKioqKiovXHJcbiAgICAgICAgbGV0IG9yZGVyZWRMZWFmcyA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5lc3QuT3JkZXJEaXJlY3RpdmVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBsZWFmOiBFc1RoRGlyZWN0aXZlID0gaW5mb3MudGhzQ2FjaGVbdGhpcy5lc3QuT3JkZXJEaXJlY3RpdmVzW2ldXTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNvbG8gc2UgbGEgbGVhZiDDqCBwcmVzZW50ZS4gUG90cmViYmVybyBlc3NlcmNpIG9yZGluYW1lbnRpIHN1IGNvbG9ubmUgc3Bhcml0ZVxyXG4gICAgICAgICAgICBpZiAobGVhZiAmJiBsZWFmLnRoVmlzaWJsZSAmJiBsZWFmLnRoSWYgJiYgIWxlYWYudGhQaW5uZWQpXHJcbiAgICAgICAgICAgICAgICBvcmRlcmVkTGVhZnMucHVzaChsZWFmKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKioqKiogU1RFUCAzOiBDcmVvIGwnYXJyYXkgZ3JvdXAgY29uIHR1dHRpIGkgcmlmZXJpbWVudGkgZGVsIGNhc28gKioqKioqL1xyXG4gICAgICAgIGxldCBjdXJyZW50UGFyZW50ID0gXCJcIjtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9yZGVyZWRMZWFmcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgcmVmVGg6IEVzVGhEaXJlY3RpdmUgPSBvcmRlcmVkTGVhZnNbaV07XHJcbiAgICAgICAgICAgIGxldCBwcmV2VGg6IEVzVGhEaXJlY3RpdmUgPSBpIC0gMSA+PSAwID8gb3JkZXJlZExlYWZzW2kgLSAxXSA6IG51bGw7XHJcblxyXG4gICAgICAgICAgICAvLyBQYXJlbnQgZGl2ZXJzbyBkYSBwcmltYSwgbWV0dG8gaWwgYm9yZG8gYSBzaW5pc3RyYSBlIGEgZGVzdHJhIGRlbGxhIGNlbGxhIHByZWNlZGVudGUgKHNlIGMnw6gpXHJcbiAgICAgICAgICAgIC8vIEFsbCd1bHRpbW8gZ2lybyBtZXR0byBpbCBib3JkbyBhIGRlc3RyYS4gVHV0dG8gcXVlc3RvIGxvIHJpZXNlZ3VvIHBlciBvZ25pIGNlbGxhIGluIG1vZG8gZGEgcmlwdWxpcmUgZXZlbnR1YWxpIGEgY3VpIGF2ZXZvIGFzc2VnbmF0byB0YWcgcHJlY2VkZW50ZW1lbnRlXHJcbiAgICAgICAgICAgICg8YW55PnJlZlRoKS5fbGJvcmQgPSByZWZUaC50aFBhcmVudCAhPSBjdXJyZW50UGFyZW50O1xyXG4gICAgICAgICAgICAoPGFueT5yZWZUaCkuX3Jib3JkID0gdmlzaWJsZVVucGlubmVkTGVhZnMubGVuZ3RoID09IGkgKyAxO1xyXG4gICAgICAgICAgICBpZiAocHJldlRoKVxyXG4gICAgICAgICAgICAgICAgKDxhbnk+cHJldlRoKS5fcmJvcmQgPSByZWZUaC50aFBhcmVudCAhPSBjdXJyZW50UGFyZW50O1xyXG5cclxuICAgICAgICAgICAgY3VycmVudFBhcmVudCA9IHJlZlRoLnRoUGFyZW50O1xyXG5cclxuICAgICAgICAgICAgLy8gUGVyIG9nbmkgZ3J1cHBvIHNyb3RvbG8gaWwgcGFyZW50IG5lbGxhIG1hdHJpY2UgZGVpIHJhZ2dydXBwYW1lbnRpXHJcbiAgICAgICAgICAgIGZvciAobGV0IGwgPSAwOyBsIDwgaW5mb3MuZ3JvdXBpbmdMZXZlbDsgbCsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgcGFyZW50ID0gcmVmVGgudGhQYXJlbnQ7XHJcbiAgICAgICAgICAgICAgICBpZiAocGFyZW50ICYmICFyZWZUaC50aFBpbm5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4cGFuZGVkR3JvdXBzW2xdW2ldID0gcGFyZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHJlZlRoID0gaW5mb3MudGhzQ2FjaGVbcGFyZW50XTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqKioqKiBTVEVQIDQ6IENvbXBhdHRvIG5lbGwnZWxlbWVudG8gZmluYWxlIHN1IGN1aSBiaW5kYXJtaS4gTCdJRCBhc3NlZ25hdG8gw6ggU09MTyBwZXIgb3R0aW1penphcmUgZ2xpIG5nRm9yICoqKioqKi9cclxuXHJcbiAgICAgICAgY3VycmVudFBhcmVudCA9IFwiXCI7XHJcbiAgICAgICAgbGV0IGN1cnJlbnRTcGFuID0gMDtcclxuICAgICAgICBsZXQgZmluYWxIZWFkZXJzOiB7IElEOiBzdHJpbmcsIFNwYW46IG51bWJlcjsgVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47IENvbnRlbnQ/OiBzdHJpbmcsIFBpbm5lZD86IGJvb2xlYW47IEJvcmRlcnM/OiBib29sZWFuOyB9W11bXSA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGwgPSAwOyBsIDwgZXhwYW5kZWRHcm91cHMubGVuZ3RoOyBsKyspIHtcclxuICAgICAgICAgICAgbGV0IGxldmVsQXJyYXk6IHsgSUQ6c3RyaW5nLCBTcGFuOiBudW1iZXI7IFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+OyBDb250ZW50Pzogc3RyaW5nLCBQaW5uZWQ/OiBib29sZWFuOyBCb3JkZXJzPzogYm9vbGVhbjsgfVtdID0gW107XHJcbiAgICAgICAgICAgIGZpbmFsSGVhZGVycy5wdXNoKGxldmVsQXJyYXkpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuZXN0LlNlbGVjdGlvbiB8fCB0aGlzLmVzdC5IYXNQaW5uZWRDb2x1bW5zKVxyXG4gICAgICAgICAgICAgICAgbGV2ZWxBcnJheS5wdXNoKHsgSUQ6IFwiX2Jhc2Vfc2VsX3Bpbm5lZFwiLCBTcGFuOiAxLCBUZW1wbGF0ZTogbnVsbCwgUGlubmVkOiB0aGlzLmVzdC5IYXNQaW5uZWRDb2x1bW5zIH0pO1xyXG5cclxuICAgICAgICAgICAgZm9yIChsZXQgaCA9IDA7IGggPCBleHBhbmRlZEdyb3Vwc1tsXS5sZW5ndGg7IGgrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IGl0ZW0gPSBleHBhbmRlZEdyb3Vwc1tsXVtoXTtcclxuICAgICAgICAgICAgICAgIGlmIChpdGVtID09IGN1cnJlbnRQYXJlbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFNwYW4rKztcclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50U3BhbiA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsQXJyYXkucHVzaCh7IElEOiBgJHtjdXJyZW50UGFyZW50ID8gaW5mb3MudGhzQ2FjaGVbY3VycmVudFBhcmVudF0udGggOiAnbm90aCd9XyR7Y3VycmVudFNwYW59YCwgU3BhbjogY3VycmVudFNwYW4sIFRlbXBsYXRlOiBjdXJyZW50UGFyZW50ID8gaW5mb3MudGhzQ2FjaGVbY3VycmVudFBhcmVudF0uVGVtcGxhdGUgOiBudWxsLCBDb250ZW50OiBjdXJyZW50UGFyZW50ID8gaW5mb3MudGhzQ2FjaGVbY3VycmVudFBhcmVudF0uX211bHRpX2NvbnRlbnQgOiBudWxsLCBCb3JkZXJzOiAhIWN1cnJlbnRQYXJlbnQgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFNwYW4gPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRQYXJlbnQgPSBpdGVtO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBVbHRpbWEgYWdnaXVudGEgY2hlIGFsdHJpbWVudGkgbWkgcmltYXJyZWJiZSBpbiBjYWNoZVxyXG4gICAgICAgICAgICBsZXZlbEFycmF5LnB1c2goeyBJRDogYCR7Y3VycmVudFBhcmVudCA/IGluZm9zLnRoc0NhY2hlW2N1cnJlbnRQYXJlbnRdLnRoIDogJ25vdGgnfV8ke2N1cnJlbnRTcGFufWAsIFNwYW46IGN1cnJlbnRTcGFuLCBUZW1wbGF0ZTogY3VycmVudFBhcmVudCA/IGluZm9zLnRoc0NhY2hlW2N1cnJlbnRQYXJlbnRdLlRlbXBsYXRlIDogbnVsbCwgQ29udGVudDogY3VycmVudFBhcmVudCA/IGluZm9zLnRoc0NhY2hlW2N1cnJlbnRQYXJlbnRdLl9tdWx0aV9jb250ZW50IDogbnVsbCAsIEJvcmRlcnM6ICEhY3VycmVudFBhcmVudCB9KTtcclxuXHJcbiAgICAgICAgICAgIC8vIEFnZ2l1bmdvIGkgcGV6emV0dGluaSBwZXIgbGEgcmltb3ppb25lIGUgZ2xpIGV4cG9ydCwgc2UgcHJlc2VudGlcclxuICAgICAgICAgICAgaWYgKHRoaXMuZXN0LlJlbW92YWwpXHJcbiAgICAgICAgICAgICAgICBsZXZlbEFycmF5LnB1c2goeyBJRDogXCJfYmFzZV9yZW1vdmFsXCIsIFNwYW46IDEsIFRlbXBsYXRlOiBudWxsIH0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuZXN0LkV4cG9ydCB8fCB0aGlzLmVzdC5IaWRkZW5Db2x1bW5zIHx8IHRoaXMuZXN0LkNvbHVtbnNPcmRlcmluZyB8fCB0aGlzLmVzdC5Db3JuZXJNZW51T3B0aW9ucylcclxuICAgICAgICAgICAgICAgIGxldmVsQXJyYXkucHVzaCh7IElEOiBcIl9iYXNlX2V4dHJhX29wdHNcIiwgU3BhbjogMSwgVGVtcGxhdGU6IG51bGwgfSk7XHJcblxyXG4gICAgICAgICAgICBjdXJyZW50U3BhbiA9IDA7XHJcbiAgICAgICAgICAgIGN1cnJlbnRQYXJlbnQgPSBcIlwiO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqKioqKiBTVEVQIDU6IFNlY2NvIGxlIHJpZ2hlIGluIGN1aSBub24gYyfDqCBudWxsYSAqKioqKiovXHJcblxyXG4gICAgICAgIHRoaXMuZXN0LlRNUFJvd1RoR3JvdXBzID0gW107XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmluYWxIZWFkZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBsZXZlbCA9IGZpbmFsSGVhZGVyc1tpXTtcclxuICAgICAgICAgICAgbGV0IGVtcHR5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBsZXZlbC5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IGl0ZW0gPSBsZXZlbFtqXTtcclxuICAgICAgICAgICAgICAgIGlmIChpdGVtLlRlbXBsYXRlIHx8IGl0ZW0uQ29udGVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVtcHR5ID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghZW1wdHkpXHJcbiAgICAgICAgICAgICAgICB0aGlzLmVzdC5UTVBSb3dUaEdyb3Vwcy5wdXNoKGxldmVsKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxjb2xhIGlsIG51bWVybyBkaSBzYWx0aSBkYSB1biBoZWFkZXIgZm9nbGlhIGFsbCd1bHRpbW8gcGFyZW50IGRlbGxhIGNhdGVuYVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUaERpcmVjdGl2ZX0gdGggSGVhZGVyIGRhIGN1aSBzY29ycmVyZSBpIHBhZHJpIHBlciBjYXBpcmUgcXVhbnRpIGxpdmVsbGkgY2kgc29ubyBzb3ByYVxyXG4gICAgICogQHBhcmFtIHt7IFtpbmRleDogc3RyaW5nXTogRXNUaERpcmVjdGl2ZSB9fSB0aHNDYWNoZSBDYWNoZSBkZWdsaSBoZWFkZXJcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBqdW1wc1RvRmluYWxQYXJlbnQodGg6IEVzVGhEaXJlY3RpdmUsIHRoc0NhY2hlOiB7IFtpbmRleDogc3RyaW5nXTogRXNUaERpcmVjdGl2ZTsgfSkge1xyXG4gICAgICAgIGxldCBqdW1wcyA9IDA7IGxldCBwYXJlbnQgPSBudWxsOyBsZXQgcGFyZW50c1ByZXBlbmQ6IHsgaWQ6IHN0cmluZywgdG1wbD86IFRlbXBsYXRlUmVmPGFueT4sIGNvbnRlbnQ/OiBzdHJpbmcgfVtdID0gW107XHJcbiAgICAgICAgbGV0IGJhc2VUaFJlZiA9IHRoO1xyXG4gICAgICAgIGRvIHtcclxuICAgICAgICAgICAgcGFyZW50ID0gdGgudGhQYXJlbnQ7XHJcbiAgICAgICAgICAgIGlmIChwYXJlbnQpIHtcclxuICAgICAgICAgICAgICAgIHRoID0gdGhzQ2FjaGVbcGFyZW50XTtcclxuICAgICAgICAgICAgICAgIGlmICghdGgudGhFbXB0eSAmJiAhdGguX211bHRpX2NvbnRlbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50c1ByZXBlbmQudW5zaGlmdCh7IGlkOiB0aC50aCwgdG1wbDogdGguVGVtcGxhdGUgfSk7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghdGgudGhFbXB0eSAmJiB0aC5fbXVsdGlfY29udGVudClcclxuICAgICAgICAgICAgICAgICAgICBwYXJlbnRzUHJlcGVuZC51bnNoaWZ0KHsgaWQ6IHRoLnRoLCBjb250ZW50OiB0aC5fbXVsdGlfY29udGVudCB9KTtcclxuICAgICAgICAgICAgICAgIGp1bXBzKys7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IHdoaWxlIChwYXJlbnQpO1xyXG4gICAgICAgIGJhc2VUaFJlZi5fdGhQYXJlbnRzID0gcGFyZW50c1ByZXBlbmQ7XHJcbiAgICAgICAgcmV0dXJuIGp1bXBzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGNoZSBnZW5lcmEgbCdvcmRpbmUgZGkgZGVmYXVsdCBkZWxsZSBjb2xvbm5lXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtBcHBTZWFyY2g8YW55Pn0gdmlldyBBcHBTZWFyY2ggZGEgdXRpbGl6emFyZSBwZXIgcXVlc3RhIG9wZXJhemlvbmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGdlbmVyYXRlRGVmYXVsdE9yZGVyKHRoczogRXNUaERpcmVjdGl2ZVtdLCB2aWV3OiBBcHBTZWFyY2g8YW55Pikge1xyXG4gICAgICAgIGlmICh0aHMubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBGaXggb3JkaW5hbWVudGkgcGVyIGNvbG9ubmUgc3Bhcml0ZSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuICAgICAgICAvLyBDb25zaWRlcm8gc29sbyBnbGkgb3JkaW5hbWVudGkgcGVyIGNvbG9ubmUgZWZmZXR0aXZhbWVudGUgcHJlc2VudGkgYWxsJ2ludGVybm8gZGVsbGEgdGFiZWxsYVxyXG4gICAgICAgIGlmICh0aGlzLmVzdC52aWV3TW9kZSlcclxuICAgICAgICAgICAgdmlldy5jb2x1bW5fb3JkZXJpbmcgPSB2aWV3LmNvbHVtbl9vcmRlcmluZy5maWx0ZXIob3JkID0+IHRocy5maW5kKHQgPT4gdC50aCA9PSBvcmQpKTtcclxuICAgICAgICAvLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIEZpeCBvcmRpbmFtZW50aSBwZXIgY29sb25uZSBzcGFyaXRlICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG5cclxuICAgICAgICBsZXQgb3JkZXJpbmdzID0gdGhpcy5lc3Qudmlld01vZGUgPyB2aWV3LmNvbHVtbl9vcmRlcmluZyA6IHRoaXMuZXN0LmFycmF5Q29sdW1uT3JkZXJpbmc7XHJcblxyXG4gICAgICAgIC8vIEdlbmVybyBvcmRpbmFtZW50byBkaSBkZWZhdWx0IGRhIDAgZmlubyBhIGRvdmUgZGV2ZSBhcnJpdmFyZS4gU2l0dWF6aW9uZSBhdHR1YWxlIHNlbnphIGhvdHBvdGF0b1xyXG4gICAgICAgIGlmICghb3JkZXJpbmdzIHx8IG9yZGVyaW5ncy5sZW5ndGggPT0gMCkge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG4gICAgICAgICAgICAgICAgbGV0IG9yZGVyID0gdGgudGg7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVzdC5PcmRlckRpcmVjdGl2ZXMucHVzaChvcmRlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcyA9IG9yZGVyaW5ncztcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuICAgICAgICAgICAgICAgIGxldCB0aElkID0gdGgudGg7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcy5maW5kKG8gPT4gbyA9PSB0aElkKSlcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVzdC5PcmRlckRpcmVjdGl2ZXMucHVzaCh0aElkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGxpY2EgbCdvcmRpbmUgc3BlY2lmaWNhdG8gYWxsZSB2YXJpZSBjb2xvbm5lXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtBcHBTZWFyY2g8YW55Pn0gdmlldyBBcHBTZWFyY2ggZGEgdXRpbGl6emFyZSBwZXIgcXVlc3RhIG9wZXJhemlvbmVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZmluYWxpemUgU2UgKip0cnVlKiogc2lnbmlmaWNhIGNoZSBub24gbWkgYXNwZXR0byBkaSBkb3ZlciBlZmZldHR1YXJlIGFsdHJlIG9wZXJhemlvbmkgZSBwb3NzbyByZW5kZXJpenphcmUgbGEgc2l0dWF6aW9uZSBpbiBiYXNlIGFpIFJvd0NvbnRleHRcclxuICAgICAqIFNlbnphIGZpbmFsaXplIHNpZ25pZmljYSBjaGUgbWkgYXNwZXR0byBhbHRyZSBvcGVyYXppb25pIGNoZSBwcmltYSBvIHBvaSByaWNoaWFtZXJhbm5vIHF1ZXN0YSBmdW56aW9uZSBjb2wgZmluYWxpemUuXHJcbiAgICAgKlxyXG4gICAgICogQWQgZXNlbXBpbywgdW5hIHZvbHRhIHNlbGV6aW9uYXRvIG9yZGluYW1lbnRvIGZpc2ljby9sb2dpY28gZGVsbGUgY29sb25uZSBzbyBjaGUgcGFydGUgdW4gYWx0cmEgcmljZXJjYSBjaGUgbWkgcml2YWxvcml6emVyw6AgZGEgXCJ3cml0ZVZhbHVlXCIsIGNoZSBnacOgIGNoaWFtYSBxdWVzdGEgZnVuemlvbmUuXHJcbiAgICAgKiBNZXR0ZW5kbyBzb2xvIGxhIGNoaWFtYXRhIGRhIFwid3JpdGVWYWx1ZVwiIGNvbWUgXCJmaW5hbGl6emFudGVcIiBtaSBhc3NpY3VybyBjaGUgc21hbmF0dGFtZW50aSBhIGZyb250ZW5kIG5vbiBjYXVzaW5vIGZsaWNrZXJpbmcgZmlubyBhIHF1YW5kbyBub24gc2Vydm9ub1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXBwbHlPcmRlcmluZyh2aWV3OiBBcHBTZWFyY2g8YW55PiwgZmluYWxpemU6IGJvb2xlYW4pIHtcclxuICAgICAgICAvLyBHZW5lcm8gb3JkaW5hbWVudG8gcGVyIGdsaSBoZWFkZXJcclxuICAgICAgICBsZXQgbmV3SGVhZGVycyA9IFtdO1xyXG5cclxuICAgICAgICAvLyBTZSBkZXZvIGZpbmFsaXp6YXJlIGFnZ2FuY2lvIHR1dHRlIGxlIHZhcmlhYmlsaSBkaSBiaW5kXHJcbiAgICAgICAgaWYgKGZpbmFsaXplKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcy5mb3JFYWNoKG8gPT4ge1xyXG4gICAgICAgICAgICAgICAgbGV0IGhlYWVkckl0ZW0gPSB0aGlzLmVzdC5UTVBSb3dUSHMuZmlsdGVyKHQgPT4gdC5JRCA9PSBvKVswXTtcclxuICAgICAgICAgICAgICAgIGlmIChoZWFlZHJJdGVtKVxyXG4gICAgICAgICAgICAgICAgICAgIG5ld0hlYWRlcnMucHVzaChoZWFlZHJJdGVtKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuZXN0LlRNUFJvd1RIcyA9IG5ld0hlYWRlcnM7XHJcblxyXG4gICAgICAgICAgICAvLyBHZW5lcm8gb3JkaW5hbWVudG8gcGVyIGxlIGNlbGxlXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5lc3QuUm93Q29udGV4dHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCBjb250ZXh0ID0gdGhpcy5lc3QuVE1QUm93VERzW3RoaXMuZXN0LlJvd0NvbnRleHRzW2ldXTtcclxuICAgICAgICAgICAgICAgIGxldCBuZXdDb250ZXh0ID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5lc3QuT3JkZXJEaXJlY3RpdmVzLmZvckVhY2gobyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbnRleHRJdGVtID0gY29udGV4dC5maWx0ZXIodCA9PiB0LklEID09IG8pWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHBvdHJlYmJlIGVzc2VyIHVuZGVmaW5lZCBuZWwgY2FzbyBjaSBmb3NzZXJvIGNvbG9ubmUgc290dG8gdGhJZlxyXG4gICAgICAgICAgICAgICAgICAgIGlmKGNvbnRleHRJdGVtKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdDb250ZXh0LnB1c2goY29udGV4dEl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5lc3QuVE1QUm93VERzW3RoaXMuZXN0LlJvd0NvbnRleHRzW2ldXSA9IG5ld0NvbnRleHQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmVzdC52aWV3TW9kZSlcclxuICAgICAgICAgICAgdmlldy5jb2x1bW5fb3JkZXJpbmcgPSB0aGlzLmVzdC5PcmRlckRpcmVjdGl2ZXM7XHJcblxyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgdGhpcy5lc3QuYXJyYXlDb2x1bW5PcmRlcmluZyA9IHRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcztcclxuXHJcbiAgICAgICAgdGhpcy5lc3QuY2hhbmdlZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICogQWxsJ2ludGVybm8gZGVsbGEgZGlhbG9nIFwiT3JkaW5hbWVudG8gZSBWaXNpYmlsaXTDoCBDb2xvbm5lXCIgbWV0dGUgbGEgY29sb25uYSBzcGVjaWZpY2F0YSBwcmltYSBkZWxsYSBjb2xvbm5hIHByZWNlZGVudGVcclxuICAqXHJcbiAgKiBAcGFyYW0ge0VzVGFibGVDb2x1bW59IGNvbHVtbkl0ZW0gQ29sb25uYSBkYSBzcG9zdGFyZVxyXG4gICovXHJcbiAgICBwdWJsaWMgc2VuZFVwKGNvbHVtbkl0ZW06IEVzVGFibGVDb2x1bW4pIHtcclxuICAgICAgICBsZXQgaXRlbUluZGV4ID0gdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QuaW5kZXhPZihjb2x1bW5JdGVtKTtcclxuICAgICAgICBpZiAodGhpcy5lc3QuVE1QQ29sdW1uc0xpc3RbaXRlbUluZGV4IC0gMV0uZml4ZWQgfHwgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3RbaXRlbUluZGV4IC0gMV0ucGlubmVkKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgdGhpcy51dGlFeHRzLnN3YXAodGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QsIGl0ZW1JbmRleCwgaXRlbUluZGV4IC0gMSk7XHJcblxyXG4gICAgICAgIC8vIE5vbiBwb3NzbyBmYXJlIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5Db2x1bW5zTGlzdCkpIHBlcmNow6kgY29udGllbmUgcmlmZXJpbWVudGkgYSBUZW1wbGF0ZVJlZlxyXG4gICAgICAgIGxldCB0bXAgPSBbXTtcclxuICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4geyB0bXAucHVzaChPYmplY3QuYXNzaWduKHt9LCBjKSk7IH0pO1xyXG4gICAgICAgIHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0ID0gdG1wO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsJ2ludGVybm8gZGVsbGEgZGlhbG9nIFwiT3JkaW5hbWVudG8gZSBWaXNpYmlsaXTDoCBDb2xvbm5lXCIgbWV0dGUgbGEgY29sb25uYSBzcGVjaWZpY2F0YSBkb3BvIGxhIGNvbG9ubmEgc3VjY2Vzc2l2YVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUYWJsZUNvbHVtbn0gY29sdW1uSXRlbSBDb2xvbm5hIGRhIHNwb3N0YXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZW5kRG93bihjb2x1bW5JdGVtOiBFc1RhYmxlQ29sdW1uKSB7XHJcbiAgICAgICAgbGV0IGl0ZW1JbmRleCA9IHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LmluZGV4T2YoY29sdW1uSXRlbSk7XHJcbiAgICAgICAgdGhpcy51dGlFeHRzLnN3YXAodGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QsIGl0ZW1JbmRleCwgaXRlbUluZGV4ICsgMSk7XHJcblxyXG4gICAgICAgIC8vIE5vbiBwb3NzbyBmYXJlIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5Db2x1bW5zTGlzdCkpIHBlcmNow6kgY29udGllbmUgcmlmZXJpbWVudGkgYSBUZW1wbGF0ZVJlZlxyXG4gICAgICAgIGxldCB0bXAgPSBbXTtcclxuICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4geyB0bXAucHVzaChPYmplY3QuYXNzaWduKHt9LCBjKSk7IH0pO1xyXG4gICAgICAgIHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0ID0gdG1wO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsJ2ludGVybm8gZGVsbGEgZGlhbG9nIFwiT3JkaW5hbWVudG8gZSBWaXNpYmlsaXTDoCBDb2xvbm5lXCIgcGlubmEgbGEgY29sb25uYSBzcGVjaWZpY2F0YVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUYWJsZUNvbHVtbn0gY29sdW1uSXRlbSBDb2xvbm5hIGRhIHNwb3N0YXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBwaW5PclVucGluQ29sdW1uKGNvbHVtbkl0ZW06IEVzVGFibGVDb2x1bW4pIHtcclxuICAgICAgICBsZXQgaXRlbUluZGV4ID0gdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QuaW5kZXhPZihjb2x1bW5JdGVtKTtcclxuICAgICAgICBpZiAoIWNvbHVtbkl0ZW0ucGlubmVkKSB7XHJcbiAgICAgICAgICAgIGNvbHVtbkl0ZW0ucHJldl9pbmRleCA9IGl0ZW1JbmRleDtcclxuXHJcbiAgICAgICAgICAgIC8vUXVhbmRvIHBpbm5vIGRldm8gc3Bvc3RhcmUgbCdlbGVtZW50byBjb21lIHVsdGltYSBjb2xvbm5hIHBpbm5hdGEgbyBjb21lIHByaW1hIGNvbG9ubmEgc2Ugbm9uIGNlIG5lIHNvbm8gZGkgcGlubmF0ZVxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZXN0LlRNUENvbHVtbnNMaXN0W2ldLnBpbm5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbGl0aWVzLmFycmF5TW92ZSh0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdCwgaXRlbUluZGV4LCBpKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy9RdWFuZG8gc3Bpbm5vIHJpcG9ydG8gbCdlbGVtZW50byBhbGxvIHN0ZXNzbyBpbmRpY2UgaW4gY3VpIGVyYSBwcmltYSAoc2Ugc29ubyBzdGF0aSBmYXR0aSBzcG9zdGFtZW50aSBuZWwgbWV6em8gY2F6emkgZGVsbCd1dGVudGUpXHJcbiAgICAgICAgICAgIGlmIChjb2x1bW5JdGVtLnByZXZfaW5kZXggIT0gbnVsbCAmJiBjb2x1bW5JdGVtLnByZXZfaW5kZXggIT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICAgICAgdGhpcy51dGlsaXRpZXMuYXJyYXlNb3ZlKHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LCBpdGVtSW5kZXgsIGNvbHVtbkl0ZW0ucHJldl9pbmRleCk7XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gU2Ugc3Bpbm5vIHNlbnphIHVuIHByZXZfaW5kZXggdnVvbCBkaXJlIGNoZSBsYSBjb2xvbm5hIGVyYSBwaW5uYXRhIGRhIGNvbmZpZ3VyYXppb25lLiBMYSBzcG9zdG8gbmVsIHByaW1vIHB1bnRvIGRpc3BvbmliaWxlXHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdFtpXS5waW5uZWQgJiYgIXRoaXMuZXN0LlRNUENvbHVtbnNMaXN0W2ldLmZpeGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbGl0aWVzLmFycmF5TW92ZSh0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdCwgaXRlbUluZGV4LCBpIC0gMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29sdW1uSXRlbS5waW5uZWQgPSAhY29sdW1uSXRlbS5waW5uZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGwnaW50ZXJubyBkZWxsYSBkaWFsb2cgXCJPcmRpbmFtZW50byBlIFZpc2liaWxpdMOgIENvbG9ubmVcIiBpbnZlcnRlIGxlIGltcG9zdGF6aW9uaSBkaSB2aXNpYmlsaXTDoCBkZWxsYSBjb2xvbm5hXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RhYmxlQ29sdW1ufSBjb2x1bW5JdGVtIENvbG9ubmEgZGEgc3Bvc3RhcmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvbHVtbkNsaWNrZWQoaXRlbTogRXNUYWJsZUNvbHVtbikge1xyXG4gICAgICAgIHRoaXMuZXN0Lmxhc3RTZWxlY3RlZEl0ZW1JRCA9IGl0ZW0uaWQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLmVzdC5IaWRkZW5Db2x1bW5zIHx8IGl0ZW0uZml4ZWQpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgaXRlbS52aXNpYmxlID0gIWl0ZW0udmlzaWJsZTtcclxuICAgICAgICB0aGlzLnVwZGF0ZUdsb2JhbENvbFZpc0NoZWNrKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEFsbCdhcGVydHVyYSBkZWxsYSBkaWFsb2cgXCJPcmRpbmFtZW50byBlIFZpc2liaWxpdMOgIENvbG9ubmVcIiByaWNhcmljYSBsZSBpbmZvcm1hemlvbmkgYXR0dWFsaSBwZXIgcGVybWV0dGVyZSBsYSBtb2RpZmljYSAqL1xyXG4gICAgcHVibGljIHJlc2V0Q29sdW1uVmlzU2VsZWN0aW9uKCkge1xyXG4gICAgICAgIHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0ID0gW107XHJcbiAgICAgICAgLy8gTm9uIHBvc3NvIGZhcmUgSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLkNvbHVtbnNMaXN0KSkgcGVyY2jDqSBjb250aWVuZSByaWZlcmltZW50aSBhIFRlbXBsYXRlUmVmXHJcbiAgICAgICAgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QgPSBbXTtcclxuICAgICAgICB0aGlzLmVzdC5Db2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4geyB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5wdXNoKE9iamVjdC5hc3NpZ24oe30sIGMpKTsgfSk7XHJcblxyXG4gICAgICAgIGxldCByZW9yZGVyZWRDb2xMaXN0ID0gW107XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmVzdC5Db2x1bW5zT3JkZXJpbmcpIHtcclxuICAgICAgICAgICAgdGhpcy5lc3QuT3JkZXJEaXJlY3RpdmVzLmZvckVhY2gobyA9PiB7XHJcbiAgICAgICAgICAgICAgICBsZXQgY29sdW1uID0gdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QuZmlsdGVyKHQgPT4gdC5pZCA9PSBvKVswXTtcclxuICAgICAgICAgICAgICAgIC8vIFBvdHJlaSBub24gYXZlcm5lIG5lbCBjYXNvIGNpIHNpYSBpbCBmbGFnIEhpZGRlbkNvbHVtbnMgYSBmYWxzZSwgZXZpdG8gZGkgaW5zZXJpcmUgZGVnbGkgdW5kZWZpbmVkXHJcbiAgICAgICAgICAgICAgICBpZiAoY29sdW1uKVxyXG4gICAgICAgICAgICAgICAgICAgIHJlb3JkZXJlZENvbExpc3QucHVzaChjb2x1bW4pO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0ID0gcmVvcmRlcmVkQ29sTGlzdDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlR2xvYmFsQ29sVmlzQ2hlY2soKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogUmlhZ2dpb3JuYSBsZSAqKk9yZGVyRGlyZWN0aXZlcyoqIGNvbiBsZSBpbmZvcm1hemlvbmkgaW4gICoqQ29sdW1uc0xpc3QqKiAqL1xyXG4gICAgcHJpdmF0ZSByZWZyZXNoQ29sdW1uT3JkZXJpbmcoKSB7XHJcbiAgICAgICAgdGhpcy5lc3QuT3JkZXJEaXJlY3RpdmVzID0gW107XHJcblxyXG4gICAgICAgIGZvciAobGV0IGMgPSAwOyBjIDwgdGhpcy5lc3QuQ29sdW1uc0xpc3QubGVuZ3RoOyBjKyspXHJcbiAgICAgICAgICAgIHRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcy5wdXNoKHRoaXMuZXN0LkNvbHVtbnNMaXN0W2NdLmlkKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogRWZmZXR0dWEgbGEgc2VsZXppb25lIG8gbWVubyBkZWwgY2hlY2sgZ2xvYmFsZSAoKipnbG9iYWxDb2xWaXNDaGVjayoqKSBkaSB2aXNpYmlsaXTDoCBpbiBiYXNlIGEgc2UgdHV0dGUgbGUgKipUTVBDb2x1bW5zTGlzdCoqIHNvbm8gdmlzaWJpbGkgbyBubyAqL1xyXG4gICAgcHVibGljIHVwZGF0ZUdsb2JhbENvbFZpc0NoZWNrKCkge1xyXG4gICAgICAgIC8vIFRNUENvbExpc3QgdmllbmUgcmllbXBpdGEgZGkgdW5kZWZpbmVkIG5lbCBjYXNvIGluIGN1aSBzaWEgZGlzYXR0aXZhdGEgbGEgc2VsZXppb25lIGRlbGxlIGNvbG9ubmUgbmFzY29zdGVcclxuICAgICAgICB0aGlzLmVzdC5nbG9iYWxDb2xWaXNDaGVjayA9IHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LmV2ZXJ5KHQgPT4gdC52aXNpYmxlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENoaWFtYXRvIHF1YW5kbyB1bmEgY29sb25uYSB2aWVuZSByaW9yZGluYXRhIGFsbCdpbnRlcm5vIGRlbGxhIGxpc3RhIGRlbGxlIHZpc2liaWxpdMOgL3Bvc2l6aW9uaSBjb2xvbm5lXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7Q2RrRHJhZ0Ryb3A8RXNUYWJsZUNvbHVtbltdPn0gZXZlbnQgRXZlbnRvIGRpIGRyb3AgZGVsbGEgbGlzdGFcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvbHVtblJlb3JkZXJlZChldmVudDogQ2RrRHJhZ0Ryb3A8RXNUYWJsZUNvbHVtbltdPikge1xyXG4gICAgICAgIG1vdmVJdGVtSW5BcnJheShldmVudC5jb250YWluZXIuZGF0YSwgZXZlbnQucHJldmlvdXNJbmRleCwgZXZlbnQuY3VycmVudEluZGV4KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENoaWFtYXRvIHF1YW5kbyB1bmEgY29sb25uYSB2aWVuZSByaW9yZGluYXRhIGFsbCdpbnRlcm5vIGRlbGxhIGxpc3RhIGRlbGxlIHZpc2liaWxpdMOgL3Bvc2l6aW9uaSBjb2xvbm5lXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBJbmRpY2UgaW4gY3VpIHZvZ2xpbyBkcm9wcGFyZSBsJ2VsZW1lbnRvIGRyYWdnYXRvXHJcbiAgICAgKiBAcGFyYW0ge0Nka0RyYWc8RXNUYWJsZUNvbHVtbj59IGl0ZW0gT2dnZXR0byBjaGUgc3RvIGRyYWdnYW5kb1xyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gKip0cnVlKiogc2UgbGEgY29sb25uYSBwdcOyIGVzc2VyZSBzcG9zdGF0YSBzdWxsJ2luZGljZSAqKmluZGV4KiosICoqZmFsc2UqKiBhbHRyaW1lbnRpXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzb3J0UHJlZGljYXRlKGluZGV4OiBudW1iZXIsIGl0ZW06IENka0RyYWc8RXNUYWJsZUNvbHVtbj4pOiBib29sZWFuIHtcclxuICAgICAgICBsZXQgaXRlbUF0SW5kZXggPSB0aGlzLmVzdC5Db2x1bW5zTGlzdFtpbmRleF07XHJcbiAgICAgICAgcmV0dXJuICFpdGVtQXRJbmRleC5maXhlZCAmJiAhaXRlbUF0SW5kZXgucGlubmVkICYmICFpdGVtLmRhdGEucGlubmVkICYmICFpdGVtLmRhdGEucGlubmVkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRnVuemlvbmUgY2hlIGVmZmV0dHVhIGxhIGNvbmZlcm1hIGRlbGxhIHZpc2liaWxpdMOgIGUgZGVsbCdvcmRpbmUgZGVsbGUgY29sb25uZS5cclxuICAgICAqXHJcbiAgICAgKiBRdWVzdGEgc2VsZXppb25lIHZpZW5lIGlub2x0cmUgc2FsdmF0YSBuZWxsZSBwcmVmZXJlbnplICgqKkBlc2ZhZW56YS9wcmVmZXJlbmNlcyoqKSwgcXVhbG9yYSBsJ0lucHV0ICoqU2F2ZVByZWZlcmVuY2VzKiogZm9zc2UgdmFsb3JpenphdG9cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gKip0cnVlKiogc2Ugbm9uIGNpIHNvbm8gcHJvYmxlbWksICoqZmFsc2UqKiBhbHRyaW1lbnRpXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb25maXJtQ29sdW1uVmlzaWJpbGl0eVNlbGVjdGlvbigpOiBib29sZWFuIHtcclxuICAgICAgICAvLyBOb24gcGVybWV0dG8gZGkgbm9uIHNlbGV6aW9uYXJlIG51bGxhXHJcbiAgICAgICAgaWYgKHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LmV2ZXJ5KHQgPT4gIXQudmlzaWJsZSkpXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgbGV0IGNhc3RlZFZpZXcgPSB0aGlzLmVzdC52aWV3TW9kZSA/ICh0aGlzLmVzdC5NYWluR3JvdXBWaWV3IHx8IHRoaXMuZXN0LlZpZXcgYXMgQXBwU2VhcmNoPGFueT4pIDogbnVsbDtcclxuICAgICAgICB0aGlzLmVzdC5Db2x1bW5zTGlzdCA9IFtdO1xyXG4gICAgICAgIHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LmZvckVhY2goYyA9PiB7IHRoaXMuZXN0LkNvbHVtbnNMaXN0LnB1c2goT2JqZWN0LmFzc2lnbih7fSwgYykpOyB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5yZWZyZXNoQ29sdW1uT3JkZXJpbmcoKTtcclxuICAgICAgICB0aGlzLmFwcGx5T3JkZXJpbmcoY2FzdGVkVmlldywgZmFsc2UpO1xyXG5cclxuICAgICAgICB0aGlzLnJlZnJlc2hDb2x1bW5zVmlzaWJpbGl0eShudWxsLCBudWxsLCBjYXN0ZWRWaWV3KTtcclxuXHJcbiAgICAgICAgLy9TYWx2byBsZSBwcmVmZXJlbmNlcyBkaSBxdWVzdGEgdmlld1xyXG4gICAgICAgIC8vRGkgZGVmYXVsdCByZWdpc3RybyBvcmRpbmFtZW50byBlIHZpc2liaWxpdMOgIGRlbGxlIGNvbG9ubmUgbmVsbGEgdmlzdGEuIFNvbG8gbGUgY29zZSBkaSBVSVxyXG4gICAgICAgIGlmICh0aGlzLmVzdC5TYXZlUHJlZmVyZW5jZXMpIFxyXG4gICAgICAgICAgICB0aGlzLnJlZ2lzdGVyVmlld1ByZWZlcmVuY2VzKGNhc3RlZFZpZXcpO1xyXG5cclxuICAgICAgICAvLyBSaWVzZWd1byBsJ3VsdGltYSByaWNlcmNhIGJpbmRhdGEgYWxsYSB0YWJlbGxhXHJcbiAgICAgICAgLy8gTWkgYXNzaWN1cm8gZGkgZmFybG8gZG9wbyBsJ2VzcGFuc2lvbmUgZGVsIGNoYW5nZWQgbyByaXNjaGlvIGNoZSBsYSByaWNlcmNhIG1pIHJpZGlhIGNvbG9ubmUgY2hlIGluIHJlYWx0w6Agbm9uIGVzaXN0b25vXHJcbiAgICAgICAgaWYgKHRoaXMuZXN0LnZpZXdNb2RlKVxyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmVzdC5NYWluR3JvdXBWaWV3KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy90aGlzLmVtaXRTZWFyY2hSZXF1ZXN0KHRydWUsIHRoaXMuTWFpbkdyb3VwVmlldyk7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmVzdC5ncm91cFNlYXJjaFJlcXVlc3RzQ2FjaGUubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHZpZXcgPSB0aGlzLmVzdC5ncm91cFNlYXJjaFJlcXVlc3RzQ2FjaGVbaV0udmlldztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmlldy5jb2x1bW5zID0gdGhpcy5lc3QuTWFpbkdyb3VwVmlldy5jb2x1bW5zO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWV3LmNvbHVtbl9vcmRlcmluZyA9IHRoaXMuZXN0Lk1haW5Hcm91cFZpZXcuY29sdW1uX29yZGVyaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVzdC5lbWl0U2VhcmNoUmVxdWVzdCh0cnVlLCB0aGlzLmVzdC5ncm91cFNlYXJjaFJlcXVlc3RzQ2FjaGVbaV0udmlldyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVzdC5lbWl0U2VhcmNoUmVxdWVzdCh0cnVlKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5lc3QuYXJyYXlNb2RlKVxyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgdGhpcy5lc3QuaW50ZXJuYWxXcml0ZVZhbHVlKCk7IH0pO1xyXG5cclxuICAgICAgICAvLyBMbyB2b3JyZWkgbWV0dGVyZSBsYXRvIHRlbXBsYXRlIG1hIG5vXHJcbiAgICAgICAgdGhpcy5lc3QubGFzdFNlbGVjdGVkSXRlbUlEID0gbnVsbDtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEVmZmV0dHVvIGwndW5waW5uaW5nIGRpIHVuYSBjb2xvbm5hIGluIG1hbmllcmEgcHJvZ3JhbW1hdGljYSBzZW1wbGljZW1lbnRlIGVzZWd1ZW5kbyB1bmEgcGVyIHVuYSBsZSBvcGVyYXppb25pIGNoZSB2ZXJyZWJiZXJvIGVzZWd1aXRlIGFsdHJpbWVudGlcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgQ29kaWNlIGRlbGxhIGNvbG9ubmEgZGEgc3Bpbm5hcmVcclxuICAgICAqL1xyXG4gICAgcHVibGljIHVucGluQ29sdW1uKGlkOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLnJlc2V0Q29sdW1uVmlzU2VsZWN0aW9uKCk7XHJcbiAgICAgICAgdGhpcy5waW5PclVucGluQ29sdW1uKHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LmZpbmQodCA9PiB0LmlkID09IGlkKSk7XHJcbiAgICAgICAgdGhpcy5jb25maXJtQ29sdW1uVmlzaWJpbGl0eVNlbGVjdGlvbigpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBTdWwgY2xpY2sgbmVsbGEgY2hlY2tib3ggZGkgc2VsZXppb25lIGdsb2JhbGUgc2kgc2NvcnJvbm8gdHV0dGUgbGUgY29sb25uZSBlIHNpIGltcG9zdGFubyBhbCB2YWxvcmUgZGVsbGEgY2hlY2sgZ2xvYmFsZSAqL1xyXG4gICAgcHVibGljIGdsb2JhbENvbFZpc0NoZWNrQ2hhbmdlZCgpIHtcclxuICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5mb3JFYWNoKHQgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIXQuZml4ZWQpXHJcbiAgICAgICAgICAgICAgICB0LnZpc2libGUgPSB0aGlzLmVzdC5nbG9iYWxDb2xWaXNDaGVjaztcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG4iXX0=
1
+ // Angular
2
+ import { moveItemInArray } from "@angular/cdk/drag-drop";
3
+ import { EsTdDirective } from "../../directives/es_td.directive";
4
+ import { EsThDirective } from "../../directives/es_th.directive";
5
+ // Modelli
6
+ import { AppOrdering } from "../../domain/externals/appsearch/AppOrdering";
7
+ import { EsTableColumn } from "../../domain/internals/EsTableColumn";
8
+ /** Classe che gestisce tutte le informaizoni relative alle colonne: visibilità, posizione, stato di pin/unpin, ecc ecc... */
9
+ export class ColumnMetadataHandler {
10
+ /** @ignore Costruttore*/
11
+ constructor(est, utilities, utiExts, prefService, rgH) {
12
+ this.est = est;
13
+ this.utilities = utilities;
14
+ this.utiExts = utiExts;
15
+ this.prefService = prefService;
16
+ this.rgH = rgH;
17
+ }
18
+ /**
19
+ * Metodo che gestisce il cambio di Ordinamento di una colonna
20
+ *
21
+ * @param {string} id ID della colonna il cui oridnamento è cambiato
22
+ * @param {'DESC' | 'ASC'} order Nuovo ordine selezionato per la colonna
23
+ */
24
+ handleTHOrderChange(id, order) {
25
+ let orders = this.est.viewMode ? this.est.View.orders : this.est.arrayOrders;
26
+ let orderToAdd = true;
27
+ let orderToRemove = null;
28
+ // Se per qualche motivo il costruttore non è passato (cache tarpate o simila) fixo
29
+ if (!orders && this.est.viewMode)
30
+ this.est.View.orders = [];
31
+ else if (!orders && this.est.arrayMode)
32
+ this.est.arrayOrders = [];
33
+ for (let i = 0; i < orders.length; i++) {
34
+ let t = orders[i];
35
+ if (t.id == id) {
36
+ if (order) {
37
+ t.order = order;
38
+ orderToAdd = false;
39
+ }
40
+ else
41
+ orderToRemove = i;
42
+ }
43
+ }
44
+ if (orderToRemove != null) {
45
+ orders.splice(orderToRemove, 1);
46
+ }
47
+ else if (orderToAdd) {
48
+ if (this.est.MultipleOrderingDirectives)
49
+ orders.push(new AppOrdering(id, order));
50
+ else {
51
+ if (this.est.viewMode)
52
+ this.est.View.orders = [new AppOrdering(id, order)];
53
+ else if (this.est.arrayMode)
54
+ this.est.arrayOrders = [new AppOrdering(id, order)];
55
+ }
56
+ }
57
+ //Salvo le preferences di questa view
58
+ //Di default registro ordinamento e visibilità delle colonne nella vista. Solo le cose di UI
59
+ if (this.est.SavePreferences) {
60
+ let castedView = this.est.viewMode ? (this.est.MainGroupView || this.est.View) : null;
61
+ this.registerViewPreferences(castedView);
62
+ }
63
+ this.est.onOrderChanged.emit({ id, order });
64
+ if (this.est.viewMode) {
65
+ if (this.est.groupSearchRequestsCache.length > 0)
66
+ this.rgH.emitRowGroupingSearches(id, orders);
67
+ else
68
+ this.est.emitSearchRequest(false);
69
+ }
70
+ else if (this.est.arrayMode)
71
+ this.est.internalWriteValue();
72
+ }
73
+ /**
74
+ * Registra le preference relative alla view passata come parametro
75
+ *
76
+ * @param {any} castedView View di cui salvare colonne e ordinamento colonne
77
+ */
78
+ registerViewPreferences(castedView) {
79
+ if (!this.est.ngControl.name) {
80
+ console.error("Non posso utilizzare le preference senza avere un 'name' per la tabella");
81
+ return false;
82
+ }
83
+ if (!this.prefService) {
84
+ console.error("Non posso utilizzare le preference senza che il pacchetto @esfaenza/preferences sia installato");
85
+ return false;
86
+ }
87
+ let columns = this.est.arrayMode ? this.est.arrayColumns : castedView.columns;
88
+ let columnsOrderings = this.est.arrayMode ? this.est.arrayColumnOrdering : castedView.column_ordering;
89
+ let columnOrders = this.est.arrayMode ? [] : castedView.orders;
90
+ var toStore = {
91
+ columns: this.utiExts.deepClone(columns),
92
+ column_ordering: this.utiExts.deepClone(columnsOrderings),
93
+ orders: this.utiExts.deepClone(columnOrders)
94
+ };
95
+ this.prefService.setItem(this.est.ngControl.name, toStore).subscribe();
96
+ }
97
+ /**
98
+ * Partendo dagli **EsThs** estrappolo la lista di **EsTableColumn** che questa tabella dovrà eventualmente gestire per Visibilità e Ordine
99
+ *
100
+ * Costo: 1 scan EsThs
101
+ *
102
+ * @param {EsThDirective[]} ths Colonne della tabella
103
+ */
104
+ reviewColumnsList(ths) {
105
+ this.est.TMPColumnsList = [];
106
+ if (ths.length == 0)
107
+ return;
108
+ // Appena il contentChildren è valorizzato scorro tutti gli header
109
+ for (let i = 0; i < ths.length; i++) {
110
+ let th = ths[i];
111
+ let column = th.th;
112
+ // Se non ho un id il th è considerato inerte
113
+ if (!column)
114
+ continue;
115
+ // Salvo le informazioni dell'header per far parte della lista da cui scegliere quali colonne visualizzare/nascondere
116
+ // Di default la visibilità è quella impostata nel componente
117
+ if ((this.est.HiddenColumns || th.thVisible) && th.thIf) {
118
+ let previouslyPinned = !this.est.ColumnsList || this.est.ColumnsList.length == 0 ? null : this.est.ColumnsList.find(t => t.id == column) || null;
119
+ let toAdd = new EsTableColumn(column, th.thStaticContent, th.thVisible, (th.thFixed || th.thGroup), previouslyPinned == null ? th.thPinned : previouslyPinned.pinned, th.thPinnable, th.thPinnedWidth, th.Template, th._thParents, th._multi, th._multi_content);
120
+ if (previouslyPinned)
121
+ toAdd.prev_index = previouslyPinned.prev_index;
122
+ this.est.TMPColumnsList.push(toAdd);
123
+ }
124
+ }
125
+ this.est.ColumnsList = [];
126
+ this.est.TMPColumnsList.forEach(c => { this.est.ColumnsList.push(Object.assign({}, c)); });
127
+ }
128
+ /** In caso siano configurati dei th "Multi" (vedere la descrizione del campo **thMulti** di **EsThDirective**) questo metodo li "srotola" in tutti i th/td che devono effettivamente diventare */
129
+ expandMultiThsAndTds(ths, tds, items) {
130
+ // Registro le info sui multiprovider
131
+ let multiDefs = {};
132
+ for (let i = 0; i < ths.length; i++) {
133
+ let th = ths[i];
134
+ if (!th.thMulti)
135
+ continue;
136
+ multiDefs[th.th] = { On: th.th, tdref: null, thref: th, thgen: {}, tdgen: {} };
137
+ }
138
+ // Assegno le info anche ai td
139
+ for (let i = 0; i < tds.length; i++) {
140
+ let td = tds[i];
141
+ td._multi = !!multiDefs[td.td];
142
+ if (td._multi)
143
+ multiDefs[td.td].tdref = td;
144
+ }
145
+ // Rimuovo i multitemplate dalle balle
146
+ // N.B: Dato che la prima operazione su th e td è questa il riferimento originale viene sovrascritto, questo significa che devo ri-emettere i due nuovi array
147
+ ths = ths.filter(t => !t.thMulti);
148
+ tds = tds.filter(t => !t._multi);
149
+ let parentThs = {};
150
+ let addedHeaders = {};
151
+ let tdsToAdd = {};
152
+ let thsToAdd = [];
153
+ // Per ogni item vedo se ci sono dei multi per le proprietà che li definiscono
154
+ for (let i = 0; i < items.length; i++) {
155
+ let itm = items[i];
156
+ for (let prop in multiDefs) {
157
+ // Se la proprietà del multi esiste nell'oggetto ed ha una lunghezza
158
+ if (itm[prop] && itm[prop].length) {
159
+ let multiRef = multiDefs[prop];
160
+ let reftd = multiRef.tdref;
161
+ let refth = multiRef.thref;
162
+ for (let ii = 0; ii < itm[prop].length; ii++) {
163
+ // Header già aggiunto, non devo inserire altri template di header/colonna
164
+ let estmv = itm[prop][ii];
165
+ if (!estmv._headersHierarchy)
166
+ estmv._headersHierarchy = estmv.header_group ? estmv.header_group.split(">").map(t => t.trim()) : [];
167
+ let headerValue = estmv.header;
168
+ let parent = estmv.header_group || null;
169
+ let parentsHier = estmv._headersHierarchy;
170
+ if (addedHeaders[`${parent}_${headerValue}`])
171
+ continue;
172
+ else
173
+ addedHeaders[`${parent}_${headerValue}`] = true;
174
+ // Per ogni valore diverso delle proprietà devo aggiungere un td e un th, quest'ultimo dev'essere eventualmente collegato ad un header
175
+ let newtH = new EsThDirective(refth.Template);
176
+ newtH._multi = true;
177
+ newtH._multi_content = headerValue;
178
+ newtH.th = `${prop}_${ii}`;
179
+ newtH.thClass = refth.thClass;
180
+ newtH.thShrink = refth.thShrink;
181
+ newtH.thIf = refth.thIf;
182
+ newtH.thVisible = refth.thVisible;
183
+ newtH.thWrap = refth.thWrap;
184
+ // Il parent è sempre l'ultimo nella gerarchia di padri
185
+ newtH.thParent = parentsHier[parentsHier.length - 1];
186
+ newtH.thOrderable = false;
187
+ for (let i = 0; i < parentsHier.length; i++) {
188
+ let par = parentsHier[i];
189
+ if (!parentThs[par])
190
+ parentThs[par] = true;
191
+ else
192
+ continue;
193
+ let thParent = new EsThDirective(null);
194
+ thParent.th = par;
195
+ thParent._multi_content = par;
196
+ thParent.thParent = i > 0 ? parentsHier[i - 1] : null;
197
+ thsToAdd.push(thParent);
198
+ }
199
+ thsToAdd.push(newtH);
200
+ let newTd = new EsTdDirective(reftd.Template);
201
+ newTd._multi = true;
202
+ newTd.td = `${prop}_${ii}`;
203
+ newTd.tdClass = reftd.tdClass;
204
+ newTd.tdIf = reftd.tdIf;
205
+ newTd.tdVisible = reftd.tdVisible;
206
+ tdsToAdd[newTd.td] = newTd;
207
+ }
208
+ }
209
+ }
210
+ }
211
+ // Ordino gli header aggiunti in base al Parent, se presente, e li aggiungo alla lista dei th, dopodiché in base allo stesso ordinamento aggiungo i relativi td
212
+ let orderedThs = [];
213
+ // Prima metto tutti i th senza parent, poi per ogni parent prendo i th ordinati come li trovo nella lista
214
+ for (let i = 0; i < thsToAdd.length; i++) {
215
+ if (!thsToAdd[i].thParent)
216
+ orderedThs.push(thsToAdd[i]);
217
+ }
218
+ for (let prop in parentThs) {
219
+ for (let i = 0; i < thsToAdd.length; i++) {
220
+ let th = thsToAdd[i];
221
+ if (th.thParent && th.thParent == prop)
222
+ orderedThs.push(th);
223
+ }
224
+ }
225
+ ths = [...ths, ...thsToAdd];
226
+ for (let i = 0; i < thsToAdd.length; i++) {
227
+ // Se il th è un header td verrebbe undefined. Lo aggiungo solo se è effettivamente presente
228
+ let td = tdsToAdd[thsToAdd[i].th];
229
+ if (td)
230
+ tds.push(td);
231
+ }
232
+ return { expTds: tds, expThs: ths };
233
+ }
234
+ /**
235
+ * Prende i th e i td in modalità diretive e li ordina in base a se ci sono colonne fixed o meno
236
+ */
237
+ moveFixedColumnsAtTheBeginning(ths, tds) {
238
+ let fixeds = 0, pinneds = 0;
239
+ let columnsCache = {};
240
+ let columnsIndexCache = {};
241
+ // Creo la cache delle colonne
242
+ for (let coli = 0; coli < this.est.ColumnsList.length; coli++) {
243
+ let col = this.est.ColumnsList[coli];
244
+ columnsCache[col.id] = col;
245
+ // Anche per le columnslist sposto le pinnate o le fixed all'inizio
246
+ if (col.pinned) {
247
+ if (coli != pinneds)
248
+ this.utilities.arrayMove(this.est.ColumnsList, coli, pinneds);
249
+ pinneds++;
250
+ }
251
+ // Se una colonna è sia pinnata che fixata la considero unicamente pinnata
252
+ if (col.fixed && !col.pinned) {
253
+ if (coli != pinneds + fixeds)
254
+ this.utilities.arrayMove(ths, coli, pinneds + fixeds);
255
+ fixeds++;
256
+ }
257
+ }
258
+ pinneds = fixeds = 0;
259
+ // Sposto tutti gli header fixed o pinned all'inizio
260
+ for (let i = 0; i < ths.length; i++) {
261
+ let th = ths[i];
262
+ // Riassegno sempre per ripulire valori di partenza o per aggiornarli in caso di modifiche utente
263
+ th.thPinned = (!columnsCache[th.th] && th.thPinned) || (columnsCache[th.th] && columnsCache[th.th].pinned);
264
+ if (th.thPinned) {
265
+ if (i != pinneds)
266
+ this.utilities.arrayMove(ths, i, pinneds);
267
+ pinneds++;
268
+ }
269
+ //In questo caso sono informazioni statiche invece, non modificabili dall'utente, quindi non mi dò preoccupazioni
270
+ if ((th.thFixed || th.thGroup) && !th.thPinned) {
271
+ if (i != pinneds + fixeds)
272
+ this.utilities.arrayMove(ths, i, pinneds + fixeds);
273
+ fixeds++;
274
+ }
275
+ }
276
+ // Cache degli indici per riposizionare i td come i th
277
+ for (let i = 0; i < ths.length; i++)
278
+ columnsIndexCache[ths[i].th] = i;
279
+ // Riordino le celle per fargli mantenere la stessa struttura dei th
280
+ let newTds = new Array(ths.length);
281
+ for (let i = 0; i < tds.length; i++) {
282
+ let item = tds[i];
283
+ newTds[columnsIndexCache[item.td]] = item;
284
+ }
285
+ this.est.HasPinnedColumns = pinneds > 0;
286
+ }
287
+ /** In base alla configurazione delle colonne calcola le dimenioni delle colonne pinnate */
288
+ evaluatePinnedColumnsWidth() {
289
+ if (!this.est.HasPinnedColumns)
290
+ return;
291
+ this.est.PinnedContainerWidth = 0;
292
+ for (let i = 0; i < this.est.ColumnsList.length; i++) {
293
+ let col = this.est.ColumnsList[i];
294
+ if (col.pinned && col.visible)
295
+ this.est.PinnedContainerWidth += col.pinnedWidth;
296
+ }
297
+ this.est.PinnedContainerWidth += this.est.Selection ? 25 : 0;
298
+ }
299
+ /**
300
+ * Terminato il binding delle colonne da **reviewColumnsList** e della **View** dal **writeValue** questo metodo si occupa
301
+ * dell'allineamento delle informazioni fra le colonne calcolate internamente e le informazioni sulle colonne che arrivano dall'AppSearch
302
+ *
303
+ * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
304
+ * @param {boolean} useLocalVisibility Indica di utilizzare le impostazioni di visibilità locali senza allinearle alla view
305
+ */
306
+ alignColumnsIfLoadedView(view) {
307
+ let emitChanged = this.est.viewMode && view.savedstate;
308
+ let newColset = [];
309
+ if (!this.est.ColumnsList || this.est.ColumnsList.length == 0)
310
+ return;
311
+ let columns = [];
312
+ // Modlaità view ->
313
+ if (this.est.viewMode) {
314
+ // colonne dinamiche -> prendo l'insieme delle colonne e operazioni dinamiche definite
315
+ // standard -> prendo le colonne della view
316
+ if (this.est.DynamicRowColumnsDefinition)
317
+ columns = [...(this.est.DynamicRowColumnsDefinition?.map(t => t.PropertyName) || []), ...(this.est.DynamicOperations?.map(t => t.id) || [])];
318
+ else
319
+ columns = view.columns;
320
+ }
321
+ // Modalità array -> prendo le colonne array
322
+ else
323
+ columns = this.est.arrayColumns;
324
+ this.est.ColumnsList.forEach(c => {
325
+ // Se la colonna è pinnata mi arriva col simoleon, ma anche se è una composizione di più colonne
326
+ let exCl = columns.filter(cc => (cc.startsWith('§') ? cc.substring(1) : cc) == c.id);
327
+ // Se la colonna è pinnata aggiorno l'informazione nella view
328
+ if (exCl.length == 1)
329
+ c.pinned = exCl[0].startsWith('§');
330
+ // Se l'appsearch viene da uno stato precedente, uso le informazioni sulle colonne che ha dentro, altrimenti sovrascrivo tutto **
331
+ if (c.visible && columns.length == 0)
332
+ newColset.push(c.id);
333
+ // Se ho una colonna lato AppSearch e nella ColumnList non è visibile, allineo all'AppSearch
334
+ else if (exCl.length == 1 && !c.visible && !this.est.useLocalVisibility)
335
+ c.visible = true;
336
+ // Allineamento sull'AppSearch per casistiche inverse al di sopra
337
+ else if (exCl.length == 0 && c.visible && !this.est.useLocalVisibility)
338
+ c.visible = false;
339
+ });
340
+ // Non ho colonne nella appsearch, vuol dire che sono al primo binding
341
+ if (columns.length == 0) {
342
+ if (this.est.viewMode)
343
+ view.columns = newColset;
344
+ else
345
+ this.est.arrayColumns = newColset;
346
+ }
347
+ if ((this.est.viewMode && view.savedstate) && this.est.ColumnsOrdering && view.column_ordering.length > 0) {
348
+ // Scorro gli ordinamenti che avevo salvato e ricreo la ColumnsList in base a loro
349
+ let newColList = [];
350
+ view.column_ordering.forEach(co => {
351
+ this.est.ColumnsList.forEach(c => {
352
+ if (c.id == co)
353
+ newColList.push(c);
354
+ });
355
+ });
356
+ // Recupero anche campi nuovi che nell'iterazione vecchia non c'erano (serve durante lo sviluppo in modo da non perdersi fra un EDIT + F5 e l'altro)
357
+ this.est.ColumnsList.forEach(c => {
358
+ if (!newColList.find(t => t == c.id))
359
+ newColList.push(c);
360
+ });
361
+ this.est.ColumnsList = newColList;
362
+ }
363
+ // In ogni caso questo non mi serve più, lo resetto **
364
+ if (this.est.viewMode)
365
+ view.savedstate = false;
366
+ // Reset di questa variabile usata one-bind
367
+ if (this.est.useLocalVisibility)
368
+ this.est.useLocalVisibility = false;
369
+ if (emitChanged)
370
+ this.est.changed();
371
+ }
372
+ /**
373
+ * In base alla visibilità registrata nelle **ColumnsList** questo metodo si occupa di prendere tutti i **EsThDirective** ed **EsTdDirective** relativi e nasonderli/mostrarli
374
+ *
375
+ * Costo: 1 scan ColumnsList, 1 scan EsThDirectives, 1 scan EsTdDirectives
376
+ *
377
+ * @param {EsThDirective[]} ths Header della tabella
378
+ * @param {EsTdDirective[]} tds Celle della tabella
379
+ * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
380
+ */
381
+ refreshColumnsVisibility(ths, tds, view) {
382
+ let newColset = [];
383
+ let fixedThs = {};
384
+ let columnsCache = {};
385
+ for (let coli = 0; coli < this.est.ColumnsList.length; coli++) {
386
+ let col = this.est.ColumnsList[coli];
387
+ columnsCache[col.id] = col;
388
+ if (col.visible)
389
+ newColset.push((col.pinned ? "§" : "") + col.id);
390
+ }
391
+ if (view)
392
+ view.columns = newColset;
393
+ else
394
+ this.est.arrayColumns = newColset;
395
+ // 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
396
+ if (ths) {
397
+ // Definisco se la colonna è visibile in base alla sua rappresentazione locale in ColumnsList
398
+ for (let i = 0; i < ths.length; i++) {
399
+ let th = ths[i];
400
+ th.thVisible = th.thFixed || (columnsCache[th.th] ? columnsCache[th.th].visible : th.thVisible);
401
+ if (th.thFixed || th.thGroup)
402
+ fixedThs[th.th] = true;
403
+ }
404
+ }
405
+ if (tds) {
406
+ // Definisco se la cella è visibile in base alla sua rappresentazione locale in ColumnsList
407
+ for (let i = 0; i < tds.length; i++) {
408
+ let td = tds[i];
409
+ td.tdVisible = fixedThs[td.td] || (columnsCache[td.td] ? columnsCache[td.td].visible : td.tdVisible);
410
+ }
411
+ }
412
+ this.est.changed();
413
+ }
414
+ /**
415
+ * Allinea gli ordinamenti dati fra le **EsThs** e le informazioni all'interno della View bindata
416
+ *
417
+ * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
418
+ * @param {EsThDirective[]} ths Colonne della tabella
419
+ */
420
+ alignHeadersOrdering(ths, view) {
421
+ let orders = view ? view.orders : this.est.arrayOrders;
422
+ for (let i = 0; i < ths.length; i++) {
423
+ let th = ths[i];
424
+ th.thOrder = null;
425
+ for (let i = 0; i < orders.length; i++) {
426
+ let or = orders[i];
427
+ if (or.id == th.th)
428
+ th.thOrder = or.order;
429
+ }
430
+ }
431
+ }
432
+ /**
433
+ * Genera tutte le informazioni che servono per gestire il raggruppamento degli header
434
+ *
435
+ * @param {EsThDirective[]} ths Colonne della tabella
436
+ *
437
+ * @returns {{ leafs: EsThDirective[], groupingLevel: number, parentsCache: any, thsCache: any }} Oggetto contenente la lista delle foglie (header base), il livello
438
+ * massimo di raggruppamento raggiunto, una cache in cui vengono indicati tutti i gruppi che sono "parent" (quindi che raggruppano almeno 1 header) e la cache degli header
439
+ */
440
+ evaluateHeadersGroupingInfos(ths) {
441
+ // Pregiro per trovare i parent
442
+ let parentsCache = {};
443
+ let thsCache = {};
444
+ for (let i = 0; i < ths.length; i++) {
445
+ let th = ths[i];
446
+ thsCache[th.th] = th;
447
+ if (th.thParent && !parentsCache[th.thParent])
448
+ parentsCache[th.thParent] = true;
449
+ }
450
+ // Secondo giro per beccare il livello massimo e la lista di foglie (th senza parent)
451
+ let hMaxLevel = 0;
452
+ let leafs = [];
453
+ for (let i = 0; i < ths.length; i++) {
454
+ let th = ths[i];
455
+ // Se sono una foglia vedo quanti livelli ci sono sopra
456
+ if (!parentsCache[th.th]) {
457
+ leafs.push(th);
458
+ let tmp = this.jumpsToFinalParent(th, thsCache);
459
+ hMaxLevel = tmp > hMaxLevel ? tmp : hMaxLevel;
460
+ }
461
+ }
462
+ return { leafs: leafs, groupingLevel: hMaxLevel, parentsCache: parentsCache, thsCache: thsCache };
463
+ }
464
+ /**
465
+ * Genera gli header groups da una lista di info sui th all'interno della variabile **TMPRowThGroups**
466
+ *
467
+ * @param {{ leafs: EsThDirective[], groupingLevel: number, parentsCache: any, thsCache: any }} infos Informazioni di raggruppamento valutate precedentemente
468
+ */
469
+ evaluateHeaderGroups(infos) {
470
+ if (infos.groupingLevel == 0)
471
+ return;
472
+ /****** STEP 1: Creo l'output dei raggruppamenti per header in modo da non dovermi preoccupare di celle non inizializzate ******/
473
+ let expandedGroups = [];
474
+ let visibleUnpinnedLeafs = infos.leafs.filter((t) => t.thVisible && t.thIf && !t.thPinned);
475
+ for (let l = 0; l < infos.groupingLevel; l++) {
476
+ expandedGroups.push([]);
477
+ for (let i = 0; i < visibleUnpinnedLeafs.length; i++)
478
+ expandedGroups[l].push("");
479
+ }
480
+ /****** STEP 2: Ordino le foglie in base agli ordinamenti delle colonne ******/
481
+ let orderedLeafs = [];
482
+ for (let i = 0; i < this.est.OrderDirectives.length; i++) {
483
+ let leaf = infos.thsCache[this.est.OrderDirectives[i]];
484
+ // Solo se la leaf è presente. Potrebbero esserci ordinamenti su colonne sparite
485
+ if (leaf && leaf.thVisible && leaf.thIf && !leaf.thPinned)
486
+ orderedLeafs.push(leaf);
487
+ }
488
+ /****** STEP 3: Creo l'array group con tutti i riferimenti del caso ******/
489
+ let currentParent = "";
490
+ for (let i = 0; i < orderedLeafs.length; i++) {
491
+ let refTh = orderedLeafs[i];
492
+ let prevTh = i - 1 >= 0 ? orderedLeafs[i - 1] : null;
493
+ // Parent diverso da prima, metto il bordo a sinistra e a destra della cella precedente (se c'è)
494
+ // 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
495
+ refTh._lbord = refTh.thParent != currentParent;
496
+ refTh._rbord = visibleUnpinnedLeafs.length == i + 1;
497
+ if (prevTh)
498
+ prevTh._rbord = refTh.thParent != currentParent;
499
+ currentParent = refTh.thParent;
500
+ // Per ogni gruppo srotolo il parent nella matrice dei raggruppamenti
501
+ for (let l = 0; l < infos.groupingLevel; l++) {
502
+ let parent = refTh.thParent;
503
+ if (parent && !refTh.thPinned) {
504
+ expandedGroups[l][i] = parent;
505
+ refTh = infos.thsCache[parent];
506
+ }
507
+ }
508
+ }
509
+ /****** STEP 4: Compatto nell'elemento finale su cui bindarmi. L'ID assegnato è SOLO per ottimizzare gli ngFor ******/
510
+ currentParent = "";
511
+ let currentSpan = 0;
512
+ let finalHeaders = [];
513
+ for (let l = 0; l < expandedGroups.length; l++) {
514
+ let levelArray = [];
515
+ finalHeaders.push(levelArray);
516
+ if (this.est.Selection || this.est.HasPinnedColumns)
517
+ levelArray.push({ ID: "_base_sel_pinned", Span: 1, Template: null, Pinned: this.est.HasPinnedColumns });
518
+ for (let h = 0; h < expandedGroups[l].length; h++) {
519
+ let item = expandedGroups[l][h];
520
+ if (item == currentParent)
521
+ currentSpan++;
522
+ else {
523
+ if (currentSpan > 0)
524
+ levelArray.push({ ID: `${currentParent ? infos.thsCache[currentParent].th : 'noth'}_${currentSpan}`, Span: currentSpan, Template: currentParent ? infos.thsCache[currentParent].Template : null, Content: currentParent ? infos.thsCache[currentParent]._multi_content : null, Borders: !!currentParent });
525
+ currentSpan = 1;
526
+ currentParent = item;
527
+ }
528
+ }
529
+ // Ultima aggiunta che altrimenti mi rimarrebbe in cache
530
+ levelArray.push({ ID: `${currentParent ? infos.thsCache[currentParent].th : 'noth'}_${currentSpan}`, Span: currentSpan, Template: currentParent ? infos.thsCache[currentParent].Template : null, Content: currentParent ? infos.thsCache[currentParent]._multi_content : null, Borders: !!currentParent });
531
+ // Aggiungo i pezzettini per la rimozione e gli export, se presenti
532
+ if (this.est.Removal)
533
+ levelArray.push({ ID: "_base_removal", Span: 1, Template: null });
534
+ if (this.est.Export || this.est.HiddenColumns || this.est.ColumnsOrdering || this.est.CornerMenuOptions)
535
+ levelArray.push({ ID: "_base_extra_opts", Span: 1, Template: null });
536
+ currentSpan = 0;
537
+ currentParent = "";
538
+ }
539
+ /****** STEP 5: Secco le righe in cui non c'è nulla ******/
540
+ this.est.TMPRowThGroups = [];
541
+ for (let i = 0; i < finalHeaders.length; i++) {
542
+ let level = finalHeaders[i];
543
+ let empty = true;
544
+ for (let j = 0; j < level.length; j++) {
545
+ let item = level[j];
546
+ if (item.Template || item.Content) {
547
+ empty = false;
548
+ break;
549
+ }
550
+ }
551
+ if (!empty)
552
+ this.est.TMPRowThGroups.push(level);
553
+ }
554
+ }
555
+ /**
556
+ * Calcola il numero di salti da un header foglia all'ultimo parent della catena
557
+ *
558
+ * @param {EsThDirective} th Header da cui scorrere i padri per capire quanti livelli ci sono sopra
559
+ * @param {{ [index: string]: EsThDirective }} thsCache Cache degli header
560
+ */
561
+ jumpsToFinalParent(th, thsCache) {
562
+ let jumps = 0;
563
+ let parent = null;
564
+ let parentsPrepend = [];
565
+ let baseThRef = th;
566
+ do {
567
+ parent = th.thParent;
568
+ if (parent) {
569
+ th = thsCache[parent];
570
+ if (!th.thEmpty && !th._multi_content)
571
+ parentsPrepend.unshift({ id: th.th, tmpl: th.Template });
572
+ else if (!th.thEmpty && th._multi_content)
573
+ parentsPrepend.unshift({ id: th.th, content: th._multi_content });
574
+ jumps++;
575
+ }
576
+ } while (parent);
577
+ baseThRef._thParents = parentsPrepend;
578
+ return jumps;
579
+ }
580
+ /**
581
+ * Metodo che genera l'ordine di default delle colonne
582
+ *
583
+ * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
584
+ */
585
+ generateDefaultOrder(ths, view) {
586
+ if (ths.length == 0)
587
+ return;
588
+ //*********************************************** Fix ordinamenti per colonne sparite ****************************** */
589
+ // Considero solo gli ordinamenti per colonne effettivamente presenti all'interno della tabella
590
+ if (this.est.viewMode)
591
+ view.column_ordering = view.column_ordering.filter(ord => ths.find(t => t.th == ord));
592
+ //*********************************************** Fix ordinamenti per colonne sparite ****************************** */
593
+ let orderings = this.est.viewMode ? view.column_ordering : this.est.arrayColumnOrdering;
594
+ // Genero ordinamento di default da 0 fino a dove deve arrivare. Situazione attuale senza hotpotato
595
+ if (!orderings || orderings.length == 0) {
596
+ for (let i = 0; i < ths.length; i++) {
597
+ let th = ths[i];
598
+ let order = th.th;
599
+ this.est.OrderDirectives.push(order);
600
+ }
601
+ }
602
+ else {
603
+ this.est.OrderDirectives = orderings;
604
+ for (let i = 0; i < ths.length; i++) {
605
+ let th = ths[i];
606
+ let thId = th.th;
607
+ if (!this.est.OrderDirectives.find(o => o == thId))
608
+ this.est.OrderDirectives.push(thId);
609
+ }
610
+ }
611
+ }
612
+ /**
613
+ * Applica l'ordine specificato alle varie colonne
614
+ *
615
+ * @param {AppSearch<any>} view AppSearch da utilizzare per questa operazione
616
+ * @param {boolean} finalize Se **true** significa che non mi aspetto di dover effettuare altre operazioni e posso renderizzare la situazione in base ai RowContext
617
+ * Senza finalize significa che mi aspetto altre operazioni che prima o poi richiameranno questa funzione col finalize.
618
+ *
619
+ * 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.
620
+ * Mettendo solo la chiamata da "writeValue" come "finalizzante" mi assicuro che smanattamenti a frontend non causino flickering fino a quando non servono
621
+ */
622
+ applyOrdering(view, finalize) {
623
+ // Genero ordinamento per gli header
624
+ let newHeaders = [];
625
+ // Se devo finalizzare aggancio tutte le variabili di bind
626
+ if (finalize) {
627
+ this.est.OrderDirectives.forEach(o => {
628
+ let heaedrItem = this.est.TMPRowTHs.filter(t => t.ID == o)[0];
629
+ if (heaedrItem)
630
+ newHeaders.push(heaedrItem);
631
+ });
632
+ this.est.TMPRowTHs = newHeaders;
633
+ // Genero ordinamento per le celle
634
+ for (let i = 0; i < this.est.RowContexts.length; i++) {
635
+ let context = this.est.TMPRowTDs[this.est.RowContexts[i]];
636
+ let newContext = [];
637
+ this.est.OrderDirectives.forEach(o => {
638
+ let contextItem = context.filter(t => t.ID == o)[0];
639
+ // potrebbe esser undefined nel caso ci fossero colonne sotto thIf
640
+ if (contextItem)
641
+ newContext.push(contextItem);
642
+ });
643
+ this.est.TMPRowTDs[this.est.RowContexts[i]] = newContext;
644
+ }
645
+ }
646
+ if (this.est.viewMode)
647
+ view.column_ordering = this.est.OrderDirectives;
648
+ else
649
+ this.est.arrayColumnOrdering = this.est.OrderDirectives;
650
+ this.est.changed();
651
+ }
652
+ /**
653
+ * All'interno della dialog "Ordinamento e Visibilità Colonne" mette la colonna specificata prima della colonna precedente
654
+ *
655
+ * @param {EsTableColumn} columnItem Colonna da spostare
656
+ */
657
+ sendUp(columnItem) {
658
+ let itemIndex = this.est.TMPColumnsList.indexOf(columnItem);
659
+ if (this.est.TMPColumnsList[itemIndex - 1].fixed || this.est.TMPColumnsList[itemIndex - 1].pinned)
660
+ return;
661
+ this.utiExts.swap(this.est.TMPColumnsList, itemIndex, itemIndex - 1);
662
+ // Non posso fare JSON.parse(JSON.stringify(this.ColumnsList)) perché contiene riferimenti a TemplateRef
663
+ let tmp = [];
664
+ this.est.TMPColumnsList.forEach(c => { tmp.push(Object.assign({}, c)); });
665
+ this.est.TMPColumnsList = tmp;
666
+ }
667
+ /**
668
+ * All'interno della dialog "Ordinamento e Visibilità Colonne" mette la colonna specificata dopo la colonna successiva
669
+ *
670
+ * @param {EsTableColumn} columnItem Colonna da spostare
671
+ */
672
+ sendDown(columnItem) {
673
+ let itemIndex = this.est.TMPColumnsList.indexOf(columnItem);
674
+ this.utiExts.swap(this.est.TMPColumnsList, itemIndex, itemIndex + 1);
675
+ // Non posso fare JSON.parse(JSON.stringify(this.ColumnsList)) perché contiene riferimenti a TemplateRef
676
+ let tmp = [];
677
+ this.est.TMPColumnsList.forEach(c => { tmp.push(Object.assign({}, c)); });
678
+ this.est.TMPColumnsList = tmp;
679
+ }
680
+ /**
681
+ * All'interno della dialog "Ordinamento e Visibilità Colonne" pinna la colonna specificata
682
+ *
683
+ * @param {EsTableColumn} columnItem Colonna da spostare
684
+ */
685
+ pinOrUnpinColumn(columnItem) {
686
+ let itemIndex = this.est.TMPColumnsList.indexOf(columnItem);
687
+ if (!columnItem.pinned) {
688
+ columnItem.prev_index = itemIndex;
689
+ //Quando pinno devo spostare l'elemento come ultima colonna pinnata o come prima colonna se non ce ne sono di pinnate
690
+ for (let i = 0; i < this.est.TMPColumnsList.length; i++) {
691
+ if (!this.est.TMPColumnsList[i].pinned) {
692
+ this.utilities.arrayMove(this.est.TMPColumnsList, itemIndex, i);
693
+ break;
694
+ }
695
+ }
696
+ }
697
+ else {
698
+ //Quando spinno riporto l'elemento allo stesso indice in cui era prima (se sono stati fatti spostamenti nel mezzo cazzi dell'utente)
699
+ if (columnItem.prev_index != null && columnItem.prev_index != undefined)
700
+ this.utilities.arrayMove(this.est.TMPColumnsList, itemIndex, columnItem.prev_index);
701
+ else {
702
+ // Se spinno senza un prev_index vuol dire che la colonna era pinnata da configurazione. La sposto nel primo punto disponibile
703
+ for (let i = 0; i < this.est.TMPColumnsList.length; i++) {
704
+ if (!this.est.TMPColumnsList[i].pinned && !this.est.TMPColumnsList[i].fixed) {
705
+ this.utilities.arrayMove(this.est.TMPColumnsList, itemIndex, i - 1);
706
+ break;
707
+ }
708
+ }
709
+ }
710
+ }
711
+ columnItem.pinned = !columnItem.pinned;
712
+ }
713
+ /**
714
+ * All'interno della dialog "Ordinamento e Visibilità Colonne" inverte le impostazioni di visibilità della colonna
715
+ *
716
+ * @param {EsTableColumn} columnItem Colonna da spostare
717
+ */
718
+ columnClicked(item) {
719
+ this.est.lastSelectedItemID = item.id;
720
+ if (!this.est.HiddenColumns || item.fixed)
721
+ return;
722
+ item.visible = !item.visible;
723
+ this.updateGlobalColVisCheck();
724
+ }
725
+ /** All'apertura della dialog "Ordinamento e Visibilità Colonne" ricarica le informazioni attuali per permettere la modifica */
726
+ resetColumnVisSelection() {
727
+ this.est.TMPColumnsList = [];
728
+ // Non posso fare JSON.parse(JSON.stringify(this.ColumnsList)) perché contiene riferimenti a TemplateRef
729
+ this.est.TMPColumnsList = [];
730
+ this.est.ColumnsList.forEach(c => { this.est.TMPColumnsList.push(Object.assign({}, c)); });
731
+ let reorderedColList = [];
732
+ if (this.est.ColumnsOrdering) {
733
+ this.est.OrderDirectives.forEach(o => {
734
+ let column = this.est.TMPColumnsList.filter(t => t.id == o)[0];
735
+ // Potrei non averne nel caso ci sia il flag HiddenColumns a false, evito di inserire degli undefined
736
+ if (column)
737
+ reorderedColList.push(column);
738
+ });
739
+ this.est.TMPColumnsList = reorderedColList;
740
+ }
741
+ this.updateGlobalColVisCheck();
742
+ }
743
+ /** Riaggiorna le **OrderDirectives** con le informazioni in **ColumnsList** */
744
+ refreshColumnOrdering() {
745
+ this.est.OrderDirectives = [];
746
+ for (let c = 0; c < this.est.ColumnsList.length; c++)
747
+ this.est.OrderDirectives.push(this.est.ColumnsList[c].id);
748
+ }
749
+ /** Effettua la selezione o meno del check globale (**globalColVisCheck**) di visibilità in base a se tutte le **TMPColumnsList** sono visibili o no */
750
+ updateGlobalColVisCheck() {
751
+ // TMPColList viene riempita di undefined nel caso in cui sia disattivata la selezione delle colonne nascoste
752
+ this.est.globalColVisCheck = this.est.TMPColumnsList.every(t => t.visible);
753
+ }
754
+ /**
755
+ * Chiamato quando una colonna viene riordinata all'interno della lista delle visibilità/posizioni colonne
756
+ *
757
+ * @param {CdkDragDrop<EsTableColumn[]>} event Evento di drop della lista
758
+ */
759
+ columnReordered(event) {
760
+ moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
761
+ }
762
+ /**
763
+ * Chiamato quando una colonna viene riordinata all'interno della lista delle visibilità/posizioni colonne
764
+ *
765
+ * @param {number} index Indice in cui voglio droppare l'elemento draggato
766
+ * @param {CdkDrag<EsTableColumn>} item Oggetto che sto draggando
767
+ *
768
+ * @returns {boolean} **true** se la colonna può essere spostata sull'indice **index**, **false** altrimenti
769
+ */
770
+ sortPredicate(index, item) {
771
+ let itemAtIndex = this.est.ColumnsList[index];
772
+ return !itemAtIndex.fixed && !itemAtIndex.pinned && !item.data.pinned && !item.data.pinned;
773
+ }
774
+ /**
775
+ * Funzione che effettua la conferma della visibilità e dell'ordine delle colonne.
776
+ *
777
+ * Questa selezione viene inoltre salvata nelle preferenze (**@esfaenza/preferences**), qualora l'Input **SavePreferences** fosse valorizzato
778
+ *
779
+ * @returns {boolean} **true** se non ci sono problemi, **false** altrimenti
780
+ */
781
+ confirmColumnVisibilitySelection() {
782
+ // Non permetto di non selezionare nulla
783
+ if (this.est.TMPColumnsList.every(t => !t.visible))
784
+ return false;
785
+ let castedView = this.est.viewMode ? (this.est.MainGroupView || this.est.View) : null;
786
+ this.est.ColumnsList = [];
787
+ this.est.TMPColumnsList.forEach(c => { this.est.ColumnsList.push(Object.assign({}, c)); });
788
+ this.refreshColumnOrdering();
789
+ this.applyOrdering(castedView, false);
790
+ this.refreshColumnsVisibility(null, null, castedView);
791
+ //Salvo le preferences di questa view
792
+ //Di default registro ordinamento e visibilità delle colonne nella vista. Solo le cose di UI
793
+ if (this.est.SavePreferences)
794
+ this.registerViewPreferences(castedView);
795
+ // Rieseguo l'ultima ricerca bindata alla tabella
796
+ // Mi assicuro di farlo dopo l'espansione del changed o rischio che la ricerca mi ridia colonne che in realtà non esistono
797
+ if (this.est.viewMode)
798
+ setTimeout(() => {
799
+ if (this.est.MainGroupView) {
800
+ //this.emitSearchRequest(true, this.MainGroupView);
801
+ for (let i = 0; i < this.est.groupSearchRequestsCache.length; i++) {
802
+ let view = this.est.groupSearchRequestsCache[i].view;
803
+ view.columns = this.est.MainGroupView.columns;
804
+ view.column_ordering = this.est.MainGroupView.column_ordering;
805
+ this.est.emitSearchRequest(true, this.est.groupSearchRequestsCache[i].view);
806
+ }
807
+ }
808
+ else
809
+ this.est.emitSearchRequest(true);
810
+ });
811
+ else if (this.est.arrayMode)
812
+ setTimeout(() => { this.est.internalWriteValue(); });
813
+ // Lo vorrei mettere lato template ma no
814
+ this.est.lastSelectedItemID = null;
815
+ return true;
816
+ }
817
+ /**
818
+ * Effettuo l'unpinning di una colonna in maniera programmatica semplicemente eseguendo una per una le operazioni che verrebbero eseguite altrimenti
819
+ *
820
+ * @param {string} id Codice della colonna da spinnare
821
+ */
822
+ unpinColumn(id) {
823
+ this.resetColumnVisSelection();
824
+ this.pinOrUnpinColumn(this.est.TMPColumnsList.find(t => t.id == id));
825
+ this.confirmColumnVisibilitySelection();
826
+ }
827
+ /** Sul click nella checkbox di selezione globale si scorrono tutte le colonne e si impostano al valore della check globale */
828
+ globalColVisCheckChanged() {
829
+ this.est.TMPColumnsList.forEach(t => {
830
+ if (!t.fixed)
831
+ t.visible = this.est.globalColVisCheck;
832
+ });
833
+ }
834
+ }
835
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29sdW1uTWV0YWRhdGFIYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZXMtdGFibGUvc3JjL2xpYi9jb3JlL2hhbmRsZXJzL0NvbHVtbk1ldGFkYXRhSGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxVQUFVO0FBQ1YsT0FBTyxFQUF3QixlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQVMvRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDakUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBTWpFLFVBQVU7QUFDVixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sOENBQThDLENBQUM7QUFFM0UsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBR3JFLDZIQUE2SDtBQUM3SCxNQUFNLE9BQU8scUJBQXFCO0lBRTlCLHlCQUF5QjtJQUN6QixZQUFvQixHQUFxQixFQUFVLFNBQTJCLEVBQVUsT0FBdUIsRUFBVSxXQUErQixFQUFVLEdBQXVCO1FBQXJLLFFBQUcsR0FBSCxHQUFHLENBQWtCO1FBQVUsY0FBUyxHQUFULFNBQVMsQ0FBa0I7UUFBVSxZQUFPLEdBQVAsT0FBTyxDQUFnQjtRQUFVLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtRQUFVLFFBQUcsR0FBSCxHQUFHLENBQW9CO0lBQUksQ0FBQztJQUU5TDs7Ozs7T0FLRztJQUNJLG1CQUFtQixDQUFDLEVBQVUsRUFBRSxLQUFxQjtRQUN4RCxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUF1QixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUM7UUFDakcsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLElB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QUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTO1lBQ3ZCLFVBQVUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV6RCx3Q0FBd0M7UUFDeEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7UUFDbkMsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxXQUFXLENBQUMsRUFBVTtRQUN6QixJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLElBQUksQ0FBQyxnQ0FBZ0MsRUFBRSxDQUFDO0lBQzVDLENBQUM7SUFFRCw4SEFBOEg7SUFDdkgsd0JBQXdCO1FBQzNCLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNoQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUs7Z0JBQ1IsQ0FBQyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDO1FBQy9DLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQW5ndWxhclxyXG5pbXBvcnQgeyBDZGtEcmFnLCBDZGtEcmFnRHJvcCwgbW92ZUl0ZW1JbkFycmF5IH0gZnJvbSBcIkBhbmd1bGFyL2Nkay9kcmFnLWRyb3BcIjtcclxuaW1wb3J0IHsgVGVtcGxhdGVSZWYgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5cclxuLy8gTGlic1xyXG5pbXBvcnQgeyBVdGlsaXR5U2VydmljZSB9IGZyb20gXCJAZXNmYWVuemEvZXh0ZW5zaW9uc1wiO1xyXG5pbXBvcnQgeyBQcmVmZXJlbmNlc1NlcnZpY2UgfSBmcm9tIFwiQGVzZmFlbnphL3ByZWZlcmVuY2VzXCI7XHJcblxyXG4vLyBDb21wb25lbnRpIC8gRGlyZXR0aXZlXHJcbmltcG9ydCB7IEVzVGFibGVDb21wb25lbnQgfSBmcm9tIFwiLi4vLi4vY29tcG9uZW50cy9lcy10YWJsZS9lc190YWJsZS5jb21wb25lbnRcIlxyXG5pbXBvcnQgeyBFc1RkRGlyZWN0aXZlIH0gZnJvbSBcIi4uLy4uL2RpcmVjdGl2ZXMvZXNfdGQuZGlyZWN0aXZlXCI7XHJcbmltcG9ydCB7IEVzVGhEaXJlY3RpdmUgfSBmcm9tIFwiLi4vLi4vZGlyZWN0aXZlcy9lc190aC5kaXJlY3RpdmVcIjtcclxuXHJcbi8vIEhhbmRsZXJzXHJcbmltcG9ydCB7IFV0aWxpdGllc0hhbmRsZXIgfSBmcm9tIFwiLi9VdGlsaXRpZXNIYW5kbGVyXCI7XHJcbmltcG9ydCB7IFJvd0dyb3VwaW5nSGFuZGxlciB9IGZyb20gXCIuL1Jvd0dyb3VwaW5nSGFuZGxlclwiO1xyXG5cclxuLy8gTW9kZWxsaVxyXG5pbXBvcnQgeyBBcHBPcmRlcmluZyB9IGZyb20gXCIuLi8uLi9kb21haW4vZXh0ZXJuYWxzL2FwcHNlYXJjaC9BcHBPcmRlcmluZ1wiO1xyXG5pbXBvcnQgeyBBcHBTZWFyY2ggfSBmcm9tIFwiLi4vLi4vZG9tYWluL2V4dGVybmFscy9hcHBzZWFyY2gvQXBwU2VhcmNoXCI7XHJcbmltcG9ydCB7IEVzVGFibGVDb2x1bW4gfSBmcm9tIFwiLi4vLi4vZG9tYWluL2ludGVybmFscy9Fc1RhYmxlQ29sdW1uXCI7XHJcbmltcG9ydCB7IEVzVGFibGVNdWx0aVZhbHVlIH0gZnJvbSBcIi4uLy4uL2RvbWFpbi9leHRlcm5hbHMvYXBwc2VhcmNoL0VzVGFibGVNdWx0aVZhbHVlXCI7XHJcblxyXG4vKiogQ2xhc3NlIGNoZSBnZXN0aXNjZSB0dXR0ZSBsZSBpbmZvcm1haXpvbmkgcmVsYXRpdmUgYWxsZSBjb2xvbm5lOiB2aXNpYmlsaXTDoCwgcG9zaXppb25lLCBzdGF0byBkaSBwaW4vdW5waW4sIGVjYyBlY2MuLi4gKi9cclxuZXhwb3J0IGNsYXNzIENvbHVtbk1ldGFkYXRhSGFuZGxlciB7XHJcblxyXG4gICAgLyoqIEBpZ25vcmUgQ29zdHJ1dHRvcmUqL1xyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBlc3Q6IEVzVGFibGVDb21wb25lbnQsIHByaXZhdGUgdXRpbGl0aWVzOiBVdGlsaXRpZXNIYW5kbGVyLCBwcml2YXRlIHV0aUV4dHM6IFV0aWxpdHlTZXJ2aWNlLCBwcml2YXRlIHByZWZTZXJ2aWNlOiBQcmVmZXJlbmNlc1NlcnZpY2UsIHByaXZhdGUgcmdIOiBSb3dHcm91cGluZ0hhbmRsZXIpIHsgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0b2RvIGNoZSBnZXN0aXNjZSBpbCBjYW1iaW8gZGkgT3JkaW5hbWVudG8gZGkgdW5hIGNvbG9ubmFcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgSUQgZGVsbGEgY29sb25uYSBpbCBjdWkgb3JpZG5hbWVudG8gw6ggY2FtYmlhdG9cclxuICAgICAqIEBwYXJhbSB7J0RFU0MnIHwgJ0FTQyd9IG9yZGVyIE51b3ZvIG9yZGluZSBzZWxlemlvbmF0byBwZXIgbGEgY29sb25uYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaGFuZGxlVEhPcmRlckNoYW5nZShpZDogc3RyaW5nLCBvcmRlcjogJ0RFU0MnIHwgJ0FTQycpIHtcclxuICAgICAgICBsZXQgb3JkZXJzID0gdGhpcy5lc3Qudmlld01vZGUgPyAodGhpcy5lc3QuVmlldyBhcyBBcHBTZWFyY2g8YW55Pikub3JkZXJzIDogdGhpcy5lc3QuYXJyYXlPcmRlcnM7XHJcbiAgICAgICAgbGV0IG9yZGVyVG9BZGQgPSB0cnVlO1xyXG4gICAgICAgIGxldCBvcmRlclRvUmVtb3ZlOiBudW1iZXIgPSBudWxsO1xyXG5cclxuICAgICAgICAvLyBTZSBwZXIgcXVhbGNoZSBtb3Rpdm8gaWwgY29zdHJ1dHRvcmUgbm9uIMOoIHBhc3NhdG8gKGNhY2hlIHRhcnBhdGUgbyBzaW1pbGEpIGZpeG9cclxuICAgICAgICBpZiAoIW9yZGVycyAmJiB0aGlzLmVzdC52aWV3TW9kZSlcclxuICAgICAgICAgICAgKHRoaXMuZXN0LlZpZXcgYXMgQXBwU2VhcmNoPGFueT4pLm9yZGVycyA9IFtdO1xyXG4gICAgICAgIGVsc2UgaWYgKCFvcmRlcnMgJiYgdGhpcy5lc3QuYXJyYXlNb2RlKVxyXG4gICAgICAgICAgICB0aGlzLmVzdC5hcnJheU9yZGVycyA9IFtdO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9yZGVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdCA9IG9yZGVyc1tpXTtcclxuICAgICAgICAgICAgaWYgKHQuaWQgPT0gaWQpIHtcclxuICAgICAgICAgICAgICAgIGlmIChvcmRlcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHQub3JkZXIgPSBvcmRlcjtcclxuICAgICAgICAgICAgICAgICAgICBvcmRlclRvQWRkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgb3JkZXJUb1JlbW92ZSA9IGk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChvcmRlclRvUmVtb3ZlICE9IG51bGwpIHtcclxuICAgICAgICAgICAgb3JkZXJzLnNwbGljZShvcmRlclRvUmVtb3ZlLCAxKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAob3JkZXJUb0FkZCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5lc3QuTXVsdGlwbGVPcmRlcmluZ0RpcmVjdGl2ZXMpXHJcbiAgICAgICAgICAgICAgICBvcmRlcnMucHVzaChuZXcgQXBwT3JkZXJpbmcoaWQsIG9yZGVyKSk7XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZXN0LnZpZXdNb2RlKVxyXG4gICAgICAgICAgICAgICAgICAgICh0aGlzLmVzdC5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+KS5vcmRlcnMgPSBbbmV3IEFwcE9yZGVyaW5nKGlkLCBvcmRlcildO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5lc3QuYXJyYXlNb2RlKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXN0LmFycmF5T3JkZXJzID0gW25ldyBBcHBPcmRlcmluZyhpZCwgb3JkZXIpXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy9TYWx2byBsZSBwcmVmZXJlbmNlcyBkaSBxdWVzdGEgdmlld1xyXG4gICAgICAgIC8vRGkgZGVmYXVsdCByZWdpc3RybyBvcmRpbmFtZW50byBlIHZpc2liaWxpdMOgIGRlbGxlIGNvbG9ubmUgbmVsbGEgdmlzdGEuIFNvbG8gbGUgY29zZSBkaSBVSVxyXG4gICAgICAgIGlmICh0aGlzLmVzdC5TYXZlUHJlZmVyZW5jZXMpIHtcclxuICAgICAgICAgICAgbGV0IGNhc3RlZFZpZXcgPSB0aGlzLmVzdC52aWV3TW9kZSA/ICh0aGlzLmVzdC5NYWluR3JvdXBWaWV3IHx8IHRoaXMuZXN0LlZpZXcgYXMgQXBwU2VhcmNoPGFueT4pIDogbnVsbDtcclxuICAgICAgICAgICAgdGhpcy5yZWdpc3RlclZpZXdQcmVmZXJlbmNlcyhjYXN0ZWRWaWV3KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuZXN0Lm9uT3JkZXJDaGFuZ2VkLmVtaXQoeyBpZCwgb3JkZXIgfSk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmVzdC52aWV3TW9kZSkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5lc3QuZ3JvdXBTZWFyY2hSZXF1ZXN0c0NhY2hlLmxlbmd0aCA+IDApXHJcbiAgICAgICAgICAgICAgICB0aGlzLnJnSC5lbWl0Um93R3JvdXBpbmdTZWFyY2hlcyhpZCwgb3JkZXJzKTtcclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgdGhpcy5lc3QuZW1pdFNlYXJjaFJlcXVlc3QoZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0aGlzLmVzdC5hcnJheU1vZGUpXHJcbiAgICAgICAgICAgIHRoaXMuZXN0LmludGVybmFsV3JpdGVWYWx1ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVnaXN0cmEgbGUgcHJlZmVyZW5jZSByZWxhdGl2ZSBhbGxhIHZpZXcgcGFzc2F0YSBjb21lIHBhcmFtZXRyb1xyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge2FueX0gY2FzdGVkVmlldyBWaWV3IGRpIGN1aSBzYWx2YXJlIGNvbG9ubmUgZSBvcmRpbmFtZW50byBjb2xvbm5lXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWdpc3RlclZpZXdQcmVmZXJlbmNlcyhjYXN0ZWRWaWV3OiBBcHBTZWFyY2g8YW55Pikge1xyXG4gICAgICAgIGlmICghdGhpcy5lc3QubmdDb250cm9sLm5hbWUpIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIk5vbiBwb3NzbyB1dGlsaXp6YXJlIGxlIHByZWZlcmVuY2Ugc2VuemEgYXZlcmUgdW4gJ25hbWUnIHBlciBsYSB0YWJlbGxhXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXRoaXMucHJlZlNlcnZpY2UpIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIk5vbiBwb3NzbyB1dGlsaXp6YXJlIGxlIHByZWZlcmVuY2Ugc2VuemEgY2hlIGlsIHBhY2NoZXR0byBAZXNmYWVuemEvcHJlZmVyZW5jZXMgc2lhIGluc3RhbGxhdG9cIik7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBjb2x1bW5zID0gdGhpcy5lc3QuYXJyYXlNb2RlID8gdGhpcy5lc3QuYXJyYXlDb2x1bW5zIDogY2FzdGVkVmlldy5jb2x1bW5zO1xyXG4gICAgICAgIGxldCBjb2x1bW5zT3JkZXJpbmdzID0gdGhpcy5lc3QuYXJyYXlNb2RlID8gdGhpcy5lc3QuYXJyYXlDb2x1bW5PcmRlcmluZyA6IGNhc3RlZFZpZXcuY29sdW1uX29yZGVyaW5nO1xyXG4gICAgICAgIGxldCBjb2x1bW5PcmRlcnMgPSB0aGlzLmVzdC5hcnJheU1vZGUgPyBbXSA6IGNhc3RlZFZpZXcub3JkZXJzO1xyXG4gICAgICAgIHZhciB0b1N0b3JlID0ge1xyXG4gICAgICAgICAgICBjb2x1bW5zOiB0aGlzLnV0aUV4dHMuZGVlcENsb25lKGNvbHVtbnMpIGFzIHN0cmluZ1tdLFxyXG4gICAgICAgICAgICBjb2x1bW5fb3JkZXJpbmc6IHRoaXMudXRpRXh0cy5kZWVwQ2xvbmUoY29sdW1uc09yZGVyaW5ncykgYXMgc3RyaW5nW10sXHJcbiAgICAgICAgICAgIG9yZGVyczogdGhpcy51dGlFeHRzLmRlZXBDbG9uZShjb2x1bW5PcmRlcnMpIGFzIHN0cmluZ1tdXHJcbiAgICAgICAgfTtcclxuICAgICAgICB0aGlzLnByZWZTZXJ2aWNlLnNldEl0ZW0oPHN0cmluZz50aGlzLmVzdC5uZ0NvbnRyb2wubmFtZSwgdG9TdG9yZSkuc3Vic2NyaWJlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQYXJ0ZW5kbyBkYWdsaSAqKkVzVGhzKiogZXN0cmFwcG9sbyBsYSBsaXN0YSBkaSAqKkVzVGFibGVDb2x1bW4qKiBjaGUgcXVlc3RhIHRhYmVsbGEgZG92csOgIGV2ZW50dWFsbWVudGUgZ2VzdGlyZSBwZXIgVmlzaWJpbGl0w6AgZSBPcmRpbmVcclxuICAgICAqXHJcbiAgICAgKiBDb3N0bzogMSBzY2FuIEVzVGhzXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RoRGlyZWN0aXZlW119IHRocyBDb2xvbm5lIGRlbGxhIHRhYmVsbGFcclxuICAgICAqL1xyXG4gICAgcHVibGljIHJldmlld0NvbHVtbnNMaXN0KHRoczogRXNUaERpcmVjdGl2ZVtdKSB7XHJcbiAgICAgICAgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QgPSBbXTtcclxuICAgICAgICBpZiAodGhzLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIC8vIEFwcGVuYSBpbCBjb250ZW50Q2hpbGRyZW4gw6ggdmFsb3JpenphdG8gc2NvcnJvIHR1dHRpIGdsaSBoZWFkZXJcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcblxyXG4gICAgICAgICAgICBsZXQgY29sdW1uID0gdGgudGg7XHJcbiAgICAgICAgICAgIC8vIFNlIG5vbiBobyB1biBpZCBpbCB0aCDDqCBjb25zaWRlcmF0byBpbmVydGVcclxuICAgICAgICAgICAgaWYgKCFjb2x1bW4pXHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNhbHZvIGxlIGluZm9ybWF6aW9uaSBkZWxsJ2hlYWRlciBwZXIgZmFyIHBhcnRlIGRlbGxhIGxpc3RhIGRhIGN1aSBzY2VnbGllcmUgcXVhbGkgY29sb25uZSB2aXN1YWxpenphcmUvbmFzY29uZGVyZVxyXG4gICAgICAgICAgICAvLyBEaSBkZWZhdWx0IGxhIHZpc2liaWxpdMOgIMOoIHF1ZWxsYSBpbXBvc3RhdGEgbmVsIGNvbXBvbmVudGVcclxuICAgICAgICAgICAgaWYgKCh0aGlzLmVzdC5IaWRkZW5Db2x1bW5zIHx8IHRoLnRoVmlzaWJsZSkgJiYgdGgudGhJZikge1xyXG4gICAgICAgICAgICAgICAgbGV0IHByZXZpb3VzbHlQaW5uZWQgPSAhdGhpcy5lc3QuQ29sdW1uc0xpc3QgfHwgdGhpcy5lc3QuQ29sdW1uc0xpc3QubGVuZ3RoID09IDAgPyBudWxsIDogdGhpcy5lc3QuQ29sdW1uc0xpc3QuZmluZCh0ID0+IHQuaWQgPT0gY29sdW1uKSB8fCBudWxsO1xyXG4gICAgICAgICAgICAgICAgbGV0IHRvQWRkID0gbmV3IEVzVGFibGVDb2x1bW4oY29sdW1uLCB0aC50aFN0YXRpY0NvbnRlbnQsIHRoLnRoVmlzaWJsZSwgKHRoLnRoRml4ZWQgfHwgdGgudGhHcm91cCksIHByZXZpb3VzbHlQaW5uZWQgPT0gbnVsbCA/IHRoLnRoUGlubmVkIDogcHJldmlvdXNseVBpbm5lZC5waW5uZWQsIHRoLnRoUGlubmFibGUsIHRoLnRoUGlubmVkV2lkdGgsIHRoLlRlbXBsYXRlLCB0aC5fdGhQYXJlbnRzLCB0aC5fbXVsdGksIHRoLl9tdWx0aV9jb250ZW50KTtcclxuICAgICAgICAgICAgICAgIGlmIChwcmV2aW91c2x5UGlubmVkKVxyXG4gICAgICAgICAgICAgICAgICAgIHRvQWRkLnByZXZfaW5kZXggPSBwcmV2aW91c2x5UGlubmVkLnByZXZfaW5kZXg7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5wdXNoKHRvQWRkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmVzdC5Db2x1bW5zTGlzdCA9IFtdO1xyXG4gICAgICAgIHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LmZvckVhY2goYyA9PiB7IHRoaXMuZXN0LkNvbHVtbnNMaXN0LnB1c2goT2JqZWN0LmFzc2lnbih7fSwgYykpOyB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogSW4gY2FzbyBzaWFubyBjb25maWd1cmF0aSBkZWkgdGggXCJNdWx0aVwiICh2ZWRlcmUgbGEgZGVzY3JpemlvbmUgZGVsIGNhbXBvICoqdGhNdWx0aSoqIGRpICoqRXNUaERpcmVjdGl2ZSoqKSBxdWVzdG8gbWV0b2RvIGxpIFwic3JvdG9sYVwiIGluIHR1dHRpIGkgdGgvdGQgY2hlIGRldm9ubyBlZmZldHRpdmFtZW50ZSBkaXZlbnRhcmUgKi9cclxuICAgIHB1YmxpYyBleHBhbmRNdWx0aVRoc0FuZFRkcyh0aHM6IEVzVGhEaXJlY3RpdmVbXSwgdGRzOiBFc1RkRGlyZWN0aXZlW10sIGl0ZW1zOiBhbnlbXSk6IHtleHBUaHM6IEVzVGhEaXJlY3RpdmVbXSwgZXhwVGRzOiBFc1RkRGlyZWN0aXZlW119IHtcclxuXHJcbiAgICAgICAgLy8gUmVnaXN0cm8gbGUgaW5mbyBzdWkgbXVsdGlwcm92aWRlclxyXG4gICAgICAgIGxldCBtdWx0aURlZnM6IHsgW2lkOiBzdHJpbmddOiB7IE9uPzogc3RyaW5nLCB0aHJlZjogRXNUaERpcmVjdGl2ZSwgdGRyZWY6IEVzVGREaXJlY3RpdmUsIHRoZ2VuOiB7IFtpZDogc3RyaW5nXTogRXNUaERpcmVjdGl2ZSB9LCB0ZGdlbjogeyBbaWQ6IHN0cmluZ106IEVzVGREaXJlY3RpdmUgfSB9IH0gPSB7IH07XHJcbiAgICAgICAgXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHRoID0gdGhzW2ldO1xyXG4gICAgICAgICAgICBpZiAoIXRoLnRoTXVsdGkpXHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuXHJcbiAgICAgICAgICAgIG11bHRpRGVmc1t0aC50aF0gPSB7IE9uOiB0aC50aCwgdGRyZWY6IG51bGwsIHRocmVmOiB0aCwgdGhnZW46IHt9LCB0ZGdlbjoge30gfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEFzc2Vnbm8gbGUgaW5mbyBhbmNoZSBhaSB0ZFxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0ZCA9IHRkc1tpXTtcclxuICAgICAgICAgICAgdGQuX211bHRpID0gISFtdWx0aURlZnNbdGQudGRdO1xyXG4gICAgICAgICAgICBpZih0ZC5fbXVsdGkpXHJcbiAgICAgICAgICAgICAgICBtdWx0aURlZnNbdGQudGRdLnRkcmVmID0gdGQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBSaW11b3ZvIGkgbXVsdGl0ZW1wbGF0ZSBkYWxsZSBiYWxsZVxyXG4gICAgICAgIC8vIE4uQjogRGF0byBjaGUgbGEgcHJpbWEgb3BlcmF6aW9uZSBzdSB0aCBlIHRkIMOoIHF1ZXN0YSBpbCByaWZlcmltZW50byBvcmlnaW5hbGUgdmllbmUgc292cmFzY3JpdHRvLCBxdWVzdG8gc2lnbmlmaWNhIGNoZSBkZXZvIHJpLWVtZXR0ZXJlIGkgZHVlIG51b3ZpIGFycmF5XHJcbiAgICAgICAgdGhzID0gdGhzLmZpbHRlcih0ID0+ICF0LnRoTXVsdGkpO1xyXG4gICAgICAgIHRkcyA9IHRkcy5maWx0ZXIodCA9PiAhdC5fbXVsdGkpO1xyXG5cclxuICAgICAgICBsZXQgcGFyZW50VGhzOiB7IFtpZDogc3RyaW5nXTogYm9vbGVhbjsgfSA9IHsgfTtcclxuICAgICAgICBsZXQgYWRkZWRIZWFkZXJzOiB7IFtpZDogc3RyaW5nXTogYm9vbGVhbjsgfSA9IHsgfTtcclxuICAgICAgICBsZXQgdGRzVG9BZGQ6IHsgW2lkOiBzdHJpbmddIDogRXNUZERpcmVjdGl2ZX0gPSB7IH07XHJcbiAgICAgICAgbGV0IHRoc1RvQWRkOiBFc1RoRGlyZWN0aXZlW10gPSBbXTtcclxuXHJcbiAgICAgICAgLy8gUGVyIG9nbmkgaXRlbSB2ZWRvIHNlIGNpIHNvbm8gZGVpIG11bHRpIHBlciBsZSBwcm9wcmlldMOgIGNoZSBsaSBkZWZpbmlzY29ub1xyXG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKyl7XHJcbiAgICAgICAgICAgIGxldCBpdG0gPSBpdGVtc1tpXTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGZvciAobGV0IHByb3AgaW4gbXVsdGlEZWZzKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBTZSBsYSBwcm9wcmlldMOgIGRlbCBtdWx0aSBlc2lzdGUgbmVsbCdvZ2dldHRvIGVkIGhhIHVuYSBsdW5naGV6emFcclxuICAgICAgICAgICAgICAgIGlmIChpdG1bcHJvcF0gJiYgaXRtW3Byb3BdLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBtdWx0aVJlZiA9IG11bHRpRGVmc1twcm9wXTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmVmdGQgPSBtdWx0aVJlZi50ZHJlZjtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmVmdGggPSBtdWx0aVJlZi50aHJlZjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaWkgPSAwOyBpaSA8IGl0bVtwcm9wXS5sZW5ndGg7IGlpKyspIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhlYWRlciBnacOgIGFnZ2l1bnRvLCBub24gZGV2byBpbnNlcmlyZSBhbHRyaSB0ZW1wbGF0ZSBkaSBoZWFkZXIvY29sb25uYVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZXN0bXYgPSA8RXNUYWJsZU11bHRpVmFsdWU+aXRtW3Byb3BdW2lpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFlc3Rtdi5faGVhZGVyc0hpZXJhcmNoeSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzdG12Ll9oZWFkZXJzSGllcmFyY2h5ID0gZXN0bXYuaGVhZGVyX2dyb3VwID8gZXN0bXYuaGVhZGVyX2dyb3VwLnNwbGl0KFwiPlwiKS5tYXAodCA9PiB0LnRyaW0oKSkgOiBbXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBoZWFkZXJWYWx1ZSA9IGVzdG12LmhlYWRlcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHBhcmVudCA9IGVzdG12LmhlYWRlcl9ncm91cCB8fCBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcGFyZW50c0hpZXIgPSBlc3Rtdi5faGVhZGVyc0hpZXJhcmNoeTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhZGRlZEhlYWRlcnNbYCR7cGFyZW50fV8ke2hlYWRlclZhbHVlfWBdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZGVkSGVhZGVyc1tgJHtwYXJlbnR9XyR7aGVhZGVyVmFsdWV9YF0gPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGVyIG9nbmkgdmFsb3JlIGRpdmVyc28gZGVsbGUgcHJvcHJpZXTDoCBkZXZvIGFnZ2l1bmdlcmUgdW4gdGQgZSB1biB0aCwgcXVlc3QndWx0aW1vIGRldidlc3NlcmUgZXZlbnR1YWxtZW50ZSBjb2xsZWdhdG8gYWQgdW4gaGVhZGVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBuZXd0SCA9IG5ldyBFc1RoRGlyZWN0aXZlKHJlZnRoLlRlbXBsYXRlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3dEguX211bHRpID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3dEguX211bHRpX2NvbnRlbnQgPSBoZWFkZXJWYWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3dEgudGggPSBgJHtwcm9wfV8ke2lpfWA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld3RILnRoQ2xhc3MgPSByZWZ0aC50aENsYXNzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXd0SC50aFNocmluayA9IHJlZnRoLnRoU2hyaW5rO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXd0SC50aElmID0gcmVmdGgudGhJZjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3dEgudGhWaXNpYmxlID0gcmVmdGgudGhWaXNpYmxlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXd0SC50aFdyYXAgPSByZWZ0aC50aFdyYXA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElsIHBhcmVudCDDqCBzZW1wcmUgbCd1bHRpbW8gbmVsbGEgZ2VyYXJjaGlhIGRpIHBhZHJpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld3RILnRoUGFyZW50ID0gcGFyZW50c0hpZXJbcGFyZW50c0hpZXIubGVuZ3RoIC0gMV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld3RILnRoT3JkZXJhYmxlID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmVudHNIaWVyLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcGFyID0gcGFyZW50c0hpZXJbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXBhcmVudFRoc1twYXJdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudFRoc1twYXJdID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgdGhQYXJlbnQgPSBuZXcgRXNUaERpcmVjdGl2ZShudWxsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoUGFyZW50LnRoID0gcGFyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhQYXJlbnQuX211bHRpX2NvbnRlbnQgPSBwYXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aFBhcmVudC50aFBhcmVudCA9IGkgPiAwID8gcGFyZW50c0hpZXJbaSAtIDFdIDogbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoc1RvQWRkLnB1c2godGhQYXJlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHNUb0FkZC5wdXNoKG5ld3RIKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBuZXdUZCA9IG5ldyBFc1RkRGlyZWN0aXZlKHJlZnRkLlRlbXBsYXRlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3VGQuX211bHRpID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3VGQudGQgPSBgJHtwcm9wfV8ke2lpfWA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1RkLnRkQ2xhc3MgPSByZWZ0ZC50ZENsYXNzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdUZC50ZElmID0gcmVmdGQudGRJZjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3VGQudGRWaXNpYmxlID0gcmVmdGQudGRWaXNpYmxlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZHNUb0FkZFtuZXdUZC50ZF0gPSBuZXdUZDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIE9yZGlubyBnbGkgaGVhZGVyIGFnZ2l1bnRpIGluIGJhc2UgYWwgUGFyZW50LCBzZSBwcmVzZW50ZSwgZSBsaSBhZ2dpdW5nbyBhbGxhIGxpc3RhIGRlaSB0aCwgZG9wb2RpY2jDqSBpbiBiYXNlIGFsbG8gc3Rlc3NvIG9yZGluYW1lbnRvIGFnZ2l1bmdvIGkgcmVsYXRpdmkgdGRcclxuICAgICAgICBsZXQgb3JkZXJlZFRocyA9IFtdO1xyXG5cclxuICAgICAgICAvLyBQcmltYSBtZXR0byB0dXR0aSBpIHRoIHNlbnphIHBhcmVudCwgcG9pIHBlciBvZ25pIHBhcmVudCBwcmVuZG8gaSB0aCBvcmRpbmF0aSBjb21lIGxpIHRyb3ZvIG5lbGxhIGxpc3RhXHJcbiAgICAgICAgZm9yKGxldCBpID0gMDsgaSA8IHRoc1RvQWRkLmxlbmd0aDsgaSsrKXtcclxuICAgICAgICAgICAgaWYoIXRoc1RvQWRkW2ldLnRoUGFyZW50KVxyXG4gICAgICAgICAgICAgICAgb3JkZXJlZFRocy5wdXNoKHRoc1RvQWRkW2ldKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm9yKGxldCBwcm9wIGluIHBhcmVudFRocyl7XHJcbiAgICAgICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCB0aHNUb0FkZC5sZW5ndGg7IGkrKyl7XHJcbiAgICAgICAgICAgICAgICBsZXQgdGggPSB0aHNUb0FkZFtpXTtcclxuICAgICAgICAgICAgICAgIGlmKHRoLnRoUGFyZW50ICYmIHRoLnRoUGFyZW50ID09IHByb3ApXHJcbiAgICAgICAgICAgICAgICAgICAgb3JkZXJlZFRocy5wdXNoKHRoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhzID0gWy4uLnRocywgLi4udGhzVG9BZGRdO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzVG9BZGQubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgLy8gU2UgaWwgdGggw6ggdW4gaGVhZGVyIHRkIHZlcnJlYmJlIHVuZGVmaW5lZC4gTG8gYWdnaXVuZ28gc29sbyBzZSDDqCBlZmZldHRpdmFtZW50ZSBwcmVzZW50ZVxyXG4gICAgICAgICAgICBsZXQgdGQgPSB0ZHNUb0FkZFt0aHNUb0FkZFtpXS50aF07XHJcbiAgICAgICAgICAgIGlmICh0ZClcclxuICAgICAgICAgICAgICAgIHRkcy5wdXNoKHRkKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB7IGV4cFRkczogdGRzLCBleHBUaHM6IHRocyB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHJlbmRlIGkgdGggZSBpIHRkIGluIG1vZGFsaXTDoCBkaXJldGl2ZSBlIGxpIG9yZGluYSBpbiBiYXNlIGEgc2UgY2kgc29ubyBjb2xvbm5lIGZpeGVkIG8gbWVub1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbW92ZUZpeGVkQ29sdW1uc0F0VGhlQmVnaW5uaW5nKHRoczogRXNUaERpcmVjdGl2ZVtdLCB0ZHM6IEVzVGREaXJlY3RpdmVbXSkge1xyXG5cclxuICAgICAgICBsZXQgZml4ZWRzID0gMCwgcGlubmVkcyA9IDA7XHJcbiAgICAgICAgbGV0IGNvbHVtbnNDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IEVzVGFibGVDb2x1bW47IH0gPSB7fTtcclxuICAgICAgICBsZXQgY29sdW1uc0luZGV4Q2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBudW1iZXI7IH0gPSB7fTtcclxuXHJcbiAgICAgICAgLy8gQ3JlbyBsYSBjYWNoZSBkZWxsZSBjb2xvbm5lXHJcbiAgICAgICAgZm9yIChsZXQgY29saSA9IDA7IGNvbGkgPCB0aGlzLmVzdC5Db2x1bW5zTGlzdC5sZW5ndGg7IGNvbGkrKykge1xyXG4gICAgICAgICAgICBsZXQgY29sID0gdGhpcy5lc3QuQ29sdW1uc0xpc3RbY29saV07XHJcbiAgICAgICAgICAgIGNvbHVtbnNDYWNoZVtjb2wuaWRdID0gY29sO1xyXG5cclxuICAgICAgICAgICAgLy8gQW5jaGUgcGVyIGxlIGNvbHVtbnNsaXN0IHNwb3N0byBsZSBwaW5uYXRlIG8gbGUgZml4ZWQgYWxsJ2luaXppb1xyXG4gICAgICAgICAgICBpZiAoY29sLnBpbm5lZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNvbGkgIT0gcGlubmVkcylcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnV0aWxpdGllcy5hcnJheU1vdmUodGhpcy5lc3QuQ29sdW1uc0xpc3QsIGNvbGksIHBpbm5lZHMpO1xyXG4gICAgICAgICAgICAgICAgcGlubmVkcysrO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBTZSB1bmEgY29sb25uYSDDqCBzaWEgcGlubmF0YSBjaGUgZml4YXRhIGxhIGNvbnNpZGVybyB1bmljYW1lbnRlIHBpbm5hdGFcclxuICAgICAgICAgICAgaWYgKGNvbC5maXhlZCAmJiAhY29sLnBpbm5lZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNvbGkgIT0gcGlubmVkcyArIGZpeGVkcylcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnV0aWxpdGllcy5hcnJheU1vdmUodGhzLCBjb2xpLCBwaW5uZWRzICsgZml4ZWRzKTtcclxuICAgICAgICAgICAgICAgIGZpeGVkcysrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBwaW5uZWRzID0gZml4ZWRzID0gMDtcclxuXHJcbiAgICAgICAgLy8gU3Bvc3RvIHR1dHRpIGdsaSBoZWFkZXIgZml4ZWQgbyBwaW5uZWQgYWxsJ2luaXppb1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuXHJcbiAgICAgICAgICAgIC8vIFJpYXNzZWdubyBzZW1wcmUgcGVyIHJpcHVsaXJlIHZhbG9yaSBkaSBwYXJ0ZW56YSBvIHBlciBhZ2dpb3JuYXJsaSBpbiBjYXNvIGRpIG1vZGlmaWNoZSB1dGVudGVcclxuICAgICAgICAgICAgdGgudGhQaW5uZWQgPSAoIWNvbHVtbnNDYWNoZVt0aC50aF0gJiYgdGgudGhQaW5uZWQpIHx8IChjb2x1bW5zQ2FjaGVbdGgudGhdICYmIGNvbHVtbnNDYWNoZVt0aC50aF0ucGlubmVkKTtcclxuICAgICAgICAgICAgaWYgKHRoLnRoUGlubmVkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaSAhPSBwaW5uZWRzKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXRpbGl0aWVzLmFycmF5TW92ZSh0aHMsIGksIHBpbm5lZHMpO1xyXG4gICAgICAgICAgICAgICAgcGlubmVkcysrO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvL0luIHF1ZXN0byBjYXNvIHNvbm8gaW5mb3JtYXppb25pIHN0YXRpY2hlIGludmVjZSwgbm9uIG1vZGlmaWNhYmlsaSBkYWxsJ3V0ZW50ZSwgcXVpbmRpIG5vbiBtaSBkw7IgcHJlb2NjdXBhemlvbmlcclxuICAgICAgICAgICAgaWYgKCh0aC50aEZpeGVkIHx8IHRoLnRoR3JvdXApICYmICF0aC50aFBpbm5lZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGkgIT0gcGlubmVkcyArIGZpeGVkcylcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnV0aWxpdGllcy5hcnJheU1vdmUodGhzLCBpLCBwaW5uZWRzICsgZml4ZWRzKTtcclxuICAgICAgICAgICAgICAgIGZpeGVkcysrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBDYWNoZSBkZWdsaSBpbmRpY2kgcGVyIHJpcG9zaXppb25hcmUgaSB0ZCBjb21lIGkgdGhcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgY29sdW1uc0luZGV4Q2FjaGVbKDxFc1RoRGlyZWN0aXZlPnRoc1tpXSkudGhdID0gaTtcclxuXHJcbiAgICAgICAgLy8gUmlvcmRpbm8gbGUgY2VsbGUgcGVyIGZhcmdsaSBtYW50ZW5lcmUgbGEgc3Rlc3NhIHN0cnV0dHVyYSBkZWkgdGhcclxuICAgICAgICBsZXQgbmV3VGRzID0gbmV3IEFycmF5KHRocy5sZW5ndGgpO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRkcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgaXRlbSA9IHRkc1tpXSBhcyBFc1RkRGlyZWN0aXZlO1xyXG4gICAgICAgICAgICBuZXdUZHNbY29sdW1uc0luZGV4Q2FjaGVbaXRlbS50ZF1dID0gaXRlbTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuZXN0Lkhhc1Bpbm5lZENvbHVtbnMgPSBwaW5uZWRzID4gMDtcclxuICAgIH1cclxuXHJcbiAgICAvKiogSW4gYmFzZSBhbGxhIGNvbmZpZ3VyYXppb25lIGRlbGxlIGNvbG9ubmUgY2FsY29sYSBsZSBkaW1lbmlvbmkgZGVsbGUgY29sb25uZSBwaW5uYXRlICovXHJcbiAgICBwdWJsaWMgZXZhbHVhdGVQaW5uZWRDb2x1bW5zV2lkdGgoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmVzdC5IYXNQaW5uZWRDb2x1bW5zKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIHRoaXMuZXN0LlBpbm5lZENvbnRhaW5lcldpZHRoID0gMDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZXN0LkNvbHVtbnNMaXN0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBjb2wgPSB0aGlzLmVzdC5Db2x1bW5zTGlzdFtpXTtcclxuICAgICAgICAgICAgaWYgKGNvbC5waW5uZWQgJiYgY29sLnZpc2libGUpXHJcbiAgICAgICAgICAgICAgICB0aGlzLmVzdC5QaW5uZWRDb250YWluZXJXaWR0aCArPSBjb2wucGlubmVkV2lkdGg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZXN0LlBpbm5lZENvbnRhaW5lcldpZHRoICs9IHRoaXMuZXN0LlNlbGVjdGlvbiA/IDI1IDogMDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlcm1pbmF0byBpbCBiaW5kaW5nIGRlbGxlIGNvbG9ubmUgZGEgKipyZXZpZXdDb2x1bW5zTGlzdCoqIGUgZGVsbGEgKipWaWV3KiogZGFsICoqd3JpdGVWYWx1ZSoqIHF1ZXN0byBtZXRvZG8gc2kgb2NjdXBhXHJcbiAgICAgKiBkZWxsJ2FsbGluZWFtZW50byBkZWxsZSBpbmZvcm1hemlvbmkgZnJhIGxlIGNvbG9ubmUgY2FsY29sYXRlIGludGVybmFtZW50ZSBlIGxlIGluZm9ybWF6aW9uaSBzdWxsZSBjb2xvbm5lIGNoZSBhcnJpdmFubyBkYWxsJ0FwcFNlYXJjaFxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7QXBwU2VhcmNoPGFueT59IHZpZXcgQXBwU2VhcmNoIGRhIHV0aWxpenphcmUgcGVyIHF1ZXN0YSBvcGVyYXppb25lXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHVzZUxvY2FsVmlzaWJpbGl0eSBJbmRpY2EgZGkgdXRpbGl6emFyZSBsZSBpbXBvc3RhemlvbmkgZGkgdmlzaWJpbGl0w6AgbG9jYWxpIHNlbnphIGFsbGluZWFybGUgYWxsYSB2aWV3XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhbGlnbkNvbHVtbnNJZkxvYWRlZFZpZXcodmlldzogQXBwU2VhcmNoPGFueT4pIHtcclxuICAgICAgICBsZXQgZW1pdENoYW5nZWQgPSB0aGlzLmVzdC52aWV3TW9kZSAmJiB2aWV3LnNhdmVkc3RhdGU7XHJcbiAgICAgICAgbGV0IG5ld0NvbHNldCA9IFtdO1xyXG5cclxuICAgICAgICBpZiAoIXRoaXMuZXN0LkNvbHVtbnNMaXN0IHx8IHRoaXMuZXN0LkNvbHVtbnNMaXN0Lmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGxldCBjb2x1bW5zID0gW107XHJcblxyXG4gICAgICAgIC8vIE1vZGxhaXTDoCB2aWV3IC0+XHJcbiAgICAgICAgaWYgKHRoaXMuZXN0LnZpZXdNb2RlKSB7XHJcbiAgICAgICAgICAgIC8vIGNvbG9ubmUgZGluYW1pY2hlIC0+IHByZW5kbyBsJ2luc2llbWUgZGVsbGUgY29sb25uZSBlIG9wZXJhemlvbmkgZGluYW1pY2hlIGRlZmluaXRlXHJcbiAgICAgICAgICAgIC8vIHN0YW5kYXJkIC0+IHByZW5kbyBsZSBjb2xvbm5lIGRlbGxhIHZpZXdcclxuICAgICAgICAgICAgaWYgKHRoaXMuZXN0LkR5bmFtaWNSb3dDb2x1bW5zRGVmaW5pdGlvbilcclxuICAgICAgICAgICAgICAgIGNvbHVtbnMgPSBbLi4uKHRoaXMuZXN0LkR5bmFtaWNSb3dDb2x1bW5zRGVmaW5pdGlvbj8ubWFwKHQgPT4gdC5Qcm9wZXJ0eU5hbWUpIHx8IFtdKSwgLi4uKHRoaXMuZXN0LkR5bmFtaWNPcGVyYXRpb25zPy5tYXAodCA9PiB0LmlkKSB8fCBbXSldO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICBjb2x1bW5zID0gdmlldy5jb2x1bW5zO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBNb2RhbGl0w6AgYXJyYXkgLT4gcHJlbmRvIGxlIGNvbG9ubmUgYXJyYXlcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIGNvbHVtbnMgPSB0aGlzLmVzdC5hcnJheUNvbHVtbnNcclxuXHJcbiAgICAgICAgdGhpcy5lc3QuQ29sdW1uc0xpc3QuZm9yRWFjaChjID0+IHtcclxuICAgICAgICAgICAgLy8gU2UgbGEgY29sb25uYSDDqCBwaW5uYXRhIG1pIGFycml2YSBjb2wgc2ltb2xlb24sIG1hIGFuY2hlIHNlIMOoIHVuYSBjb21wb3NpemlvbmUgZGkgcGnDuSBjb2xvbm5lXHJcbiAgICAgICAgICAgIGxldCBleENsID0gY29sdW1ucy5maWx0ZXIoY2MgPT4gKGNjLnN0YXJ0c1dpdGgoJ8KnJykgPyBjYy5zdWJzdHJpbmcoMSkgOiBjYykgPT0gYy5pZCk7XHJcblxyXG4gICAgICAgICAgICAvLyBTZSBsYSBjb2xvbm5hIMOoIHBpbm5hdGEgYWdnaW9ybm8gbCdpbmZvcm1hemlvbmUgbmVsbGEgdmlld1xyXG4gICAgICAgICAgICBpZiAoZXhDbC5sZW5ndGggPT0gMSlcclxuICAgICAgICAgICAgICAgIGMucGlubmVkID0gZXhDbFswXS5zdGFydHNXaXRoKCfCpycpO1xyXG5cclxuICAgICAgICAgICAgLy8gU2UgbCdhcHBzZWFyY2ggdmllbmUgZGEgdW5vIHN0YXRvIHByZWNlZGVudGUsIHVzbyBsZSBpbmZvcm1hemlvbmkgc3VsbGUgY29sb25uZSBjaGUgaGEgZGVudHJvLCBhbHRyaW1lbnRpIHNvdnJhc2NyaXZvIHR1dHRvICAqKlxyXG4gICAgICAgICAgICBpZiAoYy52aXNpYmxlICYmIGNvbHVtbnMubGVuZ3RoID09IDApXHJcbiAgICAgICAgICAgICAgICBuZXdDb2xzZXQucHVzaChjLmlkKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNlIGhvIHVuYSBjb2xvbm5hIGxhdG8gQXBwU2VhcmNoIGUgbmVsbGEgQ29sdW1uTGlzdCBub24gw6ggdmlzaWJpbGUsIGFsbGluZW8gYWxsJ0FwcFNlYXJjaFxyXG4gICAgICAgICAgICBlbHNlIGlmIChleENsLmxlbmd0aCA9PSAxICYmICFjLnZpc2libGUgJiYgIXRoaXMuZXN0LnVzZUxvY2FsVmlzaWJpbGl0eSlcclxuICAgICAgICAgICAgICAgIGMudmlzaWJsZSA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAvLyBBbGxpbmVhbWVudG8gc3VsbCdBcHBTZWFyY2ggcGVyIGNhc2lzdGljaGUgaW52ZXJzZSBhbCBkaSBzb3ByYVxyXG4gICAgICAgICAgICBlbHNlIGlmIChleENsLmxlbmd0aCA9PSAwICYmIGMudmlzaWJsZSAgJiYgIXRoaXMuZXN0LnVzZUxvY2FsVmlzaWJpbGl0eSlcclxuICAgICAgICAgICAgICAgIGMudmlzaWJsZSA9IGZhbHNlO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBOb24gaG8gY29sb25uZSBuZWxsYSBhcHBzZWFyY2gsIHZ1b2wgZGlyZSBjaGUgc29ubyBhbCBwcmltbyBiaW5kaW5nXHJcbiAgICAgICAgaWYgKGNvbHVtbnMubGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuZXN0LnZpZXdNb2RlKVxyXG4gICAgICAgICAgICAgICAgdmlldy5jb2x1bW5zID0gbmV3Q29sc2V0O1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICB0aGlzLmVzdC5hcnJheUNvbHVtbnMgPSBuZXdDb2xzZXQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoKHRoaXMuZXN0LnZpZXdNb2RlICYmIHZpZXcuc2F2ZWRzdGF0ZSkgJiYgdGhpcy5lc3QuQ29sdW1uc09yZGVyaW5nICYmIHZpZXcuY29sdW1uX29yZGVyaW5nLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgLy8gU2NvcnJvIGdsaSBvcmRpbmFtZW50aSBjaGUgYXZldm8gc2FsdmF0byBlIHJpY3JlbyBsYSBDb2x1bW5zTGlzdCBpbiBiYXNlIGEgbG9yb1xyXG4gICAgICAgICAgICBsZXQgbmV3Q29sTGlzdCA9IFtdO1xyXG4gICAgICAgICAgICB2aWV3LmNvbHVtbl9vcmRlcmluZy5mb3JFYWNoKGNvID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXN0LkNvbHVtbnNMaXN0LmZvckVhY2goYyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGMuaWQgPT0gY28pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0NvbExpc3QucHVzaChjKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIC8vIFJlY3VwZXJvIGFuY2hlIGNhbXBpIG51b3ZpIGNoZSBuZWxsJ2l0ZXJhemlvbmUgdmVjY2hpYSBub24gYydlcmFubyAoc2VydmUgZHVyYW50ZSBsbyBzdmlsdXBwbyBpbiBtb2RvIGRhIG5vbiBwZXJkZXJzaSBmcmEgdW4gRURJVCArIEY1IGUgbCdhbHRybylcclxuICAgICAgICAgICAgdGhpcy5lc3QuQ29sdW1uc0xpc3QuZm9yRWFjaChjID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICghbmV3Q29sTGlzdC5maW5kKHQgPT4gdCA9PSBjLmlkKSlcclxuICAgICAgICAgICAgICAgICAgICBuZXdDb2xMaXN0LnB1c2goYyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5lc3QuQ29sdW1uc0xpc3QgPSBuZXdDb2xMaXN0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSW4gb2duaSBjYXNvIHF1ZXN0byBub24gbWkgc2VydmUgcGnDuSwgbG8gcmVzZXR0byAgKipcclxuICAgICAgICBpZiAodGhpcy5lc3Qudmlld01vZGUpXHJcbiAgICAgICAgICAgIHZpZXcuc2F2ZWRzdGF0ZSA9IGZhbHNlO1xyXG5cclxuICAgICAgICAvLyBSZXNldCBkaSBxdWVzdGEgdmFyaWFiaWxlIHVzYXRhIG9uZS1iaW5kXHJcbiAgICAgICAgaWYgKHRoaXMuZXN0LnVzZUxvY2FsVmlzaWJpbGl0eSlcclxuICAgICAgICAgICAgdGhpcy5lc3QudXNlTG9jYWxWaXNpYmlsaXR5ID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGlmIChlbWl0Q2hhbmdlZClcclxuICAgICAgICAgICAgdGhpcy5lc3QuY2hhbmdlZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW4gYmFzZSBhbGxhIHZpc2liaWxpdMOgIHJlZ2lzdHJhdGEgbmVsbGUgKipDb2x1bW5zTGlzdCoqIHF1ZXN0byBtZXRvZG8gc2kgb2NjdXBhIGRpIHByZW5kZXJlIHR1dHRpIGkgKipFc1RoRGlyZWN0aXZlKiogZWQgKipFc1RkRGlyZWN0aXZlKiogcmVsYXRpdmkgZSBuYXNvbmRlcmxpL21vc3RyYXJsaVxyXG4gICAgICpcclxuICAgICAqIENvc3RvOiAxIHNjYW4gQ29sdW1uc0xpc3QsIDEgc2NhbiBFc1RoRGlyZWN0aXZlcywgMSBzY2FuIEVzVGREaXJlY3RpdmVzXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RoRGlyZWN0aXZlW119IHRocyBIZWFkZXIgZGVsbGEgdGFiZWxsYVxyXG4gICAgICogQHBhcmFtIHtFc1RkRGlyZWN0aXZlW119IHRkcyBDZWxsZSBkZWxsYSB0YWJlbGxhXHJcbiAgICAgKiBAcGFyYW0ge0FwcFNlYXJjaDxhbnk+fSB2aWV3IEFwcFNlYXJjaCBkYSB1dGlsaXp6YXJlIHBlciBxdWVzdGEgb3BlcmF6aW9uZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVmcmVzaENvbHVtbnNWaXNpYmlsaXR5KHRoczogRXNUaERpcmVjdGl2ZVtdLCB0ZHM6IEVzVGREaXJlY3RpdmVbXSwgdmlldzogQXBwU2VhcmNoPGFueT4pIHtcclxuICAgICAgICBsZXQgbmV3Q29sc2V0ID0gW107XHJcbiAgICAgICAgbGV0IGZpeGVkVGhzOiB7IFtpZDogc3RyaW5nXTogYm9vbGVhbjsgfSA9IHt9O1xyXG4gICAgICAgIGxldCBjb2x1bW5zQ2FjaGU6IHsgW2luZGV4OiBzdHJpbmddOiBFc1RhYmxlQ29sdW1uOyB9ID0ge307XHJcbiAgICAgICAgZm9yIChsZXQgY29saSA9IDA7IGNvbGkgPCB0aGlzLmVzdC5Db2x1bW5zTGlzdC5sZW5ndGg7IGNvbGkrKykge1xyXG4gICAgICAgICAgICBsZXQgY29sID0gdGhpcy5lc3QuQ29sdW1uc0xpc3RbY29saV07XHJcbiAgICAgICAgICAgIGNvbHVtbnNDYWNoZVtjb2wuaWRdID0gY29sO1xyXG4gICAgICAgICAgICBpZiAoY29sLnZpc2libGUpXHJcbiAgICAgICAgICAgICAgICBuZXdDb2xzZXQucHVzaCgoY29sLnBpbm5lZCA/IFwiwqdcIiA6IFwiXCIpICsgY29sLmlkKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHZpZXcpXHJcbiAgICAgICAgICAgIHZpZXcuY29sdW1ucyA9IG5ld0NvbHNldDtcclxuXHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICB0aGlzLmVzdC5hcnJheUNvbHVtbnMgPSBuZXdDb2xzZXQ7XHJcblxyXG4gICAgICAgIC8vIERhIHF1aSBpbiBwb2kgZGV2b25vIGVzc2VyZSBlc2VndWl0aSBTT0xPIGluIGZhc2UgZGkgd3JpdGVWYWx1ZSBxdWluZGkgZGV2byBhc3NpY3VyYXJtaSBkaSBwYXNzYXJsaSBudWxsIGluIHR1dHRpIGkgcGFzc2FnZ2kgZGl2ZXJzaSBkYSBxdWVsbG9cclxuICAgICAgICBpZiAodGhzKSB7XHJcbiAgICAgICAgICAgIC8vIERlZmluaXNjbyBzZSBsYSBjb2xvbm5hIMOoIHZpc2liaWxlIGluIGJhc2UgYWxsYSBzdWEgcmFwcHJlc2VudGF6aW9uZSBsb2NhbGUgaW4gQ29sdW1uc0xpc3RcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aC50aFZpc2libGUgPSB0aC50aEZpeGVkIHx8IChjb2x1bW5zQ2FjaGVbdGgudGhdID8gY29sdW1uc0NhY2hlW3RoLnRoXS52aXNpYmxlIDogdGgudGhWaXNpYmxlKTtcclxuICAgICAgICAgICAgICAgIGlmICh0aC50aEZpeGVkIHx8IHRoLnRoR3JvdXApXHJcbiAgICAgICAgICAgICAgICAgICAgZml4ZWRUaHNbdGgudGhdID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRkcykge1xyXG4gICAgICAgICAgICAvLyBEZWZpbmlzY28gc2UgbGEgY2VsbGEgw6ggdmlzaWJpbGUgaW4gYmFzZSBhbGxhIHN1YSByYXBwcmVzZW50YXppb25lIGxvY2FsZSBpbiBDb2x1bW5zTGlzdFxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRkcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IHRkID0gdGRzW2ldO1xyXG4gICAgICAgICAgICAgICAgdGQudGRWaXNpYmxlID0gZml4ZWRUaHNbdGQudGRdIHx8IChjb2x1bW5zQ2FjaGVbdGQudGRdID8gY29sdW1uc0NhY2hlW3RkLnRkXS52aXNpYmxlIDogdGQudGRWaXNpYmxlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5lc3QuY2hhbmdlZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsaW5lYSBnbGkgb3JkaW5hbWVudGkgZGF0aSBmcmEgbGUgKipFc1RocyoqIGUgbGUgaW5mb3JtYXppb25pIGFsbCdpbnRlcm5vIGRlbGxhIFZpZXcgYmluZGF0YVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7QXBwU2VhcmNoPGFueT59IHZpZXcgQXBwU2VhcmNoIGRhIHV0aWxpenphcmUgcGVyIHF1ZXN0YSBvcGVyYXppb25lXHJcbiAgICAgKiBAcGFyYW0ge0VzVGhEaXJlY3RpdmVbXX0gdGhzIENvbG9ubmUgZGVsbGEgdGFiZWxsYVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYWxpZ25IZWFkZXJzT3JkZXJpbmcodGhzOiBFc1RoRGlyZWN0aXZlW10sIHZpZXc6IEFwcFNlYXJjaDxhbnk+KSB7XHJcbiAgICAgICAgbGV0IG9yZGVycyA9IHZpZXcgPyB2aWV3Lm9yZGVycyA6IHRoaXMuZXN0LmFycmF5T3JkZXJzO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuXHJcbiAgICAgICAgICAgIHRoLnRoT3JkZXIgPSBudWxsO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9yZGVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IG9yID0gb3JkZXJzW2ldO1xyXG4gICAgICAgICAgICAgICAgaWYgKG9yLmlkID09IHRoLnRoKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoLnRoT3JkZXIgPSBvci5vcmRlcjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdlbmVyYSB0dXR0ZSBsZSBpbmZvcm1hemlvbmkgY2hlIHNlcnZvbm8gcGVyIGdlc3RpcmUgaWwgcmFnZ3J1cHBhbWVudG8gZGVnbGkgaGVhZGVyXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFc1RoRGlyZWN0aXZlW119IHRocyBDb2xvbm5lIGRlbGxhIHRhYmVsbGFcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7eyBsZWFmczogRXNUaERpcmVjdGl2ZVtdLCBncm91cGluZ0xldmVsOiBudW1iZXIsIHBhcmVudHNDYWNoZTogYW55LCB0aHNDYWNoZTogYW55IH19IE9nZ2V0dG8gY29udGVuZW50ZSBsYSBsaXN0YSBkZWxsZSBmb2dsaWUgKGhlYWRlciBiYXNlKSwgaWwgbGl2ZWxsb1xyXG4gICAgICogbWFzc2ltbyBkaSByYWdncnVwcGFtZW50byByYWdnaXVudG8sIHVuYSBjYWNoZSBpbiBjdWkgdmVuZ29ubyBpbmRpY2F0aSB0dXR0aSBpIGdydXBwaSBjaGUgc29ubyBcInBhcmVudFwiIChxdWluZGkgY2hlIHJhZ2dydXBwYW5vIGFsbWVubyAxIGhlYWRlcikgZSBsYSBjYWNoZSBkZWdsaSBoZWFkZXJcclxuICAgICAqL1xyXG4gICAgcHVibGljIGV2YWx1YXRlSGVhZGVyc0dyb3VwaW5nSW5mb3ModGhzOiBFc1RoRGlyZWN0aXZlW10pOiB7IGxlYWZzOiBFc1RoRGlyZWN0aXZlW107IGdyb3VwaW5nTGV2ZWw6IG51bWJlcjsgcGFyZW50c0NhY2hlOiBhbnk7IHRoc0NhY2hlOiBhbnk7IH0ge1xyXG4gICAgICAgIC8vIFByZWdpcm8gcGVyIHRyb3ZhcmUgaSBwYXJlbnRcclxuICAgICAgICBsZXQgcGFyZW50c0NhY2hlOiB7IFtpbmRleDogc3RyaW5nXTogYm9vbGVhbjsgfSA9IHt9O1xyXG4gICAgICAgIGxldCB0aHNDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IEVzVGhEaXJlY3RpdmU7IH0gPSB7fTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRocy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcblxyXG4gICAgICAgICAgICB0aHNDYWNoZVt0aC50aF0gPSB0aDtcclxuICAgICAgICAgICAgaWYgKHRoLnRoUGFyZW50ICYmICFwYXJlbnRzQ2FjaGVbdGgudGhQYXJlbnRdKVxyXG4gICAgICAgICAgICAgICAgcGFyZW50c0NhY2hlW3RoLnRoUGFyZW50XSA9IHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBTZWNvbmRvIGdpcm8gcGVyIGJlY2NhcmUgaWwgbGl2ZWxsbyBtYXNzaW1vIGUgbGEgbGlzdGEgZGkgZm9nbGllICh0aCBzZW56YSBwYXJlbnQpXHJcbiAgICAgICAgbGV0IGhNYXhMZXZlbCA9IDA7XHJcbiAgICAgICAgbGV0IGxlYWZzOiBhbnlbXSA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNlIHNvbm8gdW5hIGZvZ2xpYSB2ZWRvIHF1YW50aSBsaXZlbGxpIGNpIHNvbm8gc29wcmFcclxuICAgICAgICAgICAgaWYgKCFwYXJlbnRzQ2FjaGVbdGgudGhdKSB7XHJcbiAgICAgICAgICAgICAgICBsZWFmcy5wdXNoKHRoKTtcclxuICAgICAgICAgICAgICAgIGxldCB0bXAgPSB0aGlzLmp1bXBzVG9GaW5hbFBhcmVudCh0aCwgdGhzQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgaE1heExldmVsID0gdG1wID4gaE1heExldmVsID8gdG1wIDogaE1heExldmVsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4geyBsZWFmczogbGVhZnMsIGdyb3VwaW5nTGV2ZWw6IGhNYXhMZXZlbCwgcGFyZW50c0NhY2hlOiBwYXJlbnRzQ2FjaGUsIHRoc0NhY2hlOiB0aHNDYWNoZSB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2VuZXJhIGdsaSBoZWFkZXIgZ3JvdXBzIGRhIHVuYSBsaXN0YSBkaSBpbmZvIHN1aSB0aCBhbGwnaW50ZXJubyBkZWxsYSB2YXJpYWJpbGUgKipUTVBSb3dUaEdyb3VwcyoqXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHt7IGxlYWZzOiBFc1RoRGlyZWN0aXZlW10sIGdyb3VwaW5nTGV2ZWw6IG51bWJlciwgcGFyZW50c0NhY2hlOiBhbnksIHRoc0NhY2hlOiBhbnkgfX0gaW5mb3MgSW5mb3JtYXppb25pIGRpIHJhZ2dydXBwYW1lbnRvIHZhbHV0YXRlIHByZWNlZGVudGVtZW50ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZXZhbHVhdGVIZWFkZXJHcm91cHMoaW5mb3M6IHsgbGVhZnM6IEVzVGhEaXJlY3RpdmVbXTsgZ3JvdXBpbmdMZXZlbDogbnVtYmVyOyBwYXJlbnRzQ2FjaGU6IGFueTsgdGhzQ2FjaGU6IHsgW2luZGV4OnN0cmluZ106IEVzVGhEaXJlY3RpdmV9OyB9KSB7XHJcbiAgICAgICAgaWYgKGluZm9zLmdyb3VwaW5nTGV2ZWwgPT0gMClcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAvKioqKioqIFNURVAgMTogQ3JlbyBsJ291dHB1dCBkZWkgcmFnZ3J1cHBhbWVudGkgcGVyIGhlYWRlciBpbiBtb2RvIGRhIG5vbiBkb3Zlcm1pIHByZW9jY3VwYXJlIGRpIGNlbGxlIG5vbiBpbml6aWFsaXp6YXRlICoqKioqKi9cclxuXHJcbiAgICAgICAgbGV0IGV4cGFuZGVkR3JvdXBzID0gW107XHJcbiAgICAgICAgbGV0IHZpc2libGVVbnBpbm5lZExlYWZzOiBFc1RoRGlyZWN0aXZlW10gPSAoPGFueVtdPmluZm9zLmxlYWZzKS5maWx0ZXIoKHQ6IEVzVGhEaXJlY3RpdmUpID0+IHQudGhWaXNpYmxlICYmIHQudGhJZiAmJiAhdC50aFBpbm5lZCk7XHJcbiAgICAgICAgZm9yIChsZXQgbCA9IDA7IGwgPCBpbmZvcy5ncm91cGluZ0xldmVsOyBsKyspIHtcclxuICAgICAgICAgICAgZXhwYW5kZWRHcm91cHMucHVzaChbXSk7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmlzaWJsZVVucGlubmVkTGVhZnMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICBleHBhbmRlZEdyb3Vwc1tsXS5wdXNoKFwiXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqKioqKiBTVEVQIDI6IE9yZGlubyBsZSBmb2dsaWUgaW4gYmFzZSBhZ2xpIG9yZGluYW1lbnRpIGRlbGxlIGNvbG9ubmUgKioqKioqL1xyXG4gICAgICAgIGxldCBvcmRlcmVkTGVhZnMgPSBbXTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgbGVhZjogRXNUaERpcmVjdGl2ZSA9IGluZm9zLnRoc0NhY2hlW3RoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlc1tpXV07XHJcblxyXG4gICAgICAgICAgICAvLyBTb2xvIHNlIGxhIGxlYWYgw6ggcHJlc2VudGUuIFBvdHJlYmJlcm8gZXNzZXJjaSBvcmRpbmFtZW50aSBzdSBjb2xvbm5lIHNwYXJpdGVcclxuICAgICAgICAgICAgaWYgKGxlYWYgJiYgbGVhZi50aFZpc2libGUgJiYgbGVhZi50aElmICYmICFsZWFmLnRoUGlubmVkKVxyXG4gICAgICAgICAgICAgICAgb3JkZXJlZExlYWZzLnB1c2gobGVhZik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKioqKioqIFNURVAgMzogQ3JlbyBsJ2FycmF5IGdyb3VwIGNvbiB0dXR0aSBpIHJpZmVyaW1lbnRpIGRlbCBjYXNvICoqKioqKi9cclxuICAgICAgICBsZXQgY3VycmVudFBhcmVudCA9IFwiXCI7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcmRlcmVkTGVhZnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IHJlZlRoOiBFc1RoRGlyZWN0aXZlID0gb3JkZXJlZExlYWZzW2ldO1xyXG4gICAgICAgICAgICBsZXQgcHJldlRoOiBFc1RoRGlyZWN0aXZlID0gaSAtIDEgPj0gMCA/IG9yZGVyZWRMZWFmc1tpIC0gMV0gOiBudWxsO1xyXG5cclxuICAgICAgICAgICAgLy8gUGFyZW50IGRpdmVyc28gZGEgcHJpbWEsIG1ldHRvIGlsIGJvcmRvIGEgc2luaXN0cmEgZSBhIGRlc3RyYSBkZWxsYSBjZWxsYSBwcmVjZWRlbnRlIChzZSBjJ8OoKVxyXG4gICAgICAgICAgICAvLyBBbGwndWx0aW1vIGdpcm8gbWV0dG8gaWwgYm9yZG8gYSBkZXN0cmEuIFR1dHRvIHF1ZXN0byBsbyByaWVzZWd1byBwZXIgb2duaSBjZWxsYSBpbiBtb2RvIGRhIHJpcHVsaXJlIGV2ZW50dWFsaSBhIGN1aSBhdmV2byBhc3NlZ25hdG8gdGFnIHByZWNlZGVudGVtZW50ZVxyXG4gICAgICAgICAgICAoPGFueT5yZWZUaCkuX2xib3JkID0gcmVmVGgudGhQYXJlbnQgIT0gY3VycmVudFBhcmVudDtcclxuICAgICAgICAgICAgKDxhbnk+cmVmVGgpLl9yYm9yZCA9IHZpc2libGVVbnBpbm5lZExlYWZzLmxlbmd0aCA9PSBpICsgMTtcclxuICAgICAgICAgICAgaWYgKHByZXZUaClcclxuICAgICAgICAgICAgICAgICg8YW55PnByZXZUaCkuX3Jib3JkID0gcmVmVGgudGhQYXJlbnQgIT0gY3VycmVudFBhcmVudDtcclxuXHJcbiAgICAgICAgICAgIGN1cnJlbnRQYXJlbnQgPSByZWZUaC50aFBhcmVudDtcclxuXHJcbiAgICAgICAgICAgIC8vIFBlciBvZ25pIGdydXBwbyBzcm90b2xvIGlsIHBhcmVudCBuZWxsYSBtYXRyaWNlIGRlaSByYWdncnVwcGFtZW50aVxyXG4gICAgICAgICAgICBmb3IgKGxldCBsID0gMDsgbCA8IGluZm9zLmdyb3VwaW5nTGV2ZWw7IGwrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IHBhcmVudCA9IHJlZlRoLnRoUGFyZW50O1xyXG4gICAgICAgICAgICAgICAgaWYgKHBhcmVudCAmJiAhcmVmVGgudGhQaW5uZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBleHBhbmRlZEdyb3Vwc1tsXVtpXSA9IHBhcmVudDtcclxuICAgICAgICAgICAgICAgICAgICByZWZUaCA9IGluZm9zLnRoc0NhY2hlW3BhcmVudF07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKioqKiogU1RFUCA0OiBDb21wYXR0byBuZWxsJ2VsZW1lbnRvIGZpbmFsZSBzdSBjdWkgYmluZGFybWkuIEwnSUQgYXNzZWduYXRvIMOoIFNPTE8gcGVyIG90dGltaXp6YXJlIGdsaSBuZ0ZvciAqKioqKiovXHJcblxyXG4gICAgICAgIGN1cnJlbnRQYXJlbnQgPSBcIlwiO1xyXG4gICAgICAgIGxldCBjdXJyZW50U3BhbiA9IDA7XHJcbiAgICAgICAgbGV0IGZpbmFsSGVhZGVyczogeyBJRDogc3RyaW5nLCBTcGFuOiBudW1iZXI7IFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+OyBDb250ZW50Pzogc3RyaW5nLCBQaW5uZWQ/OiBib29sZWFuOyBCb3JkZXJzPzogYm9vbGVhbjsgfVtdW10gPSBbXTtcclxuICAgICAgICBmb3IgKGxldCBsID0gMDsgbCA8IGV4cGFuZGVkR3JvdXBzLmxlbmd0aDsgbCsrKSB7XHJcbiAgICAgICAgICAgIGxldCBsZXZlbEFycmF5OiB7IElEOnN0cmluZywgU3BhbjogbnVtYmVyOyBUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjsgQ29udGVudD86IHN0cmluZywgUGlubmVkPzogYm9vbGVhbjsgQm9yZGVycz86IGJvb2xlYW47IH1bXSA9IFtdO1xyXG4gICAgICAgICAgICBmaW5hbEhlYWRlcnMucHVzaChsZXZlbEFycmF5KTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVzdC5TZWxlY3Rpb24gfHwgdGhpcy5lc3QuSGFzUGlubmVkQ29sdW1ucylcclxuICAgICAgICAgICAgICAgIGxldmVsQXJyYXkucHVzaCh7IElEOiBcIl9iYXNlX3NlbF9waW5uZWRcIiwgU3BhbjogMSwgVGVtcGxhdGU6IG51bGwsIFBpbm5lZDogdGhpcy5lc3QuSGFzUGlubmVkQ29sdW1ucyB9KTtcclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGggPSAwOyBoIDwgZXhwYW5kZWRHcm91cHNbbF0ubGVuZ3RoOyBoKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCBpdGVtID0gZXhwYW5kZWRHcm91cHNbbF1baF07XHJcbiAgICAgICAgICAgICAgICBpZiAoaXRlbSA9PSBjdXJyZW50UGFyZW50KVxyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTcGFuKys7XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudFNwYW4gPiAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXZlbEFycmF5LnB1c2goeyBJRDogYCR7Y3VycmVudFBhcmVudCA/IGluZm9zLnRoc0NhY2hlW2N1cnJlbnRQYXJlbnRdLnRoIDogJ25vdGgnfV8ke2N1cnJlbnRTcGFufWAsIFNwYW46IGN1cnJlbnRTcGFuLCBUZW1wbGF0ZTogY3VycmVudFBhcmVudCA/IGluZm9zLnRoc0NhY2hlW2N1cnJlbnRQYXJlbnRdLlRlbXBsYXRlIDogbnVsbCwgQ29udGVudDogY3VycmVudFBhcmVudCA/IGluZm9zLnRoc0NhY2hlW2N1cnJlbnRQYXJlbnRdLl9tdWx0aV9jb250ZW50IDogbnVsbCwgQm9yZGVyczogISFjdXJyZW50UGFyZW50IH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTcGFuID0gMTtcclxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50UGFyZW50ID0gaXRlbTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gVWx0aW1hIGFnZ2l1bnRhIGNoZSBhbHRyaW1lbnRpIG1pIHJpbWFycmViYmUgaW4gY2FjaGVcclxuICAgICAgICAgICAgbGV2ZWxBcnJheS5wdXNoKHsgSUQ6IGAke2N1cnJlbnRQYXJlbnQgPyBpbmZvcy50aHNDYWNoZVtjdXJyZW50UGFyZW50XS50aCA6ICdub3RoJ31fJHtjdXJyZW50U3Bhbn1gLCBTcGFuOiBjdXJyZW50U3BhbiwgVGVtcGxhdGU6IGN1cnJlbnRQYXJlbnQgPyBpbmZvcy50aHNDYWNoZVtjdXJyZW50UGFyZW50XS5UZW1wbGF0ZSA6IG51bGwsIENvbnRlbnQ6IGN1cnJlbnRQYXJlbnQgPyBpbmZvcy50aHNDYWNoZVtjdXJyZW50UGFyZW50XS5fbXVsdGlfY29udGVudCA6IG51bGwgLCBCb3JkZXJzOiAhIWN1cnJlbnRQYXJlbnQgfSk7XHJcblxyXG4gICAgICAgICAgICAvLyBBZ2dpdW5nbyBpIHBlenpldHRpbmkgcGVyIGxhIHJpbW96aW9uZSBlIGdsaSBleHBvcnQsIHNlIHByZXNlbnRpXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVzdC5SZW1vdmFsKVxyXG4gICAgICAgICAgICAgICAgbGV2ZWxBcnJheS5wdXNoKHsgSUQ6IFwiX2Jhc2VfcmVtb3ZhbFwiLCBTcGFuOiAxLCBUZW1wbGF0ZTogbnVsbCB9KTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVzdC5FeHBvcnQgfHwgdGhpcy5lc3QuSGlkZGVuQ29sdW1ucyB8fCB0aGlzLmVzdC5Db2x1bW5zT3JkZXJpbmcgfHwgdGhpcy5lc3QuQ29ybmVyTWVudU9wdGlvbnMpXHJcbiAgICAgICAgICAgICAgICBsZXZlbEFycmF5LnB1c2goeyBJRDogXCJfYmFzZV9leHRyYV9vcHRzXCIsIFNwYW46IDEsIFRlbXBsYXRlOiBudWxsIH0pO1xyXG5cclxuICAgICAgICAgICAgY3VycmVudFNwYW4gPSAwO1xyXG4gICAgICAgICAgICBjdXJyZW50UGFyZW50ID0gXCJcIjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKioqKiogU1RFUCA1OiBTZWNjbyBsZSByaWdoZSBpbiBjdWkgbm9uIGMnw6ggbnVsbGEgKioqKioqL1xyXG5cclxuICAgICAgICB0aGlzLmVzdC5UTVBSb3dUaEdyb3VwcyA9IFtdO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZpbmFsSGVhZGVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBsZXQgbGV2ZWwgPSBmaW5hbEhlYWRlcnNbaV07XHJcbiAgICAgICAgICAgIGxldCBlbXB0eSA9IHRydWU7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbGV2ZWwubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCBpdGVtID0gbGV2ZWxbal07XHJcbiAgICAgICAgICAgICAgICBpZiAoaXRlbS5UZW1wbGF0ZSB8fCBpdGVtLkNvbnRlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBlbXB0eSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIWVtcHR5KVxyXG4gICAgICAgICAgICAgICAgdGhpcy5lc3QuVE1QUm93VGhHcm91cHMucHVzaChsZXZlbCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsY29sYSBpbCBudW1lcm8gZGkgc2FsdGkgZGEgdW4gaGVhZGVyIGZvZ2xpYSBhbGwndWx0aW1vIHBhcmVudCBkZWxsYSBjYXRlbmFcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VzVGhEaXJlY3RpdmV9IHRoIEhlYWRlciBkYSBjdWkgc2NvcnJlcmUgaSBwYWRyaSBwZXIgY2FwaXJlIHF1YW50aSBsaXZlbGxpIGNpIHNvbm8gc29wcmFcclxuICAgICAqIEBwYXJhbSB7eyBbaW5kZXg6IHN0cmluZ106IEVzVGhEaXJlY3RpdmUgfX0gdGhzQ2FjaGUgQ2FjaGUgZGVnbGkgaGVhZGVyXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUganVtcHNUb0ZpbmFsUGFyZW50KHRoOiBFc1RoRGlyZWN0aXZlLCB0aHNDYWNoZTogeyBbaW5kZXg6IHN0cmluZ106IEVzVGhEaXJlY3RpdmU7IH0pIHtcclxuICAgICAgICBsZXQganVtcHMgPSAwOyBsZXQgcGFyZW50ID0gbnVsbDsgbGV0IHBhcmVudHNQcmVwZW5kOiB7IGlkOiBzdHJpbmcsIHRtcGw/OiBUZW1wbGF0ZVJlZjxhbnk+LCBjb250ZW50Pzogc3RyaW5nIH1bXSA9IFtdO1xyXG4gICAgICAgIGxldCBiYXNlVGhSZWYgPSB0aDtcclxuICAgICAgICBkbyB7XHJcbiAgICAgICAgICAgIHBhcmVudCA9IHRoLnRoUGFyZW50O1xyXG4gICAgICAgICAgICBpZiAocGFyZW50KSB7XHJcbiAgICAgICAgICAgICAgICB0aCA9IHRoc0NhY2hlW3BhcmVudF07XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoLnRoRW1wdHkgJiYgIXRoLl9tdWx0aV9jb250ZW50KVxyXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudHNQcmVwZW5kLnVuc2hpZnQoeyBpZDogdGgudGgsIHRtcGw6IHRoLlRlbXBsYXRlIH0pO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoIXRoLnRoRW1wdHkgJiYgdGguX211bHRpX2NvbnRlbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50c1ByZXBlbmQudW5zaGlmdCh7IGlkOiB0aC50aCwgY29udGVudDogdGguX211bHRpX2NvbnRlbnQgfSk7XHJcbiAgICAgICAgICAgICAgICBqdW1wcysrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSB3aGlsZSAocGFyZW50KTtcclxuICAgICAgICBiYXNlVGhSZWYuX3RoUGFyZW50cyA9IHBhcmVudHNQcmVwZW5kO1xyXG4gICAgICAgIHJldHVybiBqdW1wcztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldG9kbyBjaGUgZ2VuZXJhIGwnb3JkaW5lIGRpIGRlZmF1bHQgZGVsbGUgY29sb25uZVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7QXBwU2VhcmNoPGFueT59IHZpZXcgQXBwU2VhcmNoIGRhIHV0aWxpenphcmUgcGVyIHF1ZXN0YSBvcGVyYXppb25lXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZW5lcmF0ZURlZmF1bHRPcmRlcih0aHM6IEVzVGhEaXJlY3RpdmVbXSwgdmlldzogQXBwU2VhcmNoPGFueT4pIHtcclxuICAgICAgICBpZiAodGhzLmxlbmd0aCA9PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIC8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogRml4IG9yZGluYW1lbnRpIHBlciBjb2xvbm5lIHNwYXJpdGUgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbiAgICAgICAgLy8gQ29uc2lkZXJvIHNvbG8gZ2xpIG9yZGluYW1lbnRpIHBlciBjb2xvbm5lIGVmZmV0dGl2YW1lbnRlIHByZXNlbnRpIGFsbCdpbnRlcm5vIGRlbGxhIHRhYmVsbGFcclxuICAgICAgICBpZiAodGhpcy5lc3Qudmlld01vZGUpXHJcbiAgICAgICAgICAgIHZpZXcuY29sdW1uX29yZGVyaW5nID0gdmlldy5jb2x1bW5fb3JkZXJpbmcuZmlsdGVyKG9yZCA9PiB0aHMuZmluZCh0ID0+IHQudGggPT0gb3JkKSk7XHJcbiAgICAgICAgLy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBGaXggb3JkaW5hbWVudGkgcGVyIGNvbG9ubmUgc3Bhcml0ZSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuXHJcbiAgICAgICAgbGV0IG9yZGVyaW5ncyA9IHRoaXMuZXN0LnZpZXdNb2RlID8gdmlldy5jb2x1bW5fb3JkZXJpbmcgOiB0aGlzLmVzdC5hcnJheUNvbHVtbk9yZGVyaW5nO1xyXG5cclxuICAgICAgICAvLyBHZW5lcm8gb3JkaW5hbWVudG8gZGkgZGVmYXVsdCBkYSAwIGZpbm8gYSBkb3ZlIGRldmUgYXJyaXZhcmUuIFNpdHVhemlvbmUgYXR0dWFsZSBzZW56YSBob3Rwb3RhdG9cclxuICAgICAgICBpZiAoIW9yZGVyaW5ncyB8fCBvcmRlcmluZ3MubGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCB0aCA9IHRoc1tpXTtcclxuICAgICAgICAgICAgICAgIGxldCBvcmRlciA9IHRoLnRoO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5lc3QuT3JkZXJEaXJlY3RpdmVzLnB1c2gob3JkZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmVzdC5PcmRlckRpcmVjdGl2ZXMgPSBvcmRlcmluZ3M7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgdGggPSB0aHNbaV07XHJcbiAgICAgICAgICAgICAgICBsZXQgdGhJZCA9IHRoLnRoO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmVzdC5PcmRlckRpcmVjdGl2ZXMuZmluZChvID0+IG8gPT0gdGhJZCkpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lc3QuT3JkZXJEaXJlY3RpdmVzLnB1c2godGhJZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBcHBsaWNhIGwnb3JkaW5lIHNwZWNpZmljYXRvIGFsbGUgdmFyaWUgY29sb25uZVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7QXBwU2VhcmNoPGFueT59IHZpZXcgQXBwU2VhcmNoIGRhIHV0aWxpenphcmUgcGVyIHF1ZXN0YSBvcGVyYXppb25lXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGZpbmFsaXplIFNlICoqdHJ1ZSoqIHNpZ25pZmljYSBjaGUgbm9uIG1pIGFzcGV0dG8gZGkgZG92ZXIgZWZmZXR0dWFyZSBhbHRyZSBvcGVyYXppb25pIGUgcG9zc28gcmVuZGVyaXp6YXJlIGxhIHNpdHVhemlvbmUgaW4gYmFzZSBhaSBSb3dDb250ZXh0XHJcbiAgICAgKiBTZW56YSBmaW5hbGl6ZSBzaWduaWZpY2EgY2hlIG1pIGFzcGV0dG8gYWx0cmUgb3BlcmF6aW9uaSBjaGUgcHJpbWEgbyBwb2kgcmljaGlhbWVyYW5ubyBxdWVzdGEgZnVuemlvbmUgY29sIGZpbmFsaXplLlxyXG4gICAgICpcclxuICAgICAqIEFkIGVzZW1waW8sIHVuYSB2b2x0YSBzZWxlemlvbmF0byBvcmRpbmFtZW50byBmaXNpY28vbG9naWNvIGRlbGxlIGNvbG9ubmUgc28gY2hlIHBhcnRlIHVuIGFsdHJhIHJpY2VyY2EgY2hlIG1pIHJpdmFsb3JpenplcsOgIGRhIFwid3JpdGVWYWx1ZVwiLCBjaGUgZ2nDoCBjaGlhbWEgcXVlc3RhIGZ1bnppb25lLlxyXG4gICAgICogTWV0dGVuZG8gc29sbyBsYSBjaGlhbWF0YSBkYSBcIndyaXRlVmFsdWVcIiBjb21lIFwiZmluYWxpenphbnRlXCIgbWkgYXNzaWN1cm8gY2hlIHNtYW5hdHRhbWVudGkgYSBmcm9udGVuZCBub24gY2F1c2lubyBmbGlja2VyaW5nIGZpbm8gYSBxdWFuZG8gbm9uIHNlcnZvbm9cclxuICAgICAqL1xyXG4gICAgcHVibGljIGFwcGx5T3JkZXJpbmcodmlldzogQXBwU2VhcmNoPGFueT4sIGZpbmFsaXplOiBib29sZWFuKSB7XHJcbiAgICAgICAgLy8gR2VuZXJvIG9yZGluYW1lbnRvIHBlciBnbGkgaGVhZGVyXHJcbiAgICAgICAgbGV0IG5ld0hlYWRlcnMgPSBbXTtcclxuXHJcbiAgICAgICAgLy8gU2UgZGV2byBmaW5hbGl6emFyZSBhZ2dhbmNpbyB0dXR0ZSBsZSB2YXJpYWJpbGkgZGkgYmluZFxyXG4gICAgICAgIGlmIChmaW5hbGl6ZSkge1xyXG4gICAgICAgICAgICB0aGlzLmVzdC5PcmRlckRpcmVjdGl2ZXMuZm9yRWFjaChvID0+IHtcclxuICAgICAgICAgICAgICAgIGxldCBoZWFlZHJJdGVtID0gdGhpcy5lc3QuVE1QUm93VEhzLmZpbHRlcih0ID0+IHQuSUQgPT0gbylbMF07XHJcbiAgICAgICAgICAgICAgICBpZiAoaGVhZWRySXRlbSlcclxuICAgICAgICAgICAgICAgICAgICBuZXdIZWFkZXJzLnB1c2goaGVhZWRySXRlbSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB0aGlzLmVzdC5UTVBSb3dUSHMgPSBuZXdIZWFkZXJzO1xyXG5cclxuICAgICAgICAgICAgLy8gR2VuZXJvIG9yZGluYW1lbnRvIHBlciBsZSBjZWxsZVxyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZXN0LlJvd0NvbnRleHRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgY29udGV4dCA9IHRoaXMuZXN0LlRNUFJvd1REc1t0aGlzLmVzdC5Sb3dDb250ZXh0c1tpXV07XHJcbiAgICAgICAgICAgICAgICBsZXQgbmV3Q29udGV4dCA9IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcy5mb3JFYWNoKG8gPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBjb250ZXh0SXRlbSA9IGNvbnRleHQuZmlsdGVyKHQgPT4gdC5JRCA9PSBvKVswXTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBwb3RyZWJiZSBlc3NlciB1bmRlZmluZWQgbmVsIGNhc28gY2kgZm9zc2VybyBjb2xvbm5lIHNvdHRvIHRoSWZcclxuICAgICAgICAgICAgICAgICAgICBpZihjb250ZXh0SXRlbSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3Q29udGV4dC5wdXNoKGNvbnRleHRJdGVtKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuZXN0LlRNUFJvd1REc1t0aGlzLmVzdC5Sb3dDb250ZXh0c1tpXV0gPSBuZXdDb250ZXh0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5lc3Qudmlld01vZGUpXHJcbiAgICAgICAgICAgIHZpZXcuY29sdW1uX29yZGVyaW5nID0gdGhpcy5lc3QuT3JkZXJEaXJlY3RpdmVzO1xyXG5cclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHRoaXMuZXN0LmFycmF5Q29sdW1uT3JkZXJpbmcgPSB0aGlzLmVzdC5PcmRlckRpcmVjdGl2ZXM7XHJcblxyXG4gICAgICAgIHRoaXMuZXN0LmNoYW5nZWQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAqIEFsbCdpbnRlcm5vIGRlbGxhIGRpYWxvZyBcIk9yZGluYW1lbnRvIGUgVmlzaWJpbGl0w6AgQ29sb25uZVwiIG1ldHRlIGxhIGNvbG9ubmEgc3BlY2lmaWNhdGEgcHJpbWEgZGVsbGEgY29sb25uYSBwcmVjZWRlbnRlXHJcbiAgKlxyXG4gICogQHBhcmFtIHtFc1RhYmxlQ29sdW1ufSBjb2x1bW5JdGVtIENvbG9ubmEgZGEgc3Bvc3RhcmVcclxuICAqL1xyXG4gICAgcHVibGljIHNlbmRVcChjb2x1bW5JdGVtOiBFc1RhYmxlQ29sdW1uKSB7XHJcbiAgICAgICAgbGV0IGl0ZW1JbmRleCA9IHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LmluZGV4T2YoY29sdW1uSXRlbSk7XHJcbiAgICAgICAgaWYgKHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0W2l0ZW1JbmRleCAtIDFdLmZpeGVkIHx8IHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0W2l0ZW1JbmRleCAtIDFdLnBpbm5lZClcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIHRoaXMudXRpRXh0cy5zd2FwKHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LCBpdGVtSW5kZXgsIGl0ZW1JbmRleCAtIDEpO1xyXG5cclxuICAgICAgICAvLyBOb24gcG9zc28gZmFyZSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMuQ29sdW1uc0xpc3QpKSBwZXJjaMOpIGNvbnRpZW5lIHJpZmVyaW1lbnRpIGEgVGVtcGxhdGVSZWZcclxuICAgICAgICBsZXQgdG1wID0gW107XHJcbiAgICAgICAgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QuZm9yRWFjaChjID0+IHsgdG1wLnB1c2goT2JqZWN0LmFzc2lnbih7fSwgYykpOyB9KTtcclxuICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdCA9IHRtcDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFsbCdpbnRlcm5vIGRlbGxhIGRpYWxvZyBcIk9yZGluYW1lbnRvIGUgVmlzaWJpbGl0w6AgQ29sb25uZVwiIG1ldHRlIGxhIGNvbG9ubmEgc3BlY2lmaWNhdGEgZG9wbyBsYSBjb2xvbm5hIHN1Y2Nlc3NpdmFcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VzVGFibGVDb2x1bW59IGNvbHVtbkl0ZW0gQ29sb25uYSBkYSBzcG9zdGFyZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2VuZERvd24oY29sdW1uSXRlbTogRXNUYWJsZUNvbHVtbikge1xyXG4gICAgICAgIGxldCBpdGVtSW5kZXggPSB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5pbmRleE9mKGNvbHVtbkl0ZW0pO1xyXG4gICAgICAgIHRoaXMudXRpRXh0cy5zd2FwKHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LCBpdGVtSW5kZXgsIGl0ZW1JbmRleCArIDEpO1xyXG5cclxuICAgICAgICAvLyBOb24gcG9zc28gZmFyZSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMuQ29sdW1uc0xpc3QpKSBwZXJjaMOpIGNvbnRpZW5lIHJpZmVyaW1lbnRpIGEgVGVtcGxhdGVSZWZcclxuICAgICAgICBsZXQgdG1wID0gW107XHJcbiAgICAgICAgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QuZm9yRWFjaChjID0+IHsgdG1wLnB1c2goT2JqZWN0LmFzc2lnbih7fSwgYykpOyB9KTtcclxuICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdCA9IHRtcDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFsbCdpbnRlcm5vIGRlbGxhIGRpYWxvZyBcIk9yZGluYW1lbnRvIGUgVmlzaWJpbGl0w6AgQ29sb25uZVwiIHBpbm5hIGxhIGNvbG9ubmEgc3BlY2lmaWNhdGFcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VzVGFibGVDb2x1bW59IGNvbHVtbkl0ZW0gQ29sb25uYSBkYSBzcG9zdGFyZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcGluT3JVbnBpbkNvbHVtbihjb2x1bW5JdGVtOiBFc1RhYmxlQ29sdW1uKSB7XHJcbiAgICAgICAgbGV0IGl0ZW1JbmRleCA9IHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LmluZGV4T2YoY29sdW1uSXRlbSk7XHJcbiAgICAgICAgaWYgKCFjb2x1bW5JdGVtLnBpbm5lZCkge1xyXG4gICAgICAgICAgICBjb2x1bW5JdGVtLnByZXZfaW5kZXggPSBpdGVtSW5kZXg7XHJcblxyXG4gICAgICAgICAgICAvL1F1YW5kbyBwaW5ubyBkZXZvIHNwb3N0YXJlIGwnZWxlbWVudG8gY29tZSB1bHRpbWEgY29sb25uYSBwaW5uYXRhIG8gY29tZSBwcmltYSBjb2xvbm5hIHNlIG5vbiBjZSBuZSBzb25vIGRpIHBpbm5hdGVcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdFtpXS5waW5uZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnV0aWxpdGllcy5hcnJheU1vdmUodGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QsIGl0ZW1JbmRleCwgaSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vUXVhbmRvIHNwaW5ubyByaXBvcnRvIGwnZWxlbWVudG8gYWxsbyBzdGVzc28gaW5kaWNlIGluIGN1aSBlcmEgcHJpbWEgKHNlIHNvbm8gc3RhdGkgZmF0dGkgc3Bvc3RhbWVudGkgbmVsIG1lenpvIGNhenppIGRlbGwndXRlbnRlKVxyXG4gICAgICAgICAgICBpZiAoY29sdW1uSXRlbS5wcmV2X2luZGV4ICE9IG51bGwgJiYgY29sdW1uSXRlbS5wcmV2X2luZGV4ICE9IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgIHRoaXMudXRpbGl0aWVzLmFycmF5TW92ZSh0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdCwgaXRlbUluZGV4LCBjb2x1bW5JdGVtLnByZXZfaW5kZXgpO1xyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIFNlIHNwaW5ubyBzZW56YSB1biBwcmV2X2luZGV4IHZ1b2wgZGlyZSBjaGUgbGEgY29sb25uYSBlcmEgcGlubmF0YSBkYSBjb25maWd1cmF6aW9uZS4gTGEgc3Bvc3RvIG5lbCBwcmltbyBwdW50byBkaXNwb25pYmlsZVxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3RbaV0ucGlubmVkICYmICF0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdFtpXS5maXhlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnV0aWxpdGllcy5hcnJheU1vdmUodGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QsIGl0ZW1JbmRleCwgaSAtIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbHVtbkl0ZW0ucGlubmVkID0gIWNvbHVtbkl0ZW0ucGlubmVkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsJ2ludGVybm8gZGVsbGEgZGlhbG9nIFwiT3JkaW5hbWVudG8gZSBWaXNpYmlsaXTDoCBDb2xvbm5lXCIgaW52ZXJ0ZSBsZSBpbXBvc3RhemlvbmkgZGkgdmlzaWJpbGl0w6AgZGVsbGEgY29sb25uYVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RXNUYWJsZUNvbHVtbn0gY29sdW1uSXRlbSBDb2xvbm5hIGRhIHNwb3N0YXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb2x1bW5DbGlja2VkKGl0ZW06IEVzVGFibGVDb2x1bW4pIHtcclxuICAgICAgICB0aGlzLmVzdC5sYXN0U2VsZWN0ZWRJdGVtSUQgPSBpdGVtLmlkO1xyXG4gICAgICAgIGlmICghdGhpcy5lc3QuSGlkZGVuQ29sdW1ucyB8fCBpdGVtLmZpeGVkKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGl0ZW0udmlzaWJsZSA9ICFpdGVtLnZpc2libGU7XHJcbiAgICAgICAgdGhpcy51cGRhdGVHbG9iYWxDb2xWaXNDaGVjaygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBBbGwnYXBlcnR1cmEgZGVsbGEgZGlhbG9nIFwiT3JkaW5hbWVudG8gZSBWaXNpYmlsaXTDoCBDb2xvbm5lXCIgcmljYXJpY2EgbGUgaW5mb3JtYXppb25pIGF0dHVhbGkgcGVyIHBlcm1ldHRlcmUgbGEgbW9kaWZpY2EgKi9cclxuICAgIHB1YmxpYyByZXNldENvbHVtblZpc1NlbGVjdGlvbigpIHtcclxuICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdCA9IFtdO1xyXG4gICAgICAgIC8vIE5vbiBwb3NzbyBmYXJlIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5Db2x1bW5zTGlzdCkpIHBlcmNow6kgY29udGllbmUgcmlmZXJpbWVudGkgYSBUZW1wbGF0ZVJlZlxyXG4gICAgICAgIHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0ID0gW107XHJcbiAgICAgICAgdGhpcy5lc3QuQ29sdW1uc0xpc3QuZm9yRWFjaChjID0+IHsgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QucHVzaChPYmplY3QuYXNzaWduKHt9LCBjKSk7IH0pO1xyXG5cclxuICAgICAgICBsZXQgcmVvcmRlcmVkQ29sTGlzdCA9IFtdO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5lc3QuQ29sdW1uc09yZGVyaW5nKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcy5mb3JFYWNoKG8gPT4ge1xyXG4gICAgICAgICAgICAgICAgbGV0IGNvbHVtbiA9IHRoaXMuZXN0LlRNUENvbHVtbnNMaXN0LmZpbHRlcih0ID0+IHQuaWQgPT0gbylbMF07XHJcbiAgICAgICAgICAgICAgICAvLyBQb3RyZWkgbm9uIGF2ZXJuZSBuZWwgY2FzbyBjaSBzaWEgaWwgZmxhZyBIaWRkZW5Db2x1bW5zIGEgZmFsc2UsIGV2aXRvIGRpIGluc2VyaXJlIGRlZ2xpIHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICAgaWYgKGNvbHVtbilcclxuICAgICAgICAgICAgICAgICAgICByZW9yZGVyZWRDb2xMaXN0LnB1c2goY29sdW1uKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdCA9IHJlb3JkZXJlZENvbExpc3Q7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnVwZGF0ZUdsb2JhbENvbFZpc0NoZWNrKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFJpYWdnaW9ybmEgbGUgKipPcmRlckRpcmVjdGl2ZXMqKiBjb24gbGUgaW5mb3JtYXppb25pIGluICAqKkNvbHVtbnNMaXN0KiogKi9cclxuICAgIHByaXZhdGUgcmVmcmVzaENvbHVtbk9yZGVyaW5nKCkge1xyXG4gICAgICAgIHRoaXMuZXN0Lk9yZGVyRGlyZWN0aXZlcyA9IFtdO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBjID0gMDsgYyA8IHRoaXMuZXN0LkNvbHVtbnNMaXN0Lmxlbmd0aDsgYysrKVxyXG4gICAgICAgICAgICB0aGlzLmVzdC5PcmRlckRpcmVjdGl2ZXMucHVzaCh0aGlzLmVzdC5Db2x1bW5zTGlzdFtjXS5pZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEVmZmV0dHVhIGxhIHNlbGV6aW9uZSBvIG1lbm8gZGVsIGNoZWNrIGdsb2JhbGUgKCoqZ2xvYmFsQ29sVmlzQ2hlY2sqKikgZGkgdmlzaWJpbGl0w6AgaW4gYmFzZSBhIHNlIHR1dHRlIGxlICoqVE1QQ29sdW1uc0xpc3QqKiBzb25vIHZpc2liaWxpIG8gbm8gKi9cclxuICAgIHB1YmxpYyB1cGRhdGVHbG9iYWxDb2xWaXNDaGVjaygpIHtcclxuICAgICAgICAvLyBUTVBDb2xMaXN0IHZpZW5lIHJpZW1waXRhIGRpIHVuZGVmaW5lZCBuZWwgY2FzbyBpbiBjdWkgc2lhIGRpc2F0dGl2YXRhIGxhIHNlbGV6aW9uZSBkZWxsZSBjb2xvbm5lIG5hc2Nvc3RlXHJcbiAgICAgICAgdGhpcy5lc3QuZ2xvYmFsQ29sVmlzQ2hlY2sgPSB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5ldmVyeSh0ID0+IHQudmlzaWJsZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDaGlhbWF0byBxdWFuZG8gdW5hIGNvbG9ubmEgdmllbmUgcmlvcmRpbmF0YSBhbGwnaW50ZXJubyBkZWxsYSBsaXN0YSBkZWxsZSB2aXNpYmlsaXTDoC9wb3NpemlvbmkgY29sb25uZVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0Nka0RyYWdEcm9wPEVzVGFibGVDb2x1bW5bXT59IGV2ZW50IEV2ZW50byBkaSBkcm9wIGRlbGxhIGxpc3RhXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb2x1bW5SZW9yZGVyZWQoZXZlbnQ6IENka0RyYWdEcm9wPEVzVGFibGVDb2x1bW5bXT4pIHtcclxuICAgICAgICBtb3ZlSXRlbUluQXJyYXkoZXZlbnQuY29udGFpbmVyLmRhdGEsIGV2ZW50LnByZXZpb3VzSW5kZXgsIGV2ZW50LmN1cnJlbnRJbmRleCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDaGlhbWF0byBxdWFuZG8gdW5hIGNvbG9ubmEgdmllbmUgcmlvcmRpbmF0YSBhbGwnaW50ZXJubyBkZWxsYSBsaXN0YSBkZWxsZSB2aXNpYmlsaXTDoC9wb3NpemlvbmkgY29sb25uZVxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggSW5kaWNlIGluIGN1aSB2b2dsaW8gZHJvcHBhcmUgbCdlbGVtZW50byBkcmFnZ2F0b1xyXG4gICAgICogQHBhcmFtIHtDZGtEcmFnPEVzVGFibGVDb2x1bW4+fSBpdGVtIE9nZ2V0dG8gY2hlIHN0byBkcmFnZ2FuZG9cclxuICAgICAqIFxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59ICoqdHJ1ZSoqIHNlIGxhIGNvbG9ubmEgcHXDsiBlc3NlcmUgc3Bvc3RhdGEgc3VsbCdpbmRpY2UgKippbmRleCoqLCAqKmZhbHNlKiogYWx0cmltZW50aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc29ydFByZWRpY2F0ZShpbmRleDogbnVtYmVyLCBpdGVtOiBDZGtEcmFnPEVzVGFibGVDb2x1bW4+KTogYm9vbGVhbiB7XHJcbiAgICAgICAgbGV0IGl0ZW1BdEluZGV4ID0gdGhpcy5lc3QuQ29sdW1uc0xpc3RbaW5kZXhdO1xyXG4gICAgICAgIHJldHVybiAhaXRlbUF0SW5kZXguZml4ZWQgJiYgIWl0ZW1BdEluZGV4LnBpbm5lZCAmJiAhaXRlbS5kYXRhLnBpbm5lZCAmJiAhaXRlbS5kYXRhLnBpbm5lZDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZ1bnppb25lIGNoZSBlZmZldHR1YSBsYSBjb25mZXJtYSBkZWxsYSB2aXNpYmlsaXTDoCBlIGRlbGwnb3JkaW5lIGRlbGxlIGNvbG9ubmUuXHJcbiAgICAgKlxyXG4gICAgICogUXVlc3RhIHNlbGV6aW9uZSB2aWVuZSBpbm9sdHJlIHNhbHZhdGEgbmVsbGUgcHJlZmVyZW56ZSAoKipAZXNmYWVuemEvcHJlZmVyZW5jZXMqKiksIHF1YWxvcmEgbCdJbnB1dCAqKlNhdmVQcmVmZXJlbmNlcyoqIGZvc3NlIHZhbG9yaXp6YXRvXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59ICoqdHJ1ZSoqIHNlIG5vbiBjaSBzb25vIHByb2JsZW1pLCAqKmZhbHNlKiogYWx0cmltZW50aVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY29uZmlybUNvbHVtblZpc2liaWxpdHlTZWxlY3Rpb24oKTogYm9vbGVhbiB7XHJcbiAgICAgICAgLy8gTm9uIHBlcm1ldHRvIGRpIG5vbiBzZWxlemlvbmFyZSBudWxsYVxyXG4gICAgICAgIGlmICh0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5ldmVyeSh0ID0+ICF0LnZpc2libGUpKVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgICAgIGxldCBjYXN0ZWRWaWV3ID0gdGhpcy5lc3Qudmlld01vZGUgPyAodGhpcy5lc3QuTWFpbkdyb3VwVmlldyB8fCB0aGlzLmVzdC5WaWV3IGFzIEFwcFNlYXJjaDxhbnk+KSA6IG51bGw7XHJcbiAgICAgICAgdGhpcy5lc3QuQ29sdW1uc0xpc3QgPSBbXTtcclxuICAgICAgICB0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5mb3JFYWNoKGMgPT4geyB0aGlzLmVzdC5Db2x1bW5zTGlzdC5wdXNoKE9iamVjdC5hc3NpZ24oe30sIGMpKTsgfSk7XHJcblxyXG4gICAgICAgIHRoaXMucmVmcmVzaENvbHVtbk9yZGVyaW5nKCk7XHJcbiAgICAgICAgdGhpcy5hcHBseU9yZGVyaW5nKGNhc3RlZFZpZXcsIGZhbHNlKTtcclxuXHJcbiAgICAgICAgdGhpcy5yZWZyZXNoQ29sdW1uc1Zpc2liaWxpdHkobnVsbCwgbnVsbCwgY2FzdGVkVmlldyk7XHJcblxyXG4gICAgICAgIC8vU2Fsdm8gbGUgcHJlZmVyZW5jZXMgZGkgcXVlc3RhIHZpZXdcclxuICAgICAgICAvL0RpIGRlZmF1bHQgcmVnaXN0cm8gb3JkaW5hbWVudG8gZSB2aXNpYmlsaXTDoCBkZWxsZSBjb2xvbm5lIG5lbGxhIHZpc3RhLiBTb2xvIGxlIGNvc2UgZGkgVUlcclxuICAgICAgICBpZiAodGhpcy5lc3QuU2F2ZVByZWZlcmVuY2VzKSBcclxuICAgICAgICAgICAgdGhpcy5yZWdpc3RlclZpZXdQcmVmZXJlbmNlcyhjYXN0ZWRWaWV3KTtcclxuXHJcbiAgICAgICAgLy8gUmllc2VndW8gbCd1bHRpbWEgcmljZXJjYSBiaW5kYXRhIGFsbGEgdGFiZWxsYVxyXG4gICAgICAgIC8vIE1pIGFzc2ljdXJvIGRpIGZhcmxvIGRvcG8gbCdlc3BhbnNpb25lIGRlbCBjaGFuZ2VkIG8gcmlzY2hpbyBjaGUgbGEgcmljZXJjYSBtaSByaWRpYSBjb2xvbm5lIGNoZSBpbiByZWFsdMOgIG5vbiBlc2lzdG9ub1xyXG4gICAgICAgIGlmICh0aGlzLmVzdC52aWV3TW9kZSlcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5lc3QuTWFpbkdyb3VwVmlldykge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy5lbWl0U2VhcmNoUmVxdWVzdCh0cnVlLCB0aGlzLk1haW5Hcm91cFZpZXcpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5lc3QuZ3JvdXBTZWFyY2hSZXF1ZXN0c0NhY2hlLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB2aWV3ID0gdGhpcy5lc3QuZ3JvdXBTZWFyY2hSZXF1ZXN0c0NhY2hlW2ldLnZpZXc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZXcuY29sdW1ucyA9IHRoaXMuZXN0Lk1haW5Hcm91cFZpZXcuY29sdW1ucztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmlldy5jb2x1bW5fb3JkZXJpbmcgPSB0aGlzLmVzdC5NYWluR3JvdXBWaWV3LmNvbHVtbl9vcmRlcmluZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lc3QuZW1pdFNlYXJjaFJlcXVlc3QodHJ1ZSwgdGhpcy5lc3QuZ3JvdXBTZWFyY2hSZXF1ZXN0c0NhY2hlW2ldLnZpZXcpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lc3QuZW1pdFNlYXJjaFJlcXVlc3QodHJ1ZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuZXN0LmFycmF5TW9kZSlcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IHRoaXMuZXN0LmludGVybmFsV3JpdGVWYWx1ZSgpOyB9KTtcclxuXHJcbiAgICAgICAgLy8gTG8gdm9ycmVpIG1ldHRlcmUgbGF0byB0ZW1wbGF0ZSBtYSBub1xyXG4gICAgICAgIHRoaXMuZXN0Lmxhc3RTZWxlY3RlZEl0ZW1JRCA9IG51bGw7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFZmZldHR1byBsJ3VucGlubmluZyBkaSB1bmEgY29sb25uYSBpbiBtYW5pZXJhIHByb2dyYW1tYXRpY2Egc2VtcGxpY2VtZW50ZSBlc2VndWVuZG8gdW5hIHBlciB1bmEgbGUgb3BlcmF6aW9uaSBjaGUgdmVycmViYmVybyBlc2VndWl0ZSBhbHRyaW1lbnRpXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlkIENvZGljZSBkZWxsYSBjb2xvbm5hIGRhIHNwaW5uYXJlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB1bnBpbkNvbHVtbihpZDogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5yZXNldENvbHVtblZpc1NlbGVjdGlvbigpO1xyXG4gICAgICAgIHRoaXMucGluT3JVbnBpbkNvbHVtbih0aGlzLmVzdC5UTVBDb2x1bW5zTGlzdC5maW5kKHQgPT4gdC5pZCA9PSBpZCkpO1xyXG4gICAgICAgIHRoaXMuY29uZmlybUNvbHVtblZpc2liaWxpdHlTZWxlY3Rpb24oKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogU3VsIGNsaWNrIG5lbGxhIGNoZWNrYm94IGRpIHNlbGV6aW9uZSBnbG9iYWxlIHNpIHNjb3Jyb25vIHR1dHRlIGxlIGNvbG9ubmUgZSBzaSBpbXBvc3Rhbm8gYWwgdmFsb3JlIGRlbGxhIGNoZWNrIGdsb2JhbGUgKi9cclxuICAgIHB1YmxpYyBnbG9iYWxDb2xWaXNDaGVja0NoYW5nZWQoKSB7XHJcbiAgICAgICAgdGhpcy5lc3QuVE1QQ29sdW1uc0xpc3QuZm9yRWFjaCh0ID0+IHtcclxuICAgICAgICAgICAgaWYgKCF0LmZpeGVkKVxyXG4gICAgICAgICAgICAgICAgdC52aXNpYmxlID0gdGhpcy5lc3QuZ2xvYmFsQ29sVmlzQ2hlY2s7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIl19