@kepler.gl/utils 3.1.0-alpha.1 → 3.1.0-alpha.3

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 (81) hide show
  1. package/dist/aggregation.d.ts +13 -0
  2. package/dist/aggregation.js +84 -0
  3. package/dist/application-config.d.ts +25 -0
  4. package/dist/application-config.js +52 -0
  5. package/dist/arrow-data-container.d.ts +62 -0
  6. package/dist/arrow-data-container.js +331 -0
  7. package/dist/color-utils.d.ts +108 -0
  8. package/dist/color-utils.js +443 -0
  9. package/dist/data-container-interface.d.ts +138 -0
  10. package/dist/data-container-interface.js +6 -0
  11. package/dist/data-container-utils.d.ts +30 -0
  12. package/dist/data-container-utils.js +74 -0
  13. package/dist/data-row.d.ts +59 -0
  14. package/dist/data-row.js +110 -0
  15. package/dist/data-scale-utils.d.ts +119 -0
  16. package/dist/data-scale-utils.js +340 -0
  17. package/dist/data-utils.d.ts +98 -0
  18. package/dist/data-utils.js +436 -0
  19. package/dist/dataset-utils.d.ts +45 -0
  20. package/dist/dataset-utils.js +313 -0
  21. package/dist/dom-to-image.d.ts +73 -0
  22. package/dist/dom-to-image.js +421 -0
  23. package/dist/dom-utils.d.ts +23 -0
  24. package/dist/dom-utils.js +349 -0
  25. package/dist/effect-utils.d.ts +24 -0
  26. package/dist/effect-utils.js +166 -0
  27. package/dist/export-map-html.d.ts +9 -0
  28. package/dist/export-map-html.js +25 -0
  29. package/dist/export-utils.d.ts +40 -0
  30. package/dist/export-utils.js +201 -0
  31. package/dist/filter-utils.d.ts +331 -0
  32. package/dist/filter-utils.js +1214 -0
  33. package/dist/format.d.ts +3 -0
  34. package/dist/format.js +38 -0
  35. package/dist/gl-utils.d.ts +1 -0
  36. package/dist/gl-utils.js +27 -0
  37. package/dist/index.d.ts +42 -0
  38. package/dist/index.js +941 -0
  39. package/dist/indexed-data-container.d.ts +34 -0
  40. package/dist/indexed-data-container.js +214 -0
  41. package/dist/locale-utils.d.ts +2 -0
  42. package/dist/locale-utils.js +39 -0
  43. package/dist/map-info-utils.d.ts +1 -0
  44. package/dist/map-info-utils.js +14 -0
  45. package/dist/map-style-utils/mapbox-gl-style-editor.d.ts +57 -0
  46. package/dist/map-style-utils/mapbox-gl-style-editor.js +188 -0
  47. package/dist/map-style-utils/mapbox-utils.d.ts +14 -0
  48. package/dist/map-style-utils/mapbox-utils.js +51 -0
  49. package/dist/map-utils.d.ts +9 -0
  50. package/dist/map-utils.js +48 -0
  51. package/dist/mapbox-utils.d.ts +7 -0
  52. package/dist/mapbox-utils.js +19 -0
  53. package/dist/noop.d.ts +1 -0
  54. package/dist/noop.js +13 -0
  55. package/dist/notifications-utils.d.ts +42 -0
  56. package/dist/notifications-utils.js +69 -0
  57. package/dist/observe-dimensions.d.ts +15 -0
  58. package/dist/observe-dimensions.js +130 -0
  59. package/dist/plot.d.ts +131 -0
  60. package/dist/plot.js +615 -0
  61. package/dist/position-utils.d.ts +6 -0
  62. package/dist/position-utils.js +26 -0
  63. package/dist/projection-utils.d.ts +22 -0
  64. package/dist/projection-utils.js +83 -0
  65. package/dist/quick-insertion-sort.d.ts +12 -0
  66. package/dist/quick-insertion-sort.js +132 -0
  67. package/dist/row-data-container.d.ts +31 -0
  68. package/dist/row-data-container.js +206 -0
  69. package/dist/searcher-utils.d.ts +1 -0
  70. package/dist/searcher-utils.js +25 -0
  71. package/dist/split-map-utils.d.ts +32 -0
  72. package/dist/split-map-utils.js +99 -0
  73. package/dist/strings.d.ts +4 -0
  74. package/dist/strings.js +16 -0
  75. package/dist/time.d.ts +54 -0
  76. package/dist/time.js +325 -0
  77. package/dist/types.d.ts +18 -0
  78. package/dist/types.js +6 -0
  79. package/dist/utils.d.ts +104 -0
  80. package/dist/utils.js +241 -0
  81. package/package.json +14 -6
