@esfaenza/es-table 12.2.20 → 12.2.21

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