@kepler.gl/utils 3.0.0-alpha.2 → 3.1.0-alpha.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.
Files changed (73) hide show
  1. package/package.json +14 -10
  2. package/dist/aggregate-utils.d.ts +0 -3
  3. package/dist/aggregate-utils.js +0 -75
  4. package/dist/arrow-data-container.d.ts +0 -54
  5. package/dist/arrow-data-container.js +0 -360
  6. package/dist/color-utils.d.ts +0 -51
  7. package/dist/color-utils.js +0 -161
  8. package/dist/data-container-interface.d.ts +0 -133
  9. package/dist/data-container-interface.js +0 -6
  10. package/dist/data-container-utils.d.ts +0 -30
  11. package/dist/data-container-utils.js +0 -88
  12. package/dist/data-row.d.ts +0 -59
  13. package/dist/data-row.js +0 -126
  14. package/dist/data-scale-utils.d.ts +0 -23
  15. package/dist/data-scale-utils.js +0 -62
  16. package/dist/data-utils.d.ts +0 -103
  17. package/dist/data-utils.js +0 -502
  18. package/dist/dataset-utils.d.ts +0 -116
  19. package/dist/dataset-utils.js +0 -614
  20. package/dist/dom-to-image.d.ts +0 -73
  21. package/dist/dom-to-image.js +0 -489
  22. package/dist/dom-utils.d.ts +0 -23
  23. package/dist/dom-utils.js +0 -434
  24. package/dist/effect-utils.d.ts +0 -23
  25. package/dist/effect-utils.js +0 -196
  26. package/dist/export-map-html.d.ts +0 -9
  27. package/dist/export-map-html.js +0 -28
  28. package/dist/export-utils.d.ts +0 -53
  29. package/dist/export-utils.js +0 -262
  30. package/dist/filter-utils.d.ts +0 -326
  31. package/dist/filter-utils.js +0 -1333
  32. package/dist/format.d.ts +0 -1
  33. package/dist/format.js +0 -17
  34. package/dist/gl-utils.d.ts +0 -1
  35. package/dist/gl-utils.js +0 -35
  36. package/dist/h3-utils.d.ts +0 -21
  37. package/dist/h3-utils.js +0 -81
  38. package/dist/index.d.ts +0 -36
  39. package/dist/index.js +0 -772
  40. package/dist/indexed-data-container.d.ts +0 -34
  41. package/dist/indexed-data-container.js +0 -254
  42. package/dist/locale-utils.d.ts +0 -2
  43. package/dist/locale-utils.js +0 -54
  44. package/dist/map-info-utils.d.ts +0 -1
  45. package/dist/map-info-utils.js +0 -15
  46. package/dist/map-style-utils/mapbox-gl-style-editor.d.ts +0 -65
  47. package/dist/map-style-utils/mapbox-gl-style-editor.js +0 -218
  48. package/dist/map-style-utils/mapbox-utils.d.ts +0 -9
  49. package/dist/map-style-utils/mapbox-utils.js +0 -48
  50. package/dist/map-utils.d.ts +0 -9
  51. package/dist/map-utils.js +0 -65
  52. package/dist/mapbox-utils.d.ts +0 -7
  53. package/dist/mapbox-utils.js +0 -22
  54. package/dist/noop.d.ts +0 -1
  55. package/dist/noop.js +0 -11
  56. package/dist/notifications-utils.d.ts +0 -42
  57. package/dist/notifications-utils.js +0 -85
  58. package/dist/observe-dimensions.d.ts +0 -15
  59. package/dist/observe-dimensions.js +0 -151
  60. package/dist/plot.d.ts +0 -6
  61. package/dist/plot.js +0 -31
  62. package/dist/projection-utils.d.ts +0 -21
  63. package/dist/projection-utils.js +0 -100
  64. package/dist/row-data-container.d.ts +0 -31
  65. package/dist/row-data-container.js +0 -252
  66. package/dist/searcher-utils.d.ts +0 -1
  67. package/dist/searcher-utils.js +0 -28
  68. package/dist/split-map-utils.d.ts +0 -32
  69. package/dist/split-map-utils.js +0 -114
  70. package/dist/time.d.ts +0 -16
  71. package/dist/time.js +0 -89
  72. package/dist/utils.d.ts +0 -116
  73. package/dist/utils.js +0 -305