package/dist/plot.js ADDED
@@ -0,0 +1,615 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.adjustValueToAnimationWindow = adjustValueToAnimationWindow;
8
+ exports.binByTime = binByTime;
9
+ exports.getAggregationOptiosnBasedOnField = void 0;
10
+ exports.getBinThresholds = getBinThresholds;
11
+ exports.getChartTitle = getChartTitle;
12
+ exports.getDefaultPlotType = getDefaultPlotType;
13
+ exports.getFilterDataFunc = getFilterDataFunc;
14
+ exports.getLineChart = getLineChart;
15
+ exports.getPctChange = getPctChange;
16
+ exports.getRangeFilterBins = getRangeFilterBins;
17
+ exports.getTimeBins = getTimeBins;
18
+ exports.getValueAggrFunc = void 0;
19
+ exports.histogramFromDomain = histogramFromDomain;
20
+ exports.histogramFromThreshold = histogramFromThreshold;
21
+ exports.histogramFromValues = histogramFromValues;
22
+ exports.isPercentField = isPercentField;
23
+ exports.normalizeValue = normalizeValue;
24
+ exports.runGpuFilterForPlot = runGpuFilterForPlot;
25
+ exports.snapToMarks = snapToMarks;
26
+ exports.splitSeries = splitSeries;
27
+ exports.updateAggregationByField = updateAggregationByField;
28
+ exports.updateRangeFilterPlotType = updateRangeFilterPlotType;
29
+ exports.updateTimeFilterPlotType = updateTimeFilterPlotType;
30
+ exports.validBin = validBin;
31
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
32
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
33
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
34
+ var _d3Array = require("d3-array");
35
+ var _lodash = _interopRequireDefault(require("lodash.isequal"));
36
+ var _time = require("./time");
37
+ var _moment = _interopRequireDefault(require("moment"));
38
+ var _commonUtils = require("@kepler.gl/common-utils");
39
+ var _constants = require("@kepler.gl/constants");
40
+ var _dataUtils = require("./data-utils");
41
+ var _aggregation = require("./aggregation");
42
+ var _strings = require("./strings");
43
+ var _format = require("./format");
44
+ var _colorUtils = require("./color-utils");
45
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
46
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
47
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
48
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
49
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } // SPDX-License-Identifier: MIT
50
+ // Copyright contributors to the kepler.gl project
51
+ // TODO kepler-table module isn't accessible from utils. Add compatible interface to types
52
+
53
+ /**
54
+ *
55
+ * @param thresholds
56
+ * @param values
57
+ * @param indexes
58
+ */
59
+ function histogramFromThreshold(thresholds, values, valueAccessor) {
60
+ var filterEmptyBins = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
61
+ var getBins = (0, _d3Array.histogram)().domain([thresholds[0], thresholds[thresholds.length - 1]]).thresholds(thresholds);
62
+ if (valueAccessor) {
63
+ getBins.value(valueAccessor);
64
+ }
65
+
66
+ // @ts-ignore
67
+ var bins = getBins(values).map(function (bin) {
68
+ return {
69
+ count: bin.length,
70
+ indexes: bin,
71
+ x0: bin.x0,
72
+ x1: bin.x1
73
+ };
74
+ });
75
+
76
+ // d3-histogram ignores threshold values outside the domain
77
+ // The first bin.x0 is always equal to the minimum domain value, and the last bin.x1 is always equal to the maximum domain value.
78
+
79
+ // bins[0].x0 = thresholds[0];
80
+ // bins[bins.length - 1].x1 = thresholds[thresholds.length - 1];
81
+
82
+ // @ts-ignore
83
+ return filterEmptyBins ? bins.filter(function (b) {
84
+ return b.count > 0;
85
+ }) : bins;
86
+ }
87
+
88
+ /**
89
+ *
90
+ * @param values
91
+ * @param numBins
92
+ * @param valueAccessor
93
+ */
94
+ function histogramFromValues(values, numBins, valueAccessor) {
95
+ var getBins = (0, _d3Array.histogram)().thresholds(numBins);
96
+ if (valueAccessor) {
97
+ getBins.value(valueAccessor);
98
+ }
99
+
100
+ // @ts-ignore d3-array types doesn't match
101
+ return getBins(values).map(function (bin) {
102
+ return {
103
+ count: bin.length,
104
+ indexes: bin,
105
+ x0: bin.x0,
106
+ x1: bin.x1
107
+ };
108
+ }).filter(function (b) {
109
+ var x0 = b.x0,
110
+ x1 = b.x1;
111
+ return (0, _dataUtils.isNumber)(x0) && (0, _dataUtils.isNumber)(x1);
112
+ });
113
+ }
114
+
115
+ /**
116
+ *
117
+ * @param domain
118
+ * @param values
119
+ * @param numBins
120
+ * @param valueAccessor
121
+ */
122
+ function histogramFromDomain(domain, values, numBins, valueAccessor) {
123
+ var getBins = (0, _d3Array.histogram)().thresholds((0, _d3Array.ticks)(domain[0], domain[1], numBins)).domain(domain);
124
+ if (valueAccessor) {
125
+ getBins.value(valueAccessor);
126
+ }
127
+
128
+ // @ts-ignore d3-array types doesn't match
129
+ return getBins(values).map(function (bin) {
130
+ return {
131
+ count: bin.length,
132
+ indexes: bin,
133
+ x0: bin.x0,
134
+ x1: bin.x1
135
+ };
136
+ });
137
+ }
138
+
139
+ /**
140
+ * @param filter
141
+ * @param datasets
142
+ * @param interval
143
+ */
144
+ function getTimeBins(filter, datasets, interval) {
145
+ var bins = filter.timeBins || {};
146
+ filter.dataId.forEach(function (dataId, dataIdIdx) {
147
+ // reuse bins if filterData did not change
148
+ if (bins[dataId] && bins[dataId][interval]) {
149
+ return;
150
+ }
151
+ var dataset = datasets[dataId];
152
+
153
+ // do not apply current filter
154
+ var indexes = runGpuFilterForPlot(dataset, filter);
155
+ bins = _objectSpread(_objectSpread({}, bins), {}, (0, _defineProperty2["default"])({}, dataId, _objectSpread(_objectSpread({}, bins[dataId]), {}, (0, _defineProperty2["default"])({}, interval, binByTime(indexes, dataset, interval, filter)))));
156
+ });
157
+ return bins;
158
+ }
159
+ function binByTime(indexes, dataset, interval, filter) {
160
+ // gpuFilters need to be apply to filteredIndex
161
+ var mappedValue = (0, _time.getFilterMappedValue)(dataset, filter);
162
+ if (!mappedValue) {
163
+ return null;
164
+ }
165
+ var intervalBins = getBinThresholds(interval, filter.domain);
166
+ var valueAccessor = function valueAccessor(idx) {
167
+ return mappedValue[idx];
168
+ };
169
+ var bins = histogramFromThreshold(intervalBins, indexes, valueAccessor);
170
+ return bins;
171
+ }
172
+ function getBinThresholds(interval, domain) {
173
+ var timeInterval = (0, _time.intervalToFunction)(interval);
174
+ var _domain = (0, _slicedToArray2["default"])(domain, 2),
175
+ t0 = _domain[0],
176
+ t1 = _domain[1];
177
+ var floor = timeInterval.floor(t0).getTime();
178
+ var ceiling = timeInterval.ceil(t1).getTime();
179
+ if (!timeInterval) {
180
+ // if time interval is not defined
181
+ // this should not happen
182
+ return [t0, t0 + _constants.durationDay];
183
+ }
184
+ var binThresholds = timeInterval.range(floor, ceiling + 1).map(function (t) {
185
+ return _moment["default"].utc(t).valueOf();
186
+ });
187
+ var lastStep = binThresholds[binThresholds.length - 1];
188
+ if (lastStep === t1) {
189
+ // when last step equal to domain max, add one more step
190
+ binThresholds.push(_moment["default"].utc(timeInterval.offset(lastStep)).valueOf());
191
+ }
192
+ return binThresholds;
193
+ }
194
+
195
+ /**
196
+ * Run GPU filter on current filter result to generate indexes for ploting chart
197
+ * Skip ruuning for the same field
198
+ * @param dataset
199
+ * @param filter
200
+ */
201
+ function runGpuFilterForPlot(dataset, filter) {
202
+ var skipIndexes = getSkipIndexes(dataset, filter);
203
+ var _dataset$gpuFilter = dataset.gpuFilter,
204
+ filterValueUpdateTriggers = _dataset$gpuFilter.filterValueUpdateTriggers,
205
+ filterRange = _dataset$gpuFilter.filterRange,
206
+ filterValueAccessor = _dataset$gpuFilter.filterValueAccessor,
207
+ filteredIndex = dataset.filteredIndex;
208
+ var getFilterValue = filterValueAccessor(dataset.dataContainer)();
209
+ var allChannels = Object.keys(filterValueUpdateTriggers).map(function (_, i) {
210
+ return i;
211
+ }).filter(function (i) {
212
+ return Object.values(filterValueUpdateTriggers)[i];
213
+ });
214
+ var skipAll = !allChannels.filter(function (i) {
215
+ return !skipIndexes.includes(i);
216
+ }).length;
217
+ if (skipAll) {
218
+ return filteredIndex;
219
+ }
220
+ var filterData = getFilterDataFunc(filterRange, getFilterValue, dataset.dataContainer, skipIndexes);
221
+ return filteredIndex.filter(filterData);
222
+ }
223
+ function getSkipIndexes(dataset, filter) {
224
+ // array of gpu filter names
225
+ if (!filter) {
226
+ return [];
227
+ }
228
+ var gpuFilters = Object.values(dataset.gpuFilter.filterValueUpdateTriggers);
229
+ var valueIndex = filter.dataId.findIndex(function (id) {
230
+ return id === dataset.id;
231
+ });
232
+ var filterColumn = filter.name[valueIndex];
233
+ return gpuFilters.reduce(function (accu, item, idx) {
234
+ if (item && filterColumn === item.name) {
235
+ accu.push(idx);
236
+ }
237
+ return accu;
238
+ }, []);
239
+ }
240
+ function getFilterDataFunc(filterRange, getFilterValue, dataContainer, skips) {
241
+ return function (index) {
242
+ return getFilterValue({
243
+ index: index
244
+ }).every(function (val, i) {
245
+ return skips.includes(i) || val >= filterRange[i][0] && val <= filterRange[i][1];
246
+ });
247
+ };
248
+ }
249
+ function validBin(b) {
250
+ return b.x0 !== undefined && b.x1 !== undefined;
251
+ }
252
+
253
+ /**
254
+ * Use in slider, given a number and an array of numbers, return the nears number from the array.
255
+ * Takes a value, timesteps and return the actual step.
256
+ * @param value
257
+ * @param marks
258
+ */
259
+ function snapToMarks(value, marks) {
260
+ // always use bin x0
261
+ if (!marks.length) {
262
+ // @ts-expect-error looking at the usage null return value isn't expected and requires extra handling in a lot of places
263
+ return null;
264
+ }
265
+ var i = (0, _d3Array.bisectLeft)(marks, value);
266
+ if (i === 0) {
267
+ return marks[i];
268
+ } else if (i === marks.length) {
269
+ return marks[i - 1];
270
+ }
271
+ var idx = marks[i] - value < value - marks[i - 1] ? i : i - 1;
272
+ return marks[idx];
273
+ }
274
+ function normalizeValue(val, minValue, step, marks) {
275
+ if (marks && marks.length) {
276
+ return snapToMarks(val, marks);
277
+ }
278
+ return (0, _dataUtils.roundValToStep)(minValue, step, val);
279
+ }
280
+ function isPercentField(field) {
281
+ return field.metadata && field.metadata.numerator && field.metadata.denominator;
282
+ }
283
+ function updateAggregationByField(field, aggregation) {
284
+ // shouldn't apply sum to percent fiele type
285
+ // default aggregation is average
286
+ return field && isPercentField(field) ? _constants.AGGREGATION_TYPES.average : aggregation || _constants.AGGREGATION_TYPES.average;
287
+ }
288
+ var getAgregationType = function getAgregationType(field, aggregation) {
289
+ if (isPercentField(field)) {
290
+ return 'mean_of_percent';
291
+ }
292
+ return aggregation;
293
+ };
294
+ var getAggregationAccessor = function getAggregationAccessor(field, dataContainer, fields) {
295
+ if (isPercentField(field)) {
296
+ var numeratorIdx = fields.findIndex(function (f) {
297
+ return f.name === field.metadata.numerator;
298
+ });
299
+ var denominatorIdx = fields.findIndex(function (f) {
300
+ return f.name === field.metadata.denominator;
301
+ });
302
+ return {
303
+ getNumerator: function getNumerator(i) {
304
+ return dataContainer.valueAt(i, numeratorIdx);
305
+ },
306
+ getDenominator: function getDenominator(i) {
307
+ return dataContainer.valueAt(i, denominatorIdx);
308
+ }
309
+ };
310
+ }
311
+ return function (i) {
312
+ return field.valueAccessor({
313
+ index: i
314
+ });
315
+ };
316
+ };
317
+ var getValueAggrFunc = exports.getValueAggrFunc = function getValueAggrFunc(field, aggregation, dataset) {
318
+ var dataContainer = dataset.dataContainer,
319
+ fields = dataset.fields;
320
+
321
+ // The passed-in field might not have all the fields set (e.g. valueAccessor)
322
+ var datasetField = fields.find(function (f) {
323
+ return field && (f.name === field || f.name === field.name);
324
+ });
325
+ return datasetField && aggregation ? function (bin) {
326
+ return (0, _aggregation.aggregate)(bin.indexes, getAgregationType(datasetField, aggregation),
327
+ // @ts-expect-error can return {getNumerator, getDenominator}
328
+ getAggregationAccessor(datasetField, dataContainer, fields));
329
+ } : function (bin) {
330
+ return bin.count;
331
+ };
332
+ };
333
+ var getAggregationOptiosnBasedOnField = exports.getAggregationOptiosnBasedOnField = function getAggregationOptiosnBasedOnField(field) {
334
+ if (isPercentField(field)) {
335
+ // don't show sum
336
+ return _constants.TIME_AGGREGATION.filter(function (_ref) {
337
+ var id = _ref.id;
338
+ return id !== _constants.AGGREGATION_TYPES.sum;
339
+ });
340
+ }
341
+ return _constants.TIME_AGGREGATION;
342
+ };
343
+ function getDelta(bins, y, interval) {
344
+ // if (WOW[interval]) return getWow(bins, y, interval);
345
+ var lastBin = bins[bins.length - 1];
346
+ return {
347
+ delta: 'last',
348
+ pct: lastBin ? getPctChange(y, lastBin.y) : null
349
+ };
350
+ }
351
+ function getPctChange(y, y0) {
352
+ if (Number.isFinite(y) && Number.isFinite(y0) && y0 !== 0) {
353
+ return (y - y0) / y0;
354
+ }
355
+ return null;
356
+ }
357
+
358
+ /**
359
+ *
360
+ * @param datasets
361
+ * @param filter
362
+ */
363
+ function getLineChart(datasets, filter) {
364
+ var _timeBins;
365
+ var dataId = filter.dataId,
366
+ yAxis = filter.yAxis,
367
+ plotType = filter.plotType,
368
+ lineChart = filter.lineChart;
369
+ var aggregation = plotType.aggregation,
370
+ interval = plotType.interval;
371
+ var seriesDataId = dataId[0];
372
+ var bins = (_timeBins = filter.timeBins) === null || _timeBins === void 0 || (_timeBins = _timeBins[seriesDataId]) === null || _timeBins === void 0 ? void 0 : _timeBins[interval];
373
+ if (lineChart && lineChart.aggregation === aggregation && lineChart.interval === interval && lineChart.yAxis === (yAxis === null || yAxis === void 0 ? void 0 : yAxis.name) &&
374
+ // we need to make sure we validate bins because of cross filter data changes
375
+ (0, _lodash["default"])(bins, lineChart === null || lineChart === void 0 ? void 0 : lineChart.bins)) {
376
+ // don't update lineChart if plotType hasn't change
377
+ return lineChart;
378
+ }
379
+ var dataset = datasets[seriesDataId];
380
+ var getYValue = getValueAggrFunc(yAxis, aggregation, dataset);
381
+ var init = [];
382
+ var series = (bins || []).reduce(function (accu, bin, i) {
383
+ var y = getYValue(bin);
384
+ var delta = getDelta(accu, y, interval);
385
+ accu.push(_objectSpread({
386
+ x: bin.x0,
387
+ y: y
388
+ }, delta));
389
+ return accu;
390
+ }, init);
391
+ var yDomain = (0, _d3Array.extent)(series, function (d) {
392
+ return d.y;
393
+ });
394
+ var xDomain = bins ? [bins[0].x0, bins[bins.length - 1].x1] : [];
395
+
396
+ // treat missing data as another series
397
+ var split = splitSeries(series);
398
+ var aggrName = _aggregation.AGGREGATION_NAME[aggregation];
399
+ return {
400
+ // @ts-ignore
401
+ yDomain: yDomain,
402
+ // @ts-ignore
403
+ xDomain: xDomain,
404
+ interval: interval,
405
+ aggregation: aggregation,
406
+ // @ts-ignore
407
+ series: split,
408
+ title: "".concat(aggrName, ' of ').concat(yAxis ? yAxis.name : 'Count'),
409
+ fieldType: yAxis ? yAxis.type : 'integer',
410
+ yAxis: yAxis ? yAxis.name : null,
411
+ allTime: {
412
+ title: "All Time Average",
413
+ value: (0, _aggregation.aggregate)(series, _constants.AGGREGATION_TYPES.average, function (d) {
414
+ return d.y;
415
+ })
416
+ },
417
+ // @ts-expect-error bins is Bins[], not a Bins map. Refactor to use correct types.
418
+ bins: bins
419
+ };
420
+ }
421
+
422
+ // split into multiple series when see missing data
423
+ function splitSeries(series) {
424
+ var lines = [];
425
+ var temp = [];
426
+ for (var i = 0; i < series.length; i++) {
427
+ var d = series[i];
428
+ if (!(0, _commonUtils.notNullorUndefined)(d.y) && temp.length) {
429
+ // ends temp
430
+ lines.push(temp);
431
+ temp = [];
432
+ } else if ((0, _commonUtils.notNullorUndefined)(d.y)) {
433
+ temp.push(d);
434
+ }
435
+ if (i === series.length - 1 && temp.length) {
436
+ lines.push(temp);
437
+ }
438
+ }
439
+ var markers = lines.length > 1 ? series.filter(function (d) {
440
+ return (0, _commonUtils.notNullorUndefined)(d.y);
441
+ }) : [];
442
+ return {
443
+ lines: lines,
444
+ markers: markers
445
+ };
446
+ }
447
+ function adjustValueToAnimationWindow(state, filter) {
448
+ var plotType = filter.plotType,
449
+ _filter$value = (0, _slicedToArray2["default"])(filter.value, 2),
450
+ value0 = _filter$value[0],
451
+ value1 = _filter$value[1],
452
+ animationWindow = filter.animationWindow;
453
+ var interval = plotType.interval || (0, _time.getInitialInterval)(filter, state.datasets);
454
+ var bins = getTimeBins(filter, state.datasets, interval);
455
+ var datasetBins = bins && Object.keys(bins).length && Object.values(bins)[0][interval];
456
+ var thresholds = (datasetBins || []).map(function (b) {
457
+ return b.x0;
458
+ });
459
+ var val0 = value0;
460
+ var val1 = value1;
461
+ var idx;
462
+ if (animationWindow === _constants.ANIMATION_WINDOW.interval) {
463
+ val0 = snapToMarks(value1, thresholds);
464
+ idx = thresholds.indexOf(val0);
465
+ val1 = idx > -1 ? datasetBins[idx].x1 : NaN;
466
+ } else {
467
+ // fit current value to window
468
+ val0 = snapToMarks(value0, thresholds);
469
+ val1 = snapToMarks(value1, thresholds);
470
+ if (val0 === val1) {
471
+ idx = thresholds.indexOf(val0);
472
+ if (idx === thresholds.length - 1) {
473
+ val0 = thresholds[idx - 1];
474
+ } else {
475
+ val1 = thresholds[idx + 1];
476
+ }
477
+ }
478
+ }
479
+ var updatedFilter = _objectSpread(_objectSpread({}, filter), {}, {
480
+ plotType: _objectSpread(_objectSpread({}, filter.plotType), {}, {
481
+ interval: interval
482
+ }),
483
+ timeBins: bins,
484
+ value: [val0, val1]
485
+ });
486
+ return updatedFilter;
487
+ }
488
+
489
+ /**
490
+ * Create or update colors for a filter plot
491
+ * @param filter
492
+ * @param datasets
493
+ * @param oldColorsByDataId
494
+ */
495
+ function getFilterPlotColorsByDataId(filter, datasets, oldColorsByDataId) {
496
+ var colorsByDataId = oldColorsByDataId || {};
497
+ var _iterator = _createForOfIteratorHelper(filter.dataId),
498
+ _step;
499
+ try {
500
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
501
+ var dataId = _step.value;
502
+ if (!colorsByDataId[dataId] && datasets[dataId]) {
503
+ colorsByDataId = _objectSpread(_objectSpread({}, colorsByDataId), {}, (0, _defineProperty2["default"])({}, dataId, (0, _colorUtils.rgbToHex)(datasets[dataId].color)));
504
+ }
505
+ }
506
+ } catch (err) {
507
+ _iterator.e(err);
508
+ } finally {
509
+ _iterator.f();
510
+ }
511
+ return colorsByDataId;
512
+ }
513
+
514
+ /**
515
+ *
516
+ * @param filter
517
+ * @param plotType
518
+ * @param datasets
519
+ * @param dataId
520
+ */
521
+ function updateTimeFilterPlotType(filter, plotType, datasets, dataId) {
522
+ var nextFilter = filter;
523
+ var nextPlotType = plotType;
524
+ if ((0, _typeof2["default"])(nextPlotType) !== 'object' || !nextPlotType.aggregation || !nextPlotType.interval) {
525
+ nextPlotType = getDefaultPlotType(filter, datasets);
526
+ }
527
+ if (filter.dataId.length > 1) {
528
+ nextPlotType = _objectSpread(_objectSpread({}, nextPlotType), {}, {
529
+ colorsByDataId: getFilterPlotColorsByDataId(filter, datasets, nextPlotType.colorsByDataId)
530
+ });
531
+ }
532
+ nextFilter = _objectSpread(_objectSpread({}, nextFilter), {}, {
533
+ plotType: nextPlotType
534
+ });
535
+ var bins = getTimeBins(nextFilter, datasets, nextPlotType.interval);
536
+ nextFilter = _objectSpread(_objectSpread({}, nextFilter), {}, {
537
+ timeBins: bins
538
+ });
539
+ if (plotType.type === _constants.PLOT_TYPES.histogram) {
540
+ // Histogram is calculated and memoized in the chart itself
541
+ } else if (plotType.type === _constants.PLOT_TYPES.lineChart) {
542
+ // we should be able to move this into its own component so react will do the shallow comparison for us.
543
+ nextFilter = _objectSpread(_objectSpread({}, nextFilter), {}, {
544
+ lineChart: getLineChart(datasets, nextFilter)
545
+ });
546
+ }
547
+ return nextFilter;
548
+ }
549
+ function getRangeFilterBins(filter, datasets, numBins) {
550
+ var domain = filter.domain;
551
+ if (!filter.dataId) return null;
552
+ return filter.dataId.reduce(function (acc, dataId, datasetIdx) {
553
+ var _filter$bins;
554
+ if ((_filter$bins = filter.bins) !== null && _filter$bins !== void 0 && _filter$bins[dataId]) {
555
+ // don't recalculate bins
556
+ acc[dataId] = filter.bins[dataId];
557
+ return acc;
558
+ }
559
+ var fieldName = filter.name[datasetIdx];
560
+ if (dataId && fieldName) {
561
+ var dataset = datasets[dataId];
562
+ var field = dataset === null || dataset === void 0 ? void 0 : dataset.getColumnField(fieldName);
563
+ if (dataset && field) {
564
+ var indexes = runGpuFilterForPlot(dataset, filter);
565
+ var valueAccessor = function valueAccessor(index) {
566
+ return field.valueAccessor({
567
+ index: index
568
+ });
569
+ };
570
+ acc[dataId] = histogramFromDomain(domain, indexes, numBins, valueAccessor);
571
+ }
572
+ }
573
+ return acc;
574
+ }, {});
575
+ }
576
+ function updateRangeFilterPlotType(filter, plotType, datasets, dataId) {
577
+ var nextFilter = _objectSpread(_objectSpread({}, filter), {}, {
578
+ plotType: plotType
579
+ });
580
+
581
+ // if (dataId) {
582
+ // // clear bins
583
+ // nextFilter = {
584
+ // ...nextFilter,
585
+ // bins: {
586
+ // ...nextFilter.bins,
587
+ // [dataId]: null
588
+ // }
589
+ // };
590
+ // }
591
+
592
+ return _objectSpread(_objectSpread({}, filter), {}, {
593
+ plotType: plotType,
594
+ bins: getRangeFilterBins(nextFilter, datasets, _constants.BINS)
595
+ });
596
+ }
597
+ function getChartTitle(yAxis, plotType) {
598
+ var yAxisName = yAxis === null || yAxis === void 0 ? void 0 : yAxis.displayName;
599
+ var aggregation = plotType.aggregation;
600
+ if (yAxisName) {
601
+ return (0, _strings.capitalizeFirstLetter)("".concat(aggregation, " ").concat(yAxisName, " over Time"));
602
+ }
603
+ return "Count of Rows over Time";
604
+ }
605
+ function getDefaultPlotType(filter, datasets) {
606
+ var interval = (0, _time.getInitialInterval)(filter, datasets);
607
+ var defaultTimeFormat = (0, _format.getDefaultTimeFormat)(interval);
608
+ return {
609
+ interval: interval,
610
+ defaultTimeFormat: defaultTimeFormat,
611
+ type: _constants.PLOT_TYPES.histogram,
612
+ aggregation: _constants.AGGREGATION_TYPES.sum
613
+ };
614
+ }
615
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZDNBcnJheSIsInJlcXVpcmUiLCJfbG9kYXNoIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl90aW1lIiwiX21vbWVudCIsIl9jb21tb25VdGlscyIsIl9jb25zdGFudHMiLCJfZGF0YVV0aWxzIiwiX2FnZ3JlZ2F0aW9uIiwiX3N0cmluZ3MiLCJfZm9ybWF0IiwiX2NvbG9yVXRpbHMiLCJfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlciIsInIiLCJlIiwidCIsIlN5bWJvbCIsIml0ZXJhdG9yIiwiQXJyYXkiLCJpc0FycmF5IiwiX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5IiwibGVuZ3RoIiwiX24iLCJGIiwicyIsIm4iLCJkb25lIiwidmFsdWUiLCJmIiwiVHlwZUVycm9yIiwibyIsImEiLCJ1IiwiY2FsbCIsIm5leHQiLCJfYXJyYXlMaWtlVG9BcnJheSIsInRvU3RyaW5nIiwic2xpY2UiLCJjb25zdHJ1Y3RvciIsIm5hbWUiLCJmcm9tIiwidGVzdCIsIm93bktleXMiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwiZmlsdGVyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5MiIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZGVmaW5lUHJvcGVydHkiLCJoaXN0b2dyYW1Gcm9tVGhyZXNob2xkIiwidGhyZXNob2xkcyIsInZhbHVlcyIsInZhbHVlQWNjZXNzb3IiLCJmaWx0ZXJFbXB0eUJpbnMiLCJ1bmRlZmluZWQiLCJnZXRCaW5zIiwiZDNIaXN0b2dyYW0iLCJkb21haW4iLCJiaW5zIiwibWFwIiwiYmluIiwiY291bnQiLCJpbmRleGVzIiwieDAiLCJ4MSIsImIiLCJoaXN0b2dyYW1Gcm9tVmFsdWVzIiwibnVtQmlucyIsImlzTnVtYmVyIiwiaGlzdG9ncmFtRnJvbURvbWFpbiIsInRpY2tzIiwiZ2V0VGltZUJpbnMiLCJkYXRhc2V0cyIsImludGVydmFsIiwidGltZUJpbnMiLCJkYXRhSWQiLCJkYXRhSWRJZHgiLCJkYXRhc2V0IiwicnVuR3B1RmlsdGVyRm9yUGxvdCIsImJpbkJ5VGltZSIsIm1hcHBlZFZhbHVlIiwiZ2V0RmlsdGVyTWFwcGVkVmFsdWUiLCJpbnRlcnZhbEJpbnMiLCJnZXRCaW5UaHJlc2hvbGRzIiwiaWR4IiwidGltZUludGVydmFsIiwiaW50ZXJ2YWxUb0Z1bmN0aW9uIiwiX2RvbWFpbiIsIl9zbGljZWRUb0FycmF5MiIsInQwIiwidDEiLCJmbG9vciIsImdldFRpbWUiLCJjZWlsaW5nIiwiY2VpbCIsImR1cmF0aW9uRGF5IiwiYmluVGhyZXNob2xkcyIsInJhbmdlIiwibW9tZW50IiwidXRjIiwidmFsdWVPZiIsImxhc3RTdGVwIiwib2Zmc2V0Iiwic2tpcEluZGV4ZXMiLCJnZXRTa2lwSW5kZXhlcyIsIl9kYXRhc2V0JGdwdUZpbHRlciIsImdwdUZpbHRlciIsImZpbHRlclZhbHVlVXBkYXRlVHJpZ2dlcnMiLCJmaWx0ZXJSYW5nZSIsImZpbHRlclZhbHVlQWNjZXNzb3IiLCJmaWx0ZXJlZEluZGV4IiwiZ2V0RmlsdGVyVmFsdWUiLCJkYXRhQ29udGFpbmVyIiwiYWxsQ2hhbm5lbHMiLCJfIiwiaSIsInNraXBBbGwiLCJpbmNsdWRlcyIsImZpbHRlckRhdGEiLCJnZXRGaWx0ZXJEYXRhRnVuYyIsImdwdUZpbHRlcnMiLCJ2YWx1ZUluZGV4IiwiZmluZEluZGV4IiwiaWQiLCJmaWx0ZXJDb2x1bW4iLCJyZWR1Y2UiLCJhY2N1IiwiaXRlbSIsInNraXBzIiwiaW5kZXgiLCJldmVyeSIsInZhbCIsInZhbGlkQmluIiwic25hcFRvTWFya3MiLCJtYXJrcyIsImJpc2VjdExlZnQiLCJub3JtYWxpemVWYWx1ZSIsIm1pblZhbHVlIiwic3RlcCIsInJvdW5kVmFsVG9TdGVwIiwiaXNQZXJjZW50RmllbGQiLCJmaWVsZCIsIm1ldGFkYXRhIiwibnVtZXJhdG9yIiwiZGVub21pbmF0b3IiLCJ1cGRhdGVBZ2dyZWdhdGlvbkJ5RmllbGQiLCJhZ2dyZWdhdGlvbiIsIkFHR1JFR0FUSU9OX1RZUEVTIiwiYXZlcmFnZSIsImdldEFncmVnYXRpb25UeXBlIiwiZ2V0QWdncmVnYXRpb25BY2Nlc3NvciIsImZpZWxkcyIsIm51bWVyYXRvcklkeCIsImRlbm9taW5hdG9ySWR4IiwiZ2V0TnVtZXJhdG9yIiwidmFsdWVBdCIsImdldERlbm9taW5hdG9yIiwiZ2V0VmFsdWVBZ2dyRnVuYyIsImV4cG9ydHMiLCJkYXRhc2V0RmllbGQiLCJmaW5kIiwiYWdncmVnYXRlIiwiZ2V0QWdncmVnYXRpb25PcHRpb3NuQmFzZWRPbkZpZWxkIiwiVElNRV9BR0dSRUdBVElPTiIsIl9yZWYiLCJzdW0iLCJnZXREZWx0YSIsInkiLCJsYXN0QmluIiwiZGVsdGEiLCJwY3QiLCJnZXRQY3RDaGFuZ2UiLCJ5MCIsIk51bWJlciIsImlzRmluaXRlIiwiZ2V0TGluZUNoYXJ0IiwiX3RpbWVCaW5zIiwieUF4aXMiLCJwbG90VHlwZSIsImxpbmVDaGFydCIsInNlcmllc0RhdGFJZCIsImlzRXF1YWwiLCJnZXRZVmFsdWUiLCJpbml0Iiwic2VyaWVzIiwieCIsInlEb21haW4iLCJleHRlbnQiLCJkIiwieERvbWFpbiIsInNwbGl0Iiwic3BsaXRTZXJpZXMiLCJhZ2dyTmFtZSIsIkFHR1JFR0FUSU9OX05BTUUiLCJ0aXRsZSIsImNvbmNhdCIsImZpZWxkVHlwZSIsInR5cGUiLCJhbGxUaW1lIiwibGluZXMiLCJ0ZW1wIiwibm90TnVsbG9yVW5kZWZpbmVkIiwibWFya2VycyIsImFkanVzdFZhbHVlVG9BbmltYXRpb25XaW5kb3ciLCJzdGF0ZSIsIl9maWx0ZXIkdmFsdWUiLCJ2YWx1ZTAiLCJ2YWx1ZTEiLCJhbmltYXRpb25XaW5kb3ciLCJnZXRJbml0aWFsSW50ZXJ2YWwiLCJkYXRhc2V0QmlucyIsInZhbDAiLCJ2YWwxIiwiQU5JTUFUSU9OX1dJTkRPVyIsImluZGV4T2YiLCJOYU4iLCJ1cGRhdGVkRmlsdGVyIiwiZ2V0RmlsdGVyUGxvdENvbG9yc0J5RGF0YUlkIiwib2xkQ29sb3JzQnlEYXRhSWQiLCJjb2xvcnNCeURhdGFJZCIsIl9pdGVyYXRvciIsIl9zdGVwIiwicmdiVG9IZXgiLCJjb2xvciIsImVyciIsInVwZGF0ZVRpbWVGaWx0ZXJQbG90VHlwZSIsIm5leHRGaWx0ZXIiLCJuZXh0UGxvdFR5cGUiLCJfdHlwZW9mMiIsImdldERlZmF1bHRQbG90VHlwZSIsIlBMT1RfVFlQRVMiLCJoaXN0b2dyYW0iLCJnZXRSYW5nZUZpbHRlckJpbnMiLCJhY2MiLCJkYXRhc2V0SWR4IiwiX2ZpbHRlciRiaW5zIiwiZmllbGROYW1lIiwiZ2V0Q29sdW1uRmllbGQiLCJ1cGRhdGVSYW5nZUZpbHRlclBsb3RUeXBlIiwiQklOUyIsImdldENoYXJ0VGl0bGUiLCJ5QXhpc05hbWUiLCJkaXNwbGF5TmFtZSIsImNhcGl0YWxpemVGaXJzdExldHRlciIsImRlZmF1bHRUaW1lRm9ybWF0IiwiZ2V0RGVmYXVsdFRpbWVGb3JtYXQiXSwic291cmNlcyI6WyIuLi9zcmMvcGxvdC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge2Jpc2VjdExlZnQsIGV4dGVudCwgaGlzdG9ncmFtIGFzIGQzSGlzdG9ncmFtLCB0aWNrc30gZnJvbSAnZDMtYXJyYXknO1xuaW1wb3J0IGlzRXF1YWwgZnJvbSAnbG9kYXNoLmlzZXF1YWwnO1xuaW1wb3J0IHtnZXRGaWx0ZXJNYXBwZWRWYWx1ZSwgZ2V0SW5pdGlhbEludGVydmFsLCBpbnRlcnZhbFRvRnVuY3Rpb259IGZyb20gJy4vdGltZSc7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQge1xuICBCaW4sXG4gIFRpbWVCaW5zLFxuICBNaWxsaXNlY29uZCxcbiAgVGltZVJhbmdlRmlsdGVyLFxuICBSYW5nZUZpbHRlcixcbiAgUGxvdFR5cGUsXG4gIEZpbHRlcixcbiAgTGluZUNoYXJ0LFxuICBGaWVsZCxcbiAgVmFsdWVPZixcbiAgTGluZURhdHVtXG59IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuaW1wb3J0IHtub3ROdWxsb3JVbmRlZmluZWR9IGZyb20gJ0BrZXBsZXIuZ2wvY29tbW9uLXV0aWxzJztcbmltcG9ydCB7XG4gIEFOSU1BVElPTl9XSU5ET1csXG4gIEJJTlMsXG4gIGR1cmF0aW9uRGF5LFxuICBUSU1FX0FHR1JFR0FUSU9OLFxuICBBR0dSRUdBVElPTl9UWVBFUyxcbiAgUExPVF9UWVBFUyxcbiAgQWdncmVnYXRpb25UeXBlc1xufSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5cbmltcG9ydCB7aXNOdW1iZXIsIHJvdW5kVmFsVG9TdGVwfSBmcm9tICcuL2RhdGEtdXRpbHMnO1xuaW1wb3J0IHthZ2dyZWdhdGUsIEFHR1JFR0FUSU9OX05BTUV9IGZyb20gJy4vYWdncmVnYXRpb24nO1xuaW1wb3J0IHtjYXBpdGFsaXplRmlyc3RMZXR0ZXJ9IGZyb20gJy4vc3RyaW5ncyc7XG5pbXBvcnQge2dldERlZmF1bHRUaW1lRm9ybWF0fSBmcm9tICcuL2Zvcm1hdCc7XG5pbXBvcnQge3JnYlRvSGV4fSBmcm9tICcuL2NvbG9yLXV0aWxzJztcbmltcG9ydCB7RGF0YUNvbnRhaW5lckludGVyZmFjZX0gZnJvbSAnLic7XG5pbXBvcnQge0tlcGxlclRhYmxlTW9kZWx9IGZyb20gJy4vdHlwZXMnO1xuXG4vLyBUT0RPIGtlcGxlci10YWJsZSBtb2R1bGUgaXNuJ3QgYWNjZXNzaWJsZSBmcm9tIHV0aWxzLiBBZGQgY29tcGF0aWJsZSBpbnRlcmZhY2UgdG8gdHlwZXNcbnR5cGUgRGF0YXNldHMgPSBhbnk7XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB0aHJlc2hvbGRzXG4gKiBAcGFyYW0gdmFsdWVzXG4gKiBAcGFyYW0gaW5kZXhlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gaGlzdG9ncmFtRnJvbVRocmVzaG9sZChcbiAgdGhyZXNob2xkczogbnVtYmVyW10sXG4gIHZhbHVlczogbnVtYmVyW10sXG4gIHZhbHVlQWNjZXNzb3I/OiAoZDogdW5rbm93bikgPT4gbnVtYmVyLFxuICBmaWx0ZXJFbXB0eUJpbnMgPSB0cnVlXG4pOiBCaW5bXSB7XG4gIGNvbnN0IGdldEJpbnMgPSBkM0hpc3RvZ3JhbSgpXG4gICAgLmRvbWFpbihbdGhyZXNob2xkc1swXSwgdGhyZXNob2xkc1t0aHJlc2hvbGRzLmxlbmd0aCAtIDFdXSlcbiAgICAudGhyZXNob2xkcyh0aHJlc2hvbGRzKTtcblxuICBpZiAodmFsdWVBY2Nlc3Nvcikge1xuICAgIGdldEJpbnMudmFsdWUodmFsdWVBY2Nlc3Nvcik7XG4gIH1cblxuICAvLyBAdHMtaWdub3JlXG4gIGNvbnN0IGJpbnMgPSBnZXRCaW5zKHZhbHVlcykubWFwKGJpbiA9PiAoe1xuICAgIGNvdW50OiBiaW4ubGVuZ3RoLFxuICAgIGluZGV4ZXM6IGJpbixcbiAgICB4MDogYmluLngwLFxuICAgIHgxOiBiaW4ueDFcbiAgfSkpO1xuXG4gIC8vIGQzLWhpc3RvZ3JhbSBpZ25vcmVzIHRocmVzaG9sZCB2YWx1ZXMgb3V0c2lkZSB0aGUgZG9tYWluXG4gIC8vIFRoZSBmaXJzdCBiaW4ueDAgaXMgYWx3YXlzIGVxdWFsIHRvIHRoZSBtaW5pbXVtIGRvbWFpbiB2YWx1ZSwgYW5kIHRoZSBsYXN0IGJpbi54MSBpcyBhbHdheXMgZXF1YWwgdG8gdGhlIG1heGltdW0gZG9tYWluIHZhbHVlLlxuXG4gIC8vIGJpbnNbMF0ueDAgPSB0aHJlc2hvbGRzWzBdO1xuICAvLyBiaW5zW2JpbnMubGVuZ3RoIC0gMV0ueDEgPSB0aHJlc2hvbGRzW3RocmVzaG9sZHMubGVuZ3RoIC0gMV07XG5cbiAgLy8gQHRzLWlnbm9yZVxuICByZXR1cm4gZmlsdGVyRW1wdHlCaW5zID8gYmlucy5maWx0ZXIoYiA9PiBiLmNvdW50ID4gMCkgOiBiaW5zO1xufVxuXG4vKipcbiAqXG4gKiBAcGFyYW0gdmFsdWVzXG4gKiBAcGFyYW0gbnVtQmluc1xuICogQHBhcmFtIHZhbHVlQWNjZXNzb3JcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhpc3RvZ3JhbUZyb21WYWx1ZXMoXG4gIHZhbHVlczogKE1pbGxpc2Vjb25kIHwgbnVsbCB8IG51bWJlcilbXSxcbiAgbnVtQmluczogbnVtYmVyLFxuICB2YWx1ZUFjY2Vzc29yPzogKGQ6IHVua25vd24pID0+IG51bWJlclxuKSB7XG4gIGNvbnN0IGdldEJpbnMgPSBkM0hpc3RvZ3JhbSgpLnRocmVzaG9sZHMobnVtQmlucyk7XG5cbiAgaWYgKHZhbHVlQWNjZXNzb3IpIHtcbiAgICBnZXRCaW5zLnZhbHVlKHZhbHVlQWNjZXNzb3IpO1xuICB9XG5cbiAgLy8gQHRzLWlnbm9yZSBkMy1hcnJheSB0eXBlcyBkb2Vzbid0IG1hdGNoXG4gIHJldHVybiBnZXRCaW5zKHZhbHVlcylcbiAgICAubWFwKGJpbiA9PiAoe1xuICAgICAgY291bnQ6IGJpbi5sZW5ndGgsXG4gICAgICBpbmRleGVzOiBiaW4sXG4gICAgICB4MDogYmluLngwLFxuICAgICAgeDE6IGJpbi54MVxuICAgIH0pKVxuICAgIC5maWx0ZXIoYiA9PiB7XG4gICAgICBjb25zdCB7eDAsIHgxfSA9IGI7XG4gICAgICByZXR1cm4gaXNOdW1iZXIoeDApICYmIGlzTnVtYmVyKHgxKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKlxuICogQHBhcmFtIGRvbWFpblxuICogQHBhcmFtIHZhbHVlc1xuICogQHBhcmFtIG51bUJpbnNcbiAqIEBwYXJhbSB2YWx1ZUFjY2Vzc29yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoaXN0b2dyYW1Gcm9tRG9tYWluKFxuICBkb21haW46IFtudW1iZXIsIG51bWJlcl0sXG4gIHZhbHVlczogKE1pbGxpc2Vjb25kIHwgbnVsbCB8IG51bWJlcilbXSxcbiAgbnVtQmluczogbnVtYmVyLFxuICB2YWx1ZUFjY2Vzc29yPzogKGQ6IHVua25vd24pID0+IG51bWJlclxuKTogQmluW10ge1xuICBjb25zdCBnZXRCaW5zID0gZDNIaXN0b2dyYW0oKS50aHJlc2hvbGRzKHRpY2tzKGRvbWFpblswXSwgZG9tYWluWzFdLCBudW1CaW5zKSkuZG9tYWluKGRvbWFpbik7XG4gIGlmICh2YWx1ZUFjY2Vzc29yKSB7XG4gICAgZ2V0Qmlucy52YWx1ZSh2YWx1ZUFjY2Vzc29yKTtcbiAgfVxuXG4gIC8vIEB0cy1pZ25vcmUgZDMtYXJyYXkgdHlwZXMgZG9lc24ndCBtYXRjaFxuICByZXR1cm4gZ2V0Qmlucyh2YWx1ZXMpLm1hcChiaW4gPT4gKHtcbiAgICBjb3VudDogYmluLmxlbmd0aCxcbiAgICBpbmRleGVzOiBiaW4sXG4gICAgeDA6IGJpbi54MCxcbiAgICB4MTogYmluLngxXG4gIH0pKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0gZmlsdGVyXG4gKiBAcGFyYW0gZGF0YXNldHNcbiAqIEBwYXJhbSBpbnRlcnZhbFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGltZUJpbnMoXG4gIGZpbHRlcjogVGltZVJhbmdlRmlsdGVyLFxuICBkYXRhc2V0czogRGF0YXNldHMsXG4gIGludGVydmFsOiBQbG90VHlwZVsnaW50ZXJ2YWwnXVxuKTogVGltZUJpbnMge1xuICBsZXQgYmlucyA9IGZpbHRlci50aW1lQmlucyB8fCB7fTtcblxuICBmaWx0ZXIuZGF0YUlkLmZvckVhY2goKGRhdGFJZCwgZGF0YUlkSWR4KSA9PiB7XG4gICAgLy8gcmV1c2UgYmlucyBpZiBmaWx0ZXJEYXRhIGRpZCBub3QgY2hhbmdlXG4gICAgaWYgKGJpbnNbZGF0YUlkXSAmJiBiaW5zW2RhdGFJZF1baW50ZXJ2YWxdKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGRhdGFzZXQgPSBkYXRhc2V0c1tkYXRhSWRdO1xuXG4gICAgLy8gZG8gbm90IGFwcGx5IGN1cnJlbnQgZmlsdGVyXG4gICAgY29uc3QgaW5kZXhlcyA9IHJ1bkdwdUZpbHRlckZvclBsb3QoZGF0YXNldCwgZmlsdGVyKTtcblxuICAgIGJpbnMgPSB7XG4gICAgICAuLi5iaW5zLFxuICAgICAgW2RhdGFJZF06IHtcbiAgICAgICAgLi4uYmluc1tkYXRhSWRdLFxuICAgICAgICBbaW50ZXJ2YWxdOiBiaW5CeVRpbWUoaW5kZXhlcywgZGF0YXNldCwgaW50ZXJ2YWwsIGZpbHRlcilcbiAgICAgIH1cbiAgICB9O1xuICB9KTtcblxuICByZXR1cm4gYmlucztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJpbkJ5VGltZShpbmRleGVzLCBkYXRhc2V0LCBpbnRlcnZhbCwgZmlsdGVyKSB7XG4gIC8vIGdwdUZpbHRlcnMgbmVlZCB0byBiZSBhcHBseSB0byBmaWx0ZXJlZEluZGV4XG4gIGNvbnN0IG1hcHBlZFZhbHVlID0gZ2V0RmlsdGVyTWFwcGVkVmFsdWUoZGF0YXNldCwgZmlsdGVyKTtcbiAgaWYgKCFtYXBwZWRWYWx1ZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGNvbnN0IGludGVydmFsQmlucyA9IGdldEJpblRocmVzaG9sZHMoaW50ZXJ2YWwsIGZpbHRlci5kb21haW4pO1xuICBjb25zdCB2YWx1ZUFjY2Vzc29yID0gaWR4ID0+IG1hcHBlZFZhbHVlW2lkeF07XG4gIGNvbnN0IGJpbnMgPSBoaXN0b2dyYW1Gcm9tVGhyZXNob2xkKGludGVydmFsQmlucywgaW5kZXhlcywgdmFsdWVBY2Nlc3Nvcik7XG5cbiAgcmV0dXJuIGJpbnM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCaW5UaHJlc2hvbGRzKGludGVydmFsOiBzdHJpbmcsIGRvbWFpbjogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gIGNvbnN0IHRpbWVJbnRlcnZhbCA9IGludGVydmFsVG9GdW5jdGlvbihpbnRlcnZhbCk7XG4gIGNvbnN0IFt0MCwgdDFdID0gZG9tYWluO1xuICBjb25zdCBmbG9vciA9IHRpbWVJbnRlcnZhbC5mbG9vcih0MCkuZ2V0VGltZSgpO1xuICBjb25zdCBjZWlsaW5nID0gdGltZUludGVydmFsLmNlaWwodDEpLmdldFRpbWUoKTtcblxuICBpZiAoIXRpbWVJbnRlcnZhbCkge1xuICAgIC8vIGlmIHRpbWUgaW50ZXJ2YWwgaXMgbm90IGRlZmluZWRcbiAgICAvLyB0aGlzIHNob3VsZCBub3QgaGFwcGVuXG4gICAgcmV0dXJuIFt0MCwgdDAgKyBkdXJhdGlvbkRheV07XG4gIH1cbiAgY29uc3QgYmluVGhyZXNob2xkcyA9IHRpbWVJbnRlcnZhbC5yYW5nZShmbG9vciwgY2VpbGluZyArIDEpLm1hcCh0ID0+IG1vbWVudC51dGModCkudmFsdWVPZigpKTtcbiAgY29uc3QgbGFzdFN0ZXAgPSBiaW5UaHJlc2hvbGRzW2JpblRocmVzaG9sZHMubGVuZ3RoIC0gMV07XG4gIGlmIChsYXN0U3RlcCA9PT0gdDEpIHtcbiAgICAvLyB3aGVuIGxhc3Qgc3RlcCBlcXVhbCB0byBkb21haW4gbWF4LCBhZGQgb25lIG1vcmUgc3RlcFxuICAgIGJpblRocmVzaG9sZHMucHVzaChtb21lbnQudXRjKHRpbWVJbnRlcnZhbC5vZmZzZXQobGFzdFN0ZXApKS52YWx1ZU9mKCkpO1xuICB9XG5cbiAgcmV0dXJuIGJpblRocmVzaG9sZHM7XG59XG5cbi8qKlxuICogUnVuIEdQVSBmaWx0ZXIgb24gY3VycmVudCBmaWx0ZXIgcmVzdWx0IHRvIGdlbmVyYXRlIGluZGV4ZXMgZm9yIHBsb3RpbmcgY2hhcnRcbiAqIFNraXAgcnV1bmluZyBmb3IgdGhlIHNhbWUgZmllbGRcbiAqIEBwYXJhbSBkYXRhc2V0XG4gKiBAcGFyYW0gZmlsdGVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBydW5HcHVGaWx0ZXJGb3JQbG90PEsgZXh0ZW5kcyBLZXBsZXJUYWJsZU1vZGVsPEssIEw+LCBMPihcbiAgZGF0YXNldDogSyxcbiAgZmlsdGVyPzogRmlsdGVyXG4pOiBudW1iZXJbXSB7XG4gIGNvbnN0IHNraXBJbmRleGVzID0gZ2V0U2tpcEluZGV4ZXMoZGF0YXNldCwgZmlsdGVyKTtcblxuICBjb25zdCB7XG4gICAgZ3B1RmlsdGVyOiB7ZmlsdGVyVmFsdWVVcGRhdGVUcmlnZ2VycywgZmlsdGVyUmFuZ2UsIGZpbHRlclZhbHVlQWNjZXNzb3J9LFxuICAgIGZpbHRlcmVkSW5kZXhcbiAgfSA9IGRhdGFzZXQ7XG4gIGNvbnN0IGdldEZpbHRlclZhbHVlID0gZmlsdGVyVmFsdWVBY2Nlc3NvcihkYXRhc2V0LmRhdGFDb250YWluZXIpKCk7XG5cbiAgY29uc3QgYWxsQ2hhbm5lbHMgPSBPYmplY3Qua2V5cyhmaWx0ZXJWYWx1ZVVwZGF0ZVRyaWdnZXJzKVxuICAgIC5tYXAoKF8sIGkpID0+IGkpXG4gICAgLmZpbHRlcihpID0+IE9iamVjdC52YWx1ZXMoZmlsdGVyVmFsdWVVcGRhdGVUcmlnZ2VycylbaV0pO1xuICBjb25zdCBza2lwQWxsID0gIWFsbENoYW5uZWxzLmZpbHRlcihpID0+ICFza2lwSW5kZXhlcy5pbmNsdWRlcyhpKSkubGVuZ3RoO1xuICBpZiAoc2tpcEFsbCkge1xuICAgIHJldHVybiBmaWx0ZXJlZEluZGV4O1xuICB9XG5cbiAgY29uc3QgZmlsdGVyRGF0YSA9IGdldEZpbHRlckRhdGFGdW5jKFxuICAgIGZpbHRlclJhbmdlLFxuICAgIGdldEZpbHRlclZhbHVlLFxuICAgIGRhdGFzZXQuZGF0YUNvbnRhaW5lcixcbiAgICBza2lwSW5kZXhlc1xuICApO1xuXG4gIHJldHVybiBmaWx0ZXJlZEluZGV4LmZpbHRlcihmaWx0ZXJEYXRhKTtcbn1cblxuZnVuY3Rpb24gZ2V0U2tpcEluZGV4ZXMoZGF0YXNldCwgZmlsdGVyKSB7XG4gIC8vIGFycmF5IG9mIGdwdSBmaWx0ZXIgbmFtZXNcbiAgaWYgKCFmaWx0ZXIpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgY29uc3QgZ3B1RmlsdGVycyA9IE9iamVjdC52YWx1ZXMoZGF0YXNldC5ncHVGaWx0ZXIuZmlsdGVyVmFsdWVVcGRhdGVUcmlnZ2VycykgYXMgKHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gIH0gfCBudWxsKVtdO1xuICBjb25zdCB2YWx1ZUluZGV4ID0gZmlsdGVyLmRhdGFJZC5maW5kSW5kZXgoaWQgPT4gaWQgPT09IGRhdGFzZXQuaWQpO1xuICBjb25zdCBmaWx0ZXJDb2x1bW4gPSBmaWx0ZXIubmFtZVt2YWx1ZUluZGV4XTtcblxuICByZXR1cm4gZ3B1RmlsdGVycy5yZWR1Y2UoKGFjY3UsIGl0ZW0sIGlkeCkgPT4ge1xuICAgIGlmIChpdGVtICYmIGZpbHRlckNvbHVtbiA9PT0gaXRlbS5uYW1lKSB7XG4gICAgICBhY2N1LnB1c2goaWR4KTtcbiAgICB9XG4gICAgcmV0dXJuIGFjY3U7XG4gIH0sIFtdIGFzIG51bWJlcltdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZpbHRlckRhdGFGdW5jKFxuICBmaWx0ZXJSYW5nZSxcbiAgZ2V0RmlsdGVyVmFsdWUsXG4gIGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2UsXG4gIHNraXBzXG4pIHtcbiAgcmV0dXJuIGluZGV4ID0+XG4gICAgZ2V0RmlsdGVyVmFsdWUoe2luZGV4fSkuZXZlcnkoXG4gICAgICAodmFsLCBpKSA9PiBza2lwcy5pbmNsdWRlcyhpKSB8fCAodmFsID49IGZpbHRlclJhbmdlW2ldWzBdICYmIHZhbCA8PSBmaWx0ZXJSYW5nZVtpXVsxXSlcbiAgICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRCaW4oYikge1xuICByZXR1cm4gYi54MCAhPT0gdW5kZWZpbmVkICYmIGIueDEgIT09IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBVc2UgaW4gc2xpZGVyLCBnaXZlbiBhIG51bWJlciBhbmQgYW4gYXJyYXkgb2YgbnVtYmVycywgcmV0dXJuIHRoZSBuZWFycyBudW1iZXIgZnJvbSB0aGUgYXJyYXkuXG4gKiBUYWtlcyBhIHZhbHVlLCB0aW1lc3RlcHMgYW5kIHJldHVybiB0aGUgYWN0dWFsIHN0ZXAuXG4gKiBAcGFyYW0gdmFsdWVcbiAqIEBwYXJhbSBtYXJrc1xuICovXG5leHBvcnQgZnVuY3Rpb24gc25hcFRvTWFya3ModmFsdWU6IG51bWJlciwgbWFya3M6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgLy8gYWx3YXlzIHVzZSBiaW4geDBcbiAgaWYgKCFtYXJrcy5sZW5ndGgpIHtcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGxvb2tpbmcgYXQgdGhlIHVzYWdlIG51bGwgcmV0dXJuIHZhbHVlIGlzbid0IGV4cGVjdGVkIGFuZCByZXF1aXJlcyBleHRyYSBoYW5kbGluZyBpbiBhIGxvdCBvZiBwbGFjZXNcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCBpID0gYmlzZWN0TGVmdChtYXJrcywgdmFsdWUpO1xuICBpZiAoaSA9PT0gMCkge1xuICAgIHJldHVybiBtYXJrc1tpXTtcbiAgfSBlbHNlIGlmIChpID09PSBtYXJrcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gbWFya3NbaSAtIDFdO1xuICB9XG4gIGNvbnN0IGlkeCA9IG1hcmtzW2ldIC0gdmFsdWUgPCB2YWx1ZSAtIG1hcmtzW2kgLSAxXSA/IGkgOiBpIC0gMTtcbiAgcmV0dXJuIG1hcmtzW2lkeF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVWYWx1ZSh2YWwsIG1pblZhbHVlLCBzdGVwLCBtYXJrcykge1xuICBpZiAobWFya3MgJiYgbWFya3MubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHNuYXBUb01hcmtzKHZhbCwgbWFya3MpO1xuICB9XG5cbiAgcmV0dXJuIHJvdW5kVmFsVG9TdGVwKG1pblZhbHVlLCBzdGVwLCB2YWwpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQZXJjZW50RmllbGQoZmllbGQpIHtcbiAgcmV0dXJuIGZpZWxkLm1ldGFkYXRhICYmIGZpZWxkLm1ldGFkYXRhLm51bWVyYXRvciAmJiBmaWVsZC5tZXRhZGF0YS5kZW5vbWluYXRvcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUFnZ3JlZ2F0aW9uQnlGaWVsZChmaWVsZDogRmllbGQsIGFnZ3JlZ2F0aW9uOiBWYWx1ZU9mPEFnZ3JlZ2F0aW9uVHlwZXM+KSB7XG4gIC8vIHNob3VsZG4ndCBhcHBseSBzdW0gdG8gcGVyY2VudCBmaWVsZSB0eXBlXG4gIC8vIGRlZmF1bHQgYWdncmVnYXRpb24gaXMgYXZlcmFnZVxuICByZXR1cm4gZmllbGQgJiYgaXNQZXJjZW50RmllbGQoZmllbGQpXG4gICAgPyBBR0dSRUdBVElPTl9UWVBFUy5hdmVyYWdlXG4gICAgOiBhZ2dyZWdhdGlvbiB8fCBBR0dSRUdBVElPTl9UWVBFUy5hdmVyYWdlO1xufVxuXG5jb25zdCBnZXRBZ3JlZ2F0aW9uVHlwZSA9IChmaWVsZCwgYWdncmVnYXRpb24pID0+IHtcbiAgaWYgKGlzUGVyY2VudEZpZWxkKGZpZWxkKSkge1xuICAgIHJldHVybiAnbWVhbl9vZl9wZXJjZW50JztcbiAgfVxuICByZXR1cm4gYWdncmVnYXRpb247XG59O1xuXG5jb25zdCBnZXRBZ2dyZWdhdGlvbkFjY2Vzc29yID0gKGZpZWxkLCBkYXRhQ29udGFpbmVyOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlLCBmaWVsZHMpID0+IHtcbiAgaWYgKGlzUGVyY2VudEZpZWxkKGZpZWxkKSkge1xuICAgIGNvbnN0IG51bWVyYXRvcklkeCA9IGZpZWxkcy5maW5kSW5kZXgoZiA9PiBmLm5hbWUgPT09IGZpZWxkLm1ldGFkYXRhLm51bWVyYXRvcik7XG4gICAgY29uc3QgZGVub21pbmF0b3JJZHggPSBmaWVsZHMuZmluZEluZGV4KGYgPT4gZi5uYW1lID09PSBmaWVsZC5tZXRhZGF0YS5kZW5vbWluYXRvcik7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZ2V0TnVtZXJhdG9yOiBpID0+IGRhdGFDb250YWluZXIudmFsdWVBdChpLCBudW1lcmF0b3JJZHgpLFxuICAgICAgZ2V0RGVub21pbmF0b3I6IGkgPT4gZGF0YUNvbnRhaW5lci52YWx1ZUF0KGksIGRlbm9taW5hdG9ySWR4KVxuICAgIH07XG4gIH1cblxuICByZXR1cm4gaSA9PiBmaWVsZC52YWx1ZUFjY2Vzc29yKHtpbmRleDogaX0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFZhbHVlQWdnckZ1bmMgPSAoXG4gIGZpZWxkOiBGaWVsZCB8IHN0cmluZyB8IG51bGwsXG4gIGFnZ3JlZ2F0aW9uOiBzdHJpbmcsXG4gIGRhdGFzZXQ6IEtlcGxlclRhYmxlTW9kZWw8YW55LCBhbnk+XG4pOiAoKGJpbjogQmluKSA9PiBudW1iZXIpID0+IHtcbiAgY29uc3Qge2RhdGFDb250YWluZXIsIGZpZWxkc30gPSBkYXRhc2V0O1xuXG4gIC8vIFRoZSBwYXNzZWQtaW4gZmllbGQgbWlnaHQgbm90IGhhdmUgYWxsIHRoZSBmaWVsZHMgc2V0IChlLmcuIHZhbHVlQWNjZXNzb3IpXG4gIGNvbnN0IGRhdGFzZXRGaWVsZCA9IGZpZWxkcy5maW5kKFxuICAgIGYgPT4gZmllbGQgJiYgKGYubmFtZSA9PT0gZmllbGQgfHwgZi5uYW1lID09PSAoZmllbGQgYXMgRmllbGQpLm5hbWUpXG4gICk7XG5cbiAgcmV0dXJuIGRhdGFzZXRGaWVsZCAmJiBhZ2dyZWdhdGlvblxuICAgID8gYmluID0+XG4gICAgICAgIGFnZ3JlZ2F0ZShcbiAgICAgICAgICBiaW4uaW5kZXhlcyxcbiAgICAgICAgICBnZXRBZ3JlZ2F0aW9uVHlwZShkYXRhc2V0RmllbGQsIGFnZ3JlZ2F0aW9uKSxcbiAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGNhbiByZXR1cm4ge2dldE51bWVyYXRvciwgZ2V0RGVub21pbmF0b3J9XG4gICAgICAgICAgZ2V0QWdncmVnYXRpb25BY2Nlc3NvcihkYXRhc2V0RmllbGQsIGRhdGFDb250YWluZXIsIGZpZWxkcylcbiAgICAgICAgKVxuICAgIDogYmluID0+IGJpbi5jb3VudDtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRBZ2dyZWdhdGlvbk9wdGlvc25CYXNlZE9uRmllbGQgPSBmaWVsZCA9PiB7XG4gIGlmIChpc1BlcmNlbnRGaWVsZChmaWVsZCkpIHtcbiAgICAvLyBkb24ndCBzaG93IHN1bVxuICAgIHJldHVybiBUSU1FX0FHR1JFR0FUSU9OLmZpbHRlcigoe2lkfSkgPT4gaWQgIT09IEFHR1JFR0FUSU9OX1RZUEVTLnN1bSk7XG4gIH1cbiAgcmV0dXJuIFRJTUVfQUdHUkVHQVRJT047XG59O1xuXG5mdW5jdGlvbiBnZXREZWx0YShcbiAgYmluczogTGluZURhdHVtW10sXG4gIHk6IG51bWJlcixcbiAgaW50ZXJ2YWw6IFBsb3RUeXBlWydpbnRlcnZhbCddXG4pOiBQYXJ0aWFsPExpbmVEYXR1bT4gJiB7ZGVsdGE6ICdsYXN0JzsgcGN0OiBudW1iZXIgfCBudWxsfSB7XG4gIC8vIGlmIChXT1dbaW50ZXJ2YWxdKSByZXR1cm4gZ2V0V293KGJpbnMsIHksIGludGVydmFsKTtcbiAgY29uc3QgbGFzdEJpbiA9IGJpbnNbYmlucy5sZW5ndGggLSAxXTtcblxuICByZXR1cm4ge1xuICAgIGRlbHRhOiAnbGFzdCcsXG4gICAgcGN0OiBsYXN0QmluID8gZ2V0UGN0Q2hhbmdlKHksIGxhc3RCaW4ueSkgOiBudWxsXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQY3RDaGFuZ2UoeTogdW5rbm93biwgeTA6IHVua25vd24pOiBudW1iZXIgfCBudWxsIHtcbiAgaWYgKE51bWJlci5pc0Zpbml0ZSh5KSAmJiBOdW1iZXIuaXNGaW5pdGUoeTApICYmIHkwICE9PSAwKSB7XG4gICAgcmV0dXJuICgoeSBhcyBudW1iZXIpIC0gKHkwIGFzIG51bWJlcikpIC8gKHkwIGFzIG51bWJlcik7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICpcbiAqIEBwYXJhbSBkYXRhc2V0c1xuICogQHBhcmFtIGZpbHRlclxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGluZUNoYXJ0KGRhdGFzZXRzOiBEYXRhc2V0cywgZmlsdGVyOiBGaWx0ZXIpOiBMaW5lQ2hhcnQge1xuICBjb25zdCB7ZGF0YUlkLCB5QXhpcywgcGxvdFR5cGUsIGxpbmVDaGFydH0gPSBmaWx0ZXI7XG4gIGNvbnN0IHthZ2dyZWdhdGlvbiwgaW50ZXJ2YWx9ID0gcGxvdFR5cGU7XG4gIGNvbnN0IHNlcmllc0RhdGFJZCA9IGRhdGFJZFswXTtcbiAgY29uc3QgYmlucyA9IChmaWx0ZXIgYXMgVGltZVJhbmdlRmlsdGVyKS50aW1lQmlucz8uW3Nlcmllc0RhdGFJZF0/LltpbnRlcnZhbF07XG5cbiAgaWYgKFxuICAgIGxpbmVDaGFydCAmJlxuICAgIGxpbmVDaGFydC5hZ2dyZWdhdGlvbiA9PT0gYWdncmVnYXRpb24gJiZcbiAgICBsaW5lQ2hhcnQuaW50ZXJ2YWwgPT09IGludGVydmFsICYmXG4gICAgbGluZUNoYXJ0LnlBeGlzID09PSB5QXhpcz8ubmFtZSAmJlxuICAgIC8vIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHdlIHZhbGlkYXRlIGJpbnMgYmVjYXVzZSBvZiBjcm9zcyBmaWx0ZXIgZGF0YSBjaGFuZ2VzXG4gICAgaXNFcXVhbChiaW5zLCBsaW5lQ2hhcnQ/LmJpbnMpXG4gICkge1xuICAgIC8vIGRvbid0IHVwZGF0ZSBsaW5lQ2hhcnQgaWYgcGxvdFR5cGUgaGFzbid0IGNoYW5nZVxuICAgIHJldHVybiBsaW5lQ2hhcnQ7XG4gIH1cblxuICBjb25zdCBkYXRhc2V0ID0gZGF0YXNldHNbc2VyaWVzRGF0YUlkXTtcbiAgY29uc3QgZ2V0WVZhbHVlID0gZ2V0VmFsdWVBZ2dyRnVuYyh5QXhpcywgYWdncmVnYXRpb24sIGRhdGFzZXQpO1xuXG4gIGNvbnN0IGluaXQ6IExpbmVEYXR1bVtdID0gW107XG4gIGNvbnN0IHNlcmllcyA9IChiaW5zIHx8IFtdKS5yZWR1Y2UoKGFjY3UsIGJpbiwgaSkgPT4ge1xuICAgIGNvbnN0IHkgPSBnZXRZVmFsdWUoYmluKTtcbiAgICBjb25zdCBkZWx0YSA9IGdldERlbHRhKGFjY3UsIHksIGludGVydmFsKTtcbiAgICBhY2N1LnB1c2goe1xuICAgICAgeDogYmluLngwLFxuICAgICAgeSxcbiAgICAgIC4uLmRlbHRhXG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3U7XG4gIH0sIGluaXQpO1xuXG4gIGNvbnN0IHlEb21haW4gPSBleHRlbnQ8e3k6IGFueX0+KHNlcmllcywgZCA9PiBkLnkpO1xuICBjb25zdCB4RG9tYWluID0gYmlucyA/IFtiaW5zWzBdLngwLCBiaW5zW2JpbnMubGVuZ3RoIC0gMV0ueDFdIDogW107XG5cbiAgLy8gdHJlYXQgbWlzc2luZyBkYXRhIGFzIGFub3RoZXIgc2VyaWVzXG4gIGNvbnN0IHNwbGl0ID0gc3BsaXRTZXJpZXMoc2VyaWVzKTtcbiAgY29uc3QgYWdnck5hbWUgPSBBR0dSRUdBVElPTl9OQU1FW2FnZ3JlZ2F0aW9uXTtcblxuICByZXR1cm4ge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICB5RG9tYWluLFxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICB4RG9tYWluLFxuICAgIGludGVydmFsLFxuICAgIGFnZ3JlZ2F0aW9uLFxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBzZXJpZXM6IHNwbGl0LFxuICAgIHRpdGxlOiBgJHthZ2dyTmFtZX0keycgb2YgJ30ke3lBeGlzID8geUF4aXMubmFtZSA6ICdDb3VudCd9YCxcbiAgICBmaWVsZFR5cGU6IHlBeGlzID8geUF4aXMudHlwZSA6ICdpbnRlZ2VyJyxcbiAgICB5QXhpczogeUF4aXMgPyB5QXhpcy5uYW1lIDogbnVsbCxcbiAgICBhbGxUaW1lOiB7XG4gICAgICB0aXRsZTogYEFsbCBUaW1lIEF2ZXJhZ2VgLFxuICAgICAgdmFsdWU6IGFnZ3JlZ2F0ZShzZXJpZXMsIEFHR1JFR0FUSU9OX1RZUEVTLmF2ZXJhZ2UsIGQgPT4gZC55KVxuICAgIH0sXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciBiaW5zIGlzIEJpbnNbXSwgbm90IGEgQmlucyBtYXAuIFJlZmFjdG9yIHRvIHVzZSBjb3JyZWN0IHR5cGVzLlxuICAgIGJpbnNcbiAgfTtcbn1cblxuLy8gc3BsaXQgaW50byBtdWx0aXBsZSBzZXJpZXMgd2hlbiBzZWUgbWlzc2luZyBkYXRhXG5leHBvcnQgZnVuY3Rpb24gc3BsaXRTZXJpZXMoc2VyaWVzKSB7XG4gIGNvbnN0IGxpbmVzOiBhbnlbXSA9IFtdO1xuICBsZXQgdGVtcDogYW55W10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZXJpZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBkID0gc2VyaWVzW2ldO1xuICAgIGlmICghbm90TnVsbG9yVW5kZWZpbmVkKGQueSkgJiYgdGVtcC5sZW5ndGgpIHtcbiAgICAgIC8vIGVuZHMgdGVtcFxuICAgICAgbGluZXMucHVzaCh0ZW1wKTtcbiAgICAgIHRlbXAgPSBbXTtcbiAgICB9IGVsc2UgaWYgKG5vdE51bGxvclVuZGVmaW5lZChkLnkpKSB7XG4gICAgICB0ZW1wLnB1c2goZCk7XG4gICAgfVxuXG4gICAgaWYgKGkgPT09IHNlcmllcy5sZW5ndGggLSAxICYmIHRlbXAubGVuZ3RoKSB7XG4gICAgICBsaW5lcy5wdXNoKHRlbXApO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG1hcmtlcnMgPSBsaW5lcy5sZW5ndGggPiAxID8gc2VyaWVzLmZpbHRlcihkID0+IG5vdE51bGxvclVuZGVmaW5lZChkLnkpKSA6IFtdO1xuXG4gIHJldHVybiB7bGluZXMsIG1hcmtlcnN9O1xufVxuXG50eXBlIE1pblZpc1N0YXRlRm9yQW5pbWF0aW9uV2luZG93ID0ge1xuICBkYXRhc2V0czogRGF0YXNldHM7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gYWRqdXN0VmFsdWVUb0FuaW1hdGlvbldpbmRvdzxTIGV4dGVuZHMgTWluVmlzU3RhdGVGb3JBbmltYXRpb25XaW5kb3c+KFxuICBzdGF0ZTogUyxcbiAgZmlsdGVyOiBUaW1lUmFuZ2VGaWx0ZXJcbikge1xuICBjb25zdCB7XG4gICAgcGxvdFR5cGUsXG4gICAgdmFsdWU6IFt2YWx1ZTAsIHZhbHVlMV0sXG4gICAgYW5pbWF0aW9uV2luZG93XG4gIH0gPSBmaWx0ZXI7XG5cbiAgY29uc3QgaW50ZXJ2YWwgPSBwbG90VHlwZS5pbnRlcnZhbCB8fCBnZXRJbml0aWFsSW50ZXJ2YWwoZmlsdGVyLCBzdGF0ZS5kYXRhc2V0cyk7XG4gIGNvbnN0IGJpbnMgPSBnZXRUaW1lQmlucyhmaWx0ZXIsIHN0YXRlLmRhdGFzZXRzLCBpbnRlcnZhbCk7XG4gIGNvbnN0IGRhdGFzZXRCaW5zID0gYmlucyAmJiBPYmplY3Qua2V5cyhiaW5zKS5sZW5ndGggJiYgT2JqZWN0LnZhbHVlcyhiaW5zKVswXVtpbnRlcnZhbF07XG4gIGNvbnN0IHRocmVzaG9sZHMgPSAoZGF0YXNldEJpbnMgfHwgW10pLm1hcChiID0+IGIueDApO1xuXG4gIGxldCB2YWwwID0gdmFsdWUwO1xuICBsZXQgdmFsMSA9IHZhbHVlMTtcbiAgbGV0IGlkeDtcbiAgaWYgKGFuaW1hdGlvbldpbmRvdyA9PT0gQU5JTUFUSU9OX1dJTkRPVy5pbnRlcnZhbCkge1xuICAgIHZhbDAgPSBzbmFwVG9NYXJrcyh2YWx1ZTEsIHRocmVzaG9sZHMpO1xuICAgIGlkeCA9IHRocmVzaG9sZHMuaW5kZXhPZih2YWwwKTtcbiAgICB2YWwxID0gaWR4ID4gLTEgPyBkYXRhc2V0Qmluc1tpZHhdLngxIDogTmFOO1xuICB9IGVsc2Uge1xuICAgIC8vIGZpdCBjdXJyZW50IHZhbHVlIHRvIHdpbmRvd1xuICAgIHZhbDAgPSBzbmFwVG9NYXJrcyh2YWx1ZTAsIHRocmVzaG9sZHMpO1xuICAgIHZhbDEgPSBzbmFwVG9NYXJrcyh2YWx1ZTEsIHRocmVzaG9sZHMpO1xuXG4gICAgaWYgKHZhbDAgPT09IHZhbDEpIHtcbiAgICAgIGlkeCA9IHRocmVzaG9sZHMuaW5kZXhPZih2YWwwKTtcbiAgICAgIGlmIChpZHggPT09IHRocmVzaG9sZHMubGVuZ3RoIC0gMSkge1xuICAgICAgICB2YWwwID0gdGhyZXNob2xkc1tpZHggLSAxXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbDEgPSB0aHJlc2hvbGRzW2lkeCArIDFdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHVwZGF0ZWRGaWx0ZXIgPSB7XG4gICAgLi4uZmlsdGVyLFxuICAgIHBsb3RUeXBlOiB7XG4gICAgICAuLi5maWx0ZXIucGxvdFR5cGUsXG4gICAgICBpbnRlcnZhbFxuICAgIH0sXG4gICAgdGltZUJpbnM6IGJpbnMsXG4gICAgdmFsdWU6IFt2YWwwLCB2YWwxXVxuICB9O1xuXG4gIHJldHVybiB1cGRhdGVkRmlsdGVyO1xufVxuXG4vKipcbiAqIENyZWF0ZSBvciB1cGRhdGUgY29sb3JzIGZvciBhIGZpbHRlciBwbG90XG4gKiBAcGFyYW0gZmlsdGVyXG4gKiBAcGFyYW0gZGF0YXNldHNcbiAqIEBwYXJhbSBvbGRDb2xvcnNCeURhdGFJZFxuICovXG5mdW5jdGlvbiBnZXRGaWx0ZXJQbG90Q29sb3JzQnlEYXRhSWQoZmlsdGVyLCBkYXRhc2V0cywgb2xkQ29sb3JzQnlEYXRhSWQpIHtcbiAgbGV0IGNvbG9yc0J5RGF0YUlkID0gb2xkQ29sb3JzQnlEYXRhSWQgfHwge307XG4gIGZvciAoY29uc3QgZGF0YUlkIG9mIGZpbHRlci5kYXRhSWQpIHtcbiAgICBpZiAoIWNvbG9yc0J5RGF0YUlkW2RhdGFJZF0gJiYgZGF0YXNldHNbZGF0YUlkXSkge1xuICAgICAgY29sb3JzQnlEYXRhSWQgPSB7XG4gICAgICAgIC4uLmNvbG9yc0J5RGF0YUlkLFxuICAgICAgICBbZGF0YUlkXTogcmdiVG9IZXgoZGF0YXNldHNbZGF0YUlkXS5jb2xvcilcbiAgICAgIH07XG4gICAgfVxuICB9XG4gIHJldHVybiBjb2xvcnNCeURhdGFJZDtcbn1cblxuLyoqXG4gKlxuICogQHBhcmFtIGZpbHRlclxuICogQHBhcmFtIHBsb3RUeXBlXG4gKiBAcGFyYW0gZGF0YXNldHNcbiAqIEBwYXJhbSBkYXRhSWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVRpbWVGaWx0ZXJQbG90VHlwZShcbiAgZmlsdGVyOiBUaW1lUmFuZ2VGaWx0ZXIsXG4gIHBsb3RUeXBlOiBUaW1lUmFuZ2VGaWx0ZXJbJ3Bsb3RUeXBlJ10sXG4gIGRhdGFzZXRzOiBEYXRhc2V0cyxcbiAgZGF0YUlkPzogc3RyaW5nXG4pOiBUaW1lUmFuZ2VGaWx0ZXIge1xuICBsZXQgbmV4dEZpbHRlciA9IGZpbHRlcjtcbiAgbGV0IG5leHRQbG90VHlwZSA9IHBsb3RUeXBlO1xuICBpZiAodHlwZW9mIG5leHRQbG90VHlwZSAhPT0gJ29iamVjdCcgfHwgIW5leHRQbG90VHlwZS5hZ2dyZWdhdGlvbiB8fCAhbmV4dFBsb3RUeXBlLmludGVydmFsKSB7XG4gICAgbmV4dFBsb3RUeXBlID0gZ2V0RGVmYXVsdFBsb3RUeXBlKGZpbHRlciwgZGF0YXNldHMpO1xuICB9XG5cbiAgaWYgKGZpbHRlci5kYXRhSWQubGVuZ3RoID4gMSkge1xuICAgIG5leHRQbG90VHlwZSA9IHtcbiAgICAgIC4uLm5leHRQbG90VHlwZSxcbiAgICAgIGNvbG9yc0J5RGF0YUlkOiBnZXRGaWx0ZXJQbG90Q29sb3JzQnlEYXRhSWQoZmlsdGVyLCBkYXRhc2V0cywgbmV4dFBsb3RUeXBlLmNvbG9yc0J5RGF0YUlkKVxuICAgIH07XG4gIH1cbiAgbmV4dEZpbHRlciA9IHtcbiAgICAuLi5uZXh0RmlsdGVyLFxuICAgIHBsb3RUeXBlOiBuZXh0UGxvdFR5cGVcbiAgfTtcblxuICBjb25zdCBiaW5zID0gZ2V0VGltZUJpbnMobmV4dEZpbHRlciwgZGF0YXNldHMsIG5leHRQbG90VHlwZS5pbnRlcnZhbCk7XG5cbiAgbmV4dEZpbHRlciA9IHtcbiAgICAuLi5uZXh0RmlsdGVyLFxuICAgIHRpbWVCaW5zOiBiaW5zXG4gIH07XG5cbiAgaWYgKHBsb3RUeXBlLnR5cGUgPT09IFBMT1RfVFlQRVMuaGlzdG9ncmFtKSB7XG4gICAgLy8gSGlzdG9ncmFtIGlzIGNhbGN1bGF0ZWQgYW5kIG1lbW9pemVkIGluIHRoZSBjaGFydCBpdHNlbGZcbiAgfSBlbHNlIGlmIChwbG90VHlwZS50eXBlID09PSBQTE9UX1RZUEVTLmxpbmVDaGFydCkge1xuICAgIC8vIHdlIHNob3VsZCBiZSBhYmxlIHRvIG1vdmUgdGhpcyBpbnRvIGl0cyBvd24gY29tcG9uZW50IHNvIHJlYWN0IHdpbGwgZG8gdGhlIHNoYWxsb3cgY29tcGFyaXNvbiBmb3IgdXMuXG4gICAgbmV4dEZpbHRlciA9IHtcbiAgICAgIC4uLm5leHRGaWx0ZXIsXG4gICAgICBsaW5lQ2hhcnQ6IGdldExpbmVDaGFydChkYXRhc2V0cywgbmV4dEZpbHRlcilcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIG5leHRGaWx0ZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSYW5nZUZpbHRlckJpbnMoZmlsdGVyLCBkYXRhc2V0cywgbnVtQmlucykge1xuICBjb25zdCB7ZG9tYWlufSA9IGZpbHRlcjtcbiAgaWYgKCFmaWx0ZXIuZGF0YUlkKSByZXR1cm4gbnVsbDtcblxuICByZXR1cm4gZmlsdGVyLmRhdGFJZC5yZWR1Y2UoKGFjYywgZGF0YUlkLCBkYXRhc2V0SWR4KSA9PiB7XG4gICAgaWYgKGZpbHRlci5iaW5zPy5bZGF0YUlkXSkge1xuICAgICAgLy8gZG9uJ3QgcmVjYWxjdWxhdGUgYmluc1xuICAgICAgYWNjW2RhdGFJZF0gPSBmaWx0ZXIuYmluc1tkYXRhSWRdO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9XG4gICAgY29uc3QgZmllbGROYW1lID0gZmlsdGVyLm5hbWVbZGF0YXNldElkeF07XG4gICAgaWYgKGRhdGFJZCAmJiBmaWVsZE5hbWUpIHtcbiAgICAgIGNvbnN0IGRhdGFzZXQgPSBkYXRhc2V0c1tkYXRhSWRdO1xuICAgICAgY29uc3QgZmllbGQgPSBkYXRhc2V0Py5nZXRDb2x1bW5GaWVsZChmaWVsZE5hbWUpO1xuICAgICAgaWYgKGRhdGFzZXQgJiYgZmllbGQpIHtcbiAgICAgICAgY29uc3QgaW5kZXhlcyA9IHJ1bkdwdUZpbHRlckZvclBsb3QoZGF0YXNldCwgZmlsdGVyKTtcbiAgICAgICAgY29uc3QgdmFsdWVBY2Nlc3NvciA9IGluZGV4ID0+IGZpZWxkLnZhbHVlQWNjZXNzb3Ioe2luZGV4fSk7XG4gICAgICAgIGFjY1tkYXRhSWRdID0gaGlzdG9ncmFtRnJvbURvbWFpbihkb21haW4sIGluZGV4ZXMsIG51bUJpbnMsIHZhbHVlQWNjZXNzb3IpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYWNjO1xuICB9LCB7fSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVSYW5nZUZpbHRlclBsb3RUeXBlKFxuICBmaWx0ZXI6IFJhbmdlRmlsdGVyLFxuICBwbG90VHlwZTogUmFuZ2VGaWx0ZXJbJ3Bsb3RUeXBlJ10sXG4gIGRhdGFzZXRzOiBEYXRhc2V0cyxcbiAgZGF0YUlkPzogc3RyaW5nXG4pOiBSYW5nZUZpbHRlciB7XG4gIGNvbnN0IG5leHRGaWx0ZXIgPSB7XG4gICAgLi4uZmlsdGVyLFxuICAgIHBsb3RUeXBlXG4gIH07XG5cbiAgLy8gaWYgKGRhdGFJZCkge1xuICAvLyAgIC8vIGNsZWFyIGJpbnNcbiAgLy8gICBuZXh0RmlsdGVyID0ge1xuICAvLyAgICAgLi4ubmV4dEZpbHRlcixcbiAgLy8gICAgIGJpbnM6IHtcbiAgLy8gICAgICAgLi4ubmV4dEZpbHRlci5iaW5zLFxuICAvLyAgICAgICBbZGF0YUlkXTogbnVsbFxuICAvLyAgICAgfVxuICAvLyAgIH07XG4gIC8vIH1cblxuICByZXR1cm4ge1xuICAgIC4uLmZpbHRlcixcbiAgICBwbG90VHlwZSxcbiAgICBiaW5zOiBnZXRSYW5nZUZpbHRlckJpbnMobmV4dEZpbHRlciwgZGF0YXNldHMsIEJJTlMpXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGFydFRpdGxlKFxuICB5QXhpczoge2Rpc3BsYXlOYW1lPzogc3RyaW5nfSxcbiAgcGxvdFR5cGU6IHthZ2dyZWdhdGlvbjogc3RyaW5nfVxuKTogc3RyaW5nIHtcbiAgY29uc3QgeUF4aXNOYW1lID0geUF4aXM/LmRpc3BsYXlOYW1lO1xuICBjb25zdCB7YWdncmVnYXRpb259ID0gcGxvdFR5cGU7XG5cbiAgaWYgKHlBeGlzTmFtZSkge1xuICAgIHJldHVybiBjYXBpdGFsaXplRmlyc3RMZXR0ZXIoYCR7YWdncmVnYXRpb259ICR7eUF4aXNOYW1lfSBvdmVyIFRpbWVgKTtcbiAgfVxuXG4gIHJldHVybiBgQ291bnQgb2YgUm93cyBvdmVyIFRpbWVgO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVmYXVsdFBsb3RUeXBlKGZpbHRlciwgZGF0YXNldHMpIHtcbiAgY29uc3QgaW50ZXJ2YWwgPSBnZXRJbml0aWFsSW50ZXJ2YWwoZmlsdGVyLCBkYXRhc2V0cyk7XG4gIGNvbnN0IGRlZmF1bHRUaW1lRm9ybWF0ID0gZ2V0RGVmYXVsdFRpbWVGb3JtYXQoaW50ZXJ2YWwpO1xuICByZXR1cm4ge1xuICAgIGludGVydmFsLFxuICAgIGRlZmF1bHRUaW1lRm9ybWF0LFxuICAgIHR5cGU6IFBMT1RfVFlQRVMuaGlzdG9ncmFtLFxuICAgIGFnZ3JlZ2F0aW9uOiBBR0dSRUdBVElPTl9UWVBFUy5zdW1cbiAgfTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBR0EsSUFBQUEsUUFBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsT0FBQSxHQUFBQyxzQkFBQSxDQUFBRixPQUFBO0FBQ0EsSUFBQUcsS0FBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksT0FBQSxHQUFBRixzQkFBQSxDQUFBRixPQUFBO0FBY0EsSUFBQUssWUFBQSxHQUFBTCxPQUFBO0FBQ0EsSUFBQU0sVUFBQSxHQUFBTixPQUFBO0FBVUEsSUFBQU8sVUFBQSxHQUFBUCxPQUFBO0FBQ0EsSUFBQVEsWUFBQSxHQUFBUixPQUFBO0FBQ0EsSUFBQVMsUUFBQSxHQUFBVCxPQUFBO0FBQ0EsSUFBQVUsT0FBQSxHQUFBVixPQUFBO0FBQ0EsSUFBQVcsV0FBQSxHQUFBWCxPQUFBO0FBQXVDLFNBQUFZLDJCQUFBQyxDQUFBLEVBQUFDLENBQUEsUUFBQUMsQ0FBQSx5QkFBQUMsTUFBQSxJQUFBSCxDQUFBLENBQUFHLE1BQUEsQ0FBQUMsUUFBQSxLQUFBSixDQUFBLHFCQUFBRSxDQUFBLFFBQUFHLEtBQUEsQ0FBQUMsT0FBQSxDQUFBTixDQUFBLE1BQUFFLENBQUEsR0FBQUssMkJBQUEsQ0FBQVAsQ0FBQSxNQUFBQyxDQUFBLElBQUFELENBQUEsdUJBQUFBLENBQUEsQ0FBQVEsTUFBQSxJQUFBTixDQUFBLEtBQUFGLENBQUEsR0FBQUUsQ0FBQSxPQUFBTyxFQUFBLE1BQUFDLENBQUEsWUFBQUEsRUFBQSxlQUFBQyxDQUFBLEVBQUFELENB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