@kepler.gl/deckgl-layers 3.3.0-alpha.4 → 3.3.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/3d-building-layer/3d-building-layer.js +66 -0
- package/dist/cjs/3d-building-layer/3d-building-utils.js +166 -0
- package/dist/cjs/3d-building-layer/types.js +6 -0
- package/dist/cjs/cluster-layer/cluster-layer.js +292 -0
- package/dist/cjs/column-layer/enhanced-column-layer.js +160 -0
- package/dist/{deckgl-extensions → cjs/deckgl-extensions}/filter-arrow-layer.js +1 -1
- package/dist/cjs/deckgl-extensions/filter-shader-module.js +26 -0
- package/dist/cjs/globe/atmosphere-layer.js +220 -0
- package/dist/cjs/globe/enhanced-multi-icon-layer.js +63 -0
- package/dist/cjs/globe/globe-depth-disk-layer.js +145 -0
- package/dist/cjs/globe/globe-layers.js +569 -0
- package/dist/cjs/globe/globe-stars-layer.js +69 -0
- package/dist/cjs/globe/globe-view.js +407 -0
- package/dist/{globe → cjs/globe}/index.js +1 -1
- package/dist/cjs/globe/mvt-label-layer.js +190 -0
- package/dist/cjs/grid-layer/enhanced-cpu-grid-layer.js +116 -0
- package/dist/cjs/hexagon-layer/enhanced-hexagon-layer.js +134 -0
- package/dist/{index.js → cjs/index.js} +1 -1
- package/dist/cjs/layer-utils/aggregation-utils.js +181 -0
- package/dist/cjs/layer-utils/cluster-utils.js +93 -0
- package/dist/cjs/layer-utils/cpu-aggregator.js +798 -0
- package/dist/cjs/layer-utils/globe-cell-utils.js +173 -0
- package/dist/cjs/layer-utils/shader-utils.js +38 -0
- package/dist/cjs/line-layer/line-layer.js +95 -0
- package/dist/cjs/raster/images.js +271 -0
- package/dist/cjs/raster/pipeline-validation-patch.js +101 -0
- package/dist/cjs/raster/raster-layer/raster-layer-shaders.js +163 -0
- package/dist/cjs/raster/raster-layer/raster-layer-webgl1.fs.js +10 -0
- package/dist/cjs/raster/raster-layer/raster-layer-webgl1.vs.js +10 -0
- package/dist/cjs/raster/raster-layer/raster-layer-webgl2.fs.js +10 -0
- package/dist/cjs/raster/raster-layer/raster-layer-webgl2.vs.js +10 -0
- package/dist/cjs/raster/raster-layer/raster-layer.js +287 -0
- package/dist/cjs/raster/raster-mesh-layer/matrix.js +18 -0
- package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-shaders.js +38 -0
- package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl1.fs.js +10 -0
- package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl1.vs.js +10 -0
- package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl2.fs.js +10 -0
- package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer-webgl2.vs.js +10 -0
- package/dist/cjs/raster/raster-mesh-layer/raster-mesh-layer.js +321 -0
- package/dist/cjs/raster/raster-processing-uniforms.js +124 -0
- package/dist/cjs/raster/types.js +6 -0
- package/dist/cjs/raster/util.js +139 -0
- package/dist/cjs/raster/webgl/color/colormap.js +45 -0
- package/dist/cjs/raster/webgl/color/filter.js +58 -0
- package/dist/cjs/raster/webgl/color/gamma-contrast.js +68 -0
- package/dist/cjs/raster/webgl/color/linear-rescale.js +35 -0
- package/dist/cjs/raster/webgl/color/saturation.js +42 -0
- package/dist/cjs/raster/webgl/color/sigmoidal-contrast.js +68 -0
- package/dist/{raster → cjs/raster}/webgl/index.js +1 -1
- package/dist/cjs/raster/webgl/pansharpen/pansharpen-brovey.js +46 -0
- package/dist/cjs/raster/webgl/spectral-indices/evi.js +26 -0
- package/dist/cjs/raster/webgl/spectral-indices/msavi.js +25 -0
- package/dist/cjs/raster/webgl/spectral-indices/normalized-difference.js +19 -0
- package/dist/cjs/raster/webgl/spectral-indices/savi.js +21 -0
- package/dist/cjs/raster/webgl/texture/combine-bands.js +65 -0
- package/dist/cjs/raster/webgl/texture/mask.js +50 -0
- package/dist/cjs/raster/webgl/texture/reorder-bands.js +72 -0
- package/dist/cjs/raster/webgl/texture/rgba-image.js +34 -0
- package/dist/cjs/raster/webgl/types.js +6 -0
- package/dist/cjs/svg-icon-layer/scatterplot-icon-layer.js +88 -0
- package/dist/cjs/svg-icon-layer/svg-icon-layer.js +104 -0
- package/dist/cjs/wms/wms-layer.js +624 -0
- package/dist/esm/3d-building-layer/3d-building-layer.js +62 -0
- package/dist/esm/3d-building-layer/3d-building-utils.js +157 -0
- package/dist/esm/3d-building-layer/types.js +3 -0
- package/dist/esm/cluster-layer/cluster-layer.js +286 -0
- package/dist/esm/column-layer/enhanced-column-layer.js +156 -0
- package/dist/esm/deckgl-extensions/filter-arrow-layer.js +64 -0
- package/dist/esm/deckgl-extensions/filter-shader-module.js +20 -0
- package/dist/esm/globe/atmosphere-layer.js +214 -0
- package/dist/esm/globe/enhanced-multi-icon-layer.js +60 -0
- package/dist/esm/globe/globe-depth-disk-layer.js +140 -0
- package/dist/esm/globe/globe-layers.js +561 -0
- package/dist/esm/globe/globe-stars-layer.js +63 -0
- package/dist/esm/globe/globe-view.js +401 -0
- package/dist/esm/globe/index.js +26 -0
- package/dist/esm/globe/mvt-label-layer.js +187 -0
- package/dist/esm/grid-layer/enhanced-cpu-grid-layer.js +112 -0
- package/dist/esm/hexagon-layer/enhanced-hexagon-layer.js +130 -0
- package/dist/esm/index.js +22 -0
- package/dist/esm/layer-utils/aggregation-utils.js +172 -0
- package/dist/esm/layer-utils/cluster-utils.js +86 -0
- package/dist/esm/layer-utils/cpu-aggregator.js +788 -0
- package/dist/esm/layer-utils/globe-cell-utils.js +167 -0
- package/dist/esm/layer-utils/shader-utils.js +32 -0
- package/dist/esm/line-layer/line-layer.js +91 -0
- package/dist/esm/raster/images.js +267 -0
- package/dist/esm/raster/pipeline-validation-patch.js +94 -0
- package/dist/esm/raster/raster-layer/raster-layer-shaders.js +153 -0
- package/dist/esm/raster/raster-layer/raster-layer-webgl1.fs.js +5 -0
- package/dist/esm/raster/raster-layer/raster-layer-webgl1.vs.js +5 -0
- package/dist/esm/raster/raster-layer/raster-layer-webgl2.fs.js +5 -0
- package/dist/esm/raster/raster-layer/raster-layer-webgl2.vs.js +5 -0
- package/dist/esm/raster/raster-layer/raster-layer.js +283 -0
- package/dist/esm/raster/raster-mesh-layer/matrix.js +12 -0
- package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-shaders.js +30 -0
- package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl1.fs.js +5 -0
- package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl1.vs.js +5 -0
- package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl2.fs.js +5 -0
- package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer-webgl2.vs.js +5 -0
- package/dist/esm/raster/raster-mesh-layer/raster-mesh-layer.js +318 -0
- package/dist/esm/raster/raster-processing-uniforms.js +118 -0
- package/dist/esm/raster/types.js +3 -0
- package/dist/esm/raster/util.js +134 -0
- package/dist/esm/raster/webgl/color/colormap.js +39 -0
- package/dist/esm/raster/webgl/color/filter.js +52 -0
- package/dist/esm/raster/webgl/color/gamma-contrast.js +62 -0
- package/dist/esm/raster/webgl/color/linear-rescale.js +29 -0
- package/dist/esm/raster/webgl/color/saturation.js +36 -0
- package/dist/esm/raster/webgl/color/sigmoidal-contrast.js +62 -0
- package/dist/esm/raster/webgl/index.js +26 -0
- package/dist/esm/raster/webgl/pansharpen/pansharpen-brovey.js +40 -0
- package/dist/esm/raster/webgl/spectral-indices/evi.js +20 -0
- package/dist/esm/raster/webgl/spectral-indices/msavi.js +19 -0
- package/dist/esm/raster/webgl/spectral-indices/normalized-difference.js +13 -0
- package/dist/esm/raster/webgl/spectral-indices/savi.js +15 -0
- package/dist/esm/raster/webgl/texture/combine-bands.js +58 -0
- package/dist/esm/raster/webgl/texture/mask.js +44 -0
- package/dist/esm/raster/webgl/texture/reorder-bands.js +65 -0
- package/dist/esm/raster/webgl/texture/rgba-image.js +28 -0
- package/dist/esm/raster/webgl/types.js +3 -0
- package/dist/esm/svg-icon-layer/scatterplot-icon-layer.js +84 -0
- package/dist/esm/svg-icon-layer/svg-icon-layer.js +101 -0
- package/dist/esm/wms/wms-layer.js +619 -0
- package/dist/globe/atmosphere-layer.d.ts +13 -2
- package/dist/globe/globe-depth-disk-layer.d.ts +1 -0
- package/dist/globe/globe-layers.d.ts +8 -2
- package/dist/raster/images.d.ts +10 -1
- package/dist/raster/raster-layer/raster-layer.d.ts +4 -0
- package/dist/raster/raster-mesh-layer/raster-mesh-layer.d.ts +4 -0
- package/dist/wms/wms-layer.d.ts +8 -0
- package/package.json +18 -11
- package/dist/3d-building-layer/3d-building-layer.js +0 -66
- package/dist/3d-building-layer/3d-building-utils.js +0 -166
- package/dist/3d-building-layer/types.js +0 -6
- package/dist/cluster-layer/cluster-layer.js +0 -292
- package/dist/column-layer/enhanced-column-layer.js +0 -160
- package/dist/deckgl-extensions/filter-shader-module.js +0 -26
- package/dist/globe/atmosphere-layer.js +0 -184
- package/dist/globe/enhanced-multi-icon-layer.js +0 -63
- package/dist/globe/globe-depth-disk-layer.js +0 -145
- package/dist/globe/globe-layers.js +0 -565
- package/dist/globe/globe-stars-layer.js +0 -69
- package/dist/globe/globe-view.js +0 -316
- package/dist/globe/mvt-label-layer.js +0 -190
- package/dist/grid-layer/enhanced-cpu-grid-layer.js +0 -116
- package/dist/hexagon-layer/enhanced-hexagon-layer.js +0 -134
- package/dist/layer-utils/aggregation-utils.js +0 -181
- package/dist/layer-utils/cluster-utils.js +0 -93
- package/dist/layer-utils/cpu-aggregator.js +0 -798
- package/dist/layer-utils/globe-cell-utils.js +0 -173
- package/dist/layer-utils/shader-utils.js +0 -38
- package/dist/line-layer/line-layer.js +0 -95
- package/dist/raster/images.js +0 -259
- package/dist/raster/pipeline-validation-patch.js +0 -101
- package/dist/raster/raster-layer/raster-layer-shaders.js +0 -163
- package/dist/raster/raster-layer/raster-layer-webgl1.fs.js +0 -10
- package/dist/raster/raster-layer/raster-layer-webgl1.vs.js +0 -10
- package/dist/raster/raster-layer/raster-layer-webgl2.fs.js +0 -10
- package/dist/raster/raster-layer/raster-layer-webgl2.vs.js +0 -10
- package/dist/raster/raster-layer/raster-layer.js +0 -237
- package/dist/raster/raster-mesh-layer/matrix.js +0 -18
- package/dist/raster/raster-mesh-layer/raster-mesh-layer-shaders.js +0 -38
- package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl1.fs.js +0 -10
- package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl1.vs.js +0 -10
- package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl2.fs.js +0 -10
- package/dist/raster/raster-mesh-layer/raster-mesh-layer-webgl2.vs.js +0 -10
- package/dist/raster/raster-mesh-layer/raster-mesh-layer.js +0 -271
- package/dist/raster/raster-processing-uniforms.js +0 -124
- package/dist/raster/types.js +0 -6
- package/dist/raster/util.js +0 -139
- package/dist/raster/webgl/color/colormap.js +0 -45
- package/dist/raster/webgl/color/filter.js +0 -58
- package/dist/raster/webgl/color/gamma-contrast.js +0 -68
- package/dist/raster/webgl/color/linear-rescale.js +0 -35
- package/dist/raster/webgl/color/saturation.js +0 -42
- package/dist/raster/webgl/color/sigmoidal-contrast.js +0 -68
- package/dist/raster/webgl/pansharpen/pansharpen-brovey.js +0 -46
- package/dist/raster/webgl/spectral-indices/evi.js +0 -26
- package/dist/raster/webgl/spectral-indices/msavi.js +0 -25
- package/dist/raster/webgl/spectral-indices/normalized-difference.js +0 -19
- package/dist/raster/webgl/spectral-indices/savi.js +0 -21
- package/dist/raster/webgl/texture/combine-bands.js +0 -65
- package/dist/raster/webgl/texture/mask.js +0 -50
- package/dist/raster/webgl/texture/reorder-bands.js +0 -72
- package/dist/raster/webgl/texture/rgba-image.js +0 -34
- package/dist/raster/webgl/types.js +0 -6
- package/dist/svg-icon-layer/scatterplot-icon-layer.js +0 -88
- package/dist/svg-icon-layer/svg-icon-layer.js +0 -104
- package/dist/wms/wms-layer.js +0 -594
|
@@ -0,0 +1,788 @@
|
|
|
1
|
+
import _typeof from "@babel/runtime/helpers/esm/typeof";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
3
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
4
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
5
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
6
|
+
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
7
|
+
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; }
|
|
8
|
+
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) { _defineProperty(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; }
|
|
9
|
+
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; } } }; }
|
|
10
|
+
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; } }
|
|
11
|
+
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; }
|
|
12
|
+
// SPDX-License-Identifier: MIT
|
|
13
|
+
// Copyright contributors to the kepler.gl project
|
|
14
|
+
|
|
15
|
+
/* eslint-disable guard-for-in */
|
|
16
|
+
import { console as Console } from 'global/window';
|
|
17
|
+
import { aggregate } from '@kepler.gl/utils';
|
|
18
|
+
import { AGGREGATION_TYPES, SCALE_FUNC } from '@kepler.gl/constants';
|
|
19
|
+
var AGGREGATION_OPERATION = {
|
|
20
|
+
SUM: 'SUM',
|
|
21
|
+
MEAN: 'MEAN',
|
|
22
|
+
MIN: 'MIN',
|
|
23
|
+
MAX: 'MAX',
|
|
24
|
+
COUNT: 'COUNT'
|
|
25
|
+
};
|
|
26
|
+
var MAX_32_BIT_FLOAT = 3.402823466e38;
|
|
27
|
+
var defaultGetValue = function defaultGetValue(points) {
|
|
28
|
+
return points.length;
|
|
29
|
+
};
|
|
30
|
+
var defaultGetPoints = function defaultGetPoints(bin) {
|
|
31
|
+
return bin.points;
|
|
32
|
+
};
|
|
33
|
+
var defaultGetIndex = function defaultGetIndex(bin) {
|
|
34
|
+
return bin.index;
|
|
35
|
+
};
|
|
36
|
+
var ascending = function ascending(a, b) {
|
|
37
|
+
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
|
|
38
|
+
};
|
|
39
|
+
function clamp(value, min, max) {
|
|
40
|
+
return Math.max(min, Math.min(max, value));
|
|
41
|
+
}
|
|
42
|
+
function getQuantileDomain(data, valueAccessor) {
|
|
43
|
+
return data.map(valueAccessor).sort(ascending);
|
|
44
|
+
}
|
|
45
|
+
function getOrdinalDomain(data, valueAccessor) {
|
|
46
|
+
return _toConsumableArray(new Set(data.map(valueAccessor)));
|
|
47
|
+
}
|
|
48
|
+
var BinSorter = /*#__PURE__*/function () {
|
|
49
|
+
function BinSorter() {
|
|
50
|
+
var bins = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
51
|
+
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
52
|
+
_classCallCheck(this, BinSorter);
|
|
53
|
+
_defineProperty(this, "maxCount", void 0);
|
|
54
|
+
_defineProperty(this, "maxValue", void 0);
|
|
55
|
+
_defineProperty(this, "minValue", void 0);
|
|
56
|
+
_defineProperty(this, "totalCount", void 0);
|
|
57
|
+
_defineProperty(this, "aggregatedBins", void 0);
|
|
58
|
+
_defineProperty(this, "sortedBins", void 0);
|
|
59
|
+
_defineProperty(this, "binMap", void 0);
|
|
60
|
+
this.aggregatedBins = this._getAggregatedBins(bins, props);
|
|
61
|
+
this._updateMinMaxValues();
|
|
62
|
+
this.binMap = this._getBinMap();
|
|
63
|
+
}
|
|
64
|
+
return _createClass(BinSorter, [{
|
|
65
|
+
key: "_getAggregatedBins",
|
|
66
|
+
value: function _getAggregatedBins(bins, props) {
|
|
67
|
+
var _props$getValue = props.getValue,
|
|
68
|
+
getValue = _props$getValue === void 0 ? defaultGetValue : _props$getValue,
|
|
69
|
+
_props$getPoints = props.getPoints,
|
|
70
|
+
getPoints = _props$getPoints === void 0 ? defaultGetPoints : _props$getPoints,
|
|
71
|
+
_props$getIndex = props.getIndex,
|
|
72
|
+
getIndex = _props$getIndex === void 0 ? defaultGetIndex : _props$getIndex,
|
|
73
|
+
filterData = props.filterData;
|
|
74
|
+
var hasFilter = typeof filterData === 'function';
|
|
75
|
+
var aggregatedBins = [];
|
|
76
|
+
var index = 0;
|
|
77
|
+
for (var binIndex = 0; binIndex < bins.length; binIndex++) {
|
|
78
|
+
var bin = bins[binIndex];
|
|
79
|
+
var points = getPoints(bin);
|
|
80
|
+
var i = getIndex(bin);
|
|
81
|
+
var filteredPoints = hasFilter ? points.filter(filterData) : points;
|
|
82
|
+
bin.filteredPoints = hasFilter ? filteredPoints : null;
|
|
83
|
+
var value = filteredPoints.length ? getValue(filteredPoints) : null;
|
|
84
|
+
if (value !== null && value !== undefined) {
|
|
85
|
+
aggregatedBins[index] = {
|
|
86
|
+
i: Number.isFinite(i) ? i : binIndex,
|
|
87
|
+
value: value,
|
|
88
|
+
counts: filteredPoints.length
|
|
89
|
+
};
|
|
90
|
+
index++;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return aggregatedBins;
|
|
94
|
+
}
|
|
95
|
+
}, {
|
|
96
|
+
key: "_updateMinMaxValues",
|
|
97
|
+
value: function _updateMinMaxValues() {
|
|
98
|
+
var maxCount = 0;
|
|
99
|
+
var maxValue = -MAX_32_BIT_FLOAT;
|
|
100
|
+
var minValue = MAX_32_BIT_FLOAT;
|
|
101
|
+
var totalCount = 0;
|
|
102
|
+
var _iterator = _createForOfIteratorHelper(this.aggregatedBins),
|
|
103
|
+
_step;
|
|
104
|
+
try {
|
|
105
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
106
|
+
var x = _step.value;
|
|
107
|
+
maxCount = maxCount > x.counts ? maxCount : x.counts;
|
|
108
|
+
maxValue = maxValue > x.value ? maxValue : x.value;
|
|
109
|
+
minValue = minValue < x.value ? minValue : x.value;
|
|
110
|
+
totalCount += x.counts;
|
|
111
|
+
}
|
|
112
|
+
} catch (err) {
|
|
113
|
+
_iterator.e(err);
|
|
114
|
+
} finally {
|
|
115
|
+
_iterator.f();
|
|
116
|
+
}
|
|
117
|
+
if (this.aggregatedBins.length === 0) {
|
|
118
|
+
maxValue = 0;
|
|
119
|
+
minValue = 0;
|
|
120
|
+
}
|
|
121
|
+
this.maxCount = maxCount;
|
|
122
|
+
this.maxValue = maxValue;
|
|
123
|
+
this.minValue = minValue;
|
|
124
|
+
this.totalCount = totalCount;
|
|
125
|
+
}
|
|
126
|
+
}, {
|
|
127
|
+
key: "_getBinMap",
|
|
128
|
+
value: function _getBinMap() {
|
|
129
|
+
var binMap = {};
|
|
130
|
+
var _iterator2 = _createForOfIteratorHelper(this.aggregatedBins),
|
|
131
|
+
_step2;
|
|
132
|
+
try {
|
|
133
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
134
|
+
var bin = _step2.value;
|
|
135
|
+
binMap[bin.i] = bin;
|
|
136
|
+
}
|
|
137
|
+
} catch (err) {
|
|
138
|
+
_iterator2.e(err);
|
|
139
|
+
} finally {
|
|
140
|
+
_iterator2.f();
|
|
141
|
+
}
|
|
142
|
+
return binMap;
|
|
143
|
+
}
|
|
144
|
+
}, {
|
|
145
|
+
key: "_percentileToIndex",
|
|
146
|
+
value: function _percentileToIndex(percentileRange) {
|
|
147
|
+
var len = this.sortedBins.length;
|
|
148
|
+
if (len < 2) return [0, 0];
|
|
149
|
+
var _percentileRange$map = percentileRange.map(function (n) {
|
|
150
|
+
return clamp(n, 0, 100);
|
|
151
|
+
}),
|
|
152
|
+
_percentileRange$map2 = _slicedToArray(_percentileRange$map, 2),
|
|
153
|
+
lower = _percentileRange$map2[0],
|
|
154
|
+
upper = _percentileRange$map2[1];
|
|
155
|
+
return [Math.ceil(lower / 100 * (len - 1)), Math.floor(upper / 100 * (len - 1))];
|
|
156
|
+
}
|
|
157
|
+
}, {
|
|
158
|
+
key: "getValueDomainByScale",
|
|
159
|
+
value: function getValueDomainByScale(scale) {
|
|
160
|
+
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [],
|
|
161
|
+
_ref2 = _slicedToArray(_ref, 2),
|
|
162
|
+
_ref2$ = _ref2[0],
|
|
163
|
+
lower = _ref2$ === void 0 ? 0 : _ref2$,
|
|
164
|
+
_ref2$2 = _ref2[1],
|
|
165
|
+
upper = _ref2$2 === void 0 ? 100 : _ref2$2;
|
|
166
|
+
if (!this.sortedBins) {
|
|
167
|
+
this.sortedBins = this.aggregatedBins.sort(function (a, b) {
|
|
168
|
+
return ascending(a.value, b.value);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
if (!this.sortedBins.length) return [];
|
|
172
|
+
var indexEdge = this._percentileToIndex([lower, upper]);
|
|
173
|
+
return this._getScaleDomain(scale, indexEdge);
|
|
174
|
+
}
|
|
175
|
+
}, {
|
|
176
|
+
key: "_getScaleDomain",
|
|
177
|
+
value: function _getScaleDomain(scaleType, _ref3) {
|
|
178
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
179
|
+
lowerIdx = _ref4[0],
|
|
180
|
+
upperIdx = _ref4[1];
|
|
181
|
+
var bins = this.sortedBins;
|
|
182
|
+
switch (scaleType) {
|
|
183
|
+
case 'quantize':
|
|
184
|
+
case 'linear':
|
|
185
|
+
return [bins[lowerIdx].value, bins[upperIdx].value];
|
|
186
|
+
case 'quantile':
|
|
187
|
+
return getQuantileDomain(bins.slice(lowerIdx, upperIdx + 1), function (d) {
|
|
188
|
+
return d.value;
|
|
189
|
+
});
|
|
190
|
+
case 'ordinal':
|
|
191
|
+
return getOrdinalDomain(bins, function (d) {
|
|
192
|
+
return d.value;
|
|
193
|
+
});
|
|
194
|
+
default:
|
|
195
|
+
return [bins[lowerIdx].value, bins[upperIdx].value];
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}, {
|
|
199
|
+
key: "getValueRange",
|
|
200
|
+
value: function getValueRange(percentileRange) {
|
|
201
|
+
if (!this.sortedBins) {
|
|
202
|
+
this.sortedBins = this.aggregatedBins.sort(function (a, b) {
|
|
203
|
+
return ascending(a.value, b.value);
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
if (!this.sortedBins.length) return [];
|
|
207
|
+
var lowerIdx = 0;
|
|
208
|
+
var upperIdx = this.sortedBins.length - 1;
|
|
209
|
+
if (Array.isArray(percentileRange)) {
|
|
210
|
+
var idxRange = this._percentileToIndex(percentileRange);
|
|
211
|
+
lowerIdx = idxRange[0];
|
|
212
|
+
upperIdx = idxRange[1];
|
|
213
|
+
}
|
|
214
|
+
return [this.sortedBins[lowerIdx].value, this.sortedBins[upperIdx].value];
|
|
215
|
+
}
|
|
216
|
+
}]);
|
|
217
|
+
}();
|
|
218
|
+
export var DECK_AGGREGATION_MAP = _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, AGGREGATION_OPERATION.SUM, AGGREGATION_TYPES.sum), AGGREGATION_OPERATION.MEAN, AGGREGATION_TYPES.average), AGGREGATION_OPERATION.MIN, AGGREGATION_TYPES.minimum), AGGREGATION_OPERATION.MAX, AGGREGATION_TYPES.maximum);
|
|
219
|
+
export function getValueFunc(aggregation, accessor) {
|
|
220
|
+
if (!aggregation || !AGGREGATION_OPERATION[aggregation.toUpperCase()]) {
|
|
221
|
+
Console.warn("Aggregation ".concat(aggregation, " is not supported"));
|
|
222
|
+
}
|
|
223
|
+
var op = AGGREGATION_OPERATION[aggregation.toUpperCase()] || AGGREGATION_OPERATION.SUM;
|
|
224
|
+
var keplerOp = DECK_AGGREGATION_MAP[op];
|
|
225
|
+
return function (pts) {
|
|
226
|
+
return aggregate(pts.map(accessor), keplerOp);
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
export function getScaleFunctor(scaleType) {
|
|
230
|
+
if (!scaleType || !SCALE_FUNC[scaleType]) {
|
|
231
|
+
Console.warn("Scale ".concat(scaleType, " is not supported"));
|
|
232
|
+
}
|
|
233
|
+
return SCALE_FUNC[scaleType] || SCALE_FUNC.quantize;
|
|
234
|
+
}
|
|
235
|
+
function nop() {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
export function getGetValue(step, props, dimensionUpdater) {
|
|
239
|
+
var key = dimensionUpdater.key;
|
|
240
|
+
var _step$triggers = step.triggers,
|
|
241
|
+
value = _step$triggers.value,
|
|
242
|
+
weight = _step$triggers.weight,
|
|
243
|
+
aggregation = _step$triggers.aggregation;
|
|
244
|
+
var getValue = props[value.prop];
|
|
245
|
+
if (getValue === null) {
|
|
246
|
+
// If `getValue` is not provided from props, build it with aggregation and weight.
|
|
247
|
+
getValue = getValueFunc(props[aggregation.prop], props[weight.prop]);
|
|
248
|
+
}
|
|
249
|
+
if (getValue) {
|
|
250
|
+
this._setDimensionState(key, {
|
|
251
|
+
getValue: getValue
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
export function getDimensionSortedBins(step, props, dimensionUpdater) {
|
|
256
|
+
var key = dimensionUpdater.key;
|
|
257
|
+
var getValue = this.state.dimensions[key].getValue;
|
|
258
|
+
var sortedBins = new BinSorter(this.state.layerData.data || [], {
|
|
259
|
+
getValue: getValue,
|
|
260
|
+
filterData: props._filterData
|
|
261
|
+
});
|
|
262
|
+
this._setDimensionState(key, {
|
|
263
|
+
sortedBins: sortedBins
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
export function getDimensionValueDomain(step, props, dimensionUpdater) {
|
|
267
|
+
var key = dimensionUpdater.key;
|
|
268
|
+
var _step$triggers2 = step.triggers,
|
|
269
|
+
lowerPercentile = _step$triggers2.lowerPercentile,
|
|
270
|
+
upperPercentile = _step$triggers2.upperPercentile,
|
|
271
|
+
scaleType = _step$triggers2.scaleType;
|
|
272
|
+
if (!this.state.dimensions[key].sortedBins) {
|
|
273
|
+
// the previous step should set sortedBins, if not, something went wrong
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
var valueDomain =
|
|
277
|
+
// for log and sqrt scale, returns linear domain by default
|
|
278
|
+
// TODO: support other scale function domain in bin sorter
|
|
279
|
+
this.state.dimensions[key].sortedBins.getValueDomainByScale(props[scaleType.prop], [props[lowerPercentile.prop], props[upperPercentile.prop]]);
|
|
280
|
+
if (props.colorScaleType === 'custom' && props.colorMap) {
|
|
281
|
+
// for custom scale, return custom breaks as value domain directly
|
|
282
|
+
valueDomain = props.colorMap.reduce(function (prev, cur) {
|
|
283
|
+
return Number.isFinite(cur[0]) ? prev.concat(cur[0]) : prev;
|
|
284
|
+
}, []);
|
|
285
|
+
}
|
|
286
|
+
this._setDimensionState(key, {
|
|
287
|
+
valueDomain: valueDomain
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
export function getDimensionScale(step, props, dimensionUpdater) {
|
|
291
|
+
var key = dimensionUpdater.key;
|
|
292
|
+
var _step$triggers3 = step.triggers,
|
|
293
|
+
domain = _step$triggers3.domain,
|
|
294
|
+
range = _step$triggers3.range,
|
|
295
|
+
scaleType = _step$triggers3.scaleType,
|
|
296
|
+
fixed = _step$triggers3.fixed;
|
|
297
|
+
var onSet = step.onSet;
|
|
298
|
+
if (!this.state.dimensions[key].valueDomain) {
|
|
299
|
+
// the previous step should set valueDomain, if not, something went wrong
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
var dimensionRange = props[range.prop];
|
|
303
|
+
var dimensionDomain = props[domain.prop] || this.state.dimensions[key].valueDomain;
|
|
304
|
+
var dimensionFixed = Boolean(fixed && props[fixed.prop]);
|
|
305
|
+
var scaleFunctor = getScaleFunctor(scaleType && props[scaleType.prop])();
|
|
306
|
+
var scaleFunc = scaleFunctor.domain(dimensionDomain).range(dimensionFixed ? dimensionDomain : dimensionRange);
|
|
307
|
+
scaleFunc.scaleType = props.colorScaleType;
|
|
308
|
+
if (_typeof(onSet) === 'object' && typeof props[onSet.props] === 'function') {
|
|
309
|
+
var sortedBins = this.state.dimensions[key].sortedBins;
|
|
310
|
+
if (sortedBins) {
|
|
311
|
+
props[onSet.props]({
|
|
312
|
+
domain: scaleFunc.domain(),
|
|
313
|
+
aggregatedBins: sortedBins.binMap
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
this._setDimensionState(key, {
|
|
318
|
+
scaleFunc: scaleFunc
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
function normalizeResult() {
|
|
322
|
+
var result = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
323
|
+
// support previous hexagonAggregator API
|
|
324
|
+
if (result.hexagons) {
|
|
325
|
+
return Object.assign({
|
|
326
|
+
data: result.hexagons
|
|
327
|
+
}, result);
|
|
328
|
+
} else if (result.layerData) {
|
|
329
|
+
return Object.assign({
|
|
330
|
+
data: result.layerData
|
|
331
|
+
}, result);
|
|
332
|
+
}
|
|
333
|
+
return result;
|
|
334
|
+
}
|
|
335
|
+
export function getAggregatedData(step, props, aggregation, aggregationParams) {
|
|
336
|
+
var aggr = step.triggers.aggregator;
|
|
337
|
+
var aggregator = props[aggr.prop];
|
|
338
|
+
|
|
339
|
+
// result should contain a data array and other props
|
|
340
|
+
// result = {data: [], ...other props}
|
|
341
|
+
var result = aggregator(props, aggregationParams);
|
|
342
|
+
this.setState({
|
|
343
|
+
layerData: normalizeResult(result)
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
export var defaultAggregation = {
|
|
347
|
+
key: 'position',
|
|
348
|
+
updateSteps: [{
|
|
349
|
+
key: 'aggregate',
|
|
350
|
+
triggers: {
|
|
351
|
+
cellSize: {
|
|
352
|
+
prop: 'cellSize'
|
|
353
|
+
},
|
|
354
|
+
position: {
|
|
355
|
+
prop: 'getPosition',
|
|
356
|
+
updateTrigger: 'getPosition'
|
|
357
|
+
},
|
|
358
|
+
aggregator: {
|
|
359
|
+
prop: 'gridAggregator'
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
updater: getAggregatedData
|
|
363
|
+
}]
|
|
364
|
+
};
|
|
365
|
+
function getSubLayerAccessor(dimensionState, dimension) {
|
|
366
|
+
return function (cell) {
|
|
367
|
+
var sortedBins = dimensionState.sortedBins,
|
|
368
|
+
scaleFunc = dimensionState.scaleFunc;
|
|
369
|
+
var bin = sortedBins.binMap[cell.index];
|
|
370
|
+
if (bin && bin.counts === 0) {
|
|
371
|
+
// no points left in bin after filtering
|
|
372
|
+
return dimension.nullValue;
|
|
373
|
+
}
|
|
374
|
+
var cv = bin && bin.value;
|
|
375
|
+
var domain = scaleFunc.domain();
|
|
376
|
+
var isValueInDomain = scaleFunc.scaleType === 'custom' ? cv >= sortedBins.minValue && cv <= sortedBins.maxValue : cv >= domain[0] && cv <= domain[domain.length - 1];
|
|
377
|
+
|
|
378
|
+
// if cell value is outside domain, set alpha to 0
|
|
379
|
+
return isValueInDomain ? scaleFunc(cv) : dimension.nullValue;
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
export var defaultColorDimension = {
|
|
383
|
+
key: 'fillColor',
|
|
384
|
+
accessor: 'getFillColor',
|
|
385
|
+
getPickingInfo: function getPickingInfo(dimensionState, cell) {
|
|
386
|
+
if (!cell) {
|
|
387
|
+
return {};
|
|
388
|
+
}
|
|
389
|
+
var sortedBins = dimensionState.sortedBins;
|
|
390
|
+
var colorValue = sortedBins.binMap[cell.index] && sortedBins.binMap[cell.index].value;
|
|
391
|
+
return {
|
|
392
|
+
colorValue: colorValue
|
|
393
|
+
};
|
|
394
|
+
},
|
|
395
|
+
nullValue: [0, 0, 0, 0],
|
|
396
|
+
updateSteps: [{
|
|
397
|
+
key: 'getValue',
|
|
398
|
+
triggers: {
|
|
399
|
+
value: {
|
|
400
|
+
prop: 'getColorValue',
|
|
401
|
+
updateTrigger: 'getColorValue'
|
|
402
|
+
},
|
|
403
|
+
weight: {
|
|
404
|
+
prop: 'getColorWeight',
|
|
405
|
+
updateTrigger: 'getColorWeight'
|
|
406
|
+
},
|
|
407
|
+
aggregation: {
|
|
408
|
+
prop: 'colorAggregation'
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
updater: getGetValue
|
|
412
|
+
}, {
|
|
413
|
+
key: 'getBins',
|
|
414
|
+
triggers: {
|
|
415
|
+
_filterData: {
|
|
416
|
+
prop: '_filterData',
|
|
417
|
+
updateTrigger: '_filterData'
|
|
418
|
+
}
|
|
419
|
+
},
|
|
420
|
+
updater: getDimensionSortedBins
|
|
421
|
+
}, {
|
|
422
|
+
key: 'getDomain',
|
|
423
|
+
triggers: {
|
|
424
|
+
lowerPercentile: {
|
|
425
|
+
prop: 'lowerPercentile'
|
|
426
|
+
},
|
|
427
|
+
upperPercentile: {
|
|
428
|
+
prop: 'upperPercentile'
|
|
429
|
+
},
|
|
430
|
+
scaleType: {
|
|
431
|
+
prop: 'colorScaleType'
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
updater: getDimensionValueDomain
|
|
435
|
+
}, {
|
|
436
|
+
key: 'getScaleFunc',
|
|
437
|
+
triggers: {
|
|
438
|
+
domain: {
|
|
439
|
+
prop: 'colorDomain'
|
|
440
|
+
},
|
|
441
|
+
range: {
|
|
442
|
+
prop: 'colorRange'
|
|
443
|
+
},
|
|
444
|
+
scaleType: {
|
|
445
|
+
prop: 'colorScaleType'
|
|
446
|
+
}
|
|
447
|
+
},
|
|
448
|
+
onSet: {
|
|
449
|
+
props: 'onSetColorDomain'
|
|
450
|
+
},
|
|
451
|
+
updater: getDimensionScale
|
|
452
|
+
}],
|
|
453
|
+
getSubLayerAccessor: getSubLayerAccessor
|
|
454
|
+
};
|
|
455
|
+
export var defaultElevationDimension = {
|
|
456
|
+
key: 'elevation',
|
|
457
|
+
accessor: 'getElevation',
|
|
458
|
+
getPickingInfo: function getPickingInfo(dimensionState, cell) {
|
|
459
|
+
if (!cell) {
|
|
460
|
+
return {};
|
|
461
|
+
}
|
|
462
|
+
var sortedBins = dimensionState.sortedBins;
|
|
463
|
+
var elevationValue = sortedBins.binMap[cell.index] && sortedBins.binMap[cell.index].value;
|
|
464
|
+
return {
|
|
465
|
+
elevationValue: elevationValue
|
|
466
|
+
};
|
|
467
|
+
},
|
|
468
|
+
nullValue: -1,
|
|
469
|
+
updateSteps: [{
|
|
470
|
+
key: 'getValue',
|
|
471
|
+
triggers: {
|
|
472
|
+
value: {
|
|
473
|
+
prop: 'getElevationValue',
|
|
474
|
+
updateTrigger: 'getElevationValue'
|
|
475
|
+
},
|
|
476
|
+
weight: {
|
|
477
|
+
prop: 'getElevationWeight',
|
|
478
|
+
updateTrigger: 'getElevationWeight'
|
|
479
|
+
},
|
|
480
|
+
aggregation: {
|
|
481
|
+
prop: 'elevationAggregation'
|
|
482
|
+
}
|
|
483
|
+
},
|
|
484
|
+
updater: getGetValue
|
|
485
|
+
}, {
|
|
486
|
+
key: 'getBins',
|
|
487
|
+
triggers: {
|
|
488
|
+
_filterData: {
|
|
489
|
+
prop: '_filterData',
|
|
490
|
+
updateTrigger: '_filterData'
|
|
491
|
+
}
|
|
492
|
+
},
|
|
493
|
+
updater: getDimensionSortedBins
|
|
494
|
+
}, {
|
|
495
|
+
key: 'getDomain',
|
|
496
|
+
triggers: {
|
|
497
|
+
lowerPercentile: {
|
|
498
|
+
prop: 'elevationLowerPercentile'
|
|
499
|
+
},
|
|
500
|
+
upperPercentile: {
|
|
501
|
+
prop: 'elevationUpperPercentile'
|
|
502
|
+
},
|
|
503
|
+
scaleType: {
|
|
504
|
+
prop: 'elevationScaleType'
|
|
505
|
+
}
|
|
506
|
+
},
|
|
507
|
+
updater: getDimensionValueDomain
|
|
508
|
+
}, {
|
|
509
|
+
key: 'getScaleFunc',
|
|
510
|
+
triggers: {
|
|
511
|
+
fixed: {
|
|
512
|
+
prop: 'elevationFixed'
|
|
513
|
+
},
|
|
514
|
+
domain: {
|
|
515
|
+
prop: 'elevationDomain'
|
|
516
|
+
},
|
|
517
|
+
range: {
|
|
518
|
+
prop: 'elevationRange'
|
|
519
|
+
},
|
|
520
|
+
scaleType: {
|
|
521
|
+
prop: 'elevationScaleType'
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
onSet: {
|
|
525
|
+
props: 'onSetElevationDomain'
|
|
526
|
+
},
|
|
527
|
+
updater: getDimensionScale
|
|
528
|
+
}],
|
|
529
|
+
getSubLayerAccessor: getSubLayerAccessor
|
|
530
|
+
};
|
|
531
|
+
var _defaultDimensions = [defaultColorDimension, defaultElevationDimension];
|
|
532
|
+
export { _defaultDimensions as defaultDimensions };
|
|
533
|
+
var CPUAggregator = /*#__PURE__*/function () {
|
|
534
|
+
function CPUAggregator() {
|
|
535
|
+
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
536
|
+
_classCallCheck(this, CPUAggregator);
|
|
537
|
+
_defineProperty(this, "state", void 0);
|
|
538
|
+
_defineProperty(this, "dimensionUpdaters", void 0);
|
|
539
|
+
_defineProperty(this, "aggregationUpdater", void 0);
|
|
540
|
+
this.state = _objectSpread({
|
|
541
|
+
layerData: {},
|
|
542
|
+
dimensions: {
|
|
543
|
+
// color: {
|
|
544
|
+
// getValue: null,
|
|
545
|
+
// domain: null,
|
|
546
|
+
// sortedBins: null,
|
|
547
|
+
// scaleFunc: nop
|
|
548
|
+
// },
|
|
549
|
+
// elevation: {
|
|
550
|
+
// getValue: null,
|
|
551
|
+
// domain: null,
|
|
552
|
+
// sortedBins: null,
|
|
553
|
+
// scaleFunc: nop
|
|
554
|
+
// }
|
|
555
|
+
}
|
|
556
|
+
}, opts.initialState);
|
|
557
|
+
this.dimensionUpdaters = {};
|
|
558
|
+
this.aggregationUpdater = opts.aggregation || defaultAggregation;
|
|
559
|
+
this._addDimension(opts.dimensions || _defaultDimensions);
|
|
560
|
+
}
|
|
561
|
+
return _createClass(CPUAggregator, [{
|
|
562
|
+
key: "updateAllDimensions",
|
|
563
|
+
value: function updateAllDimensions(props) {
|
|
564
|
+
var dimensionChanges = [];
|
|
565
|
+
// update all dimensions
|
|
566
|
+
for (var dim in this.dimensionUpdaters) {
|
|
567
|
+
var updaters = this._accumulateUpdaters(0, props, this.dimensionUpdaters[dim]);
|
|
568
|
+
dimensionChanges = dimensionChanges.concat(updaters);
|
|
569
|
+
}
|
|
570
|
+
dimensionChanges.forEach(function (f) {
|
|
571
|
+
return typeof f === 'function' && f();
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
}, {
|
|
575
|
+
key: "updateAggregation",
|
|
576
|
+
value: function updateAggregation(props, aggregationParams) {
|
|
577
|
+
var updaters = this._accumulateUpdaters(0, props, this.aggregationUpdater);
|
|
578
|
+
updaters.forEach(function (f) {
|
|
579
|
+
return typeof f === 'function' && f(aggregationParams);
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
}, {
|
|
583
|
+
key: "updateState",
|
|
584
|
+
value: function updateState(opts, aggregationParams) {
|
|
585
|
+
var oldProps = opts.oldProps,
|
|
586
|
+
props = opts.props,
|
|
587
|
+
changeFlags = opts.changeFlags;
|
|
588
|
+
var dimensionChanges = [];
|
|
589
|
+
if (changeFlags.dataChanged) {
|
|
590
|
+
// if data changed update everything
|
|
591
|
+
this.updateAggregation(props, aggregationParams);
|
|
592
|
+
this.updateAllDimensions(props);
|
|
593
|
+
return this.state;
|
|
594
|
+
}
|
|
595
|
+
var aggregationChanges = this._getAggregationChanges(oldProps, props, changeFlags);
|
|
596
|
+
if (aggregationChanges && aggregationChanges.length) {
|
|
597
|
+
// get aggregatedData
|
|
598
|
+
aggregationChanges.forEach(function (f) {
|
|
599
|
+
return typeof f === 'function' && f(aggregationParams);
|
|
600
|
+
});
|
|
601
|
+
this.updateAllDimensions(props);
|
|
602
|
+
} else {
|
|
603
|
+
// only update dimensions
|
|
604
|
+
dimensionChanges = this._getDimensionChanges(oldProps, props, changeFlags) || [];
|
|
605
|
+
dimensionChanges.forEach(function (f) {
|
|
606
|
+
return typeof f === 'function' && f();
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
return this.state;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// Update private state
|
|
613
|
+
}, {
|
|
614
|
+
key: "setState",
|
|
615
|
+
value: function setState(updateObject) {
|
|
616
|
+
this.state = Object.assign({}, this.state, updateObject);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// Update private state.dimensions
|
|
620
|
+
}, {
|
|
621
|
+
key: "_setDimensionState",
|
|
622
|
+
value: function _setDimensionState(key, updateObject) {
|
|
623
|
+
this.setState({
|
|
624
|
+
dimensions: Object.assign({}, this.state.dimensions, _defineProperty({}, key, Object.assign({}, this.state.dimensions[key], updateObject)))
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
}, {
|
|
628
|
+
key: "_addAggregation",
|
|
629
|
+
value: function _addAggregation(aggregation) {
|
|
630
|
+
this.aggregationUpdater = aggregation;
|
|
631
|
+
}
|
|
632
|
+
}, {
|
|
633
|
+
key: "_addDimension",
|
|
634
|
+
value: function _addDimension() {
|
|
635
|
+
var _this = this;
|
|
636
|
+
var dimensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
637
|
+
dimensions.forEach(function (dimension) {
|
|
638
|
+
var key = dimension.key;
|
|
639
|
+
_this.dimensionUpdaters[key] = dimension;
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
}, {
|
|
643
|
+
key: "_needUpdateStep",
|
|
644
|
+
value: function _needUpdateStep(dimensionStep, oldProps, props, changeFlags) {
|
|
645
|
+
// whether need to update current dimension step
|
|
646
|
+
// dimension step is the value, domain, scaleFunction of each dimension
|
|
647
|
+
// each step is an object with properties links to layer prop and whether the prop is
|
|
648
|
+
// controlled by updateTriggers
|
|
649
|
+
return Object.values(dimensionStep.triggers).some(function (item) {
|
|
650
|
+
if (item.updateTrigger) {
|
|
651
|
+
// check based on updateTriggers change first
|
|
652
|
+
return changeFlags.updateTriggersChanged && (changeFlags.updateTriggersChanged.all || changeFlags.updateTriggersChanged[item.updateTrigger]);
|
|
653
|
+
}
|
|
654
|
+
// fallback to direct comparison
|
|
655
|
+
return oldProps[item.prop] !== props[item.prop];
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
}, {
|
|
659
|
+
key: "_accumulateUpdaters",
|
|
660
|
+
value: function _accumulateUpdaters(step, props, dimension) {
|
|
661
|
+
var updaters = [];
|
|
662
|
+
for (var i = step; i < dimension.updateSteps.length; i++) {
|
|
663
|
+
var updater = dimension.updateSteps[i].updater;
|
|
664
|
+
if (typeof updater === 'function') {
|
|
665
|
+
updaters.push(updater.bind(this, dimension.updateSteps[i], props, dimension));
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
return updaters;
|
|
669
|
+
}
|
|
670
|
+
}, {
|
|
671
|
+
key: "_getAllUpdaters",
|
|
672
|
+
value: function _getAllUpdaters(dimension, oldProps, props, changeFlags) {
|
|
673
|
+
var _this2 = this;
|
|
674
|
+
var updaters = [];
|
|
675
|
+
var needUpdateStep = dimension.updateSteps.findIndex(function (step) {
|
|
676
|
+
return _this2._needUpdateStep(step, oldProps, props, changeFlags);
|
|
677
|
+
});
|
|
678
|
+
if (needUpdateStep > -1) {
|
|
679
|
+
updaters = updaters.concat(this._accumulateUpdaters(needUpdateStep, props, dimension));
|
|
680
|
+
}
|
|
681
|
+
return updaters;
|
|
682
|
+
}
|
|
683
|
+
}, {
|
|
684
|
+
key: "_getAggregationChanges",
|
|
685
|
+
value: function _getAggregationChanges(oldProps, props, changeFlags) {
|
|
686
|
+
var updaters = this._getAllUpdaters(this.aggregationUpdater, oldProps, props, changeFlags);
|
|
687
|
+
return updaters.length ? updaters : null;
|
|
688
|
+
}
|
|
689
|
+
}, {
|
|
690
|
+
key: "_getDimensionChanges",
|
|
691
|
+
value: function _getDimensionChanges(oldProps, props, changeFlags) {
|
|
692
|
+
var updaters = [];
|
|
693
|
+
|
|
694
|
+
// get dimension to be updated
|
|
695
|
+
for (var key in this.dimensionUpdaters) {
|
|
696
|
+
// return the first triggered updater for each dimension
|
|
697
|
+
var dimension = this.dimensionUpdaters[key];
|
|
698
|
+
var dimensionUpdaters = this._getAllUpdaters(dimension, oldProps, props, changeFlags);
|
|
699
|
+
updaters = updaters.concat(dimensionUpdaters);
|
|
700
|
+
}
|
|
701
|
+
return updaters.length ? updaters : null;
|
|
702
|
+
}
|
|
703
|
+
}, {
|
|
704
|
+
key: "getUpdateTriggers",
|
|
705
|
+
value: function getUpdateTriggers(props) {
|
|
706
|
+
var _this3 = this;
|
|
707
|
+
var _updateTriggers = props.updateTriggers || {};
|
|
708
|
+
var updateTriggers = {};
|
|
709
|
+
var _loop = function _loop() {
|
|
710
|
+
var _this3$dimensionUpdat = _this3.dimensionUpdaters[key],
|
|
711
|
+
accessor = _this3$dimensionUpdat.accessor,
|
|
712
|
+
updateSteps = _this3$dimensionUpdat.updateSteps;
|
|
713
|
+
// fold dimension triggers into each accessor
|
|
714
|
+
updateTriggers[accessor] = {};
|
|
715
|
+
updateSteps.forEach(function (step) {
|
|
716
|
+
Object.values(step.triggers || []).forEach(function (_ref5) {
|
|
717
|
+
var prop = _ref5.prop,
|
|
718
|
+
updateTrigger = _ref5.updateTrigger;
|
|
719
|
+
if (updateTrigger) {
|
|
720
|
+
// if prop is based on updateTrigger e.g. getColorValue, getColorWeight
|
|
721
|
+
// and updateTriggers is passed in from layer prop
|
|
722
|
+
// fold the updateTriggers into accessor
|
|
723
|
+
var fromProp = _updateTriggers[updateTrigger];
|
|
724
|
+
if (_typeof(fromProp) === 'object' && !Array.isArray(fromProp)) {
|
|
725
|
+
// if updateTrigger is an object spread it
|
|
726
|
+
Object.assign(updateTriggers[accessor], fromProp);
|
|
727
|
+
} else if (fromProp !== undefined) {
|
|
728
|
+
updateTriggers[accessor][prop] = fromProp;
|
|
729
|
+
}
|
|
730
|
+
} else {
|
|
731
|
+
// if prop is not based on updateTrigger
|
|
732
|
+
updateTriggers[accessor][prop] = props[prop];
|
|
733
|
+
}
|
|
734
|
+
});
|
|
735
|
+
});
|
|
736
|
+
};
|
|
737
|
+
for (var key in this.dimensionUpdaters) {
|
|
738
|
+
_loop();
|
|
739
|
+
}
|
|
740
|
+
return updateTriggers;
|
|
741
|
+
}
|
|
742
|
+
}, {
|
|
743
|
+
key: "getPickingInfo",
|
|
744
|
+
value: function getPickingInfo(_ref6, layerProps) {
|
|
745
|
+
var _this$state$layerData;
|
|
746
|
+
var info = _ref6.info;
|
|
747
|
+
var isPicked = info.picked && info.index > -1;
|
|
748
|
+
var object = null;
|
|
749
|
+
var cell = isPicked ? (_this$state$layerData = this.state.layerData.data) === null || _this$state$layerData === void 0 ? void 0 : _this$state$layerData[info.index] : null;
|
|
750
|
+
if (cell) {
|
|
751
|
+
var binInfo = {};
|
|
752
|
+
for (var key in this.dimensionUpdaters) {
|
|
753
|
+
var _getPickingInfo = this.dimensionUpdaters[key].getPickingInfo;
|
|
754
|
+
if (typeof _getPickingInfo === 'function') {
|
|
755
|
+
binInfo = Object.assign({}, binInfo, _getPickingInfo(this.state.dimensions[key], cell, layerProps));
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
object = Object.assign(binInfo, cell, {
|
|
759
|
+
points: cell.filteredPoints || cell.points
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// add bin and to info
|
|
764
|
+
return Object.assign(info, {
|
|
765
|
+
picked: Boolean(object),
|
|
766
|
+
// override object with picked cell
|
|
767
|
+
object: object
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
}, {
|
|
771
|
+
key: "getAccessor",
|
|
772
|
+
value: function getAccessor(dimensionKey, layerProps) {
|
|
773
|
+
if (!Object.prototype.hasOwnProperty.call(this.dimensionUpdaters, dimensionKey)) {
|
|
774
|
+
return nop;
|
|
775
|
+
}
|
|
776
|
+
return this.dimensionUpdaters[dimensionKey].getSubLayerAccessor(this.state.dimensions[dimensionKey], this.dimensionUpdaters[dimensionKey], layerProps);
|
|
777
|
+
}
|
|
778
|
+
}], [{
|
|
779
|
+
key: "defaultDimensions",
|
|
780
|
+
value: function defaultDimensions() {
|
|
781
|
+
return _defaultDimensions;
|
|
782
|
+
}
|
|
783
|
+
}]);
|
|
784
|
+
}();
|
|
785
|
+
_defineProperty(CPUAggregator, "getDimensionScale", void 0);
|
|
786
|
+
export { CPUAggregator as default };
|
|
787
|
+
CPUAggregator.getDimensionScale = getDimensionScale;
|
|
788
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb25zb2xlIiwiQ29uc29sZSIsImFnZ3JlZ2F0ZSIsIkFHR1JFR0FUSU9OX1RZUEVTIiwiU0NBTEVfRlVOQyIsIkFHR1JFR0FUSU9OX09QRVJBVElPTiIsIlNVTSIsIk1FQU4iLCJNSU4iLCJNQVgiLCJDT1VOVCIsIk1BWF8zMl9CSVRfRkxPQVQiLCJkZWZhdWx0R2V0VmFsdWUiLCJwb2ludHMiLCJsZW5ndGgiLCJkZWZhdWx0R2V0UG9pbnRzIiwiYmluIiwiZGVmYXVsdEdldEluZGV4IiwiaW5kZXgiLCJhc2NlbmRpbmciLCJhIiwiYiIsIk5hTiIsImNsYW1wIiwidmFsdWUiLCJtaW4iLCJtYXgiLCJNYXRoIiwiZ2V0UXVhbnRpbGVEb21haW4iLCJkYXRhIiwidmFsdWVBY2Nlc3NvciIsIm1hcCIsInNvcnQiLCJnZXRPcmRpbmFsRG9tYWluIiwiX3RvQ29uc3VtYWJsZUFycmF5IiwiU2V0IiwiQmluU29ydGVyIiwiYmlucyIsImFyZ3VtZW50cyIsInVuZGVmaW5lZCIsInByb3BzIiwiX2NsYXNzQ2FsbENoZWNrIiwiX2RlZmluZVByb3BlcnR5IiwiYWdncmVnYXRlZEJpbnMiLCJfZ2V0QWdncmVnYXRlZEJpbnMiLCJfdXBkYXRlTWluTWF4VmFsdWVzIiwiYmluTWFwIiwiX2dldEJpbk1hcCIsIl9jcmVhdGVDbGFzcyIsImtleSIsIl9wcm9wcyRnZXRWYWx1ZSIsImdldFZhbHVlIiwiX3Byb3BzJGdldFBvaW50cyIsImdldFBvaW50cyIsIl9wcm9wcyRnZXRJbmRleCIsImdldEluZGV4IiwiZmlsdGVyRGF0YSIsImhhc0ZpbHRlciIsImJpbkluZGV4IiwiaSIsImZpbHRlcmVkUG9pbnRzIiwiZmlsdGVyIiwiTnVtYmVyIiwiaXNGaW5pdGUiLCJjb3VudHMiLCJtYXhDb3VudCIsIm1heFZhbHVlIiwibWluVmFsdWUiLCJ0b3RhbENvdW50IiwiX2l0ZXJhdG9yIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJfc3RlcCIsInMiLCJuIiwiZG9uZSIsIngiLCJlcnIiLCJlIiwiZiIsIl9pdGVyYXRvcjIiLCJfc3RlcDIiLCJfcGVyY2VudGlsZVRvSW5kZXgiLCJwZXJjZW50aWxlUmFuZ2UiLCJsZW4iLCJzb3J0ZWRCaW5zIiwiX3BlcmNlbnRpbGVSYW5nZSRtYXAiLCJfcGVyY2VudGlsZVJhbmdlJG1hcDIiLCJfc2xpY2VkVG9BcnJheSIsImxvd2VyIiwidXBwZXIiLCJjZWlsIiwiZmxvb3IiLCJnZXRWYWx1ZURvbWFpbkJ5U2NhbGUiLCJzY2FsZSIsIl9yZWYiLCJfcmVmMiIsIl9yZWYyJCIsIl9yZWYyJDIiLCJpbmRleEVkZ2UiLCJfZ2V0U2NhbGVEb21haW4iLCJzY2FsZVR5cGUiLCJfcmVmMyIsIl9yZWY0IiwibG93ZXJJZHgiLCJ1cHBlcklkeCIsInNsaWNlIiwiZCIsImdldFZhbHVlUmFuZ2UiLCJBcnJheSIsImlzQXJyYXkiLCJpZHhSYW5nZSIsIkRFQ0tfQUdHUkVHQVRJT05fTUFQIiwic3VtIiwiYXZlcmFnZSIsIm1pbmltdW0iLCJtYXhpbXVtIiwiZ2V0VmFsdWVGdW5jIiwiYWdncmVnYXRpb24iLCJhY2Nlc3NvciIsInRvVXBwZXJDYXNlIiwid2FybiIsImNvbmNhdCIsIm9wIiwia2VwbGVyT3AiLCJwdHMiLCJnZXRTY2FsZUZ1bmN0b3IiLCJxdWFudGl6ZSIsIm5vcCIsImdldEdldFZhbHVlIiwic3RlcCIsImRpbWVuc2lvblVwZGF0ZXIiLCJfc3RlcCR0cmlnZ2VycyIsInRyaWdnZXJzIiwid2VpZ2h0IiwicHJvcCIsIl9zZXREaW1lbnNpb25TdGF0ZSIsImdldERpbWVuc2lvblNvcnRlZEJpbnMiLCJzdGF0ZSIsImRpbWVuc2lvbnMiLCJsYXllckRhdGEiLCJfZmlsdGVyRGF0YSIsImdldERpbWVuc2lvblZhbHVlRG9tYWluIiwiX3N0ZXAkdHJpZ2dlcnMyIiwibG93ZXJQZXJjZW50aWxlIiwidXBwZXJQZXJjZW50aWxlIiwidmFsdWVEb21haW4iLCJjb2xvclNjYWxlVHlwZSIsImNvbG9yTWFwIiwicmVkdWNlIiwicHJldiIsImN1ciIsImdldERpbWVuc2lvblNjYWxlIiwiX3N0ZXAkdHJpZ2dlcnMzIiwiZG9tYWluIiwicmFuZ2UiLCJmaXhlZCIsIm9uU2V0IiwiZGltZW5zaW9uUmFuZ2UiLCJkaW1lbnNpb25Eb21haW4iLCJkaW1lbnNpb25GaXhlZCIsIkJvb2xlYW4iLCJzY2FsZUZ1bmN0b3IiLCJzY2FsZUZ1bmMiLCJfdHlwZW9mIiwibm9ybWFsaXplUmVzdWx0IiwicmVzdWx0IiwiaGV4YWdvbnMiLCJPYmplY3QiLCJhc3NpZ24iLCJnZXRBZ2dyZWdhdGVkRGF0YSIsImFnZ3JlZ2F0aW9uUGFyYW1zIiwiYWdnciIsImFnZ3JlZ2F0b3IiLCJzZXRTdGF0ZSIsImRlZmF1bHRBZ2dyZWdhdGlvbiIsInVwZGF0ZVN0ZXBzIiwiY2VsbFNpemUiLCJwb3NpdGlvbiIsInVwZGF0ZVRyaWdnZXIiLCJ1cGRhdGVyIiwiZ2V0U3ViTGF5ZXJBY2Nlc3NvciIsImRpbWVuc2lvblN0YXRlIiwiZGltZW5zaW9uIiwiY2VsbCIsIm51bGxWYWx1ZSIsImN2IiwiaXNWYWx1ZUluRG9tYWluIiwiZGVmYXVsdENvbG9yRGltZW5zaW9uIiwiZ2V0UGlja2luZ0luZm8iLCJjb2xvclZhbHVlIiwiZGVmYXVsdEVsZXZhdGlvbkRpbWVuc2lvbiIsImVsZXZhdGlvblZhbHVlIiwiZGVmYXVsdERpbWVuc2lvbnMiLCJfZGVmYXVsdERpbWVuc2lvbnMiLCJDUFVBZ2dyZWdhdG9yIiwib3B0cyIsIl9vYmplY3RTcHJlYWQiLCJpbml0aWFsU3RhdGUiLCJkaW1lbnNpb25VcGRhdGVycyIsImFnZ3JlZ2F0aW9uVXBkYXRlciIsIl9hZGREaW1lbnNpb24iLCJ1cGRhdGVBbGxEaW1lbnNpb25zIiwiZGltZW5zaW9uQ2hhbmdlcyIsImRpbSIsInVwZGF0ZXJzIiwiX2FjY3VtdWxhdGVVcGRhdGVycyIsImZvckVhY2giLCJ1cGRhdGVBZ2dyZWdhdGlvbiIsInVwZGF0ZVN0YXRlIiwib2xkUHJvcHMiLCJjaGFuZ2VGbGFncyIsImRhdGFDaGFuZ2VkIiwiYWdncmVnYXRpb25DaGFuZ2VzIiwiX2dldEFnZ3JlZ2F0aW9uQ2hhbmdlcyIsIl9nZXREaW1lbnNpb25DaGFuZ2VzIiwidXBkYXRlT2JqZWN0IiwiX2FkZEFnZ3JlZ2F0aW9uIiwiX3RoaXMiLCJfbmVlZFVwZGF0ZVN0ZXAiLCJkaW1lbnNpb25TdGVwIiwidmFsdWVzIiwic29tZSIsIml0ZW0iLCJ1cGRhdGVUcmlnZ2Vyc0NoYW5nZWQiLCJhbGwiLCJwdXNoIiwiYmluZCIsIl9nZXRBbGxVcGRhdGVycyIsIl90aGlzMiIsIm5lZWRVcGRhdGVTdGVwIiwiZmluZEluZGV4IiwiZ2V0VXBkYXRlVHJpZ2dlcnMiLCJfdGhpczMiLCJfdXBkYXRlVHJpZ2dlcnMiLCJ1cGRhdGVUcmlnZ2VycyIsIl9sb29wIiwiX3RoaXMzJGRpbWVuc2lvblVwZGF0IiwiX3JlZjUiLCJmcm9tUHJvcCIsIl9yZWY2IiwibGF5ZXJQcm9wcyIsIl90aGlzJHN0YXRlJGxheWVyRGF0YSIsImluZm8iLCJpc1BpY2tlZCIsInBpY2tlZCIsIm9iamVjdCIsImJpbkluZm8iLCJnZXRBY2Nlc3NvciIsImRpbWVuc2lvbktleSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImRlZmF1bHQiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGF5ZXItdXRpbHMvY3B1LWFnZ3JlZ2F0b3IudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuLyogZXNsaW50LWRpc2FibGUgZ3VhcmQtZm9yLWluICovXG5pbXBvcnQge2NvbnNvbGUgYXMgQ29uc29sZX0gZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5cbmltcG9ydCB7YWdncmVnYXRlfSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcbmltcG9ydCB7QUdHUkVHQVRJT05fVFlQRVMsIFNDQUxFX0ZVTkN9IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcbmltcG9ydCB7UkdCQUNvbG9yfSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcbmltcG9ydCB0eXBlIENsdXN0ZXJCdWlsZGVyIGZyb20gJy4vY2x1c3Rlci11dGlscyc7XG5cbmNvbnN0IEFHR1JFR0FUSU9OX09QRVJBVElPTiA9IHtcbiAgU1VNOiAnU1VNJyBhcyBjb25zdCxcbiAgTUVBTjogJ01FQU4nIGFzIGNvbnN0LFxuICBNSU46ICdNSU4nIGFzIGNvbnN0LFxuICBNQVg6ICdNQVgnIGFzIGNvbnN0LFxuICBDT1VOVDogJ0NPVU5UJyBhcyBjb25zdFxufTtcblxuY29uc3QgTUFYXzMyX0JJVF9GTE9BVCA9IDMuNDAyODIzNDY2ZTM4O1xuXG5pbnRlcmZhY2UgQmluIHtcbiAgcG9pbnRzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdO1xuICBmaWx0ZXJlZFBvaW50cz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+W10gfCBudWxsO1xuICBpbmRleD86IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIEFnZ3JlZ2F0ZWRCaW4ge1xuICBpOiBudW1iZXI7XG4gIHZhbHVlOiBudW1iZXI7XG4gIGNvdW50czogbnVtYmVyO1xufVxuXG5jb25zdCBkZWZhdWx0R2V0VmFsdWUgPSAocG9pbnRzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdKSA9PiBwb2ludHMubGVuZ3RoO1xuY29uc3QgZGVmYXVsdEdldFBvaW50cyA9IChiaW46IEJpbikgPT4gYmluLnBvaW50cztcbmNvbnN0IGRlZmF1bHRHZXRJbmRleCA9IChiaW46IEJpbikgPT4gYmluLmluZGV4O1xuY29uc3QgYXNjZW5kaW5nID0gKGE6IG51bWJlciwgYjogbnVtYmVyKSA9PiAoYSA8IGIgPyAtMSA6IGEgPiBiID8gMSA6IGEgPj0gYiA/IDAgOiBOYU4pO1xuXG5mdW5jdGlvbiBjbGFtcCh2YWx1ZTogbnVtYmVyLCBtaW46IG51bWJlciwgbWF4OiBudW1iZXIpIHtcbiAgcmV0dXJuIE1hdGgubWF4KG1pbiwgTWF0aC5taW4obWF4LCB2YWx1ZSkpO1xufVxuXG5mdW5jdGlvbiBnZXRRdWFudGlsZURvbWFpbihkYXRhOiBBZ2dyZWdhdGVkQmluW10sIHZhbHVlQWNjZXNzb3I6IChkOiBBZ2dyZWdhdGVkQmluKSA9PiBudW1iZXIpIHtcbiAgcmV0dXJuIGRhdGEubWFwKHZhbHVlQWNjZXNzb3IpLnNvcnQoYXNjZW5kaW5nKTtcbn1cblxuZnVuY3Rpb24gZ2V0T3JkaW5hbERvbWFpbihkYXRhOiBBZ2dyZWdhdGVkQmluW10sIHZhbHVlQWNjZXNzb3I6IChkOiBBZ2dyZWdhdGVkQmluKSA9PiBudW1iZXIpIHtcbiAgcmV0dXJuIFsuLi5uZXcgU2V0KGRhdGEubWFwKHZhbHVlQWNjZXNzb3IpKV07XG59XG5cbmNsYXNzIEJpblNvcnRlciB7XG4gIG1heENvdW50ITogbnVtYmVyO1xuICBtYXhWYWx1ZSE6IG51bWJlcjtcbiAgbWluVmFsdWUhOiBudW1iZXI7XG4gIHRvdGFsQ291bnQhOiBudW1iZXI7XG4gIGFnZ3JlZ2F0ZWRCaW5zOiBBZ2dyZWdhdGVkQmluW107XG4gIHNvcnRlZEJpbnMhOiBBZ2dyZWdhdGVkQmluW107XG4gIGJpbk1hcDogUmVjb3JkPG51bWJlciwgQWdncmVnYXRlZEJpbj47XG5cbiAgY29uc3RydWN0b3IoYmluczogQmluW10gPSBbXSwgcHJvcHM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fSkge1xuICAgIHRoaXMuYWdncmVnYXRlZEJpbnMgPSB0aGlzLl9nZXRBZ2dyZWdhdGVkQmlucyhiaW5zLCBwcm9wcyk7XG4gICAgdGhpcy5fdXBkYXRlTWluTWF4VmFsdWVzKCk7XG4gICAgdGhpcy5iaW5NYXAgPSB0aGlzLl9nZXRCaW5NYXAoKTtcbiAgfVxuXG4gIF9nZXRBZ2dyZWdhdGVkQmlucyhiaW5zOiBCaW5bXSwgcHJvcHM6IFJlY29yZDxzdHJpbmcsIGFueT4pOiBBZ2dyZWdhdGVkQmluW10ge1xuICAgIGNvbnN0IHtcbiAgICAgIGdldFZhbHVlID0gZGVmYXVsdEdldFZhbHVlLFxuICAgICAgZ2V0UG9pbnRzID0gZGVmYXVsdEdldFBvaW50cyxcbiAgICAgIGdldEluZGV4ID0gZGVmYXVsdEdldEluZGV4LFxuICAgICAgZmlsdGVyRGF0YVxuICAgIH0gPSBwcm9wcztcbiAgICBjb25zdCBoYXNGaWx0ZXIgPSB0eXBlb2YgZmlsdGVyRGF0YSA9PT0gJ2Z1bmN0aW9uJztcbiAgICBjb25zdCBhZ2dyZWdhdGVkQmluczogQWdncmVnYXRlZEJpbltdID0gW107XG4gICAgbGV0IGluZGV4ID0gMDtcbiAgICBmb3IgKGxldCBiaW5JbmRleCA9IDA7IGJpbkluZGV4IDwgYmlucy5sZW5ndGg7IGJpbkluZGV4KyspIHtcbiAgICAgIGNvbnN0IGJpbiA9IGJpbnNbYmluSW5kZXhdO1xuICAgICAgY29uc3QgcG9pbnRzID0gZ2V0UG9pbnRzKGJpbik7XG4gICAgICBjb25zdCBpID0gZ2V0SW5kZXgoYmluKTtcbiAgICAgIGNvbnN0IGZpbHRlcmVkUG9pbnRzID0gaGFzRmlsdGVyID8gcG9pbnRzLmZpbHRlcihmaWx0ZXJEYXRhKSA6IHBvaW50cztcbiAgICAgIGJpbi5maWx0ZXJlZFBvaW50cyA9IGhhc0ZpbHRlciA/IGZpbHRlcmVkUG9pbnRzIDogbnVsbDtcbiAgICAgIGNvbnN0IHZhbHVlID0gZmlsdGVyZWRQb2ludHMubGVuZ3RoID8gZ2V0VmFsdWUoZmlsdGVyZWRQb2ludHMpIDogbnVsbDtcbiAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGFnZ3JlZ2F0ZWRCaW5zW2luZGV4XSA9IHtcbiAgICAgICAgICBpOiBOdW1iZXIuaXNGaW5pdGUoaSkgPyBpIDogYmluSW5kZXgsXG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgY291bnRzOiBmaWx0ZXJlZFBvaW50cy5sZW5ndGhcbiAgICAgICAgfTtcbiAgICAgICAgaW5kZXgrKztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFnZ3JlZ2F0ZWRCaW5zO1xuICB9XG5cbiAgX3VwZGF0ZU1pbk1heFZhbHVlcygpIHtcbiAgICBsZXQgbWF4Q291bnQgPSAwO1xuICAgIGxldCBtYXhWYWx1ZSA9IC1NQVhfMzJfQklUX0ZMT0FUO1xuICAgIGxldCBtaW5WYWx1ZSA9IE1BWF8zMl9CSVRfRkxPQVQ7XG4gICAgbGV0IHRvdGFsQ291bnQgPSAwO1xuICAgIGZvciAoY29uc3QgeCBvZiB0aGlzLmFnZ3JlZ2F0ZWRCaW5zKSB7XG4gICAgICBtYXhDb3VudCA9IG1heENvdW50ID4geC5jb3VudHMgPyBtYXhDb3VudCA6IHguY291bnRzO1xuICAgICAgbWF4VmFsdWUgPSBtYXhWYWx1ZSA+IHgudmFsdWUgPyBtYXhWYWx1ZSA6IHgudmFsdWU7XG4gICAgICBtaW5WYWx1ZSA9IG1pblZhbHVlIDwgeC52YWx1ZSA/IG1pblZhbHVlIDogeC52YWx1ZTtcbiAgICAgIHRvdGFsQ291bnQgKz0geC5jb3VudHM7XG4gICAgfVxuICAgIGlmICh0aGlzLmFnZ3JlZ2F0ZWRCaW5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgbWF4VmFsdWUgPSAwO1xuICAgICAgbWluVmFsdWUgPSAwO1xuICAgIH1cbiAgICB0aGlzLm1heENvdW50ID0gbWF4Q291bnQ7XG4gICAgdGhpcy5tYXhWYWx1ZSA9IG1heFZhbHVlO1xuICAgIHRoaXMubWluVmFsdWUgPSBtaW5WYWx1ZTtcbiAgICB0aGlzLnRvdGFsQ291bnQgPSB0b3RhbENvdW50O1xuICB9XG5cbiAgX2dldEJpbk1hcCgpIHtcbiAgICBjb25zdCBiaW5NYXAgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGJpbiBvZiB0aGlzLmFnZ3JlZ2F0ZWRCaW5zKSB7XG4gICAgICBiaW5NYXBbYmluLmldID0gYmluO1xuICAgIH1cbiAgICByZXR1cm4gYmluTWFwO1xuICB9XG5cbiAgX3BlcmNlbnRpbGVUb0luZGV4KHBlcmNlbnRpbGVSYW5nZTogbnVtYmVyW10pIHtcbiAgICBjb25zdCBsZW4gPSB0aGlzLnNvcnRlZEJpbnMubGVuZ3RoO1xuICAgIGlmIChsZW4gPCAyKSByZXR1cm4gWzAsIDBdO1xuICAgIGNvbnN0IFtsb3dlciwgdXBwZXJdID0gcGVyY2VudGlsZVJhbmdlLm1hcChuID0+IGNsYW1wKG4sIDAsIDEwMCkpO1xuICAgIHJldHVybiBbTWF0aC5jZWlsKChsb3dlciAvIDEwMCkgKiAobGVuIC0gMSkpLCBNYXRoLmZsb29yKCh1cHBlciAvIDEwMCkgKiAobGVuIC0gMSkpXTtcbiAgfVxuXG4gIGdldFZhbHVlRG9tYWluQnlTY2FsZShzY2FsZTogc3RyaW5nLCBbbG93ZXIgPSAwLCB1cHBlciA9IDEwMF06IG51bWJlcltdID0gW10pIHtcbiAgICBpZiAoIXRoaXMuc29ydGVkQmlucykge1xuICAgICAgdGhpcy5zb3J0ZWRCaW5zID0gdGhpcy5hZ2dyZWdhdGVkQmlucy5zb3J0KChhLCBiKSA9PiBhc2NlbmRpbmcoYS52YWx1ZSwgYi52YWx1ZSkpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuc29ydGVkQmlucy5sZW5ndGgpIHJldHVybiBbXTtcbiAgICBjb25zdCBpbmRleEVkZ2UgPSB0aGlzLl9wZXJjZW50aWxlVG9JbmRleChbbG93ZXIsIHVwcGVyXSk7XG4gICAgcmV0dXJuIHRoaXMuX2dldFNjYWxlRG9tYWluKHNjYWxlLCBpbmRleEVkZ2UpO1xuICB9XG5cbiAgX2dldFNjYWxlRG9tYWluKHNjYWxlVHlwZTogc3RyaW5nLCBbbG93ZXJJZHgsIHVwcGVySWR4XTogbnVtYmVyW10pIHtcbiAgICBjb25zdCBiaW5zID0gdGhpcy5zb3J0ZWRCaW5zO1xuICAgIHN3aXRjaCAoc2NhbGVUeXBlKSB7XG4gICAgICBjYXNlICdxdWFudGl6ZSc6XG4gICAgICBjYXNlICdsaW5lYXInOlxuICAgICAgICByZXR1cm4gW2JpbnNbbG93ZXJJZHhdLnZhbHVlLCBiaW5zW3VwcGVySWR4XS52YWx1ZV07XG4gICAgICBjYXNlICdxdWFudGlsZSc6XG4gICAgICAgIHJldHVybiBnZXRRdWFudGlsZURvbWFpbihiaW5zLnNsaWNlKGxvd2VySWR4LCB1cHBlcklkeCArIDEpLCBkID0+IGQudmFsdWUpO1xuICAgICAgY2FzZSAnb3JkaW5hbCc6XG4gICAgICAgIHJldHVybiBnZXRPcmRpbmFsRG9tYWluKGJpbnMsIGQgPT4gZC52YWx1ZSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gW2JpbnNbbG93ZXJJZHhdLnZhbHVlLCBiaW5zW3VwcGVySWR4XS52YWx1ZV07XG4gICAgfVxuICB9XG5cbiAgZ2V0VmFsdWVSYW5nZShwZXJjZW50aWxlUmFuZ2U/OiBudW1iZXJbXSkge1xuICAgIGlmICghdGhpcy5zb3J0ZWRCaW5zKSB7XG4gICAgICB0aGlzLnNvcnRlZEJpbnMgPSB0aGlzLmFnZ3JlZ2F0ZWRCaW5zLnNvcnQoKGEsIGIpID0+IGFzY2VuZGluZyhhLnZhbHVlLCBiLnZhbHVlKSk7XG4gICAgfVxuICAgIGlmICghdGhpcy5zb3J0ZWRCaW5zLmxlbmd0aCkgcmV0dXJuIFtdO1xuICAgIGxldCBsb3dlcklkeCA9IDA7XG4gICAgbGV0IHVwcGVySWR4ID0gdGhpcy5zb3J0ZWRCaW5zLmxlbmd0aCAtIDE7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocGVyY2VudGlsZVJhbmdlKSkge1xuICAgICAgY29uc3QgaWR4UmFuZ2UgPSB0aGlzLl9wZXJjZW50aWxlVG9JbmRleChwZXJjZW50aWxlUmFuZ2UpO1xuICAgICAgbG93ZXJJZHggPSBpZHhSYW5nZVswXTtcbiAgICAgIHVwcGVySWR4ID0gaWR4UmFuZ2VbMV07XG4gICAgfVxuICAgIHJldHVybiBbdGhpcy5zb3J0ZWRCaW5zW2xvd2VySWR4XS52YWx1ZSwgdGhpcy5zb3J0ZWRCaW5zW3VwcGVySWR4XS52YWx1ZV07XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgVXBkYXRlclR5cGUgPSAodGhpczogQ1BVQWdncmVnYXRvciwgc3RlcCwgcHJvcHMsIGRpbWVuc2lvblVwZGF0ZXIpID0+IHZvaWQ7XG5leHBvcnQgdHlwZSBCaW5kZWRVcGRhdGVyVHlwZSA9ICgpID0+IHZvaWQ7XG5leHBvcnQgdHlwZSBBZ2dyZWdhdGVkVXBkYXRlclR5cGUgPSAoXG4gIHRoaXM6IENQVUFnZ3JlZ2F0b3IsXG4gIHN0ZXAsXG4gIHByb3BzLFxuICBhZ2dyZWdhdGlvbixcbiAgYWdncmVnYXRpb25QYXJhbXNcbikgPT4gdm9pZDtcbmV4cG9ydCB0eXBlIEJpbmRlZEFnZ3JlZ2F0ZWRVcGRhdGVyVHlwZSA9IChhZ2dyZWdhdGlvblBhcmFtcykgPT4gdm9pZDtcblxuZXhwb3J0IHR5cGUgVXBkYXRlU3RlcHNUeXBlID0ge1xuICBrZXk6IHN0cmluZztcbiAgdHJpZ2dlcnM6IHtcbiAgICBba2V5OiBzdHJpbmddOiB7XG4gICAgICBwcm9wOiBzdHJpbmc7XG4gICAgICB1cGRhdGVUcmlnZ2VyPzogc3RyaW5nO1xuICAgIH07XG4gIH07XG4gIG9uU2V0Pzoge1xuICAgIHByb3BzOiBzdHJpbmc7XG4gIH07XG4gIHVwZGF0ZXI6IFVwZGF0ZXJUeXBlO1xufTtcblxuZXhwb3J0IHR5cGUgRGltZW5zaW9uVHlwZTxWYWx1ZVR5cGUgPSBhbnk+ID0ge1xuICBrZXk6IHN0cmluZztcbiAgYWNjZXNzb3I6IHN0cmluZztcbiAgZ2V0UGlja2luZ0luZm86IChkaW1lbnNpb25TdGF0ZSwgY2VsbCwgbGF5ZXJQcm9wcz8pID0+IGFueTtcbiAgbnVsbFZhbHVlOiBWYWx1ZVR5cGU7XG4gIHVwZGF0ZVN0ZXBzOiBVcGRhdGVTdGVwc1R5cGVbXTtcbiAgZ2V0U3ViTGF5ZXJBY2Nlc3Nvcjtcbn07XG5cbmV4cG9ydCB0eXBlIEFnZ3JlZ2F0aW9uVXBkYXRlU3RlcHNUeXBlID0ge1xuICBrZXk6IHN0cmluZztcbiAgdHJpZ2dlcnM6IHtcbiAgICBba2V5OiBzdHJpbmddOiB7XG4gICAgICBwcm9wOiBzdHJpbmc7XG4gICAgICB1cGRhdGVUcmlnZ2VyPzogc3RyaW5nO1xuICAgIH07XG4gIH07XG4gIHVwZGF0ZXI6IEFnZ3JlZ2F0ZWRVcGRhdGVyVHlwZTtcbn07XG5cbmV4cG9ydCB0eXBlIEFnZ3JlZ2F0aW9uVHlwZSA9IHtcbiAga2V5OiBzdHJpbmc7XG4gIHVwZGF0ZVN0ZXBzOiBBZ2dyZWdhdGlvblVwZGF0ZVN0ZXBzVHlwZVtdO1xufTtcblxuZXhwb3J0IGNvbnN0IERFQ0tfQUdHUkVHQVRJT05fTUFQID0ge1xuICBbQUdHUkVHQVRJT05fT1BFUkFUSU9OLlNVTV06IEFHR1JFR0FUSU9OX1RZUEVTLnN1bSxcbiAgW0FHR1JFR0FUSU9OX09QRVJBVElPTi5NRUFOXTogQUdHUkVHQVRJT05fVFlQRVMuYXZlcmFnZSxcbiAgW0FHR1JFR0FUSU9OX09QRVJBVElPTi5NSU5dOiBBR0dSRUdBVElPTl9UWVBFUy5taW5pbXVtLFxuICBbQUdHUkVHQVRJT05fT1BFUkFUSU9OLk1BWF06IEFHR1JFR0FUSU9OX1RZUEVTLm1heGltdW1cbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRWYWx1ZUZ1bmMoXG4gIGFnZ3JlZ2F0aW9uOiBzdHJpbmcsXG4gIGFjY2Vzc29yOiAoZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IG51bWJlclxuKSB7XG4gIGlmICghYWdncmVnYXRpb24gfHwgIUFHR1JFR0FUSU9OX09QRVJBVElPTlthZ2dyZWdhdGlvbi50b1VwcGVyQ2FzZSgpXSkge1xuICAgIENvbnNvbGUud2FybihgQWdncmVnYXRpb24gJHthZ2dyZWdhdGlvbn0gaXMgbm90IHN1cHBvcnRlZGApO1xuICB9XG5cbiAgY29uc3Qgb3AgPSBBR0dSRUdBVElPTl9PUEVSQVRJT05bYWdncmVnYXRpb24udG9VcHBlckNhc2UoKV0gfHwgQUdHUkVHQVRJT05fT1BFUkFUSU9OLlNVTTtcbiAgY29uc3Qga2VwbGVyT3AgPSBERUNLX0FHR1JFR0FUSU9OX01BUFtvcF07XG5cbiAgcmV0dXJuIHB0cyA9PiBhZ2dyZWdhdGUocHRzLm1hcChhY2Nlc3NvciksIGtlcGxlck9wKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNjYWxlRnVuY3RvcihzY2FsZVR5cGU6IHN0cmluZykge1xuICBpZiAoIXNjYWxlVHlwZSB8fCAhU0NBTEVfRlVOQ1tzY2FsZVR5cGVdKSB7XG4gICAgQ29uc29sZS53YXJuKGBTY2FsZSAke3NjYWxlVHlwZX0gaXMgbm90IHN1cHBvcnRlZGApO1xuICB9XG4gIHJldHVybiBTQ0FMRV9GVU5DW3NjYWxlVHlwZV0gfHwgU0NBTEVfRlVOQy5xdWFudGl6ZTtcbn1cblxuZnVuY3Rpb24gbm9wKCkge1xuICByZXR1cm47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRHZXRWYWx1ZSh0aGlzOiBDUFVBZ2dyZWdhdG9yLCBzdGVwLCBwcm9wcywgZGltZW5zaW9uVXBkYXRlcikge1xuICBjb25zdCB7a2V5fSA9IGRpbWVuc2lvblVwZGF0ZXI7XG4gIGNvbnN0IHt2YWx1ZSwgd2VpZ2h0LCBhZ2dyZWdhdGlvbn0gPSBzdGVwLnRyaWdnZXJzO1xuXG4gIGxldCBnZXRWYWx1ZSA9IHByb3BzW3ZhbHVlLnByb3BdO1xuXG4gIGlmIChnZXRWYWx1ZSA9PT0gbnVsbCkge1xuICAgIC8vIElmIGBnZXRWYWx1ZWAgaXMgbm90IHByb3ZpZGVkIGZyb20gcHJvcHMsIGJ1aWxkIGl0IHdpdGggYWdncmVnYXRpb24gYW5kIHdlaWdodC5cbiAgICBnZXRWYWx1ZSA9IGdldFZhbHVlRnVuYyhwcm9wc1thZ2dyZWdhdGlvbi5wcm9wXSwgcHJvcHNbd2VpZ2h0LnByb3BdKTtcbiAgfVxuXG4gIGlmIChnZXRWYWx1ZSkge1xuICAgIHRoaXMuX3NldERpbWVuc2lvblN0YXRlKGtleSwge2dldFZhbHVlfSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERpbWVuc2lvblNvcnRlZEJpbnModGhpczogQ1BVQWdncmVnYXRvciwgc3RlcCwgcHJvcHMsIGRpbWVuc2lvblVwZGF0ZXIpIHtcbiAgY29uc3Qge2tleX0gPSBkaW1lbnNpb25VcGRhdGVyO1xuICBjb25zdCB7Z2V0VmFsdWV9ID0gdGhpcy5zdGF0ZS5kaW1lbnNpb25zW2tleV07XG4gIGNvbnN0IHNvcnRlZEJpbnMgPSBuZXcgQmluU29ydGVyKCh0aGlzLnN0YXRlLmxheWVyRGF0YS5kYXRhIHx8IFtdKSBhcyB1bmtub3duIGFzIEJpbltdLCB7XG4gICAgZ2V0VmFsdWUsXG4gICAgZmlsdGVyRGF0YTogcHJvcHMuX2ZpbHRlckRhdGFcbiAgfSk7XG4gIHRoaXMuX3NldERpbWVuc2lvblN0YXRlKGtleSwge3NvcnRlZEJpbnN9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERpbWVuc2lvblZhbHVlRG9tYWluKHRoaXM6IENQVUFnZ3JlZ2F0b3IsIHN0ZXAsIHByb3BzLCBkaW1lbnNpb25VcGRhdGVyKSB7XG4gIGNvbnN0IHtrZXl9ID0gZGltZW5zaW9uVXBkYXRlcjtcbiAgY29uc3Qge1xuICAgIHRyaWdnZXJzOiB7bG93ZXJQZXJjZW50aWxlLCB1cHBlclBlcmNlbnRpbGUsIHNjYWxlVHlwZX1cbiAgfSA9IHN0ZXA7XG5cbiAgaWYgKCF0aGlzLnN0YXRlLmRpbWVuc2lvbnNba2V5XS5zb3J0ZWRCaW5zKSB7XG4gICAgLy8gdGhlIHByZXZpb3VzIHN0ZXAgc2hvdWxkIHNldCBzb3J0ZWRCaW5zLCBpZiBub3QsIHNvbWV0aGluZyB3ZW50IHdyb25nXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbGV0IHZhbHVlRG9tYWluID1cbiAgICAvLyBmb3IgbG9nIGFuZCBzcXJ0IHNjYWxlLCByZXR1cm5zIGxpbmVhciBkb21haW4gYnkgZGVmYXVsdFxuICAgIC8vIFRPRE86IHN1cHBvcnQgb3RoZXIgc2NhbGUgZnVuY3Rpb24gZG9tYWluIGluIGJpbiBzb3J0ZXJcbiAgICB0aGlzLnN0YXRlLmRpbWVuc2lvbnNba2V5XS5zb3J0ZWRCaW5zLmdldFZhbHVlRG9tYWluQnlTY2FsZShwcm9wc1tzY2FsZVR5cGUucHJvcF0sIFtcbiAgICAgIHByb3BzW2xvd2VyUGVyY2VudGlsZS5wcm9wXSxcbiAgICAgIHByb3BzW3VwcGVyUGVyY2VudGlsZS5wcm9wXVxuICAgIF0pO1xuXG4gIGlmIChwcm9wcy5jb2xvclNjYWxlVHlwZSA9PT0gJ2N1c3RvbScgJiYgcHJvcHMuY29sb3JNYXApIHtcbiAgICAvLyBmb3IgY3VzdG9tIHNjYWxlLCByZXR1cm4gY3VzdG9tIGJyZWFrcyBhcyB2YWx1ZSBkb21haW4gZGlyZWN0bHlcbiAgICB2YWx1ZURvbWFpbiA9IHByb3BzLmNvbG9yTWFwLnJlZHVjZShcbiAgICAgIChwcmV2LCBjdXIpID0+IChOdW1iZXIuaXNGaW5pdGUoY3VyWzBdKSA/IHByZXYuY29uY2F0KGN1clswXSkgOiBwcmV2KSxcbiAgICAgIFtdXG4gICAgKTtcbiAgfVxuXG4gIHRoaXMuX3NldERpbWVuc2lvblN0YXRlKGtleSwge3ZhbHVlRG9tYWlufSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREaW1lbnNpb25TY2FsZSh0aGlzOiBDUFVBZ2dyZWdhdG9yLCBzdGVwLCBwcm9wcywgZGltZW5zaW9uVXBkYXRlcikge1xuICBjb25zdCB7a2V5fSA9IGRpbWVuc2lvblVwZGF0ZXI7XG4gIGNvbnN0IHtkb21haW4sIHJhbmdlLCBzY2FsZVR5cGUsIGZpeGVkfSA9IHN0ZXAudHJpZ2dlcnM7XG4gIGNvbnN0IHtvblNldH0gPSBzdGVwO1xuICBpZiAoIXRoaXMuc3RhdGUuZGltZW5zaW9uc1trZXldLnZhbHVlRG9tYWluKSB7XG4gICAgLy8gdGhlIHByZXZpb3VzIHN0ZXAgc2hvdWxkIHNldCB2YWx1ZURvbWFpbiwgaWYgbm90LCBzb21ldGhpbmcgd2VudCB3cm9uZ1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGRpbWVuc2lvblJhbmdlID0gcHJvcHNbcmFuZ2UucHJvcF07XG4gIGNvbnN0IGRpbWVuc2lvbkRvbWFpbiA9IHByb3BzW2RvbWFpbi5wcm9wXSB8fCB0aGlzLnN0YXRlLmRpbWVuc2lvbnNba2V5XS52YWx1ZURvbWFpbjtcbiAgY29uc3QgZGltZW5zaW9uRml4ZWQgPSBCb29sZWFuKGZpeGVkICYmIHByb3BzW2ZpeGVkLnByb3BdKTtcblxuICBjb25zdCBzY2FsZUZ1bmN0b3IgPSBnZXRTY2FsZUZ1bmN0b3Ioc2NhbGVUeXBlICYmIHByb3BzW3NjYWxlVHlwZS5wcm9wXSkoKTtcblxuICBjb25zdCBzY2FsZUZ1bmMgPSBzY2FsZUZ1bmN0b3JcbiAgICAuZG9tYWluKGRpbWVuc2lvbkRvbWFpbilcbiAgICAucmFuZ2UoZGltZW5zaW9uRml4ZWQgPyBkaW1lbnNpb25Eb21haW4gOiBkaW1lbnNpb25SYW5nZSk7XG4gIHNjYWxlRnVuYy5zY2FsZVR5cGUgPSBwcm9wcy5jb2xvclNjYWxlVHlwZTtcblxuICBpZiAodHlwZW9mIG9uU2V0ID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgcHJvcHNbb25TZXQucHJvcHNdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY29uc3Qgc29ydGVkQmlucyA9IHRoaXMuc3RhdGUuZGltZW5zaW9uc1trZXldLnNvcnRlZEJpbnM7XG4gICAgaWYgKHNvcnRlZEJpbnMpIHtcbiAgICAgIHByb3BzW29uU2V0LnByb3BzXSh7ZG9tYWluOiBzY2FsZUZ1bmMuZG9tYWluKCksIGFnZ3JlZ2F0ZWRCaW5zOiBzb3J0ZWRCaW5zLmJpbk1hcH0pO1xuICAgIH1cbiAgfVxuICB0aGlzLl9zZXREaW1lbnNpb25TdGF0ZShrZXksIHtzY2FsZUZ1bmN9KTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplUmVzdWx0KFxuICByZXN1bHQ6IHtcbiAgICBoZXhhZ29ucz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+W107XG4gICAgbGF5ZXJEYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXTtcbiAgICBkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXTtcbiAgfSA9IHt9XG4pIHtcbiAgLy8gc3VwcG9ydCBwcmV2aW91cyBoZXhhZ29uQWdncmVnYXRvciBBUElcbiAgaWYgKHJlc3VsdC5oZXhhZ29ucykge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtkYXRhOiByZXN1bHQuaGV4YWdvbnN9LCByZXN1bHQpO1xuICB9IGVsc2UgaWYgKHJlc3VsdC5sYXllckRhdGEpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7ZGF0YTogcmVzdWx0LmxheWVyRGF0YX0sIHJlc3VsdCk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWdncmVnYXRlZERhdGEoXG4gIHRoaXM6IENQVUFnZ3JlZ2F0b3IsXG4gIHN0ZXAsXG4gIHByb3BzLFxuICBhZ2dyZWdhdGlvbixcbiAgYWdncmVnYXRpb25QYXJhbXNcbikge1xuICBjb25zdCB7XG4gICAgdHJpZ2dlcnM6IHthZ2dyZWdhdG9yOiBhZ2dyfVxuICB9ID0gc3RlcDtcbiAgY29uc3QgYWdncmVnYXRvciA9IHByb3BzW2FnZ3IucHJvcF07XG5cbiAgLy8gcmVzdWx0IHNob3VsZCBjb250YWluIGEgZGF0YSBhcnJheSBhbmQgb3RoZXIgcHJvcHNcbiAgLy8gcmVzdWx0ID0ge2RhdGE6IFtdLCAuLi5vdGhlciBwcm9wc31cbiAgY29uc3QgcmVzdWx0ID0gYWdncmVnYXRvcihwcm9wcywgYWdncmVnYXRpb25QYXJhbXMpO1xuICB0aGlzLnNldFN0YXRlKHtcbiAgICBsYXllckRhdGE6IG5vcm1hbGl6ZVJlc3VsdChyZXN1bHQpXG4gIH0pO1xufVxuXG5leHBvcnQgY29uc3QgZGVmYXVsdEFnZ3JlZ2F0aW9uOiBBZ2dyZWdhdGlvblR5cGUgPSB7XG4gIGtleTogJ3Bvc2l0aW9uJyxcbiAgdXBkYXRlU3RlcHM6IFtcbiAgICB7XG4gICAgICBrZXk6ICdhZ2dyZWdhdGUnLFxuICAgICAgdHJpZ2dlcnM6IHtcbiAgICAgICAgY2VsbFNpemU6IHtcbiAgICAgICAgICBwcm9wOiAnY2VsbFNpemUnXG4gICAgICAgIH0sXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgcHJvcDogJ2dldFBvc2l0aW9uJyxcbiAgICAgICAgICB1cGRhdGVUcmlnZ2VyOiAnZ2V0UG9zaXRpb24nXG4gICAgICAgIH0sXG4gICAgICAgIGFnZ3JlZ2F0b3I6IHtcbiAgICAgICAgICBwcm9wOiAnZ3JpZEFnZ3JlZ2F0b3InXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB1cGRhdGVyOiBnZXRBZ2dyZWdhdGVkRGF0YVxuICAgIH1cbiAgXVxufTtcblxuZnVuY3Rpb24gZ2V0U3ViTGF5ZXJBY2Nlc3NvcihcbiAgZGltZW5zaW9uU3RhdGU6IHtzb3J0ZWRCaW5zOiBCaW5Tb3J0ZXI7IHNjYWxlRnVuYzogUmV0dXJuVHlwZTx0eXBlb2YgZ2V0U2NhbGVGdW5jdG9yPn0sXG4gIGRpbWVuc2lvbjogRGltZW5zaW9uVHlwZVxuKSB7XG4gIHJldHVybiAoY2VsbDoge2luZGV4OiBudW1iZXJ9KSA9PiB7XG4gICAgY29uc3Qge3NvcnRlZEJpbnMsIHNjYWxlRnVuY30gPSBkaW1lbnNpb25TdGF0ZTtcbiAgICBjb25zdCBiaW4gPSBzb3J0ZWRCaW5zLmJpbk1hcFtjZWxsLmluZGV4XTtcblxuICAgIGlmIChiaW4gJiYgYmluLmNvdW50cyA9PT0gMCkge1xuICAgICAgLy8gbm8gcG9pbnRzIGxlZnQgaW4gYmluIGFmdGVyIGZpbHRlcmluZ1xuICAgICAgcmV0dXJuIGRpbWVuc2lvbi5udWxsVmFsdWU7XG4gICAgfVxuXG4gICAgY29uc3QgY3YgPSBiaW4gJiYgYmluLnZhbHVlO1xuICAgIGNvbnN0IGRvbWFpbiA9IHNjYWxlRnVuYy5kb21haW4oKTtcblxuICAgIGNvbnN0IGlzVmFsdWVJbkRvbWFpbiA9XG4gICAgICBzY2FsZUZ1bmMuc2NhbGVUeXBlID09PSAnY3VzdG9tJ1xuICAgICAgICA/IGN2ID49IHNvcnRlZEJpbnMubWluVmFsdWUgJiYgY3YgPD0gc29ydGVkQmlucy5tYXhWYWx1ZVxuICAgICAgICA6IGN2ID49IGRvbWFpblswXSAmJiBjdiA8PSBkb21haW5bZG9tYWluLmxlbmd0aCAtIDFdO1xuXG4gICAgLy8gaWYgY2VsbCB2YWx1ZSBpcyBvdXRzaWRlIGRvbWFpbiwgc2V0IGFscGhhIHRvIDBcbiAgICByZXR1cm4gaXNWYWx1ZUluRG9tYWluID8gc2NhbGVGdW5jKGN2KSA6IGRpbWVuc2lvbi5udWxsVmFsdWU7XG4gIH07XG59XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0Q29sb3JEaW1lbnNpb246IERpbWVuc2lvblR5cGU8UkdCQUNvbG9yPiA9IHtcbiAga2V5OiAnZmlsbENvbG9yJyxcbiAgYWNjZXNzb3I6ICdnZXRGaWxsQ29sb3InLFxuICBnZXRQaWNraW5nSW5mbzogKGRpbWVuc2lvblN0YXRlLCBjZWxsKSA9PiB7XG4gICAgaWYgKCFjZWxsKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNvbnN0IHtzb3J0ZWRCaW5zfSA9IGRpbWVuc2lvblN0YXRlO1xuICAgIGNvbnN0IGNvbG9yVmFsdWUgPSBzb3J0ZWRCaW5zLmJpbk1hcFtjZWxsLmluZGV4XSAmJiBzb3J0ZWRCaW5zLmJpbk1hcFtjZWxsLmluZGV4XS52YWx1ZTtcbiAgICByZXR1cm4ge2NvbG9yVmFsdWV9O1xuICB9LFxuICBudWxsVmFsdWU6IFswLCAwLCAwLCAwXSxcbiAgdXBkYXRlU3RlcHM6IFtcbiAgICB7XG4gICAgICBrZXk6ICdnZXRWYWx1ZScsXG4gICAgICB0cmlnZ2Vyczoge1xuICAgICAgICB2YWx1ZToge1xuICAgICAgICAgIHByb3A6ICdnZXRDb2xvclZhbHVlJyxcbiAgICAgICAgICB1cGRhdGVUcmlnZ2VyOiAnZ2V0Q29sb3JWYWx1ZSdcbiAgICAgICAgfSxcbiAgICAgICAgd2VpZ2h0OiB7XG4gICAgICAgICAgcHJvcDogJ2dldENvbG9yV2VpZ2h0JyxcbiAgICAgICAgICB1cGRhdGVUcmlnZ2VyOiAnZ2V0Q29sb3JXZWlnaHQnXG4gICAgICAgIH0sXG4gICAgICAgIGFnZ3JlZ2F0aW9uOiB7XG4gICAgICAgICAgcHJvcDogJ2NvbG9yQWdncmVnYXRpb24nXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB1cGRhdGVyOiBnZXRHZXRWYWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAga2V5OiAnZ2V0QmlucycsXG4gICAgICB0cmlnZ2Vyczoge1xuICAgICAgICBfZmlsdGVyRGF0YToge1xuICAgICAgICAgIHByb3A6ICdfZmlsdGVyRGF0YScsXG4gICAgICAgICAgdXBkYXRlVHJpZ2dlcjogJ19maWx0ZXJEYXRhJ1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgdXBkYXRlcjogZ2V0RGltZW5zaW9uU29ydGVkQmluc1xuICAgIH0sXG4gICAge1xuICAgICAga2V5OiAnZ2V0RG9tYWluJyxcbiAgICAgIHRyaWdnZXJzOiB7XG4gICAgICAgIGxvd2VyUGVyY2VudGlsZToge1xuICAgICAgICAgIHByb3A6ICdsb3dlclBlcmNlbnRpbGUnXG4gICAgICAgIH0sXG4gICAgICAgIHVwcGVyUGVyY2VudGlsZToge1xuICAgICAgICAgIHByb3A6ICd1cHBlclBlcmNlbnRpbGUnXG4gICAgICAgIH0sXG4gICAgICAgIHNjYWxlVHlwZToge3Byb3A6ICdjb2xvclNjYWxlVHlwZSd9XG4gICAgICB9LFxuICAgICAgdXBkYXRlcjogZ2V0RGltZW5zaW9uVmFsdWVEb21haW5cbiAgICB9LFxuICAgIHtcbiAgICAgIGtleTogJ2dldFNjYWxlRnVuYycsXG4gICAgICB0cmlnZ2Vyczoge1xuICAgICAgICBkb21haW46IHtwcm9wOiAnY29sb3JEb21haW4nfSxcbiAgICAgICAgcmFuZ2U6IHtwcm9wOiAnY29sb3JSYW5nZSd9LFxuICAgICAgICBzY2FsZVR5cGU6IHtwcm9wOiAnY29sb3JTY2FsZVR5cGUnfVxuICAgICAgfSxcbiAgICAgIG9uU2V0OiB7XG4gICAgICAgIHByb3BzOiAnb25TZXRDb2xvckRvbWFpbidcbiAgICAgIH0sXG4gICAgICB1cGRhdGVyOiBnZXREaW1lbnNpb25TY2FsZVxuICAgIH1cbiAgXSxcbiAgZ2V0U3ViTGF5ZXJBY2Nlc3NvclxufTtcblxuZXhwb3J0IGNvbnN0IGRlZmF1bHRFbGV2YXRpb25EaW1lbnNpb246IERpbWVuc2lvblR5cGU8bnVtYmVyPiA9IHtcbiAga2V5OiAnZWxldmF0aW9uJyxcbiAgYWNjZXNzb3I6ICdnZXRFbGV2YXRpb24nLFxuICBnZXRQaWNraW5nSW5mbzogKGRpbWVuc2lvblN0YXRlLCBjZWxsKSA9PiB7XG4gICAgaWYgKCFjZWxsKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNvbnN0IHtzb3J0ZWRCaW5zfSA9IGRpbWVuc2lvblN0YXRlO1xuICAgIGNvbnN0IGVsZXZhdGlvblZhbHVlID0gc29ydGVkQmlucy5iaW5NYXBbY2VsbC5pbmRleF0gJiYgc29ydGVkQmlucy5iaW5NYXBbY2VsbC5pbmRleF0udmFsdWU7XG4gICAgcmV0dXJuIHtlbGV2YXRpb25WYWx1ZX07XG4gIH0sXG4gIG51bGxWYWx1ZTogLTEsXG4gIHVwZGF0ZVN0ZXBzOiBbXG4gICAge1xuICAgICAga2V5OiAnZ2V0VmFsdWUnLFxuICAgICAgdHJpZ2dlcnM6IHtcbiAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICBwcm9wOiAnZ2V0RWxldmF0aW9uVmFsdWUnLFxuICAgICAgICAgIHVwZGF0ZVRyaWdnZXI6ICdnZXRFbGV2YXRpb25WYWx1ZSdcbiAgICAgICAgfSxcbiAgICAgICAgd2VpZ2h0OiB7XG4gICAgICAgICAgcHJvcDogJ2dldEVsZXZhdGlvbldlaWdodCcsXG4gICAgICAgICAgdXBkYXRlVHJpZ2dlcjogJ2dldEVsZXZhdGlvbldlaWdodCdcbiAgICAgICAgfSxcbiAgICAgICAgYWdncmVnYXRpb246IHtcbiAgICAgICAgICBwcm9wOiAnZWxldmF0aW9uQWdncmVnYXRpb24nXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB1cGRhdGVyOiBnZXRHZXRWYWx1ZVxuICAgIH0sXG4gICAge1xuICAgICAga2V5OiAnZ2V0QmlucycsXG4gICAgICB0cmlnZ2Vyczoge1xuICAgICAgICBfZmlsdGVyRGF0YToge1xuICAgICAgICAgIHByb3A6ICdfZmlsdGVyRGF0YScsXG4gICAgICAgICAgdXBkYXRlVHJpZ2dlcjogJ19maWx0ZXJEYXRhJ1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgdXBkYXRlcjogZ2V0RGltZW5zaW9uU29ydGVkQmluc1xuICAgIH0sXG4gICAge1xuICAgICAga2V5OiAnZ2V0RG9tYWluJyxcbiAgICAgIHRyaWdnZXJzOiB7XG4gICAgICAgIGxvd2VyUGVyY2VudGlsZToge1xuICAgICAgICAgIHByb3A6ICdlbGV2YXRpb25Mb3dlclBlcmNlbnRpbGUnXG4gICAgICAgIH0sXG4gICAgICAgIHVwcGVyUGVyY2VudGlsZToge1xuICAgICAgICAgIHByb3A6ICdlbGV2YXRpb25VcHBlclBlcmNlbnRpbGUnXG4gICAgICAgIH0sXG4gICAgICAgIHNjYWxlVHlwZToge3Byb3A6ICdlbGV2YXRpb25TY2FsZVR5cGUnfVxuICAgICAgfSxcbiAgICAgIHVwZGF0ZXI6IGdldERpbWVuc2lvblZhbHVlRG9tYWluXG4gICAgfSxcbiAgICB7XG4gICAgICBrZXk6ICdnZXRTY2FsZUZ1bmMnLFxuICAgICAgdHJpZ2dlcnM6IHtcbiAgICAgICAgZml4ZWQ6IHtwcm9wOiAnZWxldmF0aW9uRml4ZWQnfSxcbiAgICAgICAgZG9tYWluOiB7cHJvcDogJ2VsZXZhdGlvbkRvbWFpbid9LFxuICAgICAgICByYW5nZToge3Byb3A6ICdlbGV2YXRpb25SYW5nZSd9LFxuICAgICAgICBzY2FsZVR5cGU6IHtwcm9wOiAnZWxldmF0aW9uU2NhbGVUeXBlJ31cbiAgICAgIH0sXG4gICAgICBvblNldDoge1xuICAgICAgICBwcm9wczogJ29uU2V0RWxldmF0aW9uRG9tYWluJ1xuICAgICAgfSxcbiAgICAgIHVwZGF0ZXI6IGdldERpbWVuc2lvblNjYWxlXG4gICAgfVxuICBdLFxuICBnZXRTdWJMYXllckFjY2Vzc29yXG59O1xuXG5leHBvcnQgY29uc3QgZGVmYXVsdERpbWVuc2lvbnMgPSBbZGVmYXVsdENvbG9yRGltZW5zaW9uLCBkZWZhdWx0RWxldmF0aW9uRGltZW5zaW9uXTtcblxuZXhwb3J0IHR5cGUgQ1BVQWdncmVnYXRvclN0YXRlID0ge1xuICBsYXllckRhdGE6IHtkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXX07XG4gIGRpbWVuc2lvbnM6IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAge1xuICAgICAgZ2V0VmFsdWU/OiAoLi4uYXJnczogdW5rbm93bltdKSA9PiBudW1iZXI7XG4gICAgICBzb3J0ZWRCaW5zPzogQmluU29ydGVyO1xuICAgICAgdmFsdWVEb21haW4/OiBudW1iZXJbXTtcbiAgICAgIHNjYWxlRnVuYz86ICgoLi4uYXJnczogdW5rbm93bltdKSA9PiB1bmtub3duKSAmIHtkb21haW46ICgpID0+IG51bWJlcltdOyBzY2FsZVR5cGU/OiBzdHJpbmd9O1xuICAgIH1cbiAgPjtcbiAgZ2VvSlNPTj86IEdlb0pTT04uRmVhdHVyZUNvbGxlY3Rpb247XG4gIGNsdXN0ZXJCdWlsZGVyPzogQ2x1c3RlckJ1aWxkZXI7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDUFVBZ2dyZWdhdG9yIHtcbiAgc3RhdGljIGdldERpbWVuc2lvblNjYWxlOiBhbnk7XG4gIHN0YXRlOiBDUFVBZ2dyZWdhdG9yU3RhdGU7XG4gIGRpbWVuc2lvblVwZGF0ZXJzOiB7W2tleTogc3RyaW5nXTogRGltZW5zaW9uVHlwZX07XG4gIGFnZ3JlZ2F0aW9uVXBkYXRlcjogQWdncmVnYXRpb25UeXBlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIG9wdHM6IHtcbiAgICAgIGluaXRpYWxTdGF0ZT86IENQVUFnZ3JlZ2F0b3JTdGF0ZTtcbiAgICAgIGRpbWVuc2lvbnM/OiBEaW1lbnNpb25UeXBlW107XG4gICAgICBhZ2dyZWdhdGlvbj86IEFnZ3JlZ2F0aW9uVHlwZTtcbiAgICB9ID0ge31cbiAgKSB7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGxheWVyRGF0YToge30sXG4gICAgICBkaW1lbnNpb25zOiB7XG4gICAgICAgIC8vIGNvbG9yOiB7XG4gICAgICAgIC8vICAgZ2V0VmFsdWU6IG51bGwsXG4gICAgICAgIC8vICAgZG9tYWluOiBudWxsLFxuICAgICAgICAvLyAgIHNvcnRlZEJpbnM6IG51bGwsXG4gICAgICAgIC8vICAgc2NhbGVGdW5jOiBub3BcbiAgICAgICAgLy8gfSxcbiAgICAgICAgLy8gZWxldmF0aW9uOiB7XG4gICAgICAgIC8vICAgZ2V0VmFsdWU6IG51bGwsXG4gICAgICAgIC8vICAgZG9tYWluOiBudWxsLFxuICAgICAgICAvLyAgIHNvcnRlZEJpbnM6IG51bGwsXG4gICAgICAgIC8vICAgc2NhbGVGdW5jOiBub3BcbiAgICAgICAgLy8gfVxuICAgICAgfSxcbiAgICAgIC4uLm9wdHMuaW5pdGlhbFN0YXRlXG4gICAgfTtcblxuICAgIHRoaXMuZGltZW5zaW9uVXBkYXRlcnMgPSB7fTtcbiAgICB0aGlzLmFnZ3JlZ2F0aW9uVXBkYXRlciA9IG9wdHMuYWdncmVnYXRpb24gfHwgZGVmYXVsdEFnZ3JlZ2F0aW9uO1xuXG4gICAgdGhpcy5fYWRkRGltZW5zaW9uKG9wdHMuZGltZW5zaW9ucyB8fCBkZWZhdWx0RGltZW5zaW9ucyk7XG4gIH1cblxuICBzdGF0aWMgZGVmYXVsdERpbWVuc2lvbnMoKSB7XG4gICAgcmV0dXJuIGRlZmF1bHREaW1lbnNpb25zO1xuICB9XG5cbiAgdXBkYXRlQWxsRGltZW5zaW9ucyhwcm9wczogUmVjb3JkPHN0cmluZywgYW55Pikge1xuICAgIGxldCBkaW1lbnNpb25DaGFuZ2VzOiBCaW5kZWRVcGRhdGVyVHlwZVtdID0gW107XG4gICAgLy8gdXBkYXRlIGFsbCBkaW1lbnNpb25zXG4gICAgZm9yIChjb25zdCBkaW0gaW4gdGhpcy5kaW1lbnNpb25VcGRhdGVycykge1xuICAgICAgY29uc3QgdXBkYXRlcnMgPSB0aGlzLl9hY2N1bXVsYXRlVXBkYXRlcnMoMCwgcHJvcHMsIHRoaXMuZGltZW5zaW9uVXBkYXRlcnNbZGltXSk7XG4gICAgICBkaW1lbnNpb25DaGFuZ2VzID0gZGltZW5zaW9uQ2hhbmdlcy5jb25jYXQodXBkYXRlcnMpO1xuICAgIH1cblxuICAgIGRpbWVuc2lvbkNoYW5nZXMuZm9yRWFjaChmID0+IHR5cGVvZiBmID09PSAnZnVuY3Rpb24nICYmIGYoKSk7XG4gIH1cblxuICB1cGRhdGVBZ2dyZWdhdGlvbihwcm9wczogUmVjb3JkPHN0cmluZywgYW55PiwgYWdncmVnYXRpb25QYXJhbXM6IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbiAgICBjb25zdCB1cGRhdGVycyA9IHRoaXMuX2FjY3VtdWxhdGVVcGRhdGVycygwLCBwcm9wcywgdGhpcy5hZ2dyZWdhdGlvblVwZGF0ZXIpO1xuICAgIHVwZGF0ZXJzLmZvckVhY2goZiA9PiB0eXBlb2YgZiA9PT0gJ2Z1bmN0aW9uJyAmJiBmKGFnZ3JlZ2F0aW9uUGFyYW1zKSk7XG4gIH1cblxuICB1cGRhdGVTdGF0ZShcbiAgICBvcHRzOiB7XG4gICAgICBvbGRQcm9wczogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICAgIHByb3BzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgICAgY2hhbmdlRmxhZ3M6IFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgfSxcbiAgICBhZ2dyZWdhdGlvblBhcmFtczogUmVjb3JkPHN0cmluZywgYW55PlxuICApIHtcbiAgICBjb25zdCB7b2xkUHJvcHMsIHByb3BzLCBjaGFuZ2VGbGFnc30gPSBvcHRzO1xuICAgIGxldCBkaW1lbnNpb25DaGFuZ2VzOiBCaW5kZWRVcGRhdGVyVHlwZVtdID0gW107XG5cbiAgICBpZiAoY2hhbmdlRmxhZ3MuZGF0YUNoYW5nZWQpIHtcbiAgICAgIC8vIGlmIGRhdGEgY2hhbmdlZCB1cGRhdGUgZXZlcnl0aGluZ1xuICAgICAgdGhpcy51cGRhdGVBZ2dyZWdhdGlvbihwcm9wcywgYWdncmVnYXRpb25QYXJhbXMpO1xuICAgICAgdGhpcy51cGRhdGVBbGxEaW1lbnNpb25zKHByb3BzKTtcblxuICAgICAgcmV0dXJuIHRoaXMuc3RhdGU7XG4gICAgfVxuXG4gICAgY29uc3QgYWdncmVnYXRpb25DaGFuZ2VzID0gdGhpcy5fZ2V0QWdncmVnYXRpb25DaGFuZ2VzKG9sZFByb3BzLCBwcm9wcywgY2hhbmdlRmxhZ3MpO1xuXG4gICAgaWYgKGFnZ3JlZ2F0aW9uQ2hhbmdlcyAmJiBhZ2dyZWdhdGlvbkNoYW5nZXMubGVuZ3RoKSB7XG4gICAgICAvLyBnZXQgYWdncmVnYXRlZERhdGFcbiAgICAgIGFnZ3JlZ2F0aW9uQ2hhbmdlcy5mb3JFYWNoKGYgPT4gdHlwZW9mIGYgPT09ICdmdW5jdGlvbicgJiYgZihhZ2dyZWdhdGlvblBhcmFtcykpO1xuICAgICAgdGhpcy51cGRhdGVBbGxEaW1lbnNpb25zKHByb3BzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gb25seSB1cGRhdGUgZGltZW5zaW9uc1xuICAgICAgZGltZW5zaW9uQ2hhbmdlcyA9IHRoaXMuX2dldERpbWVuc2lvbkNoYW5nZXMob2xkUHJvcHMsIHByb3BzLCBjaGFuZ2VGbGFncykgfHwgW107XG4gICAgICBkaW1lbnNpb25DaGFuZ2VzLmZvckVhY2goZiA9PiB0eXBlb2YgZiA9PT0gJ2Z1bmN0aW9uJyAmJiBmKCkpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0YXRlO1xuICB9XG5cbiAgLy8gVXBkYXRlIHByaXZhdGUgc3RhdGVcbiAgc2V0U3RhdGUodXBkYXRlT2JqZWN0OiBQYXJ0aWFsPENQVUFnZ3JlZ2F0b3JTdGF0ZT4pIHtcbiAgICB0aGlzLnN0YXRlID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5zdGF0ZSwgdXBkYXRlT2JqZWN0KTtcbiAgfVxuXG4gIC8vIFVwZGF0ZSBwcml2YXRlIHN0YXRlLmRpbWVuc2lvbnNcbiAgX3NldERpbWVuc2lvblN0YXRlKGtleTogc3RyaW5nLCB1cGRhdGVPYmplY3Q6IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIGRpbWVuc2lvbnM6IE9iamVjdC5hc3NpZ24oe30sIHRoaXMuc3RhdGUuZGltZW5zaW9ucywge1xuICAgICAgICBba2V5XTogT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5zdGF0ZS5kaW1lbnNpb25zW2tleV0sIHVwZGF0ZU9iamVjdClcbiAgICAgIH0pXG4gICAgfSk7XG4gIH1cblxuICBfYWRkQWdncmVnYXRpb24oYWdncmVnYXRpb246IEFnZ3JlZ2F0aW9uVHlwZSkge1xuICAgIHRoaXMuYWdncmVnYXRpb25VcGRhdGVyID0gYWdncmVnYXRpb247XG4gIH1cblxuICBfYWRkRGltZW5zaW9uKGRpbWVuc2lvbnM6IERpbWVuc2lvblR5cGVbXSA9IFtdKSB7XG4gICAgZGltZW5zaW9ucy5mb3JFYWNoKGRpbWVuc2lvbiA9PiB7XG4gICAgICBjb25zdCB7a2V5fSA9IGRpbWVuc2lvbjtcbiAgICAgIHRoaXMuZGltZW5zaW9uVXBkYXRlcnNba2V5XSA9IGRpbWVuc2lvbjtcbiAgICB9KTtcbiAgfVxuXG4gIF9uZWVkVXBkYXRlU3RlcChcbiAgICBkaW1lbnNpb25TdGVwOiBVcGRhdGVTdGVwc1R5cGUgfCBBZ2dyZWdhdGlvblVwZGF0ZVN0ZXBzVHlwZSxcbiAgICBvbGRQcm9wcyxcbiAgICBwcm9wcyxcbiAgICBjaGFuZ2VGbGFnc1xuICApIHtcbiAgICAvLyB3aGV0aGVyIG5lZWQgdG8gdXBkYXRlIGN1cnJlbnQgZGltZW5zaW9uIHN0ZXBcbiAgICAvLyBkaW1lbnNpb24gc3RlcCBpcyB0aGUgdmFsdWUsIGRvbWFpbiwgc2NhbGVGdW5jdGlvbiBvZiBlYWNoIGRpbWVuc2lvblxuICAgIC8vIGVhY2ggc3RlcCBpcyBhbiBvYmplY3Qgd2l0aCBwcm9wZXJ0aWVzIGxpbmtzIHRvIGxheWVyIHByb3AgYW5kIHdoZXRoZXIgdGhlIHByb3AgaXNcbiAgICAvLyBjb250cm9sbGVkIGJ5IHVwZGF0ZVRyaWdnZXJzXG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXMoZGltZW5zaW9uU3RlcC50cmlnZ2Vycykuc29tZShpdGVtID0+IHtcbiAgICAgIGlmIChpdGVtLnVwZGF0ZVRyaWdnZXIpIHtcbiAgICAgICAgLy8gY2hlY2sgYmFzZWQgb24gdXBkYXRlVHJpZ2dlcnMgY2hhbmdlIGZpcnN0XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgY2hhbmdlRmxhZ3MudXBkYXRlVHJpZ2dlcnNDaGFuZ2VkICYmXG4gICAgICAgICAgKGNoYW5nZUZsYWdzLnVwZGF0ZVRyaWdnZXJzQ2hhbmdlZC5hbGwgfHxcbiAgICAgICAgICAgIGNoYW5nZUZsYWdzLnVwZGF0ZVRyaWdnZXJzQ2hhbmdlZFtpdGVtLnVwZGF0ZVRyaWdnZXJdKVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgLy8gZmFsbGJhY2sgdG8gZGlyZWN0IGNvbXBhcmlzb25cbiAgICAgIHJldHVybiBvbGRQcm9wc1tpdGVtLnByb3BdICE9PSBwcm9wc1tpdGVtLnByb3BdO1xuICAgIH0pO1xuICB9XG5cbiAgX2FjY3VtdWxhdGVVcGRhdGVyczxVcGRhdGVyT2JqZWN0VHlwZSBleHRlbmRzIERpbWVuc2lvblR5cGUgfCBBZ2dyZWdhdGlvblR5cGU+KFxuICAgIHN0ZXAsXG4gICAgcHJvcHMsXG4gICAgZGltZW5zaW9uOiBVcGRhdGVyT2JqZWN0VHlwZVxuICApIHtcbiAgICB0eXBlIExvY2FsVXBkYXRlclR5cGUgPSBVcGRhdGVyT2JqZWN0VHlwZSBleHRlbmRzIERpbWVuc2lvblR5cGVcbiAgICAgID8gQmluZGVkVXBkYXRlclR5cGVcbiAgICAgIDogQmluZGVkQWdncmVnYXRlZFVwZGF0ZXJUeXBlO1xuICAgIGNvbnN0IHVwZGF0ZXJzOiBMb2NhbFVwZGF0ZXJUeXBlW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gc3RlcDsgaSA8IGRpbWVuc2lvbi51cGRhdGVTdGVwcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgdXBkYXRlciA9IGRpbWVuc2lvbi51cGRhdGVTdGVwc1tpXS51cGRhdGVyO1xuICAgICAgaWYgKHR5cGVvZiB1cGRhdGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHVwZGF0ZXJzLnB1c2goXG4gICAgICAgICAgKHVwZGF0ZXIgYXMgVXBkYXRlclR5cGUpLmJpbmQoXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgZGltZW5zaW9uLnVwZGF0ZVN0ZXBzW2ldLFxuICAgICAgICAgICAgcHJvcHMsXG4gICAgICAgICAgICBkaW1lbnNpb25cbiAgICAgICAgICApIGFzIExvY2FsVXBkYXRlclR5cGVcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdXBkYXRlcnM7XG4gIH1cblxuICBfZ2V0QWxsVXBkYXRlcnM8VXBkYXRlck9iamVjdFR5cGUgZXh0ZW5kcyBEaW1lbnNpb25UeXBlIHwgQWdncmVnYXRpb25UeXBlPihcbiAgICBkaW1lbnNpb246IFVwZGF0ZXJPYmplY3RUeXBlLFxuICAgIG9sZFByb3BzLFxuICAgIHByb3BzLFxuICAgIGNoYW5nZUZsYWdzXG4gICkge1xuICAgIHR5cGUgTG9jYWxVcGRhdGVyVHlwZSA9IFVwZGF0ZXJPYmplY3RUeXBlIGV4dGVuZHMgRGltZW5zaW9uVHlwZVxuICAgICAgPyBCaW5kZWRVcGRhdGVyVHlwZVxuICAgICAgOiBCaW5kZWRBZ2dyZWdhdGVkVXBkYXRlclR5cGU7XG4gICAgbGV0IHVwZGF0ZXJzOiBMb2NhbFVwZGF0ZXJUeXBlW10gPSBbXTtcbiAgICBjb25zdCBuZWVkVXBkYXRlU3RlcCA9IGRpbWVuc2lvbi51cGRhdGVTdGVwcy5maW5kSW5kZXgoc3RlcCA9PlxuICAgICAgdGhpcy5fbmVlZFVwZGF0ZVN0ZXAoc3RlcCwgb2xkUHJvcHMsIHByb3BzLCBjaGFuZ2VGbGFncylcbiAgICApO1xuXG4gICAgaWYgKG5lZWRVcGRhdGVTdGVwID4gLTEpIHtcbiAgICAgIHVwZGF0ZXJzID0gdXBkYXRlcnMuY29uY2F0KHRoaXMuX2FjY3VtdWxhdGVVcGRhdGVycyhuZWVkVXBkYXRlU3RlcCwgcHJvcHMsIGRpbWVuc2lvbikpO1xuICAgIH1cblxuICAgIHJldHVybiB1cGRhdGVycztcbiAgfVxuXG4gIF9nZXRBZ2dyZWdhdGlvbkNoYW5nZXMoXG4gICAgb2xkUHJvcHM6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgcHJvcHM6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgY2hhbmdlRmxhZ3M6IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgKSB7XG4gICAgY29uc3QgdXBkYXRlcnMgPSB0aGlzLl9nZXRBbGxVcGRhdGVycyh0aGlzLmFnZ3JlZ2F0aW9uVXBkYXRlciwgb2xkUHJvcHMsIHByb3BzLCBjaGFuZ2VGbGFncyk7XG4gICAgcmV0dXJuIHVwZGF0ZXJzLmxlbmd0aCA/IHVwZGF0ZXJzIDogbnVsbDtcbiAgfVxuXG4gIF9nZXREaW1lbnNpb25DaGFuZ2VzKFxuICAgIG9sZFByb3BzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIHByb3BzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIGNoYW5nZUZsYWdzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICkge1xuICAgIGxldCB1cGRhdGVyczogQmluZGVkVXBkYXRlclR5cGVbXSA9IFtdO1xuXG4gICAgLy8gZ2V0IGRpbWVuc2lvbiB0byBiZSB1cGRhdGVkXG4gICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy5kaW1lbnNpb25VcGRhdGVycykge1xuICAgICAgLy8gcmV0dXJuIHRoZSBmaXJzdCB0cmlnZ2VyZWQgdXBkYXRlciBmb3IgZWFjaCBkaW1lbnNpb25cbiAgICAgIGNvbnN0IGRpbWVuc2lvbiA9IHRoaXMuZGltZW5zaW9uVXBkYXRlcnNba2V5XTtcbiAgICAgIGNvbnN0IGRpbWVuc2lvblVwZGF0ZXJzID0gdGhpcy5fZ2V0QWxsVXBkYXRlcnMoZGltZW5zaW9uLCBvbGRQcm9wcywgcHJvcHMsIGNoYW5nZUZsYWdzKTtcbiAgICAgIHVwZGF0ZXJzID0gdXBkYXRlcnMuY29uY2F0KGRpbWVuc2lvblVwZGF0ZXJzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdXBkYXRlcnMubGVuZ3RoID8gdXBkYXRlcnMgOiBudWxsO1xuICB9XG5cbiAgZ2V0VXBkYXRlVHJpZ2dlcnMocHJvcHM6IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbiAgICBjb25zdCBfdXBkYXRlVHJpZ2dlcnMgPSBwcm9wcy51cGRhdGVUcmlnZ2VycyB8fCB7fTtcbiAgICBjb25zdCB1cGRhdGVUcmlnZ2VycyA9IHt9O1xuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy5kaW1lbnNpb25VcGRhdGVycykge1xuICAgICAgY29uc3Qge2FjY2Vzc29yLCB1cGRhdGVTdGVwc306IHthY2Nlc3Nvcjogc3RyaW5nOyB1cGRhdGVTdGVwczogVXBkYXRlU3RlcHNUeXBlW119ID1cbiAgICAgICAgdGhpcy5kaW1lbnNpb25VcGRhdGVyc1trZXldO1xuICAgICAgLy8gZm9sZCBkaW1lbnNpb24gdHJpZ2dlcnMgaW50byBlYWNoIGFjY2Vzc29yXG4gICAgICB1cGRhdGVUcmlnZ2Vyc1thY2Nlc3Nvcl0gPSB7fTtcblxuICAgICAgdXBkYXRlU3RlcHMuZm9yRWFjaChzdGVwID0+IHtcbiAgICAgICAgT2JqZWN0LnZhbHVlcyhzdGVwLnRyaWdnZXJzIHx8IFtdKS5mb3JFYWNoKCh7cHJvcCwgdXBkYXRlVHJpZ2dlcn0pID0+IHtcbiAgICAgICAgICBpZiAodXBkYXRlVHJpZ2dlcikge1xuICAgICAgICAgICAgLy8gaWYgcHJvcCBpcyBiYXNlZCBvbiB1cGRhdGVUcmlnZ2VyIGUuZy4gZ2V0Q29sb3JWYWx1ZSwgZ2V0Q29sb3JXZWlnaHRcbiAgICAgICAgICAgIC8vIGFuZCB1cGRhdGVUcmlnZ2VycyBpcyBwYXNzZWQgaW4gZnJvbSBsYXllciBwcm9wXG4gICAgICAgICAgICAvLyBmb2xkIHRoZSB1cGRhdGVUcmlnZ2VycyBpbnRvIGFjY2Vzc29yXG4gICAgICAgICAgICBjb25zdCBmcm9tUHJvcCA9IF91cGRhdGVUcmlnZ2Vyc1t1cGRhdGVUcmlnZ2VyXTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZnJvbVByb3AgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KGZyb21Qcm9wKSkge1xuICAgICAgICAgICAgICAvLyBpZiB1cGRhdGVUcmlnZ2VyIGlzIGFuIG9iamVjdCBzcHJlYWQgaXRcbiAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih1cGRhdGVUcmlnZ2Vyc1thY2Nlc3Nvcl0sIGZyb21Qcm9wKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZnJvbVByb3AgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICB1cGRhdGVUcmlnZ2Vyc1thY2Nlc3Nvcl1bcHJvcF0gPSBmcm9tUHJvcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gaWYgcHJvcCBpcyBub3QgYmFzZWQgb24gdXBkYXRlVHJpZ2dlclxuICAgICAgICAgICAgdXBkYXRlVHJpZ2dlcnNbYWNjZXNzb3JdW3Byb3BdID0gcHJvcHNbcHJvcF07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB1cGRhdGVUcmlnZ2VycztcbiAgfVxuXG4gIGdldFBpY2tpbmdJbmZvKHtpbmZvfToge2luZm86IFJlY29yZDxzdHJpbmcsIGFueT59LCBsYXllclByb3BzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSB7XG4gICAgY29uc3QgaXNQaWNrZWQgPSBpbmZvLnBpY2tlZCAmJiBpbmZvLmluZGV4ID4gLTE7XG4gICAgbGV0IG9iamVjdDogUmVjb3JkPHN0cmluZywgYW55PiB8IG51bGwgPSBudWxsO1xuICAgIGNvbnN0IGNlbGwgPSBpc1BpY2tlZCA/IHRoaXMuc3RhdGUubGF5ZXJEYXRhLmRhdGE/LltpbmZvLmluZGV4XSA6IG51bGw7XG4gICAgaWYgKGNlbGwpIHtcbiAgICAgIGxldCBiaW5JbmZvID0ge307XG4gICAgICBmb3IgKGNvbnN0IGtleSBpbiB0aGlzLmRpbWVuc2lvblVwZGF0ZXJzKSB7XG4gICAgICAgIGNvbnN0IHtnZXRQaWNraW5nSW5mb30gPSB0aGlzLmRpbWVuc2lvblVwZGF0ZXJzW2tleV07XG4gICAgICAgIGlmICh0eXBlb2YgZ2V0UGlja2luZ0luZm8gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBiaW5JbmZvID0gT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAgYmluSW5mbyxcbiAgICAgICAgICAgIGdldFBpY2tpbmdJbmZvKHRoaXMuc3RhdGUuZGltZW5zaW9uc1trZXldLCBjZWxsLCBsYXllclByb3BzKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgb2JqZWN0ID0gT2JqZWN0LmFzc2lnbihiaW5JbmZvLCBjZWxsLCB7XG4gICAgICAgIHBvaW50czogY2VsbC5maWx0ZXJlZFBvaW50cyB8fCBjZWxsLnBvaW50c1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gYWRkIGJpbiAgYW5kICB0byBpbmZvXG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oaW5mbywge1xuICAgICAgcGlja2VkOiBCb29sZWFuKG9iamVjdCksXG4gICAgICAvLyBvdmVycmlkZSBvYmplY3Qgd2l0aCBwaWNrZWQgY2VsbFxuICAgICAgb2JqZWN0XG4gICAgfSk7XG4gIH1cblxuICBnZXRBY2Nlc3NvcihkaW1lbnNpb25LZXk6IHN0cmluZywgbGF5ZXJQcm9wczogUmVjb3JkPHN0cmluZywgYW55Pikge1xuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuZGltZW5zaW9uVXBkYXRlcnMsIGRpbWVuc2lvbktleSkpIHtcbiAgICAgIHJldHVybiBub3A7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmRpbWVuc2lvblVwZGF0ZXJzW2RpbWVuc2lvbktleV0uZ2V0U3ViTGF5ZXJBY2Nlc3NvcihcbiAgICAgIHRoaXMuc3RhdGUuZGltZW5zaW9uc1tkaW1lbnNpb25LZXldLFxuICAgICAgdGhpcy5kaW1lbnNpb25VcGRhdGVyc1tkaW1lbnNpb25LZXldLFxuICAgICAgbGF5ZXJQcm9wc1xuICAgICk7XG4gIH1cbn1cblxuQ1BVQWdncmVnYXRvci5nZXREaW1lbnNpb25TY2FsZSA9IGdldERpbWVuc2lvblNjYWxlO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUFBO0FBQ0E7O0FBRUE7QUFDQSxTQUFRQSxPQUFPLElBQUlDLE9BQU8sUUFBTyxlQUFlO0FBRWhELFNBQVFDLFNBQVMsUUFBTyxrQkFBa0I7QUFDMUMsU0FBUUMsaUJBQWlCLEVBQUVDLFVBQVUsUUFBTyxzQkFBc0I7QUFJbEUsSUFBTUMscUJBQXFCLEdBQUc7RUFDNUJDLEdBQUcsRUFBRSxLQUFjO0VBQ25CQyxJQUFJLEVBQUUsTUFBZTtFQUNyQkMsR0FBRyxFQUFFLEtBQWM7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
|