@@ -1,1333 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
6
-
7
- Object.defineProperty(exports, "__esModule", {
8
- value: true
9
- });
10
- exports.getDefaultFilter = getDefaultFilter;
11
- exports.shouldApplyFilter = shouldApplyFilter;
12
- exports.validatePolygonFilter = validatePolygonFilter;
13
- exports.validateFilter = validateFilter;
14
- exports.validateFilterWithData = validateFilterWithData;
15
- exports.getFilterProps = getFilterProps;
16
- exports.getFilterFunction = getFilterFunction;
17
- exports.updateFilterDataId = updateFilterDataId;
18
- exports.filterDataByFilterTypes = filterDataByFilterTypes;
19
- exports.getFilterRecord = getFilterRecord;
20
- exports.diffFilters = diffFilters;
21
- exports.adjustValueToFilterDomain = adjustValueToFilterDomain;
22
- exports.getNumericFieldDomain = getNumericFieldDomain;
23
- exports.getNumericStepSize = getNumericStepSize;
24
- exports.getTimestampFieldDomain = getTimestampFieldDomain;
25
- exports.histogramConstruct = histogramConstruct;
26
- exports.getHistogram = getHistogram;
27
- exports.formatNumberByStep = formatNumberByStep;
28
- exports.isInRange = isInRange;
29
- exports.isInPolygon = isInPolygon;
30
- exports.getTimeWidgetTitleFormatter = getTimeWidgetTitleFormatter;
31
- exports.isFilterValidToSave = isFilterValidToSave;
32
- exports.isValidFilterValue = isValidFilterValue;
33
- exports.getColumnFilterProps = getColumnFilterProps;
34
- exports.getDefaultFilterPlotType = getDefaultFilterPlotType;
35
- exports.applyFiltersToDatasets = applyFiltersToDatasets;
36
- exports.applyFilterFieldName = applyFilterFieldName;
37
- exports.mergeFilterDomainStep = mergeFilterDomainStep;
38
- exports.generatePolygonFilter = generatePolygonFilter;
39
- exports.filterDatasetCPU = filterDatasetCPU;
40
- exports.validateFiltersUpdateDatasets = validateFiltersUpdateDatasets;
41
- exports.getFilterPlot = getFilterPlot;
42
- exports.getIntervalBins = getIntervalBins;
43
- exports.isValidTimeDomain = isValidTimeDomain;
44
- exports.getTimeWidgetHintFormatter = getTimeWidgetHintFormatter;
45
- exports.isSideFilter = isSideFilter;
46
- exports.getFilterIdInFeature = exports.featureToFilterValue = exports.getPolygonFilterFunctor = exports.LAYER_FILTERS = exports.FILTER_ID_LENGTH = exports.DEFAULT_FILTER_STRUCTURE = exports.FILTER_COMPONENTS = exports.LIMITED_FILTER_EFFECT_PROPS = exports.FILTER_UPDATER_PROPS = exports.enlargedHistogramBins = exports.histogramBins = exports.TimestampStepMap = exports.durationYear = exports.durationWeek = exports.durationDay = exports.durationHour = exports.durationMinute = exports.durationSecond = void 0;
47
-
48
- var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
49
-
50
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
51
-
52
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
53
-
54
- var _d3Array = require("d3-array");
55
-
56
- var _keymirror = _interopRequireDefault(require("keymirror"));
57
-
58
- var _console = _interopRequireDefault(require("global/console"));
59
-
60
- var _lodash = _interopRequireDefault(require("lodash.get"));
61
-
62
- var _lodash2 = _interopRequireDefault(require("lodash.isequal"));
63
-
64
- var _booleanWithin = _interopRequireDefault(require("@turf/boolean-within"));
65
-
66
- var _helpers = require("@turf/helpers");
67
-
68
- var _decimal = require("decimal.js");
69
-
70
- var _constants = require("@kepler.gl/constants");
71
-
72
- var ScaleUtils = _interopRequireWildcard(require("./data-scale-utils"));
73
-
74
- var _h3Js = require("h3-js");
75
-
76
- var _utils = require("./utils");
77
-
78
- var _dataUtils = require("./data-utils");
79
-
80
- var _h3Utils = require("./h3-utils");
81
-
82
- var _FILTER_TYPES$timeRan, _FILTER_TYPES$range, _SupportedPlotType, _FILTER_COMPONENTS;
83
-
84
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
85
-
86
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
87
-
88
- var durationSecond = 1000;
89
- exports.durationSecond = durationSecond;
90
- var durationMinute = durationSecond * 60;
91
- exports.durationMinute = durationMinute;
92
- var durationHour = durationMinute * 60;
93
- exports.durationHour = durationHour;
94
- var durationDay = durationHour * 24;
95
- exports.durationDay = durationDay;
96
- var durationWeek = durationDay * 7;
97
- exports.durationWeek = durationWeek;
98
- var durationYear = durationDay * 365;
99
- exports.durationYear = durationYear;
100
- var TimestampStepMap = [{
101
- max: 1,
102
- step: 0.05
103
- }, {
104
- max: 10,
105
- step: 0.1
106
- }, {
107
- max: 100,
108
- step: 1
109
- }, {
110
- max: 500,
111
- step: 5
112
- }, {
113
- max: 1000,
114
- step: 10
115
- }, {
116
- max: 5000,
117
- step: 50
118
- }, {
119
- max: Number.POSITIVE_INFINITY,
120
- step: 1000
121
- }];
122
- exports.TimestampStepMap = TimestampStepMap;
123
- var histogramBins = 30;
124
- exports.histogramBins = histogramBins;
125
- var enlargedHistogramBins = 100;
126
- exports.enlargedHistogramBins = enlargedHistogramBins;
127
- var FILTER_UPDATER_PROPS = (0, _keymirror["default"])({
128
- dataId: null,
129
- name: null,
130
- layerId: null
131
- });
132
- exports.FILTER_UPDATER_PROPS = FILTER_UPDATER_PROPS;
133
- var LIMITED_FILTER_EFFECT_PROPS = (0, _keymirror["default"])((0, _defineProperty2["default"])({}, FILTER_UPDATER_PROPS.name, null));
134
- /**
135
- * Max number of filter value buffers that deck.gl provides
136
- */
137
-
138
- exports.LIMITED_FILTER_EFFECT_PROPS = LIMITED_FILTER_EFFECT_PROPS;
139
- var SupportedPlotType = (_SupportedPlotType = {}, (0, _defineProperty2["default"])(_SupportedPlotType, _constants.FILTER_TYPES.timeRange, (_FILTER_TYPES$timeRan = {
140
- "default": 'histogram'
141
- }, (0, _defineProperty2["default"])(_FILTER_TYPES$timeRan, _constants.ALL_FIELD_TYPES.integer, 'lineChart'), (0, _defineProperty2["default"])(_FILTER_TYPES$timeRan, _constants.ALL_FIELD_TYPES.real, 'lineChart'), _FILTER_TYPES$timeRan)), (0, _defineProperty2["default"])(_SupportedPlotType, _constants.FILTER_TYPES.range, (_FILTER_TYPES$range = {
142
- "default": 'histogram'
143
- }, (0, _defineProperty2["default"])(_FILTER_TYPES$range, _constants.ALL_FIELD_TYPES.integer, 'lineChart'), (0, _defineProperty2["default"])(_FILTER_TYPES$range, _constants.ALL_FIELD_TYPES.real, 'lineChart'), _FILTER_TYPES$range)), _SupportedPlotType);
144
- var FILTER_COMPONENTS = (_FILTER_COMPONENTS = {}, (0, _defineProperty2["default"])(_FILTER_COMPONENTS, _constants.FILTER_TYPES.select, 'SingleSelectFilter'), (0, _defineProperty2["default"])(_FILTER_COMPONENTS, _constants.FILTER_TYPES.multiSelect, 'MultiSelectFilter'), (0, _defineProperty2["default"])(_FILTER_COMPONENTS, _constants.FILTER_TYPES.timeRange, 'TimeRangeFilter'), (0, _defineProperty2["default"])(_FILTER_COMPONENTS, _constants.FILTER_TYPES.range, 'RangeFilter'), (0, _defineProperty2["default"])(_FILTER_COMPONENTS, _constants.FILTER_TYPES.polygon, 'PolygonFilter'), _FILTER_COMPONENTS);
145
- exports.FILTER_COMPONENTS = FILTER_COMPONENTS;
146
- var DEFAULT_FILTER_STRUCTURE = {
147
- dataId: [],
148
- // [string]
149
- freeze: false,
150
- id: null,
151
- enabled: true,
152
- // time range filter specific
153
- fixedDomain: false,
154
- view: _constants.FILTER_VIEW_TYPES.side,
155
- isAnimating: false,
156
- animationWindow: _constants.ANIMATION_WINDOW.free,
157
- speed: 1,
158
- // field specific
159
- name: [],
160
- // string
161
- type: null,
162
- fieldIdx: [],
163
- // [integer]
164
- domain: null,
165
- value: null,
166
- // plot
167
- plotType: _constants.PLOT_TYPES.histogram,
168
- yAxis: null,
169
- interval: null,
170
- // mode
171
- gpu: false
172
- };
173
- exports.DEFAULT_FILTER_STRUCTURE = DEFAULT_FILTER_STRUCTURE;
174
- var FILTER_ID_LENGTH = 4;
175
- exports.FILTER_ID_LENGTH = FILTER_ID_LENGTH;
176
- var LAYER_FILTERS = [_constants.FILTER_TYPES.polygon];
177
- /**
178
- * Generates a filter with a dataset id as dataId
179
- */
180
-
181
- exports.LAYER_FILTERS = LAYER_FILTERS;
182
-
183
- function getDefaultFilter() {
184
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
185
- dataId = _ref.dataId,
186
- id = _ref.id;
187
-
188
- return _objectSpread(_objectSpread({}, DEFAULT_FILTER_STRUCTURE), {}, {
189
- // store it as dataId and it could be one or many
190
- dataId: dataId ? (0, _utils.toArray)(dataId) : [],
191
- id: id || (0, _utils.generateHashId)(FILTER_ID_LENGTH)
192
- });
193
- }
194
- /**
195
- * Check if a filter is valid based on the given dataId
196
- * @param filter to validate
197
- * @param datasetId id to validate filter against
198
- * @return true if a filter is valid, false otherwise
199
- */
200
-
201
-
202
- function shouldApplyFilter(filter, datasetId) {
203
- var dataIds = (0, _utils.toArray)(filter.dataId);
204
- return dataIds.includes(datasetId) && filter.value !== null;
205
- }
206
-
207
- /**
208
- * Validates and modifies polygon filter structure
209
- * @param dataset
210
- * @param filter
211
- * @param layers
212
- * @return - {filter, dataset}
213
- */
214
- function validatePolygonFilter(dataset, filter, layers) {
215
- var failed = {
216
- dataset: dataset,
217
- filter: null
218
- };
219
- var value = filter.value,
220
- layerId = filter.layerId,
221
- type = filter.type,
222
- dataId = filter.dataId;
223
-
224
- if (!layerId || !isValidFilterValue(type, value)) {
225
- return failed;
226
- }
227
-
228
- var isValidDataset = dataId.includes(dataset.id);
229
-
230
- if (!isValidDataset) {
231
- return failed;
232
- }
233
-
234
- var layer = layers.find(function (l) {
235
- return layerId.includes(l.id);
236
- });
237
-
238
- if (!layer) {
239
- return failed;
240
- }
241
-
242
- return {
243
- filter: _objectSpread(_objectSpread({}, filter), {}, {
244
- freeze: true,
245
- fieldIdx: []
246
- }),
247
- dataset: dataset
248
- };
249
- }
250
- /**
251
- * Custom filter validators
252
- */
253
-
254
-
255
- var filterValidators = (0, _defineProperty2["default"])({}, _constants.FILTER_TYPES.polygon, validatePolygonFilter);
256
- /**
257
- * Default validate filter function
258
- * @param dataset
259
- * @param filter
260
- * @return - {filter, dataset}
261
- */
262
-
263
- function validateFilter(dataset, filter) {
264
- var _filter$view;
265
-
266
- // match filter.dataId
267
- var failed = {
268
- dataset: dataset,
269
- filter: null
270
- };
271
- var filterDataId = (0, _utils.toArray)(filter.dataId);
272
- var filterDatasetIndex = filterDataId.indexOf(dataset.id);
273
-
274
- if (filterDatasetIndex < 0 || !(0, _utils.toArray)(filter.name)[filterDatasetIndex]) {
275
- // the current filter is not mapped against the current dataset
276
- return failed;
277
- }
278
-
279
- var initializeFilter = _objectSpread(_objectSpread(_objectSpread({}, getDefaultFilter({
280
- dataId: filter.dataId
281
- })), filter), {}, {
282
- dataId: filterDataId,
283
- name: (0, _utils.toArray)(filter.name)
284
- });
285
-
286
- var fieldName = initializeFilter.name[filterDatasetIndex];
287
-
288
- var _applyFilterFieldName = applyFilterFieldName(initializeFilter, dataset, fieldName, filterDatasetIndex, {
289
- mergeDomain: true
290
- }),
291
- updatedFilter = _applyFilterFieldName.filter,
292
- updatedDataset = _applyFilterFieldName.dataset;
293
-
294
- if (!updatedFilter) {
295
- return failed;
296
- }
297
-
298
- updatedFilter.value = adjustValueToFilterDomain(filter.value, updatedFilter);
299
- updatedFilter.view = (_filter$view = filter.view) !== null && _filter$view !== void 0 ? _filter$view : updatedFilter.view;
300
-
301
- if (updatedFilter.value === null) {
302
- // cannot adjust saved value to filter
303
- return failed;
304
- }
305
-
306
- return {
307
- filter: validateFilterYAxis(updatedFilter, updatedDataset),
308
- dataset: updatedDataset
309
- };
310
- }
311
- /**
312
- * Validate saved filter config with new data,
313
- * calculate domain and fieldIdx based new fields and data
314
- *
315
- * @param dataset
316
- * @param filter - filter to be validate
317
- * @param layers - layers
318
- * @return validated filter
319
- */
320
-
321
-
322
- function validateFilterWithData(dataset, filter, layers) {
323
- return filter.type && filterValidators.hasOwnProperty(filter.type) ? filterValidators[filter.type](dataset, filter, layers) : validateFilter(dataset, filter);
324
- }
325
- /**
326
- * Validate YAxis
327
- * @param filter
328
- * @param dataset
329
- * @return {*}
330
- */
331
-
332
-
333
- function validateFilterYAxis(filter, dataset) {
334
- // TODO: validate yAxis against other datasets
335
- var fields = dataset.fields;
336
- var _filter = filter,
337
- yAxis = _filter.yAxis; // TODO: validate yAxis against other datasets
338
-
339
- if (yAxis) {
340
- var matchedAxis = fields.find(function (_ref2) {
341
- var name = _ref2.name,
342
- type = _ref2.type;
343
- return name === yAxis.name && type === yAxis.type;
344
- });
345
- filter = matchedAxis ? _objectSpread(_objectSpread({}, filter), {}, {
346
- yAxis: matchedAxis
347
- }, getFilterPlot(_objectSpread(_objectSpread({}, filter), {}, {
348
- yAxis: matchedAxis
349
- }), dataset)) : filter;
350
- }
351
-
352
- return filter;
353
- }
354
- /**
355
- * Get default filter prop based on field type
356
- *
357
- * @param field
358
- * @param fieldDomain
359
- * @returns default filter
360
- */
361
-
362
-
363
- function getFilterProps(field, fieldDomain) {
364
- var filterProps = _objectSpread(_objectSpread({}, fieldDomain), {}, {
365
- fieldType: field.type,
366
- view: _constants.FILTER_VIEW_TYPES.side
367
- });
368
-
369
- switch (field.type) {
370
- case _constants.ALL_FIELD_TYPES.real:
371
- case _constants.ALL_FIELD_TYPES.integer:
372
- return _objectSpread(_objectSpread({}, filterProps), {}, {
373
- value: fieldDomain.domain,
374
- type: _constants.FILTER_TYPES.range,
375
- // @ts-expect-error
376
- typeOptions: [_constants.FILTER_TYPES.range],
377
- gpu: true
378
- });
379
-
380
- case _constants.ALL_FIELD_TYPES["boolean"]:
381
- // @ts-expect-error
382
- return _objectSpread(_objectSpread({}, filterProps), {}, {
383
- type: _constants.FILTER_TYPES.select,
384
- value: true,
385
- gpu: false
386
- });
387
-
388
- case _constants.ALL_FIELD_TYPES.string:
389
- case _constants.ALL_FIELD_TYPES.date:
390
- // @ts-expect-error
391
- return _objectSpread(_objectSpread({}, filterProps), {}, {
392
- type: _constants.FILTER_TYPES.multiSelect,
393
- value: [],
394
- gpu: false
395
- });
396
-
397
- case _constants.ALL_FIELD_TYPES.timestamp:
398
- // @ts-expect-error
399
- return _objectSpread(_objectSpread({}, filterProps), {}, {
400
- type: _constants.FILTER_TYPES.timeRange,
401
- view: _constants.FILTER_VIEW_TYPES.enlarged,
402
- fixedDomain: true,
403
- value: filterProps.domain,
404
- gpu: true
405
- });
406
-
407
- default:
408
- // @ts-expect-error
409
- return {};
410
- }
411
- }
412
-
413
- var getPolygonFilterFunctor = function getPolygonFilterFunctor(layer, filter, dataContainer) {
414
- var getPosition = layer.getPositionAccessor(dataContainer);
415
-
416
- switch (layer.type) {
417
- case _constants.LAYER_TYPES.point:
418
- case _constants.LAYER_TYPES.icon:
419
- return function (data) {
420
- var pos = getPosition(data);
421
- return pos.every(Number.isFinite) && isInPolygon(pos, filter.value);
422
- };
423
-
424
- case _constants.LAYER_TYPES.arc:
425
- case _constants.LAYER_TYPES.line:
426
- return function (data) {
427
- var pos = getPosition(data);
428
- return pos.every(Number.isFinite) && [[pos[0], pos[1]], [pos[3], pos[4]]].every(function (point) {
429
- return isInPolygon(point, filter.value);
430
- });
431
- };
432
-
433
- case _constants.LAYER_TYPES.hexagonId:
434
- if (layer.dataToFeature && layer.dataToFeature.centroids) {
435
- return function (data) {
436
- // null or getCentroid({id})
437
- var centroid = layer.dataToFeature.centroids[data.index];
438
- return centroid && isInPolygon(centroid, filter.value);
439
- };
440
- }
441
-
442
- return function (data) {
443
- var id = getPosition(data);
444
-
445
- if (!(0, _h3Js.h3IsValid)(id)) {
446
- return false;
447
- }
448
-
449
- var pos = (0, _h3Utils.getCentroid)({
450
- id: id
451
- });
452
- return pos.every(Number.isFinite) && isInPolygon(pos, filter.value);
453
- };
454
-
455
- case _constants.LAYER_TYPES.geojson:
456
- return function (data) {
457
- return layer.isInPolygon(data, data.index, filter.value);
458
- };
459
-
460
- default:
461
- return function () {
462
- return true;
463
- };
464
- }
465
- };
466
- /**
467
- * @param param An object that represents a row record.
468
- * @param param.index Index of the row in data container.
469
- * @returns Returns true to keep the element, or false otherwise.
470
- */
471
-
472
-
473
- exports.getPolygonFilterFunctor = getPolygonFilterFunctor;
474
-
475
- /**
476
- * @param field dataset Field
477
- * @param dataId Dataset id
478
- * @param filter Filter object
479
- * @param layers list of layers to filter upon
480
- * @param dataContainer Data container
481
- * @return filterFunction
482
- */
483
-
484
- /* eslint-disable complexity */
485
- function getFilterFunction(field, dataId, filter, layers, dataContainer) {
486
- // field could be null in polygon filter
487
- var valueAccessor = field ? field.valueAccessor : function (data) {
488
- return null;
489
- };
490
-
491
- var defaultFunc = function defaultFunc(d) {
492
- return true;
493
- };
494
-
495
- if (filter.enabled === false) {
496
- return defaultFunc;
497
- }
498
-
499
- switch (filter.type) {
500
- case _constants.FILTER_TYPES.range:
501
- return function (data) {
502
- return isInRange(valueAccessor(data), filter.value);
503
- };
504
-
505
- case _constants.FILTER_TYPES.multiSelect:
506
- return function (data) {
507
- return filter.value.includes(valueAccessor(data));
508
- };
509
-
510
- case _constants.FILTER_TYPES.select:
511
- return function (data) {
512
- return valueAccessor(data) === filter.value;
513
- };
514
-
515
- case _constants.FILTER_TYPES.timeRange:
516
- if (!field) {
517
- return defaultFunc;
518
- }
519
-
520
- var mappedValue = (0, _lodash["default"])(field, ['filterProps', 'mappedValue']);
521
- var accessor = Array.isArray(mappedValue) ? function (data) {
522
- return mappedValue[data.index];
523
- } : function (data) {
524
- return (0, _dataUtils.timeToUnixMilli)(valueAccessor(data), field.format);
525
- };
526
- return function (data) {
527
- return isInRange(accessor(data), filter.value);
528
- };
529
-
530
- case _constants.FILTER_TYPES.polygon:
531
- if (!layers || !layers.length || !filter.layerId) {
532
- return defaultFunc;
533
- }
534
-
535
- var layerFilterFunctions = filter.layerId.map(function (id) {
536
- return layers.find(function (l) {
537
- return l.id === id;
538
- });
539
- }).filter(function (l) {
540
- return l && l.config.dataId === dataId;
541
- }).map(function (layer) {
542
- return getPolygonFilterFunctor(layer, filter, dataContainer);
543
- });
544
- return function (data) {
545
- return layerFilterFunctions.every(function (filterFunc) {
546
- return filterFunc(data);
547
- });
548
- };
549
-
550
- default:
551
- return defaultFunc;
552
- }
553
- }
554
-
555
- function updateFilterDataId(dataId) {
556
- return getDefaultFilter({
557
- dataId: dataId
558
- });
559
- }
560
-
561
- function filterDataByFilterTypes(_ref3, dataContainer) {
562
- var dynamicDomainFilters = _ref3.dynamicDomainFilters,
563
- cpuFilters = _ref3.cpuFilters,
564
- filterFuncs = _ref3.filterFuncs;
565
- var filteredIndexForDomain = [];
566
- var filteredIndex = [];
567
- var filterContext = {
568
- index: -1,
569
- dataContainer: dataContainer
570
- };
571
-
572
- var filterFuncCaller = function filterFuncCaller(filter) {
573
- return filterFuncs[filter.id](filterContext);
574
- };
575
-
576
- var numRows = dataContainer.numRows();
577
-
578
- for (var i = 0; i < numRows; ++i) {
579
- filterContext.index = i;
580
- var matchForDomain = dynamicDomainFilters && dynamicDomainFilters.every(filterFuncCaller);
581
-
582
- if (matchForDomain) {
583
- filteredIndexForDomain.push(filterContext.index);
584
- }
585
-
586
- var matchForRender = cpuFilters && cpuFilters.every(filterFuncCaller);
587
-
588
- if (matchForRender) {
589
- filteredIndex.push(filterContext.index);
590
- }
591
- }
592
-
593
- return _objectSpread(_objectSpread({}, dynamicDomainFilters ? {
594
- filteredIndexForDomain: filteredIndexForDomain
595
- } : {}), cpuFilters ? {
596
- filteredIndex: filteredIndex
597
- } : {});
598
- }
599
- /**
600
- * Get a record of filters based on domain type and gpu / cpu
601
- */
602
-
603
-
604
- function getFilterRecord(dataId, filters) {
605
- var opt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
606
- var filterRecord = {
607
- dynamicDomain: [],
608
- fixedDomain: [],
609
- cpu: [],
610
- gpu: []
611
- };
612
- filters.forEach(function (f) {
613
- if (isValidFilterValue(f.type, f.value) && (0, _utils.toArray)(f.dataId).includes(dataId)) {
614
- (f.fixedDomain || opt.ignoreDomain ? filterRecord.fixedDomain : filterRecord.dynamicDomain).push(f);
615
- (f.gpu && !opt.cpuOnly ? filterRecord.gpu : filterRecord.cpu).push(f);
616
- }
617
- });
618
- return filterRecord;
619
- }
620
- /**
621
- * Compare filter records to get what has changed
622
- */
623
-
624
-
625
- function diffFilters(filterRecord) {
626
- var oldFilterRecord = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
627
- var filterChanged = {};
628
- Object.entries(filterRecord).forEach(function (_ref4) {
629
- var _ref5 = (0, _slicedToArray2["default"])(_ref4, 2),
630
- record = _ref5[0],
631
- items = _ref5[1];
632
-
633
- items.forEach(function (filter) {
634
- var oldFilter = (oldFilterRecord[record] || []).find(function (f) {
635
- return f.id === filter.id;
636
- });
637
-
638
- if (!oldFilter) {
639
- // added
640
- filterChanged = (0, _utils.set)([record, filter.id], 'added', filterChanged);
641
- } else {
642
- // check what has changed
643
- ['name', 'value', 'dataId'].forEach(function (prop) {
644
- if (filter[prop] !== oldFilter[prop]) {
645
- filterChanged = (0, _utils.set)([record, filter.id], "".concat(prop, "_changed"), filterChanged);
646
- }
647
- });
648
- }
649
- });
650
- (oldFilterRecord[record] || []).forEach(function (oldFilter) {
651
- // deleted
652
- if (!items.find(function (f) {
653
- return f.id === oldFilter.id;
654
- })) {
655
- filterChanged = (0, _utils.set)([record, oldFilter.id], 'deleted', filterChanged);
656
- }
657
- });
658
- });
659
- return _objectSpread(_objectSpread({}, {
660
- dynamicDomain: null,
661
- fixedDomain: null,
662
- cpu: null,
663
- gpu: null
664
- }), filterChanged);
665
- }
666
- /**
667
- * Call by parsing filters from URL
668
- * Check if value of filter within filter domain, if not adjust it to match
669
- * filter domain
670
- *
671
- * @returns value - adjusted value to match filter or null to remove filter
672
- */
673
- // eslint-disable-next-line complexity
674
-
675
-
676
- function adjustValueToFilterDomain(value, _ref6) {
677
- var domain = _ref6.domain,
678
- type = _ref6.type;
679
-
680
- if (!type) {
681
- return false;
682
- } // if the current filter is a polygon it will not have any domain
683
- // all other filter types require domain
684
-
685
-
686
- if (type !== _constants.FILTER_TYPES.polygon && !domain) {
687
- return false;
688
- }
689
-
690
- switch (type) {
691
- case _constants.FILTER_TYPES.range:
692
- case _constants.FILTER_TYPES.timeRange:
693
- if (!Array.isArray(value) || value.length !== 2) {
694
- return domain.map(function (d) {
695
- return d;
696
- });
697
- }
698
-
699
- return value.map(function (d, i) {
700
- return (0, _dataUtils.notNullorUndefined)(d) && isInRange(d, domain) ? d : domain[i];
701
- });
702
-
703
- case _constants.FILTER_TYPES.multiSelect:
704
- if (!Array.isArray(value)) {
705
- return [];
706
- }
707
-
708
- var filteredValue = value.filter(function (d) {
709
- return domain.includes(d);
710
- });
711
- return filteredValue.length ? filteredValue : [];
712
-
713
- case _constants.FILTER_TYPES.select:
714
- return domain.includes(value) ? value : true;
715
-
716
- case _constants.FILTER_TYPES.polygon:
717
- return value;
718
-
719
- default:
720
- return null;
721
- }
722
- }
723
- /* eslint-enable complexity */
724
-
725
- /**
726
- * Calculate numeric domain and suitable step
727
- */
728
-
729
-
730
- function getNumericFieldDomain(dataContainer, valueAccessor) {
731
- var domain = [0, 1];
732
- var step = 0.1;
733
- var mappedValue = dataContainer.mapIndex(valueAccessor);
734
-
735
- if (dataContainer.numRows() > 1) {
736
- domain = ScaleUtils.getLinearDomain(mappedValue);
737
- var diff = domain[1] - domain[0]; // in case equal domain, [96, 96], which will break quantize scale
738
-
739
- if (!diff) {
740
- domain[1] = domain[0] + 1;
741
- }
742
-
743
- step = getNumericStepSize(diff) || step;
744
- domain[0] = formatNumberByStep(domain[0], step, 'floor');
745
- domain[1] = formatNumberByStep(domain[1], step, 'ceil');
746
- }
747
-
748
- var _getHistogram = getHistogram(domain, mappedValue),
749
- histogram = _getHistogram.histogram,
750
- enlargedHistogram = _getHistogram.enlargedHistogram;
751
-
752
- return {
753
- domain: domain,
754
- step: step,
755
- histogram: histogram,
756
- enlargedHistogram: enlargedHistogram
757
- };
758
- }
759
- /**
760
- * Calculate step size for range and timerange filter
761
- */
762
-
763
-
764
- function getNumericStepSize(diff) {
765
- diff = Math.abs(diff);
766
-
767
- if (diff > 100) {
768
- return 1;
769
- } else if (diff > 3) {
770
- return 0.01;
771
- } else if (diff > 1) {
772
- return 0.001;
773
- } // Try to get at least 1000 steps - and keep the step size below that of
774
- // the (diff > 1) case.
775
-
776
-
777
- var x = diff / 1000; // Find the exponent and truncate to 10 to the power of that exponent
778
-
779
- var exponentialForm = x.toExponential();
780
- var exponent = parseFloat(exponentialForm.split('e')[1]); // Getting ready for node 12
781
- // this is why we need decimal.js
782
- // Math.pow(10, -5) = 0.000009999999999999999
783
- // the above result shows in browser and node 10
784
- // node 12 behaves correctly
785
-
786
- return new _decimal.Decimal(10).pow(exponent).toNumber();
787
- }
788
- /**
789
- * Calculate timestamp domain and suitable step
790
- */
791
-
792
-
793
- function getTimestampFieldDomain(dataContainer, valueAccessor) {
794
- // to avoid converting string format time to epoch
795
- // every time we compare we store a value mapped to int in filter domain
796
- var mappedValue = dataContainer.mapIndex(valueAccessor);
797
- var domain = ScaleUtils.getLinearDomain(mappedValue);
798
- var defaultTimeFormat = getTimeWidgetTitleFormatter(domain);
799
- var step = 0.01;
800
- var diff = domain[1] - domain[0]; // in case equal timestamp add 1 second padding to prevent break
801
-
802
- if (!diff) {
803
- domain[1] = domain[0] + 1000;
804
- }
805
-
806
- var entry = TimestampStepMap.find(function (f) {
807
- return f.max >= diff;
808
- });
809
-
810
- if (entry) {
811
- step = entry.step;
812
- }
813
-
814
- var _getHistogram2 = getHistogram(domain, mappedValue),
815
- histogram = _getHistogram2.histogram,
816
- enlargedHistogram = _getHistogram2.enlargedHistogram;
817
-
818
- return {
819
- domain: domain,
820
- step: step,
821
- mappedValue: mappedValue,
822
- histogram: histogram,
823
- enlargedHistogram: enlargedHistogram,
824
- defaultTimeFormat: defaultTimeFormat
825
- };
826
- }
827
-
828
- function histogramConstruct(domain, mappedValue, bins) {
829
- return (0, _d3Array.histogram)().thresholds((0, _d3Array.ticks)(domain[0], domain[1], bins)).domain(domain)(mappedValue).map(function (bin) {
830
- return {
831
- count: bin.length,
832
- bin: bin,
833
- x0: bin.x0,
834
- x1: bin.x1
835
- };
836
- });
837
- }
838
- /**
839
- * Calculate histogram from domain and array of values
840
- */
841
-
842
-
843
- function getHistogram(domain, mappedValue) {
844
- var histogram = histogramConstruct(domain, mappedValue, histogramBins);
845
- var enlargedHistogram = histogramConstruct(domain, mappedValue, enlargedHistogramBins);
846
- return {
847
- histogram: histogram,
848
- enlargedHistogram: enlargedHistogram
849
- };
850
- }
851
- /**
852
- * round number based on step
853
- *
854
- * @param {Number} val
855
- * @param {Number} step
856
- * @param {string} bound
857
- * @returns {Number} rounded number
858
- */
859
-
860
-
861
- function formatNumberByStep(val, step, bound) {
862
- if (bound === 'floor') {
863
- return Math.floor(val * (1 / step)) / (1 / step);
864
- }
865
-
866
- return Math.ceil(val * (1 / step)) / (1 / step);
867
- }
868
-
869
- function isInRange(val, domain) {
870
- if (!Array.isArray(domain)) {
871
- return false;
872
- }
873
-
874
- return val >= domain[0] && val <= domain[1];
875
- }
876
- /**
877
- * Determines whether a point is within the provided polygon
878
- *
879
- * @param point as input search [lat, lng]
880
- * @param polygon Points must be within these (Multi)Polygon(s)
881
- * @return {boolean}
882
- */
883
-
884
-
885
- function isInPolygon(point, polygon) {
886
- return (0, _booleanWithin["default"])((0, _helpers.point)(point), polygon);
887
- }
888
-
889
- function getTimeWidgetTitleFormatter(domain) {
890
- if (!isValidTimeDomain(domain)) {
891
- return null;
892
- }
893
-
894
- var diff = domain[1] - domain[0]; // Local aware formats
895
- // https://momentjs.com/docs/#/parsing/string-format
896
-
897
- return diff > durationYear ? 'L' : diff > durationDay ? 'L LT' : 'L LTS';
898
- }
899
- /**
900
- * Sanity check on filters to prepare for save
901
- * @type {typeof import('./filter-utils').isFilterValidToSave}
902
- */
903
-
904
-
905
- function isFilterValidToSave(filter) {
906
- return (filter === null || filter === void 0 ? void 0 : filter.type) && Array.isArray(filter === null || filter === void 0 ? void 0 : filter.name) && ((filter === null || filter === void 0 ? void 0 : filter.name.length) || (filter === null || filter === void 0 ? void 0 : filter.layerId.length));
907
- }
908
- /**
909
- * Sanity check on filters to prepare for save
910
- * @type {typeof import('./filter-utils').isValidFilterValue}
911
- */
912
-
913
- /* eslint-disable complexity */
914
-
915
-
916
- function isValidFilterValue(type, value) {
917
- if (!type) {
918
- return false;
919
- }
920
-
921
- switch (type) {
922
- case _constants.FILTER_TYPES.select:
923
- return value === true || value === false;
924
-
925
- case _constants.FILTER_TYPES.range:
926
- case _constants.FILTER_TYPES.timeRange:
927
- return Array.isArray(value) && value.every(function (v) {
928
- return v !== null && !isNaN(v);
929
- });
930
-
931
- case _constants.FILTER_TYPES.multiSelect:
932
- return Array.isArray(value) && Boolean(value.length);
933
-
934
- case _constants.FILTER_TYPES.input:
935
- return Boolean(value.length);
936
-
937
- case _constants.FILTER_TYPES.polygon:
938
- var coordinates = (0, _lodash["default"])(value, ['geometry', 'coordinates']);
939
- return Boolean(value && value.id && coordinates);
940
-
941
- default:
942
- return true;
943
- }
944
- }
945
-
946
- function getColumnFilterProps(filter, dataset) {
947
- if (filter.plotType === _constants.PLOT_TYPES.histogram || !filter.yAxis) {
948
- // histogram should be calculated when create filter
949
- return {};
950
- }
951
-
952
- var _filter$mappedValue = filter.mappedValue,
953
- mappedValue = _filter$mappedValue === void 0 ? [] : _filter$mappedValue;
954
- var yAxis = filter.yAxis;
955
- var fieldIdx = dataset.getColumnFieldIdx(yAxis.name);
956
-
957
- if (fieldIdx < 0) {
958
- _console["default"].warn("yAxis ".concat(yAxis.name, " does not exist in dataset"));
959
-
960
- return {
961
- lineChart: {},
962
- yAxis: yAxis
963
- };
964
- } // return lineChart
965
-
966
-
967
- var series = dataset.dataContainer.map(function (row, rowIndex) {
968
- return {
969
- x: mappedValue[rowIndex],
970
- y: row.valueAt(fieldIdx)
971
- };
972
- }, true).filter(function (_ref7) {
973
- var x = _ref7.x,
974
- y = _ref7.y;
975
- return Number.isFinite(x) && Number.isFinite(y);
976
- }).sort(function (a, b) {
977
- return (0, _d3Array.ascending)(a.x, b.x);
978
- });
979
- var yDomain = (0, _d3Array.extent)(series, function (d) {
980
- return d.y;
981
- });
982
- var xDomain = [series[0].x, series[series.length - 1].x];
983
- return {
984
- lineChart: {
985
- series: series,
986
- yDomain: yDomain,
987
- xDomain: xDomain
988
- },
989
- yAxis: yAxis
990
- };
991
- }
992
-
993
- function getDefaultFilterPlotType(filter) {
994
- var filterPlotTypes = filter.type && SupportedPlotType[filter.type];
995
-
996
- if (!filterPlotTypes) {
997
- return null;
998
- }
999
-
1000
- if (!filter.yAxis) {
1001
- return filterPlotTypes["default"];
1002
- }
1003
-
1004
- return filterPlotTypes[filter.yAxis.type] || null;
1005
- }
1006
- /**
1007
- *
1008
- * @param datasetIds list of dataset ids to be filtered
1009
- * @param datasets all datasets
1010
- * @param filters all filters to be applied to datasets
1011
- * @return datasets - new updated datasets
1012
- */
1013
-
1014
-
1015
- function applyFiltersToDatasets(datasetIds, datasets, filters, layers) {
1016
- var dataIds = (0, _utils.toArray)(datasetIds);
1017
- return dataIds.reduce(function (acc, dataId) {
1018
- var layersToFilter = (layers || []).filter(function (l) {
1019
- return l.config.dataId === dataId;
1020
- });
1021
- var appliedFilters = filters.filter(function (d) {
1022
- return shouldApplyFilter(d, dataId);
1023
- });
1024
- var table = datasets[dataId];
1025
- return _objectSpread(_objectSpread({}, acc), {}, (0, _defineProperty2["default"])({}, dataId, table.filterTable(appliedFilters, layersToFilter, {})));
1026
- }, datasets);
1027
- }
1028
- /**
1029
- * Applies a new field name value to fielter and update both filter and dataset
1030
- * @param filter - to be applied the new field name on
1031
- * @param dataset - dataset the field belongs to
1032
- * @param fieldName - field.name
1033
- * @param filterDatasetIndex - field.name
1034
- * @param option
1035
- * @return - {filter, datasets}
1036
- */
1037
-
1038
-
1039
- function applyFilterFieldName(filter, dataset, fieldName) {
1040
- var filterDatasetIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
1041
- var option = arguments.length > 4 ? arguments[4] : undefined;
1042
- // using filterDatasetIndex we can filter only the specified dataset
1043
- var mergeDomain = option && option.hasOwnProperty('mergeDomain') ? option.mergeDomain : false;
1044
- var fieldIndex = dataset.getColumnFieldIdx(fieldName); // if no field with same name is found, move to the next datasets
1045
-
1046
- if (fieldIndex === -1) {
1047
- // throw new Error(`fieldIndex not found. Dataset must contain a property with name: ${fieldName}`);
1048
- return {
1049
- filter: null,
1050
- dataset: dataset
1051
- };
1052
- } // TODO: validate field type
1053
-
1054
-
1055
- var filterProps = dataset.getColumnFilterProps(fieldName);
1056
-
1057
- var newFilter = _objectSpread(_objectSpread({}, mergeDomain ? mergeFilterDomainStep(filter, filterProps) : _objectSpread(_objectSpread({}, filter), filterProps)), {}, {
1058
- name: Object.assign((0, _toConsumableArray2["default"])((0, _utils.toArray)(filter.name)), (0, _defineProperty2["default"])({}, filterDatasetIndex, fieldName)),
1059
- fieldIdx: Object.assign((0, _toConsumableArray2["default"])((0, _utils.toArray)(filter.fieldIdx)), (0, _defineProperty2["default"])({}, filterDatasetIndex, fieldIndex)),
1060
- // TODO, since we allow to add multiple fields to a filter we can no longer freeze the filter
1061
- freeze: true
1062
- });
1063
-
1064
- return {
1065
- filter: newFilter,
1066
- dataset: dataset
1067
- };
1068
- }
1069
- /**
1070
- * Merge one filter with other filter prop domain
1071
- */
1072
-
1073
- /* eslint-disable complexity */
1074
-
1075
-
1076
- function mergeFilterDomainStep(filter, filterProps) {
1077
- if (!filter) {
1078
- return null;
1079
- }
1080
-
1081
- if (!filterProps) {
1082
- return filter;
1083
- }
1084
-
1085
- if (filter.fieldType && filter.fieldType !== filterProps.fieldType || !filterProps.domain) {
1086
- return filter;
1087
- }
1088
-
1089
- var combinedDomain = !filter.domain ? filterProps.domain : [].concat((0, _toConsumableArray2["default"])(filter.domain || []), (0, _toConsumableArray2["default"])(filterProps.domain || [])).sort(function (a, b) {
1090
- return a - b;
1091
- });
1092
-
1093
- var newFilter = _objectSpread(_objectSpread(_objectSpread({}, filter), filterProps), {}, {
1094
- domain: [combinedDomain[0], combinedDomain[combinedDomain.length - 1]]
1095
- });
1096
-
1097
- switch (filterProps.fieldType) {
1098
- case _constants.ALL_FIELD_TYPES.string:
1099
- case _constants.ALL_FIELD_TYPES.date:
1100
- return _objectSpread(_objectSpread({}, newFilter), {}, {
1101
- domain: (0, _dataUtils.unique)(combinedDomain).sort()
1102
- });
1103
-
1104
- case _constants.ALL_FIELD_TYPES.timestamp:
1105
- var step = filter.step < filterProps.step ? filter.step : filterProps.step;
1106
- return _objectSpread(_objectSpread({}, newFilter), {}, {
1107
- step: step
1108
- });
1109
-
1110
- case _constants.ALL_FIELD_TYPES.real:
1111
- case _constants.ALL_FIELD_TYPES.integer:
1112
- default:
1113
- return newFilter;
1114
- }
1115
- }
1116
- /* eslint-enable complexity */
1117
-
1118
- /**
1119
- * Generates polygon filter
1120
- */
1121
-
1122
-
1123
- var featureToFilterValue = function featureToFilterValue(feature, filterId, properties) {
1124
- return _objectSpread(_objectSpread({}, feature), {}, {
1125
- id: feature.id,
1126
- properties: _objectSpread(_objectSpread(_objectSpread({}, feature.properties), properties), {}, {
1127
- filterId: filterId
1128
- })
1129
- });
1130
- };
1131
-
1132
- exports.featureToFilterValue = featureToFilterValue;
1133
-
1134
- var getFilterIdInFeature = function getFilterIdInFeature(f) {
1135
- return (0, _lodash["default"])(f, ['properties', 'filterId']);
1136
- };
1137
- /**
1138
- * Generates polygon filter
1139
- */
1140
-
1141
-
1142
- exports.getFilterIdInFeature = getFilterIdInFeature;
1143
-
1144
- function generatePolygonFilter(layers, feature) {
1145
- var dataId = layers.map(function (l) {
1146
- return l.config.dataId;
1147
- }).filter(_dataUtils.notNullorUndefined);
1148
- var layerId = layers.map(function (l) {
1149
- return l.id;
1150
- });
1151
- var name = layers.map(function (l) {
1152
- return l.config.label;
1153
- });
1154
- var filter = getDefaultFilter({
1155
- dataId: dataId
1156
- });
1157
- return _objectSpread(_objectSpread({}, filter), {}, {
1158
- fixedDomain: true,
1159
- type: _constants.FILTER_TYPES.polygon,
1160
- name: name,
1161
- layerId: layerId,
1162
- value: featureToFilterValue(feature, filter.id, {
1163
- isVisible: true
1164
- })
1165
- });
1166
- }
1167
- /**
1168
- * Run filter entirely on CPU
1169
- */
1170
-
1171
-
1172
- function filterDatasetCPU(state, dataId) {
1173
- var datasetFilters = state.filters.filter(function (f) {
1174
- return f.dataId.includes(dataId);
1175
- });
1176
- var dataset = state.datasets[dataId];
1177
-
1178
- if (!dataset) {
1179
- return state;
1180
- }
1181
-
1182
- var cpuFilteredDataset = dataset.filterTableCPU(datasetFilters, state.layers);
1183
- return (0, _utils.set)(['datasets', dataId], cpuFilteredDataset, state);
1184
- }
1185
- /**
1186
- * Validate parsed filters with datasets and add filterProps to field
1187
- */
1188
-
1189
-
1190
- function validateFiltersUpdateDatasets(state) {
1191
- var filtersToValidate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
1192
- // TODO Better Typings here
1193
- var validated = [];
1194
- var failed = [];
1195
- var datasets = state.datasets;
1196
- var updatedDatasets = datasets; // merge filters
1197
-
1198
- filtersToValidate.forEach(function (filter) {
1199
- // we can only look for datasets define in the filter dataId
1200
- var datasetIds = (0, _utils.toArray)(filter.dataId); // we can merge a filter only if all datasets in filter.dataId are loaded
1201
-
1202
- if (datasetIds.every(function (d) {
1203
- return datasets[d] && !state.isMergingDatasets[d];
1204
- })) {
1205
- // all datasetIds in filter must be present the state datasets
1206
- var _datasetIds$reduce = datasetIds.reduce(function (acc, datasetId) {
1207
- var dataset = updatedDatasets[datasetId];
1208
- var layers = state.layers.filter(function (l) {
1209
- return l.config.dataId === dataset.id;
1210
- });
1211
-
1212
- var _validateFilterWithDa = validateFilterWithData(acc.augmentedDatasets[datasetId] || dataset, filter, layers),
1213
- updatedFilter = _validateFilterWithDa.filter,
1214
- updatedDataset = _validateFilterWithDa.dataset;
1215
-
1216
- if (updatedFilter) {
1217
- return _objectSpread(_objectSpread({}, acc), {}, {
1218
- // merge filter props
1219
- filter: acc.filter ? _objectSpread(_objectSpread({}, acc.filter), mergeFilterDomainStep(acc.filter, updatedFilter)) : updatedFilter,
1220
- applyToDatasets: [].concat((0, _toConsumableArray2["default"])(acc.applyToDatasets), [datasetId]),
1221
- augmentedDatasets: _objectSpread(_objectSpread({}, acc.augmentedDatasets), {}, (0, _defineProperty2["default"])({}, datasetId, updatedDataset))
1222
- });
1223
- }
1224
-
1225
- return acc;
1226
- }, {
1227
- filter: null,
1228
- applyToDatasets: [],
1229
- augmentedDatasets: {}
1230
- }),
1231
- validatedFilter = _datasetIds$reduce.filter,
1232
- applyToDatasets = _datasetIds$reduce.applyToDatasets,
1233
- augmentedDatasets = _datasetIds$reduce.augmentedDatasets;
1234
-
1235
- if (validatedFilter && (0, _lodash2["default"])(datasetIds, applyToDatasets)) {
1236
- validated.push(validatedFilter);
1237
- updatedDatasets = _objectSpread(_objectSpread({}, updatedDatasets), augmentedDatasets);
1238
- } else {
1239
- failed.push(filter);
1240
- }
1241
- } else {
1242
- failed.push(filter);
1243
- }
1244
- });
1245
- return {
1246
- validated: validated,
1247
- failed: failed,
1248
- updatedDatasets: updatedDatasets
1249
- };
1250
- }
1251
-
1252
- function getFilterPlot(filter, dataset) {
1253
- if (filter.plotType === _constants.PLOT_TYPES.histogram || !filter.yAxis) {
1254
- // histogram should be calculated when create filter
1255
- return {};
1256
- }
1257
-
1258
- var _filter$mappedValue2 = filter.mappedValue,
1259
- mappedValue = _filter$mappedValue2 === void 0 ? [] : _filter$mappedValue2;
1260
- var yAxis = filter.yAxis;
1261
- var fieldIdx = dataset.getColumnFieldIdx(yAxis.name);
1262
-
1263
- if (fieldIdx < 0) {
1264
- _console["default"].warn("yAxis ".concat(yAxis.name, " does not exist in dataset"));
1265
-
1266
- return {
1267
- lineChart: {},
1268
- yAxis: yAxis
1269
- };
1270
- } // return lineChart
1271
-
1272
-
1273
- var series = dataset.dataContainer.map(function (row, rowIndex) {
1274
- return {
1275
- x: mappedValue[rowIndex],
1276
- y: row.valueAt(fieldIdx)
1277
- };
1278
- }, true).filter(function (_ref8) {
1279
- var x = _ref8.x,
1280
- y = _ref8.y;
1281
- return Number.isFinite(x) && Number.isFinite(y);
1282
- }).sort(function (a, b) {
1283
- return (0, _d3Array.ascending)(a.x, b.x);
1284
- });
1285
- var yDomain = (0, _d3Array.extent)(series, function (d) {
1286
- return d.y;
1287
- });
1288
- var xDomain = [series[0].x, series[series.length - 1].x];
1289
- return {
1290
- lineChart: {
1291
- series: series,
1292
- yDomain: yDomain,
1293
- xDomain: xDomain
1294
- },
1295
- yAxis: yAxis
1296
- };
1297
- }
1298
- /**
1299
- * Retrieve interval bins for time filter
1300
- */
1301
-
1302
-
1303
- function getIntervalBins(filter) {
1304
- var _filter$plotType;
1305
-
1306
- var bins = filter.bins;
1307
- var interval = (_filter$plotType = filter.plotType) === null || _filter$plotType === void 0 ? void 0 : _filter$plotType.interval;
1308
-
1309
- if (!interval || !bins || Object.keys(bins).length === 0) {
1310
- return null;
1311
- }
1312
-
1313
- var values = Object.values(bins);
1314
- return values[0] ? values[0][interval] : null;
1315
- }
1316
-
1317
- function isValidTimeDomain(domain) {
1318
- return Array.isArray(domain) && domain.every(Number.isFinite);
1319
- }
1320
-
1321
- function getTimeWidgetHintFormatter(domain) {
1322
- if (!isValidTimeDomain(domain)) {
1323
- return undefined;
1324
- }
1325
-
1326
- var diff = domain[1] - domain[0];
1327
- return diff > durationWeek ? 'L' : diff > durationDay ? 'L LT' : diff > durationHour ? 'LT' : 'LTS';
1328
- }
1329
-
1330
- function isSideFilter(filter) {
1331
- return filter.view === _constants.FILTER_VIEW_TYPES.side;
1332
- }
1333
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9maWx0ZXItdXRpbHMudHMiXSwibmFtZXMiOlsiZHVyYXRpb25TZWNvbmQiLCJkdXJhdGlvbk1pbnV0ZSIsImR1cmF0aW9uSG91ciIsImR1cmF0aW9uRGF5IiwiZHVyYXRpb25XZWVrIiwiZHVyYXRpb25ZZWFyIiwiVGltZXN0YW1wU3RlcE1hcCIsIm1heCIsInN0ZXAiLCJOdW1iZXIiLCJQT1NJVElWRV9JTkZJTklUWSIsImhpc3RvZ3JhbUJpbnMiLCJlbmxhcmdlZEhpc3RvZ3JhbUJpbnMiLCJGSUxURVJfVVBEQVRFUl9QUk9QUyIsImRhdGFJZCIsIm5hbWUiLCJsYXllcklkIiwiTElNSVRFRF9GSUxURVJfRUZGRUNUX1BST1BTIiwiU3VwcG9ydGVkUGxvdFR5cGUiLCJGSUxURVJfVFlQRVMiLCJ0aW1lUmFuZ2UiLCJBTExfRklFTERfVFlQRVMiLCJpbnRlZ2VyIiwicmVhbCIsInJhbmdlIiwiRklMVEVSX0NPTVBPTkVOVFMiLCJzZWxlY3QiLCJtdWx0aVNlbGVjdCIsInBvbHlnb24iLCJERUZBVUxUX0ZJTFRFUl9TVFJVQ1RVUkUiLCJmcmVlemUiLCJpZCIsImVuYWJsZWQiLCJmaXhlZERvbWFpbiIsInZpZXciLCJGSUxURVJfVklFV19UWVBFUyIsInNpZGUiLCJpc0FuaW1hdGluZyIsImFuaW1hdGlvbldpbmRvdyIsIkFOSU1BVElPTl9XSU5ET1ciLCJmcmVlIiwic3BlZWQiLCJ0eXBlIiwiZmllbGRJZHgiLCJkb21haW4iLCJ2YWx1ZSIsInBsb3RUeXBlIiwiUExPVF9UWVBFUyIsImhpc3RvZ3JhbSIsInlBeGlzIiwiaW50ZXJ2YWwiLCJncHUiLCJGSUxURVJfSURfTEVOR1RIIiwiTEFZRVJfRklMVEVSUyIsImdldERlZmF1bHRGaWx0ZXIiLCJzaG91bGRBcHBseUZpbHRlciIsImZpbHRlciIsImRhdGFzZXRJZCIsImRhdGFJZHMiLCJpbmNsdWRlcyIsInZhbGlkYXRlUG9seWdvbkZpbHRlciIsImRhdGFzZXQiLCJsYXllcnMiLCJmYWlsZWQiLCJpc1ZhbGlkRmlsdGVyVmFsdWUiLCJpc1ZhbGlkRGF0YXNldCIsImxheWVyIiwiZmluZCIsImwiLCJmaWx0ZXJWYWxpZGF0b3JzIiwidmFsaWRhdGVGaWx0ZXIiLCJmaWx0ZXJEYXRhSWQiLCJmaWx0ZXJEYXRhc2V0SW5kZXgiLCJpbmRleE9mIiwiaW5pdGlhbGl6ZUZpbHRlciIsImZpZWxkTmFtZSIsImFwcGx5RmlsdGVyRmllbGROYW1lIiwibWVyZ2VEb21haW4iLCJ1cGRhdGVkRmlsdGVyIiwidXBkYXRlZERhdGFzZXQiLCJhZGp1c3RWYWx1ZVRvRmlsdGVyRG9tYWluIiwidmFsaWRhdGVGaWx0ZXJZQXhpcyIsInZhbGlkYXRlRmlsdGVyV2l0aERhdGEiLCJoYXNPd25Qcm9wZXJ0eSIsImZpZWxkcyIsIm1hdGNoZWRBeGlzIiwiZ2V0RmlsdGVyUGxvdCIsImdldEZpbHRlclByb3BzIiwiZmllbGQiLCJmaWVsZERvbWFpbiIsImZpbHRlclByb3BzIiwiZmllbGRUeXBlIiwidHlwZU9wdGlvbnMiLCJzdHJpbmciLCJkYXRlIiwidGltZXN0YW1wIiwiZW5sYXJnZWQiLCJnZXRQb2x5Z29uRmlsdGVyRnVuY3RvciIsImRhdGFDb250YWluZXIiLCJnZXRQb3NpdGlvbiIsImdldFBvc2l0aW9uQWNjZXNzb3IiLCJMQVlFUl9UWVBFUyIsInBvaW50IiwiaWNvbiIsImRhdGEiLCJwb3MiLCJldmVyeSIsImlzRmluaXRlIiwiaXNJblBvbHlnb24iLCJhcmMiLCJsaW5lIiwiaGV4YWdvbklkIiwiZGF0YVRvRmVhdHVyZSIsImNlbnRyb2lkcyIsImNlbnRyb2lkIiwiaW5kZXgiLCJnZW9qc29uIiwiZ2V0RmlsdGVyRnVuY3Rpb24iLCJ2YWx1ZUFjY2Vzc29yIiwiZGVmYXVsdEZ1bmMiLCJkIiwiaXNJblJhbmdlIiwibWFwcGVkVmFsdWUiLCJhY2Nlc3NvciIsIkFycmF5IiwiaXNBcnJheSIsImZvcm1hdCIsImxlbmd0aCIsImxheWVyRmlsdGVyRnVuY3Rpb25zIiwibWFwIiwiY29uZmlnIiwiZmlsdGVyRnVuYyIsInVwZGF0ZUZpbHRlckRhdGFJZCIsImZpbHRlckRhdGFCeUZpbHRlclR5cGVzIiwiZHluYW1pY0RvbWFpbkZpbHRlcnMiLCJjcHVGaWx0ZXJzIiwiZmlsdGVyRnVuY3MiLCJmaWx0ZXJlZEluZGV4Rm9yRG9tYWluIiwiZmlsdGVyZWRJbmRleCIsImZpbHRlckNvbnRleHQiLCJmaWx0ZXJGdW5jQ2FsbGVyIiwibnVtUm93cyIsImkiLCJtYXRjaEZvckRvbWFpbiIsInB1c2giLCJtYXRjaEZvclJlbmRlciIsImdldEZpbHRlclJlY29yZCIsImZpbHRlcnMiLCJvcHQiLCJmaWx0ZXJSZWNvcmQiLCJkeW5hbWljRG9tYWluIiwiY3B1IiwiZm9yRWFjaCIsImYiLCJpZ25vcmVEb21haW4iLCJjcHVPbmx5IiwiZGlmZkZpbHRlcnMiLCJvbGRGaWx0ZXJSZWNvcmQiLCJmaWx0ZXJDaGFuZ2VkIiwiT2JqZWN0IiwiZW50cmllcyIsInJlY29yZCIsIml0ZW1zIiwib2xkRmlsdGVyIiwicHJvcCIsImZpbHRlcmVkVmFsdWUiLCJnZXROdW1lcmljRmllbGREb21haW4iLCJtYXBJbmRleCIsIlNjYWxlVXRpbHMiLCJnZXRMaW5lYXJEb21haW4iLCJkaWZmIiwiZ2V0TnVtZXJpY1N0ZXBTaXplIiwiZm9ybWF0TnVtYmVyQnlTdGVwIiwiZ2V0SGlzdG9ncmFtIiwiZW5sYXJnZWRIaXN0b2dyYW0iLCJNYXRoIiwiYWJzIiwieCIsImV4cG9uZW50aWFsRm9ybSIsInRvRXhwb25lbnRpYWwiLCJleHBvbmVudCIsInBhcnNlRmxvYXQiLCJzcGxpdCIsIkRlY2ltYWwiLCJwb3ciLCJ0b051bWJlciIsImdldFRpbWVzdGFtcEZpZWxkRG9tYWluIiwiZGVmYXVsdFRpbWVGb3JtYXQiLCJnZXRUaW1lV2lkZ2V0VGl0bGVGb3JtYXR0ZXIiLCJlbnRyeSIsImhpc3RvZ3JhbUNvbnN0cnVjdCIsImJpbnMiLCJ0aHJlc2hvbGRzIiwiYmluIiwiY291bnQiLCJ4MCIsIngxIiwidmFsIiwiYm91bmQiLCJmbG9vciIsImNlaWwiLCJpc1ZhbGlkVGltZURvbWFpbiIsImlzRmlsdGVyVmFsaWRUb1NhdmUiLCJ2IiwiaXNOYU4iLCJCb29sZWFuIiwiaW5wdXQiLCJjb29yZGluYXRlcyIsImdldENvbHVtbkZpbHRlclByb3BzIiwiZ2V0Q29sdW1uRmllbGRJZHgiLCJDb25zb2xlIiwid2FybiIsImxpbmVDaGFydCIsInNlcmllcyIsInJvdyIsInJvd0luZGV4IiwieSIsInZhbHVlQXQiLCJzb3J0IiwiYSIsImIiLCJ5RG9tYWluIiwieERvbWFpbiIsImdldERlZmF1bHRGaWx0ZXJQbG90VHlwZSIsImZpbHRlclBsb3RUeXBlcyIsImFwcGx5RmlsdGVyc1RvRGF0YXNldHMiLCJkYXRhc2V0SWRzIiwiZGF0YXNldHMiLCJyZWR1Y2UiLCJhY2MiLCJsYXllcnNUb0ZpbHRlciIsImFwcGxpZWRGaWx0ZXJzIiwidGFibGUiLCJmaWx0ZXJUYWJsZSIsIm9wdGlvbiIsImZpZWxkSW5kZXgiLCJuZXdGaWx0ZXIiLCJtZXJnZUZpbHRlckRvbWFpblN0ZXAiLCJhc3NpZ24iLCJjb21iaW5lZERvbWFpbiIsImZlYXR1cmVUb0ZpbHRlclZhbHVlIiwiZmVhdHVyZSIsImZpbHRlcklkIiwicHJvcGVydGllcyIsImdldEZpbHRlcklkSW5GZWF0dXJlIiwiZ2VuZXJhdGVQb2x5Z29uRmlsdGVyIiwibm90TnVsbG9yVW5kZWZpbmVkIiwibGFiZWwiLCJpc1Zpc2libGUiLCJmaWx0ZXJEYXRhc2V0Q1BVIiwic3RhdGUiLCJkYXRhc2V0RmlsdGVycyIsImNwdUZpbHRlcmVkRGF0YXNldCIsImZpbHRlclRhYmxlQ1BVIiwidmFsaWRhdGVGaWx0ZXJzVXBkYXRlRGF0YXNldHMiLCJmaWx0ZXJzVG9WYWxpZGF0ZSIsInZhbGlkYXRlZCIsInVwZGF0ZWREYXRhc2V0cyIsImlzTWVyZ2luZ0RhdGFzZXRzIiwiYXVnbWVudGVkRGF0YXNldHMiLCJhcHBseVRvRGF0YXNldHMiLCJ2YWxpZGF0ZWRGaWx0ZXIiLCJnZXRJbnRlcnZhbEJpbnMiLCJrZXlzIiwidmFsdWVzIiwiZ2V0VGltZVdpZGdldEhpbnRGb3JtYXR0ZXIiLCJ1bmRlZmluZWQiLCJpc1NpZGVGaWx0ZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBR0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBU0E7O0FBQ0E7O0FBdUJBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVPLElBQU1BLGNBQWMsR0FBRyxJQUF2Qjs7QUFDQSxJQUFNQyxjQUFjLEdBQUdELGNBQWMsR0FBRyxFQUF4Qzs7QUFDQSxJQUFNRSxZQUFZLEdBQUdELGNBQWMsR0FBRyxFQUF0Qzs7QUFDQSxJQUFNRSxXQUFXLEdBQUdELFlBQVksR0FBRyxFQUFuQzs7QUFDQSxJQUFNRSxZQUFZLEdBQUdELFdBQVcsR0FBRyxDQUFuQzs7QUFDQSxJQUFNRSxZQUFZLEdBQUdGLFdBQVcsR0FBRyxHQUFuQzs7QUFnQkEsSUFBTUcsZ0JBQWdCLEdBQUcsQ0FDOUI7QUFBQ0MsRUFBQUEsR0FBRyxFQUFFLENBQU47QUFBU0MsRUFBQUEsSUFBSSxFQUFFO0FBQWYsQ0FEOEIsRUFFOUI7QUFBQ0QsRUFBQUEsR0FBRyxFQUFFLEVBQU47QUFBVUMsRUFBQUEsSUFBSSxFQUFFO0FBQWhCLENBRjhCLEVBRzlCO0FBQUNELEVBQUFBLEdBQUcsRUFBRSxHQUFOO0FBQVdDLEVBQUFBLElBQUksRUFBRTtBQUFqQixDQUg4QixFQUk5QjtBQUFDRCxFQUFBQSxHQUFHLEVBQUUsR0FBTjtBQUFXQyxFQUFBQSxJQUFJLEVBQUU7QUFBakIsQ0FKOEIsRUFLOUI7QUFBQ0QsRUFBQUEsR0FBRyxFQUFFLElBQU47QUFBWUMsRUFBQUEsSUFBSSxFQUFFO0FBQWxCLENBTDhCLEVBTTlCO0FBQUNELEVBQUFBLEdBQUcsRUFBRSxJQUFOO0FBQVlDLEVBQUFBLElBQUksRUFBRTtBQUFsQixDQU44QixFQU85QjtBQUFDRCxFQUFBQSxHQUFHLEVBQUVFLE1BQU0sQ0FB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RUQsTUFBTWhHLElBQUksR0FBRzlILE1BQU0sQ0FBQyxDQUFELENBQU4sR0FBWUEsTUFBTSxDQUFDLENBQUQsQ0FBL0I7QUFDQSxTQUFPOEgsSUFBSSxHQUFHdEssWUFBUCxHQUNILEdBREcsR0FFSHNLLElBQUksR0FBR3ZLLFdBQVAsR0FDQSxNQURBLEdBRUF1SyxJQUFJLEdBQUd4SyxZQUFQLEdBQ0EsSUFEQSxHQUVBLEtBTko7QUFPRDs7QUFFTSxTQUFTeVEsWUFBVCxDQUFzQm5OLE1BQXRCLEVBQStDO0FBQ3BELFNBQU9BLE1BQU0sQ0FBQ3RCLElBQVAsS0FBZ0JDLDZCQUFrQkMsSUFBekM7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbmltcG9ydCB7YXNjZW5kaW5nLCBleHRlbnQsIGhpc3RvZ3JhbSBhcyBkM0hpc3RvZ3JhbSwgdGlja3N9IGZyb20gJ2QzLWFycmF5JztcbmltcG9ydCBrZXlNaXJyb3IgZnJvbSAna2V5bWlycm9yJztcbmltcG9ydCBDb25zb2xlIGZyb20gJ2dsb2JhbC9jb25zb2xlJztcbmltcG9ydCBnZXQgZnJvbSAnbG9kYXNoLmdldCc7XG5pbXBvcnQgaXNFcXVhbCBmcm9tICdsb2Rhc2guaXNlcXVhbCc7XG5cbmltcG9ydCBib29sZWFuV2l0aGluIGZyb20gJ0B0dXJmL2Jvb2xlYW4td2l0aGluJztcbmltcG9ydCB7cG9pbnQgYXMgdHVyZlBvaW50fSBmcm9tICdAdHVyZi9oZWxwZXJzJztcbmltcG9ydCB7RGVjaW1hbH0gZnJvbSAnZGVjaW1hbC5qcyc7XG5pbXBvcnQge1xuICBBTExfRklFTERfVFlQRVMsXG4gIEZJTFRFUl9UWVBFUyxcbiAgQU5JTUFUSU9OX1dJTkRPVyxcbiAgUExPVF9UWVBFUyxcbiAgTEFZRVJfVFlQRVMsXG4gIEZJTFRFUl9WSUVXX1RZUEVTXG59IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcbmltcG9ydCB7VmlzU3RhdGV9IGZyb20gJ0BrZXBsZXIuZ2wvc2NoZW1hcyc7XG5pbXBvcnQgKiBhcyBTY2FsZVV0aWxzIGZyb20gJy4vZGF0YS1zY2FsZS11dGlscyc7XG5pbXBvcnQge2gzSXNWYWxpZH0gZnJvbSAnaDMtanMnO1xuXG5pbXBvcnQge1xuICBNaWxsaXNlY29uZCxcbiAgRW50cmllcyxcbiAgRmllbGQsXG4gIFBhcnNlZEZpbHRlcixcbiAgRmlsdGVyLFxuICBGaWx0ZXJCYXNlLFxuICBQb2x5Z29uRmlsdGVyLFxuICBGaWVsZERvbWFpbixcbiAgVGltZVJhbmdlRmllbGREb21haW4sXG4gIEhpc3RvZ3JhbUJpbixcbiAgRmVhdHVyZSxcbiAgRmVhdHVyZVZhbHVlLFxuICBMaW5lQ2hhcnQsXG4gIFRpbWVSYW5nZUZpbHRlcixcbiAgUmFuZ2VGaWVsZERvbWFpbixcbiAgRmlsdGVyRGF0YXNldE9wdCxcbiAgRmlsdGVyUmVjb3JkXG59IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuXG5pbXBvcnQge0RhdGFDb250YWluZXJJbnRlcmZhY2V9IGZyb20gJy4vZGF0YS1jb250YWluZXItaW50ZXJmYWNlJztcbmltcG9ydCB7Z2VuZXJhdGVIYXNoSWQsIHNldCwgdG9BcnJheX0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQge25vdE51bGxvclVuZGVmaW5lZCwgdGltZVRvVW5peE1pbGxpLCB1bmlxdWV9IGZyb20gJy4vZGF0YS11dGlscyc7XG5pbXBvcnQge2dldENlbnRyb2lkfSBmcm9tICcuL2gzLXV0aWxzJztcblxuZXhwb3J0IGNvbnN0IGR1cmF0aW9uU2Vjb25kID0gMTAwMDtcbmV4cG9ydCBjb25zdCBkdXJhdGlvbk1pbnV0ZSA9IGR1cmF0aW9uU2Vjb25kICogNjA7XG5leHBvcnQgY29uc3QgZHVyYXRpb25Ib3VyID0gZHVyYXRpb25NaW51dGUgKiA2MDtcbmV4cG9ydCBjb25zdCBkdXJhdGlvbkRheSA9IGR1cmF0aW9uSG91ciAqIDI0O1xuZXhwb3J0IGNvbnN0IGR1cmF0aW9uV2VlayA9IGR1cmF0aW9uRGF5ICogNztcbmV4cG9ydCBjb25zdCBkdXJhdGlvblllYXIgPSBkdXJhdGlvbkRheSAqIDM2NTtcblxuZXhwb3J0IHR5cGUgRmlsdGVyUmVzdWx0ID0ge1xuICBmaWx0ZXJlZEluZGV4Rm9yRG9tYWluPzogbnVtYmVyW107XG4gIGZpbHRlcmVkSW5kZXg/OiBudW1iZXJbXTtcbn07XG5cbmV4cG9ydCB0eXBlIEZpbHRlckNoYW5nZWQgPSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICBba2V5IGluIGtleW9mIEZpbHRlclJlY29yZF06IHtcbiAgICBba2V5OiBzdHJpbmddOiAnYWRkZWQnIHwgJ2RlbGV0ZWQnIHwgJ25hbWVfY2hhbmdlZCcgfCAndmFsdWVfY2hhbmdlZCcgfCAnZGF0YUlkX2NoYW5nZWQnO1xuICB9IHwgbnVsbDtcbn07XG5cbmV4cG9ydCB0eXBlIGRhdGFWYWx1ZUFjY2Vzc29yID0gKGRhdGE6IHtpbmRleDogbnVtYmVyfSkgPT4gbnVtYmVyIHwgbnVsbDtcblxuZXhwb3J0IGNvbnN0IFRpbWVzdGFtcFN0ZXBNYXAgPSBbXG4gIHttYXg6IDEsIHN0ZXA6IDAuMDV9LFxuICB7bWF4OiAxMCwgc3RlcDogMC4xfSxcbiAge21heDogMTAwLCBzdGVwOiAxfSxcbiAge21heDogNTAwLCBzdGVwOiA1fSxcbiAge21heDogMTAwMCwgc3RlcDogMTB9LFxuICB7bWF4OiA1MDAwLCBzdGVwOiA1MH0sXG4gIHttYXg6IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSwgc3RlcDogMTAwMH1cbl07XG5cbmV4cG9ydCBjb25zdCBoaXN0b2dyYW1CaW5zID0gMzA7XG5leHBvcnQgY29uc3QgZW5sYXJnZWRIaXN0b2dyYW1CaW5zID0gMTAwO1xuXG5leHBvcnQgY29uc3QgRklMVEVSX1VQREFURVJfUFJPUFMgPSBrZXlNaXJyb3Ioe1xuICBkYXRhSWQ6IG51bGwsXG4gIG5hbWU6IG51bGwsXG4gIGxheWVySWQ6IG51bGxcbn0pO1xuXG5leHBvcnQgY29uc3QgTElNSVRFRF9GSUxURVJfRUZGRUNUX1BST1BTID0ga2V5TWlycm9yKHtcbiAgW0ZJTFRFUl9VUERBVEVSX1BST1BTLm5hbWVdOiBudWxsXG59KTtcbi8qKlxuICogTWF4IG51bWJlciBvZiBmaWx0ZXIgdmFsdWUgYnVmZmVycyB0aGF0IGRlY2suZ2wgcHJvdmlkZXNcbiAqL1xuXG5jb25zdCBTdXBwb3J0ZWRQbG90VHlwZSA9IHtcbiAgW0ZJTFRFUl9UWVBFUy50aW1lUmFuZ2VdOiB7XG4gICAgZGVmYXVsdDogJ2hpc3RvZ3JhbScsXG4gICAgW0FMTF9GSUVMRF9UWVBFUy5pbnRlZ2VyXTogJ2xpbmVDaGFydCcsXG4gICAgW0FMTF9GSUVMRF9UWVBFUy5yZWFsXTogJ2xpbmVDaGFydCdcbiAgfSxcbiAgW0ZJTFRFUl9UWVBFUy5yYW5nZV06IHtcbiAgICBkZWZhdWx0OiAnaGlzdG9ncmFtJyxcbiAgICBbQUxMX0ZJRUxEX1RZUEVTLmludGVnZXJdOiAnbGluZUNoYXJ0JyxcbiAgICBbQUxMX0ZJRUxEX1RZUEVTLnJlYWxdOiAnbGluZUNoYXJ0J1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgRklMVEVSX0NPTVBPTkVOVFMgPSB7XG4gIFtGSUxURVJfVFlQRVMuc2VsZWN0XTogJ1NpbmdsZVNlbGVjdEZpbHRlcicsXG4gIFtGSUxURVJfVFlQRVMubXVsdGlTZWxlY3RdOiAnTXVsdGlTZWxlY3RGaWx0ZXInLFxuICBbRklMVEVSX1RZUEVTLnRpbWVSYW5nZV06ICdUaW1lUmFuZ2VGaWx0ZXInLFxuICBbRklMVEVSX1RZUEVTLnJhbmdlXTogJ1JhbmdlRmlsdGVyJyxcbiAgW0ZJTFRFUl9UWVBFUy5wb2x5Z29uXTogJ1BvbHlnb25GaWx0ZXInXG59O1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9GSUxURVJfU1RSVUNUVVJFID0ge1xuICBkYXRhSWQ6IFtdLCAvLyBbc3RyaW5nXVxuICBmcmVlemU6IGZhbHNlLFxuICBpZDogbnVsbCxcbiAgZW5hYmxlZDogdHJ1ZSxcblxuICAvLyB0aW1lIHJhbmdlIGZpbHRlciBzcGVjaWZpY1xuICBmaXhlZERvbWFpbjogZmFsc2UsXG4gIHZpZXc6IEZJTFRFUl9WSUVXX1RZUEVTLnNpZGUsXG4gIGlzQW5pbWF0aW5nOiBmYWxzZSxcbiAgYW5pbWF0aW9uV2luZG93OiBBTklNQVRJT05fV0lORE9XLmZyZWUsXG4gIHNwZWVkOiAxLFxuXG4gIC8vIGZpZWxkIHNwZWNpZmljXG4gIG5hbWU6IFtdLCAvLyBzdHJpbmdcbiAgdHlwZTogbnVsbCxcbiAgZmllbGRJZHg6IFtdLCAvLyBbaW50ZWdlcl1cbiAgZG9tYWluOiBudWxsLFxuICB2YWx1ZTogbnVsbCxcblxuICAvLyBwbG90XG4gIHBsb3RUeXBlOiBQTE9UX1RZUEVTLmhpc3RvZ3JhbSxcbiAgeUF4aXM6IG51bGwsXG4gIGludGVydmFsOiBudWxsLFxuXG4gIC8vIG1vZGVcbiAgZ3B1OiBmYWxzZVxufTtcblxuZXhwb3J0IGNvbnN0IEZJTFRFUl9JRF9MRU5HVEggPSA0O1xuXG5leHBvcnQgY29uc3QgTEFZRVJfRklMVEVSUyA9IFtGSUxURVJfVFlQRVMucG9seWdvbl07XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgZmlsdGVyIHdpdGggYSBkYXRhc2V0IGlkIGFzIGRhdGFJZFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVmYXVsdEZpbHRlcih7XG4gIGRhdGFJZCxcbiAgaWRcbn06IHtcbiAgZGF0YUlkPzogc3RyaW5nIHwgbnVsbCB8IHN0cmluZ1tdO1xuICBpZD86IHN0cmluZztcbn0gPSB7fSk6IEZpbHRlckJhc2U8TGluZUNoYXJ0PiB7XG4gIHJldHVybiB7XG4gICAgLi4uREVGQVVMVF9GSUxURVJfU1RSVUNUVVJFLFxuICAgIC8vIHN0b3JlIGl0IGFzIGRhdGFJZCBhbmQgaXQgY291bGQgYmUgb25lIG9yIG1hbnlcbiAgICBkYXRhSWQ6IGRhdGFJZCA/IHRvQXJyYXkoZGF0YUlkKSA6IFtdLFxuICAgIGlkOiBpZCB8fCBnZW5lcmF0ZUhhc2hJZChGSUxURVJfSURfTEVOR1RIKVxuICB9O1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgZmlsdGVyIGlzIHZhbGlkIGJhc2VkIG9uIHRoZSBnaXZlbiBkYXRhSWRcbiAqIEBwYXJhbSAgZmlsdGVyIHRvIHZhbGlkYXRlXG4gKiBAcGFyYW0gIGRhdGFzZXRJZCBpZCB0byB2YWxpZGF0ZSBmaWx0ZXIgYWdhaW5zdFxuICogQHJldHVybiB0cnVlIGlmIGEgZmlsdGVyIGlzIHZhbGlkLCBmYWxzZSBvdGhlcndpc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNob3VsZEFwcGx5RmlsdGVyKGZpbHRlcjogRmlsdGVyLCBkYXRhc2V0SWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBkYXRhSWRzID0gdG9BcnJheShmaWx0ZXIuZGF0YUlkKTtcbiAgcmV0dXJuIGRhdGFJZHMuaW5jbHVkZXMoZGF0YXNldElkKSAmJiBmaWx0ZXIudmFsdWUgIT09IG51bGw7XG59XG5cbmludGVyZmFjZSBLZXBsZXJUYWJsZU1vZGVsPEssIEw+IHtcbiAgaWQ6IHN0cmluZztcbiAgZ2V0Q29sdW1uRmllbGRJZHgoY29sdW1uTmFtZTogc3RyaW5nKTogbnVtYmVyO1xuICBmaWx0ZXJUYWJsZShmaWx0ZXJzOiBGaWx0ZXJbXSwgbGF5ZXJzOiBMW10sIG9wdD86IEZpbHRlckRhdGFzZXRPcHQpOiBLO1xuICBnZXRDb2x1bW5GaWx0ZXJQcm9wcyhjb2x1bW5OYW1lOiBzdHJpbmcpOiBGaWVsZFsnZmlsdGVyUHJvcHMnXSB8IG51bGwgfCB1bmRlZmluZWQ7XG4gIGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2U7XG4gIGZpbHRlclRhYmxlQ1BVKGZpbHRlcnM6IEZpbHRlcltdLCBsYXllcnM6IExbXSk6IEs7XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIGFuZCBtb2RpZmllcyBwb2x5Z29uIGZpbHRlciBzdHJ1Y3R1cmVcbiAqIEBwYXJhbSBkYXRhc2V0XG4gKiBAcGFyYW0gZmlsdGVyXG4gKiBAcGFyYW0gbGF5ZXJzXG4gKiBAcmV0dXJuIC0ge2ZpbHRlciwgZGF0YXNldH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlUG9seWdvbkZpbHRlcjxLIGV4dGVuZHMgS2VwbGVyVGFibGVNb2RlbDxLLCBMPiwgTCBleHRlbmRzIHtpZDogc3RyaW5nfT4oXG4gIGRhdGFzZXQ6IEssXG4gIGZpbHRlcjogUG9seWdvbkZpbHRlcixcbiAgbGF5ZXJzOiBMW11cbik6IHtmaWx0ZXI6IFBvbHlnb25GaWx0ZXIgfCBudWxsOyBkYXRhc2V0OiBLfSB7XG4gIGNvbnN0IGZhaWxlZCA9IHtkYXRhc2V0LCBmaWx0ZXI6IG51bGx9O1xuICBjb25zdCB7dmFsdWUsIGxheWVySWQsIHR5cGUsIGRhdGFJZH0gPSBmaWx0ZXI7XG5cbiAgaWYgKCFsYXllcklkIHx8ICFpc1ZhbGlkRmlsdGVyVmFsdWUodHlwZSwgdmFsdWUpKSB7XG4gICAgcmV0dXJuIGZhaWxlZDtcbiAgfVxuXG4gIGNvbnN0IGlzVmFsaWREYXRhc2V0ID0gZGF0YUlkLmluY2x1ZGVzKGRhdGFzZXQuaWQpO1xuXG4gIGlmICghaXNWYWxpZERhdGFzZXQpIHtcbiAgICByZXR1cm4gZmFpbGVkO1xuICB9XG5cbiAgY29uc3QgbGF5ZXIgPSBsYXllcnMuZmluZChsID0+IGxheWVySWQuaW5jbHVkZXMobC5pZCkpO1xuXG4gIGlmICghbGF5ZXIpIHtcbiAgICByZXR1cm4gZmFpbGVkO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBmaWx0ZXI6IHtcbiAgICAgIC4uLmZpbHRlcixcbiAgICAgIGZyZWV6ZTogdHJ1ZSxcbiAgICAgIGZpZWxkSWR4OiBbXVxuICAgIH0sXG4gICAgZGF0YXNldFxuICB9O1xufVxuXG4vKipcbiAqIEN1c3RvbSBmaWx0ZXIgdmFsaWRhdG9yc1xuICovXG5jb25zdCBmaWx0ZXJWYWxpZGF0b3JzID0ge1xuICBbRklMVEVSX1RZUEVTLnBvbHlnb25dOiB2YWxpZGF0ZVBvbHlnb25GaWx0ZXJcbn07XG5cbi8qKlxuICogRGVmYXVsdCB2YWxpZGF0ZSBmaWx0ZXIgZnVuY3Rpb25cbiAqIEBwYXJhbSBkYXRhc2V0XG4gKiBAcGFyYW0gZmlsdGVyXG4gKiBAcmV0dXJuIC0ge2ZpbHRlciwgZGF0YXNldH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlRmlsdGVyPEsgZXh0ZW5kcyBLZXBsZXJUYWJsZU1vZGVsPEssIEw+LCBMPihcbiAgZGF0YXNldDogSyxcbiAgZmlsdGVyOiBQYXJzZWRGaWx0ZXJcbik6IHtmaWx0ZXI6IEZpbHRlciB8IG51bGw7IGRhdGFzZXQ6IEt9IHtcbiAgLy8gbWF0Y2ggZmlsdGVyLmRhdGFJZFxuICBjb25zdCBmYWlsZWQgPSB7ZGF0YXNldCwgZmlsdGVyOiBudWxsfTtcbiAgY29uc3QgZmlsdGVyRGF0YUlkID0gdG9BcnJheShmaWx0ZXIuZGF0YUlkKTtcblxuICBjb25zdCBmaWx0ZXJEYXRhc2V0SW5kZXggPSBmaWx0ZXJEYXRhSWQuaW5kZXhPZihkYXRhc2V0LmlkKTtcbiAgaWYgKGZpbHRlckRhdGFzZXRJbmRleCA8IDAgfHwgIXRvQXJyYXkoZmlsdGVyLm5hbWUpW2ZpbHRlckRhdGFzZXRJbmRleF0pIHtcbiAgICAvLyB0aGUgY3VycmVudCBmaWx0ZXIgaXMgbm90IG1hcHBlZCBhZ2FpbnN0IHRoZSBjdXJyZW50IGRhdGFzZXRcbiAgICByZXR1cm4gZmFpbGVkO1xuICB9XG5cbiAgY29uc3QgaW5pdGlhbGl6ZUZpbHRlcjogRmlsdGVyID0ge1xuICAgIC4uLmdldERlZmF1bHRGaWx0ZXIoe2RhdGFJZDogZmlsdGVyLmRhdGFJZH0pLFxuICAgIC4uLmZpbHRlcixcbiAgICBkYXRhSWQ6IGZpbHRlckRhdGFJZCxcbiAgICBuYW1lOiB0b0FycmF5KGZpbHRlci5uYW1lKVxuICB9O1xuXG4gIGNvbnN0IGZpZWxkTmFtZSA9IGluaXRpYWxpemVGaWx0ZXIubmFtZVtmaWx0ZXJEYXRhc2V0SW5kZXhdO1xuICBjb25zdCB7ZmlsdGVyOiB1cGRhdGVkRmlsdGVyLCBkYXRhc2V0OiB1cGRhdGVkRGF0YXNldH0gPSBhcHBseUZpbHRlckZpZWxkTmFtZShcbiAgICBpbml0aWFsaXplRmlsdGVyLFxuICAgIGRhdGFzZXQsXG4gICAgZmllbGROYW1lLFxuICAgIGZpbHRlckRhdGFzZXRJbmRleCxcbiAgICB7bWVyZ2VEb21haW46IHRydWV9XG4gICk7XG5cbiAgaWYgKCF1cGRhdGVkRmlsdGVyKSB7XG4gICAgcmV0dXJuIGZhaWxlZDtcbiAgfVxuXG4gIHVwZGF0ZWRGaWx0ZXIudmFsdWUgPSBhZGp1c3RWYWx1ZVRvRmlsdGVyRG9tYWluKGZpbHRlci52YWx1ZSwgdXBkYXRlZEZpbHRlcik7XG4gIHVwZGF0ZWRGaWx0ZXIudmlldyA9IGZpbHRlci52aWV3ID8/IHVwZGF0ZWRGaWx0ZXIudmlldztcblxuICBpZiAodXBkYXRlZEZpbHRlci52YWx1ZSA9PT0gbnVsbCkge1xuICAgIC8vIGNhbm5vdCBhZGp1c3Qgc2F2ZWQgdmFsdWUgdG8gZmlsdGVyXG4gICAgcmV0dXJuIGZhaWxlZDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZmlsdGVyOiB2YWxpZGF0ZUZpbHRlcllBeGlzKHVwZGF0ZWRGaWx0ZXIsIHVwZGF0ZWREYXRhc2V0KSxcbiAgICBkYXRhc2V0OiB1cGRhdGVkRGF0YXNldFxuICB9O1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIHNhdmVkIGZpbHRlciBjb25maWcgd2l0aCBuZXcgZGF0YSxcbiAqIGNhbGN1bGF0ZSBkb21haW4gYW5kIGZpZWxkSWR4IGJhc2VkIG5ldyBmaWVsZHMgYW5kIGRhdGFcbiAqXG4gKiBAcGFyYW0gZGF0YXNldFxuICogQHBhcmFtIGZpbHRlciAtIGZpbHRlciB0byBiZSB2YWxpZGF0ZVxuICogQHBhcmFtIGxheWVycyAtIGxheWVyc1xuICogQHJldHVybiB2YWxpZGF0ZWQgZmlsdGVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUZpbHRlcldpdGhEYXRhPEsgZXh0ZW5kcyBLZXBsZXJUYWJsZU1vZGVsPEssIEw+LCBMPihcbiAgZGF0YXNldDogSyxcbiAgZmlsdGVyOiBQYXJzZWRGaWx0ZXIsXG4gIGxheWVyczogTFtdXG4pOiB7ZmlsdGVyOiBGaWx0ZXI7IGRhdGFzZXQ6IEt9IHtcbiAgcmV0dXJuIGZpbHRlci50eXBlICYmIGZpbHRlclZhbGlkYXRvcnMuaGFzT3duUHJvcGVydHkoZmlsdGVyLnR5cGUpXG4gICAgPyBmaWx0ZXJWYWxpZGF0b3JzW2ZpbHRlci50eXBlXShkYXRhc2V0LCBmaWx0ZXIsIGxheWVycylcbiAgICA6IHZhbGlkYXRlRmlsdGVyKGRhdGFzZXQsIGZpbHRlcik7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgWUF4aXNcbiAqIEBwYXJhbSBmaWx0ZXJcbiAqIEBwYXJhbSBkYXRhc2V0XG4gKiBAcmV0dXJuIHsqfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUZpbHRlcllBeGlzKGZpbHRlciwgZGF0YXNldCkge1xuICAvLyBUT0RPOiB2YWxpZGF0ZSB5QXhpcyBhZ2FpbnN0IG90aGVyIGRhdGFzZXRzXG5cbiAgY29uc3Qge2ZpZWxkc30gPSBkYXRhc2V0O1xuICBjb25zdCB7eUF4aXN9ID0gZmlsdGVyO1xuICAvLyBUT0RPOiB2YWxpZGF0ZSB5QXhpcyBhZ2FpbnN0IG90aGVyIGRhdGFzZXRzXG4gIGlmICh5QXhpcykge1xuICAgIGNvbnN0IG1hdGNoZWRBeGlzID0gZmllbGRzLmZpbmQoKHtuYW1lLCB0eXBlfSkgPT4gbmFtZSA9PT0geUF4aXMubmFtZSAmJiB0eXBlID09PSB5QXhpcy50eXBlKTtcblxuICAgIGZpbHRlciA9IG1hdGNoZWRBeGlzXG4gICAgICA/IHtcbiAgICAgICAgICAuLi5maWx0ZXIsXG4gICAgICAgICAgeUF4aXM6IG1hdGNoZWRBeGlzLFxuICAgICAgICAgIC4uLmdldEZpbHRlclBsb3Qoey4uLmZpbHRlciwgeUF4aXM6IG1hdGNoZWRBeGlzfSwgZGF0YXNldClcbiAgICAgICAgfVxuICAgICAgOiBmaWx0ZXI7XG4gIH1cblxuICByZXR1cm4gZmlsdGVyO1xufVxuXG4vKipcbiAqIEdldCBkZWZhdWx0IGZpbHRlciBwcm9wIGJhc2VkIG9uIGZpZWxkIHR5cGVcbiAqXG4gKiBAcGFyYW0gZmllbGRcbiAqIEBwYXJhbSBmaWVsZERvbWFpblxuICogQHJldHVybnMgZGVmYXVsdCBmaWx0ZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZpbHRlclByb3BzKFxuICBmaWVsZDogRmllbGQsXG4gIGZpZWxkRG9tYWluOiBGaWVsZERvbWFpblxuKTogUGFydGlhbDxGaWx0ZXI+ICYge2ZpZWxkVHlwZTogc3RyaW5nfSB7XG4gIGNvbnN0IGZpbHRlclByb3BzID0ge1xuICAgIC4uLmZpZWxkRG9tYWluLFxuICAgIGZpZWxkVHlwZTogZmllbGQudHlwZSxcbiAgICB2aWV3OiBGSUxURVJfVklFV19UWVBFUy5zaWRlXG4gIH07XG5cbiAgc3dpdGNoIChmaWVsZC50eXBlKSB7XG4gICAgY2FzZSBBTExfRklFTERfVFlQRVMucmVhbDpcbiAgICBjYXNlIEFMTF9GSUVMRF9UWVBFUy5pbnRlZ2VyOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uZmlsdGVyUHJvcHMsXG4gICAgICAgIHZhbHVlOiBmaWVsZERvbWFpbi5kb21haW4sXG4gICAgICAgIHR5cGU6IEZJTFRFUl9UWVBFUy5yYW5nZSxcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICB0eXBlT3B0aW9uczogW0ZJTFRFUl9UWVBFUy5yYW5nZV0sXG4gICAgICAgIGdwdTogdHJ1ZVxuICAgICAgfTtcblxuICAgIGNhc2UgQUxMX0ZJRUxEX1RZUEVTLmJvb2xlYW46XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5maWx0ZXJQcm9wcyxcbiAgICAgICAgdHlwZTogRklMVEVSX1RZUEVTLnNlbGVjdCxcbiAgICAgICAgdmFsdWU6IHRydWUsXG4gICAgICAgIGdwdTogZmFsc2VcbiAgICAgIH07XG5cbiAgICBjYXNlIEFMTF9GSUVMRF9UWVBFUy5zdHJpbmc6XG4gICAgY2FzZSBBTExfRklFTERfVFlQRVMuZGF0ZTpcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmZpbHRlclByb3BzLFxuICAgICAgICB0eXBlOiBGSUxURVJfVFlQRVMubXVsdGlTZWxlY3QsXG4gICAgICAgIHZhbHVlOiBbXSxcbiAgICAgICAgZ3B1OiBmYWxzZVxuICAgICAgfTtcblxuICAgIGNhc2UgQUxMX0ZJRUxEX1RZUEVTLnRpbWVzdGFtcDpcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmZpbHRlclByb3BzLFxuICAgICAgICB0eXBlOiBGSUxURVJfVFlQRVMudGltZVJhbmdlLFxuICAgICAgICB2aWV3OiBGSUxURVJfVklFV19UWVBFUy5lbmxhcmdlZCxcbiAgICAgICAgZml4ZWREb21haW46IHRydWUsXG4gICAgICAgIHZhbHVlOiBmaWx0ZXJQcm9wcy5kb21haW4sXG4gICAgICAgIGdwdTogdHJ1ZVxuICAgICAgfTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICByZXR1cm4ge307XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGdldFBvbHlnb25GaWx0ZXJGdW5jdG9yID0gKGxheWVyLCBmaWx0ZXIsIGRhdGFDb250YWluZXIpID0+IHtcbiAgY29uc3QgZ2V0UG9zaXRpb24gPSBsYXllci5nZXRQb3NpdGlvbkFjY2Vzc29yKGRhdGFDb250YWluZXIpO1xuXG4gIHN3aXRjaCAobGF5ZXIudHlwZSkge1xuICAgIGNhc2UgTEFZRVJfVFlQRVMucG9pbnQ6XG4gICAgY2FzZSBMQVlFUl9UWVBFUy5pY29uOlxuICAgICAgcmV0dXJuIGRhdGEgPT4ge1xuICAgICAgICBjb25zdCBwb3MgPSBnZXRQb3NpdGlvbihkYXRhKTtcbiAgICAgICAgcmV0dXJuIHBvcy5ldmVyeShOdW1iZXIuaXNGaW5pdGUpICYmIGlzSW5Qb2x5Z29uKHBvcywgZmlsdGVyLnZhbHVlKTtcbiAgICAgIH07XG4gICAgY2FzZSBMQVlFUl9UWVBFUy5hcmM6XG4gICAgY2FzZSBMQVlFUl9UWVBFUy5saW5lOlxuICAgICAgcmV0dXJuIGRhdGEgPT4ge1xuICAgICAgICBjb25zdCBwb3MgPSBnZXRQb3NpdGlvbihkYXRhKTtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICBwb3MuZXZlcnkoTnVtYmVyLmlzRmluaXRlKSAmJlxuICAgICAgICAgIFtcbiAgICAgICAgICAgIFtwb3NbMF0sIHBvc1sxXV0sXG4gICAgICAgICAgICBbcG9zWzNdLCBwb3NbNF1dXG4gICAgICAgICAgXS5ldmVyeShwb2ludCA9PiBpc0luUG9seWdvbihwb2ludCwgZmlsdGVyLnZhbHVlKSlcbiAgICAgICAgKTtcbiAgICAgIH07XG4gICAgY2FzZSBMQVlFUl9UWVBFUy5oZXhhZ29uSWQ6XG4gICAgICBpZiAobGF5ZXIuZGF0YVRvRmVhdHVyZSAmJiBsYXllci5kYXRhVG9GZWF0dXJlLmNlbnRyb2lkcykge1xuICAgICAgICByZXR1cm4gZGF0YSA9PiB7XG4gICAgICAgICAgLy8gbnVsbCBvciBnZXRDZW50cm9pZCh7aWR9KVxuICAgICAgICAgIGNvbnN0IGNlbnRyb2lkID0gbGF5ZXIuZGF0YVRvRmVhdHVyZS5jZW50cm9pZHNbZGF0YS5pbmRleF07XG4gICAgICAgICAgcmV0dXJuIGNlbnRyb2lkICYmIGlzSW5Qb2x5Z29uKGNlbnRyb2lkLCBmaWx0ZXIudmFsdWUpO1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGEgPT4ge1xuICAgICAgICBjb25zdCBpZCA9IGdldFBvc2l0aW9uKGRhdGEpO1xuICAgICAgICBpZiAoIWgzSXNWYWxpZChpZCkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcG9zID0gZ2V0Q2VudHJvaWQoe2lkfSk7XG4gICAgICAgIHJldHVybiBwb3MuZXZlcnkoTnVtYmVyLmlzRmluaXRlKSAmJiBpc0luUG9seWdvbihwb3MsIGZpbHRlci52YWx1ZSk7XG4gICAgICB9O1xuICAgIGNhc2UgTEFZRVJfVFlQRVMuZ2VvanNvbjpcbiAgICAgIHJldHVybiBkYXRhID0+IHtcbiAgICAgICAgcmV0dXJuIGxheWVyLmlzSW5Qb2x5Z29uKGRhdGEsIGRhdGEuaW5kZXgsIGZpbHRlci52YWx1ZSk7XG4gICAgICB9O1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gKCkgPT4gdHJ1ZTtcbiAgfVxufTtcblxuLyoqXG4gKiBAcGFyYW0gcGFyYW0gQW4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhIHJvdyByZWNvcmQuXG4gKiBAcGFyYW0gcGFyYW0uaW5kZXggSW5kZXggb2YgdGhlIHJvdyBpbiBkYXRhIGNvbnRhaW5lci5cbiAqIEByZXR1cm5zIFJldHVybnMgdHJ1ZSB0byBrZWVwIHRoZSBlbGVtZW50LCBvciBmYWxzZSBvdGhlcndpc2UuXG4gKi9cbnR5cGUgZmlsdGVyRnVuY3Rpb24gPSAoZGF0YToge2luZGV4OiBudW1iZXJ9KSA9PiBib29sZWFuO1xuLyoqXG4gKiBAcGFyYW0gZmllbGQgZGF0YXNldCBGaWVsZFxuICogQHBhcmFtIGRhdGFJZCBEYXRhc2V0IGlkXG4gKiBAcGFyYW0gZmlsdGVyIEZpbHRlciBvYmplY3RcbiAqIEBwYXJhbSBsYXllcnMgbGlzdCBvZiBsYXllcnMgdG8gZmlsdGVyIHVwb25cbiAqIEBwYXJhbSBkYXRhQ29udGFpbmVyIERhdGEgY29udGFpbmVyXG4gKiBAcmV0dXJuIGZpbHRlckZ1bmN0aW9uXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRGaWx0ZXJGdW5jdGlvbjxMIGV4dGVuZHMge2NvbmZpZzoge2RhdGFJZDogc3RyaW5nIHwgbnVsbH07IGlkOiBzdHJpbmd9PihcbiAgZmllbGQ6IEZpZWxkIHwgbnVsbCxcbiAgZGF0YUlkOiBzdHJpbmcsXG4gIGZpbHRlcjogRmlsdGVyLFxuICBsYXllcnM6IExbXSxcbiAgZGF0YUNvbnRhaW5lcjogRGF0YUNvbnRhaW5lckludGVyZmFjZVxuKTogZmlsdGVyRnVuY3Rpb24ge1xuICAvLyBmaWVsZCBjb3VsZCBiZSBudWxsIGluIHBvbHlnb24gZmlsdGVyXG4gIGNvbnN0IHZhbHVlQWNjZXNzb3IgPSBmaWVsZCA/IGZpZWxkLnZhbHVlQWNjZXNzb3IgOiBkYXRhID0+IG51bGw7XG4gIGNvbnN0IGRlZmF1bHRGdW5jID0gZCA9PiB0cnVlO1xuXG4gIGlmIChmaWx0ZXIuZW5hYmxlZCA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm4gZGVmYXVsdEZ1bmM7XG4gIH1cblxuICBzd2l0Y2ggKGZpbHRlci50eXBlKSB7XG4gICAgY2FzZSBGSUxURVJfVFlQRVMucmFuZ2U6XG4gICAgICByZXR1cm4gZGF0YSA9PiBpc0luUmFuZ2UodmFsdWVBY2Nlc3NvcihkYXRhKSwgZmlsdGVyLnZhbHVlKTtcbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5tdWx0aVNlbGVjdDpcbiAgICAgIHJldHVybiBkYXRhID0+IGZpbHRlci52YWx1ZS5pbmNsdWRlcyh2YWx1ZUFjY2Vzc29yKGRhdGEpKTtcbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5zZWxlY3Q6XG4gICAgICByZXR1cm4gZGF0YSA9PiB2YWx1ZUFjY2Vzc29yKGRhdGEpID09PSBmaWx0ZXIudmFsdWU7XG4gICAgY2FzZSBGSUxURVJfVFlQRVMudGltZVJhbmdlOlxuICAgICAgaWYgKCFmaWVsZCkge1xuICAgICAgICByZXR1cm4gZGVmYXVsdEZ1bmM7XG4gICAgICB9XG4gICAgICBjb25zdCBtYXBwZWRWYWx1ZSA9IGdldChmaWVsZCwgWydmaWx0ZXJQcm9wcycsICdtYXBwZWRWYWx1ZSddKTtcbiAgICAgIGNvbnN0IGFjY2Vzc29yID0gQXJyYXkuaXNBcnJheShtYXBwZWRWYWx1ZSlcbiAgICAgICAgPyBkYXRhID0+IG1hcHBlZFZhbHVlW2RhdGEuaW5kZXhdXG4gICAgICAgIDogZGF0YSA9PiB0aW1lVG9Vbml4TWlsbGkodmFsdWVBY2Nlc3NvcihkYXRhKSwgZmllbGQuZm9ybWF0KTtcbiAgICAgIHJldHVybiBkYXRhID0+IGlzSW5SYW5nZShhY2Nlc3NvcihkYXRhKSwgZmlsdGVyLnZhbHVlKTtcbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5wb2x5Z29uOlxuICAgICAgaWYgKCFsYXllcnMgfHwgIWxheWVycy5sZW5ndGggfHwgIWZpbHRlci5sYXllcklkKSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0RnVuYztcbiAgICAgIH1cbiAgICAgIGNvbnN0IGxheWVyRmlsdGVyRnVuY3Rpb25zID0gZmlsdGVyLmxheWVySWRcbiAgICAgICAgLm1hcChpZCA9PiBsYXllcnMuZmluZChsID0+IGwuaWQgPT09IGlkKSlcbiAgICAgICAgLmZpbHRlcihsID0+IGwgJiYgbC5jb25maWcuZGF0YUlkID09PSBkYXRhSWQpXG4gICAgICAgIC5tYXAobGF5ZXIgPT4gZ2V0UG9seWdvbkZpbHRlckZ1bmN0b3IobGF5ZXIsIGZpbHRlciwgZGF0YUNvbnRhaW5lcikpO1xuXG4gICAgICByZXR1cm4gZGF0YSA9PiBsYXllckZpbHRlckZ1bmN0aW9ucy5ldmVyeShmaWx0ZXJGdW5jID0+IGZpbHRlckZ1bmMoZGF0YSkpO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZGVmYXVsdEZ1bmM7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUZpbHRlckRhdGFJZChkYXRhSWQ6IHN0cmluZyB8IHN0cmluZ1tdKTogRmlsdGVyQmFzZTxMaW5lQ2hhcnQ+IHtcbiAgcmV0dXJuIGdldERlZmF1bHRGaWx0ZXIoe2RhdGFJZH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyRGF0YUJ5RmlsdGVyVHlwZXMoXG4gIHtcbiAgICBkeW5hbWljRG9tYWluRmlsdGVycyxcbiAgICBjcHVGaWx0ZXJzLFxuICAgIGZpbHRlckZ1bmNzXG4gIH06IHtcbiAgICBkeW5hbWljRG9tYWluRmlsdGVyczogRmlsdGVyW10gfCBudWxsO1xuICAgIGNwdUZpbHRlcnM6IEZpbHRlcltdIHwgbnVsbDtcbiAgICBmaWx0ZXJGdW5jczoge1xuICAgICAgW2tleTogc3RyaW5nXTogZmlsdGVyRnVuY3Rpb247XG4gICAgfTtcbiAgfSxcbiAgZGF0YUNvbnRhaW5lcjogRGF0YUNvbnRhaW5lckludGVyZmFjZVxuKTogRmlsdGVyUmVzdWx0IHtcbiAgY29uc3QgZmlsdGVyZWRJbmRleEZvckRvbWFpbjogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgZmlsdGVyZWRJbmRleDogbnVtYmVyW10gPSBbXTtcblxuICBjb25zdCBmaWx0ZXJDb250ZXh0ID0ge2luZGV4OiAtMSwgZGF0YUNvbnRhaW5lcn07XG4gIGNvbnN0IGZpbHRlckZ1bmNDYWxsZXIgPSAoZmlsdGVyOiBGaWx0ZXIpID0+IGZpbHRlckZ1bmNzW2ZpbHRlci5pZF0oZmlsdGVyQ29udGV4dCk7XG5cbiAgY29uc3QgbnVtUm93cyA9IGRhdGFDb250YWluZXIubnVtUm93cygpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG51bVJvd3M7ICsraSkge1xuICAgIGZpbHRlckNvbnRleHQuaW5kZXggPSBpO1xuXG4gICAgY29uc3QgbWF0Y2hGb3JEb21haW4gPSBkeW5hbWljRG9tYWluRmlsdGVycyAmJiBkeW5hbWljRG9tYWluRmlsdGVycy5ldmVyeShmaWx0ZXJGdW5jQ2FsbGVyKTtcbiAgICBpZiAobWF0Y2hGb3JEb21haW4pIHtcbiAgICAgIGZpbHRlcmVkSW5kZXhGb3JEb21haW4ucHVzaChmaWx0ZXJDb250ZXh0LmluZGV4KTtcbiAgICB9XG5cbiAgICBjb25zdCBtYXRjaEZvclJlbmRlciA9IGNwdUZpbHRlcnMgJiYgY3B1RmlsdGVycy5ldmVyeShmaWx0ZXJGdW5jQ2FsbGVyKTtcbiAgICBpZiAobWF0Y2hGb3JSZW5kZXIpIHtcbiAgICAgIGZpbHRlcmVkSW5kZXgucHVzaChmaWx0ZXJDb250ZXh0LmluZGV4KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLihkeW5hbWljRG9tYWluRmlsdGVycyA/IHtmaWx0ZXJlZEluZGV4Rm9yRG9tYWlufSA6IHt9KSxcbiAgICAuLi4oY3B1RmlsdGVycyA/IHtmaWx0ZXJlZEluZGV4fSA6IHt9KVxuICB9O1xufVxuXG4vKipcbiAqIEdldCBhIHJlY29yZCBvZiBmaWx0ZXJzIGJhc2VkIG9uIGRvbWFpbiB0eXBlIGFuZCBncHUgLyBjcHVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZpbHRlclJlY29yZChcbiAgZGF0YUlkOiBzdHJpbmcsXG4gIGZpbHRlcnM6IEZpbHRlcltdLFxuICBvcHQ6IEZpbHRlckRhdGFzZXRPcHQgPSB7fVxuKTogRmlsdGVyUmVjb3JkIHtcbiAgY29uc3QgZmlsdGVyUmVjb3JkOiBGaWx0ZXJSZWNvcmQgPSB7XG4gICAgZHluYW1pY0RvbWFpbjogW10sXG4gICAgZml4ZWREb21haW46IFtdLFxuICAgIGNwdTogW10sXG4gICAgZ3B1OiBbXVxuICB9O1xuXG4gIGZpbHRlcnMuZm9yRWFjaChmID0+IHtcbiAgICBpZiAoaXNWYWxpZEZpbHRlclZhbHVlKGYudHlwZSwgZi52YWx1ZSkgJiYgdG9BcnJheShmLmRhdGFJZCkuaW5jbHVkZXMoZGF0YUlkKSkge1xuICAgICAgKGYuZml4ZWREb21haW4gfHwgb3B0Lmlnbm9yZURvbWFpblxuICAgICAgICA/IGZpbHRlclJlY29yZC5maXhlZERvbWFpblxuICAgICAgICA6IGZpbHRlclJlY29yZC5keW5hbWljRG9tYWluXG4gICAgICApLnB1c2goZik7XG5cbiAgICAgIChmLmdwdSAmJiAhb3B0LmNwdU9ubHkgPyBmaWx0ZXJSZWNvcmQuZ3B1IDogZmlsdGVyUmVjb3JkLmNwdSkucHVzaChmKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBmaWx0ZXJSZWNvcmQ7XG59XG5cbi8qKlxuICogQ29tcGFyZSBmaWx0ZXIgcmVjb3JkcyB0byBnZXQgd2hhdCBoYXMgY2hhbmdlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gZGlmZkZpbHRlcnMoXG4gIGZpbHRlclJlY29yZDogRmlsdGVyUmVjb3JkLFxuICBvbGRGaWx0ZXJSZWNvcmQ6IEZpbHRlclJlY29yZCB8IHt9ID0ge31cbik6IEZpbHRlckNoYW5nZWQge1xuICBsZXQgZmlsdGVyQ2hhbmdlZDogUGFydGlhbDxGaWx0ZXJDaGFuZ2VkPiA9IHt9O1xuXG4gIChPYmplY3QuZW50cmllcyhmaWx0ZXJSZWNvcmQpIGFzIEVudHJpZXM8RmlsdGVyUmVjb3JkPikuZm9yRWFjaCgoW3JlY29yZCwgaXRlbXNdKSA9PiB7XG4gICAgaXRlbXMuZm9yRWFjaChmaWx0ZXIgPT4ge1xuICAgICAgY29uc3Qgb2xkRmlsdGVyOiBGaWx0ZXIgPSAob2xkRmlsdGVyUmVjb3JkW3JlY29yZF0gfHwgW10pLmZpbmQoXG4gICAgICAgIChmOiBGaWx0ZXIpID0+IGYuaWQgPT09IGZpbHRlci5pZFxuICAgICAgKTtcblxuICAgICAgaWYgKCFvbGRGaWx0ZXIpIHtcbiAgICAgICAgLy8gYWRkZWRcbiAgICAgICAgZmlsdGVyQ2hhbmdlZCA9IHNldChbcmVjb3JkLCBmaWx0ZXIuaWRdLCAnYWRkZWQnLCBmaWx0ZXJDaGFuZ2VkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGNoZWNrICB3aGF0IGhhcyBjaGFuZ2VkXG4gICAgICAgIFsnbmFtZScsICd2YWx1ZScsICdkYXRhSWQnXS5mb3JFYWNoKHByb3AgPT4ge1xuICAgICAgICAgIGlmIChmaWx0ZXJbcHJvcF0gIT09IG9sZEZpbHRlcltwcm9wXSkge1xuICAgICAgICAgICAgZmlsdGVyQ2hhbmdlZCA9IHNldChbcmVjb3JkLCBmaWx0ZXIuaWRdLCBgJHtwcm9wfV9jaGFuZ2VkYCwgZmlsdGVyQ2hhbmdlZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIChvbGRGaWx0ZXJSZWNvcmRbcmVjb3JkXSB8fCBbXSkuZm9yRWFjaCgob2xkRmlsdGVyOiBGaWx0ZXIpID0+IHtcbiAgICAgIC8vIGRlbGV0ZWRcbiAgICAgIGlmICghaXRlbXMuZmluZChmID0+IGYuaWQgPT09IG9sZEZpbHRlci5pZCkpIHtcbiAgICAgICAgZmlsdGVyQ2hhbmdlZCA9IHNldChbcmVjb3JkLCBvbGRGaWx0ZXIuaWRdLCAnZGVsZXRlZCcsIGZpbHRlckNoYW5nZWQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICByZXR1cm4gey4uLntkeW5hbWljRG9tYWluOiBudWxsLCBmaXhlZERvbWFpbjogbnVsbCwgY3B1OiBudWxsLCBncHU6IG51bGx9LCAuLi5maWx0ZXJDaGFuZ2VkfTtcbn1cbi8qKlxuICogQ2FsbCBieSBwYXJzaW5nIGZpbHRlcnMgZnJvbSBVUkxcbiAqIENoZWNrIGlmIHZhbHVlIG9mIGZpbHRlciB3aXRoaW4gZmlsdGVyIGRvbWFpbiwgaWYgbm90IGFkanVzdCBpdCB0byBtYXRjaFxuICogZmlsdGVyIGRvbWFpblxuICpcbiAqIEByZXR1cm5zIHZhbHVlIC0gYWRqdXN0ZWQgdmFsdWUgdG8gbWF0Y2ggZmlsdGVyIG9yIG51bGwgdG8gcmVtb3ZlIGZpbHRlclxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuZXhwb3J0IGZ1bmN0aW9uIGFkanVzdFZhbHVlVG9GaWx0ZXJEb21haW4odmFsdWU6IEZpbHRlclsndmFsdWUnXSwge2RvbWFpbiwgdHlwZX0pIHtcbiAgaWYgKCF0eXBlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIGlmIHRoZSBjdXJyZW50IGZpbHRlciBpcyBhIHBvbHlnb24gaXQgd2lsbCBub3QgaGF2ZSBhbnkgZG9tYWluXG4gIC8vIGFsbCBvdGhlciBmaWx0ZXIgdHlwZXMgcmVxdWlyZSBkb21haW5cbiAgaWYgKHR5cGUgIT09IEZJTFRFUl9UWVBFUy5wb2x5Z29uICYmICFkb21haW4pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5yYW5nZTpcbiAgICBjYXNlIEZJTFRFUl9UWVBFUy50aW1lUmFuZ2U6XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpIHx8IHZhbHVlLmxlbmd0aCAhPT0gMikge1xuICAgICAgICByZXR1cm4gZG9tYWluLm1hcChkID0+IGQpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdmFsdWUubWFwKChkLCBpKSA9PiAobm90TnVsbG9yVW5kZWZpbmVkKGQpICYmIGlzSW5SYW5nZShkLCBkb21haW4pID8gZCA6IGRvbWFpbltpXSkpO1xuXG4gICAgY2FzZSBGSUxURVJfVFlQRVMubXVsdGlTZWxlY3Q6XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpbHRlcmVkVmFsdWUgPSB2YWx1ZS5maWx0ZXIoZCA9PiBkb21haW4uaW5jbHVkZXMoZCkpO1xuICAgICAgcmV0dXJuIGZpbHRlcmVkVmFsdWUubGVuZ3RoID8gZmlsdGVyZWRWYWx1ZSA6IFtdO1xuXG4gICAgY2FzZSBGSUxURVJfVFlQRVMuc2VsZWN0OlxuICAgICAgcmV0dXJuIGRvbWFpbi5pbmNsdWRlcyh2YWx1ZSkgPyB2YWx1ZSA6IHRydWU7XG4gICAgY2FzZSBGSUxURVJfVFlQRVMucG9seWdvbjpcbiAgICAgIHJldHVybiB2YWx1ZTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuLyogZXNsaW50LWVuYWJsZSBjb21wbGV4aXR5ICovXG5cbi8qKlxuICogQ2FsY3VsYXRlIG51bWVyaWMgZG9tYWluIGFuZCBzdWl0YWJsZSBzdGVwXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXROdW1lcmljRmllbGREb21haW4oXG4gIGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2UsXG4gIHZhbHVlQWNjZXNzb3I6IGRhdGFWYWx1ZUFjY2Vzc29yXG4pOiBSYW5nZUZpZWxkRG9tYWluIHtcbiAgbGV0IGRvbWFpbjogW251bWJlciwgbnVtYmVyXSA9IFswLCAxXTtcbiAgbGV0IHN0ZXAgPSAwLjE7XG5cbiAgY29uc3QgbWFwcGVkVmFsdWUgPSBkYXRhQ29udGFpbmVyLm1hcEluZGV4KHZhbHVlQWNjZXNzb3IpO1xuXG4gIGlmIChkYXRhQ29udGFpbmVyLm51bVJvd3MoKSA+IDEpIHtcbiAgICBkb21haW4gPSBTY2FsZVV0aWxzLmdldExpbmVhckRvbWFpbihtYXBwZWRWYWx1ZSk7XG4gICAgY29uc3QgZGlmZiA9IGRvbWFpblsxXSAtIGRvbWFpblswXTtcblxuICAgIC8vIGluIGNhc2UgZXF1YWwgZG9tYWluLCBbOTYsIDk2XSwgd2hpY2ggd2lsbCBicmVhayBxdWFudGl6ZSBzY2FsZVxuICAgIGlmICghZGlmZikge1xuICAgICAgZG9tYWluWzFdID0gZG9tYWluWzBdICsgMTtcbiAgICB9XG5cbiAgICBzdGVwID0gZ2V0TnVtZXJpY1N0ZXBTaXplKGRpZmYpIHx8IHN0ZXA7XG4gICAgZG9tYWluWzBdID0gZm9ybWF0TnVtYmVyQnlTdGVwKGRvbWFpblswXSwgc3RlcCwgJ2Zsb29yJyk7XG4gICAgZG9tYWluWzFdID0gZm9ybWF0TnVtYmVyQnlTdGVwKGRvbWFpblsxXSwgc3RlcCwgJ2NlaWwnKTtcbiAgfVxuXG4gIGNvbnN0IHtoaXN0b2dyYW0sIGVubGFyZ2VkSGlzdG9ncmFtfSA9IGdldEhpc3RvZ3JhbShkb21haW4sIG1hcHBlZFZhbHVlKTtcblxuICByZXR1cm4ge2RvbWFpbiwgc3RlcCwgaGlzdG9ncmFtLCBlbmxhcmdlZEhpc3RvZ3JhbX07XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHN0ZXAgc2l6ZSBmb3IgcmFuZ2UgYW5kIHRpbWVyYW5nZSBmaWx0ZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE51bWVyaWNTdGVwU2l6ZShkaWZmOiBudW1iZXIpOiBudW1iZXIge1xuICBkaWZmID0gTWF0aC5hYnMoZGlmZik7XG5cbiAgaWYgKGRpZmYgPiAxMDApIHtcbiAgICByZXR1cm4gMTtcbiAgfSBlbHNlIGlmIChkaWZmID4gMykge1xuICAgIHJldHVybiAwLjAxO1xuICB9IGVsc2UgaWYgKGRpZmYgPiAxKSB7XG4gICAgcmV0dXJuIDAuMDAxO1xuICB9XG4gIC8vIFRyeSB0byBnZXQgYXQgbGVhc3QgMTAwMCBzdGVwcyAtIGFuZCBrZWVwIHRoZSBzdGVwIHNpemUgYmVsb3cgdGhhdCBvZlxuICAvLyB0aGUgKGRpZmYgPiAxKSBjYXNlLlxuICBjb25zdCB4ID0gZGlmZiAvIDEwMDA7XG4gIC8vIEZpbmQgdGhlIGV4cG9uZW50IGFuZCB0cnVuY2F0ZSB0byAxMCB0byB0aGUgcG93ZXIgb2YgdGhhdCBleHBvbmVudFxuXG4gIGNvbnN0IGV4cG9uZW50aWFsRm9ybSA9IHgudG9FeHBvbmVudGlhbCgpO1xuICBjb25zdCBleHBvbmVudCA9IHBhcnNlRmxvYXQoZXhwb25lbnRpYWxGb3JtLnNwbGl0KCdlJylbMV0pO1xuXG4gIC8vIEdldHRpbmcgcmVhZHkgZm9yIG5vZGUgMTJcbiAgLy8gdGhpcyBpcyB3aHkgd2UgbmVlZCBkZWNpbWFsLmpzXG4gIC8vIE1hdGgucG93KDEwLCAtNSkgPSAwLjAwMDAwOTk5OTk5OTk5OTk5OTk5OVxuICAvLyB0aGUgYWJvdmUgcmVzdWx0IHNob3dzIGluIGJyb3dzZXIgYW5kIG5vZGUgMTBcbiAgLy8gbm9kZSAxMiBiZWhhdmVzIGNvcnJlY3RseVxuICByZXR1cm4gbmV3IERlY2ltYWwoMTApLnBvdyhleHBvbmVudCkudG9OdW1iZXIoKTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgdGltZXN0YW1wIGRvbWFpbiBhbmQgc3VpdGFibGUgc3RlcFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGltZXN0YW1wRmllbGREb21haW4oXG4gIGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2UsXG4gIHZhbHVlQWNjZXNzb3I6IGRhdGFWYWx1ZUFjY2Vzc29yXG4pOiBUaW1lUmFuZ2VGaWVsZERvbWFpbiB7XG4gIC8vIHRvIGF2b2lkIGNvbnZlcnRpbmcgc3RyaW5nIGZvcm1hdCB0aW1lIHRvIGVwb2NoXG4gIC8vIGV2ZXJ5IHRpbWUgd2UgY29tcGFyZSB3ZSBzdG9yZSBhIHZhbHVlIG1hcHBlZCB0byBpbnQgaW4gZmlsdGVyIGRvbWFpblxuXG4gIGNvbnN0IG1hcHBlZFZhbHVlID0gZGF0YUNvbnRhaW5lci5tYXBJbmRleCh2YWx1ZUFjY2Vzc29yKTtcbiAgY29uc3QgZG9tYWluID0gU2NhbGVVdGlscy5nZXRMaW5lYXJEb21haW4obWFwcGVkVmFsdWUpO1xuICBjb25zdCBkZWZhdWx0VGltZUZvcm1hdCA9IGdldFRpbWVXaWRnZXRUaXRsZUZvcm1hdHRlcihkb21haW4pO1xuXG4gIGxldCBzdGVwID0gMC4wMTtcblxuICBjb25zdCBkaWZmID0gZG9tYWluWzFdIC0gZG9tYWluWzBdO1xuICAvLyBpbiBjYXNlIGVxdWFsIHRpbWVzdGFtcCBhZGQgMSBzZWNvbmQgcGFkZGluZyB0byBwcmV2ZW50IGJyZWFrXG4gIGlmICghZGlmZikge1xuICAgIGRvbWFpblsxXSA9IGRvbWFpblswXSArIDEwMDA7XG4gIH1cbiAgY29uc3QgZW50cnkgPSBUaW1lc3RhbXBTdGVwTWFwLmZpbmQoZiA9PiBmLm1heCA+PSBkaWZmKTtcbiAgaWYgKGVudHJ5KSB7XG4gICAgc3RlcCA9IGVudHJ5LnN0ZXA7XG4gIH1cblxuICBjb25zdCB7aGlzdG9ncmFtLCBlbmxhcmdlZEhpc3RvZ3JhbX0gPSBnZXRIaXN0b2dyYW0oZG9tYWluLCBtYXBwZWRWYWx1ZSk7XG5cbiAgcmV0dXJuIHtcbiAgICBkb21haW4sXG4gICAgc3RlcCxcbiAgICBtYXBwZWRWYWx1ZSxcbiAgICBoaXN0b2dyYW0sXG4gICAgZW5sYXJnZWRIaXN0b2dyYW0sXG4gICAgZGVmYXVsdFRpbWVGb3JtYXRcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhpc3RvZ3JhbUNvbnN0cnVjdChcbiAgZG9tYWluOiBbbnVtYmVyLCBudW1iZXJdLFxuICBtYXBwZWRWYWx1ZTogKE1pbGxpc2Vjb25kIHwgbnVtYmVyKVtdLFxuICBiaW5zOiBudW1iZXJcbik6IEhpc3RvZ3JhbUJpbltdIHtcbiAgcmV0dXJuIGQzSGlzdG9ncmFtKClcbiAgICAudGhyZXNob2xkcyh0aWNrcyhkb21haW5bMF0sIGRvbWFpblsxXSwgYmlucykpXG4gICAgLmRvbWFpbihkb21haW4pKG1hcHBlZFZhbHVlKVxuICAgIC5tYXAoYmluID0+ICh7XG4gICAgICBjb3VudDogYmluLmxlbmd0aCxcbiAgICAgIGJpbixcbiAgICAgIHgwOiBiaW4ueDAsXG4gICAgICB4MTogYmluLngxXG4gICAgfSkpO1xufVxuLyoqXG4gKiBDYWxjdWxhdGUgaGlzdG9ncmFtIGZyb20gZG9tYWluIGFuZCBhcnJheSBvZiB2YWx1ZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEhpc3RvZ3JhbShcbiAgZG9tYWluOiBbbnVtYmVyLCBudW1iZXJdLFxuICBtYXBwZWRWYWx1ZTogKE1pbGxpc2Vjb25kIHwgbnVtYmVyKVtdXG4pOiB7aGlzdG9ncmFtOiBIaXN0b2dyYW1CaW5bXTsgZW5sYXJnZWRIaXN0b2dyYW06IEhpc3RvZ3JhbUJpbltdfSB7XG4gIGNvbnN0IGhpc3RvZ3JhbSA9IGhpc3RvZ3JhbUNvbnN0cnVjdChkb21haW4sIG1hcHBlZFZhbHVlLCBoaXN0b2dyYW1CaW5zKTtcbiAgY29uc3QgZW5sYXJnZWRIaXN0b2dyYW0gPSBoaXN0b2dyYW1Db25zdHJ1Y3QoZG9tYWluLCBtYXBwZWRWYWx1ZSwgZW5sYXJnZWRIaXN0b2dyYW1CaW5zKTtcblxuICByZXR1cm4ge2hpc3RvZ3JhbSwgZW5sYXJnZWRIaXN0b2dyYW19O1xufVxuXG4vKipcbiAqIHJvdW5kIG51bWJlciBiYXNlZCBvbiBzdGVwXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHZhbFxuICogQHBhcmFtIHtOdW1iZXJ9IHN0ZXBcbiAqIEBwYXJhbSB7c3RyaW5nfSBib3VuZFxuICogQHJldHVybnMge051bWJlcn0gcm91bmRlZCBudW1iZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdE51bWJlckJ5U3RlcCh2YWw6IG51bWJlciwgc3RlcDogbnVtYmVyLCBib3VuZDogJ2Zsb29yJyB8ICdjZWlsJyk6IG51bWJlciB7XG4gIGlmIChib3VuZCA9PT0gJ2Zsb29yJykge1xuICAgIHJldHVybiBNYXRoLmZsb29yKHZhbCAqICgxIC8gc3RlcCkpIC8gKDEgLyBzdGVwKTtcbiAgfVxuXG4gIHJldHVybiBNYXRoLmNlaWwodmFsICogKDEgLyBzdGVwKSkgLyAoMSAvIHN0ZXApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNJblJhbmdlKHZhbDogYW55LCBkb21haW46IG51bWJlcltdKTogYm9vbGVhbiB7XG4gIGlmICghQXJyYXkuaXNBcnJheShkb21haW4pKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHZhbCA+PSBkb21haW5bMF0gJiYgdmFsIDw9IGRvbWFpblsxXTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgYSBwb2ludCBpcyB3aXRoaW4gdGhlIHByb3ZpZGVkIHBvbHlnb25cbiAqXG4gKiBAcGFyYW0gcG9pbnQgYXMgaW5wdXQgc2VhcmNoIFtsYXQsIGxuZ11cbiAqIEBwYXJhbSBwb2x5Z29uIFBvaW50cyBtdXN0IGJlIHdpdGhpbiB0aGVzZSAoTXVsdGkpUG9seWdvbihzKVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzSW5Qb2x5Z29uKHBvaW50OiBudW1iZXJbXSwgcG9seWdvbjogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiBib29sZWFuV2l0aGluKHR1cmZQb2ludChwb2ludCksIHBvbHlnb24pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldFRpbWVXaWRnZXRUaXRsZUZvcm1hdHRlcihkb21haW46IFtudW1iZXIsIG51bWJlcl0pOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKCFpc1ZhbGlkVGltZURvbWFpbihkb21haW4pKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBkaWZmID0gZG9tYWluWzFdIC0gZG9tYWluWzBdO1xuXG4gIC8vIExvY2FsIGF3YXJlIGZvcm1hdHNcbiAgLy8gaHR0cHM6Ly9tb21lbnRqcy5jb20vZG9jcy8jL3BhcnNpbmcvc3RyaW5nLWZvcm1hdFxuICByZXR1cm4gZGlmZiA+IGR1cmF0aW9uWWVhciA/ICdMJyA6IGRpZmYgPiBkdXJhdGlvbkRheSA/ICdMIExUJyA6ICdMIExUUyc7XG59XG5cbi8qKlxuICogU2FuaXR5IGNoZWNrIG9uIGZpbHRlcnMgdG8gcHJlcGFyZSBmb3Igc2F2ZVxuICogQHR5cGUge3R5cGVvZiBpbXBvcnQoJy4vZmlsdGVyLXV0aWxzJykuaXNGaWx0ZXJWYWxpZFRvU2F2ZX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRmlsdGVyVmFsaWRUb1NhdmUoZmlsdGVyOiBhbnkpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBmaWx0ZXI/LnR5cGUgJiYgQXJyYXkuaXNBcnJheShmaWx0ZXI/Lm5hbWUpICYmIChmaWx0ZXI/Lm5hbWUubGVuZ3RoIHx8IGZpbHRlcj8ubGF5ZXJJZC5sZW5ndGgpXG4gICk7XG59XG5cbi8qKlxuICogU2FuaXR5IGNoZWNrIG9uIGZpbHRlcnMgdG8gcHJlcGFyZSBmb3Igc2F2ZVxuICogQHR5cGUge3R5cGVvZiBpbXBvcnQoJy4vZmlsdGVyLXV0aWxzJykuaXNWYWxpZEZpbHRlclZhbHVlfVxuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBjb21wbGV4aXR5ICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZEZpbHRlclZhbHVlKHR5cGU6IHN0cmluZyB8IG51bGwsIHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKCF0eXBlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgRklMVEVSX1RZUEVTLnNlbGVjdDpcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gZmFsc2U7XG5cbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5yYW5nZTpcbiAgICBjYXNlIEZJTFRFUl9UWVBFUy50aW1lUmFuZ2U6XG4gICAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUuZXZlcnkodiA9PiB2ICE9PSBudWxsICYmICFpc05hTih2KSk7XG5cbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5tdWx0aVNlbGVjdDpcbiAgICAgIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKSAmJiBCb29sZWFuKHZhbHVlLmxlbmd0aCk7XG5cbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5pbnB1dDpcbiAgICAgIHJldHVybiBCb29sZWFuKHZhbHVlLmxlbmd0aCk7XG5cbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5wb2x5Z29uOlxuICAgICAgY29uc3QgY29vcmRpbmF0ZXMgPSBnZXQodmFsdWUsIFsnZ2VvbWV0cnknLCAnY29vcmRpbmF0ZXMnXSk7XG4gICAgICByZXR1cm4gQm9vbGVhbih2YWx1ZSAmJiB2YWx1ZS5pZCAmJiBjb29yZGluYXRlcyk7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbHVtbkZpbHRlclByb3BzPEsgZXh0ZW5kcyBLZXBsZXJUYWJsZU1vZGVsPEssIEw+LCBMPihcbiAgZmlsdGVyOiBGaWx0ZXIsXG4gIGRhdGFzZXQ6IEtcbik6IHtsaW5lQ2hhcnQ6IExpbmVDaGFydDsgeUF4czogRmllbGR9IHwge30ge1xuICBpZiAoZmlsdGVyLnBsb3RUeXBlID09PSBQTE9UX1RZUEVTLmhpc3RvZ3JhbSB8fCAhZmlsdGVyLnlBeGlzKSB7XG4gICAgLy8gaGlzdG9ncmFtIHNob3VsZCBiZSBjYWxjdWxhdGVkIHdoZW4gY3JlYXRlIGZpbHRlclxuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGNvbnN0IHttYXBwZWRWYWx1ZSA9IFtdfSA9IGZpbHRlcjtcbiAgY29uc3Qge3lBeGlzfSA9IGZpbHRlcjtcbiAgY29uc3QgZmllbGRJZHggPSBkYXRhc2V0LmdldENvbHVtbkZpZWxkSWR4KHlBeGlzLm5hbWUpO1xuICBpZiAoZmllbGRJZHggPCAwKSB7XG4gICAgQ29uc29sZS53YXJuKGB5QXhpcyAke3lBeGlzLm5hbWV9IGRvZXMgbm90IGV4aXN0IGluIGRhdGFzZXRgKTtcbiAgICByZXR1cm4ge2xpbmVDaGFydDoge30sIHlBeGlzfTtcbiAgfVxuXG4gIC8vIHJldHVybiBsaW5lQ2hhcnRcbiAgY29uc3Qgc2VyaWVzID0gZGF0YXNldC5kYXRhQ29udGFpbmVyXG4gICAgLm1hcChcbiAgICAgIChyb3csIHJvd0luZGV4KSA9PiAoe1xuICAgICAgICB4OiBtYXBwZWRWYWx1ZVtyb3dJbmRleF0sXG4gICAgICAgIHk6IHJvdy52YWx1ZUF0KGZpZWxkSWR4KVxuICAgICAgfSksXG4gICAgICB0cnVlXG4gICAgKVxuICAgIC5maWx0ZXIoKHt4LCB5fSkgPT4gTnVtYmVyLmlzRmluaXRlKHgpICYmIE51bWJlci5pc0Zpbml0ZSh5KSlcbiAgICAuc29ydCgoYSwgYikgPT4gYXNjZW5kaW5nKGEueCwgYi54KSk7XG5cbiAgY29uc3QgeURvbWFpbiA9IGV4dGVudChzZXJpZXMsIGQgPT4gZC55KTtcbiAgY29uc3QgeERvbWFpbiA9IFtzZXJpZXNbMF0ueCwgc2VyaWVzW3Nlcmllcy5sZW5ndGggLSAxXS54XTtcblxuICByZXR1cm4ge2xpbmVDaGFydDoge3NlcmllcywgeURvbWFpbiwgeERvbWFpbn0sIHlBeGlzfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERlZmF1bHRGaWx0ZXJQbG90VHlwZShmaWx0ZXI6IEZpbHRlcik6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBmaWx0ZXJQbG90VHlwZXM6IHR5cGVvZiBTdXBwb3J0ZWRQbG90VHlwZVtrZXlvZiB0eXBlb2YgU3VwcG9ydGVkUGxvdFR5cGVdIHwgbnVsbCA9XG4gICAgZmlsdGVyLnR5cGUgJiYgU3VwcG9ydGVkUGxvdFR5cGVbZmlsdGVyLnR5cGVdO1xuICBpZiAoIWZpbHRlclBsb3RUeXBlcykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKCFmaWx0ZXIueUF4aXMpIHtcbiAgICByZXR1cm4gZmlsdGVyUGxvdFR5cGVzLmRlZmF1bHQ7XG4gIH1cblxuICByZXR1cm4gZmlsdGVyUGxvdFR5cGVzW2ZpbHRlci55QXhpcy50eXBlXSB8fCBudWxsO1xufVxuXG4vKipcbiAqXG4gKiBAcGFyYW0gZGF0YXNldElkcyBsaXN0IG9mIGRhdGFzZXQgaWRzIHRvIGJlIGZpbHRlcmVkXG4gKiBAcGFyYW0gZGF0YXNldHMgYWxsIGRhdGFzZXRzXG4gKiBAcGFyYW0gZmlsdGVycyBhbGwgZmlsdGVycyB0byBiZSBhcHBsaWVkIHRvIGRhdGFzZXRzXG4gKiBAcmV0dXJuIGRhdGFzZXRzIC0gbmV3IHVwZGF0ZWQgZGF0YXNldHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5RmlsdGVyc1RvRGF0YXNldHM8XG4gIEsgZXh0ZW5kcyBLZXBsZXJUYWJsZU1vZGVsPEssIEw+LFxuICBMIGV4dGVuZHMge2NvbmZpZzoge2RhdGFJZDogc3RyaW5nIHwgbnVsbH19XG4+KFxuICBkYXRhc2V0SWRzOiBzdHJpbmdbXSxcbiAgZGF0YXNldHM6IHtbaWQ6IHN0cmluZ106IEt9LFxuICBmaWx0ZXJzOiBGaWx0ZXJbXSxcbiAgbGF5ZXJzPzogTFtdXG4pOiB7W2lkOiBzdHJpbmddOiBLfSB7XG4gIGNvbnN0IGRhdGFJZHMgPSB0b0FycmF5KGRhdGFzZXRJZHMpO1xuICByZXR1cm4gZGF0YUlkcy5yZWR1Y2UoKGFjYywgZGF0YUlkKSA9PiB7XG4gICAgY29uc3QgbGF5ZXJzVG9GaWx0ZXIgPSAobGF5ZXJzIHx8IFtdKS5maWx0ZXIobCA9PiBsLmNvbmZpZy5kYXRhSWQgPT09IGRhdGFJZCk7XG4gICAgY29uc3QgYXBwbGllZEZpbHRlcnMgPSBmaWx0ZXJzLmZpbHRlcihkID0+IHNob3VsZEFwcGx5RmlsdGVyKGQsIGRhdGFJZCkpO1xuICAgIGNvbnN0IHRhYmxlID0gZGF0YXNldHNbZGF0YUlkXTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5hY2MsXG4gICAgICBbZGF0YUlkXTogdGFibGUuZmlsdGVyVGFibGUoYXBwbGllZEZpbHRlcnMsIGxheWVyc1RvRmlsdGVyLCB7fSlcbiAgICB9O1xuICB9LCBkYXRhc2V0cyk7XG59XG5cbi8qKlxuICogQXBwbGllcyBhIG5ldyBmaWVsZCBuYW1lIHZhbHVlIHRvIGZpZWx0ZXIgYW5kIHVwZGF0ZSBib3RoIGZpbHRlciBhbmQgZGF0YXNldFxuICogQHBhcmFtIGZpbHRlciAtIHRvIGJlIGFwcGxpZWQgdGhlIG5ldyBmaWVsZCBuYW1lIG9uXG4gKiBAcGFyYW0gZGF0YXNldCAtIGRhdGFzZXQgdGhlIGZpZWxkIGJlbG9uZ3MgdG9cbiAqIEBwYXJhbSBmaWVsZE5hbWUgLSBmaWVsZC5uYW1lXG4gKiBAcGFyYW0gZmlsdGVyRGF0YXNldEluZGV4IC0gZmllbGQubmFtZVxuICogQHBhcmFtIG9wdGlvblxuICogQHJldHVybiAtIHtmaWx0ZXIsIGRhdGFzZXRzfVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlGaWx0ZXJGaWVsZE5hbWU8SyBleHRlbmRzIEtlcGxlclRhYmxlTW9kZWw8SywgTD4sIEw+KFxuICBmaWx0ZXI6IEZpbHRlcixcbiAgZGF0YXNldDogSyxcbiAgZmllbGROYW1lOiBzdHJpbmcsXG4gIGZpbHRlckRhdGFzZXRJbmRleCA9IDAsXG4gIG9wdGlvbj86IHttZXJnZURvbWFpbjogYm9vbGVhbn1cbik6IHtcbiAgZmlsdGVyOiBGaWx0ZXIgfCBudWxsO1xuICBkYXRhc2V0OiBLO1xufSB7XG4gIC8vIHVzaW5nIGZpbHRlckRhdGFzZXRJbmRleCB3ZSBjYW4gZmlsdGVyIG9ubHkgdGhlIHNwZWNpZmllZCBkYXRhc2V0XG4gIGNvbnN0IG1lcmdlRG9tYWluID0gb3B0aW9uICYmIG9wdGlvbi5oYXNPd25Qcm9wZXJ0eSgnbWVyZ2VEb21haW4nKSA/IG9wdGlvbi5tZXJnZURvbWFpbiA6IGZhbHNlO1xuXG4gIGNvbnN0IGZpZWxkSW5kZXggPSBkYXRhc2V0LmdldENvbHVtbkZpZWxkSWR4KGZpZWxkTmFtZSk7XG4gIC8vIGlmIG5vIGZpZWxkIHdpdGggc2FtZSBuYW1lIGlzIGZvdW5kLCBtb3ZlIHRvIHRoZSBuZXh0IGRhdGFzZXRzXG4gIGlmIChmaWVsZEluZGV4ID09PSAtMSkge1xuICAgIC8vIHRocm93IG5ldyBFcnJvcihgZmllbGRJbmRleCBub3QgZm91bmQuIERhdGFzZXQgbXVzdCBjb250YWluIGEgcHJvcGVydHkgd2l0aCBuYW1lOiAke2ZpZWxkTmFtZX1gKTtcbiAgICByZXR1cm4ge2ZpbHRlcjogbnVsbCwgZGF0YXNldH07XG4gIH1cblxuICAvLyBUT0RPOiB2YWxpZGF0ZSBmaWVsZCB0eXBlXG4gIGNvbnN0IGZpbHRlclByb3BzID0gZGF0YXNldC5nZXRDb2x1bW5GaWx0ZXJQcm9wcyhmaWVsZE5hbWUpO1xuXG4gIGNvbnN0IG5ld0ZpbHRlciA9IHtcbiAgICAuLi4obWVyZ2VEb21haW4gPyBtZXJnZUZpbHRlckRvbWFpblN0ZXAoZmlsdGVyLCBmaWx0ZXJQcm9wcykgOiB7Li4uZmlsdGVyLCAuLi5maWx0ZXJQcm9wc30pLFxuICAgIG5hbWU6IE9iamVjdC5hc3NpZ24oWy4uLnRvQXJyYXkoZmlsdGVyLm5hbWUpXSwge1tmaWx0ZXJEYXRhc2V0SW5kZXhdOiBmaWVsZE5hbWV9KSxcbiAgICBmaWVsZElkeDogT2JqZWN0LmFzc2lnbihbLi4udG9BcnJheShmaWx0ZXIuZmllbGRJZHgpXSwge1xuICAgICAgW2ZpbHRlckRhdGFzZXRJbmRleF06IGZpZWxkSW5kZXhcbiAgICB9KSxcbiAgICAvLyBUT0RPLCBzaW5jZSB3ZSBhbGxvdyB0byBhZGQgbXVsdGlwbGUgZmllbGRzIHRvIGEgZmlsdGVyIHdlIGNhbiBubyBsb25nZXIgZnJlZXplIHRoZSBmaWx0ZXJcbiAgICBmcmVlemU6IHRydWVcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIGZpbHRlcjogbmV3RmlsdGVyLFxuICAgIGRhdGFzZXRcbiAgfTtcbn1cblxuLyoqXG4gKiBNZXJnZSBvbmUgZmlsdGVyIHdpdGggb3RoZXIgZmlsdGVyIHByb3AgZG9tYWluXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUZpbHRlckRvbWFpblN0ZXAoXG4gIGZpbHRlcjogRmlsdGVyLFxuICBmaWx0ZXJQcm9wcz86IFBhcnRpYWw8RmlsdGVyPlxuKTogKEZpbHRlciAmIHtzdGVwPzogbnVtYmVyfSkgfCBudWxsIHtcbiAgaWYgKCFmaWx0ZXIpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmICghZmlsdGVyUHJvcHMpIHtcbiAgICByZXR1cm4gZmlsdGVyO1xuICB9XG5cbiAgaWYgKChmaWx0ZXIuZmllbGRUeXBlICYmIGZpbHRlci5maWVsZFR5cGUgIT09IGZpbHRlclByb3BzLmZpZWxkVHlwZSkgfHwgIWZpbHRlclByb3BzLmRvbWFpbikge1xuICAgIHJldHVybiBmaWx0ZXI7XG4gIH1cblxuICBjb25zdCBjb21iaW5lZERvbWFpbiA9ICFmaWx0ZXIuZG9tYWluXG4gICAgPyBmaWx0ZXJQcm9wcy5kb21haW5cbiAgICA6IFsuLi4oZmlsdGVyLmRvbWFpbiB8fCBbXSksIC4uLihmaWx0ZXJQcm9wcy5kb21haW4gfHwgW10pXS5zb3J0KChhLCBiKSA9PiBhIC0gYik7XG5cbiAgY29uc3QgbmV3RmlsdGVyID0ge1xuICAgIC4uLmZpbHRlcixcbiAgICAuLi5maWx0ZXJQcm9wcyxcbiAgICBkb21haW46IFtjb21iaW5lZERvbWFpblswXSwgY29tYmluZWREb21haW5bY29tYmluZWREb21haW4ubGVuZ3RoIC0gMV1dXG4gIH07XG5cbiAgc3dpdGNoIChmaWx0ZXJQcm9wcy5maWVsZFR5cGUpIHtcbiAgICBjYXNlIEFMTF9GSUVMRF9UWVBFUy5zdHJpbmc6XG4gICAgY2FzZSBBTExfRklFTERfVFlQRVMuZGF0ZTpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLm5ld0ZpbHRlcixcbiAgICAgICAgZG9tYWluOiB1bmlxdWUoY29tYmluZWREb21haW4pLnNvcnQoKVxuICAgICAgfTtcblxuICAgIGNhc2UgQUxMX0ZJRUxEX1RZUEVTLnRpbWVzdGFtcDpcbiAgICAgIGNvbnN0IHN0ZXAgPVxuICAgICAgICAoZmlsdGVyIGFzIFRpbWVSYW5nZUZpbHRlcikuc3RlcCA8IChmaWx0ZXJQcm9wcyBhcyBUaW1lUmFuZ2VGaWVsZERvbWFpbikuc3RlcFxuICAgICAgICAgID8gKGZpbHRlciBhcyBUaW1lUmFuZ2VGaWx0ZXIpLnN0ZXBcbiAgICAgICAgICA6IChmaWx0ZXJQcm9wcyBhcyBUaW1lUmFuZ2VGaWVsZERvbWFpbikuc3RlcDtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubmV3RmlsdGVyLFxuICAgICAgICBzdGVwXG4gICAgICB9O1xuICAgIGNhc2UgQUxMX0ZJRUxEX1RZUEVTLnJlYWw6XG4gICAgY2FzZSBBTExfRklFTERfVFlQRVMuaW50ZWdlcjpcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIG5ld0ZpbHRlcjtcbiAgfVxufVxuLyogZXNsaW50LWVuYWJsZSBjb21wbGV4aXR5ICovXG5cbi8qKlxuICogR2VuZXJhdGVzIHBvbHlnb24gZmlsdGVyXG4gKi9cbmV4cG9ydCBjb25zdCBmZWF0dXJlVG9GaWx0ZXJWYWx1ZSA9IChcbiAgZmVhdHVyZTogRmVhdHVyZSxcbiAgZmlsdGVySWQ6IHN0cmluZyxcbiAgcHJvcGVydGllcz86IHt9XG4pOiBGZWF0dXJlVmFsdWUgPT4gKHtcbiAgLi4uZmVhdHVyZSxcbiAgaWQ6IGZlYXR1cmUuaWQsXG4gIHByb3BlcnRpZXM6IHtcbiAgICAuLi5mZWF0dXJlLnByb3BlcnRpZXMsXG4gICAgLi4ucHJvcGVydGllcyxcbiAgICBmaWx0ZXJJZFxuICB9XG59KTtcblxuZXhwb3J0IGNvbnN0IGdldEZpbHRlcklkSW5GZWF0dXJlID0gKGY6IEZlYXR1cmVWYWx1ZSk6IHN0cmluZyA9PiBnZXQoZiwgWydwcm9wZXJ0aWVzJywgJ2ZpbHRlcklkJ10pO1xuXG4vKipcbiAqIEdlbmVyYXRlcyBwb2x5Z29uIGZpbHRlclxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVQb2x5Z29uRmlsdGVyPFxuICBMIGV4dGVuZHMge2NvbmZpZzoge2RhdGFJZDogc3RyaW5nIHwgbnVsbDsgbGFiZWw6IHN0cmluZ307IGlkOiBzdHJpbmd9XG4+KGxheWVyczogTFtdLCBmZWF0dXJlOiBGZWF0dXJlKTogUG9seWdvbkZpbHRlciB7XG4gIGNvbnN0IGRhdGFJZCA9IGxheWVycy5tYXAobCA9PiBsLmNvbmZpZy5kYXRhSWQpLmZpbHRlcihub3ROdWxsb3JVbmRlZmluZWQpO1xuICBjb25zdCBsYXllcklkID0gbGF5ZXJzLm1hcChsID0+IGwuaWQpO1xuICBjb25zdCBuYW1lID0gbGF5ZXJzLm1hcChsID0+IGwuY29uZmlnLmxhYmVsKTtcbiAgY29uc3QgZmlsdGVyID0gZ2V0RGVmYXVsdEZpbHRlcih7ZGF0YUlkfSk7XG4gIHJldHVybiB7XG4gICAgLi4uZmlsdGVyLFxuICAgIGZpeGVkRG9tYWluOiB0cnVlLFxuICAgIHR5cGU6IEZJTFRFUl9UWVBFUy5wb2x5Z29uLFxuICAgIG5hbWUsXG4gICAgbGF5ZXJJZCxcbiAgICB2YWx1ZTogZmVhdHVyZVRvRmlsdGVyVmFsdWUoZmVhdHVyZSwgZmlsdGVyLmlkLCB7aXNWaXNpYmxlOiB0cnVlfSlcbiAgfTtcbn1cblxuLyoqXG4gKiBSdW4gZmlsdGVyIGVudGlyZWx5IG9uIENQVVxuICovXG5pbnRlcmZhY2UgU3RhdGVUeXBlPEsgZXh0ZW5kcyBLZXBsZXJUYWJsZU1vZGVsPEssIEw+LCBMPiB7XG4gIGxheWVyczogTFtdO1xuICBmaWx0ZXJzOiBGaWx0ZXJbXTtcbiAgZGF0YXNldHM6IHtbaWQ6IHN0cmluZ106IEt9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyRGF0YXNldENQVTxUIGV4dGVuZHMgU3RhdGVUeXBlPEssIEw+LCBLIGV4dGVuZHMgS2VwbGVyVGFibGVNb2RlbDxLLCBMPiwgTD4oXG4gIHN0YXRlOiBULFxuICBkYXRhSWQ6IHN0cmluZ1xuKTogVCB7XG4gIGNvbnN0IGRhdGFzZXRGaWx0ZXJzID0gc3RhdGUuZmlsdGVycy5maWx0ZXIoZiA9PiBmLmRhdGFJZC5pbmNsdWRlcyhkYXRhSWQpKTtcbiAgY29uc3QgZGF0YXNldCA9IHN0YXRlLmRhdGFzZXRzW2RhdGFJZF07XG5cbiAgaWYgKCFkYXRhc2V0KSB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgY29uc3QgY3B1RmlsdGVyZWREYXRhc2V0ID0gZGF0YXNldC5maWx0ZXJUYWJsZUNQVShkYXRhc2V0RmlsdGVycywgc3RhdGUubGF5ZXJzKTtcblxuICByZXR1cm4gc2V0KFsnZGF0YXNldHMnLCBkYXRhSWRdLCBjcHVGaWx0ZXJlZERhdGFzZXQsIHN0YXRlKTtcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBwYXJzZWQgZmlsdGVycyB3aXRoIGRhdGFzZXRzIGFuZCBhZGQgZmlsdGVyUHJvcHMgdG8gZmllbGRcbiAqL1xudHlwZSBNaW5WaXNTdGF0ZUZvckZpbHRlciA9IFBpY2s8VmlzU3RhdGUsICdsYXllcnMnIHwgJ2RhdGFzZXRzJyB8ICdpc01lcmdpbmdEYXRhc2V0cyc+O1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlRmlsdGVyc1VwZGF0ZURhdGFzZXRzPFxuICBTIGV4dGVuZHMgTWluVmlzU3RhdGVGb3JGaWx0ZXIsXG4gIEsgZXh0ZW5kcyBLZXBsZXJUYWJsZU1vZGVsPEssIEw+LFxuICBMIGV4dGVuZHMge2NvbmZpZzoge2RhdGFJZDogc3RyaW5nIHwgbnVsbDsgbGFiZWw6IHN0cmluZ307IGlkOiBzdHJpbmd9XG4+KFxuICBzdGF0ZTogUyxcbiAgZmlsdGVyc1RvVmFsaWRhdGU6IFBhcnNlZEZpbHRlcltdID0gW11cbik6IHtcbiAgdmFsaWRhdGVkOiBGaWx0ZXJbXTtcbiAgZmFpbGVkOiBGaWx0ZXJbXTtcbiAgdXBkYXRlZERhdGFzZXRzOiBTWydkYXRhc2V0cyddO1xufSB7XG4gIC8vIFRPRE8gQmV0dGVyIFR5cGluZ3MgaGVyZVxuICBjb25zdCB2YWxpZGF0ZWQ6IGFueVtdID0gW107XG4gIGNvbnN0IGZhaWxlZDogYW55W10gPSBbXTtcbiAgY29uc3Qge2RhdGFzZXRzfSA9IHN0YXRlO1xuICBsZXQgdXBkYXRlZERhdGFzZXRzID0gZGF0YXNldHM7XG5cbiAgLy8gbWVyZ2UgZmlsdGVyc1xuICBmaWx0ZXJzVG9WYWxpZGF0ZS5mb3JFYWNoKGZpbHRlciA9PiB7XG4gICAgLy8gd2UgY2FuIG9ubHkgbG9vayBmb3IgZGF0YXNldHMgZGVmaW5lIGluIHRoZSBmaWx0ZXIgZGF0YUlkXG4gICAgY29uc3QgZGF0YXNldElkcyA9IHRvQXJyYXkoZmlsdGVyLmRhdGFJZCk7XG5cbiAgICAvLyB3ZSBjYW4gbWVyZ2UgYSBmaWx0ZXIgb25seSBpZiBhbGwgZGF0YXNldHMgaW4gZmlsdGVyLmRhdGFJZCBhcmUgbG9hZGVkXG4gICAgaWYgKGRhdGFzZXRJZHMuZXZlcnkoZCA9PiBkYXRhc2V0c1tkXSAmJiAhc3RhdGUuaXNNZXJnaW5nRGF0YXNldHNbZF0pKSB7XG4gICAgICAvLyBhbGwgZGF0YXNldElkcyBpbiBmaWx0ZXIgbXVzdCBiZSBwcmVzZW50IHRoZSBzdGF0ZSBkYXRhc2V0c1xuICAgICAgY29uc3Qge2ZpbHRlcjogdmFsaWRhdGVkRmlsdGVyLCBhcHBseVRvRGF0YXNldHMsIGF1Z21lbnRlZERhdGFzZXRzfSA9IGRhdGFzZXRJZHMucmVkdWNlPHtcbiAgICAgICAgZmlsdGVyOiBGaWx0ZXIgfCBudWxsO1xuICAgICAgICBhcHBseVRvRGF0YXNldHM6IHN0cmluZ1tdO1xuICAgICAgICBhdWdtZW50ZWREYXRhc2V0czoge1tkYXRhc2V0SWQ6IHN0cmluZ106IGFueX07XG4gICAgICB9PihcbiAgICAgICAgKGFjYywgZGF0YXNldElkKSA9PiB7XG4gICAgICAgICAgY29uc3QgZGF0YXNldCA9IHVwZGF0ZWREYXRhc2V0c1tkYXRhc2V0SWRdO1xuICAgICAgICAgIGNvbnN0IGxheWVycyA9IHN0YXRlLmxheWVycy5maWx0ZXIobCA9PiBsLmNvbmZpZy5kYXRhSWQgPT09IGRhdGFzZXQuaWQpO1xuICAgICAgICAgIGNvbnN0IHtmaWx0ZXI6IHVwZGF0ZWRGaWx0ZXIsIGRhdGFzZXQ6IHVwZGF0ZWREYXRhc2V0fSA9IHZhbGlkYXRlRmlsdGVyV2l0aERhdGEoXG4gICAgICAgICAgICBhY2MuYXVnbWVudGVkRGF0YXNldHNbZGF0YXNldElkXSB8fCBkYXRhc2V0LFxuICAgICAgICAgICAgZmlsdGVyLFxuICAgICAgICAgICAgbGF5ZXJzXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmICh1cGRhdGVkRmlsdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAuLi5hY2MsXG4gICAgICAgICAgICAgIC8vIG1lcmdlIGZpbHRlciBwcm9wc1xuICAgICAgICAgICAgICBmaWx0ZXI6IGFjYy5maWx0ZXJcbiAgICAgICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uYWNjLmZpbHRlcixcbiAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyBjaGVjazogY2hhbmdlZCBmcm9tIGFjYyB0byBhY2MuZmlsdGVyIHRvIGZpeCB0eXBlc1xuICAgICAgICAgICAgICAgICAgICAuLi5tZXJnZUZpbHRlckRvbWFpblN0ZXAoYWNjLmZpbHRlciwgdXBkYXRlZEZpbHRlcilcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA6IHVwZGF0ZWRGaWx0ZXIsXG5cbiAgICAgICAgICAgICAgYXBwbHlUb0RhdGFzZXRzOiBbLi4uYWNjLmFwcGx5VG9EYXRhc2V0cywgZGF0YXNldElkXSxcblxuICAgICAgICAgICAgICBhdWdtZW50ZWREYXRhc2V0czoge1xuICAgICAgICAgICAgICAgIC4uLmFjYy5hdWdtZW50ZWREYXRhc2V0cyxcbiAgICAgICAgICAgICAgICBbZGF0YXNldElkXTogdXBkYXRlZERhdGFzZXRcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgZmlsdGVyOiBudWxsLFxuICAgICAgICAgIGFwcGx5VG9EYXRhc2V0czogW10sXG4gICAgICAgICAgYXVnbWVudGVkRGF0YXNldHM6IHt9XG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIGlmICh2YWxpZGF0ZWRGaWx0ZXIgJiYgaXNFcXVhbChkYXRhc2V0SWRzLCBhcHBseVRvRGF0YXNldHMpKSB7XG4gICAgICAgIHZhbGlkYXRlZC5wdXNoKHZhbGlkYXRlZEZpbHRlcik7XG4gICAgICAgIHVwZGF0ZWREYXRhc2V0cyA9IHtcbiAgICAgICAgICAuLi51cGRhdGVkRGF0YXNldHMsXG4gICAgICAgICAgLi4uYXVnbWVudGVkRGF0YXNldHNcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZhaWxlZC5wdXNoKGZpbHRlcik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZhaWxlZC5wdXNoKGZpbHRlcik7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4ge3ZhbGlkYXRlZCwgZmFpbGVkLCB1cGRhdGVkRGF0YXNldHN9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsdGVyUGxvdDxLIGV4dGVuZHMgS2VwbGVyVGFibGVNb2RlbDxLLCBMPiwgTD4oXG4gIGZpbHRlcjogRmlsdGVyLFxuICBkYXRhc2V0OiBLXG4pOiB7bGluZUNoYXJ0OiBMaW5lQ2hhcnQ7IHlBeHM6IEZpZWxkfSB8IHt9IHtcbiAgaWYgKGZpbHRlci5wbG90VHlwZSA9PT0gUExPVF9UWVBFUy5oaXN0b2dyYW0gfHwgIWZpbHRlci55QXhpcykge1xuICAgIC8vIGhpc3RvZ3JhbSBzaG91bGQgYmUgY2FsY3VsYXRlZCB3aGVuIGNyZWF0ZSBmaWx0ZXJcbiAgICByZXR1cm4ge307XG4gIH1cblxuICBjb25zdCB7bWFwcGVkVmFsdWUgPSBbXX0gPSBmaWx0ZXI7XG4gIGNvbnN0IHt5QXhpc30gPSBmaWx0ZXI7XG4gIGNvbnN0IGZpZWxkSWR4ID0gZGF0YXNldC5nZXRDb2x1bW5GaWVsZElkeCh5QXhpcy5uYW1lKTtcbiAgaWYgKGZpZWxkSWR4IDwgMCkge1xuICAgIENvbnNvbGUud2FybihgeUF4aXMgJHt5QXhpcy5uYW1lfSBkb2VzIG5vdCBleGlzdCBpbiBkYXRhc2V0YCk7XG4gICAgcmV0dXJuIHtsaW5lQ2hhcnQ6IHt9LCB5QXhpc307XG4gIH1cblxuICAvLyByZXR1cm4gbGluZUNoYXJ0XG4gIGNvbnN0IHNlcmllcyA9IGRhdGFzZXQuZGF0YUNvbnRhaW5lclxuICAgIC5tYXAoXG4gICAgICAocm93LCByb3dJbmRleCkgPT4gKHtcbiAgICAgICAgeDogbWFwcGVkVmFsdWVbcm93SW5kZXhdLFxuICAgICAgICB5OiByb3cudmFsdWVBdChmaWVsZElkeClcbiAgICAgIH0pLFxuICAgICAgdHJ1ZVxuICAgIClcbiAgICAuZmlsdGVyKCh7eCwgeX0pID0+IE51bWJlci5pc0Zpbml0ZSh4KSAmJiBOdW1iZXIuaXNGaW5pdGUoeSkpXG4gICAgLnNvcnQoKGEsIGIpID0+IGFzY2VuZGluZyhhLngsIGIueCkpO1xuXG4gIGNvbnN0IHlEb21haW4gPSBleHRlbnQoc2VyaWVzLCBkID0+IGQueSk7XG4gIGNvbnN0IHhEb21haW4gPSBbc2VyaWVzWzBdLngsIHNlcmllc1tzZXJpZXMubGVuZ3RoIC0gMV0ueF07XG5cbiAgcmV0dXJuIHtsaW5lQ2hhcnQ6IHtzZXJpZXMsIHlEb21haW4sIHhEb21haW59LCB5QXhpc307XG59XG5cbi8qKlxuICogUmV0cmlldmUgaW50ZXJ2YWwgYmlucyBmb3IgdGltZSBmaWx0ZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEludGVydmFsQmlucyhmaWx0ZXI6IFRpbWVSYW5nZUZpbHRlcikge1xuICBjb25zdCB7Ymluc30gPSBmaWx0ZXI7XG4gIGNvbnN0IGludGVydmFsID0gZmlsdGVyLnBsb3RUeXBlPy5pbnRlcnZhbDtcbiAgaWYgKCFpbnRlcnZhbCB8fCAhYmlucyB8fCBPYmplY3Qua2V5cyhiaW5zKS5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCB2YWx1ZXMgPSBPYmplY3QudmFsdWVzKGJpbnMpO1xuICByZXR1cm4gdmFsdWVzWzBdID8gdmFsdWVzWzBdW2ludGVydmFsXSA6IG51bGw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkVGltZURvbWFpbihkb21haW4pIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoZG9tYWluKSAmJiBkb21haW4uZXZlcnkoTnVtYmVyLmlzRmluaXRlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRpbWVXaWRnZXRIaW50Rm9ybWF0dGVyKGRvbWFpbjogW251bWJlciwgbnVtYmVyXSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghaXNWYWxpZFRpbWVEb21haW4oZG9tYWluKSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBkaWZmID0gZG9tYWluWzFdIC0gZG9tYWluWzBdO1xuICByZXR1cm4gZGlmZiA+IGR1cmF0aW9uV2Vla1xuICAgID8gJ0wnXG4gICAgOiBkaWZmID4gZHVyYXRpb25EYXlcbiAgICA/ICdMIExUJ1xuICAgIDogZGlmZiA+IGR1cmF0aW9uSG91clxuICAgID8gJ0xUJ1xuICAgIDogJ0xUUyc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1NpZGVGaWx0ZXIoZmlsdGVyOiBGaWx0ZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIGZpbHRlci52aWV3ID09PSBGSUxURVJfVklFV19UWVBFUy5zaWRlO1xufVxuIl19