@esfaenza/es-table 13.1.9 → 13.1.13

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