@lumeer/pivot 0.0.13 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/lumeer-pivot.mjs +56 -43
- package/fesm2022/lumeer-pivot.mjs.map +1 -1
- package/index.d.ts +332 -5
- package/lumeer-pivot-0.2.0.tgz +0 -0
- package/package.json +4 -6
- package/esm2022/lib/directives/lmr-templates.directive.mjs +0 -27
- package/esm2022/lib/lmr-pivot-table.component.mjs +0 -147
- package/esm2022/lib/lmr-pivot-table.module.mjs +0 -63
- package/esm2022/lib/lmr-simple-pivot-table.component.mjs +0 -101
- package/esm2022/lib/pipes/cell-has-value.pipe.mjs +0 -35
- package/esm2022/lib/pipes/contrast-color.pipe.mjs +0 -41
- package/esm2022/lib/pipes/filter-visible-cells.pipe.mjs +0 -35
- package/esm2022/lib/pipes/is-cell-expandable.pipe.mjs +0 -35
- package/esm2022/lib/pipes/is-cell-expanded.pipe.mjs +0 -37
- package/esm2022/lib/pipes/is-cell-rows-expandable.pipe.mjs +0 -35
- package/esm2022/lib/pipes/pivot-data-empty.pipe.mjs +0 -38
- package/esm2022/lib/util/lmr-pivot-config.mjs +0 -17
- package/esm2022/lib/util/lmr-pivot-constants.mjs +0 -12
- package/esm2022/lib/util/lmr-pivot-data.mjs +0 -2
- package/esm2022/lib/util/lmr-pivot-state.mjs +0 -156
- package/esm2022/lib/util/lmr-pivot-table.mjs +0 -2
- package/esm2022/lib/util/lmr-simple-pivot-config.mjs +0 -2
- package/esm2022/lib/util/pivot-data-converter.mjs +0 -507
- package/esm2022/lib/util/pivot-table-converter.mjs +0 -1017
- package/esm2022/lib/util/pivot-util.mjs +0 -75
- package/esm2022/lumeer-pivot.mjs +0 -5
- package/esm2022/public-api.mjs +0 -13
- package/lib/directives/lmr-templates.directive.d.ts +0 -14
- package/lib/lmr-pivot-table.component.d.ts +0 -49
- package/lib/lmr-pivot-table.module.d.ts +0 -18
- package/lib/lmr-simple-pivot-table.component.d.ts +0 -38
- package/lib/pipes/cell-has-value.pipe.d.ts +0 -8
- package/lib/pipes/contrast-color.pipe.d.ts +0 -11
- package/lib/pipes/filter-visible-cells.pipe.d.ts +0 -9
- package/lib/pipes/is-cell-expandable.pipe.d.ts +0 -8
- package/lib/pipes/is-cell-expanded.pipe.d.ts +0 -9
- package/lib/pipes/is-cell-rows-expandable.pipe.d.ts +0 -8
- package/lib/pipes/pivot-data-empty.pipe.d.ts +0 -8
- package/lib/util/lmr-pivot-config.d.ts +0 -84
- package/lib/util/lmr-pivot-constants.d.ts +0 -11
- package/lib/util/lmr-pivot-data.d.ts +0 -50
- package/lib/util/lmr-pivot-state.d.ts +0 -14
- package/lib/util/lmr-pivot-table.d.ts +0 -25
- package/lib/util/lmr-simple-pivot-config.d.ts +0 -9
- package/lib/util/pivot-data-converter.d.ts +0 -46
- package/lib/util/pivot-table-converter.d.ts +0 -74
- package/lib/util/pivot-util.d.ts +0 -12
- package/lumeer-pivot-0.0.13.tgz +0 -0
- package/public-api.d.ts +0 -9
|
@@ -1,1017 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Lumeer: Modern Data Definition and Processing Platform
|
|
3
|
-
*
|
|
4
|
-
* Copyright (C) since 2017 Lumeer.io, s.r.o. and/or its affiliates.
|
|
5
|
-
*
|
|
6
|
-
* This program is free software: you can redistribute it and/or modify
|
|
7
|
-
* it under the terms of the GNU General Public License as published by
|
|
8
|
-
* the Free Software Foundation, either version 3 of the License, or
|
|
9
|
-
* (at your option) any later version.
|
|
10
|
-
*
|
|
11
|
-
* This program is distributed in the hope that it will be useful,
|
|
12
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
-
* GNU General Public License for more details.
|
|
15
|
-
*
|
|
16
|
-
* You should have received a copy of the GNU General Public License
|
|
17
|
-
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
-
*/
|
|
19
|
-
import { aggregateDataValues, DataAggregationType, isValueAggregation, NumberConstraint, PercentageConstraint, UnknownConstraint, } from '@lumeer/data-filters';
|
|
20
|
-
import { createRange, deepObjectCopy, isArray, isNotNullOrUndefined, isNullOrUndefined, isNumeric, shadeColor, toNumber, uniqueValues, } from '@lumeer/utils';
|
|
21
|
-
import { LmrPivotPosition, LmrPivotValueType } from './lmr-pivot-config';
|
|
22
|
-
import { COLOR_GRAY100, COLOR_GRAY200, COLOR_GRAY300, COLOR_GRAY400, COLOR_GRAY500 } from './lmr-pivot-constants';
|
|
23
|
-
export class PivotTableConverter {
|
|
24
|
-
static emptyClass = 'pivot-empty-cell';
|
|
25
|
-
static dataClass = 'pivot-data-cell';
|
|
26
|
-
static groupDataClass = 'pivot-data-group-cell';
|
|
27
|
-
static rowHeaderClass = 'pivot-row-header-cell';
|
|
28
|
-
static rowGroupHeaderClass = 'pivot-row-group-header-cell';
|
|
29
|
-
static rowAttributeHeaderClass = 'pivot-row-attribute-header-cell';
|
|
30
|
-
static columnHeaderClass = 'pivot-column-header-cell';
|
|
31
|
-
static columnGroupHeaderClass = 'pivot-column-group-header-cell';
|
|
32
|
-
groupColors = [COLOR_GRAY100, COLOR_GRAY200, COLOR_GRAY300, COLOR_GRAY400, COLOR_GRAY500];
|
|
33
|
-
percentageConstraint = new PercentageConstraint({ decimals: 2 });
|
|
34
|
-
data;
|
|
35
|
-
transform;
|
|
36
|
-
values;
|
|
37
|
-
dataResources;
|
|
38
|
-
constraintData;
|
|
39
|
-
rowLevels;
|
|
40
|
-
rowsTransformationArray;
|
|
41
|
-
columnLevels;
|
|
42
|
-
columnsTransformationArray;
|
|
43
|
-
valueTypeInfo;
|
|
44
|
-
nonStickyRowIndex;
|
|
45
|
-
nonStickyColumnIndex;
|
|
46
|
-
createTables(pivotData, transform) {
|
|
47
|
-
if (!pivotData) {
|
|
48
|
-
return [{ cells: [] }];
|
|
49
|
-
}
|
|
50
|
-
this.transform = transform;
|
|
51
|
-
this.constraintData = pivotData.constraintData;
|
|
52
|
-
return (pivotData.data || []).map(d => {
|
|
53
|
-
if (this.dataAreEmpty(d)) {
|
|
54
|
-
return { cells: [] };
|
|
55
|
-
}
|
|
56
|
-
this.updateData(d);
|
|
57
|
-
return this.transformData();
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
dataAreEmpty(data) {
|
|
61
|
-
return (data.rowHeaders || []).length === 0 && (data.columnHeaders || []).length === 0;
|
|
62
|
-
}
|
|
63
|
-
updateData(data) {
|
|
64
|
-
const numberOfSums = Math.max(1, (data.valueTitles || []).length);
|
|
65
|
-
this.valueTypeInfo = getValuesTypeInfo(data.values, data.valueTypes, numberOfSums);
|
|
66
|
-
this.data = preparePivotData(data, this.constraintData, this.valueTypeInfo);
|
|
67
|
-
this.values = data.values || [];
|
|
68
|
-
this.dataResources = data.dataResources || [];
|
|
69
|
-
this.rowLevels = (data.rowsConfig || []).length;
|
|
70
|
-
this.columnLevels = (data.columnsConfig || []).length + (data.hasAdditionalColumnLevel ? 1 : 0);
|
|
71
|
-
const rowAllSticky = this.data.rowsConfig?.length && this.data.rowsConfig.every(config => !!config?.sticky);
|
|
72
|
-
this.nonStickyRowIndex = Math.max(rowAllSticky ? this.rowLevels : (this.data.rowsConfig?.findIndex(config => !config?.sticky) || 0), 0);
|
|
73
|
-
const columnAllSticky = this.data.columnsConfig?.length && this.data.columnsConfig.every(config => !!config?.sticky);
|
|
74
|
-
this.nonStickyColumnIndex = Math.max(columnAllSticky ? this.columnLevels : (this.data.columnsConfig?.findIndex(config => !config?.sticky) || 0), 0);
|
|
75
|
-
const hasValue = (data.valueTitles || []).length > 0;
|
|
76
|
-
if ((this.data.rowHeaders || []).length > 0) {
|
|
77
|
-
this.rowsTransformationArray = createTransformationMap(this.data.rowHeaders, this.rowShowSums, this.columnLevels, 1);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
this.rowsTransformationArray = hasValue ? [this.columnLevels] : [];
|
|
81
|
-
}
|
|
82
|
-
if ((this.data.columnHeaders || []).length > 0) {
|
|
83
|
-
this.columnsTransformationArray = createTransformationMap(this.data.columnHeaders, this.columnShowSums, this.rowLevels, numberOfSums);
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
this.columnsTransformationArray = hasValue ? [this.rowLevels] : [];
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
get rowShowSums() {
|
|
90
|
-
return (this.data.rowsConfig || []).map(config => config.showSums);
|
|
91
|
-
}
|
|
92
|
-
get columnShowSums() {
|
|
93
|
-
return (this.data.columnsConfig || []).map(config => config.showSums);
|
|
94
|
-
}
|
|
95
|
-
transformData() {
|
|
96
|
-
const cells = this.initCells();
|
|
97
|
-
const rowGroups = this.fillCellsByRows(cells);
|
|
98
|
-
const columnGroups = this.fillCellsByColumns(cells);
|
|
99
|
-
this.fillCellsByGroupIntersection(cells, rowGroups, columnGroups);
|
|
100
|
-
return { cells };
|
|
101
|
-
}
|
|
102
|
-
fillCellsByRows(cells) {
|
|
103
|
-
const rowGroups = [];
|
|
104
|
-
this.iterateAndFillCellsByRows(cells, rowGroups, this.data.rowHeaders, this.columnLevels, this.rowShowSums, 0);
|
|
105
|
-
return rowGroups;
|
|
106
|
-
}
|
|
107
|
-
iterateAndFillCellsByRows(cells, rowGroupsInfo, headers, startIndex, showSums, level, parentHeader) {
|
|
108
|
-
let currentIndex = startIndex;
|
|
109
|
-
for (const header of headers) {
|
|
110
|
-
const beforeExpressions = (header.expressions || []).filter(exp => exp.position === LmrPivotPosition.BeforeHeader);
|
|
111
|
-
this.fillCellsForExpressions(cells, rowGroupsInfo, level, currentIndex, beforeExpressions);
|
|
112
|
-
currentIndex += beforeExpressions.length;
|
|
113
|
-
const rowSpan = getDirectHeaderChildCount(header, level, showSums);
|
|
114
|
-
cells[currentIndex][level] = {
|
|
115
|
-
value: this.formatRowHeader(header.title, level),
|
|
116
|
-
cssClass: PivotTableConverter.rowHeaderClass,
|
|
117
|
-
isHeader: true,
|
|
118
|
-
stickyStart: this.isRowLevelSticky(level),
|
|
119
|
-
rowSpan,
|
|
120
|
-
colSpan: 1,
|
|
121
|
-
background: this.getHeaderBackground(header, level),
|
|
122
|
-
constraint: header.constraint,
|
|
123
|
-
label: header.attributeName,
|
|
124
|
-
childIndexes: createRange(currentIndex, currentIndex + (header.children?.length || 1)),
|
|
125
|
-
expandable: true,
|
|
126
|
-
};
|
|
127
|
-
if (header.children) {
|
|
128
|
-
this.iterateAndFillCellsByRows(cells, rowGroupsInfo, header.children, currentIndex, showSums, level + 1, header);
|
|
129
|
-
}
|
|
130
|
-
else if (isNotNullOrUndefined(header.targetIndex)) {
|
|
131
|
-
this.fillCellsForRow(cells, header.targetIndex);
|
|
132
|
-
}
|
|
133
|
-
const afterExpressions = (header.expressions || []).filter(exp => exp.position === LmrPivotPosition.StickToEnd);
|
|
134
|
-
currentIndex += getHeaderChildCount(header, level, showSums) - beforeExpressions.length;
|
|
135
|
-
this.fillCellsForExpressions(cells, rowGroupsInfo, level, currentIndex - afterExpressions.length, afterExpressions);
|
|
136
|
-
}
|
|
137
|
-
if (showSums[level]) {
|
|
138
|
-
const { title, summary } = this.formatSummaryHeader(parentHeader, level);
|
|
139
|
-
const background = this.getSummaryBackground(level);
|
|
140
|
-
const columnIndex = Math.max(level - 1, 0);
|
|
141
|
-
this.splitRowGroupHeader(cells, columnIndex, currentIndex, background, summary, [], false, title, parentHeader?.constraint, parentHeader?.attributeName);
|
|
142
|
-
const rowIndexes = getTargetIndexesForHeaders(headers);
|
|
143
|
-
const transformedRowIndexes = this.transformRowIndexes(rowIndexes);
|
|
144
|
-
rowGroupsInfo[currentIndex] = { background, indexes: transformedRowIndexes, level };
|
|
145
|
-
this.fillCellsForGroupedRow(cells, rowIndexes, currentIndex, background);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
fillCellsForExpressions(cells, rowGroupsInfo, level, currentIndex, expressions) {
|
|
149
|
-
for (let i = 0; i < expressions.length; i++) {
|
|
150
|
-
const expressionIndex = currentIndex + i;
|
|
151
|
-
const background = this.getSummaryBackground(level);
|
|
152
|
-
const { indexes } = this.fillCellsForExpressionRow(cells, expressions[i], expressionIndex, background);
|
|
153
|
-
this.splitRowGroupHeader(cells, level, expressionIndex, background, expressions[i].title, indexes, expressions[i].expandable);
|
|
154
|
-
rowGroupsInfo[expressionIndex] = { background, indexes: [], expression: expressions[i], level };
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
splitRowGroupHeader(cells, columnIndex, currentIndex, background, summary, rowIndexes, expandable, title, constraint, label) {
|
|
158
|
-
let colSpan = this.rowLevels - columnIndex;
|
|
159
|
-
const stickyStart = this.isRowLevelSticky(columnIndex);
|
|
160
|
-
// split row group header cell because of correct sticky scroll
|
|
161
|
-
if (stickyStart && this.nonStickyRowIndex > 0 && this.nonStickyRowIndex < this.rowLevels && colSpan > 1) {
|
|
162
|
-
const newColspan = this.nonStickyRowIndex - columnIndex;
|
|
163
|
-
cells[currentIndex][this.nonStickyRowIndex] = {
|
|
164
|
-
value: undefined,
|
|
165
|
-
constraint: undefined,
|
|
166
|
-
label: undefined,
|
|
167
|
-
cssClass: PivotTableConverter.rowGroupHeaderClass,
|
|
168
|
-
isSummary: true,
|
|
169
|
-
rowSpan: 1,
|
|
170
|
-
colSpan: colSpan - newColspan,
|
|
171
|
-
background,
|
|
172
|
-
summary: undefined,
|
|
173
|
-
expandable,
|
|
174
|
-
};
|
|
175
|
-
colSpan = newColspan;
|
|
176
|
-
}
|
|
177
|
-
cells[currentIndex][columnIndex] = {
|
|
178
|
-
value: title,
|
|
179
|
-
constraint,
|
|
180
|
-
label,
|
|
181
|
-
cssClass: PivotTableConverter.rowGroupHeaderClass,
|
|
182
|
-
isSummary: true,
|
|
183
|
-
stickyStart,
|
|
184
|
-
rowSpan: 1,
|
|
185
|
-
colSpan,
|
|
186
|
-
background,
|
|
187
|
-
summary,
|
|
188
|
-
rowIndexes,
|
|
189
|
-
expandable,
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
formatSummaryHeader(header, level) {
|
|
193
|
-
return this.transform.formatSummaryHeader?.(header, level) || {
|
|
194
|
-
title: header?.title,
|
|
195
|
-
summary: '',
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
formatRowHeader(title, level) {
|
|
199
|
-
return this.transform?.formatRowHeader?.(title, level) || title;
|
|
200
|
-
}
|
|
201
|
-
formatColumnHeader(title, level) {
|
|
202
|
-
return this.transform?.formatColumnHeader?.(title, level) || title;
|
|
203
|
-
}
|
|
204
|
-
getHeaderBackground(header, level) {
|
|
205
|
-
if (header?.color) {
|
|
206
|
-
return shadeColor(header.color, this.getLevelOpacity(level));
|
|
207
|
-
}
|
|
208
|
-
return undefined;
|
|
209
|
-
}
|
|
210
|
-
getLevelOpacity(level) {
|
|
211
|
-
return Math.min(80, 50 + level * 5) / 100;
|
|
212
|
-
}
|
|
213
|
-
isRowLevelSticky(level) {
|
|
214
|
-
return this.data?.rowsConfig?.[level]?.sticky;
|
|
215
|
-
}
|
|
216
|
-
isColumnLevelSticky(level) {
|
|
217
|
-
const maxLevel = Math.min(level, (this.data?.columnsConfig?.length ?? Number.MAX_SAFE_INTEGER) - 1);
|
|
218
|
-
return this.data?.columnsConfig?.[maxLevel]?.sticky;
|
|
219
|
-
}
|
|
220
|
-
getSummaryBackground(level) {
|
|
221
|
-
const index = Math.min(level, this.groupColors.length - 1);
|
|
222
|
-
return this.groupColors[index];
|
|
223
|
-
}
|
|
224
|
-
fillCellsForRow(cells, row) {
|
|
225
|
-
const rowIndexInCells = this.rowsTransformationArray[row];
|
|
226
|
-
if (isNotNullOrUndefined(rowIndexInCells)) {
|
|
227
|
-
for (let column = 0; column < this.columnsTransformationArray.length; column++) {
|
|
228
|
-
const columnIndexInCells = this.columnsTransformationArray[column];
|
|
229
|
-
if (isNotNullOrUndefined(columnIndexInCells)) {
|
|
230
|
-
const value = this.data.values[row][column];
|
|
231
|
-
const dataResources = this.dataResources?.[row]?.[column] || [];
|
|
232
|
-
const formattedValue = this.aggregateOrFormatSingleValue(value, column);
|
|
233
|
-
const stringValue = isNotNullOrUndefined(formattedValue) ? String(formattedValue) : '';
|
|
234
|
-
cells[rowIndexInCells][columnIndexInCells] = {
|
|
235
|
-
value: stringValue,
|
|
236
|
-
dataResources,
|
|
237
|
-
rowSpan: 1,
|
|
238
|
-
colSpan: 1,
|
|
239
|
-
cssClass: PivotTableConverter.dataClass,
|
|
240
|
-
isValue: true,
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
getValueIndexForColumns(columns) {
|
|
247
|
-
return columns[0] % this.data.valueTitles.length;
|
|
248
|
-
}
|
|
249
|
-
formatValueByValueType(value, valueIndex) {
|
|
250
|
-
const valueType = (this.data.valueTypes || [])[valueIndex];
|
|
251
|
-
if (!valueType || valueType === LmrPivotValueType.Default) {
|
|
252
|
-
return this.formatValueByConstraint(value, valueIndex);
|
|
253
|
-
}
|
|
254
|
-
if ([LmrPivotValueType.AllPercentage, LmrPivotValueType.ColumnPercentage, LmrPivotValueType.RowPercentage].includes(valueType)) {
|
|
255
|
-
return this.formatValueByPercentage(value);
|
|
256
|
-
}
|
|
257
|
-
return this.formatValueByConstraint(value, valueIndex);
|
|
258
|
-
}
|
|
259
|
-
formatGroupedValueByValueType(value, rows, columns) {
|
|
260
|
-
const valueIndex = columns[0] % this.data.valueTitles.length;
|
|
261
|
-
const valueType = this.data.valueTypes && this.data.valueTypes[valueIndex];
|
|
262
|
-
const valueTypeInfo = this.valueTypeInfo[valueIndex];
|
|
263
|
-
if (!valueTypeInfo || !valueType || valueType === LmrPivotValueType.Default) {
|
|
264
|
-
return this.formatValueByConstraint(value, valueIndex);
|
|
265
|
-
}
|
|
266
|
-
if (valueType === LmrPivotValueType.AllPercentage) {
|
|
267
|
-
return this.formatValueByPercentage(divideValues(value, valueTypeInfo.sum));
|
|
268
|
-
}
|
|
269
|
-
else if (valueType === LmrPivotValueType.ColumnPercentage) {
|
|
270
|
-
const columnsDividers = columns.reduce((dividers, column) => {
|
|
271
|
-
dividers.push(valueTypeInfo.sumsColumns[column]);
|
|
272
|
-
return dividers;
|
|
273
|
-
}, []);
|
|
274
|
-
const columnsDivider = aggregateDataValues(DataAggregationType.Sum, columnsDividers);
|
|
275
|
-
return this.formatValueByPercentage(divideValues(value, columnsDivider));
|
|
276
|
-
}
|
|
277
|
-
else if (valueType === LmrPivotValueType.RowPercentage) {
|
|
278
|
-
const rowsDividers = rows.reduce((dividers, row) => {
|
|
279
|
-
dividers.push(valueTypeInfo.sumsRows[row]);
|
|
280
|
-
return dividers;
|
|
281
|
-
}, []);
|
|
282
|
-
const rowsDivider = aggregateDataValues(DataAggregationType.Sum, rowsDividers);
|
|
283
|
-
return this.formatValueByPercentage(divideValues(value, rowsDivider));
|
|
284
|
-
}
|
|
285
|
-
return this.formatValueByConstraint(value, valueIndex);
|
|
286
|
-
}
|
|
287
|
-
formatValueByPercentage(value) {
|
|
288
|
-
return this.percentageConstraint.createDataValue(value).format();
|
|
289
|
-
}
|
|
290
|
-
formatValueByConstraint(value, valueIndex) {
|
|
291
|
-
const constraint = this.data.valuesConstraints?.[valueIndex] || this.valueTypeInfo[valueIndex]?.defaultConstraint;
|
|
292
|
-
if (constraint) {
|
|
293
|
-
return constraint.createDataValue(value, this.constraintData).preview();
|
|
294
|
-
}
|
|
295
|
-
return value;
|
|
296
|
-
}
|
|
297
|
-
fillCellsForGroupedRow(cells, rows, rowIndexInCells, background) {
|
|
298
|
-
for (let column = 0; column < this.columnsTransformationArray.length; column++) {
|
|
299
|
-
const columnIndexInCells = this.columnsTransformationArray[column];
|
|
300
|
-
if (isNotNullOrUndefined(columnIndexInCells)) {
|
|
301
|
-
const { values, dataResources } = this.getGroupedValuesForRowsAndCols(rows, [column]);
|
|
302
|
-
const formattedValue = this.aggregateAndFormatDataValues(values, rows, [column]);
|
|
303
|
-
cells[rowIndexInCells][columnIndexInCells] = {
|
|
304
|
-
value: String(formattedValue),
|
|
305
|
-
dataResources,
|
|
306
|
-
colSpan: 1,
|
|
307
|
-
rowSpan: 1,
|
|
308
|
-
cssClass: PivotTableConverter.groupDataClass,
|
|
309
|
-
background,
|
|
310
|
-
isValue: true,
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
fillCellsForExpressionRow(cells, expression, rowIndexInCells, background) {
|
|
316
|
-
let rowIndexes = [];
|
|
317
|
-
for (let column = 0; column < this.columnsTransformationArray.length; column++) {
|
|
318
|
-
const columnIndexInCells = this.columnsTransformationArray[column];
|
|
319
|
-
if (isNotNullOrUndefined(columnIndexInCells)) {
|
|
320
|
-
const { value, dataResources, indexes } = this.evaluateExpression(expression, [column]);
|
|
321
|
-
rowIndexes = indexes;
|
|
322
|
-
const valueIndex = column % this.data.valueTitles.length;
|
|
323
|
-
const formattedValue = this.formatValueByConstraint(value, valueIndex);
|
|
324
|
-
cells[rowIndexInCells][columnIndexInCells] = {
|
|
325
|
-
value: String(formattedValue),
|
|
326
|
-
dataResources,
|
|
327
|
-
colSpan: 1,
|
|
328
|
-
rowSpan: 1,
|
|
329
|
-
cssClass: PivotTableConverter.groupDataClass,
|
|
330
|
-
background,
|
|
331
|
-
isValue: true,
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
return { indexes: uniqueValues([rowIndexInCells, ...rowIndexes]) };
|
|
336
|
-
}
|
|
337
|
-
evaluateExpression(expression, columns) {
|
|
338
|
-
return (expression.operands || []).reduce((result, operand, index) => {
|
|
339
|
-
const { value, dataResources, indexes } = this.evaluateOperand(operand, columns);
|
|
340
|
-
result.dataResources.push(...dataResources);
|
|
341
|
-
result.indexes.push(...indexes);
|
|
342
|
-
switch (expression.operation) {
|
|
343
|
-
case 'add':
|
|
344
|
-
result.value += value;
|
|
345
|
-
break;
|
|
346
|
-
case 'subtract':
|
|
347
|
-
result.value = (index === 0 ? value : result.value - value);
|
|
348
|
-
break;
|
|
349
|
-
case 'multiply':
|
|
350
|
-
result.value = index === 0 ? value : result.value * value;
|
|
351
|
-
break;
|
|
352
|
-
case 'divide':
|
|
353
|
-
result.value = index === 0 ? value : value ? result.value / value : result.value;
|
|
354
|
-
break;
|
|
355
|
-
}
|
|
356
|
-
return result;
|
|
357
|
-
}, { value: 0, dataResources: [], indexes: [] });
|
|
358
|
-
}
|
|
359
|
-
evaluateOperand(operand, columns) {
|
|
360
|
-
switch (operand.type) {
|
|
361
|
-
case 'expression': return this.evaluateExpression(operand, columns);
|
|
362
|
-
case 'value': return { value: operand.value, dataResources: [], indexes: [] };
|
|
363
|
-
case 'header': {
|
|
364
|
-
const rows = getTargetIndexesForHeaders(operand.headers);
|
|
365
|
-
const { values, dataResources } = this.getGroupedValuesForRowsAndCols(rows, columns);
|
|
366
|
-
const { value } = this.aggregateDataValues(values, columns);
|
|
367
|
-
return { value, dataResources, indexes: this.transformRowIndexes(rows) };
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
transformRowIndexes(rows) {
|
|
372
|
-
return rows
|
|
373
|
-
.map(v => this.rowsTransformationArray[v])
|
|
374
|
-
.filter(v => isNotNullOrUndefined(v));
|
|
375
|
-
}
|
|
376
|
-
getGroupedValuesForRowsAndCols(rows, columns) {
|
|
377
|
-
const values = [];
|
|
378
|
-
const dataResources = [];
|
|
379
|
-
for (const row of rows) {
|
|
380
|
-
for (const column of columns) {
|
|
381
|
-
const rowColumnValue = this.values[row][column];
|
|
382
|
-
if (isArray(rowColumnValue)) {
|
|
383
|
-
values.push(...rowColumnValue);
|
|
384
|
-
}
|
|
385
|
-
else {
|
|
386
|
-
values.push(rowColumnValue);
|
|
387
|
-
}
|
|
388
|
-
dataResources.push(...(this.dataResources?.[row]?.[column] || []));
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
return { values, dataResources };
|
|
392
|
-
}
|
|
393
|
-
fillCellsByColumns(cells) {
|
|
394
|
-
const columnGroups = [];
|
|
395
|
-
this.iterateAndFillCellsByColumns(cells, columnGroups, this.data.columnHeaders, this.rowLevels, this.columnShowSums, 0);
|
|
396
|
-
return columnGroups;
|
|
397
|
-
}
|
|
398
|
-
iterateAndFillCellsByColumns(cells, columnGroupsInfo, headers, startIndex, showSums, level, parentHeader) {
|
|
399
|
-
let currentIndex = startIndex;
|
|
400
|
-
const numberOfSums = Math.max(1, this.data.valueTitles.length);
|
|
401
|
-
for (const header of headers) {
|
|
402
|
-
const colSpan = getDirectHeaderChildCount(header, level, showSums, numberOfSums);
|
|
403
|
-
cells[level][currentIndex] = {
|
|
404
|
-
value: this.formatColumnHeader(header.title, level),
|
|
405
|
-
cssClass: PivotTableConverter.columnHeaderClass,
|
|
406
|
-
isHeader: true,
|
|
407
|
-
rowSpan: 1,
|
|
408
|
-
colSpan,
|
|
409
|
-
stickyTop: this.isColumnLevelSticky(level),
|
|
410
|
-
background: this.getHeaderBackground(header, level),
|
|
411
|
-
constraint: header.constraint,
|
|
412
|
-
label: header.attributeName,
|
|
413
|
-
};
|
|
414
|
-
if (header.children) {
|
|
415
|
-
this.iterateAndFillCellsByColumns(cells, columnGroupsInfo, header.children, currentIndex, showSums, level + 1, header);
|
|
416
|
-
}
|
|
417
|
-
else if (isNotNullOrUndefined(header.targetIndex)) {
|
|
418
|
-
this.fillCellsForColumn(cells, header.targetIndex);
|
|
419
|
-
}
|
|
420
|
-
currentIndex += getHeaderChildCount(header, level, showSums, numberOfSums);
|
|
421
|
-
}
|
|
422
|
-
if (showSums[level]) {
|
|
423
|
-
const background = this.getSummaryBackground(level);
|
|
424
|
-
const { title, summary } = this.formatSummaryHeader(parentHeader, level);
|
|
425
|
-
const numberOfValues = this.data.valueTitles.length;
|
|
426
|
-
const rowIndex = Math.max(level - 1, 0);
|
|
427
|
-
const shouldAddValueHeaders = numberOfValues > 1;
|
|
428
|
-
cells[rowIndex][currentIndex] = {
|
|
429
|
-
value: title,
|
|
430
|
-
constraint: parentHeader?.constraint,
|
|
431
|
-
label: parentHeader?.attributeName,
|
|
432
|
-
cssClass: PivotTableConverter.columnGroupHeaderClass,
|
|
433
|
-
isSummary: true,
|
|
434
|
-
stickyTop: this.isColumnLevelSticky(level),
|
|
435
|
-
rowSpan: this.columnLevels - rowIndex - (shouldAddValueHeaders ? 1 : 0),
|
|
436
|
-
colSpan: numberOfSums,
|
|
437
|
-
background,
|
|
438
|
-
summary,
|
|
439
|
-
};
|
|
440
|
-
if (numberOfValues > 0) {
|
|
441
|
-
for (let i = 0; i < numberOfValues; i++) {
|
|
442
|
-
const columnIndexInCells = currentIndex + i;
|
|
443
|
-
if (shouldAddValueHeaders) {
|
|
444
|
-
const valueTitle = this.data.valueTitles[i];
|
|
445
|
-
cells[this.columnLevels - 1][columnIndexInCells] = {
|
|
446
|
-
value: valueTitle,
|
|
447
|
-
cssClass: PivotTableConverter.columnGroupHeaderClass,
|
|
448
|
-
isSummary: true,
|
|
449
|
-
stickyTop: this.isColumnLevelSticky(level),
|
|
450
|
-
rowSpan: 1,
|
|
451
|
-
colSpan: 1,
|
|
452
|
-
background,
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
const columnsIndexes = getTargetIndexesForHeaders(headers);
|
|
456
|
-
const valueColumnsIndexes = columnsIndexes.filter(index => index % numberOfValues === i);
|
|
457
|
-
const transformedColumnIndexes = valueColumnsIndexes
|
|
458
|
-
.map(v => this.columnsTransformationArray[v])
|
|
459
|
-
.filter(v => isNotNullOrUndefined(v));
|
|
460
|
-
columnGroupsInfo[columnIndexInCells] = { background, indexes: transformedColumnIndexes, level };
|
|
461
|
-
this.fillCellsForGroupedColumn(cells, valueColumnsIndexes, columnIndexInCells, background);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
else {
|
|
465
|
-
columnGroupsInfo[currentIndex] = { background, indexes: [], level };
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
fillCellsForGroupedColumn(cells, columns, columnIndexInCells, background) {
|
|
470
|
-
for (let row = 0; row < this.rowsTransformationArray.length; row++) {
|
|
471
|
-
const rowIndexInCells = this.rowsTransformationArray[row];
|
|
472
|
-
if (isNotNullOrUndefined(rowIndexInCells)) {
|
|
473
|
-
const { values, dataResources } = this.getGroupedValuesForRowsAndCols([row], columns);
|
|
474
|
-
const formattedValue = this.aggregateAndFormatDataValues(values, [row], columns);
|
|
475
|
-
cells[rowIndexInCells][columnIndexInCells] = {
|
|
476
|
-
value: String(formattedValue),
|
|
477
|
-
dataResources,
|
|
478
|
-
colSpan: 1,
|
|
479
|
-
rowSpan: 1,
|
|
480
|
-
cssClass: PivotTableConverter.groupDataClass,
|
|
481
|
-
background,
|
|
482
|
-
isValue: true,
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
aggregateAndFormatDataValues(values, rows, columns) {
|
|
488
|
-
const { value, aggregation } = this.aggregateDataValues(values, columns);
|
|
489
|
-
return aggregation === DataAggregationType.Join ? value : this.formatGroupedValueByValueType(value, rows, columns);
|
|
490
|
-
}
|
|
491
|
-
aggregateDataValues(values, columns) {
|
|
492
|
-
const aggregation = this.aggregationByColumns(columns);
|
|
493
|
-
if (aggregation === DataAggregationType.Join) {
|
|
494
|
-
const valueIndex = this.getValueIndexForColumns(columns);
|
|
495
|
-
const constraint = this.data.valuesConstraints?.[valueIndex] || this.valueTypeInfo[valueIndex]?.defaultConstraint;
|
|
496
|
-
return { value: aggregateDataValues(aggregation, values, constraint, false, this.constraintData), aggregation };
|
|
497
|
-
}
|
|
498
|
-
return { value: aggregateDataValues(aggregation, values), aggregation };
|
|
499
|
-
}
|
|
500
|
-
aggregationByColumns(columns) {
|
|
501
|
-
const valueIndex = columns[0] % this.data.valueTitles.length;
|
|
502
|
-
const aggregation = this.data.valueAggregations?.[valueIndex];
|
|
503
|
-
return isValueAggregation(aggregation) ? aggregation : DataAggregationType.Sum;
|
|
504
|
-
}
|
|
505
|
-
fillCellsForColumn(cells, column) {
|
|
506
|
-
const columnIndexInCells = this.columnsTransformationArray[column];
|
|
507
|
-
if (isNotNullOrUndefined(columnIndexInCells)) {
|
|
508
|
-
for (let row = 0; row < this.rowsTransformationArray.length; row++) {
|
|
509
|
-
const rowIndexInCells = this.rowsTransformationArray[row];
|
|
510
|
-
if (isNotNullOrUndefined(rowIndexInCells)) {
|
|
511
|
-
const value = this.data.values[row][column];
|
|
512
|
-
const dataResources = this.dataResources?.[row]?.[column] || [];
|
|
513
|
-
const formattedValue = this.aggregateOrFormatSingleValue(value, column);
|
|
514
|
-
const stringValue = isNotNullOrUndefined(formattedValue) ? String(formattedValue) : '';
|
|
515
|
-
cells[rowIndexInCells][columnIndexInCells] = {
|
|
516
|
-
value: stringValue,
|
|
517
|
-
dataResources,
|
|
518
|
-
rowSpan: 1,
|
|
519
|
-
colSpan: 1,
|
|
520
|
-
cssClass: PivotTableConverter.dataClass,
|
|
521
|
-
isValue: true,
|
|
522
|
-
};
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
aggregateOrFormatSingleValue(value, column) {
|
|
528
|
-
const aggregation = this.aggregationByColumns([column]);
|
|
529
|
-
const valueIndex = this.getValueIndexForColumns([column]);
|
|
530
|
-
if (aggregation === DataAggregationType.Join) {
|
|
531
|
-
const constraint = this.data.valuesConstraints?.[valueIndex] || this.valueTypeInfo[valueIndex]?.defaultConstraint;
|
|
532
|
-
return aggregateDataValues(aggregation, [value], constraint, false, this.constraintData);
|
|
533
|
-
}
|
|
534
|
-
return this.formatValueByValueType(value, valueIndex);
|
|
535
|
-
}
|
|
536
|
-
fillCellsByGroupIntersection(cells, rowGroupsInfo, columnGroupsInfo) {
|
|
537
|
-
const rowsCount = cells.length;
|
|
538
|
-
const columnsCount = cells[0]?.length || 0;
|
|
539
|
-
for (let i = 0; i < rowGroupsInfo.length; i++) {
|
|
540
|
-
const rowGroupInfo = rowGroupsInfo[i];
|
|
541
|
-
if (!rowGroupInfo) {
|
|
542
|
-
continue;
|
|
543
|
-
}
|
|
544
|
-
for (let j = 0; j < columnGroupsInfo.length; j++) {
|
|
545
|
-
if (!columnGroupsInfo[j]) {
|
|
546
|
-
continue;
|
|
547
|
-
}
|
|
548
|
-
const columns = columnGroupsInfo[j].indexes;
|
|
549
|
-
const { rowsIndexes, columnsIndexes } = this.getValuesIndexesFromCellsIndexes(rowGroupInfo.indexes, columns);
|
|
550
|
-
let formattedValue;
|
|
551
|
-
let dataResources;
|
|
552
|
-
if (rowGroupInfo.expression) {
|
|
553
|
-
const result = this.evaluateExpression(rowGroupInfo.expression, columnsIndexes);
|
|
554
|
-
const valueIndex = columnsIndexes[0] % this.data.valueTitles.length;
|
|
555
|
-
formattedValue = this.formatValueByConstraint(result.value, valueIndex);
|
|
556
|
-
dataResources = result.dataResources;
|
|
557
|
-
}
|
|
558
|
-
else {
|
|
559
|
-
// it's enough to fill group values only from row side
|
|
560
|
-
const result = this.getGroupedValuesForRowsAndCols(rowsIndexes, columnsIndexes);
|
|
561
|
-
formattedValue = this.aggregateAndFormatDataValues(result.values, rowsIndexes, columnsIndexes);
|
|
562
|
-
dataResources = result.dataResources;
|
|
563
|
-
}
|
|
564
|
-
cells[i][j] = {
|
|
565
|
-
value: String(formattedValue),
|
|
566
|
-
dataResources,
|
|
567
|
-
colSpan: 1,
|
|
568
|
-
rowSpan: 1,
|
|
569
|
-
cssClass: PivotTableConverter.groupDataClass,
|
|
570
|
-
isValue: true,
|
|
571
|
-
};
|
|
572
|
-
}
|
|
573
|
-
this.fillRowWithColor(cells, i, rowGroupInfo, columnsCount);
|
|
574
|
-
}
|
|
575
|
-
for (let j = 0; j < columnGroupsInfo.length; j++) {
|
|
576
|
-
if (columnGroupsInfo[j]) {
|
|
577
|
-
this.fillColumnWithColor(cells, j, columnGroupsInfo[j], rowGroupsInfo, rowsCount);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
getValuesIndexesFromCellsIndexes(rows, columns) {
|
|
582
|
-
const rowsIndexes = rows
|
|
583
|
-
.map(row => this.rowsTransformationArray.findIndex(tRow => tRow === row))
|
|
584
|
-
.filter(index => index >= 0);
|
|
585
|
-
const columnsIndexes = columns
|
|
586
|
-
.map(column => this.columnsTransformationArray.findIndex(tColumn => tColumn === column))
|
|
587
|
-
.filter(index => index >= 0);
|
|
588
|
-
return { rowsIndexes, columnsIndexes };
|
|
589
|
-
}
|
|
590
|
-
fillRowWithColor(cells, row, rowGroupInfo, columnsCount) {
|
|
591
|
-
for (let i = this.rowLevels; i < columnsCount; i++) {
|
|
592
|
-
cells[row][i] && (cells[row][i].background = rowGroupInfo.background);
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
fillColumnWithColor(cells, column, columnGroupInfo, rowGroupsInfo, rowCount) {
|
|
596
|
-
for (let i = this.columnLevels; i < rowCount; i++) {
|
|
597
|
-
const rowGroupInfo = rowGroupsInfo[i];
|
|
598
|
-
if (!rowGroupInfo || rowGroupInfo.level > columnGroupInfo.level) {
|
|
599
|
-
cells[i][column] && (cells[i][column].background = columnGroupInfo.background);
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
initCells() {
|
|
604
|
-
const rows = this.getRowsCount() + this.columnLevels;
|
|
605
|
-
const columns = this.getColumnsCount() + this.rowLevels;
|
|
606
|
-
const matrix = [];
|
|
607
|
-
for (let i = 0; i < rows; i++) {
|
|
608
|
-
matrix[i] = [];
|
|
609
|
-
for (let j = 0; j < columns; j++) {
|
|
610
|
-
if (i >= this.columnLevels && j >= this.rowLevels) {
|
|
611
|
-
const isDataClass = this.rowsTransformationArray.includes(i) && this.columnsTransformationArray.includes(j);
|
|
612
|
-
matrix[i][j] = {
|
|
613
|
-
value: '',
|
|
614
|
-
dataResources: [],
|
|
615
|
-
cssClass: isDataClass ? PivotTableConverter.dataClass : PivotTableConverter.groupDataClass,
|
|
616
|
-
rowSpan: 1,
|
|
617
|
-
colSpan: 1,
|
|
618
|
-
isValue: true,
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
else {
|
|
622
|
-
matrix[i][j] = undefined;
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
if (this.rowLevels > 0 && this.columnLevels > 0) {
|
|
627
|
-
for (let j = 0; j < this.rowLevels; j++) {
|
|
628
|
-
const rowHeaderAttribute = this.data.rowHeaderAttributes[j];
|
|
629
|
-
if (rowHeaderAttribute) {
|
|
630
|
-
const titleRowSpan = this.nonStickyColumnIndex || this.columnLevels;
|
|
631
|
-
matrix[0][j] = {
|
|
632
|
-
value: rowHeaderAttribute.title,
|
|
633
|
-
cssClass: PivotTableConverter.rowAttributeHeaderClass,
|
|
634
|
-
isAttributeHeader: true,
|
|
635
|
-
rowSpan: titleRowSpan,
|
|
636
|
-
colSpan: 1,
|
|
637
|
-
stickyTop: this.isColumnLevelSticky(0),
|
|
638
|
-
stickyStart: this.isRowLevelSticky(j),
|
|
639
|
-
background: rowHeaderAttribute.color,
|
|
640
|
-
};
|
|
641
|
-
if (this.columnLevels - titleRowSpan > 0) {
|
|
642
|
-
matrix[this.nonStickyColumnIndex][j] = {
|
|
643
|
-
value: '',
|
|
644
|
-
cssClass: PivotTableConverter.rowAttributeHeaderClass,
|
|
645
|
-
isAttributeHeader: true,
|
|
646
|
-
rowSpan: this.columnLevels - titleRowSpan,
|
|
647
|
-
colSpan: 1,
|
|
648
|
-
background: rowHeaderAttribute.color,
|
|
649
|
-
stickyStart: this.isRowLevelSticky(j),
|
|
650
|
-
};
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
else {
|
|
654
|
-
for (let i = 0; i < this.columnLevels; i++) {
|
|
655
|
-
matrix[i][j] = {
|
|
656
|
-
value: '',
|
|
657
|
-
cssClass: PivotTableConverter.emptyClass,
|
|
658
|
-
rowSpan: 1,
|
|
659
|
-
colSpan: 1,
|
|
660
|
-
stickyStart: this.isRowLevelSticky(j),
|
|
661
|
-
stickyTop: this.isColumnLevelSticky(i),
|
|
662
|
-
isHeader: false,
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
return matrix;
|
|
669
|
-
}
|
|
670
|
-
getRowsCount() {
|
|
671
|
-
if (this.data.rowHeaders.length === 0 && (this.data.valueTitles || []).length > 0) {
|
|
672
|
-
return 1;
|
|
673
|
-
}
|
|
674
|
-
return getHeadersChildCount(this.data.rowHeaders, this.rowShowSums);
|
|
675
|
-
}
|
|
676
|
-
getColumnsCount() {
|
|
677
|
-
if (this.data.columnHeaders.length === 0 && (this.data.valueTitles || []).length > 0) {
|
|
678
|
-
return 1;
|
|
679
|
-
}
|
|
680
|
-
const numberOfSums = Math.max(1, (this.data.valueTitles || []).length);
|
|
681
|
-
return getHeadersChildCount(this.data.columnHeaders, this.columnShowSums, numberOfSums);
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
function preparePivotData(data, constraintData, valueTypeInfo) {
|
|
685
|
-
const numberOfSums = Math.max(1, (data.valueTitles || []).length);
|
|
686
|
-
const values = computeValuesByValueType(data.values, data.valueTypes, numberOfSums, valueTypeInfo);
|
|
687
|
-
const sorted = sortPivotData({ ...data, values }, constraintData);
|
|
688
|
-
return fillExpressionsToData(sorted);
|
|
689
|
-
}
|
|
690
|
-
function fillExpressionsToData(data) {
|
|
691
|
-
return {
|
|
692
|
-
...data,
|
|
693
|
-
rowHeaders: fillExpressionsToHeaders(data.rowHeaders, data.rowsConfig, 0),
|
|
694
|
-
columnHeaders: fillExpressionsToHeaders(data.columnHeaders, data.columnsConfig, 0),
|
|
695
|
-
};
|
|
696
|
-
}
|
|
697
|
-
function fillExpressionsToHeaders(headers, configs, index) {
|
|
698
|
-
const expressions = configs?.[index]?.expressions || [];
|
|
699
|
-
const headersCopy = [...(headers || [])];
|
|
700
|
-
for (const expression of expressions) {
|
|
701
|
-
const dataHeaderExpression = extendPivotExpression(expression, headers);
|
|
702
|
-
if (dataHeaderExpression.firstHeaderIndex >= 0) {
|
|
703
|
-
const firstHeaderIndex = dataHeaderExpression.firstHeaderIndex;
|
|
704
|
-
const newHeader = { ...headersCopy[firstHeaderIndex], expressions: [...(headersCopy[firstHeaderIndex].expressions || []), dataHeaderExpression] };
|
|
705
|
-
headersCopy.splice(firstHeaderIndex, 1, newHeader);
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
if (configs?.[index + 1]) {
|
|
709
|
-
for (let i = 0; i < headersCopy.length; i++) {
|
|
710
|
-
headersCopy.splice(i, 1, { ...headersCopy[i], children: fillExpressionsToHeaders(headersCopy[i].children, configs, index + 1) });
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
return headersCopy;
|
|
714
|
-
}
|
|
715
|
-
function extendPivotExpression(expression, headers) {
|
|
716
|
-
const dataHeaderOperands = [];
|
|
717
|
-
let firstHeaderIndex = Number.MAX_SAFE_INTEGER;
|
|
718
|
-
function traverse(operands) {
|
|
719
|
-
for (const operand of operands) {
|
|
720
|
-
if (operand.type === 'header') {
|
|
721
|
-
const indexes = getOperandIndexesInHeaders(operand, headers);
|
|
722
|
-
firstHeaderIndex = Math.min(firstHeaderIndex, ...indexes);
|
|
723
|
-
const operandHeaders = indexes.map(index => headers[index]);
|
|
724
|
-
dataHeaderOperands.push({ ...operand, headers: operandHeaders });
|
|
725
|
-
}
|
|
726
|
-
else if (operand.type === 'expression') {
|
|
727
|
-
traverse(operand.operands);
|
|
728
|
-
}
|
|
729
|
-
else {
|
|
730
|
-
dataHeaderOperands.push(operand);
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
traverse(expression.operands);
|
|
735
|
-
if (expression.position === LmrPivotPosition.StickToEnd) {
|
|
736
|
-
firstHeaderIndex = headers.length - 1;
|
|
737
|
-
}
|
|
738
|
-
if (firstHeaderIndex === Number.MAX_SAFE_INTEGER) {
|
|
739
|
-
firstHeaderIndex = -1;
|
|
740
|
-
}
|
|
741
|
-
return { ...expression, firstHeaderIndex, operands: dataHeaderOperands };
|
|
742
|
-
}
|
|
743
|
-
function getOperandIndexesInHeaders(operand, headers) {
|
|
744
|
-
return (headers || []).reduce((indexes, header, index) => {
|
|
745
|
-
if (operandContainsHeader(operand, header)) {
|
|
746
|
-
indexes.push(index);
|
|
747
|
-
}
|
|
748
|
-
return indexes;
|
|
749
|
-
}, []);
|
|
750
|
-
}
|
|
751
|
-
function operandContainsHeader(operand, header) {
|
|
752
|
-
return header.title.match(new RegExp(operand.value))?.length > 0;
|
|
753
|
-
}
|
|
754
|
-
function computeValuesByValueType(values, valueTypes, numValues, valueTypeInfo) {
|
|
755
|
-
const rowsIndexes = [...Array(values.length).keys()];
|
|
756
|
-
const modifiedValues = deepObjectCopy(values);
|
|
757
|
-
for (let i = 0; i < numValues; i++) {
|
|
758
|
-
const valueType = valueTypes && valueTypes[i];
|
|
759
|
-
if (!valueType || valueType === LmrPivotValueType.Default) {
|
|
760
|
-
continue;
|
|
761
|
-
}
|
|
762
|
-
const columnsCount = (values[0] && values[0].length) || 0;
|
|
763
|
-
const columnIndexes = [...Array(columnsCount).keys()].filter(key => key % numValues === i);
|
|
764
|
-
const info = valueTypeInfo[i];
|
|
765
|
-
for (const row of rowsIndexes) {
|
|
766
|
-
for (const column of columnIndexes) {
|
|
767
|
-
if (valueType === LmrPivotValueType.AllPercentage) {
|
|
768
|
-
modifiedValues[row][column] = divideValues(values[row][column], info.sum);
|
|
769
|
-
}
|
|
770
|
-
else if (valueType === LmrPivotValueType.RowPercentage) {
|
|
771
|
-
modifiedValues[row][column] = divideValues(values[row][column], info.sumsRows[row]);
|
|
772
|
-
}
|
|
773
|
-
else if (valueType === LmrPivotValueType.ColumnPercentage) {
|
|
774
|
-
modifiedValues[row][column] = divideValues(values[row][column], info.sumsColumns[column]);
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
return modifiedValues;
|
|
780
|
-
}
|
|
781
|
-
function getValuesTypeInfo(values, valueTypes, numValues) {
|
|
782
|
-
const valueTypeInfo = [];
|
|
783
|
-
const rowsIndexes = [...Array(values.length).keys()];
|
|
784
|
-
for (let i = 0; i < numValues; i++) {
|
|
785
|
-
const valueType = valueTypes && valueTypes[i];
|
|
786
|
-
const columnsCount = (values[0] && values[0].length) || 0;
|
|
787
|
-
const columnIndexes = [...Array(columnsCount).keys()].filter(key => key % numValues === i);
|
|
788
|
-
valueTypeInfo[i] = getValueTypeInfo(values, valueType, rowsIndexes, columnIndexes);
|
|
789
|
-
}
|
|
790
|
-
return valueTypeInfo;
|
|
791
|
-
}
|
|
792
|
-
function getValueTypeInfo(values, type, rows, columns) {
|
|
793
|
-
const containsDecimal = containsDecimalValue(values, rows, columns);
|
|
794
|
-
const valueTypeInfo = {
|
|
795
|
-
defaultConstraint: containsDecimal ? new NumberConstraint({ decimals: 2 }) : null,
|
|
796
|
-
};
|
|
797
|
-
if (type === LmrPivotValueType.AllPercentage) {
|
|
798
|
-
return { ...valueTypeInfo, sum: getNumericValuesSummary(values, rows, columns) };
|
|
799
|
-
}
|
|
800
|
-
else if (type === LmrPivotValueType.RowPercentage) {
|
|
801
|
-
return {
|
|
802
|
-
...valueTypeInfo,
|
|
803
|
-
sumsRows: rows.reduce((arr, row) => {
|
|
804
|
-
arr[row] = getNumericValuesSummary(values, [row], columns);
|
|
805
|
-
return arr;
|
|
806
|
-
}, []),
|
|
807
|
-
};
|
|
808
|
-
}
|
|
809
|
-
else if (type === LmrPivotValueType.ColumnPercentage) {
|
|
810
|
-
return {
|
|
811
|
-
...valueTypeInfo,
|
|
812
|
-
sumsColumns: columns.reduce((arr, column) => {
|
|
813
|
-
arr[column] = getNumericValuesSummary(values, rows, [column]);
|
|
814
|
-
return arr;
|
|
815
|
-
}, []),
|
|
816
|
-
};
|
|
817
|
-
}
|
|
818
|
-
return { ...valueTypeInfo };
|
|
819
|
-
}
|
|
820
|
-
function containsDecimalValue(values, rows, columns) {
|
|
821
|
-
for (const row of rows) {
|
|
822
|
-
for (const column of columns) {
|
|
823
|
-
if (isValueDecimal(values[row][column])) {
|
|
824
|
-
return true;
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
return false;
|
|
829
|
-
}
|
|
830
|
-
function isValueDecimal(value) {
|
|
831
|
-
if (isNullOrUndefined(value)) {
|
|
832
|
-
return false;
|
|
833
|
-
}
|
|
834
|
-
if (isNumeric(value)) {
|
|
835
|
-
return toNumber(value) % 1 !== 0;
|
|
836
|
-
}
|
|
837
|
-
return false;
|
|
838
|
-
}
|
|
839
|
-
function createTransformationMap(headers, showSums, additionalNum, numberOfSums) {
|
|
840
|
-
const array = [];
|
|
841
|
-
iterateThroughTransformationMap(headers, additionalNum, array, 0, showSums, numberOfSums);
|
|
842
|
-
return array;
|
|
843
|
-
}
|
|
844
|
-
function iterateThroughTransformationMap(headers, additionalNum, array, level, showSums, numberOfSums) {
|
|
845
|
-
let additional = additionalNum;
|
|
846
|
-
for (let i = 0; i < headers.length; i++) {
|
|
847
|
-
const header = headers[i];
|
|
848
|
-
const beforeExpressionsLength = (header.expressions || []).filter(exp => exp.position === LmrPivotPosition.BeforeHeader).length;
|
|
849
|
-
const afterExpressionsLength = (header.expressions || []).filter(exp => exp.position === LmrPivotPosition.StickToEnd).length;
|
|
850
|
-
if (header.children) {
|
|
851
|
-
additional += beforeExpressionsLength;
|
|
852
|
-
iterateThroughTransformationMap(header.children, additional, array, level + 1, showSums, numberOfSums);
|
|
853
|
-
additional += (getHeaderChildCount(header, level, showSums, numberOfSums) - beforeExpressionsLength);
|
|
854
|
-
}
|
|
855
|
-
else if (isNotNullOrUndefined(header.targetIndex)) {
|
|
856
|
-
array[header.targetIndex] = i + additional + beforeExpressionsLength;
|
|
857
|
-
additional += beforeExpressionsLength + afterExpressionsLength;
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
function getTargetIndexesForHeaders(headers) {
|
|
862
|
-
const allRows = (headers || []).reduce((rows, header) => {
|
|
863
|
-
rows.push(...getTargetIndexesForHeader(header));
|
|
864
|
-
return rows;
|
|
865
|
-
}, []);
|
|
866
|
-
return uniqueValues(allRows);
|
|
867
|
-
}
|
|
868
|
-
function getTargetIndexesForHeader(pivotDataHeader) {
|
|
869
|
-
if (pivotDataHeader.children) {
|
|
870
|
-
return pivotDataHeader.children.reduce((rows, header) => {
|
|
871
|
-
rows.push(...getTargetIndexesForHeader(header));
|
|
872
|
-
return rows;
|
|
873
|
-
}, []);
|
|
874
|
-
}
|
|
875
|
-
return [pivotDataHeader.targetIndex];
|
|
876
|
-
}
|
|
877
|
-
function getHeadersChildCount(headers, showSums, numberOfSums = 1) {
|
|
878
|
-
return (headers || []).reduce((sum, header) => sum + getHeaderChildCount(header, 0, showSums, numberOfSums), showSums[0] ? numberOfSums : 0);
|
|
879
|
-
}
|
|
880
|
-
function getHeaderChildCount(pivotDataHeader, level, showSums, numberOfSums = 1) {
|
|
881
|
-
const numExpressions = (pivotDataHeader.expressions || []).length;
|
|
882
|
-
if (pivotDataHeader.children) {
|
|
883
|
-
return pivotDataHeader.children.reduce((sum, header) => sum + getHeaderChildCount(header, level + 1, showSums, numberOfSums), (showSums[level + 1] ? numberOfSums : 0) + numExpressions);
|
|
884
|
-
}
|
|
885
|
-
return 1 + numExpressions;
|
|
886
|
-
}
|
|
887
|
-
function getDirectHeaderChildCount(pivotDataHeader, level, showSums, numberOfSums = 1) {
|
|
888
|
-
if (pivotDataHeader.children) {
|
|
889
|
-
return pivotDataHeader.children.reduce((sum, header) => sum + getHeaderChildCount(header, level + 1, showSums, numberOfSums), 0);
|
|
890
|
-
}
|
|
891
|
-
return 1;
|
|
892
|
-
}
|
|
893
|
-
export function sortPivotData(data, constraintData) {
|
|
894
|
-
const rowSorts = (data.rowsConfig || []).map(config => config.sort);
|
|
895
|
-
const columnSorts = (data.columnsConfig || []).map(config => config.sort);
|
|
896
|
-
return {
|
|
897
|
-
...data,
|
|
898
|
-
rowHeaders: sortPivotRowDataHeaders(data.rowHeaders, rowSorts, data, constraintData),
|
|
899
|
-
columnHeaders: sortPivotColumnDataHeaders(data.columnHeaders, columnSorts, data, constraintData),
|
|
900
|
-
};
|
|
901
|
-
}
|
|
902
|
-
function sortPivotRowDataHeaders(rowHeaders, rowSorts, pivotData, constraintData) {
|
|
903
|
-
return sortPivotDataHeadersRecursive(rowHeaders, 0, rowSorts, pivotData.columnHeaders, pivotData.values, pivotData.valueTitles || [], true, constraintData);
|
|
904
|
-
}
|
|
905
|
-
function sortPivotColumnDataHeaders(columnHeaders, columnSorts, pivotData, constraintData) {
|
|
906
|
-
return sortPivotDataHeadersRecursive(columnHeaders, 0, columnSorts, pivotData.rowHeaders, pivotData.values, pivotData.valueTitles || [], false, constraintData);
|
|
907
|
-
}
|
|
908
|
-
function sortPivotDataHeadersRecursive(headers, index, sorts, otherSideHeaders, values, valueTitles, isRows, constraintData) {
|
|
909
|
-
// we don't want to sort values headers
|
|
910
|
-
if (!isRows && isValuesHeaders(headers, valueTitles)) {
|
|
911
|
-
return headers;
|
|
912
|
-
}
|
|
913
|
-
const sort = sorts && sorts[index];
|
|
914
|
-
const constraint = getConstraintForSort(sort, headers);
|
|
915
|
-
const valuesMap = createHeadersValuesMap(headers, sort, otherSideHeaders, values, valueTitles, isRows);
|
|
916
|
-
return headers
|
|
917
|
-
.map(header => ({
|
|
918
|
-
...header,
|
|
919
|
-
children: header.children &&
|
|
920
|
-
sortPivotDataHeadersRecursive(header.children, index + 1, sorts, otherSideHeaders, values, valueTitles, isRows, constraintData),
|
|
921
|
-
}))
|
|
922
|
-
.sort((r1, r2) => {
|
|
923
|
-
const r1Value = constraint.createDataValue(valuesMap[r1.title], constraintData);
|
|
924
|
-
const r2Value = constraint.createDataValue(valuesMap[r2.title], constraintData);
|
|
925
|
-
const multiplier = !sort || sort.asc ? 1 : -1;
|
|
926
|
-
return r1Value.compareTo(r2Value) * multiplier;
|
|
927
|
-
});
|
|
928
|
-
}
|
|
929
|
-
function getConstraintForSort(sort, headers) {
|
|
930
|
-
if ((sort?.list?.values || []).length > 0) {
|
|
931
|
-
// sort is done by values in columns
|
|
932
|
-
return new NumberConstraint({});
|
|
933
|
-
}
|
|
934
|
-
return ((headers || [])[0] && (headers || [])[0].constraint) || new UnknownConstraint();
|
|
935
|
-
}
|
|
936
|
-
function isValuesHeaders(headers, valueTitles) {
|
|
937
|
-
return (valueTitles.length > 1 &&
|
|
938
|
-
(headers || []).every((header, index) => isNotNullOrUndefined(header.targetIndex) && header.title === valueTitles[index]));
|
|
939
|
-
}
|
|
940
|
-
function createHeadersValuesMap(headers, sort, otherSideHeaders, values, valueTitles, isRows) {
|
|
941
|
-
const sortTargetIndexes = sortValueTargetIndexes(sort, otherSideHeaders, valueTitles);
|
|
942
|
-
if (!sortTargetIndexes) {
|
|
943
|
-
return (headers || []).reduce((valuesMap, header) => {
|
|
944
|
-
valuesMap[header.title] = header.title;
|
|
945
|
-
return valuesMap;
|
|
946
|
-
}, {});
|
|
947
|
-
}
|
|
948
|
-
return (headers || []).reduce((valuesMap, header) => {
|
|
949
|
-
const rows = isRows ? getTargetIndexesForHeader(header) : sortTargetIndexes;
|
|
950
|
-
const columns = isRows ? sortTargetIndexes : getTargetIndexesForHeader(header);
|
|
951
|
-
valuesMap[header.title] = getNumericValuesSummary(values, rows, columns);
|
|
952
|
-
return valuesMap;
|
|
953
|
-
}, {});
|
|
954
|
-
}
|
|
955
|
-
function getNumericValuesSummary(values, rows, columns) {
|
|
956
|
-
let sum = 0;
|
|
957
|
-
for (const row of rows) {
|
|
958
|
-
for (const column of columns) {
|
|
959
|
-
const value = values[row][column];
|
|
960
|
-
if (isNotNullOrUndefined(value) && isNumeric(value)) {
|
|
961
|
-
sum += toNumber(value);
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
return sum;
|
|
966
|
-
}
|
|
967
|
-
function sortValueTargetIndexes(sort, otherSideHeaders, valueTitles) {
|
|
968
|
-
if (sort && sort.list) {
|
|
969
|
-
let valueIndex = valueTitles.findIndex(title => title === sort.list.valueTitle);
|
|
970
|
-
if (valueIndex === -1) {
|
|
971
|
-
if (valueTitles.length === 1) {
|
|
972
|
-
valueIndex = 0;
|
|
973
|
-
}
|
|
974
|
-
else {
|
|
975
|
-
return null;
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
let pivotHeader = null;
|
|
979
|
-
let currentOtherSideHeaders = otherSideHeaders;
|
|
980
|
-
for (const value of sort.list.values || []) {
|
|
981
|
-
if (value.isSummary) {
|
|
982
|
-
const indexes = getTargetIndexesForHeaders(currentOtherSideHeaders || []) || [];
|
|
983
|
-
return filterIndexesByMod(indexes, valueTitles.length, valueIndex);
|
|
984
|
-
}
|
|
985
|
-
pivotHeader = (currentOtherSideHeaders || []).find(header => header.title === value.title);
|
|
986
|
-
if (!pivotHeader) {
|
|
987
|
-
break;
|
|
988
|
-
}
|
|
989
|
-
currentOtherSideHeaders = pivotHeader.children || [];
|
|
990
|
-
}
|
|
991
|
-
if (pivotHeader) {
|
|
992
|
-
const targetIndexes = isNotNullOrUndefined(pivotHeader.targetIndex)
|
|
993
|
-
? [pivotHeader.targetIndex]
|
|
994
|
-
: getTargetIndexesForHeaders(currentOtherSideHeaders);
|
|
995
|
-
return filterIndexesByMod(targetIndexes, valueTitles.length, valueIndex);
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
return null;
|
|
999
|
-
}
|
|
1000
|
-
function filterIndexesByMod(indexes, mod, value) {
|
|
1001
|
-
return (indexes || []).filter(index => index % mod === value);
|
|
1002
|
-
}
|
|
1003
|
-
function divideValues(value, divider) {
|
|
1004
|
-
if (isNullOrUndefined(value)) {
|
|
1005
|
-
return null;
|
|
1006
|
-
}
|
|
1007
|
-
if (isNumeric(value) && isNumeric(divider)) {
|
|
1008
|
-
if (divider !== 0) {
|
|
1009
|
-
return value / divider;
|
|
1010
|
-
}
|
|
1011
|
-
else {
|
|
1012
|
-
return 0;
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
return null;
|
|
1016
|
-
}
|
|
1017
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGl2b3QtdGFibGUtY29udmVydGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbG1yLXBpdm90LXRhYmxlL3NyYy9saWIvdXRpbC9waXZvdC10YWJsZS1jb252ZXJ0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsT0FBTyxFQUFDLG1CQUFtQixFQUE4QixtQkFBbUIsRUFBZ0Isa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQUUsb0JBQW9CLEVBQUUsaUJBQWlCLEdBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN4TSxPQUFPLEVBQUMsV0FBVyxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsWUFBWSxHQUFFLE1BQU0sZUFBZSxDQUFDO0FBSTVKLE9BQU8sRUFBNkQsZ0JBQWdCLEVBQW1DLGlCQUFpQixFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFDcEssT0FBTyxFQUFDLGFBQWEsRUFBRSxhQUFhLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQWdCaEgsTUFBTSxPQUFPLG1CQUFtQjtJQUN2QixNQUFNLENBQVUsVUFBVSxHQUFHLGtCQUFrQixDQUFDO0lBQ2hELE1BQU0sQ0FBVSxTQUFTLEdBQUcsaUJBQWlCLENBQUM7SUFDOUMsTUFBTSxDQUFVLGNBQWMsR0FBRyx1QkFBdUIsQ0FBQztJQUN6RCxNQUFNLENBQVUsY0FBYyxHQUFHLHVCQUF1QixDQUFDO0lBQ3pELE1BQU0sQ0FBVSxtQkFBbUIsR0FBRyw2QkFBNkIsQ0FBQztJQUNwRSxNQUFNLENBQVUsdUJBQXVCLEdBQUcsaUNBQWlDLENBQUM7SUFDNUUsTUFBTSxDQUFVLGlCQUFpQixHQUFHLDBCQUEwQixDQUFDO0lBQy9ELE1BQU0sQ0FBVSxzQkFBc0IsR0FB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O0lBQzVDLElBQUksaUJBQWlCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUM3QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxJQUFJLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUMzQyxJQUFJLE9BQU8sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNsQixPQUFPLEtBQUssR0FBRyxPQUFPLENBQUM7UUFDekIsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLENBQUMsQ0FBQztRQUNYLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIEx1bWVlcjogTW9kZXJuIERhdGEgRGVmaW5pdGlvbiBhbmQgUHJvY2Vzc2luZyBQbGF0Zm9ybVxuICpcbiAqIENvcHlyaWdodCAoQykgc2luY2UgMjAxNyBMdW1lZXIuaW8sIHMuci5vLiBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqL1xuaW1wb3J0IHthZ2dyZWdhdGVEYXRhVmFsdWVzLCBDb25zdHJhaW50LCBDb25zdHJhaW50RGF0YSwgRGF0YUFnZ3JlZ2F0aW9uVHlwZSwgRGF0YVJlc291cmNlLCBpc1ZhbHVlQWdncmVnYXRpb24sIE51bWJlckNvbnN0cmFpbnQsIFBlcmNlbnRhZ2VDb25zdHJhaW50LCBVbmtub3duQ29uc3RyYWludCx9IGZyb20gJ0BsdW1lZXIvZGF0YS1maWx0ZXJzJztcbmltcG9ydCB7Y3JlYXRlUmFuZ2UsIGRlZXBPYmplY3RDb3B5LCBpc0FycmF5LCBpc05vdE51bGxPclVuZGVmaW5lZCwgaXNOdWxsT3JVbmRlZmluZWQsIGlzTnVtZXJpYywgc2hhZGVDb2xvciwgdG9OdW1iZXIsIHVuaXF1ZVZhbHVlcyx9IGZyb20gJ0BsdW1lZXIvdXRpbHMnO1xuXG5pbXBvcnQge0xtclBpdm90RGF0YSwgTG1yUGl2b3REYXRhSGVhZGVyLCBMbXJQaXZvdERhdGFIZWFkZXJFeHByZXNzaW9uLCBMbXJQaXZvdERhdGFIZWFkZXJPcGVyYW5kLCBMbXJQaXZvdERpbWVuc2lvbkNvbmZpZywgTG1yUGl2b3RTdGVtRGF0YX0gZnJvbSAnLi9sbXItcGl2b3QtZGF0YSc7XG5pbXBvcnQge0xtclBpdm90VGFibGUsIExtclBpdm90VGFibGVDZWxsfSBmcm9tICcuL2xtci1waXZvdC10YWJsZSc7XG5pbXBvcnQge0xtclBpdm90RXhwcmVzc2lvbiwgTG1yUGl2b3RIZWFkZXJPcGVyYW5kLCBMbXJQaXZvdE9wZXJhbmQsIExtclBpdm90UG9zaXRpb24sIExtclBpdm90U29ydCwgTG1yUGl2b3RUcmFuc2Zvcm0sIExtclBpdm90VmFsdWVUeXBlfSBmcm9tICcuL2xtci1waXZvdC1jb25maWcnO1xuaW1wb3J0IHtDT0xPUl9HUkFZMTAwLCBDT0xPUl9HUkFZMjAwLCBDT0xPUl9HUkFZMzAwLCBDT0xPUl9HUkFZNDAwLCBDT0xPUl9HUkFZNTAwfSBmcm9tICcuL2xtci1waXZvdC1jb25zdGFudHMnO1xuXG5pbnRlcmZhY2UgSGVhZGVyR3JvdXBJbmZvIHtcbiAgYmFja2dyb3VuZDogc3RyaW5nO1xuICBpbmRleGVzOiBudW1iZXJbXTtcbiAgZXhwcmVzc2lvbj86IExtclBpdm90RGF0YUhlYWRlckV4cHJlc3Npb247XG4gIGxldmVsOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBWYWx1ZVR5cGVJbmZvIHtcbiAgc3VtPzogbnVtYmVyO1xuICBzdW1zUm93cz86IG51bWJlcltdO1xuICBzdW1zQ29sdW1ucz86IG51bWJlcltdO1xuICBkZWZhdWx0Q29uc3RyYWludD86IENvbnN0cmFpbnQ7XG59XG5cbmV4cG9ydCBjbGFzcyBQaXZvdFRhYmxlQ29udmVydGVyIHtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBlbXB0eUNsYXNzID0gJ3Bpdm90LWVtcHR5LWNlbGwnO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IGRhdGFDbGFzcyA9ICdwaXZvdC1kYXRhLWNlbGwnO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IGdyb3VwRGF0YUNsYXNzID0gJ3Bpdm90LWRhdGEtZ3JvdXAtY2VsbCc7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgcm93SGVhZGVyQ2xhc3MgPSAncGl2b3Qtcm93LWhlYWRlci1jZWxsJztcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSByb3dHcm91cEhlYWRlckNsYXNzID0gJ3Bpdm90LXJvdy1ncm91cC1oZWFkZXItY2VsbCc7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgcm93QXR0cmlidXRlSGVhZGVyQ2xhc3MgPSAncGl2b3Qtcm93LWF0dHJpYnV0ZS1oZWFkZXItY2VsbCc7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgY29sdW1uSGVhZGVyQ2xhc3MgPSAncGl2b3QtY29sdW1uLWhlYWRlci1jZWxsJztcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBjb2x1bW5Hcm91cEhlYWRlckNsYXNzID0gJ3Bpdm90LWNvbHVtbi1ncm91cC1oZWFkZXItY2VsbCc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBncm91cENvbG9ycyA9IFtDT0xPUl9HUkFZMTAwLCBDT0xPUl9HUkFZMjAwLCBDT0xPUl9HUkFZMzAwLCBDT0xPUl9HUkFZNDAwLCBDT0xPUl9HUkFZNTAwXTtcblxuICBwcml2YXRlIHJlYWRvbmx5IHBlcmNlbnRhZ2VDb25zdHJhaW50ID0gbmV3IFBlcmNlbnRhZ2VDb25zdHJhaW50KHtkZWNpbWFsczogMn0pO1xuXG4gIHByaXZhdGUgZGF0YTogTG1yUGl2b3RTdGVtRGF0YTtcbiAgcHJpdmF0ZSB0cmFuc2Zvcm06IExtclBpdm90VHJhbnNmb3JtO1xuICBwcml2YXRlIHZhbHVlczogYW55W11bXTtcbiAgcHJpdmF0ZSBkYXRhUmVzb3VyY2VzOiBEYXRhUmVzb3VyY2VbXVtdW107XG4gIHByaXZhdGUgY29uc3RyYWludERhdGE6IENvbnN0cmFpbnREYXRhO1xuICBwcml2YXRlIHJvd0xldmVsczogbnVtYmVyO1xuICBwcml2YXRlIHJvd3NUcmFuc2Zvcm1hdGlvbkFycmF5OiBudW1iZXJbXTtcbiAgcHJpdmF0ZSBjb2x1bW5MZXZlbHM6IG51bWJlcjtcbiAgcHJpdmF0ZSBjb2x1bW5zVHJhbnNmb3JtYXRpb25BcnJheTogbnVtYmVyW107XG4gIHByaXZhdGUgdmFsdWVUeXBlSW5mbzogVmFsdWVUeXBlSW5mb1tdO1xuICBwcml2YXRlIG5vblN0aWNreVJvd0luZGV4OiBudW1iZXI7XG4gIHByaXZhdGUgbm9uU3RpY2t5Q29sdW1uSW5kZXg6IG51bWJlcjtcblxuICBwdWJsaWMgY3JlYXRlVGFibGVzKHBpdm90RGF0YTogTG1yUGl2b3REYXRhLCB0cmFuc2Zvcm06IExtclBpdm90VHJhbnNmb3JtKTogTG1yUGl2b3RUYWJsZVtdIHtcbiAgICBpZiAoIXBpdm90RGF0YSkge1xuICAgICAgcmV0dXJuIFt7Y2VsbHM6IFtdfV07XG4gICAgfVxuXG4gICAgdGhpcy50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgdGhpcy5jb25zdHJhaW50RGF0YSA9IHBpdm90RGF0YS5jb25zdHJhaW50RGF0YTtcblxuICAgIHJldHVybiAocGl2b3REYXRhLmRhdGEgfHwgW10pLm1hcChkID0+IHtcbiAgICAgIGlmICh0aGlzLmRhdGFBcmVFbXB0eShkKSkge1xuICAgICAgICByZXR1cm4ge2NlbGxzOiBbXX07XG4gICAgICB9XG4gICAgICB0aGlzLnVwZGF0ZURhdGEoZCk7XG4gICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm1EYXRhKCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGRhdGFBcmVFbXB0eShkYXRhOiBMbXJQaXZvdFN0ZW1EYXRhKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChkYXRhLnJvd0hlYWRlcnMgfHwgW10pLmxlbmd0aCA9PT0gMCAmJiAoZGF0YS5jb2x1bW5IZWFkZXJzIHx8IFtdKS5sZW5ndGggPT09IDA7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZURhdGEoZGF0YTogTG1yUGl2b3RTdGVtRGF0YSkge1xuICAgIGNvbnN0IG51bWJlck9mU3VtcyA9IE1hdGgubWF4KDEsIChkYXRhLnZhbHVlVGl0bGVzIHx8IFtdKS5sZW5ndGgpO1xuICAgIHRoaXMudmFsdWVUeXBlSW5mbyA9IGdldFZhbHVlc1R5cGVJbmZvKGRhdGEudmFsdWVzLCBkYXRhLnZhbHVlVHlwZXMsIG51bWJlck9mU3Vtcyk7XG4gICAgdGhpcy5kYXRhID0gcHJlcGFyZVBpdm90RGF0YShkYXRhLCB0aGlzLmNvbnN0cmFpbnREYXRhLCB0aGlzLnZhbHVlVHlwZUluZm8pO1xuICAgIHRoaXMudmFsdWVzID0gZGF0YS52YWx1ZXMgfHwgW107XG4gICAgdGhpcy5kYXRhUmVzb3VyY2VzID0gZGF0YS5kYXRhUmVzb3VyY2VzIHx8IFtdO1xuICAgIHRoaXMucm93TGV2ZWxzID0gKGRhdGEucm93c0NvbmZpZyB8fCBbXSkubGVuZ3RoO1xuICAgIHRoaXMuY29sdW1uTGV2ZWxzID0gKGRhdGEuY29sdW1uc0NvbmZpZyB8fCBbXSkubGVuZ3RoICsgKGRhdGEuaGFzQWRkaXRpb25hbENvbHVtbkxldmVsID8gMSA6IDApO1xuICAgIGNvbnN0IHJvd0FsbFN0aWNreSA9IHRoaXMuZGF0YS5yb3dzQ29uZmlnPy5sZW5ndGggJiYgdGhpcy5kYXRhLnJvd3NDb25maWcuZXZlcnkoY29uZmlnID0+ICEhY29uZmlnPy5zdGlja3kpXG4gICAgdGhpcy5ub25TdGlja3lSb3dJbmRleCA9IE1hdGgubWF4KHJvd0FsbFN0aWNreSA/IHRoaXMucm93TGV2ZWxzIDogKHRoaXMuZGF0YS5yb3dzQ29uZmlnPy5maW5kSW5kZXgoY29uZmlnID0+ICFjb25maWc/LnN0aWNreSkgfHwgMCksIDApO1xuICAgIGNvbnN0IGNvbHVtbkFsbFN0aWNreSA9IHRoaXMuZGF0YS5jb2x1bW5zQ29uZmlnPy5sZW5ndGggJiYgdGhpcy5kYXRhLmNvbHVtbnNDb25maWcuZXZlcnkoY29uZmlnID0+ICEhY29uZmlnPy5zdGlja3kpXG4gICAgdGhpcy5ub25TdGlja3lDb2x1bW5JbmRleCA9IE1hdGgubWF4KGNvbHVtbkFsbFN0aWNreSA/IHRoaXMuY29sdW1uTGV2ZWxzIDogKHRoaXMuZGF0YS5jb2x1bW5zQ29uZmlnPy5maW5kSW5kZXgoY29uZmlnID0+ICFjb25maWc/LnN0aWNreSkgfHwgMCksIDApO1xuICAgIGNvbnN0IGhhc1ZhbHVlID0gKGRhdGEudmFsdWVUaXRsZXMgfHwgW10pLmxlbmd0aCA+IDA7XG4gICAgaWYgKCh0aGlzLmRhdGEucm93SGVhZGVycyB8fCBbXSkubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5yb3dzVHJhbnNmb3JtYXRpb25BcnJheSA9IGNyZWF0ZVRyYW5zZm9ybWF0aW9uTWFwKFxuICAgICAgICB0aGlzLmRhdGEucm93SGVhZGVycyxcbiAgICAgICAgdGhpcy5yb3dTaG93U3VtcyxcbiAgICAgICAgdGhpcy5jb2x1bW5MZXZlbHMsXG4gICAgICAgIDFcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucm93c1RyYW5zZm9ybWF0aW9uQXJyYXkgPSBoYXNWYWx1ZSA/IFt0aGlzLmNvbHVtbkxldmVsc10gOiBbXTtcbiAgICB9XG5cbiAgICBpZiAoKHRoaXMuZGF0YS5jb2x1bW5IZWFkZXJzIHx8IFtdKS5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5ID0gY3JlYXRlVHJhbnNmb3JtYXRpb25NYXAoXG4gICAgICAgIHRoaXMuZGF0YS5jb2x1bW5IZWFkZXJzLFxuICAgICAgICB0aGlzLmNvbHVtblNob3dTdW1zLFxuICAgICAgICB0aGlzLnJvd0xldmVscyxcbiAgICAgICAgbnVtYmVyT2ZTdW1zXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5ID0gaGFzVmFsdWUgPyBbdGhpcy5yb3dMZXZlbHNdIDogW107XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXQgcm93U2hvd1N1bXMoKTogYm9vbGVhbltdIHtcbiAgICByZXR1cm4gKHRoaXMuZGF0YS5yb3dzQ29uZmlnIHx8IFtdKS5tYXAoY29uZmlnID0+IGNvbmZpZy5zaG93U3Vtcyk7XG4gIH1cblxuICBwcml2YXRlIGdldCBjb2x1bW5TaG93U3VtcygpOiBib29sZWFuW10ge1xuICAgIHJldHVybiAodGhpcy5kYXRhLmNvbHVtbnNDb25maWcgfHwgW10pLm1hcChjb25maWcgPT4gY29uZmlnLnNob3dTdW1zKTtcbiAgfVxuXG4gIHByaXZhdGUgdHJhbnNmb3JtRGF0YSgpOiBMbXJQaXZvdFRhYmxlIHtcbiAgICBjb25zdCBjZWxscyA9IHRoaXMuaW5pdENlbGxzKCk7XG4gICAgY29uc3Qgcm93R3JvdXBzID0gdGhpcy5maWxsQ2VsbHNCeVJvd3MoY2VsbHMpO1xuICAgIGNvbnN0IGNvbHVtbkdyb3VwcyA9IHRoaXMuZmlsbENlbGxzQnlDb2x1bW5zKGNlbGxzKTtcbiAgICB0aGlzLmZpbGxDZWxsc0J5R3JvdXBJbnRlcnNlY3Rpb24oY2VsbHMsIHJvd0dyb3VwcywgY29sdW1uR3JvdXBzKTtcbiAgICByZXR1cm4ge2NlbGxzfTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsbENlbGxzQnlSb3dzKGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10pOiBIZWFkZXJHcm91cEluZm9bXSB7XG4gICAgY29uc3Qgcm93R3JvdXBzID0gW107XG4gICAgdGhpcy5pdGVyYXRlQW5kRmlsbENlbGxzQnlSb3dzKGNlbGxzLCByb3dHcm91cHMsIHRoaXMuZGF0YS5yb3dIZWFkZXJzLCB0aGlzLmNvbHVtbkxldmVscywgdGhpcy5yb3dTaG93U3VtcywgMCk7XG4gICAgcmV0dXJuIHJvd0dyb3VwcztcbiAgfVxuXG4gIHByaXZhdGUgaXRlcmF0ZUFuZEZpbGxDZWxsc0J5Um93cyhcbiAgICBjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLFxuICAgIHJvd0dyb3Vwc0luZm86IEhlYWRlckdyb3VwSW5mb1tdLFxuICAgIGhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLFxuICAgIHN0YXJ0SW5kZXg6IG51bWJlcixcbiAgICBzaG93U3VtczogYm9vbGVhbltdLFxuICAgIGxldmVsOiBudW1iZXIsXG4gICAgcGFyZW50SGVhZGVyPzogTG1yUGl2b3REYXRhSGVhZGVyXG4gICkge1xuICAgIGxldCBjdXJyZW50SW5kZXggPSBzdGFydEluZGV4O1xuICAgIGZvciAoY29uc3QgaGVhZGVyIG9mIGhlYWRlcnMpIHtcblxuICAgICAgY29uc3QgYmVmb3JlRXhwcmVzc2lvbnMgPSAoaGVhZGVyLmV4cHJlc3Npb25zIHx8IFtdKS5maWx0ZXIoZXhwID0+IGV4cC5wb3NpdGlvbiA9PT0gTG1yUGl2b3RQb3NpdGlvbi5CZWZvcmVIZWFkZXIpXG4gICAgICB0aGlzLmZpbGxDZWxsc0ZvckV4cHJlc3Npb25zKGNlbGxzLCByb3dHcm91cHNJbmZvLCBsZXZlbCwgY3VycmVudEluZGV4LCBiZWZvcmVFeHByZXNzaW9ucylcbiAgICAgIGN1cnJlbnRJbmRleCArPSBiZWZvcmVFeHByZXNzaW9ucy5sZW5ndGhcblxuICAgICAgY29uc3Qgcm93U3BhbiA9IGdldERpcmVjdEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCBsZXZlbCwgc2hvd1N1bXMpO1xuICAgICAgY2VsbHNbY3VycmVudEluZGV4XVtsZXZlbF0gPSB7XG4gICAgICAgIHZhbHVlOiB0aGlzLmZvcm1hdFJvd0hlYWRlcihoZWFkZXIudGl0bGUsIGxldmVsKSxcbiAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIucm93SGVhZGVyQ2xhc3MsXG4gICAgICAgIGlzSGVhZGVyOiB0cnVlLFxuICAgICAgICBzdGlja3lTdGFydDogdGhpcy5pc1Jvd0xldmVsU3RpY2t5KGxldmVsKSxcbiAgICAgICAgcm93U3BhbixcbiAgICAgICAgY29sU3BhbjogMSxcbiAgICAgICAgYmFja2dyb3VuZDogdGhpcy5nZXRIZWFkZXJCYWNrZ3JvdW5kKGhlYWRlciwgbGV2ZWwpLFxuICAgICAgICBjb25zdHJhaW50OiBoZWFkZXIuY29uc3RyYWludCxcbiAgICAgICAgbGFiZWw6IGhlYWRlci5hdHRyaWJ1dGVOYW1lLFxuICAgICAgICBjaGlsZEluZGV4ZXM6IGNyZWF0ZVJhbmdlKGN1cnJlbnRJbmRleCwgY3VycmVudEluZGV4ICsgKGhlYWRlci5jaGlsZHJlbj8ubGVuZ3RoIHx8IDEpKSxcbiAgICAgICAgZXhwYW5kYWJsZTogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGlmIChoZWFkZXIuY2hpbGRyZW4pIHtcbiAgICAgICAgdGhpcy5pdGVyYXRlQW5kRmlsbENlbGxzQnlSb3dzKFxuICAgICAgICAgIGNlbGxzLFxuICAgICAgICAgIHJvd0dyb3Vwc0luZm8sXG4gICAgICAgICAgaGVhZGVyLmNoaWxkcmVuLFxuICAgICAgICAgIGN1cnJlbnRJbmRleCxcbiAgICAgICAgICBzaG93U3VtcyxcbiAgICAgICAgICBsZXZlbCArIDEsXG4gICAgICAgICAgaGVhZGVyXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKGhlYWRlci50YXJnZXRJbmRleCkpIHtcbiAgICAgICAgdGhpcy5maWxsQ2VsbHNGb3JSb3coY2VsbHMsIGhlYWRlci50YXJnZXRJbmRleCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFmdGVyRXhwcmVzc2lvbnMgPSAoaGVhZGVyLmV4cHJlc3Npb25zIHx8IFtdKS5maWx0ZXIoZXhwID0+IGV4cC5wb3NpdGlvbiA9PT0gTG1yUGl2b3RQb3NpdGlvbi5TdGlja1RvRW5kKVxuICAgICAgY3VycmVudEluZGV4ICs9IGdldEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCBsZXZlbCwgc2hvd1N1bXMpIC0gYmVmb3JlRXhwcmVzc2lvbnMubGVuZ3RoO1xuICAgICAgdGhpcy5maWxsQ2VsbHNGb3JFeHByZXNzaW9ucyhjZWxscywgcm93R3JvdXBzSW5mbywgbGV2ZWwsIGN1cnJlbnRJbmRleCAtIGFmdGVyRXhwcmVzc2lvbnMubGVuZ3RoLCBhZnRlckV4cHJlc3Npb25zKVxuICAgIH1cblxuICAgIGlmIChzaG93U3Vtc1tsZXZlbF0pIHtcbiAgICAgIGNvbnN0IHsgdGl0bGUsIHN1bW1hcnkgfSA9IHRoaXMuZm9ybWF0U3VtbWFyeUhlYWRlcihwYXJlbnRIZWFkZXIsIGxldmVsKVxuICAgICAgY29uc3QgYmFja2dyb3VuZCA9IHRoaXMuZ2V0U3VtbWFyeUJhY2tncm91bmQobGV2ZWwpO1xuICAgICAgY29uc3QgY29sdW1uSW5kZXggPSBNYXRoLm1heChsZXZlbCAtIDEsIDApO1xuICAgICAgdGhpcy5zcGxpdFJvd0dyb3VwSGVhZGVyKGNlbGxzLCBjb2x1bW5JbmRleCwgY3VycmVudEluZGV4LCBiYWNrZ3JvdW5kLCBzdW1tYXJ5LCBbXSwgZmFsc2UsIHRpdGxlLCBwYXJlbnRIZWFkZXI/LmNvbnN0cmFpbnQsIHBhcmVudEhlYWRlcj8uYXR0cmlidXRlTmFtZSlcblxuICAgICAgY29uc3Qgcm93SW5kZXhlcyA9IGdldFRhcmdldEluZGV4ZXNGb3JIZWFkZXJzKGhlYWRlcnMpO1xuICAgICAgY29uc3QgdHJhbnNmb3JtZWRSb3dJbmRleGVzID0gdGhpcy50cmFuc2Zvcm1Sb3dJbmRleGVzKHJvd0luZGV4ZXMpO1xuICAgICAgcm93R3JvdXBzSW5mb1tjdXJyZW50SW5kZXhdID0ge2JhY2tncm91bmQsIGluZGV4ZXM6IHRyYW5zZm9ybWVkUm93SW5kZXhlcywgbGV2ZWx9O1xuXG4gICAgICB0aGlzLmZpbGxDZWxsc0Zvckdyb3VwZWRSb3coY2VsbHMsIHJvd0luZGV4ZXMsIGN1cnJlbnRJbmRleCwgYmFja2dyb3VuZCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmaWxsQ2VsbHNGb3JFeHByZXNzaW9ucyhjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLCByb3dHcm91cHNJbmZvOiBIZWFkZXJHcm91cEluZm9bXSwgbGV2ZWw6IG51bWJlciwgY3VycmVudEluZGV4OiBudW1iZXIsIGV4cHJlc3Npb25zOiBMbXJQaXZvdERhdGFIZWFkZXJFeHByZXNzaW9uW10pIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cHJlc3Npb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBleHByZXNzaW9uSW5kZXggPSBjdXJyZW50SW5kZXggKyBpXG4gICAgICBjb25zdCBiYWNrZ3JvdW5kID0gdGhpcy5nZXRTdW1tYXJ5QmFja2dyb3VuZChsZXZlbCk7XG4gICAgICBjb25zdCB7aW5kZXhlc30gPSB0aGlzLmZpbGxDZWxsc0ZvckV4cHJlc3Npb25Sb3coY2VsbHMsIGV4cHJlc3Npb25zW2ldLCBleHByZXNzaW9uSW5kZXgsIGJhY2tncm91bmQpXG4gICAgICB0aGlzLnNwbGl0Um93R3JvdXBIZWFkZXIoY2VsbHMsIGxldmVsLCBleHByZXNzaW9uSW5kZXgsIGJhY2tncm91bmQsIGV4cHJlc3Npb25zW2ldLnRpdGxlLCBpbmRleGVzLCBleHByZXNzaW9uc1tpXS5leHBhbmRhYmxlKVxuICAgICAgcm93R3JvdXBzSW5mb1tleHByZXNzaW9uSW5kZXhdID0ge2JhY2tncm91bmQsIGluZGV4ZXM6IFtdLCBleHByZXNzaW9uOiBleHByZXNzaW9uc1tpXSwgbGV2ZWx9O1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3BsaXRSb3dHcm91cEhlYWRlcihjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLCBjb2x1bW5JbmRleDogbnVtYmVyLCBjdXJyZW50SW5kZXg6IG51bWJlciwgYmFja2dyb3VuZDogc3RyaW5nLCBzdW1tYXJ5OiBzdHJpbmcsIHJvd0luZGV4ZXM6IG51bWJlcltdLCBleHBhbmRhYmxlOiBib29sZWFuLCB0aXRsZT86IHN0cmluZywgY29uc3RyYWludD86IENvbnN0cmFpbnQsIGxhYmVsPzogc3RyaW5nKSB7XG4gICAgbGV0IGNvbFNwYW4gPSB0aGlzLnJvd0xldmVscyAtIGNvbHVtbkluZGV4O1xuICAgIGNvbnN0IHN0aWNreVN0YXJ0ID0gdGhpcy5pc1Jvd0xldmVsU3RpY2t5KGNvbHVtbkluZGV4KTtcblxuICAgIC8vIHNwbGl0IHJvdyBncm91cCBoZWFkZXIgY2VsbCBiZWNhdXNlIG9mIGNvcnJlY3Qgc3RpY2t5IHNjcm9sbFxuICAgIGlmIChzdGlja3lTdGFydCAmJiB0aGlzLm5vblN0aWNreVJvd0luZGV4ID4gMCAmJiB0aGlzLm5vblN0aWNreVJvd0luZGV4IDwgdGhpcy5yb3dMZXZlbHMgJiYgY29sU3BhbiA+IDEpIHtcbiAgICAgIGNvbnN0IG5ld0NvbHNwYW4gPSB0aGlzLm5vblN0aWNreVJvd0luZGV4IC0gY29sdW1uSW5kZXg7XG5cbiAgICAgIGNlbGxzW2N1cnJlbnRJbmRleF1bdGhpcy5ub25TdGlja3lSb3dJbmRleF0gPSB7XG4gICAgICAgIHZhbHVlOiB1bmRlZmluZWQsXG4gICAgICAgIGNvbnN0cmFpbnQ6IHVuZGVmaW5lZCxcbiAgICAgICAgbGFiZWw6IHVuZGVmaW5lZCxcbiAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIucm93R3JvdXBIZWFkZXJDbGFzcyxcbiAgICAgICAgaXNTdW1tYXJ5OiB0cnVlLFxuICAgICAgICByb3dTcGFuOiAxLFxuICAgICAgICBjb2xTcGFuOiBjb2xTcGFuIC0gbmV3Q29sc3BhbixcbiAgICAgICAgYmFja2dyb3VuZCxcbiAgICAgICAgc3VtbWFyeTogdW5kZWZpbmVkLFxuICAgICAgICBleHBhbmRhYmxlLFxuICAgICAgfTtcblxuICAgICAgY29sU3BhbiA9IG5ld0NvbHNwYW47XG4gICAgfVxuXG4gICAgY2VsbHNbY3VycmVudEluZGV4XVtjb2x1bW5JbmRleF0gPSB7XG4gICAgICB2YWx1ZTogdGl0bGUsXG4gICAgICBjb25zdHJhaW50LFxuICAgICAgbGFiZWwsXG4gICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5yb3dHcm91cEhlYWRlckNsYXNzLFxuICAgICAgaXNTdW1tYXJ5OiB0cnVlLFxuICAgICAgc3RpY2t5U3RhcnQsXG4gICAgICByb3dTcGFuOiAxLFxuICAgICAgY29sU3BhbixcbiAgICAgIGJhY2tncm91bmQsXG4gICAgICBzdW1tYXJ5LFxuICAgICAgcm93SW5kZXhlcyxcbiAgICAgIGV4cGFuZGFibGUsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0U3VtbWFyeUhlYWRlcihoZWFkZXI6IExtclBpdm90RGF0YUhlYWRlciwgbGV2ZWw6IG51bWJlcik6IHt0aXRsZT86IHN0cmluZzsgc3VtbWFyeTogc3RyaW5nfSB7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtLmZvcm1hdFN1bW1hcnlIZWFkZXI/LihoZWFkZXIsIGxldmVsKSB8fCB7XG4gICAgICB0aXRsZTogaGVhZGVyPy50aXRsZSxcbiAgICAgIHN1bW1hcnk6ICcnLFxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0Um93SGVhZGVyKHRpdGxlOiBzdHJpbmcsIGxldmVsOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybT8uZm9ybWF0Um93SGVhZGVyPy4odGl0bGUsIGxldmVsKSB8fCB0aXRsZVxuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRDb2x1bW5IZWFkZXIodGl0bGU6IHN0cmluZywgbGV2ZWw6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtPy5mb3JtYXRDb2x1bW5IZWFkZXI/Lih0aXRsZSwgbGV2ZWwpIHx8IHRpdGxlXG4gIH1cblxuICBwcml2YXRlIGdldEhlYWRlckJhY2tncm91bmQoaGVhZGVyOiB7IGNvbG9yOiBzdHJpbmcgfSwgbGV2ZWw6IG51bWJlcik6IHN0cmluZyB7XG4gICAgaWYgKGhlYWRlcj8uY29sb3IpIHtcbiAgICAgIHJldHVybiBzaGFkZUNvbG9yKGhlYWRlci5jb2xvciwgdGhpcy5nZXRMZXZlbE9wYWNpdHkobGV2ZWwpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRMZXZlbE9wYWNpdHkobGV2ZWw6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgubWluKDgwLCA1MCArIGxldmVsICogNSkgLyAxMDA7XG4gIH1cblxuICBwcml2YXRlIGlzUm93TGV2ZWxTdGlja3kobGV2ZWw6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmRhdGE/LnJvd3NDb25maWc/LltsZXZlbF0/LnN0aWNreTtcbiAgfVxuXG4gIHByaXZhdGUgaXNDb2x1bW5MZXZlbFN0aWNreShsZXZlbDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgbWF4TGV2ZWwgPSBNYXRoLm1pbihsZXZlbCwgKHRoaXMuZGF0YT8uY29sdW1uc0NvbmZpZz8ubGVuZ3RoID8/IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSKSAtIDEpO1xuICAgIHJldHVybiB0aGlzLmRhdGE/LmNvbHVtbnNDb25maWc/LlttYXhMZXZlbF0/LnN0aWNreTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3VtbWFyeUJhY2tncm91bmQobGV2ZWw6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgaW5kZXggPSBNYXRoLm1pbihsZXZlbCwgdGhpcy5ncm91cENvbG9ycy5sZW5ndGggLSAxKTtcbiAgICByZXR1cm4gdGhpcy5ncm91cENvbG9yc1tpbmRleF07XG4gIH1cblxuICBwcml2YXRlIGZpbGxDZWxsc0ZvclJvdyhjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLCByb3c6IG51bWJlcikge1xuICAgIGNvbnN0IHJvd0luZGV4SW5DZWxscyA9IHRoaXMucm93c1RyYW5zZm9ybWF0aW9uQXJyYXlbcm93XTtcbiAgICBpZiAoaXNOb3ROdWxsT3JVbmRlZmluZWQocm93SW5kZXhJbkNlbGxzKSkge1xuICAgICAgZm9yIChsZXQgY29sdW1uID0gMDsgY29sdW1uIDwgdGhpcy5jb2x1bW5zVHJhbnNmb3JtYXRpb25BcnJheS5sZW5ndGg7IGNvbHVtbisrKSB7XG4gICAgICAgIGNvbnN0IGNvbHVtbkluZGV4SW5DZWxscyA9IHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXlbY29sdW1uXTtcbiAgICAgICAgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKGNvbHVtbkluZGV4SW5DZWxscykpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZGF0YS52YWx1ZXNbcm93XVtjb2x1bW5dO1xuICAgICAgICAgIGNvbnN0IGRhdGFSZXNvdXJjZXMgPSB0aGlzLmRhdGFSZXNvdXJjZXM/Lltyb3ddPy5bY29sdW1uXSB8fCBbXTtcbiAgICAgICAgICBjb25zdCBmb3JtYXR0ZWRWYWx1ZSA9IHRoaXMuYWdncmVnYXRlT3JGb3JtYXRTaW5nbGVWYWx1ZSh2YWx1ZSwgY29sdW1uKTtcbiAgICAgICAgICBjb25zdCBzdHJpbmdWYWx1ZSA9IGlzTm90TnVsbE9yVW5kZWZpbmVkKGZvcm1hdHRlZFZhbHVlKSA/IFN0cmluZyhmb3JtYXR0ZWRWYWx1ZSkgOiAnJztcbiAgICAgICAgICBjZWxsc1tyb3dJbmRleEluQ2VsbHNdW2NvbHVtbkluZGV4SW5DZWxsc10gPSB7XG4gICAgICAgICAgICB2YWx1ZTogc3RyaW5nVmFsdWUsXG4gICAgICAgICAgICBkYXRhUmVzb3VyY2VzLFxuICAgICAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5kYXRhQ2xhc3MsXG4gICAgICAgICAgICBpc1ZhbHVlOiB0cnVlLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldFZhbHVlSW5kZXhGb3JDb2x1bW5zKGNvbHVtbnM6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgICByZXR1cm4gY29sdW1uc1swXSAlIHRoaXMuZGF0YS52YWx1ZVRpdGxlcy5sZW5ndGg7XG4gIH1cblxuICBwcml2YXRlIGZvcm1hdFZhbHVlQnlWYWx1ZVR5cGUodmFsdWU6IGFueSwgdmFsdWVJbmRleDogbnVtYmVyKTogYW55IHtcbiAgICBjb25zdCB2YWx1ZVR5cGUgPSAodGhpcy5kYXRhLnZhbHVlVHlwZXMgfHwgW10pW3ZhbHVlSW5kZXhdO1xuICAgIGlmICghdmFsdWVUeXBlIHx8IHZhbHVlVHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuRGVmYXVsdCkge1xuICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0VmFsdWVCeUNvbnN0cmFpbnQodmFsdWUsIHZhbHVlSW5kZXgpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIFtMbXJQaXZvdFZhbHVlVHlwZS5BbGxQZXJjZW50YWdlLCBMbXJQaXZvdFZhbHVlVHlwZS5Db2x1bW5QZXJjZW50YWdlLCBMbXJQaXZvdFZhbHVlVHlwZS5Sb3dQZXJjZW50YWdlXS5pbmNsdWRlcyh2YWx1ZVR5cGUpXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy5mb3JtYXRWYWx1ZUJ5UGVyY2VudGFnZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZm9ybWF0VmFsdWVCeUNvbnN0cmFpbnQodmFsdWUsIHZhbHVlSW5kZXgpO1xuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRHcm91cGVkVmFsdWVCeVZhbHVlVHlwZSh2YWx1ZTogYW55LCByb3dzOiBudW1iZXJbXSwgY29sdW1uczogbnVtYmVyW10pOiBhbnkge1xuICAgIGNvbnN0IHZhbHVlSW5kZXggPSBjb2x1bW5zWzBdICUgdGhpcy5kYXRhLnZhbHVlVGl0bGVzLmxlbmd0aDtcbiAgICBjb25zdCB2YWx1ZVR5cGUgPSB0aGlzLmRhdGEudmFsdWVUeXBlcyAmJiB0aGlzLmRhdGEudmFsdWVUeXBlc1t2YWx1ZUluZGV4XTtcbiAgICBjb25zdCB2YWx1ZVR5cGVJbmZvID0gdGhpcy52YWx1ZVR5cGVJbmZvW3ZhbHVlSW5kZXhdO1xuICAgIGlmICghdmFsdWVUeXBlSW5mbyB8fCAhdmFsdWVUeXBlIHx8IHZhbHVlVHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuRGVmYXVsdCkge1xuICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0VmFsdWVCeUNvbnN0cmFpbnQodmFsdWUsIHZhbHVlSW5kZXgpO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZVR5cGUgPT09IExtclBpdm90VmFsdWVUeXBlLkFsbFBlcmNlbnRhZ2UpIHtcbiAgICAgIHJldHVybiB0aGlzLmZvcm1hdFZhbHVlQnlQZXJjZW50YWdlKGRpdmlkZVZhbHVlcyh2YWx1ZSwgdmFsdWVUeXBlSW5mby5zdW0pKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlVHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuQ29sdW1uUGVyY2VudGFnZSkge1xuICAgICAgY29uc3QgY29sdW1uc0RpdmlkZXJzID0gY29sdW1ucy5yZWR1Y2UoKGRpdmlkZXJzLCBjb2x1bW4pID0+IHtcbiAgICAgICAgZGl2aWRlcnMucHVzaCh2YWx1ZVR5cGVJbmZvLnN1bXNDb2x1bW5zW2NvbHVtbl0pO1xuICAgICAgICByZXR1cm4gZGl2aWRlcnM7XG4gICAgICB9LCBbXSk7XG4gICAgICBjb25zdCBjb2x1bW5zRGl2aWRlciA9IGFnZ3JlZ2F0ZURhdGFWYWx1ZXMoRGF0YUFnZ3JlZ2F0aW9uVHlwZS5TdW0sIGNvbHVtbnNEaXZpZGVycyk7XG4gICAgICByZXR1cm4gdGhpcy5mb3JtYXRWYWx1ZUJ5UGVyY2VudGFnZShkaXZpZGVWYWx1ZXModmFsdWUsIGNvbHVtbnNEaXZpZGVyKSk7XG4gICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09IExtclBpdm90VmFsdWVUeXBlLlJvd1BlcmNlbnRhZ2UpIHtcbiAgICAgIGNvbnN0IHJvd3NEaXZpZGVycyA9IHJvd3MucmVkdWNlKChkaXZpZGVycywgcm93KSA9PiB7XG4gICAgICAgIGRpdmlkZXJzLnB1c2godmFsdWVUeXBlSW5mby5zdW1zUm93c1tyb3ddKTtcbiAgICAgICAgcmV0dXJuIGRpdmlkZXJzO1xuICAgICAgfSwgW10pO1xuICAgICAgY29uc3Qgcm93c0RpdmlkZXIgPSBhZ2dyZWdhdGVEYXRhVmFsdWVzKERhdGFBZ2dyZWdhdGlvblR5cGUuU3VtLCByb3dzRGl2aWRlcnMpO1xuICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0VmFsdWVCeVBlcmNlbnRhZ2UoZGl2aWRlVmFsdWVzKHZhbHVlLCByb3dzRGl2aWRlcikpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmZvcm1hdFZhbHVlQnlDb25zdHJhaW50KHZhbHVlLCB2YWx1ZUluZGV4KTtcbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0VmFsdWVCeVBlcmNlbnRhZ2UodmFsdWU6IGFueSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucGVyY2VudGFnZUNvbnN0cmFpbnQuY3JlYXRlRGF0YVZhbHVlKHZhbHVlKS5mb3JtYXQoKTtcbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0VmFsdWVCeUNvbnN0cmFpbnQodmFsdWU6IGFueSwgdmFsdWVJbmRleDogbnVtYmVyKTogYW55IHtcbiAgICBjb25zdCBjb25zdHJhaW50ID0gdGhpcy5kYXRhLnZhbHVlc0NvbnN0cmFpbnRzPy5bdmFsdWVJbmRleF0gfHwgdGhpcy52YWx1ZVR5cGVJbmZvW3ZhbHVlSW5kZXhdPy5kZWZhdWx0Q29uc3RyYWludDtcbiAgICBpZiAoY29uc3RyYWludCkge1xuICAgICAgcmV0dXJuIGNvbnN0cmFpbnQuY3JlYXRlRGF0YVZhbHVlKHZhbHVlLCB0aGlzLmNvbnN0cmFpbnREYXRhKS5wcmV2aWV3KCk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsbENlbGxzRm9yR3JvdXBlZFJvdyhcbiAgICBjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLFxuICAgIHJvd3M6IG51bWJlcltdLFxuICAgIHJvd0luZGV4SW5DZWxsczogbnVtYmVyLFxuICAgIGJhY2tncm91bmQ6IHN0cmluZ1xuICApIHtcbiAgICBmb3IgKGxldCBjb2x1bW4gPSAwOyBjb2x1bW4gPCB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5Lmxlbmd0aDsgY29sdW1uKyspIHtcbiAgICAgIGNvbnN0IGNvbHVtbkluZGV4SW5DZWxscyA9IHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXlbY29sdW1uXTtcbiAgICAgIGlmIChpc05vdE51bGxPclVuZGVmaW5lZChjb2x1bW5JbmRleEluQ2VsbHMpKSB7XG4gICAgICAgIGNvbnN0IHt2YWx1ZXMsIGRhdGFSZXNvdXJjZXN9ID0gdGhpcy5nZXRHcm91cGVkVmFsdWVzRm9yUm93c0FuZENvbHMocm93cywgW2NvbHVtbl0pO1xuICAgICAgICBjb25zdCBmb3JtYXR0ZWRWYWx1ZSA9IHRoaXMuYWdncmVnYXRlQW5kRm9ybWF0RGF0YVZhbHVlcyh2YWx1ZXMsIHJvd3MsIFtjb2x1bW5dKTtcbiAgICAgICAgY2VsbHNbcm93SW5kZXhJbkNlbGxzXVtjb2x1bW5JbmRleEluQ2VsbHNdID0ge1xuICAgICAgICAgIHZhbHVlOiBTdHJpbmcoZm9ybWF0dGVkVmFsdWUpLFxuICAgICAgICAgIGRhdGFSZXNvdXJjZXMsXG4gICAgICAgICAgY29sU3BhbjogMSxcbiAgICAgICAgICByb3dTcGFuOiAxLFxuICAgICAgICAgIGNzc0NsYXNzOiBQaXZvdFRhYmxlQ29udmVydGVyLmdyb3VwRGF0YUNsYXNzLFxuICAgICAgICAgIGJhY2tncm91bmQsXG4gICAgICAgICAgaXNWYWx1ZTogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZpbGxDZWxsc0ZvckV4cHJlc3Npb25Sb3coXG4gICAgY2VsbHM6IExtclBpdm90VGFibGVDZWxsW11bXSxcbiAgICBleHByZXNzaW9uOiBMbXJQaXZvdERhdGFIZWFkZXJFeHByZXNzaW9uLFxuICAgIHJvd0luZGV4SW5DZWxsczogbnVtYmVyLFxuICAgIGJhY2tncm91bmQ6IHN0cmluZ1xuICApOntpbmRleGVzOiBudW1iZXJbXX0ge1xuICAgIGxldCByb3dJbmRleGVzOiBudW1iZXJbXSA9IFtdO1xuICAgIGZvciAobGV0IGNvbHVtbiA9IDA7IGNvbHVtbiA8IHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXkubGVuZ3RoOyBjb2x1bW4rKykge1xuICAgICAgY29uc3QgY29sdW1uSW5kZXhJbkNlbGxzID0gdGhpcy5jb2x1bW5zVHJhbnNmb3JtYXRpb25BcnJheVtjb2x1bW5dO1xuICAgICAgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKGNvbHVtbkluZGV4SW5DZWxscykpIHtcbiAgICAgICAgY29uc3Qge3ZhbHVlLCBkYXRhUmVzb3VyY2VzLCBpbmRleGVzfSA9IHRoaXMuZXZhbHVhdGVFeHByZXNzaW9uKGV4cHJlc3Npb24sIFtjb2x1bW5dKTtcbiAgICAgICAgcm93SW5kZXhlcyA9IGluZGV4ZXNcbiAgICAgICAgY29uc3QgdmFsdWVJbmRleCA9IGNvbHVtbiAlIHRoaXMuZGF0YS52YWx1ZVRpdGxlcy5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGZvcm1hdHRlZFZhbHVlID0gdGhpcy5mb3JtYXRWYWx1ZUJ5Q29uc3RyYWludCh2YWx1ZSwgdmFsdWVJbmRleCk7XG4gICAgICAgIGNlbGxzW3Jvd0luZGV4SW5DZWxsc11bY29sdW1uSW5kZXhJbkNlbGxzXSA9IHtcbiAgICAgICAgICB2YWx1ZTogU3RyaW5nKGZvcm1hdHRlZFZhbHVlKSxcbiAgICAgICAgICBkYXRhUmVzb3VyY2VzLFxuICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5ncm91cERhdGFDbGFzcyxcbiAgICAgICAgICBiYWNrZ3JvdW5kLFxuICAgICAgICAgIGlzVmFsdWU6IHRydWUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7aW5kZXhlczogdW5pcXVlVmFsdWVzKFtyb3dJbmRleEluQ2VsbHMsIC4uLnJvd0luZGV4ZXNdKX1cbiAgfVxuXG4gIHByaXZhdGUgZXZhbHVhdGVFeHByZXNzaW9uKGV4cHJlc3Npb246IExtclBpdm90RGF0YUhlYWRlckV4cHJlc3Npb24sIGNvbHVtbnM6IG51bWJlcltdKToge3ZhbHVlOiBudW1iZXI7IGRhdGFSZXNvdXJjZXM6IERhdGFSZXNvdXJjZVtdOyBpbmRleGVzOiBudW1iZXJbXSAgfSB7XG4gICAgcmV0dXJuIChleHByZXNzaW9uLm9wZXJhbmRzIHx8IFtdKS5yZWR1Y2UoKHJlc3VsdCwgb3BlcmFuZCwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IHt2YWx1ZSwgZGF0YVJlc291cmNlcywgaW5kZXhlcyB9ID0gdGhpcy5ldmFsdWF0ZU9wZXJhbmQob3BlcmFuZCwgY29sdW1ucylcbiAgICAgIHJlc3VsdC5kYXRhUmVzb3VyY2VzLnB1c2goLi4uZGF0YVJlc291cmNlcylcbiAgICAgIHJlc3VsdC5pbmRleGVzLnB1c2goLi4uaW5kZXhlcylcbiAgICAgIHN3aXRjaCAoZXhwcmVzc2lvbi5vcGVyYXRpb24pIHtcbiAgICAgICAgY2FzZSAnYWRkJzpcbiAgICAgICAgICByZXN1bHQudmFsdWUgKz0gdmFsdWVcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnc3VidHJhY3QnOlxuICAgICAgICAgIHJlc3VsdC52YWx1ZSA9IChpbmRleCA9PT0gMCA/IHZhbHVlIDogcmVzdWx0LnZhbHVlIC0gdmFsdWUpXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ211bHRpcGx5JzpcbiAgICAgICAgICByZXN1bHQudmFsdWUgPSBpbmRleCA9PT0gMCA/IHZhbHVlIDogcmVzdWx0LnZhbHVlICogdmFsdWVcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnZGl2aWRlJzpcbiAgICAgICAgICByZXN1bHQudmFsdWUgPSBpbmRleCA9PT0gMCA/IHZhbHVlIDogdmFsdWUgPyByZXN1bHQudmFsdWUgLyB2YWx1ZSA6IHJlc3VsdC52YWx1ZVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0XG4gICAgfSAsIHt2YWx1ZTogMCwgZGF0YVJlc291cmNlczogW10sIGluZGV4ZXM6IFtdfSlcbiAgfVxuXG4gIHByaXZhdGUgZXZhbHVhdGVPcGVyYW5kKG9wZXJhbmQ6IExtclBpdm90RGF0YUhlYWRlck9wZXJhbmQsIGNvbHVtbnM6IG51bWJlcltdKToge3ZhbHVlOiBudW1iZXI7IGRhdGFSZXNvdXJjZXM6IERhdGFSZXNvdXJjZVtdOyBpbmRleGVzOiBudW1iZXJbXSB9IHtcbiAgICBzd2l0Y2ggKG9wZXJhbmQudHlwZSkge1xuICAgICAgY2FzZSAnZXhwcmVzc2lvbic6IHJldHVybiB0aGlzLmV2YWx1YXRlRXhwcmVzc2lvbihvcGVyYW5kLCBjb2x1bW5zKVxuICAgICAgY2FzZSAndmFsdWUnOiByZXR1cm4ge3ZhbHVlOiBvcGVyYW5kLnZhbHVlLCBkYXRhUmVzb3VyY2VzOiBbXSwgaW5kZXhlczogW119XG4gICAgICBjYXNlICdoZWFkZXInOiB7XG4gICAgICAgIGNvbnN0IHJvd3MgPSBnZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVycyhvcGVyYW5kLmhlYWRlcnMpO1xuICAgICAgICBjb25zdCB7dmFsdWVzLCBkYXRhUmVzb3VyY2VzfSA9IHRoaXMuZ2V0R3JvdXBlZFZhbHVlc0ZvclJvd3NBbmRDb2xzKHJvd3MsIGNvbHVtbnMpO1xuICAgICAgICBjb25zdCB7dmFsdWV9ID0gdGhpcy5hZ2dyZWdhdGVEYXRhVmFsdWVzKHZhbHVlcywgY29sdW1ucyk7XG4gICAgICAgIHJldHVybiB7dmFsdWUsIGRhdGFSZXNvdXJjZXMsIGluZGV4ZXM6IHRoaXMudHJhbnNmb3JtUm93SW5kZXhlcyhyb3dzKX1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHRyYW5zZm9ybVJvd0luZGV4ZXMocm93czogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIHJvd3NcbiAgICAgIC5tYXAodiA9PiB0aGlzLnJvd3NUcmFuc2Zvcm1hdGlvbkFycmF5W3ZdKVxuICAgICAgLmZpbHRlcih2ID0+IGlzTm90TnVsbE9yVW5kZWZpbmVkKHYpKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0R3JvdXBlZFZhbHVlc0ZvclJvd3NBbmRDb2xzKFxuICAgIHJvd3M6IG51bWJlcltdLFxuICAgIGNvbHVtbnM6IG51bWJlcltdXG4gICk6IHsgdmFsdWVzOiBhbnlbXTsgZGF0YVJlc291cmNlczogRGF0YVJlc291cmNlW10gfSB7XG4gICAgY29uc3QgdmFsdWVzID0gW107XG4gICAgY29uc3QgZGF0YVJlc291cmNlcyA9IFtdO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgIGZvciAoY29uc3QgY29sdW1uIG9mIGNvbHVtbnMpIHtcbiAgICAgICAgY29uc3Qgcm93Q29sdW1uVmFsdWUgPSB0aGlzLnZhbHVlc1tyb3ddW2NvbHVtbl07XG4gICAgICAgIGlmIChpc0FycmF5KHJvd0NvbHVtblZhbHVlKSkge1xuICAgICAgICAgIHZhbHVlcy5wdXNoKC4uLnJvd0NvbHVtblZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWx1ZXMucHVzaChyb3dDb2x1bW5WYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZGF0YVJlc291cmNlcy5wdXNoKC4uLih0aGlzLmRhdGFSZXNvdXJjZXM/Lltyb3ddPy5bY29sdW1uXSB8fCBbXSkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge3ZhbHVlcywgZGF0YVJlc291cmNlc307XG4gIH1cblxuICBwcml2YXRlIGZpbGxDZWxsc0J5Q29sdW1ucyhjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdKTogSGVhZGVyR3JvdXBJbmZvW10ge1xuICAgIGNvbnN0IGNvbHVtbkdyb3VwcyA9IFtdO1xuICAgIHRoaXMuaXRlcmF0ZUFuZEZpbGxDZWxsc0J5Q29sdW1ucyhcbiAgICAgIGNlbGxzLFxuICAgICAgY29sdW1uR3JvdXBzLFxuICAgICAgdGhpcy5kYXRhLmNvbHVtbkhlYWRlcnMsXG4gICAgICB0aGlzLnJvd0xldmVscyxcbiAgICAgIHRoaXMuY29sdW1uU2hvd1N1bXMsXG4gICAgICAwXG4gICAgKTtcbiAgICByZXR1cm4gY29sdW1uR3JvdXBzO1xuICB9XG5cbiAgcHJpdmF0ZSBpdGVyYXRlQW5kRmlsbENlbGxzQnlDb2x1bW5zKFxuICAgIGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10sXG4gICAgY29sdW1uR3JvdXBzSW5mbzogSGVhZGVyR3JvdXBJbmZvW10sXG4gICAgaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gICAgc3RhcnRJbmRleDogbnVtYmVyLFxuICAgIHNob3dTdW1zOiBib29sZWFuW10sXG4gICAgbGV2ZWw6IG51bWJlcixcbiAgICBwYXJlbnRIZWFkZXI/OiBMbXJQaXZvdERhdGFIZWFkZXJcbiAgKSB7XG4gICAgbGV0IGN1cnJlbnRJbmRleCA9IHN0YXJ0SW5kZXg7XG4gICAgY29uc3QgbnVtYmVyT2ZTdW1zID0gTWF0aC5tYXgoMSwgdGhpcy5kYXRhLnZhbHVlVGl0bGVzLmxlbmd0aCk7XG4gICAgZm9yIChjb25zdCBoZWFkZXIgb2YgaGVhZGVycykge1xuICAgICAgY29uc3QgY29sU3BhbiA9IGdldERpcmVjdEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCBsZXZlbCwgc2hvd1N1bXMsIG51bWJlck9mU3Vtcyk7XG4gICAgICBjZWxsc1tsZXZlbF1bY3VycmVudEluZGV4XSA9IHtcbiAgICAgICAgdmFsdWU6IHRoaXMuZm9ybWF0Q29sdW1uSGVhZGVyKGhlYWRlci50aXRsZSwgbGV2ZWwpLFxuICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5jb2x1bW5IZWFkZXJDbGFzcyxcbiAgICAgICAgaXNIZWFkZXI6IHRydWUsXG4gICAgICAgIHJvd1NwYW46IDEsXG4gICAgICAgIGNvbFNwYW4sXG4gICAgICAgIHN0aWNreVRvcDogdGhpcy5pc0NvbHVtbkxldmVsU3RpY2t5KGxldmVsKSxcbiAgICAgICAgYmFja2dyb3VuZDogdGhpcy5nZXRIZWFkZXJCYWNrZ3JvdW5kKGhlYWRlciwgbGV2ZWwpLFxuICAgICAgICBjb25zdHJhaW50OiBoZWFkZXIuY29uc3RyYWludCxcbiAgICAgICAgbGFiZWw6IGhlYWRlci5hdHRyaWJ1dGVOYW1lLFxuICAgICAgfTtcblxuICAgICAgaWYgKGhlYWRlci5jaGlsZHJlbikge1xuICAgICAgICB0aGlzLml0ZXJhdGVBbmRGaWxsQ2VsbHNCeUNvbHVtbnMoXG4gICAgICAgICAgY2VsbHMsXG4gICAgICAgICAgY29sdW1uR3JvdXBzSW5mbyxcbiAgICAgICAgICBoZWFkZXIuY2hpbGRyZW4sXG4gICAgICAgICAgY3VycmVudEluZGV4LFxuICAgICAgICAgIHNob3dTdW1zLFxuICAgICAgICAgIGxldmVsICsgMSxcbiAgICAgICAgICBoZWFkZXJcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNOb3ROdWxsT3JVbmRlZmluZWQoaGVhZGVyLnRhcmdldEluZGV4KSkge1xuICAgICAgICB0aGlzLmZpbGxDZWxsc0ZvckNvbHVtbihjZWxscywgaGVhZGVyLnRhcmdldEluZGV4KTtcbiAgICAgIH1cblxuICAgICAgY3VycmVudEluZGV4ICs9IGdldEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCBsZXZlbCwgc2hvd1N1bXMsIG51bWJlck9mU3Vtcyk7XG4gICAgfVxuXG4gICAgaWYgKHNob3dTdW1zW2xldmVsXSkge1xuICAgICAgY29uc3QgYmFja2dyb3VuZCA9IHRoaXMuZ2V0U3VtbWFyeUJhY2tncm91bmQobGV2ZWwpO1xuICAgICAgY29uc3QgeyB0aXRsZSwgc3VtbWFyeSB9ID0gdGhpcy5mb3JtYXRTdW1tYXJ5SGVhZGVyKHBhcmVudEhlYWRlciwgbGV2ZWwpXG4gICAgICBjb25zdCBudW1iZXJPZlZhbHVlcyA9IHRoaXMuZGF0YS52YWx1ZVRpdGxlcy5sZW5ndGg7XG4gICAgICBjb25zdCByb3dJbmRleCA9IE1hdGgubWF4KGxldmVsIC0gMSwgMCk7XG4gICAgICBjb25zdCBzaG91bGRBZGRWYWx1ZUhlYWRlcnMgPSBudW1iZXJPZlZhbHVlcyA+IDE7XG5cbiAgICAgIGNlbGxzW3Jvd0luZGV4XVtjdXJyZW50SW5kZXhdID0ge1xuICAgICAgICB2YWx1ZTogdGl0bGUsXG4gICAgICAgIGNvbnN0cmFpbnQ6IHBhcmVudEhlYWRlcj8uY29uc3RyYWludCxcbiAgICAgICAgbGFiZWw6IHBhcmVudEhlYWRlcj8uYXR0cmlidXRlTmFtZSxcbiAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIuY29sdW1uR3JvdXBIZWFkZXJDbGFzcyxcbiAgICAgICAgaXNTdW1tYXJ5OiB0cnVlLFxuICAgICAgICBzdGlja3lUb3A6IHRoaXMuaXNDb2x1bW5MZXZlbFN0aWNreShsZXZlbCksXG4gICAgICAgIHJvd1NwYW46IHRoaXMuY29sdW1uTGV2ZWxzIC0gcm93SW5kZXggLSAoc2hvdWxkQWRkVmFsdWVIZWFkZXJzID8gMSA6IDApLFxuICAgICAgICBjb2xTcGFuOiBudW1iZXJPZlN1bXMsXG4gICAgICAgIGJhY2tncm91bmQsXG4gICAgICAgIHN1bW1hcnksXG4gICAgICB9O1xuXG4gICAgICBpZiAobnVtYmVyT2ZWYWx1ZXMgPiAwKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZWYWx1ZXM7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGNvbHVtbkluZGV4SW5DZWxscyA9IGN1cnJlbnRJbmRleCArIGk7XG4gICAgICAgICAgaWYgKHNob3VsZEFkZFZhbHVlSGVhZGVycykge1xuICAgICAgICAgICAgY29uc3QgdmFsdWVUaXRsZSA9IHRoaXMuZGF0YS52YWx1ZVRpdGxlc1tpXTtcbiAgICAgICAgICAgIGNlbGxzW3RoaXMuY29sdW1uTGV2ZWxzIC0gMV1bY29sdW1uSW5kZXhJbkNlbGxzXSA9IHtcbiAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlVGl0bGUsXG4gICAgICAgICAgICAgIGNzc0NsYXNzOiBQaXZvdFRhYmxlQ29udmVydGVyLmNvbHVtbkdyb3VwSGVhZGVyQ2xhc3MsXG4gICAgICAgICAgICAgIGlzU3VtbWFyeTogdHJ1ZSxcbiAgICAgICAgICAgICAgc3RpY2t5VG9wOiB0aGlzLmlzQ29sdW1uTGV2ZWxTdGlja3kobGV2ZWwpLFxuICAgICAgICAgICAgICByb3dTcGFuOiAxLFxuICAgICAgICAgICAgICBjb2xTcGFuOiAxLFxuICAgICAgICAgICAgICBiYWNrZ3JvdW5kLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBjb2x1bW5zSW5kZXhlcyA9IGdldFRhcmdldEluZGV4ZXNGb3JIZWFkZXJzKGhlYWRlcnMpO1xuICAgICAgICAgIGNvbnN0IHZhbHVlQ29sdW1uc0luZGV4ZXMgPSBjb2x1bW5zSW5kZXhlcy5maWx0ZXIoaW5kZXggPT4gaW5kZXggJSBudW1iZXJPZlZhbHVlcyA9PT0gaSk7XG4gICAgICAgICAgY29uc3QgdHJhbnNmb3JtZWRDb2x1bW5JbmRleGVzID0gdmFsdWVDb2x1bW5zSW5kZXhlc1xuICAgICAgICAgICAgLm1hcCh2ID0+IHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXlbdl0pXG4gICAgICAgICAgICAuZmlsdGVyKHYgPT4gaXNOb3ROdWxsT3JVbmRlZmluZWQodikpO1xuICAgICAgICAgIGNvbHVtbkdyb3Vwc0luZm9bY29sdW1uSW5kZXhJbkNlbGxzXSA9IHtiYWNrZ3JvdW5kLCBpbmRleGVzOiB0cmFuc2Zvcm1lZENvbHVtbkluZGV4ZXMsIGxldmVsfTtcblxuICAgICAgICAgIHRoaXMuZmlsbENlbGxzRm9yR3JvdXBlZENvbHVtbihjZWxscywgdmFsdWVDb2x1bW5zSW5kZXhlcywgY29sdW1uSW5kZXhJbkNlbGxzLCBiYWNrZ3JvdW5kKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29sdW1uR3JvdXBzSW5mb1tjdXJyZW50SW5kZXhdID0ge2JhY2tncm91bmQsIGluZGV4ZXM6IFtdLCBsZXZlbH07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmaWxsQ2VsbHNGb3JHcm91cGVkQ29sdW1uKFxuICAgIGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10sXG4gICAgY29sdW1uczogbnVtYmVyW10sXG4gICAgY29sdW1uSW5kZXhJbkNlbGxzOiBudW1iZXIsXG4gICAgYmFja2dyb3VuZDogc3RyaW5nXG4gICkge1xuICAgIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8IHRoaXMucm93c1RyYW5zZm9ybWF0aW9uQXJyYXkubGVuZ3RoOyByb3crKykge1xuICAgICAgY29uc3Qgcm93SW5kZXhJbkNlbGxzID0gdGhpcy5yb3dzVHJhbnNmb3JtYXRpb25BcnJheVtyb3ddO1xuICAgICAgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKHJvd0luZGV4SW5DZWxscykpIHtcbiAgICAgICAgY29uc3Qge3ZhbHVlcywgZGF0YVJlc291cmNlc30gPSB0aGlzLmdldEdyb3VwZWRWYWx1ZXNGb3JSb3dzQW5kQ29scyhbcm93XSwgY29sdW1ucyk7XG4gICAgICAgIGNvbnN0IGZvcm1hdHRlZFZhbHVlID0gdGhpcy5hZ2dyZWdhdGVBbmRGb3JtYXREYXRhVmFsdWVzKHZhbHVlcywgW3Jvd10sIGNvbHVtbnMpO1xuICAgICAgICBjZWxsc1tyb3dJbmRleEluQ2VsbHNdW2NvbHVtbkluZGV4SW5DZWxsc10gPSB7XG4gICAgICAgICAgdmFsdWU6IFN0cmluZyhmb3JtYXR0ZWRWYWx1ZSksXG4gICAgICAgICAgZGF0YVJlc291cmNlcyxcbiAgICAgICAgICBjb2xTcGFuOiAxLFxuICAgICAgICAgIHJvd1NwYW46IDEsXG4gICAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIuZ3JvdXBEYXRhQ2xhc3MsXG4gICAgICAgICAgYmFja2dyb3VuZCxcbiAgICAgICAgICBpc1ZhbHVlOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYWdncmVnYXRlQW5kRm9ybWF0RGF0YVZhbHVlcyh2YWx1ZXM6IGFueVtdLCByb3dzOiBudW1iZXJbXSwgY29sdW1uczogbnVtYmVyW10pOiBhbnkge1xuICAgIGNvbnN0IHt2YWx1ZSwgYWdncmVnYXRpb259ID0gdGhpcy5hZ2dyZWdhdGVEYXRhVmFsdWVzKHZhbHVlcywgY29sdW1ucyk7XG4gICAgcmV0dXJuIGFnZ3JlZ2F0aW9uID09PSBEYXRhQWdncmVnYXRpb25UeXBlLkpvaW4gPyB2YWx1ZSA6IHRoaXMuZm9ybWF0R3JvdXBlZFZhbHVlQnlWYWx1ZVR5cGUodmFsdWUsIHJvd3MsIGNvbHVtbnMpXG4gIH1cblxuICBwcml2YXRlIGFnZ3JlZ2F0ZURhdGFWYWx1ZXModmFsdWVzOiBhbnlbXSwgY29sdW1uczogbnVtYmVyW10pOiB7dmFsdWU6IGFueTsgYWdncmVnYXRpb246IERhdGFBZ2dyZWdhdGlvblR5cGV9IHtcbiAgICBjb25zdCBhZ2dyZWdhdGlvbiA9IHRoaXMuYWdncmVnYXRpb25CeUNvbHVtbnMoY29sdW1ucyk7XG4gICAgaWYgKGFnZ3JlZ2F0aW9uID09PSBEYXRhQWdncmVnYXRpb25UeXBlLkpvaW4pIHtcbiAgICAgIGNvbnN0IHZhbHVlSW5kZXggPSB0aGlzLmdldFZhbHVlSW5kZXhGb3JDb2x1bW5zKGNvbHVtbnMpO1xuICAgICAgY29uc3QgY29uc3RyYWludCA9IHRoaXMuZGF0YS52YWx1ZXNDb25zdHJhaW50cz8uW3ZhbHVlSW5kZXhdIHx8IHRoaXMudmFsdWVUeXBlSW5mb1t2YWx1ZUluZGV4XT8uZGVmYXVsdENvbnN0cmFpbnQ7XG4gICAgICByZXR1cm4ge3ZhbHVlOiBhZ2dyZWdhdGVEYXRhVmFsdWVzKGFnZ3JlZ2F0aW9uLCB2YWx1ZXMsIGNvbnN0cmFpbnQsIGZhbHNlLCB0aGlzLmNvbnN0cmFpbnREYXRhKSwgYWdncmVnYXRpb259O1xuICAgIH1cbiAgICByZXR1cm4ge3ZhbHVlOiBhZ2dyZWdhdGVEYXRhVmFsdWVzKGFnZ3JlZ2F0aW9uLCB2YWx1ZXMpLCBhZ2dyZWdhdGlvbn07XG4gIH1cblxuICBwcml2YXRlIGFnZ3JlZ2F0aW9uQnlDb2x1bW5zKGNvbHVtbnM6IG51bWJlcltdKTogRGF0YUFnZ3JlZ2F0aW9uVHlwZSB7XG4gICAgY29uc3QgdmFsdWVJbmRleCA9IGNvbHVtbnNbMF0gJSB0aGlzLmRhdGEudmFsdWVUaXRsZXMubGVuZ3RoO1xuICAgIGNvbnN0IGFnZ3JlZ2F0aW9uID0gdGhpcy5kYXRhLnZhbHVlQWdncmVnYXRpb25zPy5bdmFsdWVJbmRleF07XG4gICAgcmV0dXJuIGlzVmFsdWVBZ2dyZWdhdGlvbihhZ2dyZWdhdGlvbikgPyBhZ2dyZWdhdGlvbiA6IERhdGFBZ2dyZWdhdGlvblR5cGUuU3VtO1xuICB9XG5cbiAgcHJpdmF0ZSBmaWxsQ2VsbHNGb3JDb2x1bW4oY2VsbHM6IExtclBpdm90VGFibGVDZWxsW11bXSwgY29sdW1uOiBudW1iZXIpIHtcbiAgICBjb25zdCBjb2x1bW5JbmRleEluQ2VsbHMgPSB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5W2NvbHVtbl07XG4gICAgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKGNvbHVtbkluZGV4SW5DZWxscykpIHtcbiAgICAgIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8IHRoaXMucm93c1RyYW5zZm9ybWF0aW9uQXJyYXkubGVuZ3RoOyByb3crKykge1xuICAgICAgICBjb25zdCByb3dJbmRleEluQ2VsbHMgPSB0aGlzLnJvd3NUcmFuc2Zvcm1hdGlvbkFycmF5W3Jvd107XG4gICAgICAgIGlmIChpc05vdE51bGxPclVuZGVmaW5lZChyb3dJbmRleEluQ2VsbHMpKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmRhdGEudmFsdWVzW3Jvd11bY29sdW1uXTtcbiAgICAgICAgICBjb25zdCBkYXRhUmVzb3VyY2VzID0gdGhpcy5kYXRhUmVzb3VyY2VzPy5bcm93XT8uW2NvbHVtbl0gfHwgW107XG4gICAgICAgICAgY29uc3QgZm9ybWF0dGVkVmFsdWUgPSB0aGlzLmFnZ3JlZ2F0ZU9yRm9ybWF0U2luZ2xlVmFsdWUodmFsdWUsIGNvbHVtbik7XG4gICAgICAgICAgY29uc3Qgc3RyaW5nVmFsdWUgPSBpc05vdE51bGxPclVuZGVmaW5lZChmb3JtYXR0ZWRWYWx1ZSkgPyBTdHJpbmcoZm9ybWF0dGVkVmFsdWUpIDogJyc7XG4gICAgICAgICAgY2VsbHNbcm93SW5kZXhJbkNlbGxzXVtjb2x1bW5JbmRleEluQ2VsbHNdID0ge1xuICAgICAgICAgICAgdmFsdWU6IHN0cmluZ1ZhbHVlLFxuICAgICAgICAgICAgZGF0YVJlc291cmNlcyxcbiAgICAgICAgICAgIHJvd1NwYW46IDEsXG4gICAgICAgICAgICBjb2xTcGFuOiAxLFxuICAgICAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIuZGF0YUNsYXNzLFxuICAgICAgICAgICAgaXNWYWx1ZTogdHJ1ZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZ2dyZWdhdGVPckZvcm1hdFNpbmdsZVZhbHVlKHZhbHVlOiBhbnksIGNvbHVtbjogbnVtYmVyKTogYW55IHtcbiAgICBjb25zdCBhZ2dyZWdhdGlvbiA9IHRoaXMuYWdncmVnYXRpb25CeUNvbHVtbnMoW2NvbHVtbl0pO1xuICAgIGNvbnN0IHZhbHVlSW5kZXggPSB0aGlzLmdldFZhbHVlSW5kZXhGb3JDb2x1bW5zKFtjb2x1bW5dKTtcbiAgICBpZiAoYWdncmVnYXRpb24gPT09IERhdGFBZ2dyZWdhdGlvblR5cGUuSm9pbikge1xuICAgICAgY29uc3QgY29uc3RyYWludCA9IHRoaXMuZGF0YS52YWx1ZXNDb25zdHJhaW50cz8uW3ZhbHVlSW5kZXhdIHx8IHRoaXMudmFsdWVUeXBlSW5mb1t2YWx1ZUluZGV4XT8uZGVmYXVsdENvbnN0cmFpbnQ7XG4gICAgICByZXR1cm4gYWdncmVnYXRlRGF0YVZhbHVlcyhhZ2dyZWdhdGlvbiwgW3ZhbHVlXSwgY29uc3RyYWludCwgZmFsc2UsIHRoaXMuY29uc3RyYWludERhdGEpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5mb3JtYXRWYWx1ZUJ5VmFsdWVUeXBlKHZhbHVlLCB2YWx1ZUluZGV4KTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsbENlbGxzQnlHcm91cEludGVyc2VjdGlvbihcbiAgICBjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLFxuICAgIHJvd0dyb3Vwc0luZm86IEhlYWRlckdyb3VwSW5mb1tdLFxuICAgIGNvbHVtbkdyb3Vwc0luZm86IEhlYWRlckdyb3VwSW5mb1tdXG4gICkge1xuICAgIGNvbnN0IHJvd3NDb3VudCA9IGNlbGxzLmxlbmd0aDtcbiAgICBjb25zdCBjb2x1bW5zQ291bnQgPSBjZWxsc1swXT8ubGVuZ3RoIHx8IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvd0dyb3Vwc0luZm8ubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHJvd0dyb3VwSW5mbyA9IHJvd0dyb3Vwc0luZm9baV07XG4gICAgICBpZiAoIXJvd0dyb3VwSW5mbykge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNvbHVtbkdyb3Vwc0luZm8ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKCFjb2x1bW5Hcm91cHNJbmZvW2pdKSB7XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbHVtbnMgPSBjb2x1bW5Hcm91cHNJbmZvW2pdLmluZGV4ZXNcbiAgICAgICAgY29uc3Qge3Jvd3NJbmRleGVzLCBjb2x1bW5zSW5kZXhlc30gPSB0aGlzLmdldFZhbHVlc0luZGV4ZXNGcm9tQ2VsbHNJbmRleGVzKFxuICAgICAgICAgIHJvd0dyb3VwSW5mby5pbmRleGVzLFxuICAgICAgICAgIGNvbHVtbnNcbiAgICAgICAgKTtcbiAgICAgICAgbGV0IGZvcm1hdHRlZFZhbHVlOiBzdHJpbmc7XG4gICAgICAgIGxldCBkYXRhUmVzb3VyY2VzOiBEYXRhUmVzb3VyY2VbXTtcbiAgICAgICAgaWYgKHJvd0dyb3VwSW5mby5leHByZXNzaW9uKSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5ldmFsdWF0ZUV4cHJlc3Npb24ocm93R3JvdXBJbmZvLmV4cHJlc3Npb24sIGNvbHVtbnNJbmRleGVzKTtcbiAgICAgICAgICBjb25zdCB2YWx1ZUluZGV4ID0gY29sdW1uc0luZGV4ZXNbMF0gJSB0aGlzLmRhdGEudmFsdWVUaXRsZXMubGVuZ3RoO1xuICAgICAgICAgIGZvcm1hdHRlZFZhbHVlID0gdGhpcy5mb3JtYXRWYWx1ZUJ5Q29uc3RyYWludChyZXN1bHQudmFsdWUsIHZhbHVlSW5kZXgpO1xuICAgICAgICAgIGRhdGFSZXNvdXJjZXMgPSByZXN1bHQuZGF0YVJlc291cmNlc1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGl0J3MgZW5vdWdoIHRvIGZpbGwgZ3JvdXAgdmFsdWVzIG9ubHkgZnJvbSByb3cgc2lkZVxuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuZ2V0R3JvdXBlZFZhbHVlc0ZvclJvd3NBbmRDb2xzKHJvd3NJbmRleGVzLCBjb2x1bW5zSW5kZXhlcyk7XG4gICAgICAgICAgZm9ybWF0dGVkVmFsdWUgPSB0aGlzLmFnZ3JlZ2F0ZUFuZEZvcm1hdERhdGFWYWx1ZXMocmVzdWx0LnZhbHVlcywgcm93c0luZGV4ZXMsIGNvbHVtbnNJbmRleGVzKTtcbiAgICAgICAgICBkYXRhUmVzb3VyY2VzID0gcmVzdWx0LmRhdGFSZXNvdXJjZXNcbiAgICAgICAgfVxuICAgICAgICBjZWxsc1tpXVtqXSA9IHtcbiAgICAgICAgICB2YWx1ZTogU3RyaW5nKGZvcm1hdHRlZFZhbHVlKSxcbiAgICAgICAgICBkYXRhUmVzb3VyY2VzLFxuICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5ncm91cERhdGFDbGFzcyxcbiAgICAgICAgICBpc1ZhbHVlOiB0cnVlLFxuICAgICAgICB9O1xuXG4gICAgICB9XG5cbiAgICAgIHRoaXMuZmlsbFJvd1dpdGhDb2xvcihjZWxscywgaSwgcm93R3JvdXBJbmZvLCBjb2x1bW5zQ291bnQpO1xuICAgIH1cblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgY29sdW1uR3JvdXBzSW5mby5sZW5ndGg7IGorKykge1xuICAgICAgaWYgKGNvbHVtbkdyb3Vwc0luZm9bal0pIHtcbiAgICAgICAgdGhpcy5maWxsQ29sdW1uV2l0aENvbG9yKGNlbGxzLCBqLCBjb2x1bW5Hcm91cHNJbmZvW2pdLCByb3dHcm91cHNJbmZvLCByb3dzQ291bnQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0VmFsdWVzSW5kZXhlc0Zyb21DZWxsc0luZGV4ZXMoXG4gICAgcm93czogbnVtYmVyW10sXG4gICAgY29sdW1uczogbnVtYmVyW11cbiAgKTogeyByb3dzSW5kZXhlczogbnVtYmVyW107IGNvbHVtbnNJbmRleGVzOiBudW1iZXJbXSB9IHtcbiAgICBjb25zdCByb3dzSW5kZXhlcyA9IHJvd3NcbiAgICAgIC5tYXAocm93ID0+IHRoaXMucm93c1RyYW5zZm9ybWF0aW9uQXJyYXkuZmluZEluZGV4KHRSb3cgPT4gdFJvdyA9PT0gcm93KSlcbiAgICAgIC5maWx0ZXIoaW5kZXggPT4gaW5kZXggPj0gMCk7XG4gICAgY29uc3QgY29sdW1uc0luZGV4ZXMgPSBjb2x1bW5zXG4gICAgICAubWFwKGNvbHVtbiA9PiB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5LmZpbmRJbmRleCh0Q29sdW1uID0+IHRDb2x1bW4gPT09IGNvbHVtbikpXG4gICAgICAuZmlsdGVyKGluZGV4ID0+IGluZGV4ID49IDApO1xuICAgIHJldHVybiB7cm93c0luZGV4ZXMsIGNvbHVtbnNJbmRleGVzfTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsbFJvd1dpdGhDb2xvcihcbiAgICBjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLFxuICAgIHJvdzogbnVtYmVyLFxuICAgIHJvd0dyb3VwSW5mbzogSGVhZGVyR3JvdXBJbmZvLFxuICAgIGNvbHVtbnNDb3VudDogbnVtYmVyXG4gICkge1xuICAgIGZvciAobGV0IGkgPSB0aGlzLnJvd0xldmVsczsgaSA8IGNvbHVtbnNDb3VudDsgaSsrKSB7XG4gICAgICBjZWxsc1tyb3ddW2ldICYmIChjZWxsc1tyb3ddW2ldLmJhY2tncm91bmQgPSByb3dHcm91cEluZm8uYmFja2dyb3VuZCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmaWxsQ29sdW1uV2l0aENvbG9yKFxuICAgIGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10sXG4gICAgY29sdW1uOiBudW1iZXIsXG4gICAgY29sdW1uR3JvdXBJbmZvOiBIZWFkZXJHcm91cEluZm8sXG4gICAgcm93R3JvdXBzSW5mbzogSGVhZGVyR3JvdXBJbmZvW10sXG4gICAgcm93Q291bnQ6IG51bWJlclxuICApIHtcbiAgICBmb3IgKGxldCBpID0gdGhpcy5jb2x1bW5MZXZlbHM7IGkgPCByb3dDb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCByb3dHcm91cEluZm8gPSByb3dHcm91cHNJbmZvW2ldO1xuICAgICAgaWYgKCFyb3dHcm91cEluZm8gfHwgcm93R3JvdXBJbmZvLmxldmVsID4gY29sdW1uR3JvdXBJbmZvLmxldmVsKSB7XG4gICAgICAgIGNlbGxzW2ldW2NvbHVtbl0gJiYgKGNlbGxzW2ldW2NvbHVtbl0uYmFja2dyb3VuZCA9IGNvbHVtbkdyb3VwSW5mby5iYWNrZ3JvdW5kKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGluaXRDZWxscygpOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10ge1xuICAgIGNvbnN0IHJvd3MgPSB0aGlzLmdldFJvd3NDb3VudCgpICsgdGhpcy5jb2x1bW5MZXZlbHM7XG4gICAgY29uc3QgY29sdW1ucyA9IHRoaXMuZ2V0Q29sdW1uc0NvdW50KCkgKyB0aGlzLnJvd0xldmVscztcblxuICAgIGNvbnN0IG1hdHJpeDogTG1yUGl2b3RUYWJsZUNlbGxbXVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzOyBpKyspIHtcbiAgICAgIG1hdHJpeFtpXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjb2x1bW5zOyBqKyspIHtcbiAgICAgICAgaWYgKGkgPj0gdGhpcy5jb2x1bW5MZXZlbHMgJiYgaiA+PSB0aGlzLnJvd0xldmVscykge1xuICAgICAgICAgIGNvbnN0IGlzRGF0YUNsYXNzID0gdGhpcy5yb3dzVHJhbnNmb3JtYXRpb25BcnJheS5pbmNsdWRlcyhpKSAmJiB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5LmluY2x1ZGVzKGopO1xuICAgICAgICAgIG1hdHJpeFtpXVtqXSA9IHtcbiAgICAgICAgICAgIHZhbHVlOiAnJyxcbiAgICAgICAgICAgIGRhdGFSZXNvdXJjZXM6IFtdLFxuICAgICAgICAgICAgY3NzQ2xhc3M6IGlzRGF0YUNsYXNzID8gUGl2b3RUYWJsZUNvbnZlcnRlci5kYXRhQ2xhc3MgOiBQaXZvdFRhYmxlQ29udmVydGVyLmdyb3VwRGF0YUNsYXNzLFxuICAgICAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgICBpc1ZhbHVlOiB0cnVlLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWF0cml4W2ldW2pdID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucm93TGV2ZWxzID4gMCAmJiB0aGlzLmNvbHVtbkxldmVscyA+IDApIHtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5yb3dMZXZlbHM7IGorKykge1xuICAgICAgICBjb25zdCByb3dIZWFkZXJBdHRyaWJ1dGUgPSB0aGlzLmRhdGEucm93SGVhZGVyQXR0cmlidXRlc1tqXTtcbiAgICAgICAgaWYgKHJvd0hlYWRlckF0dHJpYnV0ZSkge1xuICAgICAgICAgIGNvbnN0IHRpdGxlUm93U3BhbiA9IHRoaXMubm9uU3RpY2t5Q29sdW1uSW5kZXggfHwgdGhpcy5jb2x1bW5MZXZlbHNcbiAgICAgICAgICBtYXRyaXhbMF1bal0gPSB7XG4gICAgICAgICAgICB2YWx1ZTogcm93SGVhZGVyQXR0cmlidXRlLnRpdGxlLFxuICAgICAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIucm93QXR0cmlidXRlSGVhZGVyQ2xhc3MsXG4gICAgICAgICAgICBpc0F0dHJpYnV0ZUhlYWRlcjogdHJ1ZSxcbiAgICAgICAgICAgIHJvd1NwYW46IHRpdGxlUm93U3BhbixcbiAgICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgICBzdGlja3lUb3A6IHRoaXMuaXNDb2x1bW5MZXZlbFN0aWNreSgwKSxcbiAgICAgICAgICAgIHN0aWNreVN0YXJ0OiB0aGlzLmlzUm93TGV2ZWxTdGlja3koaiksXG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiByb3dIZWFkZXJBdHRyaWJ1dGUuY29sb3IsXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGlmICh0aGlzLmNvbHVtbkxldmVscyAtIHRpdGxlUm93U3BhbiA+IDApIHtcbiAgICAgICAgICAgIG1hdHJpeFt0aGlzLm5vblN0aWNreUNvbHVtbkluZGV4XVtqXSA9IHtcbiAgICAgICAgICAgICAgdmFsdWU6ICcnLFxuICAgICAgICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5yb3dBdHRyaWJ1dGVIZWFkZXJDbGFzcyxcbiAgICAgICAgICAgICAgaXNBdHRyaWJ1dGVIZWFkZXI6IHRydWUsXG4gICAgICAgICAgICAgIHJvd1NwYW46IHRoaXMuY29sdW1uTGV2ZWxzIC0gdGl0bGVSb3dTcGFuLFxuICAgICAgICAgICAgICBjb2xTcGFuOiAxLFxuICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiByb3dIZWFkZXJBdHRyaWJ1dGUuY29sb3IsXG4gICAgICAgICAgICAgIHN0aWNreVN0YXJ0OiB0aGlzLmlzUm93TGV2ZWxTdGlja3koaiksXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jb2x1bW5MZXZlbHM7IGkrKykge1xuICAgICAgICAgICAgbWF0cml4W2ldW2pdID0ge1xuICAgICAgICAgICAgICB2YWx1ZTogJycsXG4gICAgICAgICAgICAgIGNzc0NsYXNzOiBQaXZvdFRhYmxlQ29udmVydGVyLmVtcHR5Q2xhc3MsXG4gICAgICAgICAgICAgIHJvd1NwYW46IDEsXG4gICAgICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgICAgIHN0aWNreVN0YXJ0OiB0aGlzLmlzUm93TGV2ZWxTdGlja3koaiksXG4gICAgICAgICAgICAgIHN0aWNreVRvcDogdGhpcy5pc0NvbHVtbkxldmVsU3RpY2t5KGkpLFxuICAgICAgICAgICAgICBpc0hlYWRlcjogZmFsc2UsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hdHJpeDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Um93c0NvdW50KCk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuZGF0YS5yb3dIZWFkZXJzLmxlbmd0aCA9PT0gMCAmJiAodGhpcy5kYXRhLnZhbHVlVGl0bGVzIHx8IFtdKS5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gICAgcmV0dXJuIGdldEhlYWRlcnNDaGlsZENvdW50KHRoaXMuZGF0YS5yb3dIZWFkZXJzLCB0aGlzLnJvd1Nob3dTdW1zKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29sdW1uc0NvdW50KCk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuZGF0YS5jb2x1bW5IZWFkZXJzLmxlbmd0aCA9PT0gMCAmJiAodGhpcy5kYXRhLnZhbHVlVGl0bGVzIHx8IFtdKS5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gICAgY29uc3QgbnVtYmVyT2ZTdW1zID0gTWF0aC5tYXgoMSwgKHRoaXMuZGF0YS52YWx1ZVRpdGxlcyB8fCBbXSkubGVuZ3RoKTtcbiAgICByZXR1cm4gZ2V0SGVhZGVyc0NoaWxkQ291bnQodGhpcy5kYXRhLmNvbHVtbkhlYWRlcnMsIHRoaXMuY29sdW1uU2hvd1N1bXMsIG51bWJlck9mU3Vtcyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJlcGFyZVBpdm90RGF0YShcbiAgZGF0YTogTG1yUGl2b3RTdGVtRGF0YSxcbiAgY29uc3RyYWludERhdGE6IENvbnN0cmFpbnREYXRhLFxuICB2YWx1ZVR5cGVJbmZvOiBWYWx1ZVR5cGVJbmZvW11cbik6IExtclBpdm90U3RlbURhdGEge1xuICBjb25zdCBudW1iZXJPZlN1bXMgPSBNYXRoLm1heCgxLCAoZGF0YS52YWx1ZVRpdGxlcyB8fCBbXSkubGVuZ3RoKTtcbiAgY29uc3QgdmFsdWVzID0gY29tcHV0ZVZhbHVlc0J5VmFsdWVUeXBlKGRhdGEudmFsdWVzLCBkYXRhLnZhbHVlVHlwZXMsIG51bWJlck9mU3VtcywgdmFsdWVUeXBlSW5mbyk7XG4gIGNvbnN0IHNvcnRlZCA9IHNvcnRQaXZvdERhdGEoey4uLmRhdGEsIHZhbHVlc30sIGNvbnN0cmFpbnREYXRhKTtcbiAgcmV0dXJuIGZpbGxFeHByZXNzaW9uc1RvRGF0YShzb3J0ZWQpXG59XG5cbmZ1bmN0aW9uIGZpbGxFeHByZXNzaW9uc1RvRGF0YShkYXRhOiBMbXJQaXZvdFN0ZW1EYXRhKTogTG1yUGl2b3RTdGVtRGF0YSB7XG4gIHJldHVybiB7XG4gICAgLi4uZGF0YSxcbiAgICByb3dIZWFkZXJzOiBmaWxsRXhwcmVzc2lvbnNUb0hlYWRlcnMoZGF0YS5yb3dIZWFkZXJzLCBkYXRhLnJvd3NDb25maWcsIDApLFxuICAgIGNvbHVtbkhlYWRlcnM6IGZpbGxFeHByZXNzaW9uc1RvSGVhZGVycyhkYXRhLmNvbHVtbkhlYWRlcnMsIGRhdGEuY29sdW1uc0NvbmZpZywgMCksXG4gIH1cbn1cblxuZnVuY3Rpb24gZmlsbEV4cHJlc3Npb25zVG9IZWFkZXJzKGhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLCBjb25maWdzOiBMbXJQaXZvdERpbWVuc2lvbkNvbmZpZ1tdLCBpbmRleDogbnVtYmVyKTogTG1yUGl2b3REYXRhSGVhZGVyW10ge1xuICBjb25zdCBleHByZXNzaW9ucyA9IGNvbmZpZ3M/LltpbmRleF0/LmV4cHJlc3Npb25zIHx8IFtdXG4gIGNvbnN0IGhlYWRlcnNDb3B5ID0gWy4uLihoZWFkZXJzIHx8IFtdKV1cbiAgZm9yIChjb25zdCBleHByZXNzaW9uIG9mIGV4cHJlc3Npb25zKSB7XG4gICAgY29uc3QgZGF0YUhlYWRlckV4cHJlc3Npb24gPSBleHRlbmRQaXZvdEV4cHJlc3Npb24oZXhwcmVzc2lvbiwgaGVhZGVycylcbiAgICBpZiAoZGF0YUhlYWRlckV4cHJlc3Npb24uZmlyc3RIZWFkZXJJbmRleCA+PSAwKSB7XG4gICAgICBjb25zdCBmaXJzdEhlYWRlckluZGV4ID0gZGF0YUhlYWRlckV4cHJlc3Npb24uZmlyc3RIZWFkZXJJbmRleFxuICAgICAgY29uc3QgbmV3SGVhZGVyOiBMbXJQaXZvdERhdGFIZWFkZXIgPSB7Li4uaGVhZGVyc0NvcHlbZmlyc3RIZWFkZXJJbmRleF0sIGV4cHJlc3Npb25zOiBbLi4uKGhlYWRlcnNDb3B5W2ZpcnN0SGVhZGVySW5kZXhdLmV4cHJlc3Npb25zIHx8IFtdKSwgZGF0YUhlYWRlckV4cHJlc3Npb25dfVxuICAgICAgaGVhZGVyc0NvcHkuc3BsaWNlKGZpcnN0SGVhZGVySW5kZXgsIDEsIG5ld0hlYWRlcilcbiAgICB9XG4gIH1cblxuICBpZiAoY29uZmlncz8uW2luZGV4ICsgMV0pIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhlYWRlcnNDb3B5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBoZWFkZXJzQ29weS5zcGxpY2UoaSwgMSwgey4uLmhlYWRlcnNDb3B5W2ldLCBjaGlsZHJlbjogZmlsbEV4cHJlc3Npb25zVG9IZWFkZXJzKGhlYWRlcnNDb3B5W2ldLmNoaWxkcmVuLCBjb25maWdzLCBpbmRleCArIDEpfSlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaGVhZGVyc0NvcHlcbn1cblxuZnVuY3Rpb24gZXh0ZW5kUGl2b3RFeHByZXNzaW9uKGV4cHJlc3Npb246IExtclBpdm90RXhwcmVzc2lvbiwgaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10pOiBMbXJQaXZvdERhdGFIZWFkZXJFeHByZXNzaW9uIHtcbiAgY29uc3QgZGF0YUhlYWRlck9wZXJhbmRzOiBMbXJQaXZvdERhdGFIZWFkZXJPcGVyYW5kW10gPSBbXTtcbiAgbGV0IGZpcnN0SGVhZGVySW5kZXg6IG51bWJlciA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSXG5cbiAgZnVuY3Rpb24gdHJhdmVyc2Uob3BlcmFuZHM6IExtclBpdm90T3BlcmFuZFtdKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBvcGVyYW5kIG9mIG9wZXJhbmRzKSB7XG4gICAgICBpZiAob3BlcmFuZC50eXBlID09PSAnaGVhZGVyJykge1xuICAgICAgICBjb25zdCBpbmRleGVzID0gZ2V0T3BlcmFuZEluZGV4ZXNJbkhlYWRlcnMob3BlcmFuZCwgaGVhZGVycylcbiAgICAgICAgZmlyc3RIZWFkZXJJbmRleCA9IE1hdGgubWluKGZpcnN0SGVhZGVySW5kZXgsIC4uLmluZGV4ZXMpXG4gICAgICAgIGNvbnN0IG9wZXJhbmRIZWFkZXJzID0gaW5kZXhlcy5tYXAoaW5kZXggPT4gaGVhZGVyc1tpbmRleF0pXG4gICAgICAgIGRhdGFIZWFkZXJPcGVyYW5kcy5wdXNoKHsuLi5vcGVyYW5kLCBoZWFkZXJzOiBvcGVyYW5kSGVhZGVyc30pO1xuICAgICAgfSBlbHNlIGlmIChvcGVyYW5kLnR5cGUgPT09ICdleHByZXNzaW9uJykge1xuICAgICAgICB0cmF2ZXJzZShvcGVyYW5kLm9wZXJhbmRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRhdGFIZWFkZXJPcGVyYW5kcy5wdXNoKG9wZXJhbmQpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdHJhdmVyc2UoZXhwcmVzc2lvbi5vcGVyYW5kcyk7XG5cbiAgaWYgKGV4cHJlc3Npb24ucG9zaXRpb24gPT09IExtclBpdm90UG9zaXRpb24uU3RpY2tUb0VuZCkge1xuICAgIGZpcnN0SGVhZGVySW5kZXggPSBoZWFkZXJzLmxlbmd0aCAtIDFcbiAgfVxuXG4gIGlmIChmaXJzdEhlYWRlckluZGV4ID09PSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUikge1xuICAgIGZpcnN0SGVhZGVySW5kZXggPSAtMVxuICB9XG5cbiAgcmV0dXJuIHsuLi5leHByZXNzaW9uLCBmaXJzdEhlYWRlckluZGV4LCBvcGVyYW5kczogZGF0YUhlYWRlck9wZXJhbmRzfTtcbn1cblxuZnVuY3Rpb24gZ2V0T3BlcmFuZEluZGV4ZXNJbkhlYWRlcnMob3BlcmFuZDogTG1yUGl2b3RIZWFkZXJPcGVyYW5kLCBoZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSk6IG51bWJlcltdIHtcbiAgcmV0dXJuIChoZWFkZXJzIHx8IFtdKS5yZWR1Y2U8bnVtYmVyW10+KChpbmRleGVzLCBoZWFkZXIsIGluZGV4KSA9PiB7XG4gICAgaWYgKG9wZXJhbmRDb250YWluc0hlYWRlcihvcGVyYW5kLCBoZWFkZXIpKSB7XG4gICAgICBpbmRleGVzLnB1c2goaW5kZXgpXG4gICAgfVxuICAgIHJldHVybiBpbmRleGVzXG4gIH0sIFtdKVxufVxuXG5mdW5jdGlvbiBvcGVyYW5kQ29udGFpbnNIZWFkZXIob3BlcmFuZDogTG1yUGl2b3RIZWFkZXJPcGVyYW5kLCBoZWFkZXI6IExtclBpdm90RGF0YUhlYWRlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gaGVhZGVyLnRpdGxlLm1hdGNoKG5ldyBSZWdFeHAob3BlcmFuZC52YWx1ZSkpPy5sZW5ndGggPiAwXG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVWYWx1ZXNCeVZhbHVlVHlwZShcbiAgdmFsdWVzOiBhbnlbXVtdLFxuICB2YWx1ZVR5cGVzOiBMbXJQaXZvdFZhbHVlVHlwZVtdLFxuICBudW1WYWx1ZXM6IG51bWJlcixcbiAgdmFsdWVUeXBlSW5mbzogVmFsdWVUeXBlSW5mb1tdXG4pOiBhbnlbXVtdIHtcbiAgY29uc3Qgcm93c0luZGV4ZXMgPSBbLi4uQXJyYXkodmFsdWVzLmxlbmd0aCkua2V5cygpXTtcbiAgY29uc3QgbW9kaWZpZWRWYWx1ZXMgPSBkZWVwT2JqZWN0Q29weSh2YWx1ZXMpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtVmFsdWVzOyBpKyspIHtcbiAgICBjb25zdCB2YWx1ZVR5cGUgPSB2YWx1ZVR5cGVzICYmIHZhbHVlVHlwZXNbaV07XG4gICAgaWYgKCF2YWx1ZVR5cGUgfHwgdmFsdWVUeXBlID09PSBMbXJQaXZvdFZhbHVlVHlwZS5EZWZhdWx0KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBjb2x1bW5zQ291bnQgPSAodmFsdWVzWzBdICYmIHZhbHVlc1swXS5sZW5ndGgpIHx8IDA7XG4gICAgY29uc3QgY29sdW1uSW5kZXhlcyA9IFsuLi5BcnJheShjb2x1bW5zQ291bnQpLmtleXMoKV0uZmlsdGVyKGtleSA9PiBrZXkgJSBudW1WYWx1ZXMgPT09IGkpO1xuICAgIGNvbnN0IGluZm8gPSB2YWx1ZVR5cGVJbmZvW2ldO1xuXG4gICAgZm9yIChjb25zdCByb3cgb2Ygcm93c0luZGV4ZXMpIHtcbiAgICAgIGZvciAoY29uc3QgY29sdW1uIG9mIGNvbHVtbkluZGV4ZXMpIHtcbiAgICAgICAgaWYgKHZhbHVlVHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuQWxsUGVyY2VudGFnZSkge1xuICAgICAgICAgIG1vZGlmaWVkVmFsdWVzW3Jvd11bY29sdW1uXSA9IGRpdmlkZVZhbHVlcyh2YWx1ZXNbcm93XVtjb2x1bW5dLCBpbmZvLnN1bSk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWVUeXBlID09PSBMbXJQaXZvdFZhbHVlVHlwZS5Sb3dQZXJjZW50YWdlKSB7XG4gICAgICAgICAgbW9kaWZpZWRWYWx1ZXNbcm93XVtjb2x1bW5dID0gZGl2aWRlVmFsdWVzKHZhbHVlc1tyb3ddW2NvbHVtbl0sIGluZm8uc3Vtc1Jvd3Nbcm93XSk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWVUeXBlID09PSBMbXJQaXZvdFZhbHVlVHlwZS5Db2x1bW5QZXJjZW50YWdlKSB7XG4gICAgICAgICAgbW9kaWZpZWRWYWx1ZXNbcm93XVtjb2x1bW5dID0gZGl2aWRlVmFsdWVzKHZhbHVlc1tyb3ddW2NvbHVtbl0sIGluZm8uc3Vtc0NvbHVtbnNbY29sdW1uXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbW9kaWZpZWRWYWx1ZXM7XG59XG5cbmZ1bmN0aW9uIGdldFZhbHVlc1R5cGVJbmZvKHZhbHVlczogYW55W11bXSwgdmFsdWVUeXBlczogTG1yUGl2b3RWYWx1ZVR5cGVbXSwgbnVtVmFsdWVzOiBudW1iZXIpOiBWYWx1ZVR5cGVJbmZvW10ge1xuICBjb25zdCB2YWx1ZVR5cGVJbmZvID0gW107XG4gIGNvbnN0IHJvd3NJbmRleGVzID0gWy4uLkFycmF5KHZhbHVlcy5sZW5ndGgpLmtleXMoKV07XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1WYWx1ZXM7IGkrKykge1xuICAgIGNvbnN0IHZhbHVlVHlwZSA9IHZhbHVlVHlwZXMgJiYgdmFsdWVUeXBlc1tpXTtcbiAgICBjb25zdCBjb2x1bW5zQ291bnQgPSAodmFsdWVzWzBdICYmIHZhbHVlc1swXS5sZW5ndGgpIHx8IDA7XG4gICAgY29uc3QgY29sdW1uSW5kZXhlcyA9IFsuLi5BcnJheShjb2x1bW5zQ291bnQpLmtleXMoKV0uZmlsdGVyKGtleSA9PiBrZXkgJSBudW1WYWx1ZXMgPT09IGkpO1xuXG4gICAgdmFsdWVUeXBlSW5mb1tpXSA9IGdldFZhbHVlVHlwZUluZm8odmFsdWVzLCB2YWx1ZVR5cGUsIHJvd3NJbmRleGVzLCBjb2x1bW5JbmRleGVzKTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZVR5cGVJbmZvO1xufVxuXG5mdW5jdGlvbiBnZXRWYWx1ZVR5cGVJbmZvKHZhbHVlczogYW55W11bXSwgdHlwZTogTG1yUGl2b3RWYWx1ZVR5cGUsIHJvd3M6IG51bWJlcltdLCBjb2x1bW5zOiBudW1iZXJbXSk6IFZhbHVlVHlwZUluZm8ge1xuICBjb25zdCBjb250YWluc0RlY2ltYWwgPSBjb250YWluc0RlY2ltYWxWYWx1ZSh2YWx1ZXMsIHJvd3MsIGNvbHVtbnMpO1xuICBjb25zdCB2YWx1ZVR5cGVJbmZvOiBWYWx1ZVR5cGVJbmZvID0ge1xuICAgIGRlZmF1bHRDb25zdHJhaW50OiBjb250YWluc0RlY2ltYWwgPyBuZXcgTnVtYmVyQ29uc3RyYWludCh7ZGVjaW1hbHM6IDJ9KSA6IG51bGwsXG4gIH07XG5cbiAgaWYgKHR5cGUgPT09IExtclBpdm90VmFsdWVUeXBlLkFsbFBlcmNlbnRhZ2UpIHtcbiAgICByZXR1cm4gey4uLnZhbHVlVHlwZUluZm8sIHN1bTogZ2V0TnVtZXJpY1ZhbHVlc1N1bW1hcnkodmFsdWVzLCByb3dzLCBjb2x1bW5zKX07XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuUm93UGVyY2VudGFnZSkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi52YWx1ZVR5cGVJbmZvLFxuICAgICAgc3Vtc1Jvd3M6IHJvd3MucmVkdWNlKChhcnIsIHJvdykgPT4ge1xuICAgICAgICBhcnJbcm93XSA9IGdldE51bWVyaWNWYWx1ZXNTdW1tYXJ5KHZhbHVlcywgW3Jvd10sIGNvbHVtbnMpO1xuICAgICAgICByZXR1cm4gYXJyO1xuICAgICAgfSwgW10pLFxuICAgIH07XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuQ29sdW1uUGVyY2VudGFnZSkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi52YWx1ZVR5cGVJbmZvLFxuICAgICAgc3Vtc0NvbHVtbnM6IGNvbHVtbnMucmVkdWNlKChhcnIsIGNvbHVtbikgPT4ge1xuICAgICAgICBhcnJbY29sdW1uXSA9IGdldE51bWVyaWNWYWx1ZXNTdW1tYXJ5KHZhbHVlcywgcm93cywgW2NvbHVtbl0pO1xuICAgICAgICByZXR1cm4gYXJyO1xuICAgICAgfSwgW10pLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gey4uLnZhbHVlVHlwZUluZm99O1xufVxuXG5mdW5jdGlvbiBjb250YWluc0RlY2ltYWxWYWx1ZSh2YWx1ZXM6IGFueVtdW10sIHJvd3M6IG51bWJlcltdLCBjb2x1bW5zOiBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgZm9yIChjb25zdCBjb2x1bW4gb2YgY29sdW1ucykge1xuICAgICAgaWYgKGlzVmFsdWVEZWNpbWFsKHZhbHVlc1tyb3ddW2NvbHVtbl0pKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzVmFsdWVEZWNpbWFsKHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKGlzTnVsbE9yVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChpc051bWVyaWModmFsdWUpKSB7XG4gICAgcmV0dXJuIHRvTnVtYmVyKHZhbHVlKSAlIDEgIT09IDA7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVUcmFuc2Zvcm1hdGlvbk1hcChcbiAgaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gIHNob3dTdW1zOiBib29sZWFuW10sXG4gIGFkZGl0aW9uYWxOdW06IG51bWJlcixcbiAgbnVtYmVyT2ZTdW1zOiBudW1iZXJcbik6IG51bWJlcltdIHtcbiAgY29uc3QgYXJyYXkgPSBbXTtcbiAgaXRlcmF0ZVRocm91Z2hUcmFuc2Zvcm1hdGlvbk1hcChoZWFkZXJzLCBhZGRpdGlvbmFsTnVtLCBhcnJheSwgMCwgc2hvd1N1bXMsIG51bWJlck9mU3Vtcyk7XG4gIHJldHVybiBhcnJheTtcbn1cblxuZnVuY3Rpb24gaXRlcmF0ZVRocm91Z2hUcmFuc2Zvcm1hdGlvbk1hcChcbiAgaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gIGFkZGl0aW9uYWxOdW06IG51bWJlcixcbiAgYXJyYXk6IG51bWJlcltdLFxuICBsZXZlbDogbnVtYmVyLFxuICBzaG93U3VtczogYm9vbGVhbltdLFxuICBudW1iZXJPZlN1bXM6IG51bWJlclxuKSB7XG4gIGxldCBhZGRpdGlvbmFsID0gYWRkaXRpb25hbE51bTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBoZWFkZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgaGVhZGVyID0gaGVhZGVyc1tpXTtcbiAgICBjb25zdCBiZWZvcmVFeHByZXNzaW9uc0xlbmd0aCA9IChoZWFkZXIuZXhwcmVzc2lvbnMgfHwgW10pLmZpbHRlcihleHAgPT4gZXhwLnBvc2l0aW9uID09PSBMbXJQaXZvdFBvc2l0aW9uLkJlZm9yZUhlYWRlcikubGVuZ3RoXG4gICAgY29uc3QgYWZ0ZXJFeHByZXNzaW9uc0xlbmd0aCA9IChoZWFkZXIuZXhwcmVzc2lvbnMgfHwgW10pLmZpbHRlcihleHAgPT4gZXhwLnBvc2l0aW9uID09PSBMbXJQaXZvdFBvc2l0aW9uLlN0aWNrVG9FbmQpLmxlbmd0aFxuICAgIGlmIChoZWFkZXIuY2hpbGRyZW4pIHtcbiAgICAgIGFkZGl0aW9uYWwgKz0gYmVmb3JlRXhwcmVzc2lvbnNMZW5ndGhcbiAgICAgIGl0ZXJhdGVUaHJvdWdoVHJhbnNmb3JtYXRpb25NYXAoaGVhZGVyLmNoaWxkcmVuLCBhZGRpdGlvbmFsLCBhcnJheSwgbGV2ZWwgKyAxLCBzaG93U3VtcywgbnVtYmVyT2ZTdW1zKTtcbiAgICAgIGFkZGl0aW9uYWwgKz0gKGdldEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCBsZXZlbCwgc2hvd1N1bXMsIG51bWJlck9mU3VtcykgLSBiZWZvcmVFeHByZXNzaW9uc0xlbmd0aCk7XG4gICAgfSBlbHNlIGlmIChpc05vdE51bGxPclVuZGVmaW5lZChoZWFkZXIudGFyZ2V0SW5kZXgpKSB7XG4gICAgICBhcnJheVtoZWFkZXIudGFyZ2V0SW5kZXhdID0gaSArIGFkZGl0aW9uYWwgKyBiZWZvcmVFeHByZXNzaW9uc0xlbmd0aDtcbiAgICAgIGFkZGl0aW9uYWwgKz0gYmVmb3JlRXhwcmVzc2lvbnNMZW5ndGggKyBhZnRlckV4cHJlc3Npb25zTGVuZ3RoO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVycyhoZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSk6IG51bWJlcltdIHtcbiAgY29uc3QgYWxsUm93cyA9IChoZWFkZXJzIHx8IFtdKS5yZWR1Y2UoKHJvd3MsIGhlYWRlcikgPT4ge1xuICAgIHJvd3MucHVzaCguLi5nZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVyKGhlYWRlcikpO1xuICAgIHJldHVybiByb3dzO1xuICB9LCBbXSk7XG4gIHJldHVybiB1bmlxdWVWYWx1ZXM8bnVtYmVyPihhbGxSb3dzKTtcbn1cblxuZnVuY3Rpb24gZ2V0VGFyZ2V0SW5kZXhlc0ZvckhlYWRlcihwaXZvdERhdGFIZWFkZXI6IExtclBpdm90RGF0YUhlYWRlcik6IG51bWJlcltdIHtcbiAgaWYgKHBpdm90RGF0YUhlYWRlci5jaGlsZHJlbikge1xuICAgIHJldHVybiBwaXZvdERhdGFIZWFkZXIuY2hpbGRyZW4ucmVkdWNlKChyb3dzLCBoZWFkZXIpID0+IHtcbiAgICAgIHJvd3MucHVzaCguLi5nZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVyKGhlYWRlcikpO1xuICAgICAgcmV0dXJuIHJvd3M7XG4gICAgfSwgW10pO1xuICB9XG4gIHJldHVybiBbcGl2b3REYXRhSGVhZGVyLnRhcmdldEluZGV4XTtcbn1cblxuZnVuY3Rpb24gZ2V0SGVhZGVyc0NoaWxkQ291bnQoaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sIHNob3dTdW1zOiBib29sZWFuW10sIG51bWJlck9mU3VtcyA9IDEpOiBudW1iZXIge1xuICByZXR1cm4gKGhlYWRlcnMgfHwgW10pLnJlZHVjZShcbiAgICAoc3VtLCBoZWFkZXIpID0+IHN1bSArIGdldEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCAwLCBzaG93U3VtcywgbnVtYmVyT2ZTdW1zKSxcbiAgICBzaG93U3Vtc1swXSA/IG51bWJlck9mU3VtcyA6IDBcbiAgKTtcbn1cblxuZnVuY3Rpb24gZ2V0SGVhZGVyQ2hpbGRDb3VudChcbiAgcGl2b3REYXRhSGVhZGVyOiBMbXJQaXZvdERhdGFIZWFkZXIsXG4gIGxldmVsOiBudW1iZXIsXG4gIHNob3dTdW1zOiBib29sZWFuW10sXG4gIG51bWJlck9mU3VtcyA9IDEsXG4pOiBudW1iZXIge1xuICBjb25zdCBudW1FeHByZXNzaW9ucyA9IChwaXZvdERhdGFIZWFkZXIuZXhwcmVzc2lvbnMgfHwgW10pLmxlbmd0aFxuICBpZiAocGl2b3REYXRhSGVhZGVyLmNoaWxkcmVuKSB7XG4gICAgcmV0dXJuIHBpdm90RGF0YUhlYWRlci5jaGlsZHJlbi5yZWR1Y2UoXG4gICAgICAoc3VtLCBoZWFkZXIpID0+IHN1bSArIGdldEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCBsZXZlbCArIDEsIHNob3dTdW1zLCBudW1iZXJPZlN1bXMpLFxuICAgICAgKHNob3dTdW1zW2xldmVsICsgMV0gPyBudW1iZXJPZlN1bXMgOiAwKSArIG51bUV4cHJlc3Npb25zXG4gICAgKTtcbiAgfVxuICByZXR1cm4gMSArIG51bUV4cHJlc3Npb25zO1xufVxuXG5mdW5jdGlvbiBnZXREaXJlY3RIZWFkZXJDaGlsZENvdW50KFxuICBwaXZvdERhdGFIZWFkZXI6IExtclBpdm90RGF0YUhlYWRlcixcbiAgbGV2ZWw6IG51bWJlcixcbiAgc2hvd1N1bXM6IGJvb2xlYW5bXSxcbiAgbnVtYmVyT2ZTdW1zID0gMVxuKTogbnVtYmVyIHtcbiAgaWYgKHBpdm90RGF0YUhlYWRlci5jaGlsZHJlbikge1xuICAgIHJldHVybiBwaXZvdERhdGFIZWFkZXIuY2hpbGRyZW4ucmVkdWNlKFxuICAgICAgKHN1bSwgaGVhZGVyKSA9PiBzdW0gKyBnZXRIZWFkZXJDaGlsZENvdW50KGhlYWRlciwgbGV2ZWwgKyAxLCBzaG93U3VtcywgbnVtYmVyT2ZTdW1zKSxcbiAgICAgIDBcbiAgICApO1xuICB9XG4gIHJldHVybiAxO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc29ydFBpdm90RGF0YShkYXRhOiBMbXJQaXZvdFN0ZW1EYXRhLCBjb25zdHJhaW50RGF0YTogQ29uc3RyYWludERhdGEpOiBMbXJQaXZvdFN0ZW1EYXRhIHtcbiAgY29uc3Qgcm93U29ydHMgPSAoZGF0YS5yb3dzQ29uZmlnIHx8IFtdKS5tYXAoY29uZmlnID0+IGNvbmZpZy5zb3J0KVxuICBjb25zdCBjb2x1bW5Tb3J0cyA9IChkYXRhLmNvbHVtbnNDb25maWcgfHwgW10pLm1hcChjb25maWcgPT4gY29uZmlnLnNvcnQpXG4gIHJldHVybiB7XG4gICAgLi4uZGF0YSxcbiAgICByb3dIZWFkZXJzOiBzb3J0UGl2b3RSb3dEYXRhSGVhZGVycyhkYXRhLnJvd0hlYWRlcnMsIHJvd1NvcnRzLCBkYXRhLCBjb25zdHJhaW50RGF0YSksXG4gICAgY29sdW1uSGVhZGVyczogc29ydFBpdm90Q29sdW1uRGF0YUhlYWRlcnMoZGF0YS5jb2x1bW5IZWFkZXJzLCBjb2x1bW5Tb3J0cywgZGF0YSwgY29uc3RyYWludERhdGEpLFxuICB9O1xufVxuXG5mdW5jdGlvbiBzb3J0UGl2b3RSb3dEYXRhSGVhZGVycyhcbiAgcm93SGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gIHJvd1NvcnRzOiBMbXJQaXZvdFNvcnRbXSxcbiAgcGl2b3REYXRhOiBMbXJQaXZvdFN0ZW1EYXRhLFxuICBjb25zdHJhaW50RGF0YTogQ29uc3RyYWludERhdGFcbik6IExtclBpdm90RGF0YUhlYWRlcltdIHtcbiAgcmV0dXJuIHNvcnRQaXZvdERhdGFIZWFkZXJzUmVjdXJzaXZlKFxuICAgIHJvd0hlYWRlcnMsXG4gICAgMCxcbiAgICByb3dTb3J0cyxcbiAgICBwaXZvdERhdGEuY29sdW1uSGVhZGVycyxcbiAgICBwaXZvdERhdGEudmFsdWVzLFxuICAgIHBpdm90RGF0YS52YWx1ZVRpdGxlcyB8fCBbXSxcbiAgICB0cnVlLFxuICAgIGNvbnN0cmFpbnREYXRhXG4gICk7XG59XG5cbmZ1bmN0aW9uIHNvcnRQaXZvdENvbHVtbkRhdGFIZWFkZXJzKFxuICBjb2x1bW5IZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSxcbiAgY29sdW1uU29ydHM6IExtclBpdm90U29ydFtdLFxuICBwaXZvdERhdGE6IExtclBpdm90U3RlbURhdGEsXG4gIGNvbnN0cmFpbnREYXRhOiBDb25zdHJhaW50RGF0YVxuKTogTG1yUGl2b3REYXRhSGVhZGVyW10ge1xuICByZXR1cm4gc29ydFBpdm90RGF0YUhlYWRlcnNSZWN1cnNpdmUoXG4gICAgY29sdW1uSGVhZGVycyxcbiAgICAwLFxuICAgIGNvbHVtblNvcnRzLFxuICAgIHBpdm90RGF0YS5yb3dIZWFkZXJzLFxuICAgIHBpdm90RGF0YS52YWx1ZXMsXG4gICAgcGl2b3REYXRhLnZhbHVlVGl0bGVzIHx8IFtdLFxuICAgIGZhbHNlLFxuICAgIGNvbnN0cmFpbnREYXRhXG4gICk7XG59XG5cbmZ1bmN0aW9uIHNvcnRQaXZvdERhdGFIZWFkZXJzUmVjdXJzaXZlKFxuICBoZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSxcbiAgaW5kZXg6IG51bWJlcixcbiAgc29ydHM6IExtclBpdm90U29ydFtdLFxuICBvdGhlclNpZGVIZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSxcbiAgdmFsdWVzOiBhbnlbXVtdLFxuICB2YWx1ZVRpdGxlczogc3RyaW5nW10sXG4gIGlzUm93czogYm9vbGVhbixcbiAgY29uc3RyYWludERhdGE6IENvbnN0cmFpbnREYXRhXG4pOiBMbXJQaXZvdERhdGFIZWFkZXJbXSB7XG4gIC8vIHdlIGRvbid0IHdhbnQgdG8gc29ydCB2YWx1ZXMgaGVhZGVyc1xuICBpZiAoIWlzUm93cyAmJiBpc1ZhbHVlc0hlYWRlcnMoaGVhZGVycywgdmFsdWVUaXRsZXMpKSB7XG4gICAgcmV0dXJuIGhlYWRlcnM7XG4gIH1cbiAgY29uc3Qgc29ydCA9IHNvcnRzICYmIHNvcnRzW2luZGV4XTtcbiAgY29uc3QgY29uc3RyYWludCA9IGdldENvbnN0cmFpbnRGb3JTb3J0KHNvcnQsIGhlYWRlcnMpO1xuICBjb25zdCB2YWx1ZXNNYXAgPSBjcmVhdGVIZWFkZXJzVmFsdWVzTWFwKGhlYWRlcnMsIHNvcnQsIG90aGVyU2lkZUhlYWRlcnMsIHZhbHVlcywgdmFsdWVUaXRsZXMsIGlzUm93cyk7XG4gIHJldHVybiBoZWFkZXJzXG4gICAgLm1hcChoZWFkZXIgPT4gKHtcbiAgICAgIC4uLmhlYWRlcixcbiAgICAgIGNoaWxkcmVuOlxuICAgICAgICBoZWFkZXIuY2hpbGRyZW4gJiZcbiAgICAgICAgc29ydFBpdm90RGF0YUhlYWRlcnNSZWN1cnNpdmUoXG4gICAgICAgICAgaGVhZGVyLmNoaWxkcmVuLFxuICAgICAgICAgIGluZGV4ICsgMSxcbiAgICAgICAgICBzb3J0cyxcbiAgICAgICAgICBvdGhlclNpZGVIZWFkZXJzLFxuICAgICAgICAgIHZhbHVlcyxcbiAgICAgICAgICB2YWx1ZVRpdGxlcyxcbiAgICAgICAgICBpc1Jvd3MsXG4gICAgICAgICAgY29uc3RyYWludERhdGFcbiAgICAgICAgKSxcbiAgICB9KSlcbiAgICAuc29ydCgocjEsIHIyKSA9PiB7XG4gICAgICBjb25zdCByMVZhbHVlID0gY29uc3RyYWludC5jcmVhdGVEYXRhVmFsdWUodmFsdWVzTWFwW3IxLnRpdGxlXSwgY29uc3RyYWludERhdGEpO1xuICAgICAgY29uc3QgcjJWYWx1ZSA9IGNvbnN0cmFpbnQuY3JlYXRlRGF0YVZhbHVlKHZhbHVlc01hcFtyMi50aXRsZV0sIGNvbnN0cmFpbnREYXRhKTtcbiAgICAgIGNvbnN0IG11bHRpcGxpZXIgPSAhc29ydCB8fCBzb3J0LmFzYyA/IDEgOiAtMTtcbiAgICAgIHJldHVybiByMVZhbHVlLmNvbXBhcmVUbyhyMlZhbHVlKSAqIG11bHRpcGxpZXI7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldENvbnN0cmFpbnRGb3JTb3J0KHNvcnQ6IExtclBpdm90U29ydCwgaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10pOiBDb25zdHJhaW50IHtcbiAgaWYgKChzb3J0Py5saXN0Py52YWx1ZXMgfHwgW10pLmxlbmd0aCA+IDApIHtcbiAgICAvLyBzb3J0IGlzIGRvbmUgYnkgdmFsdWVzIGluIGNvbHVtbnNcbiAgICByZXR1cm4gbmV3IE51bWJlckNvbnN0cmFpbnQoe30pO1xuICB9XG4gIHJldHVybiAoKGhlYWRlcnMgfHwgW10pWzBdICYmIChoZWFkZXJzIHx8IFtdKVswXS5jb25zdHJhaW50KSB8fCBuZXcgVW5rbm93bkNvbnN0cmFpbnQoKTtcbn1cblxuZnVuY3Rpb24gaXNWYWx1ZXNIZWFkZXJzKGhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLCB2YWx1ZVRpdGxlczogc3RyaW5nW10pOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICB2YWx1ZVRpdGxlcy5sZW5ndGggPiAxICYmXG4gICAgKGhlYWRlcnMgfHwgW10pLmV2ZXJ5KFxuICAgICAgKGhlYWRlciwgaW5kZXgpID0+IGlzTm90TnVsbE9yVW5kZWZpbmVkKGhlYWRlci50YXJnZXRJbmRleCkgJiYgaGVhZGVyLnRpdGxlID09PSB2YWx1ZVRpdGxlc1tpbmRleF1cbiAgICApXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUhlYWRlcnNWYWx1ZXNNYXAoXG4gIGhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLFxuICBzb3J0OiBMbXJQaXZvdFNvcnQsXG4gIG90aGVyU2lkZUhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLFxuICB2YWx1ZXM6IGFueVtdW10sXG4gIHZhbHVlVGl0bGVzOiBzdHJpbmdbXSxcbiAgaXNSb3dzOiBib29sZWFuXG4pOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgY29uc3Qgc29ydFRhcmdldEluZGV4ZXMgPSBzb3J0VmFsdWVUYXJnZXRJbmRleGVzKHNvcnQsIG90aGVyU2lkZUhlYWRlcnMsIHZhbHVlVGl0bGVzKTtcbiAgaWYgKCFzb3J0VGFyZ2V0SW5kZXhlcykge1xuICAgIHJldHVybiAoaGVhZGVycyB8fCBbXSkucmVkdWNlKCh2YWx1ZXNNYXAsIGhlYWRlcikgPT4ge1xuICAgICAgdmFsdWVzTWFwW2hlYWRlci50aXRsZV0gPSBoZWFkZXIudGl0bGU7XG4gICAgICByZXR1cm4gdmFsdWVzTWFwO1xuICAgIH0sIHt9KTtcbiAgfVxuXG4gIHJldHVybiAoaGVhZGVycyB8fCBbXSkucmVkdWNlKCh2YWx1ZXNNYXAsIGhlYWRlcikgPT4ge1xuICAgIGNvbnN0IHJvd3MgPSBpc1Jvd3MgPyBnZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVyKGhlYWRlcikgOiBzb3J0VGFyZ2V0SW5kZXhlcztcbiAgICBjb25zdCBjb2x1bW5zID0gaXNSb3dzID8gc29ydFRhcmdldEluZGV4ZXMgOiBnZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVyKGhlYWRlcik7XG4gICAgdmFsdWVzTWFwW2hlYWRlci50aXRsZV0gPSBnZXROdW1lcmljVmFsdWVzU3VtbWFyeSh2YWx1ZXMsIHJvd3MsIGNvbHVtbnMpO1xuICAgIHJldHVybiB2YWx1ZXNNYXA7XG4gIH0sIHt9KTtcbn1cblxuZnVuY3Rpb24gZ2V0TnVtZXJpY1ZhbHVlc1N1bW1hcnkodmFsdWVzOiBhbnlbXVtdLCByb3dzOiBudW1iZXJbXSwgY29sdW1uczogbnVtYmVyW10pOiBudW1iZXIge1xuICBsZXQgc3VtID0gMDtcbiAgZm9yIChjb25zdCByb3cgb2Ygcm93cykge1xuICAgIGZvciAoY29uc3QgY29sdW1uIG9mIGNvbHVtbnMpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdmFsdWVzW3Jvd11bY29sdW1uXTtcbiAgICAgIGlmIChpc05vdE51bGxPclVuZGVmaW5lZCh2YWx1ZSkgJiYgaXNOdW1lcmljKHZhbHVlKSkge1xuICAgICAgICBzdW0gKz0gdG9OdW1iZXIodmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gc3VtO1xufVxuXG5mdW5jdGlvbiBzb3J0VmFsdWVUYXJnZXRJbmRleGVzKFxuICBzb3J0OiBMbXJQaXZvdFNvcnQsXG4gIG90aGVyU2lkZUhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLFxuICB2YWx1ZVRpdGxlczogc3RyaW5nW11cbik6IG51bWJlcltdIHwgbnVsbCB7XG4gIGlmIChzb3J0ICYmIHNvcnQubGlzdCkge1xuICAgIGxldCB2YWx1ZUluZGV4ID0gdmFsdWVUaXRsZXMuZmluZEluZGV4KHRpdGxlID0+IHRpdGxlID09PSBzb3J0Lmxpc3QudmFsdWVUaXRsZSk7XG4gICAgaWYgKHZhbHVlSW5kZXggPT09IC0xKSB7XG4gICAgICBpZiAodmFsdWVUaXRsZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHZhbHVlSW5kZXggPSAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IHBpdm90SGVhZGVyOiBMbXJQaXZvdERhdGFIZWFkZXIgPSBudWxsO1xuICAgIGxldCBjdXJyZW50T3RoZXJTaWRlSGVhZGVycyA9IG90aGVyU2lkZUhlYWRlcnM7XG4gICAgZm9yIChjb25zdCB2YWx1ZSBvZiBzb3J0Lmxpc3QudmFsdWVzIHx8IFtdKSB7XG4gICAgICBpZiAodmFsdWUuaXNTdW1tYXJ5KSB7XG4gICAgICAgIGNvbnN0IGluZGV4ZXMgPSBnZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVycyhjdXJyZW50T3RoZXJTaWRlSGVhZGVycyB8fCBbXSkgfHwgW107XG4gICAgICAgIHJldHVybiBmaWx0ZXJJbmRleGVzQnlNb2QoaW5kZXhlcywgdmFsdWVUaXRsZXMubGVuZ3RoLCB2YWx1ZUluZGV4KTtcbiAgICAgIH1cblxuICAgICAgcGl2b3RIZWFkZXIgPSAoY3VycmVudE90aGVyU2lkZUhlYWRlcnMgfHwgW10pLmZpbmQoaGVhZGVyID0+IGhlYWRlci50aXRsZSA9PT0gdmFsdWUudGl0bGUpO1xuICAgICAgaWYgKCFwaXZvdEhlYWRlcikge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY3VycmVudE90aGVyU2lkZUhlYWRlcnMgPSBwaXZvdEhlYWRlci5jaGlsZHJlbiB8fCBbXTtcbiAgICB9XG5cbiAgICBpZiAocGl2b3RIZWFkZXIpIHtcbiAgICAgIGNvbnN0IHRhcmdldEluZGV4ZXMgPSBpc05vdE51bGxPclVuZGVmaW5lZChwaXZvdEhlYWRlci50YXJnZXRJbmRleClcbiAgICAgICAgPyBbcGl2b3RIZWFkZXIudGFyZ2V0SW5kZXhdXG4gICAgICAgIDogZ2V0VGFyZ2V0SW5kZXhlc0ZvckhlYWRlcnMoY3VycmVudE90aGVyU2lkZUhlYWRlcnMpO1xuICAgICAgcmV0dXJuIGZpbHRlckluZGV4ZXNCeU1vZCh0YXJnZXRJbmRleGVzLCB2YWx1ZVRpdGxlcy5sZW5ndGgsIHZhbHVlSW5kZXgpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBmaWx0ZXJJbmRleGVzQnlNb2QoaW5kZXhlczogbnVtYmVyW10sIG1vZDogbnVtYmVyLCB2YWx1ZTogbnVtYmVyKTogbnVtYmVyW10ge1xuICByZXR1cm4gKGluZGV4ZXMgfHwgW10pLmZpbHRlcihpbmRleCA9PiBpbmRleCAlIG1vZCA9PT0gdmFsdWUpO1xufVxuXG5mdW5jdGlvbiBkaXZpZGVWYWx1ZXModmFsdWU6IGFueSwgZGl2aWRlcjogYW55KTogbnVtYmVyIHtcbiAgaWYgKGlzTnVsbE9yVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKGlzTnVtZXJpYyh2YWx1ZSkgJiYgaXNOdW1lcmljKGRpdmlkZXIpKSB7XG4gICAgaWYgKGRpdmlkZXIgIT09IDApIHtcbiAgICAgIHJldHVybiB2YWx1ZSAvIGRpdmlkZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuIl19
|