kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
313 lines (304 loc) • 54.4 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.HISTOGRAM_WIDTH = exports.HISTOGRAM_HEIGHT = exports.ColorChartTick = exports.ColorChartHeader = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
var _d3Format = require("d3-format");
var _d3Scale = require("d3-scale");
var _react = _interopRequireWildcard(require("react"));
var _styledComponents = _interopRequireDefault(require("styled-components"));
var _utils = require("@kepler.gl/utils");
var _colorPalette = _interopRequireDefault(require("../side-panel/layer-panel/color-palette"));
var _histogramPlot = _interopRequireWildcard(require("./histogram-plot"));
var _loadingSpinner = _interopRequireDefault(require("./loading-spinner"));
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8; // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
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; }
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; }
var HISTOGRAM_WIDTH = exports.HISTOGRAM_WIDTH = 210;
var HISTOGRAM_HEIGHT = exports.HISTOGRAM_HEIGHT = 80;
var HISTOGRAM_MARGIN = {
top: 10,
bottom: 8,
left: 10,
right: 20
};
var COLOR_CHART_TICK_WRAPPER_HEIGHT = 10;
var COLOR_CHART_TICK_HEIGHT = 8;
var COLOR_CHART_TICK_WIDTH = 4;
var COLOR_CHART_TICK_BORDER_COLOR = '#999999';
var StyledContainer = _styledComponents["default"].div.attrs({
className: 'color-chart-loading'
})(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n height: ", "px;\n"])), HISTOGRAM_HEIGHT);
// height 142 = 18 + 110 + 10
var ColorChartContainer = _styledComponents["default"].div.attrs({
className: 'color-chart-container'
})(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2["default"])(["\n margin-top: 8px;\n"])));
var ColorChartHeaderWrapper = _styledComponents["default"].div.attrs({
className: 'color-chart-header'
})(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n justify-content: space-around;\n color: ", ";\n margin-left: ", "px;\n margin-right: ", "px;\n font-size: 9px;\n"])), function (props) {
return props.theme.textColor;
}, HISTOGRAM_MARGIN.left, HISTOGRAM_MARGIN.right);
var ColorChartHeaderItem = _styledComponents["default"].div(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2["default"])(["\n width: 33%;\n overflow: hidden;\n white-space: nowrap;\n"])));
var ColorChartWrapper = _styledComponents["default"].div.attrs({
className: 'color-chart-wrapper'
})(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2["default"])(["\n position: relative;\n height: ", "px;\n"])), HISTOGRAM_HEIGHT + 30);
var ColorPaletteWrapper = _styledComponents["default"].div.attrs({
className: 'color-chart-palette'
})(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2["default"])(["\n position: absolute;\n margin-top: ", "px;\n margin-left: ", "px;\n margin-right: ", "px;\n"])), HISTOGRAM_MARGIN.top, HISTOGRAM_MARGIN.left, HISTOGRAM_MARGIN.right);
var HistogramWrapper = _styledComponents["default"].div.attrs({
className: 'color-chart-histogram'
})(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2["default"])(["\n position: absolute;\n"])));
var ColorChartTickContainer = _styledComponents["default"].div.attrs({
className: 'color-chart-tick-container'
})(_templateObject8 || (_templateObject8 = (0, _taggedTemplateLiteral2["default"])(["\n height: ", "px;\n position: relative;\n margin-left: ", "px;\n margin-right: ", "px;\n"])), COLOR_CHART_TICK_WRAPPER_HEIGHT, HISTOGRAM_MARGIN.left, HISTOGRAM_MARGIN.right);
var ColorChartHeader = exports.ColorChartHeader = function ColorChartHeader(_ref) {
var minVal = _ref.minVal,
meanVal = _ref.meanVal,
maxVal = _ref.maxVal;
return /*#__PURE__*/_react["default"].createElement(ColorChartHeaderWrapper, null, /*#__PURE__*/_react["default"].createElement(ColorChartHeaderItem, {
title: minVal
}, "MIN: ", minVal), /*#__PURE__*/_react["default"].createElement(ColorChartHeaderItem, {
title: meanVal
}, "MEAN: ", (0, _d3Format.format)('.4~r')(meanVal)), /*#__PURE__*/_react["default"].createElement(ColorChartHeaderItem, {
title: maxVal,
style: {
textAlign: 'right'
}
}, "MAX: ", maxVal));
};
var ColorChartTick = exports.ColorChartTick = function ColorChartTick(_ref2) {
var colors = _ref2.colors,
positions = _ref2.positions,
histogramWidth = _ref2.histogramWidth,
onTickMoving = _ref2.onTickMoving,
onTickChanged = _ref2.onTickChanged;
var _useState = (0, _react.useState)(positions),
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
statePositions = _useState2[0],
setPositions = _useState2[1];
var _useState3 = (0, _react.useState)(-1),
_useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
dragTick = _useState4[0],
setDragTick = _useState4[1];
var containerRef = (0, _react.useRef)(null);
(0, _react.useEffect)(function () {
setPositions(positions);
setDragTick(dragTick);
}, [positions, dragTick]);
var onMouseMove = (0, _react.useCallback)(function (e) {
if (dragTick >= 0) {
// @ts-ignore
var offsetX = containerRef.current.getBoundingClientRect().x;
statePositions[dragTick] = e.clientX - (offsetX !== null && offsetX !== void 0 ? offsetX : 0);
var leftBound = dragTick === 0 ? 0 : statePositions[dragTick - 1] + 1;
var rightBound = dragTick === positions.length - 1 ? histogramWidth : statePositions[dragTick + 1] - 1;
// restrict user drag-n-move between left and right neighboring ticks
if (statePositions[dragTick] < leftBound) {
statePositions[dragTick] = leftBound;
}
if (statePositions[dragTick] > rightBound) {
statePositions[dragTick] = rightBound;
}
setPositions((0, _toConsumableArray2["default"])(statePositions));
onTickMoving(statePositions, dragTick);
}
}, [dragTick, onTickMoving, positions.length, statePositions, histogramWidth]);
var onMouseUp = (0, _react.useCallback)(function (e) {
if (dragTick >= 0) {
onTickChanged();
setDragTick(-1);
e.stopPropagation();
e.preventDefault();
}
}, [dragTick, onTickChanged]);
var _onMouseDown = (0, _react.useCallback)(function (e, tickIndex) {
if ((0, _utils.isNumber)(tickIndex)) {
setDragTick(tickIndex);
e.stopPropagation();
e.preventDefault();
}
}, []);
return /*#__PURE__*/_react["default"].createElement(ColorChartTickContainer, {
ref: containerRef,
onMouseMove: onMouseMove,
onMouseUp: onMouseUp,
onMouseLeave: onMouseUp
}, colors.map(function (color, index) {
return /*#__PURE__*/_react["default"].createElement("div", {
draggable: true,
key: "color-chart-tick-".concat(color, "-").concat(index),
onMouseDown: function onMouseDown(e) {
return _onMouseDown(e, index);
},
style: {
backgroundColor: color,
left: "".concat(statePositions[index] - COLOR_CHART_TICK_WIDTH / 2 - 1, "px"),
borderWidth: "1px",
borderStyle: 'solid',
borderColor: COLOR_CHART_TICK_BORDER_COLOR,
position: 'absolute',
width: "".concat(COLOR_CHART_TICK_WIDTH, "px"),
height: "".concat(COLOR_CHART_TICK_HEIGHT, "px"),
cursor: 'pointer'
}
});
}));
};
// only for numetic field
ColumnStatsChartFactory.deps = [_histogramPlot["default"]];
function ColumnStatsChartFactory(HistogramPlot) {
var ColumnStatsChart = function ColumnStatsChart(_ref3) {
var allBins = _ref3.allBins,
filteredBins = _ref3.filteredBins,
isFiltered = _ref3.isFiltered,
histogramDomain = _ref3.histogramDomain,
colorBreaks = _ref3.colorBreaks,
onChangedUpdater = _ref3.onChangedUpdater;
var _useState5 = (0, _react.useState)(colorBreaks),
_useState6 = (0, _slicedToArray2["default"])(_useState5, 2),
ticks = _useState6[0],
setTicks = _useState6[1];
var _useDimensions = (0, _utils.useDimensions)(),
_useDimensions2 = (0, _slicedToArray2["default"])(_useDimensions, 2),
ref = _useDimensions2[0],
size = _useDimensions2[1];
var histogramWidth = size ? size.width - HISTOGRAM_MARGIN.left - HISTOGRAM_MARGIN.right : HISTOGRAM_WIDTH;
// distinguish between props.colorBreaks and states.ticks
var isTickChangingRef = _react["default"].useRef(false);
(0, _react.useEffect)(function () {
setTicks(ticks);
// reset isTickChanging once histogram domain is recomputed
isTickChangingRef.current = false;
}, [ticks]);
// histograms used by histogram-plot.js
var histogramsByGroup = (0, _react.useMemo)(function () {
return {
bins: allBins,
filteredBins: filteredBins
};
}, [allBins, filteredBins]);
// get colors from colorBreaks
var domainColors = (0, _react.useMemo)(function () {
return colorBreaks ? colorBreaks.map(function (c) {
return c.data;
}) : [];
}, [colorBreaks]);
var tickPositions = (0, _react.useMemo)(function () {
if (!isTickChangingRef.current) {
setTicks(colorBreaks);
}
var _histogramDomain = (0, _slicedToArray2["default"])(histogramDomain, 2),
valueMin = _histogramDomain[0],
valueMax = _histogramDomain[1];
var widthScale = (0, _d3Scale.scaleLinear)().domain([valueMin, valueMax]).range([0, histogramWidth]);
return ticks.slice(0, -1).map(function (cb) {
var pos = widthScale(cb.range[1]);
if (pos < 0) return 0;else if (pos > histogramWidth) return histogramWidth;
return pos;
});
}, [histogramDomain, ticks, colorBreaks, histogramWidth]);
var domainColorWidths = (0, _react.useMemo)(function () {
var n = tickPositions.length;
var widths = [tickPositions[0]];
for (var i = 1; i < n; ++i) {
widths.push(tickPositions[i] - tickPositions[i - 1]);
}
widths.push(histogramWidth - tickPositions[n - 1]);
return widths;
}, [tickPositions, histogramWidth]);
// handle tick drag-n-move
var onTickMovingHandler = (0, _react.useCallback)(function (newTickPositions, tickIndex) {
var _histogramDomain2 = (0, _slicedToArray2["default"])(histogramDomain, 2),
valueMin = _histogramDomain2[0],
valueMax = _histogramDomain2[1];
var valueRange = valueMax - valueMin;
var breaks = [valueMin];
newTickPositions.forEach(function (element) {
breaks.push(valueMin + valueRange * element / histogramWidth);
});
breaks.push(valueMax);
for (var i = 0; i < ticks.length; ++i) {
var leftValue = i === tickIndex + 1 ? breaks[i] : ticks[i].range[0];
var rightValue = i + 1 === tickIndex + 1 ? breaks[i + 1] : ticks[i].range[1];
ticks[i] = _objectSpread(_objectSpread({}, ticks[i]), {}, {
range: [leftValue, rightValue],
inputs: [leftValue, rightValue],
label: "".concat((0, _d3Format.format)('.2f')(breaks[i]), " to ").concat((0, _d3Format.format)('.2f')(breaks[i + 1]))
});
}
isTickChangingRef.current = true;
setTicks((0, _toConsumableArray2["default"])(ticks));
}, [histogramDomain, ticks, histogramWidth]);
// update parent and sibling components when tick dragging ended
var onTickChangedHandler = (0, _react.useCallback)(function () {
onChangedUpdater(ticks);
}, [onChangedUpdater, ticks]);
return /*#__PURE__*/_react["default"].createElement(ColorChartContainer, {
ref: ref
}, /*#__PURE__*/_react["default"].createElement(ColorChartHeader, {
minVal: histogramDomain[0],
maxVal: histogramDomain[1],
meanVal: histogramDomain[2]
}), /*#__PURE__*/_react["default"].createElement(ColorChartWrapper, null, /*#__PURE__*/_react["default"].createElement(ColorPaletteWrapper, null, /*#__PURE__*/_react["default"].createElement(_colorPalette["default"], {
colors: domainColors,
colorWidths: domainColorWidths,
height: HISTOGRAM_HEIGHT + 16
})), /*#__PURE__*/_react["default"].createElement(HistogramWrapper, null, /*#__PURE__*/_react["default"].createElement(HistogramPlot, {
histogramsByGroup: histogramsByGroup,
colorsByGroup: null,
isMasked: isFiltered ? _histogramPlot.HISTOGRAM_MASK_MODE.MaskWithOverlay : _histogramPlot.HISTOGRAM_MASK_MODE.Mask,
value: histogramDomain,
width: histogramWidth,
height: HISTOGRAM_HEIGHT,
margin: HISTOGRAM_MARGIN,
breakLines: tickPositions
}))), /*#__PURE__*/_react["default"].createElement(ColorChartTick, {
colors: domainColors.slice(0, -1),
positions: tickPositions,
histogramWidth: histogramWidth,
onTickMoving: onTickMovingHandler,
onTickChanged: onTickChangedHandler
}));
};
var ColumnStatsChartWLoading = function ColumnStatsChartWLoading(_ref4) {
var colorField = _ref4.colorField,
dataset = _ref4.dataset,
colorBreaks = _ref4.colorBreaks,
allBins = _ref4.allBins,
filteredBins = _ref4.filteredBins,
isFiltered = _ref4.isFiltered,
histogramDomain = _ref4.histogramDomain,
onChangedUpdater = _ref4.onChangedUpdater;
var fieldName = colorField === null || colorField === void 0 ? void 0 : colorField.name;
var field = (0, _react.useMemo)(function () {
return fieldName ? dataset.getColumnField(fieldName) : null;
}, [dataset, fieldName]);
if (!(0, _utils.isNumericColorBreaks)(colorBreaks)) {
// TODO: implement display for ordinal breaks
return null;
}
if (field !== null && field !== void 0 && field.isLoadingStats) {
return /*#__PURE__*/_react["default"].createElement(StyledContainer, null, /*#__PURE__*/_react["default"].createElement(_loadingSpinner["default"], null));
}
return /*#__PURE__*/_react["default"].createElement(ColumnStatsChart, {
colorBreaks: colorBreaks,
allBins: allBins,
filteredBins: filteredBins,
isFiltered: isFiltered,
histogramDomain: histogramDomain,
onChangedUpdater: onChangedUpdater
});
};
return ColumnStatsChartWLoading;
}
var _default = exports["default"] = ColumnStatsChartFactory;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZDNGb3JtYXQiLCJyZXF1aXJlIiwiX2QzU2NhbGUiLCJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsIl9zdHlsZWRDb21wb25lbnRzIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl91dGlscyIsIl9jb2xvclBhbGV0dGUiLCJfaGlzdG9ncmFtUGxvdCIsIl9sb2FkaW5nU3Bpbm5lciIsIl90ZW1wbGF0ZU9iamVjdCIsIl90ZW1wbGF0ZU9iamVjdDIiLCJfdGVtcGxhdGVPYmplY3QzIiwiX3RlbXBsYXRlT2JqZWN0NCIsIl90ZW1wbGF0ZU9iamVjdDUiLCJfdGVtcGxhdGVPYmplY3Q2IiwiX3RlbXBsYXRlT2JqZWN0NyIsIl90ZW1wbGF0ZU9iamVjdDgiLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJlIiwiV2Vha01hcCIsInIiLCJ0IiwiX19lc01vZHVsZSIsIl90eXBlb2YiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwidSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImkiLCJzZXQiLCJvd25LZXlzIiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsIm8iLCJmaWx0ZXIiLCJlbnVtZXJhYmxlIiwicHVzaCIsImFwcGx5IiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJISVNUT0dSQU1fV0lEVEgiLCJleHBvcnRzIiwiSElTVE9HUkFNX0hFSUdIVCIsIkhJU1RPR1JBTV9NQVJHSU4iLCJ0b3AiLCJib3R0b20iLCJsZWZ0IiwicmlnaHQiLCJDT0xPUl9DSEFSVF9USUNLX1dSQVBQRVJfSEVJR0hUIiwiQ09MT1JfQ0hBUlRfVElDS19IRUlHSFQiLCJDT0xPUl9DSEFSVF9USUNLX1dJRFRIIiwiQ09MT1JfQ0hBUlRfVElDS19CT1JERVJfQ09MT1IiLCJTdHlsZWRDb250YWluZXIiLCJzdHlsZWQiLCJkaXYiLCJhdHRycyIsImNsYXNzTmFtZSIsIl90YWdnZWRUZW1wbGF0ZUxpdGVyYWwyIiwiQ29sb3JDaGFydENvbnRhaW5lciIsIkNvbG9yQ2hhcnRIZWFkZXJXcmFwcGVyIiwicHJvcHMiLCJ0aGVtZSIsInRleHRDb2xvciIsIkNvbG9yQ2hhcnRIZWFkZXJJdGVtIiwiQ29sb3JDaGFydFdyYXBwZXIiLCJDb2xvclBhbGV0dGVXcmFwcGVyIiwiSGlzdG9ncmFtV3JhcHBlciIsIkNvbG9yQ2hhcnRUaWNrQ29udGFpbmVyIiwiQ29sb3JDaGFydEhlYWRlciIsIl9yZWYiLCJtaW5WYWwiLCJtZWFuVmFsIiwibWF4VmFsIiwiY3JlYXRlRWxlbWVudCIsInRpdGxlIiwiZDNGb3JtYXQiLCJzdHlsZSIsInRleHRBbGlnbiIsIkNvbG9yQ2hhcnRUaWNrIiwiX3JlZjIiLCJjb2xvcnMiLCJwb3NpdGlvbnMiLCJoaXN0b2dyYW1XaWR0aCIsIm9uVGlja01vdmluZyIsIm9uVGlja0NoYW5nZWQiLCJfdXNlU3RhdGUiLCJ1c2VTdGF0ZSIsIl91c2VTdGF0ZTIiLCJfc2xpY2VkVG9BcnJheTIiLCJzdGF0ZVBvc2l0aW9ucyIsInNldFBvc2l0aW9ucyIsIl91c2VTdGF0ZTMiLCJfdXNlU3RhdGU0IiwiZHJhZ1RpY2siLCJzZXREcmFnVGljayIsImNvbnRhaW5lclJlZiIsInVzZVJlZiIsInVzZUVmZmVjdCIsIm9uTW91c2VNb3ZlIiwidXNlQ2FsbGJhY2siLCJvZmZzZXRYIiwiY3VycmVudCIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsIngiLCJjbGllbnRYIiwibGVmdEJvdW5kIiwicmlnaHRCb3VuZCIsIl90b0NvbnN1bWFibGVBcnJheTIiLCJvbk1vdXNlVXAiLCJzdG9wUHJvcGFnYXRpb24iLCJwcmV2ZW50RGVmYXVsdCIsIm9uTW91c2VEb3duIiwidGlja0luZGV4IiwiaXNOdW1iZXIiLCJyZWYiLCJvbk1vdXNlTGVhdmUiLCJtYXAiLCJjb2xvciIsImluZGV4IiwiZHJhZ2dhYmxlIiwia2V5IiwiY29uY2F0IiwiYmFja2dyb3VuZENvbG9yIiwiYm9yZGVyV2lkdGgiLCJib3JkZXJTdHlsZSIsImJvcmRlckNvbG9yIiwicG9zaXRpb24iLCJ3aWR0aCIsImhlaWdodCIsImN1cnNvciIsIkNvbHVtblN0YXRzQ2hhcnRGYWN0b3J5IiwiZGVwcyIsIkhpc3RvZ3JhbVBsb3RGYWN0b3J5IiwiSGlzdG9ncmFtUGxvdCIsIkNvbHVtblN0YXRzQ2hhcnQiLCJfcmVmMyIsImFsbEJpbnMiLCJmaWx0ZXJlZEJpbnMiLCJpc0ZpbHRlcmVkIiwiaGlzdG9ncmFtRG9tYWluIiwiY29sb3JCcmVha3MiLCJvbkNoYW5nZWRVcGRhdGVyIiwiX3VzZVN0YXRlNSIsIl91c2VTdGF0ZTYiLCJ0aWNrcyIsInNldFRpY2tzIiwiX3VzZURpbWVuc2lvbnMiLCJ1c2VEaW1lbnNpb25zIiwiX3VzZURpbWVuc2lvbnMyIiwic2l6ZSIsImlzVGlja0NoYW5naW5nUmVmIiwiUmVhY3QiLCJoaXN0b2dyYW1zQnlHcm91cCIsInVzZU1lbW8iLCJiaW5zIiwiZG9tYWluQ29sb3JzIiwiYyIsImRhdGEiLCJ0aWNrUG9zaXRpb25zIiwiX2hpc3RvZ3JhbURvbWFpbiIsInZhbHVlTWluIiwidmFsdWVNYXgiLCJ3aWR0aFNjYWxlIiwic2NhbGVMaW5lYXIiLCJkb21haW4iLCJyYW5nZSIsInNsaWNlIiwiY2IiLCJwb3MiLCJkb21haW5Db2xvcldpZHRocyIsIndpZHRocyIsIm9uVGlja01vdmluZ0hhbmRsZXIiLCJuZXdUaWNrUG9zaXRpb25zIiwiX2hpc3RvZ3JhbURvbWFpbjIiLCJ2YWx1ZVJhbmdlIiwiYnJlYWtzIiwiZWxlbWVudCIsImxlZnRWYWx1ZSIsInJpZ2h0VmFsdWUiLCJpbnB1dHMiLCJsYWJlbCIsIm9uVGlja0NoYW5nZWRIYW5kbGVyIiwiY29sb3JXaWR0aHMiLCJjb2xvcnNCeUdyb3VwIiwiaXNNYXNrZWQiLCJISVNUT0dSQU1fTUFTS19NT0RFIiwiTWFza1dpdGhPdmVybGF5IiwiTWFzayIsInZhbHVlIiwibWFyZ2luIiwiYnJlYWtMaW5lcyIsIkNvbHVtblN0YXRzQ2hhcnRXTG9hZGluZyIsIl9yZWY0IiwiY29sb3JGaWVsZCIsImRhdGFzZXQiLCJmaWVsZE5hbWUiLCJuYW1lIiwiZmllbGQiLCJnZXRDb2x1bW5GaWVsZCIsImlzTnVtZXJpY0NvbG9yQnJlYWtzIiwiaXNMb2FkaW5nU3RhdHMiLCJfZGVmYXVsdCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tb24vY29sdW1uLXN0YXRzLWNoYXJ0LnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge2Zvcm1hdCBhcyBkM0Zvcm1hdH0gZnJvbSAnZDMtZm9ybWF0JztcbmltcG9ydCB7c2NhbGVMaW5lYXJ9IGZyb20gJ2QzLXNjYWxlJztcbmltcG9ydCBSZWFjdCwge3VzZUNhbGxiYWNrLCB1c2VFZmZlY3QsIHVzZU1lbW8sIHVzZVJlZiwgdXNlU3RhdGV9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBzdHlsZWQgZnJvbSAnc3R5bGVkLWNvbXBvbmVudHMnO1xuXG5pbXBvcnQge0tlcGxlclRhYmxlfSBmcm9tICdAa2VwbGVyLmdsL3RhYmxlJztcbmltcG9ydCB7QmluLCBGaWVsZH0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5pbXBvcnQge1xuICBDb2xvckJyZWFrLFxuICBDb2xvckJyZWFrT3JkaW5hbCxcbiAgaXNOdW1iZXIsXG4gIGlzTnVtZXJpY0NvbG9yQnJlYWtzLFxuICB1c2VEaW1lbnNpb25zXG59IGZyb20gJ0BrZXBsZXIuZ2wvdXRpbHMnO1xuXG5pbXBvcnQgQ29sb3JQYWxldHRlIGZyb20gJy4uL3NpZGUtcGFuZWwvbGF5ZXItcGFuZWwvY29sb3ItcGFsZXR0ZSc7XG5pbXBvcnQgSGlzdG9ncmFtUGxvdEZhY3RvcnksIHtISVNUT0dSQU1fTUFTS19NT0RFfSBmcm9tICcuL2hpc3RvZ3JhbS1wbG90JztcbmltcG9ydCBMb2FkaW5nU3Bpbm5lciBmcm9tICcuL2xvYWRpbmctc3Bpbm5lcic7XG5cbmV4cG9ydCBjb25zdCBISVNUT0dSQU1fV0lEVEggPSAyMTA7XG5leHBvcnQgY29uc3QgSElTVE9HUkFNX0hFSUdIVCA9IDgwO1xuY29uc3QgSElTVE9HUkFNX01BUkdJTiA9IHt0b3A6IDEwLCBib3R0b206IDgsIGxlZnQ6IDEwLCByaWdodDogMjB9O1xuY29uc3QgQ09MT1JfQ0hBUlRfVElDS19XUkFQUEVSX0hFSUdIVCA9IDEwO1xuY29uc3QgQ09MT1JfQ0hBUlRfVElDS19IRUlHSFQgPSA4O1xuY29uc3QgQ09MT1JfQ0hBUlRfVElDS19XSURUSCA9IDQ7XG5jb25zdCBDT0xPUl9DSEFSVF9USUNLX0JPUkRFUl9DT0xPUiA9ICcjOTk5OTk5JztcblxuY29uc3QgU3R5bGVkQ29udGFpbmVyID0gc3R5bGVkLmRpdi5hdHRycyh7XG4gIGNsYXNzTmFtZTogJ2NvbG9yLWNoYXJ0LWxvYWRpbmcnXG59KWBcbiAgaGVpZ2h0OiAke0hJU1RPR1JBTV9IRUlHSFR9cHg7XG5gO1xuXG4vLyBoZWlnaHQgMTQyID0gMTggKyAxMTAgKyAxMFxuY29uc3QgQ29sb3JDaGFydENvbnRhaW5lciA9IHN0eWxlZC5kaXYuYXR0cnMoe1xuICBjbGFzc05hbWU6ICdjb2xvci1jaGFydC1jb250YWluZXInXG59KWBcbiAgbWFyZ2luLXRvcDogOHB4O1xuYDtcblxuY29uc3QgQ29sb3JDaGFydEhlYWRlcldyYXBwZXIgPSBzdHlsZWQuZGl2LmF0dHJzKHtcbiAgY2xhc3NOYW1lOiAnY29sb3ItY2hhcnQtaGVhZGVyJ1xufSlgXG4gIGRpc3BsYXk6IGZsZXg7XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYXJvdW5kO1xuICBjb2xvcjogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS50ZXh0Q29sb3J9O1xuICBtYXJnaW4tbGVmdDogJHtISVNUT0dSQU1fTUFSR0lOLmxlZnR9cHg7XG4gIG1hcmdpbi1yaWdodDogJHtISVNUT0dSQU1fTUFSR0lOLnJpZ2h0fXB4O1xuICBmb250LXNpemU6IDlweDtcbmA7XG5cbmNvbnN0IENvbG9yQ2hhcnRIZWFkZXJJdGVtID0gc3R5bGVkLmRpdmBcbiAgd2lkdGg6IDMzJTtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbmA7XG5cbmNvbnN0IENvbG9yQ2hhcnRXcmFwcGVyID0gc3R5bGVkLmRpdi5hdHRycyh7XG4gIGNsYXNzTmFtZTogJ2NvbG9yLWNoYXJ0LXdyYXBwZXInXG59KWBcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBoZWlnaHQ6ICR7SElTVE9HUkFNX0hFSUdIVCArIDMwfXB4O1xuYDtcblxuY29uc3QgQ29sb3JQYWxldHRlV3JhcHBlciA9IHN0eWxlZC5kaXYuYXR0cnMoe1xuICBjbGFzc05hbWU6ICdjb2xvci1jaGFydC1wYWxldHRlJ1xufSlgXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgbWFyZ2luLXRvcDogJHtISVNUT0dSQU1fTUFSR0lOLnRvcH1weDtcbiAgbWFyZ2luLWxlZnQ6ICR7SElTVE9HUkFNX01BUkdJTi5sZWZ0fXB4O1xuICBtYXJnaW4tcmlnaHQ6ICR7SElTVE9HUkFNX01BUkdJTi5yaWdodH1weDtcbmA7XG5cbmNvbnN0IEhpc3RvZ3JhbVdyYXBwZXIgPSBzdHlsZWQuZGl2LmF0dHJzKHtcbiAgY2xhc3NOYW1lOiAnY29sb3ItY2hhcnQtaGlzdG9ncmFtJ1xufSlgXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbmA7XG5cbmNvbnN0IENvbG9yQ2hhcnRUaWNrQ29udGFpbmVyID0gc3R5bGVkLmRpdi5hdHRycyh7XG4gIGNsYXNzTmFtZTogJ2NvbG9yLWNoYXJ0LXRpY2stY29udGFpbmVyJ1xufSlgXG4gIGhlaWdodDogJHtDT0xPUl9DSEFSVF9USUNLX1dSQVBQRVJfSEVJR0hUfXB4O1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIG1hcmdpbi1sZWZ0OiAke0hJU1RPR1JBTV9NQVJHSU4ubGVmdH1weDtcbiAgbWFyZ2luLXJpZ2h0OiAke0hJU1RPR1JBTV9NQVJHSU4ucmlnaHR9cHg7XG5gO1xuXG5leHBvcnQgY29uc3QgQ29sb3JDaGFydEhlYWRlciA9ICh7bWluVmFsLCBtZWFuVmFsLCBtYXhWYWx9KSA9PiB7XG4gIHJldHVybiAoXG4gICAgPENvbG9yQ2hhcnRIZWFkZXJXcmFwcGVyPlxuICAgICAgPENvbG9yQ2hhcnRIZWFkZXJJdGVtIHRpdGxlPXttaW5WYWx9Pk1JTjoge21pblZhbH08L0NvbG9yQ2hhcnRIZWFkZXJJdGVtPlxuICAgICAgPENvbG9yQ2hhcnRIZWFkZXJJdGVtIHRpdGxlPXttZWFuVmFsfT5NRUFOOiB7ZDNGb3JtYXQoJy40fnInKShtZWFuVmFsKX08L0NvbG9yQ2hhcnRIZWFkZXJJdGVtPlxuICAgICAgPENvbG9yQ2hhcnRIZWFkZXJJdGVtIHRpdGxlPXttYXhWYWx9IHN0eWxlPXt7dGV4dEFsaWduOiAncmlnaHQnfX0+XG4gICAgICAgIE1BWDoge21heFZhbH1cbiAgICAgIDwvQ29sb3JDaGFydEhlYWRlckl0ZW0+XG4gICAgPC9Db2xvckNoYXJ0SGVhZGVyV3JhcHBlcj5cbiAgKTtcbn07XG5cbmV4cG9ydCB0eXBlIENvbG9yQ2hhcnRUaWNrUHJvcHMgPSB7XG4gIGNvbG9yczogc3RyaW5nW107XG4gIHBvc2l0aW9uczogbnVtYmVyW107XG4gIG9uVGlja01vdmluZzogKHBvc2l0aW9uczogbnVtYmVyW10sIGRyYWdUaWNrOiBudW1iZXIpID0+IHZvaWQ7XG4gIG9uVGlja0NoYW5nZWQ6ICgpID0+IHZvaWQ7XG4gIGhpc3RvZ3JhbVdpZHRoOiBudW1iZXI7XG59O1xuXG5leHBvcnQgY29uc3QgQ29sb3JDaGFydFRpY2s6IFJlYWN0LkZDPENvbG9yQ2hhcnRUaWNrUHJvcHM+ID0gKHtcbiAgY29sb3JzLFxuICBwb3NpdGlvbnMsXG4gIGhpc3RvZ3JhbVdpZHRoLFxuICBvblRpY2tNb3ZpbmcsXG4gIG9uVGlja0NoYW5nZWRcbn0pID0+IHtcbiAgY29uc3QgW3N0YXRlUG9zaXRpb25zLCBzZXRQb3NpdGlvbnNdID0gdXNlU3RhdGUocG9zaXRpb25zKTtcbiAgY29uc3QgW2RyYWdUaWNrLCBzZXREcmFnVGlja10gPSB1c2VTdGF0ZSgtMSk7XG4gIGNvbnN0IGNvbnRhaW5lclJlZiA9IHVzZVJlZjxIVE1MRGl2RWxlbWVudD4obnVsbCk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBzZXRQb3NpdGlvbnMocG9zaXRpb25zKTtcbiAgICBzZXREcmFnVGljayhkcmFnVGljayk7XG4gIH0sIFtwb3NpdGlvbnMsIGRyYWdUaWNrXSk7XG5cbiAgY29uc3Qgb25Nb3VzZU1vdmUgPSB1c2VDYWxsYmFjayhcbiAgICBlID0+IHtcbiAgICAgIGlmIChkcmFnVGljayA+PSAwKSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgY29uc3Qgb2Zmc2V0WCA9IGNvbnRhaW5lclJlZi5jdXJyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLng7XG4gICAgICAgIHN0YXRlUG9zaXRpb25zW2RyYWdUaWNrXSA9IGUuY2xpZW50WCAtIChvZmZzZXRYID8/IDApO1xuICAgICAgICBjb25zdCBsZWZ0Qm91bmQgPSBkcmFnVGljayA9PT0gMCA/IDAgOiBzdGF0ZVBvc2l0aW9uc1tkcmFnVGljayAtIDFdICsgMTtcbiAgICAgICAgY29uc3QgcmlnaHRCb3VuZCA9XG4gICAgICAgICAgZHJhZ1RpY2sgPT09IHBvc2l0aW9ucy5sZW5ndGggLSAxID8gaGlzdG9ncmFtV2lkdGggOiBzdGF0ZVBvc2l0aW9uc1tkcmFnVGljayArIDFdIC0gMTtcblxuICAgICAgICAvLyByZXN0cmljdCB1c2VyIGRyYWctbi1tb3ZlIGJldHdlZW4gbGVmdCBhbmQgcmlnaHQgbmVpZ2hib3JpbmcgdGlja3NcbiAgICAgICAgaWYgKHN0YXRlUG9zaXRpb25zW2RyYWdUaWNrXSA8IGxlZnRCb3VuZCkge1xuICAgICAgICAgIHN0YXRlUG9zaXRpb25zW2RyYWdUaWNrXSA9IGxlZnRCb3VuZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RhdGVQb3NpdGlvbnNbZHJhZ1RpY2tdID4gcmlnaHRCb3VuZCkge1xuICAgICAgICAgIHN0YXRlUG9zaXRpb25zW2RyYWdUaWNrXSA9IHJpZ2h0Qm91bmQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0UG9zaXRpb25zKFsuLi5zdGF0ZVBvc2l0aW9uc10pO1xuICAgICAgICBvblRpY2tNb3Zpbmcoc3RhdGVQb3NpdGlvbnMsIGRyYWdUaWNrKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIFtkcmFnVGljaywgb25UaWNrTW92aW5nLCBwb3NpdGlvbnMubGVuZ3RoLCBzdGF0ZVBvc2l0aW9ucywgaGlzdG9ncmFtV2lkdGhdXG4gICk7XG5cbiAgY29uc3Qgb25Nb3VzZVVwID0gdXNlQ2FsbGJhY2soXG4gICAgZSA9PiB7XG4gICAgICBpZiAoZHJhZ1RpY2sgPj0gMCkge1xuICAgICAgICBvblRpY2tDaGFuZ2VkKCk7XG4gICAgICAgIHNldERyYWdUaWNrKC0xKTtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW2RyYWdUaWNrLCBvblRpY2tDaGFuZ2VkXVxuICApO1xuXG4gIGNvbnN0IG9uTW91c2VEb3duID0gdXNlQ2FsbGJhY2soKGUsIHRpY2tJbmRleCkgPT4ge1xuICAgIGlmIChpc051bWJlcih0aWNrSW5kZXgpKSB7XG4gICAgICBzZXREcmFnVGljayh0aWNrSW5kZXgpO1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH0sIFtdKTtcblxuICByZXR1cm4gKFxuICAgIDxDb2xvckNoYXJ0VGlja0NvbnRhaW5lclxuICAgICAgcmVmPXtjb250YWluZXJSZWZ9XG4gICAgICBvbk1vdXNlTW92ZT17b25Nb3VzZU1vdmV9XG4gICAgICBvbk1vdXNlVXA9e29uTW91c2VVcH1cbiAgICAgIG9uTW91c2VMZWF2ZT17b25Nb3VzZVVwfVxuICAgID5cbiAgICAgIHtjb2xvcnMubWFwKChjb2xvciwgaW5kZXgpID0+IChcbiAgICAgICAgPGRpdlxuICAgICAgICAgIGRyYWdnYWJsZT17dHJ1ZX1cbiAgICAgICAgICBrZXk9e2Bjb2xvci1jaGFydC10aWNrLSR7Y29sb3J9LSR7aW5kZXh9YH1cbiAgICAgICAgICBvbk1vdXNlRG93bj17ZSA9PiBvbk1vdXNlRG93bihlLCBpbmRleCl9XG4gICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogY29sb3IsXG4gICAgICAgICAgICBsZWZ0OiBgJHtzdGF0ZVBvc2l0aW9uc1tpbmRleF0gLSBDT0xPUl9DSEFSVF9USUNLX1dJRFRIIC8gMiAtIDF9cHhgLFxuICAgICAgICAgICAgYm9yZGVyV2lkdGg6IGAxcHhgLFxuICAgICAgICAgICAgYm9yZGVyU3R5bGU6ICdzb2xpZCcsXG4gICAgICAgICAgICBib3JkZXJDb2xvcjogQ09MT1JfQ0hBUlRfVElDS19CT1JERVJfQ09MT1IsXG4gICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgIHdpZHRoOiBgJHtDT0xPUl9DSEFSVF9USUNLX1dJRFRIfXB4YCxcbiAgICAgICAgICAgIGhlaWdodDogYCR7Q09MT1JfQ0hBUlRfVElDS19IRUlHSFR9cHhgLFxuICAgICAgICAgICAgY3Vyc29yOiAncG9pbnRlcidcbiAgICAgICAgICB9fVxuICAgICAgICAvPlxuICAgICAgKSl9XG4gICAgPC9Db2xvckNoYXJ0VGlja0NvbnRhaW5lcj5cbiAgKTtcbn07XG5cbi8vIG9ubHkgZm9yIG51bWV0aWMgZmllbGRcbkNvbHVtblN0YXRzQ2hhcnRGYWN0b3J5LmRlcHMgPSBbSGlzdG9ncmFtUGxvdEZhY3RvcnldO1xuXG5leHBvcnQgdHlwZSBDb2x1bW5TdGF0c0NoYXJ0V0xvYWRpbmdQcm9wcyA9IHtcbiAgY29sb3JGaWVsZDogRmllbGQ7XG4gIGRhdGFzZXQ6IEtlcGxlclRhYmxlO1xuICBjb2xvckJyZWFrczogQ29sb3JCcmVha1tdIHwgQ29sb3JCcmVha09yZGluYWxbXSB8IG51bGw7XG4gIGFsbEJpbnM6IEJpbltdO1xuICBmaWx0ZXJlZEJpbnM6IEJpbltdO1xuICBpc0ZpbHRlcmVkOiBib29sZWFuO1xuICBoaXN0b2dyYW1Eb21haW46IG51bWJlcltdO1xuICBvbkNoYW5nZWRVcGRhdGVyOiAodGlja3M6IENvbG9yQnJlYWtbXSkgPT4gdm9pZDtcbn07XG5cbmV4cG9ydCB0eXBlIENvbHVtblN0YXRzQ2hhcnRQcm9wcyA9IHtcbiAgYWxsQmluczogQmluW107XG4gIGZpbHRlcmVkQmluczogQmluW107XG4gIGlzRmlsdGVyZWQ6IGJvb2xlYW47XG4gIGhpc3RvZ3JhbURvbWFpbjogbnVtYmVyW107XG4gIGNvbG9yQnJlYWtzOiBDb2xvckJyZWFrW107XG4gIG9uQ2hhbmdlZFVwZGF0ZXI6ICh0aWNrczogQ29sb3JCcmVha1tdKSA9PiB2b2lkO1xufTtcbmZ1bmN0aW9uIENvbHVtblN0YXRzQ2hhcnRGYWN0b3J5KFxuICBIaXN0b2dyYW1QbG90OiBSZXR1cm5UeXBlPHR5cGVvZiBIaXN0b2dyYW1QbG90RmFjdG9yeT5cbik6IFJlYWN0LkZDPENvbHVtblN0YXRzQ2hhcnRXTG9hZGluZ1Byb3BzPiB7XG4gIGNvbnN0IENvbHVtblN0YXRzQ2hhcnQ6IFJlYWN0LkZDPENvbHVtblN0YXRzQ2hhcnRQcm9wcz4gPSAoe1xuICAgIGFsbEJpbnMsXG4gICAgZmlsdGVyZWRCaW5zLFxuICAgIGlzRmlsdGVyZWQsXG4gICAgaGlzdG9ncmFtRG9tYWluLFxuICAgIGNvbG9yQnJlYWtzLFxuICAgIG9uQ2hhbmdlZFVwZGF0ZXJcbiAgfSkgPT4ge1xuICAgIGNvbnN0IFt0aWNrcywgc2V0VGlja3NdID0gdXNlU3RhdGUoY29sb3JCcmVha3MpO1xuICAgIGNvbnN0IFtyZWYsIHNpemVdID0gdXNlRGltZW5zaW9uczxIVE1MRGl2RWxlbWVudD4oKTtcbiAgICBjb25zdCBoaXN0b2dyYW1XaWR0aCA9IHNpemVcbiAgICAgID8gc2l6ZS53aWR0aCAtIEhJU1RPR1JBTV9NQVJHSU4ubGVmdCAtIEhJU1RPR1JBTV9NQVJHSU4ucmlnaHRcbiAgICAgIDogSElTVE9HUkFNX1dJRFRIO1xuXG4gICAgLy8gZGlzdGluZ3Vpc2ggYmV0d2VlbiBwcm9wcy5jb2xvckJyZWFrcyBhbmQgc3RhdGVzLnRpY2tzXG4gICAgY29uc3QgaXNUaWNrQ2hhbmdpbmdSZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuXG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgIHNldFRpY2tzKHRpY2tzKTtcbiAgICAgIC8vIHJlc2V0IGlzVGlja0NoYW5naW5nIG9uY2UgaGlzdG9ncmFtIGRvbWFpbiBpcyByZWNvbXB1dGVkXG4gICAgICBpc1RpY2tDaGFuZ2luZ1JlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgfSwgW3RpY2tzXSk7XG5cbiAgICAvLyBoaXN0b2dyYW1zIHVzZWQgYnkgaGlzdG9ncmFtLXBsb3QuanNcbiAgICBjb25zdCBoaXN0b2dyYW1zQnlHcm91cCA9IHVzZU1lbW8oXG4gICAgICAoKSA9PiAoe1xuICAgICAgICBiaW5zOiBhbGxCaW5zLFxuICAgICAgICBmaWx0ZXJlZEJpbnNcbiAgICAgIH0pLFxuICAgICAgW2FsbEJpbnMsIGZpbHRlcmVkQmluc11cbiAgICApO1xuXG4gICAgLy8gZ2V0IGNvbG9ycyBmcm9tIGNvbG9yQnJlYWtzXG4gICAgY29uc3QgZG9tYWluQ29sb3JzID0gdXNlTWVtbyhcbiAgICAgICgpID0+IChjb2xvckJyZWFrcyA/IGNvbG9yQnJlYWtzLm1hcChjID0+IGMuZGF0YSkgOiBbXSksXG4gICAgICBbY29sb3JCcmVha3NdXG4gICAgKTtcblxuICAgIGNvbnN0IHRpY2tQb3NpdGlvbnMgPSB1c2VNZW1vKCgpID0+IHtcbiAgICAgIGlmICghaXNUaWNrQ2hhbmdpbmdSZWYuY3VycmVudCkge1xuICAgICAgICBzZXRUaWNrcyhjb2xvckJyZWFrcyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IFt2YWx1ZU1pbiwgdmFsdWVNYXhdID0gaGlzdG9ncmFtRG9tYWluO1xuICAgICAgY29uc3Qgd2lkdGhTY2FsZSA9IHNjYWxlTGluZWFyKCkuZG9tYWluKFt2YWx1ZU1pbiwgdmFsdWVNYXhdKS5yYW5nZShbMCwgaGlzdG9ncmFtV2lkdGhdKTtcbiAgICAgIHJldHVybiB0aWNrcy5zbGljZSgwLCAtMSkubWFwKGNiID0+IHtcbiAgICAgICAgY29uc3QgcG9zID0gd2lkdGhTY2FsZShjYi5yYW5nZVsxXSk7XG4gICAgICAgIGlmIChwb3MgPCAwKSByZXR1cm4gMDtcbiAgICAgICAgZWxzZSBpZiAocG9zID4gaGlzdG9ncmFtV2lkdGgpIHJldHVybiBoaXN0b2dyYW1XaWR0aDtcbiAgICAgICAgcmV0dXJuIHBvcztcbiAgICAgIH0pO1xuICAgIH0sIFtoaXN0b2dyYW1Eb21haW4sIHRpY2tzLCBjb2xvckJyZWFrcywgaGlzdG9ncmFtV2lkdGhdKTtcblxuICAgIGNvbnN0IGRvbWFpbkNvbG9yV2lkdGhzID0gdXNlTWVtbygoKSA9PiB7XG4gICAgICBjb25zdCBuID0gdGlja1Bvc2l0aW9ucy5sZW5ndGg7XG4gICAgICBjb25zdCB3aWR0aHMgPSBbdGlja1Bvc2l0aW9uc1swXV07XG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8IG47ICsraSkge1xuICAgICAgICB3aWR0aHMucHVzaCh0aWNrUG9zaXRpb25zW2ldIC0gdGlja1Bvc2l0aW9uc1tpIC0gMV0pO1xuICAgICAgfVxuICAgICAgd2lkdGhzLnB1c2goaGlzdG9ncmFtV2lkdGggLSB0aWNrUG9zaXRpb25zW24gLSAxXSk7XG4gICAgICByZXR1cm4gd2lkdGhzO1xuICAgIH0sIFt0aWNrUG9zaXRpb25zLCBoaXN0b2dyYW1XaWR0aF0pO1xuXG4gICAgLy8gaGFuZGxlIHRpY2sgZHJhZy1uLW1vdmVcbiAgICBjb25zdCBvblRpY2tNb3ZpbmdIYW5kbGVyID0gdXNlQ2FsbGJhY2soXG4gICAgICAobmV3VGlja1Bvc2l0aW9ucywgdGlja0luZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IFt2YWx1ZU1pbiwgdmFsdWVNYXhdID0gaGlzdG9ncmFtRG9tYWluO1xuICAgICAgICBjb25zdCB2YWx1ZVJhbmdlID0gdmFsdWVNYXggLSB2YWx1ZU1pbjtcbiAgICAgICAgY29uc3QgYnJlYWtzID0gW3ZhbHVlTWluXTtcbiAgICAgICAgbmV3VGlja1Bvc2l0aW9ucy5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgICAgIGJyZWFrcy5wdXNoKHZhbHVlTWluICsgKHZhbHVlUmFuZ2UgKiBlbGVtZW50KSAvIGhpc3RvZ3JhbVdpZHRoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrcy5wdXNoKHZhbHVlTWF4KTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRpY2tzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgY29uc3QgbGVmdFZhbHVlID0gaSA9PT0gdGlja0luZGV4ICsgMSA/IGJyZWFrc1tpXSA6IHRpY2tzW2ldLnJhbmdlWzBdO1xuICAgICAgICAgIGNvbnN0IHJpZ2h0VmFsdWUgPSBpICsgMSA9PT0gdGlja0luZGV4ICsgMSA/IGJyZWFrc1tpICsgMV0gOiB0aWNrc1tpXS5yYW5nZVsxXTtcblxuICAgICAgICAgIHRpY2tzW2ldID0ge1xuICAgICAgICAgICAgLi4udGlja3NbaV0sXG4gICAgICAgICAgICByYW5nZTogW2xlZnRWYWx1ZSwgcmlnaHRWYWx1ZV0sXG4gICAgICAgICAgICBpbnB1dHM6IFtsZWZ0VmFsdWUsIHJpZ2h0VmFsdWVdLFxuICAgICAgICAgICAgbGFiZWw6IGAke2QzRm9ybWF0KCcuMmYnKShicmVha3NbaV0pfSB0byAke2QzRm9ybWF0KCcuMmYnKShicmVha3NbaSArIDFdKX1gXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpc1RpY2tDaGFuZ2luZ1JlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgICAgc2V0VGlja3MoWy4uLnRpY2tzXSk7XG4gICAgICB9LFxuICAgICAgW2hpc3RvZ3JhbURvbWFpbiwgdGlja3MsIGhpc3RvZ3JhbVdpZHRoXVxuICAgICk7XG5cbiAgICAvLyB1cGRhdGUgcGFyZW50IGFuZCBzaWJsaW5nIGNvbXBvbmVudHMgd2hlbiB0aWNrIGRyYWdnaW5nIGVuZGVkXG4gICAgY29uc3Qgb25UaWNrQ2hhbmdlZEhhbmRsZXIgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgICBvbkNoYW5nZWRVcGRhdGVyKHRpY2tzKTtcbiAgICB9LCBbb25DaGFuZ2VkVXBkYXRlciwgdGlja3NdKTtcblxuICAgIHJldHVybiAoXG4gICAgICA8Q29sb3JDaGFydENvbnRhaW5lciByZWY9e3JlZn0+XG4gICAgICAgIDxDb2xvckNoYXJ0SGVhZGVyXG4gICAgICAgICAgbWluVmFsPXtoaXN0b2dyYW1Eb21haW5bMF19XG4gICAgICAgICAgbWF4VmFsPXtoaXN0b2dyYW1Eb21haW5bMV19XG4gICAgICAgICAgbWVhblZhbD17aGlzdG9ncmFtRG9tYWluWzJdfVxuICAgICAgICAvPlxuICAgICAgICA8Q29sb3JDaGFydFdyYXBwZXI+XG4gICAgICAgICAgPENvbG9yUGFsZXR0ZVdyYXBwZXI+XG4gICAgICAgICAgICA8Q29sb3JQYWxldHRlXG4gICAgICAgICAgICAgIGNvbG9ycz17ZG9tYWluQ29sb3JzfVxuICAgICAgICAgICAgICBjb2xvcldpZHRocz17ZG9tYWluQ29sb3JXaWR0aHN9XG4gICAgICAgICAgICAgIGhlaWdodD17SElTVE9HUkFNX0hFSUdIVCArIDE2fVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICA8L0NvbG9yUGFsZXR0ZVdyYXBwZXI+XG4gICAgICAgICAgPEhpc3RvZ3JhbVdyYXBwZXI+XG4gICAgICAgICAgICA8SGlzdG9ncmFtUGxvdFxuICAgICAgICAgICAgICBoaXN0b2dyYW1zQnlHcm91cD17aGlzdG9ncmFtc0J5R3JvdXB9XG4gICAgICAgICAgICAgIGNvbG9yc0J5R3JvdXA9e251bGx9XG4gICAgICAgICAgICAgIGlzTWFza2VkPXtpc0ZpbHRlcmVkID8gSElTVE9HUkFNX01BU0tfTU9ERS5NYXNrV2l0aE92ZXJsYXkgOiBISVNUT0dSQU1fTUFTS19NT0RFLk1hc2t9XG4gICAgICAgICAgICAgIHZhbHVlPXtoaXN0b2dyYW1Eb21haW59XG4gICAgICAgICAgICAgIHdpZHRoPXtoaXN0b2dyYW1XaWR0aH1cbiAgICAgICAgICAgICAgaGVpZ2h0PXtISVNUT0dSQU1fSEVJR0hUfVxuICAgICAgICAgICAgICBtYXJnaW49e0hJU1RPR1JBTV9NQVJHSU59XG4gICAgICAgICAgICAgIGJyZWFrTGluZXM9e3RpY2tQb3NpdGlvbnN9XG4gICAgICAgICAgICAvPlxuICAgICAgICAgIDwvSGlzdG9ncmFtV3JhcHBlcj5cbiAgICAgICAgPC9Db2xvckNoYXJ0V3JhcHBlcj5cbiAgICAgICAgPENvbG9yQ2hhcnRUaWNrXG4gICAgICAgICAgY29sb3JzPXtkb21haW5Db2xvcnMuc2xpY2UoMCwgLTEpfVxuICAgICAgICAgIHBvc2l0aW9ucz17dGlja1Bvc2l0aW9uc31cbiAgICAgICAgICBoaXN0b2dyYW1XaWR0aD17aGlzdG9ncmFtV2lkdGh9XG4gICAgICAgICAgb25UaWNrTW92aW5nPXtvblRpY2tNb3ZpbmdIYW5kbGVyfVxuICAgICAgICAgIG9uVGlja0NoYW5nZWQ9e29uVGlja0NoYW5nZWRIYW5kbGVyfVxuICAgICAgICAvPlxuICAgICAgPC9Db2xvckNoYXJ0Q29udGFpbmVyPlxuICAgICk7XG4gIH07XG5cbiAgY29uc3QgQ29sdW1uU3RhdHNDaGFydFdMb2FkaW5nOiBSZWFjdC5GQzxDb2x1bW5TdGF0c0NoYXJ0V0xvYWRpbmdQcm9wcz4gPSAoe1xuICAgIGNvbG9yRmllbGQsXG4gICAgZGF0YXNldCxcbiAgICBjb2xvckJyZWFrcyxcbiAgICBhbGxCaW5zLFxuICAgIGZpbHRlcmVkQmlucyxcbiAgICBpc0ZpbHRlcmVkLFxuICAgIGhpc3RvZ3JhbURvbWFpbixcbiAgICBvbkNoYW5nZWRVcGRhdGVyXG4gIH0pID0+IHtcbiAgICBjb25zdCBmaWVsZE5hbWUgPSBjb2xvckZpZWxkPy5uYW1lO1xuICAgIGNvbnN0IGZpZWxkID0gdXNlTWVtbyhcbiAgICAgICgpID0+IChmaWVsZE5hbWUgPyBkYXRhc2V0LmdldENvbHVtbkZpZWxkKGZpZWxkTmFtZSkgOiBudWxsKSxcbiAgICAgIFtkYXRhc2V0LCBmaWVsZE5hbWVdXG4gICAgKTtcblxuICAgIGlmICghaXNOdW1lcmljQ29sb3JCcmVha3MoY29sb3JCcmVha3MpKSB7XG4gICAgICAvLyBUT0RPOiBpbXBsZW1lbnQgZGlzcGxheSBmb3Igb3JkaW5hbCBicmVha3NcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmIChmaWVsZD8uaXNMb2FkaW5nU3RhdHMpIHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxTdHlsZWRDb250YWluZXI+XG4gICAgICAgICAgPExvYWRpbmdTcGlubmVyIC8+XG4gICAgICAgIDwvU3R5bGVkQ29udGFpbmVyPlxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gKFxuICAgICAgPENvbHVtblN0YXRzQ2hhcnRcbiAgICAgICAgY29sb3JCcmVha3M9e2NvbG9yQnJlYWtzfVxuICAgICAgICBhbGxCaW5zPXthbGxCaW5zfVxuICAgICAgICBmaWx0ZXJlZEJpbnM9e2ZpbHRlcmVkQmluc31cbiAgICAgICAgaXNGaWx0ZXJlZD17aXNGaWx0ZXJlZH1cbiAgICAgICAgaGlzdG9ncmFtRG9tYWluPXtoaXN0b2dyYW1Eb21haW59XG4gICAgICAgIG9uQ2hhbmdlZFVwZGF0ZXI9e29uQ2hhbmdlZFVwZGF0ZXJ9XG4gICAgICAvPlxuICAgICk7XG4gIH07XG5cbiAgcmV0dXJuIENvbHVtblN0YXRzQ2hhcnRXTG9hZGluZztcbn1cblxuZXhwb3J0IGRlZmF1bHQgQ29sdW1uU3RhdHNDaGFydEZhY3Rvcnk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUdBLElBQUFBLFNBQUEsR0FB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