react-native-chart-kit
Version:
Beautiful React Native charts for dashboards, reports, and data-rich mobile apps.
283 lines • 61.9 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import React, { Component } from "react";
import { Defs, Line, LinearGradient, Stop, Text } from "react-native-svg";
export var DEFAULT_X_LABELS_HEIGHT_PERCENTAGE = 0.75;
var nextChartId = 0;
var AbstractChart = /** @class */ (function (_super) {
__extends(AbstractChart, _super);
function AbstractChart() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.chartId = nextChartId++;
_this.getValidData = function (data) {
if (data === void 0) { data = []; }
return data.filter(function (value) { return typeof value === "number" && isFinite(value); });
};
_this.getGradientId = function (id) {
return "chart-kit-".concat(_this.chartId, "-").concat(id);
};
_this.getGradientUrl = function (id) {
return "url(#".concat(_this.getGradientId(id), ")");
};
_this.calcScaler = function (data) {
var values = _this.getValidData(data);
if (values.length === 0) {
return 1;
}
if (_this.props.fromZero && _this.props.fromNumber) {
return (Math.max.apply(Math, __spreadArray(__spreadArray([], values, false), [_this.props.fromNumber], false)) - Math.min.apply(Math, __spreadArray(__spreadArray([], values, false), [0], false)) || 1);
}
else if (_this.props.fromZero) {
return Math.max.apply(Math, __spreadArray(__spreadArray([], values, false), [0], false)) - Math.min.apply(Math, __spreadArray(__spreadArray([], values, false), [0], false)) || 1;
}
else if (_this.props.fromNumber) {
return (Math.max.apply(Math, __spreadArray(__spreadArray([], values, false), [_this.props.fromNumber], false)) - Math.min.apply(Math, __spreadArray(__spreadArray([], values, false), [_this.props.fromNumber], false)) || 1);
}
else {
return Math.max.apply(Math, values) - Math.min.apply(Math, values) || 1;
}
};
_this.calcBaseHeight = function (data, height) {
var values = _this.getValidData(data);
if (values.length === 0) {
return height;
}
var min = Math.min.apply(Math, values);
var max = Math.max.apply(Math, values);
if (min >= 0 && max >= 0) {
return height;
}
else if (min < 0 && max <= 0) {
return 0;
}
else if (min < 0 && max > 0) {
return (height * max) / _this.calcScaler(values);
}
};
_this.calcHeight = function (val, data, height) {
if (typeof val !== "number" || !isFinite(val)) {
return 0;
}
var values = _this.getValidData(data);
if (values.length === 0) {
return 0;
}
var max = Math.max.apply(Math, values);
var min = Math.min.apply(Math, values);
if (min < 0 && max > 0) {
return height * (val / _this.calcScaler(values));
}
else if (min >= 0 && max >= 0) {
return _this.props.fromZero
? height * (val / _this.calcScaler(values))
: height * ((val - min) / _this.calcScaler(values));
}
else if (min < 0 && max <= 0) {
return _this.props.fromZero
? height * (val / _this.calcScaler(values))
: height * ((val - max) / _this.calcScaler(values));
}
};
_this.renderHorizontalLines = function (config) {
var count = config.count, width = config.width, height = config.height, paddingTop = config.paddingTop, paddingRight = config.paddingRight, _a = config.verticalLabelsHeightPercentage, verticalLabelsHeightPercentage = _a === void 0 ? DEFAULT_X_LABELS_HEIGHT_PERCENTAGE : _a;
var basePosition = height * verticalLabelsHeightPercentage;
return __spreadArray([], new Array(count + 1), true).map(function (_, i) {
var y = (basePosition / count) * i + paddingTop;
return (<Line key={"horizontal-line-".concat(i)} x1={paddingRight} y1={y} x2={width} y2={y} {..._this.getPropsForBackgroundLines()}/>);
});
};
_this.renderHorizontalLine = function (config) {
var width = config.width, height = config.height, paddingTop = config.paddingTop, paddingRight = config.paddingRight, _a = config.verticalLabelsHeightPercentage, verticalLabelsHeightPercentage = _a === void 0 ? DEFAULT_X_LABELS_HEIGHT_PERCENTAGE : _a;
return (<Line key="horizontal-line" x1={paddingRight} y1={height * verticalLabelsHeightPercentage + paddingTop} x2={width} y2={height * verticalLabelsHeightPercentage + paddingTop} {..._this.getPropsForBackgroundLines()}/>);
};
_this.renderHorizontalLabels = function (config) {
var count = config.count, data = config.data, height = config.height, paddingTop = config.paddingTop, paddingRight = config.paddingRight, _a = config.horizontalLabelRotation, horizontalLabelRotation = _a === void 0 ? 0 : _a, _b = config.decimalPlaces, decimalPlaces = _b === void 0 ? 2 : _b, _c = config.formatYLabel, formatYLabel = _c === void 0 ? function (yLabel) { return yLabel; } : _c, _d = config.verticalLabelsHeightPercentage, verticalLabelsHeightPercentage = _d === void 0 ? DEFAULT_X_LABELS_HEIGHT_PERCENTAGE : _d;
var values = _this.getValidData(data);
var labelData = values.length === 0 ? [0] : values;
var _e = _this.props, _f = _e.yAxisLabel, yAxisLabel = _f === void 0 ? "" : _f, _g = _e.yAxisSuffix, yAxisSuffix = _g === void 0 ? "" : _g, _h = _e.yLabelsOffset, yLabelsOffset = _h === void 0 ? 12 : _h;
return new Array(count === 1 ? 1 : count + 1).fill(1).map(function (_, i) {
var yLabel = String(i * count);
if (count === 1) {
yLabel = "".concat(yAxisLabel).concat(formatYLabel(labelData[0].toFixed(decimalPlaces))).concat(yAxisSuffix);
}
else {
var label = _this.props.fromZero
? (_this.calcScaler(labelData) / count) * i + Math.min.apply(Math, __spreadArray(__spreadArray([], labelData, false), [0], false))
: (_this.calcScaler(labelData) / count) * i + Math.min.apply(Math, labelData);
yLabel = "".concat(yAxisLabel).concat(formatYLabel(label.toFixed(decimalPlaces))).concat(yAxisSuffix);
}
var basePosition = height * verticalLabelsHeightPercentage;
var x = paddingRight - yLabelsOffset;
var y = count === 1 && _this.props.fromZero
? paddingTop + 4
: height * verticalLabelsHeightPercentage -
(basePosition / count) * i +
paddingTop;
return (<Text rotation={horizontalLabelRotation} origin={"".concat(x, ", ").concat(y)} key={"horizontal-label-".concat(i, "-").concat(yLabel)} x={x} textAnchor="end" y={y} {..._this.getPropsForLabels()} {..._this.getPropsForHorizontalLabels()}>
{yLabel}
</Text>);
});
};
_this.renderVerticalLabels = function (_a) {
var _b = _a.labels, labels = _b === void 0 ? [] : _b, width = _a.width, height = _a.height, paddingRight = _a.paddingRight, paddingTop = _a.paddingTop, _c = _a.horizontalOffset, horizontalOffset = _c === void 0 ? 0 : _c, xAxisIntervalCount = _a.xAxisIntervalCount, _d = _a.stackedBar, stackedBar = _d === void 0 ? false : _d, _e = _a.verticalLabelRotation, verticalLabelRotation = _e === void 0 ? 0 : _e, _f = _a.formatXLabel, formatXLabel = _f === void 0 ? function (xLabel) { return xLabel; } : _f, _g = _a.verticalLabelsHeightPercentage, verticalLabelsHeightPercentage = _g === void 0 ? DEFAULT_X_LABELS_HEIGHT_PERCENTAGE : _g;
var _h = _this.props, _j = _h.xAxisLabel, xAxisLabel = _j === void 0 ? "" : _j, _k = _h.xLabelsOffset, xLabelsOffset = _k === void 0 ? 0 : _k, _l = _h.hidePointsAtIndex, hidePointsAtIndex = _l === void 0 ? [] : _l;
var fontSize = 12;
var fac = 1;
if (stackedBar) {
fac = 0.71;
}
var labelIntervalCount = xAxisIntervalCount !== null && xAxisIntervalCount !== void 0 ? xAxisIntervalCount : labels.length;
var xAxisDivisor = Math.max(labelIntervalCount, 1);
return labels.map(function (label, i) {
if (hidePointsAtIndex.includes(i)) {
return null;
}
var isLastLabel = i === labels.length - 1;
var labelText = "".concat(formatXLabel(label)).concat(xAxisLabel);
var x = (((width - paddingRight) / xAxisDivisor) * i +
paddingRight +
horizontalOffset) *
fac;
var rotatedLabelRightOverflow = labelText.length *
fontSize *
0.62 *
Math.cos((Math.abs(verticalLabelRotation) * Math.PI) / 180);
var labelX = isLastLabel && i > 0 && verticalLabelRotation !== 0
? Math.min(x, width - rotatedLabelRightOverflow - 4)
: x;
var y = height * verticalLabelsHeightPercentage +
paddingTop +
fontSize * 2 +
xLabelsOffset;
return (<Text origin={"".concat(labelX, ", ").concat(y)} rotation={verticalLabelRotation} key={"vertical-label-".concat(i, "-").concat(label)} x={labelX} y={y} textAnchor={isLastLabel &&
i > 0 &&
xAxisIntervalCount !== undefined &&
verticalLabelRotation === 0
? "end"
: verticalLabelRotation === 0
? "middle"
: "start"} {..._this.getPropsForLabels()} {..._this.getPropsForVerticalLabels()}>
{labelText}
</Text>);
});
};
_this.renderVerticalLines = function (_a) {
var data = _a.data, width = _a.width, height = _a.height, paddingTop = _a.paddingTop, paddingRight = _a.paddingRight, xAxisIntervalCount = _a.xAxisIntervalCount, _b = _a.verticalLabelsHeightPercentage, verticalLabelsHeightPercentage = _b === void 0 ? DEFAULT_X_LABELS_HEIGHT_PERCENTAGE : _b;
var _c = _this.props.yAxisInterval, yAxisInterval = _c === void 0 ? 1 : _c;
var lineCount = Math.ceil(data.length / yAxisInterval);
var verticalLineStep = xAxisIntervalCount === undefined
? (width - paddingRight) / (data.length / yAxisInterval)
: ((width - paddingRight) / Math.max(xAxisIntervalCount, 1)) *
yAxisInterval;
return __spreadArray([], new Array(lineCount), true).map(function (_, i) {
var x = Math.floor(verticalLineStep * i + paddingRight);
return (<Line key={"vertical-line-".concat(i)} x1={x} y1={0} x2={x} y2={height * verticalLabelsHeightPercentage + paddingTop} {..._this.getPropsForBackgroundLines()}/>);
});
};
_this.renderVerticalLine = function (_a) {
var height = _a.height, paddingTop = _a.paddingTop, paddingRight = _a.paddingRight, _b = _a.verticalLabelsHeightPercentage, verticalLabelsHeightPercentage = _b === void 0 ? DEFAULT_X_LABELS_HEIGHT_PERCENTAGE : _b;
return (<Line key="vertical-line" x1={Math.floor(paddingRight)} y1={0} x2={Math.floor(paddingRight)} y2={height * verticalLabelsHeightPercentage + paddingTop} {..._this.getPropsForBackgroundLines()}/>);
};
_this.renderDefs = function (config) {
var width = config.width, height = config.height, backgroundGradientFrom = config.backgroundGradientFrom, backgroundGradientTo = config.backgroundGradientTo, useShadowColorFromDataset = config.useShadowColorFromDataset, data = config.data;
var fromOpacity = config.hasOwnProperty("backgroundGradientFromOpacity")
? config.backgroundGradientFromOpacity
: 1.0;
var toOpacity = config.hasOwnProperty("backgroundGradientToOpacity")
? config.backgroundGradientToOpacity
: 1.0;
var fillShadowGradient = config.hasOwnProperty("fillShadowGradient")
? config.fillShadowGradient
: _this.props.chartConfig.color(1.0);
var fillShadowGradientOpacity = config.hasOwnProperty("fillShadowGradientOpacity")
? config.fillShadowGradientOpacity
: 0.1;
var fillShadowGradientFrom = config.hasOwnProperty("fillShadowGradientFrom")
? config.fillShadowGradientFrom
: fillShadowGradient;
var fillShadowGradientFromOpacity = config.hasOwnProperty("fillShadowGradientFromOpacity")
? config.fillShadowGradientFromOpacity
: fillShadowGradientOpacity;
var fillShadowGradientFromOffset = config.hasOwnProperty("fillShadowGradientFromOffset")
? config.fillShadowGradientFromOffset
: 0;
var fillShadowGradientTo = config.hasOwnProperty("fillShadowGradientTo")
? config.fillShadowGradientTo
: _this.props.chartConfig.color(1.0);
var fillShadowGradientToOpacity = config.hasOwnProperty("fillShadowGradientToOpacity")
? config.fillShadowGradientToOpacity
: 0.1;
var fillShadowGradientToOffset = config.hasOwnProperty("fillShadowGradientToOffset")
? config.fillShadowGradientToOffset
: 1;
return (<Defs>
<LinearGradient id={_this.getGradientId("backgroundGradient")} x1={0} y1={height} x2={width} y2={0} gradientUnits="userSpaceOnUse">
<Stop offset="0" stopColor={backgroundGradientFrom} stopOpacity={fromOpacity}/>
<Stop offset="1" stopColor={backgroundGradientTo} stopOpacity={toOpacity}/>
</LinearGradient>
{useShadowColorFromDataset && data ? (data.map(function (dataset, index) { return (<LinearGradient id={_this.getGradientId("fillShadowGradientFrom_".concat(index))} key={"".concat(index)} x1={0} y1={0} x2={0} y2={height} gradientUnits="userSpaceOnUse">
<Stop offset={fillShadowGradientFromOffset} stopColor={dataset.color ? dataset.color(1.0) : fillShadowGradientFrom} stopOpacity={fillShadowGradientFromOpacity}/>
<Stop offset={fillShadowGradientToOffset} stopColor={dataset.color
? dataset.color(fillShadowGradientFromOpacity)
: fillShadowGradientFrom} stopOpacity={fillShadowGradientToOpacity || 0}/>
</LinearGradient>); })) : (<LinearGradient id={_this.getGradientId("fillShadowGradientFrom")} x1={0} y1={0} x2={0} y2={height} gradientUnits="userSpaceOnUse">
<Stop offset={fillShadowGradientFromOffset} stopColor={fillShadowGradientFrom} stopOpacity={fillShadowGradientFromOpacity}/>
<Stop offset={fillShadowGradientToOffset} stopColor={fillShadowGradientTo || fillShadowGradientFrom} stopOpacity={fillShadowGradientToOpacity || 0}/>
</LinearGradient>)}
</Defs>);
};
return _this;
}
AbstractChart.prototype.getPropsForBackgroundLines = function () {
var _a = this.props.chartConfig.propsForBackgroundLines, propsForBackgroundLines = _a === void 0 ? {} : _a;
return __assign({ stroke: this.props.chartConfig.color(0.2), strokeDasharray: "5, 10", strokeWidth: 1 }, propsForBackgroundLines);
};
AbstractChart.prototype.getPropsForLabels = function () {
var _a = this.props.chartConfig, _b = _a.propsForLabels, propsForLabels = _b === void 0 ? {} : _b, color = _a.color, _c = _a.labelColor, labelColor = _c === void 0 ? color : _c;
return __assign({ fontSize: 12, fill: labelColor(0.8) }, propsForLabels);
};
AbstractChart.prototype.getPropsForVerticalLabels = function () {
var _a = this.props.chartConfig, _b = _a.propsForVerticalLabels, propsForVerticalLabels = _b === void 0 ? {} : _b, color = _a.color, _c = _a.labelColor, labelColor = _c === void 0 ? color : _c;
return __assign({ fill: labelColor(0.8) }, propsForVerticalLabels);
};
AbstractChart.prototype.getPropsForHorizontalLabels = function () {
var _a = this.props.chartConfig, _b = _a.propsForHorizontalLabels, propsForHorizontalLabels = _b === void 0 ? {} : _b, color = _a.color, _c = _a.labelColor, labelColor = _c === void 0 ? color : _c;
return __assign({ fill: labelColor(0.8) }, propsForHorizontalLabels);
};
return AbstractChart;
}(Component));
export default AbstractChart;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWJzdHJhY3RDaGFydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zaGFyZWQvQWJzdHJhY3RDaGFydC50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEtBQUssRUFBRSxFQUFFLFNBQVMsRUFBRSxNQUFNLE9BQU8sQ0FBQztBQUN6QyxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBc0MxRSxNQUFNLENBQUMsSUFBTSxrQ0FBa0MsR0FBRyxJQUFJLENBQUM7QUFFdkQsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0FBRXBCO0lBR1UsaUNBQW1FO0lBSDdFOztRQUlVLGFBQU8sR0FBRyxXQUFXLEVBQUUsQ0FBQztRQUV0QixrQkFBWSxHQUFHLFVBQUMsSUFBbUI7WUFBbkIscUJBQUEsRUFBQSxTQUFtQjtZQUMzQyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBQyxLQUFLLElBQUssT0FBQSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUE1QyxDQUE0QyxDQUFDLENBQUM7UUFDOUUsQ0FBQyxDQUFDO1FBRVEsbUJBQWEsR0FBRyxVQUFDLEVBQVU7WUFDbkMsT0FBTyxvQkFBYSxLQUFJLENBQUMsT0FBTyxjQUFJLEVBQUUsQ0FBRSxDQUFDO1FBQzNDLENBQUMsQ0FBQztRQUVRLG9CQUFjLEdBQUcsVUFBQyxFQUFVO1lBQ3BDLE9BQU8sZUFBUSxLQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxNQUFHLENBQUM7UUFDM0MsQ0FBQyxDQUFDO1FBRUYsZ0JBQVUsR0FBRyxVQUFDLElBQWM7WUFDMUIsSUFBTSxNQUFNLEdBQUcsS0FBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUV2QyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3hCLE9BQU8sQ0FBQyxDQUFDO1lBQ1gsQ0FBQztZQUVELElBQUksS0FBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLElBQUksS0FBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDakQsT0FBTyxDQUNMLElBQUksQ0FBQyxHQUFHLE9BQVIsSUFBSSxrQ0FBUSxNQUFNLFdBQUUsS0FBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLGFBQUksSUFBSSxDQUFDLEdBQUcsT0FBUixJQUFJLGtDQUFRLE1BQU0sV0FBRSxDQUFDLFVBQUMsSUFBSSxDQUFDLENBQ3pFLENBQUM7WUFDSixDQUFDO2lCQUFNLElBQUksS0FBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDL0IsT0FBTyxJQUFJLENBQUMsR0FBRyxPQUFSLElBQUksa0NBQVEsTUFBTSxXQUFFLENBQUMsYUFBSSxJQUFJLENBQUMsR0FBRyxPQUFSLElBQUksa0NBQVEsTUFBTSxXQUFFLENBQUMsVUFBQyxJQUFJLENBQUMsQ0FBQztZQUM5RCxDQUFDO2lCQUFNLElBQUksS0FBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDakMsT0FBTyxDQUNMLElBQUksQ0FBQyxHQUFHLE9BQVIsSUFBSSxrQ0FBUSxNQUFNLFdBQUUsS0FBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLGFBQ3ZDLElBQUksQ0FBQyxHQUFHLE9BQVIsSUFBSSxrQ0FBUSxNQUFNLFdBQUUsS0FBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLFVBQUMsSUFBSSxDQUFDLENBQ2xELENBQUM7WUFDSixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sT0FBTyxJQUFJLENBQUMsR0FBRyxPQUFSLElBQUksRUFBUSxNQUFNLElBQUksSUFBSSxDQUFDLEdBQUcsT0FBUixJQUFJLEVBQVEsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3hELENBQUM7UUFDSCxDQUFDLENBQUM7UUFFRixvQkFBYyxHQUFHLFVBQUMsSUFBYyxFQUFFLE1BQWM7WUFDOUMsSUFBTSxNQUFNLEdBQUcsS0FBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUV2QyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3hCLE9BQU8sTUFBTSxDQUFDO1lBQ2hCLENBQUM7WUFFRCxJQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxPQUFSLElBQUksRUFBUSxNQUFNLENBQUMsQ0FBQztZQUNoQyxJQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxPQUFSLElBQUksRUFBUSxNQUFNLENBQUMsQ0FBQztZQUNoQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUN6QixPQUFPLE1BQU0sQ0FBQztZQUNoQixDQUFDO2lCQUFNLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQy9CLE9BQU8sQ0FBQyxDQUFDO1lBQ1gsQ0FBQztpQkFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUM5QixPQUFPLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxHQUFHLEtBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbEQsQ0FBQztRQUNILENBQUMsQ0FBQztRQUVGLGdCQUFVLEdBQUcsVUFBQyxHQUFXLEVBQUUsSUFBYyxFQUFFLE1BQWM7WUFDdkQsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDOUMsT0FBTyxDQUFDLENBQUM7WUFDWCxDQUFDO1lBRUQsSUFBTSxNQUFNLEdBQUcsS0FBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUV2QyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3hCLE9BQU8sQ0FBQyxDQUFDO1lBQ1gsQ0FBQztZQUVELElBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLE9BQVIsSUFBSSxFQUFRLE1BQU0sQ0FBQyxDQUFDO1lBQ2hDLElBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLE9BQVIsSUFBSSxFQUFRLE1BQU0sQ0FBQyxDQUFDO1lBRWhDLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZCLE9BQU8sTUFBTSxHQUFHLENBQUMsR0FBRyxHQUFHLEtBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNsRCxDQUFDO2lCQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ2hDLE9BQU8sS0FBSSxDQUFDLEtBQUssQ0FBQyxRQUFRO29CQUN4QixDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxHQUFHLEtBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQzFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxLQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDdkQsQ0FBQztpQkFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUMvQixPQUFPLEtBQUksQ0FBQyxLQUFLLENBQUMsUUFBUTtvQkFDeEIsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsR0FBRyxLQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUMxQyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsS0FBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3ZELENBQUM7UUFDSCxDQUFDLENBQUM7UUFpREYsMkJBQXFCLEdBQUcsVUFBQyxNQUFNO1lBRTNCLElBQUEsS0FBSyxHQU1ILE1BQU0sTUFOSCxFQUNMLEtBQUssR0FLSCxNQUFNLE1BTEgsRUFDTCxNQUFNLEdBSUosTUFBTSxPQUpGLEVBQ04sVUFBVSxHQUdSLE1BQU0sV0FIRSxFQUNWLFlBQVksR0FFVixNQUFNLGFBRkksRUFDWixLQUNFLE1BQU0sK0JBRDJELEVBQW5FLDhCQUE4QixtQkFBRyxrQ0FBa0MsS0FBQSxDQUMxRDtZQUNYLElBQU0sWUFBWSxHQUFHLE1BQU0sR0FBRyw4QkFBOEIsQ0FBQztZQUU3RCxPQUFPLGtCQUFJLElBQUksS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsUUFBRSxHQUFHLENBQUMsVUFBQyxDQUFDLEVBQUUsQ0FBQztnQkFDeEMsSUFBTSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFVBQVUsQ0FBQztnQkFDbEQsT0FBTyxDQUNMLENBQUMsSUFBSSxDQUNILEdBQUcsQ0FBQyxDQUFDLDBCQUFtQixDQUFDLENBQUUsQ0FBQyxDQUM1QixFQUFFLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FDakIsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ04sRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQ1YsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ04sSUFBSSxLQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQyxFQUN0QyxDQUNILENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUVGLDBCQUFvQixHQUFHLFVBQUMsTUFBTTtZQUUxQixJQUFBLEtBQUssR0FLSCxNQUFNLE1BTEgsRUFDTCxNQUFNLEdBSUosTUFBTSxPQUpGLEVBQ04sVUFBVSxHQUdSLE1BQU0sV0FIRSxFQUNWLFlBQVksR0FFVixNQUFNLGFBRkksRUFDWixLQUNFLE1BQU0sK0JBRDJELEVBQW5FLDhCQUE4QixtQkFBRyxrQ0FBa0MsS0FBQSxDQUMxRDtZQUNYLE9BQU8sQ0FDTCxDQUFDLElBQUksQ0FDSCxHQUFHLENBQUMsaUJBQWlCLENBQ3JCLEVBQUUsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUNqQixFQUFFLENBQUMsQ0FBQyxNQUFNLEdBQUcsOEJBQThCLEdBQUcsVUFBVSxDQUFDLENBQ3pELEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUNWLEVBQUUsQ0FBQyxDQUFDLE1BQU0sR0FBRyw4QkFBOEIsR0FBRyxVQUFVLENBQUMsQ0FDekQsSUFBSSxLQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQyxFQUN0QyxDQUNILENBQUM7UUFDSixDQUFDLENBQUM7UUFFRiw0QkFBc0IsR0FBRyxVQUN2QixNQUE4RDtZQUc1RCxJQUFBLEtBQUssR0FTSCxNQUFNLE1BVEgsRUFDTCxJQUFJLEdBUUYsTUFBTSxLQVJKLEVBQ0osTUFBTSxHQU9KLE1BQU0sT0FQRixFQUNOLFVBQVUsR0FNUixNQUFNLFdBTkUsRUFDVixZQUFZLEdBS1YsTUFBTSxhQUxJLEVBQ1osS0FJRSxNQUFNLHdCQUptQixFQUEzQix1QkFBdUIsbUJBQUcsQ0FBQyxLQUFBLEVBQzNCLEtBR0UsTUFBTSxjQUhTLEVBQWpCLGFBQWEsbUJBQUcsQ0FBQyxLQUFBLEVBQ2pCLEtBRUUsTUFBTSxhQUZpQyxFQUF6QyxZQUFZLG1CQUFHLFVBQUMsTUFBYyxJQUFLLE9BQUEsTUFBTSxFQUFOLENBQU0sS0FBQSxFQUN6QyxLQUNFLE1BQU0sK0JBRDJELEVBQW5FLDhCQUE4QixtQkFBRyxrQ0FBa0MsS0FBQSxDQUMxRDtZQUNYLElBQU0sTUFBTSxHQUFHLEtBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkMsSUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztZQUUvQyxJQUFBLEtBSUYsS0FBSSxDQUFDLEtBQUssRUFIWixrQkFBZSxFQUFmLFVBQVUsbUJBQUcsRUFBRSxLQUFBLEVBQ2YsbUJBQWdCLEVBQWhCLFdBQVcsbUJBQUcsRUFBRSxLQUFBLEVBQ2hCLHFCQUFrQixFQUFsQixhQUFhLG1CQUFHLEVBQUUsS0FDTixDQUFDO1lBQ2YsT0FBTyxJQUFJLEtBQUssQ0FBQyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQzdELElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUM7Z0JBRS9CLElBQUksS0FBSyxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUNoQixNQUFNLEdBQUcsVUFBRyxVQUFVLFNBQUcsWUFBWSxDQUNuQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUNwQyxTQUFHLFdBQVcsQ0FBRSxDQUFDO2dCQUNwQixDQUFDO3FCQUFNLENBQUM7b0JBQ04sSUFBTSxLQUFLLEdBQUcsS0FBSSxDQUFDLEtBQUssQ0FBQyxRQUFRO3dCQUMvQixDQUFDLENBQUMsQ0FBQyxLQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxPQUFSLElBQUksa0NBQVEsU0FBUyxXQUFFLENBQUMsVUFBQzt3QkFDdEUsQ0FBQyxDQUFDLENBQUMsS0FBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsT0FBUixJQUFJLEVBQVEsU0FBUyxDQUFDLENBQUM7b0JBQ3RFLE1BQU0sR0FBRyxVQUFHLFVBQVUsU0FBRyxZQUFZLENBQ25DLEtBQUssQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQzdCLFNBQUcsV0FBVyxDQUFFLENBQUM7Z0JBQ3BCLENBQUM7Z0JBRUQsSUFBTSxZQUFZLEdBQUcsTUFBTSxHQUFHLDhCQUE4QixDQUFDO2dCQUM3RCxJQUFNLENBQUMsR0FBRyxZQUFZLEdBQUcsYUFBYSxDQUFDO2dCQUN2QyxJQUFNLENBQUMsR0FDTCxLQUFLLEtBQUssQ0FBQyxJQUFJLEtBQUksQ0FBQyxLQUFLLENBQUMsUUFBUTtvQkFDaEMsQ0FBQyxDQUFDLFVBQVUsR0FBRyxDQUFDO29CQUNoQixDQUFDLENBQUMsTUFBTSxHQUFHLDhCQUE4Qjt3QkFDdkMsQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQzt3QkFDMUIsVUFBVSxDQUFDO2dCQUNqQixPQUFPLENBQ0wsQ0FBQyxJQUFJLENBQ0gsUUFBUSxDQUFDLENBQUMsdUJBQXVCLENBQUMsQ0FDbEMsTUFBTSxDQUFDLENBQUMsVUFBRyxDQUFDLGVBQUssQ0FBQyxDQUFFLENBQUMsQ0FDckIsR0FBRyxDQUFDLENBQUMsMkJBQW9CLENBQUMsY0FBSSxNQUFNLENBQUUsQ0FBQyxDQUN2QyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDTCxVQUFVLENBQUMsS0FBSyxDQUNoQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDTCxJQUFJLEtBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQzdCLElBQUksS0FBSSxDQUFDLDJCQUEyQixFQUFFLENBQUMsQ0FFdkM7VUFBQSxDQUFDLE1BQU0sQ0FDVDtRQUFBLEVBQUUsSUFBSSxDQUFDLENBQ1IsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBRUYsMEJBQW9CLEdBQUcsVUFBQyxFQXlCdkI7Z0JBeEJDLGNBQVcsRUFBWCxNQUFNLG1CQUFHLEVBQUUsS0FBQSxFQUNYLEtBQUssV0FBQSxFQUNMLE1BQU0sWUFBQSxFQUNOLFlBQVksa0JBQUEsRUFDWixVQUFVLGdCQUFBLEVBQ1Ysd0JBQW9CLEVBQXBCLGdCQUFnQixtQkFBRyxDQUFDLEtBQUEsRUFDcEIsa0JBQWtCLHdCQUFBLEVBQ2xCLGtCQUFrQixFQUFsQixVQUFVLG1CQUFHLEtBQUssS0FBQSxFQUNsQiw2QkFBeUIsRUFBekIscUJBQXFCLG1CQUFHLENBQUMsS0FBQSxFQUN6QixvQkFBaUMsRUFBakMsWUFBWSxtQkFBRyxVQUFDLE1BQU0sSUFBSyxPQUFBLE1BQU0sRUFBTixDQUFNLEtBQUEsRUFDakMsc0NBQW1FLEVBQW5FLDhCQUE4QixtQkFBRyxrQ0FBa0MsS0FBQTtZQWU3RCxJQUFBLEtBSUYsS0FBSSxDQUFDLEtBQUssRUFIWixrQkFBZSxFQUFmLFVBQVUsbUJBQUcsRUFBRSxLQUFBLEVBQ2YscUJBQWlCLEVBQWpCLGFBQWEsbUJBQUcsQ0FBQyxLQUFBLEVBQ2pCLHlCQUFzQixFQUF0QixpQkFBaUIsbUJBQUcsRUFBRSxLQUNWLENBQUM7WUFFZixJQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7WUFFcEIsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1lBQ1osSUFBSSxVQUFVLEVBQUUsQ0FBQztnQkFDZixHQUFHLEdBQUcsSUFBSSxDQUFDO1lBQ2IsQ0FBQztZQUNELElBQU0sa0JBQWtCLEdBQUcsa0JBQWtCLGFBQWxCLGtCQUFrQixjQUFsQixrQkFBa0IsR0FBSSxNQUFNLENBQUMsTUFBTSxDQUFDO1lBQy9ELElBQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFckQsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLFVBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3pCLElBQUksaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQ2xDLE9BQU8sSUFBSSxDQUFDO2dCQUNkLENBQUM7Z0JBRUQsSUFBTSxXQUFXLEdBQUcsQ0FBQyxLQUFLLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO2dCQUM1QyxJQUFNLFNBQVMsR0FBRyxVQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsU0FBRyxVQUFVLENBQUUsQ0FBQztnQkFDeEQsSUFBTSxDQUFDLEdBQ0wsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLFlBQVksQ0FBQyxHQUFHLFlBQVksQ0FBQyxHQUFHLENBQUM7b0JBQzFDLFlBQVk7b0JBQ1osZ0JBQWdCLENBQUM7b0JBQ25CLEdBQUcsQ0FBQztnQkFDTixJQUFNLHlCQUF5QixHQUM3QixTQUFTLENBQUMsTUFBTTtvQkFDaEIsUUFBUTtvQkFDUixJQUFJO29CQUNKLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO2dCQUM5RCxJQUFNLE1BQU0sR0FDVixXQUFXLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxxQkFBcUIsS0FBSyxDQUFDO29CQUNqRCxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsS0FBSyxHQUFHLHlCQUF5QixHQUFHLENBQUMsQ0FBQztvQkFDcEQsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFUixJQUFNLENBQUMsR0FDTCxNQUFNLEdBQUcsOEJBQThCO29CQUN2QyxVQUFVO29CQUNWLFFBQVEsR0FBRyxDQUFDO29CQUNaLGFBQWEsQ0FBQztnQkFFaEIsT0FBTyxDQUNMLENBQUMsSUFBSSxDQUNILE1BQU0sQ0FBQyxDQUFDLFVBQUcsTUFBTSxlQUFLLENBQUMsQ0FBRSxDQUFDLENBQzFCLFFBQVEsQ0FBQyxDQUFDLHFCQUFxQixDQUFDLENBQ2hDLEdBQUcsQ0FBQyxDQUFDLHlCQUFrQixDQUFDLGNBQUksS0FBSyxDQUFFLENBQUMsQ0FDcEMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQ1YsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ0wsVUFBVSxDQUFDLENBQ1QsV0FBVzt3QkFDWCxDQUFDLEdBQUcsQ0FBQzt3QkFDTCxrQkFBa0IsS0FBSyxTQUFTO3dCQUNoQyxxQkFBcUIsS0FBSyxDQUFDO3dCQUN6QixDQUFDLENBQUMsS0FBSzt3QkFDUCxDQUFDLENBQUMscUJBQXFCLEtBQUssQ0FBQzs0QkFDM0IsQ0FBQyxDQUFDLFFBQVE7NEJBQ1YsQ0FBQyxDQUFDLE9BQ1IsQ0FBQyxDQUNELElBQUksS0FBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FDN0IsSUFBSSxLQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUVyQztVQUFBLENBQUMsU0FBUyxDQUNaO1FBQUEsRUFBRSxJQUFJLENBQUMsQ0FDUixDQUFDO1lBQ0osQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUM7UUFFRix5QkFBbUIsR0FBRyxVQUFDLEVBb0JEO2dCQW5CcEIsSUFBSSxVQUFBLEVBQ0osS0FBSyxXQUFBLEVBQ0wsTUFBTSxZQUFBLEVBQ04sVUFBVSxnQkFBQSxFQUNWLFlBQVksa0JBQUEsRUFDWixrQkFBa0Isd0JBQUEsRUFDbEIsc0NBQW1FLEVBQW5FLDhCQUE4QixtQkFBRyxrQ0FBa0MsS0FBQTtZQWMzRCxJQUFBLEtBQXNCLEtBQUksQ0FBQyxLQUFLLGNBQWYsRUFBakIsYUFBYSxtQkFBRyxDQUFDLEtBQUEsQ0FBZ0I7WUFDekMsSUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLGFBQWEsQ0FBQyxDQUFDO1lBQ3pELElBQU0sZ0JBQWdCLEdBQ3BCLGtCQUFrQixLQUFLLFNBQVM7Z0JBQzlCLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsYUFBYSxDQUFDO2dCQUN4RCxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUMxRCxhQUFhLENBQUM7WUFFcEIsT0FBTyxrQkFBSSxJQUFJLEtBQUssQ0FBQyxTQUFTLENBQUMsUUFBRSxHQUFHLENBQUMsVUFBQyxDQUFDLEVBQUUsQ0FBQztnQkFDeEMsSUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLEdBQUcsWUFBWSxDQUFDLENBQUM7Z0JBQzFELE9BQU8sQ0FDTCxDQUFDLElBQUksQ0FDSCxHQUFHLENBQUMsQ0FBQyx3QkFBaUIsQ0FBQyxDQUFFLENBQUMsQ0FDMUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ04sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ04sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ04sRUFBRSxDQUFDLENBQUMsTUFBTSxHQUFHLDhCQUE4QixHQUFHLFVBQVUsQ0FBQyxDQUN6RCxJQUFJLEtBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDLEVBQ3RDLENBQ0gsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBRUYsd0JBQWtCLEdBQUcsVUFBQyxFQVFyQjtnQkFQQyxNQUFNLFlBQUEsRUFDTixVQUFVLGdCQUFBLEVBQ1YsWUFBWSxrQkFBQSxFQUNaLHNDQUFtRSxFQUFuRSw4QkFBOEIsbUJBQUcsa0NBQWtDLEtBQUE7WUFJL0QsT0FBQSxDQUNKLENBQUMsSUFBSSxDQUNILEdBQUcsQ0FBQyxlQUFlLENBQ25CLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FDN0IsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ04sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUM3QixFQUFFLENBQUMsQ0FBQyxNQUFNLEdBQUcsOEJBQThCLEdBQUcsVUFBVSxDQUFDLENBQ3pELElBQUksS0FBSSxDQUFDLDBCQUEwQixFQUFFLENBQUMsRUFDdEMsQ0FDSDtRQVRLLENBU0wsQ0FBQztRQUVGLGdCQUFVLEdBQUcsVUFDWCxNQThCQztZQUdDLElBQUEsS0FBSyxHQU1ILE1BQU0sTUFOSCxFQUNMLE1BQU0sR0FLSixNQUFNLE9BTEYsRUFDTixzQkFBc0IsR0FJcEIsTUFBTSx1QkFKYyxFQUN0QixvQkFBb0IsR0FHbEIsTUFBTSxxQkFIWSxFQUNwQix5QkFBeUIsR0FFdkIsTUFBTSwwQkFGaUIsRUFDekIsSUFBSSxHQUNGLE1BQU0sS0FESixDQUNLO1lBRVgsSUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQywrQkFBK0IsQ0FBQztnQkFDeEUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyw2QkFBNkI7Z0JBQ3RDLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDUixJQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLDZCQUE2QixDQUFDO2dCQUNwRSxDQUFDLENBQUMsTUFBTSxDQUFDLDJCQUEyQjtnQkFDcEMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUVSLElBQU0sa0JBQWtCLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxvQkFBb0IsQ0FBQztnQkFDcEUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxrQkFBa0I7Z0JBQzNCLENBQUMsQ0FBQyxLQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFdEMsSUFBTSx5QkFBeUIsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUNyRCwyQkFBMkIsQ0FDNUI7Z0JBQ0MsQ0FBQyxDQUFDLE1BQU0sQ0FBQyx5QkFBeUI7Z0JBQ2xDLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFFUixJQUFNLHNCQUFzQixHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQ2xELHdCQUF3QixDQUN6QjtnQkFDQyxDQUFDLENBQUMsTUFBTSxDQUFDLHNCQUFzQjtnQkFDL0IsQ0FBQyxDQUFDLGtCQUFrQixDQUFDO1lBRXZCLElBQU0sNkJBQTZCLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FDekQsK0JBQStCLENBQ2hDO2dCQUNDLENBQUMsQ0FBQyxNQUFNLENBQUMsNkJBQTZCO2dCQUN0QyxDQUFDLENBQUMseUJBQXlCLENBQUM7WUFFOUIsSUFBTSw0QkFBNEIsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUN4RCw4QkFBOEIsQ0FDL0I7Z0JBQ0MsQ0FBQyxDQUFDLE1BQU0sQ0FBQyw0QkFBNEI7Z0JBQ3JDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFTixJQUFNLG9CQUFvQixHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsc0JBQXNCLENBQUM7Z0JBQ3hFLENBQUMsQ0FBQyxNQUFNLENBQUMsb0JBQW9CO2dCQUM3QixDQUFDLENBQUMsS0FBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRXRDLElBQU0sMkJBQTJCLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FDdkQsNkJBQTZCLENBQzlCO2dCQUNDLENBQUMsQ0FBQyxNQUFNLENBQUMsMkJBQTJCO2dCQUNwQyxDQUFDLENBQUMsR0FBRyxDQUFDO1lBRVIsSUFBTSwwQkFBMEIsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUN0RCw0QkFBNEIsQ0FDN0I7Z0JBQ0MsQ0FBQyxDQUFDLE1BQU0sQ0FBQywwQkFBMEI7Z0JBQ25DLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFTixPQUFPLENBQ0wsQ0FBQyxJQUFJLENBQ0g7UUFBQSxDQUFDLGNBQWMsQ0FDYixFQUFFLENBQUMsQ0FBQyxLQUFJLENBQUMsYUFBYSxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FDN0MsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ04sRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQ1gsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQ1YsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ04sYUFBYSxDQUFDLGdCQUFnQixDQUU5QjtVQUFBLENBQUMsSUFBSSxDQUNILE1BQU0sQ0FBQyxHQUFHLENBQ1YsU0FBUyxDQUFDLENBQUMsc0JBQXNCLENBQUMsQ0FDbEMsV0FBVyxDQUFDLENBQUMsV0FBVyxDQUFDLEVBRTNCO1VBQUEsQ0FBQyxJQUFJLENBQ0gsTUFBTSxDQUFDLEdBQUcsQ0FDVixTQUFTLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUNoQyxXQUFXLENBQUMsQ0FBQyxTQUFTLENBQUMsRUFFM0I7UUFBQSxFQUFFLGNBQWMsQ0FDaEI7UUFBQSxDQUFDLHlCQUF5QixJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FDbkMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFDLE9BQU8sRUFBRSxLQUFLLElBQUssT0FBQSxDQUMzQixDQUFDLGNBQWMsQ0FDYixFQUFFLENBQUMsQ0FBQyxLQUFJLENBQUMsYUFBYSxDQUFDLGlDQUEwQixLQUFLLENBQUUsQ0FBQyxDQUFDLENBQzFELEdBQUcsQ0FBQyxDQUFDLFVBQUcsS0FBSyxDQUFFLENBQUMsQ0FDaEIsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ04sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ04sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ04sRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQ1gsYUFBYSxDQUFDLGdCQUFnQixDQUU5QjtjQUFBLENBQUMsSUFBSSxDQUNILE1BQU0sQ0FBQyxDQUFDLDRCQUE0QixDQUFDLENBQ3JDLFNBQVMsQ0FBQyxDQUNSLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLHNCQUN2QyxDQUFDLENBQ0QsV0FBVyxDQUFDLENBQUMsNkJBQTZCLENBQUMsRUFFN0M7Y0FBQSxDQUFDLElBQUksQ0FDSCxNQUFNLENBQUMsQ0FBQywwQkFBMEIsQ0FBQyxDQUNuQyxTQUFTLENBQUMsQ0FDUixPQUFPLENBQUMsS0FBSzt3QkFDWCxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsQ0FBQzt3QkFDOUMsQ0FBQyxDQUFDLHNCQUNOLENBQUMsQ0FDRCxXQUFXLENBQUMsQ0FBQywyQkFBMkIsSUFBSSxDQUFDLENBQUMsRUFFbEQ7WUFBQSxFQUFFLGNBQWMsQ0FBQyxDQUNsQixFQTNCNEIsQ0EyQjVCLENBQUMsQ0FDSCxDQUFDLENBQUMsQ0FBQyxDQUNGLENBQUMsY0FBYyxDQUNiLEVBQUUsQ0FBQyxDQUFDLEtBQUksQ0FBQyxhQUFhLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUNqRCxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDTixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDTixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDTixFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FDWCxhQUFhLENBQUMsZ0JBQWdCLENBRTlCO1lBQUEsQ0FBQyxJQUFJLENBQ0gsTUFBTSxDQUFDLENBQUMsNEJBQTRCLENBQUMsQ0FDckMsU0FBUyxDQUFDLENBQUMsc0JBQXNCLENBQUMsQ0FDbEMsV0FBVyxDQUFDLENBQUMsNkJBQTZCLENBQUMsRUFFN0M7WUFBQSxDQUFDLElBQUksQ0FDSCxNQUFNLENBQUMsQ0FBQywwQkFBMEIsQ0FBQyxDQUNuQyxTQUFTLENBQUMsQ0FBQyxvQkFBb0IsSUFBSSxzQkFBc0IsQ0FBQyxDQUMxRCxXQUFXLENBQUMsQ0FBQywyQkFBMkIsSUFBSSxDQUFDLENBQUMsRUFFbEQ7VUFBQSxFQUFFLGNBQWMsQ0FBQyxDQUNsQixDQUNIO01BQUEsRUFBRSxJQUFJLENBQUMsQ0FDUixDQUFDO1FBQ0osQ0FBQyxDQUFDOztJQUNKLENBQUM7SUFqZUMsa0RBQTBCLEdBQTFCO1FBQ1UsSUFBQSxLQUFpQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsd0JBQTNCLEVBQTVCLHVCQUF1QixtQkFBRyxFQUFFLEtBQUEsQ0FBNEI7UUFDaEUsa0JBQ0UsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFDekMsZUFBZSxFQUFFLE9BQU8sRUFDeEIsV0FBVyxFQUFFLENBQUMsSUFDWCx1QkFBdUIsRUFDMUI7SUFDSixDQUFDO0lBRUQseUNBQWlCLEdBQWpCO1FBQ1EsSUFBQSxLQUlGLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUh4QixzQkFBbUIsRUFBbkIsY0FBYyxtQkFBRyxFQUFFLEtBQUEsRUFDbkIsS0FBSyxXQUFBLEVBQ0wsa0JBQWtCLEVBQWxCLFVBQVUsbUJBQUcsS0FBSyxLQUNNLENBQUM7UUFDM0Isa0JBQ0UsUUFBUSxFQUFFLEVBQUUsRUFDWixJQUFJLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUNsQixjQUFjLEVBQ2pCO0lBQ0osQ0FBQztJQUVELGlEQUF5QixHQUF6QjtRQUNRLElBQUEsS0FJRixJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFIeEIsOEJBQTJCLEVBQTNCLHNCQUFzQixtQkFBRyxFQUFFLEtBQUEsRUFDM0IsS0FBSyxXQUFBLEVBQ0wsa0JBQWtCLEVBQWxCLFVBQVUsbUJBQUcsS0FBSyxLQUNNLENBQUM7UUFDM0Isa0JBQ0UsSUFBSSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFDbEIsc0JBQXNCLEVBQ3pCO0lBQ0osQ0FBQztJQUVELG1EQUEyQixHQUEzQjtRQUNRLElBQUEsS0FJRixJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFIeEIsZ0NBQTZCLEVBQTdCLHdCQUF3QixtQkFBRyxFQUFFLEtBQUEsRUFDN0IsS0FBSyxXQUFBLEVBQ0wsa0JBQWtCLEVBQWxCLFVBQVUsbUJBQUcsS0FBSyxLQUNNLENBQUM7UUFDM0Isa0JBQ0UsSUFBSSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFDbEIsd0JBQXdCLEVBQzNCO0lBQ0osQ0FBQztJQW9iSCxvQkFBQztBQUFELENBQUMsQUF2akJELENBR1UsU0FBUyxHQW9qQmxCO0FBRUQsZUFBZSxhQUFhLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHsgQ29tcG9uZW50IH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBEZWZzLCBMaW5lLCBMaW5lYXJHcmFkaWVudCwgU3RvcCwgVGV4dCB9IGZyb20gXCJyZWFjdC1uYXRpdmUtc3ZnXCI7XG5cbmltcG9ydCB7IENoYXJ0Q29uZmlnLCBEYXRhc2V0LCBQYXJ0aWFsQnkgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFic3RyYWN0Q2hhcnRQcm9wcyB7XG4gIGZyb21aZXJvPzogYm9vbGVhbjtcbiAgZnJvbU51bWJlcj86IG51bWJlcjtcbiAgY2hhcnRDb25maWc/OiBBYnN0cmFjdENoYXJ0Q29uZmlnO1xuICB5QXhpc0xhYmVsPzogc3RyaW5nO1xuICB5QXhpc1N1ZmZpeD86IHN0cmluZztcbiAgeUxhYmVsc09mZnNldD86IG51bWJlcjtcbiAgeUF4aXNJbnRlcnZhbD86IG51bWJlcjtcbiAgeEF4aXNMYWJlbD86IHN0cmluZztcbiAgeExhYmVsc09mZnNldD86IG51bWJlcjtcbiAgaGlkZVBvaW50c0F0SW5kZXg/OiBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBYnN0cmFjdENoYXJ0Q29uZmlnIGV4dGVuZHMgQ2hhcnRDb25maWcge1xuICBjb3VudD86IG51bWJlcjtcbiAgZGF0YT86IERhdGFzZXRbXTtcbiAgd2lkdGg/OiBudW1iZXI7XG4gIGhlaWdodD86IG51bWJlcjtcbiAgcGFkZGluZ1RvcD86IG51bWJlcjtcbiAgcGFkZGluZ1JpZ2h0PzogbnVtYmVyO1xuICBob3Jpem9udGFsTGFiZWxSb3RhdGlvbj86IG51bWJlcjtcbiAgZm9ybWF0WUxhYmVsPzogKHlMYWJlbDogc3RyaW5nKSA9PiBzdHJpbmc7XG4gIGxhYmVscz86IHN0cmluZ1tdO1xuICBob3Jpem9udGFsT2Zmc2V0PzogbnVtYmVyO1xuICB4QXhpc0ludGVydmFsQ291bnQ/OiBudW1iZXI7XG4gIHN0YWNrZWRCYXI/OiBib29sZWFuO1xuICB2ZXJ0aWNhbExhYmVsUm90YXRpb24/OiBudW1iZXI7XG4gIGZvcm1hdFhMYWJlbD86ICh4TGFiZWw6IHN0cmluZykgPT4gc3RyaW5nO1xuICB2ZXJ0aWNhbExhYmVsc0hlaWdodFBlcmNlbnRhZ2U/OiBudW1iZXI7XG4gIGZvcm1hdFRvcEJhclZhbHVlPzogKHRvcEJhclZhbHVlOiBudW1iZXIpID0+IHN0cmluZyB8IG51bWJlcjtcbn1cblxuZXhwb3J0IHR5cGUgQWJzdHJhY3RDaGFydFN0YXRlID0ge307XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1hfTEFCRUxTX0hFSUdIVF9QRVJDRU5UQUdFID0gMC43NTtcblxubGV0IG5leHRDaGFydElkID0gMDtcblxuY2xhc3MgQWJzdHJhY3RDaGFydDxcbiAgSVByb3BzIGV4dGVuZHMgQWJzdHJhY3RDaGFydFByb3BzLFxuICBJU3RhdGUgZXh0ZW5kcyBBYnN0cmFjdENoYXJ0U3RhdGVcbj4gZXh0ZW5kcyBDb21wb25lbnQ8QWJzdHJhY3RDaGFydFByb3BzICYgSVByb3BzLCBBYnN0cmFjdENoYXJ0U3RhdGUgJiBJU3RhdGU+IHtcbiAgcHJpdmF0ZSBjaGFydElkID0gbmV4dENoYXJ0SWQrKztcblxuICBwcm90ZWN0ZWQgZ2V0VmFsaWREYXRhID0gKGRhdGE6IG51bWJlcltdID0gW10pID0+IHtcbiAgICByZXR1cm4gZGF0YS5maWx0ZXIoKHZhbHVlKSA9PiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgaXNGaW5pdGUodmFsdWUpKTtcbiAgfTtcblxuICBwcm90ZWN0ZWQgZ2V0R3JhZGllbnRJZCA9IChpZDogc3RyaW5nKSA9PiB7XG4gICAgcmV0dXJuIGBjaGFydC1raXQtJHt0aGlzLmNoYXJ0SWR9LSR7aWR9YDtcbiAgfTtcblxuICBwcm90ZWN0ZWQgZ2V0R3JhZGllbnRVcmwgPSAoaWQ6IHN0cmluZykgPT4ge1xuICAgIHJldHVybiBgdXJsKCMke3RoaXMuZ2V0R3JhZGllbnRJZChpZCl9KWA7XG4gIH07XG5cbiAgY2FsY1NjYWxlciA9IChkYXRhOiBudW1iZXJbXSkgPT4ge1xuICAgIGNvbnN0IHZhbHVlcyA9IHRoaXMuZ2V0VmFsaWREYXRhKGRhdGEpO1xuXG4gICAgaWYgKHZhbHVlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnByb3BzLmZyb21aZXJvICYmIHRoaXMucHJvcHMuZnJvbU51bWJlcikge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgTWF0aC5tYXgoLi4udmFsdWVzLCB0aGlzLnByb3BzLmZyb21OdW1iZXIpIC0gTWF0aC5taW4oLi4udmFsdWVzLCAwKSB8fCAxXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy5mcm9tWmVybykge1xuICAgICAgcmV0dXJuIE1hdGgubWF4KC4uLnZhbHVlcywgMCkgLSBNYXRoLm1pbiguLi52YWx1ZXMsIDApIHx8IDE7XG4gICAgfSBlbHNlIGlmICh0aGlzLnByb3BzLmZyb21OdW1iZXIpIHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIE1hdGgubWF4KC4uLnZhbHVlcywgdGhpcy5wcm9wcy5mcm9tTnVtYmVyKSAtXG4gICAgICAgICAgTWF0aC5taW4oLi4udmFsdWVzLCB0aGlzLnByb3BzLmZyb21OdW1iZXIpIHx8IDFcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBNYXRoLm1heCguLi52YWx1ZXMpIC0gTWF0aC5taW4oLi4udmFsdWVzKSB8fCAxO1xuICAgIH1cbiAgfTtcblxuICBjYWxjQmFzZUhlaWdodCA9IChkYXRhOiBudW1iZXJbXSwgaGVpZ2h0OiBudW1iZXIpID0+IHtcbiAgICBjb25zdCB2YWx1ZXMgPSB0aGlzLmdldFZhbGlkRGF0YShkYXRhKTtcblxuICAgIGlmICh2YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gaGVpZ2h0O1xuICAgIH1cblxuICAgIGNvbnN0IG1pbiA9IE1hdGgubWluKC4uLnZhbHVlcyk7XG4gICAgY29uc3QgbWF4ID0gTWF0aC5tYXgoLi4udmFsdWVzKTtcbiAgICBpZiAobWluID49IDAgJiYgbWF4ID49IDApIHtcbiAgICAgIHJldHVybiBoZWlnaHQ7XG4gICAgfSBlbHNlIGlmIChtaW4gPCAwICYmIG1heCA8PSAwKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2UgaWYgKG1pbiA8IDAgJiYgbWF4ID4gMCkge1xuICAgICAgcmV0dXJuIChoZWlnaHQgKiBtYXgpIC8gdGhpcy5jYWxjU2NhbGVyKHZhbHVlcyk7XG4gICAgfVxuICB9O1xuXG4gIGNhbGNIZWlnaHQgPSAodmFsOiBudW1iZXIsIGRhdGE6IG51bWJlcltdLCBoZWlnaHQ6IG51bWJlcikgPT4ge1xuICAgIGlmICh0eXBlb2YgdmFsICE9PSBcIm51bWJlclwiIHx8ICFpc0Zpbml0ZSh2YWwpKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBjb25zdCB2YWx1ZXMgPSB0aGlzLmdldFZhbGlkRGF0YShkYXRhKTtcblxuICAgIGlmICh2YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBjb25zdCBtYXggPSBNYXRoLm1heCguLi52YWx1ZXMpO1xuICAgIGNvbnN0IG1pbiA9IE1hdGgubWluKC4uLnZhbHVlcyk7XG5cbiAgICBpZiAobWluIDwgMCAmJiBtYXggPiAwKSB7XG4gICAgICByZXR1cm4gaGVpZ2h0ICogKHZhbCAvIHRoaXMuY2FsY1NjYWxlcih2YWx1ZXMpKTtcbiAgICB9IGVsc2UgaWYgKG1pbiA+PSAwICYmIG1heCA+PSAwKSB7XG4gICAgICByZXR1cm4gdGhpcy5wcm9wcy5mcm9tWmVyb1xuICAgICAgICA/IGhlaWdodCAqICh2YWwgLyB0aGlzLmNhbGNTY2FsZXIodmFsdWVzKSlcbiAgICAgICAgOiBoZWlnaHQgKiAoKHZhbCAtIG1pbikgLyB0aGlzLmNhbGNTY2FsZXIodmFsdWVzKSk7XG4gICAgfSBlbHNlIGlmIChtaW4gPCAwICYmIG1heCA8PSAwKSB7XG4gICAgICByZXR1cm4gdGhpcy5wcm9wcy5mcm9tWmVyb1xuICAgICAgICA/IGhlaWdodCAqICh2YWwgLyB0aGlzLmNhbGNTY2FsZXIodmFsdWVzKSlcbiAgICAgICAgOiBoZWlnaHQgKiAoKHZhbCAtIG1heCkgLyB0aGlzLmNhbGNTY2FsZXIodmFsdWVzKSk7XG4gICAgfVxuICB9O1xuXG4gIGdldFByb3BzRm9yQmFja2dyb3VuZExpbmVzKCkge1xuICAgIGNvbnN0IHsgcHJvcHNGb3JCYWNrZ3JvdW5kTGluZXMgPSB7fSB9ID0gdGhpcy5wcm9wcy5jaGFydENvbmZpZztcbiAgICByZXR1cm4ge1xuICAgICAgc3Ryb2tlOiB0aGlzLnByb3BzLmNoYXJ0Q29uZmlnLmNvbG9yKDAuMiksXG4gICAgICBzdHJva2VEYXNoYXJyYXk6IFwiNSwgMTBcIixcbiAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgLi4ucHJvcHNGb3JCYWNrZ3JvdW5kTGluZXNcbiAgICB9O1xuICB9XG5cbiAgZ2V0UHJvcHNGb3JMYWJlbHMoKSB7XG4gICAgY29uc3Qge1xuICAgICAgcHJvcHNGb3JMYWJlbHMgPSB7fSxcbiAgICAgIGNvbG9yLFxuICAgICAgbGFiZWxDb2xvciA9IGNvbG9yXG4gICAgfSA9IHRoaXMucHJvcHMuY2hhcnRDb25maWc7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgIGZpbGw6IGxhYmVsQ29sb3IoMC44KSxcbiAgICAgIC4uLnByb3BzRm9yTGFiZWxzXG4gICAgfTtcbiAgfVxuXG4gIGdldFByb3BzRm9yVmVydGljYWxMYWJlbHMoKSB7XG4gICAgY29uc3Qge1xuICAgICAgcHJvcHNGb3JWZXJ0aWNhbExhYmVscyA9IHt9LFxuICAgICAgY29sb3IsXG4gICAgICBsYWJlbENvbG9yID0gY29sb3JcbiAgICB9ID0gdGhpcy5wcm9wcy5jaGFydENvbmZpZztcbiAgICByZXR1cm4ge1xuICAgICAgZmlsbDogbGFiZWxDb2xvcigwLjgpLFxuICAgICAgLi4ucHJvcHNGb3JWZXJ0aWNhbExhYmVsc1xuICAgIH07XG4gIH1cblxuICBnZXRQcm9wc0Zvckhvcml6b250YWxMYWJlbHMoKSB7XG4gICAgY29uc3Qge1xuICAgICAgcHJvcHNGb3JIb3Jpem9udGFsTGFiZWxzID0ge30sXG4gICAgICBjb2xvcixcbiAgICAgIGxhYmVsQ29sb3IgPSBjb2xvclxuICAgIH0gPSB0aGlzLnByb3BzLmNoYXJ0Q29uZmlnO1xuICAgIHJldHVybiB7XG4gICAgICBmaWxsOiBsYWJlbENvbG9yKDAuOCksXG4gICAgICAuLi5wcm9wc0Zvckhvcml6b250YWxMYWJlbHNcbiAgICB9O1xuICB9XG5cbiAgcmVuZGVySG9yaXpvbnRhbExpbmVzID0gKGNvbmZpZykgPT4ge1xuICAgIGNvbnN0IHtcbiAgICAgIGNvdW50LFxuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICBwYWRkaW5nVG9wLFxuICAgICAgcGFkZGluZ1JpZ2h0LFxuICAgICAgdmVydGljYWxMYWJlbHNIZWlnaHRQZXJjZW50YWdlID0gREVGQVVMVF9YX0xBQkVMU19IRUlHSFRfUEVSQ0VOVEFHRVxuICAgIH0gPSBjb25maWc7XG4gICAgY29uc3QgYmFzZVBvc2l0aW9uID0gaGVpZ2h0ICogdmVydGljYWxMYWJlbHNIZWlnaHRQZXJjZW50YWdlO1xuXG4gICAgcmV0dXJuIFsuLi5uZXcgQXJyYXkoY291bnQgKyAxKV0ubWFwKChfLCBpKSA9PiB7XG4gICAgICBjb25zdCB5ID0gKGJhc2VQb3NpdGlvbiAvIGNvdW50KSAqIGkgKyBwYWRkaW5nVG9wO1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPExpbmVcbiAgICAgICAgICBrZXk9e2Bob3Jpem9udGFsLWxpbmUtJHtpfWB9XG4gICAgICAgICAgeDE9e3BhZGRpbmdSaWdodH1cbiAgICAgICAgICB5MT17eX1cbiAgICAgICAgICB4Mj17d2lkdGh9XG4gICAgICAgICAgeTI9e3l9XG4gICAgICAgICAgey4uLnRoaXMuZ2V0UHJvcHNGb3JCYWNrZ3JvdW5kTGluZXMoKX1cbiAgICAgICAgLz5cbiAgICAgICk7XG4gICAgfSk7XG4gIH07XG5cbiAgcmVuZGVySG9yaXpvbnRhbExpbmUgPSAoY29uZmlnKSA9PiB7XG4gICAgY29uc3Qge1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICBwYWRkaW5nVG9wLFxuICAgICAgcGFkZGluZ1JpZ2h0LFxuICAgICAgdmVydGljYWxMYWJlbHNIZWlnaHRQZXJjZW50YWdlID0gREVGQVVMVF9YX0xBQkVMU19IRUlHSFRfUEVSQ0VOVEFHRVxuICAgIH0gPSBjb25maWc7XG4gICAgcmV0dXJuIChcbiAgICAgIDxMaW5lXG4gICAgICAgIGtleT1cImhvcml6b250YWwtbGluZVwiXG4gICAgICAgIHgxPXtwYWRkaW5nUmlnaHR9XG4gICAgICAgIHkxPXtoZWlnaHQgKiB2ZXJ0aWNhbExhYmVsc0hlaWdodFBlcmNlbnRhZ2UgKyBwYWRkaW5nVG9wfVxuICAgICAgICB4Mj17d2lkdGh9XG4gICAgICAgIHkyPXtoZWlnaHQgKiB2ZXJ0aWNhbExhYmVsc0hlaWdodFBlcmNlbnRhZ2UgKyBwYWRkaW5nVG9wfVxuICAgICAgICB7Li4udGhpcy5nZXRQcm9wc0ZvckJhY2tncm91bmRMaW5lcygpfVxuICAgICAgLz5cbiAgICApO1xuICB9O1xuXG4gIHJlbmRlckhvcml6b250YWxMYWJlbHMgPSAoXG4gICAgY29uZmlnOiBPbWl0PEFic3RyYWN0Q2hhcnRDb25maWcsIFwiZGF0YVwiPiAmIHsgZGF0YTogbnVtYmVyW10gfVxuICApID0+IHtcbiAgICBjb25zdCB7XG4gICAgICBjb3VudCxcbiAgICAgIGRhdGEsXG4gICAgICBoZWlnaHQsXG4gICAgICBwYWRkaW5nVG9wLFxuICAgICAgcGFkZGluZ1JpZ2h0LFxuICAgICAgaG9yaXpvbnRhbExhYmVsUm90YXRpb24gPSAwLFxuICAgICAgZGVjaW1hbFBsYWNlcyA9IDIsXG4gICAgICBmb3JtYXRZTGFiZWwgPSAoeUxhYmVsOiBzdHJpbmcpID0+IHlMYWJlbCxcbiAgICAgIHZlcnRpY2FsTGFiZWxzSGVpZ2h0UGVyY2VudGFnZSA9IERFRkFVTFRfWF9MQUJFTFNfSEVJR0hUX1BFUkNFTlRBR0VcbiAgICB9ID0gY29uZmlnO1xuICAgIGNvbnN0IHZhbHVlcyA9IHRoaXMuZ2V0VmFsaWREYXRhKGRhdGEpO1xuICAgIGNvbnN0IGxhYmVsRGF0YSA9IHZhbHVlcy5sZW5ndGggPT09IDAgPyBbMF0gOiB2YWx1ZXM7XG5cbiAgICBjb25zdCB7XG4gICAgICB5QXhpc0xhYmVsID0gXCJcIixcbiAgICAgIHlBeGlzU3VmZml4ID0gXCJcIixcbiAgICAgIHlMYWJlbHNPZmZzZXQgPSAxMlxuICAgIH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiBuZXcgQXJyYXkoY291bnQgPT09IDEgPyAxIDogY291bnQgKyAxKS5maWxsKDEpLm1hcCgoXywgaSkgPT4ge1xuICAgICAgbGV0IHlMYWJlbCA9IFN0cmluZyhpICogY291bnQpO1xuXG4gICAgICBpZiAoY291bnQgPT09IDEpIHtcbiAgICAgICAgeUxhYmVsID0gYCR7eUF4aXNMYWJlbH0ke2Zvcm1hdFlMYWJlbChcbiAgICAgICAgICBsYWJlbERhdGFbMF0udG9GaXhlZChkZWNpbWFsUGxhY2VzKVxuICAgICAgICApfSR7eUF4aXNTdWZmaXh9YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGxhYmVsID0gdGhpcy5wcm9wcy5mcm9tWmVyb1xuICAgICAgICAgID8gKHRoaXMuY2FsY1NjYWxlcihsYWJlbERhdGEpIC8gY291bnQpICogaSArIE1hdGgubWluKC4uLmxhYmVsRGF0YSwgMClcbiAgICAgICAgICA6ICh0aGlzLmNhbGNTY2FsZXIobGFiZWxEYXRhKSAvIGNvdW50KSAqIGkgKyBNYXRoLm1pbiguLi5sYWJlbERhdGEpO1xuICAgICAgICB5TGFiZWwgPSBgJHt5QXhpc0xhYmVsfSR7Zm9ybWF0WUxhYmVsKFxuICAgICAgICAgIGxhYmVsLnRvRml4ZWQoZGVjaW1hbFBsYWNlcylcbiAgICAgICAgKX0ke3lBeGlzU3VmZml4fWA7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGJhc2VQb3NpdGlvbiA9IGhlaWdodCAqIHZlcnRpY2FsTGFiZWxzSGVpZ2h0UGVyY2VudGFnZTtcbiAgICAgIGNvbnN0IHggPSBwYWRkaW5nUmlnaHQgLSB5TGFiZWxzT2Zmc2V0O1xuICAgICAgY29uc3QgeSA9XG4gICAgICAgIGNvdW50ID09PSAxICYmIHRoaXMucHJvcHMuZnJvbVplcm9cbiAgICAgICAgICA/IHBhZGRpbmdUb3AgKyA0XG4gICAgICAgICAgOiBoZWlnaHQgKiB2ZXJ0aWNhbExhYmVsc0hlaWdodFBlcmNlbnRhZ2UgLVxuICAgICAgICAgICAgKGJhc2VQb3NpdGlvbiAvIGNvdW50KSAqIGkgK1xuICAgICAgICAgICAgcGFkZGluZ1RvcDtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxUZXh0XG4gICAgICAgICAgcm90YXRpb249e2hvcml6b250YWxMYWJlbFJvdGF0aW9ufVxuICAgICAgICAgIG9yaWdpbj17YCR7eH0sICR7eX1gfVxuICAgICAgICAgIGtleT17YGhvcml6b250YWwtbGFiZWwtJHtpfS0ke3lMYWJlbH1gfVxuICAgICAgICAgIHg9e3h9XG4gICAgICAgICAgdGV4dEFuY2hvcj1cImVuZFwiXG4gICAgICAgICAgeT17eX1cbiAgICAgICAgICB7Li4udGhpcy5nZXRQcm9wc0ZvckxhYmVscygpfVxuICAgICAgICAgIHsuLi50aGlzLmdldFByb3BzRm9ySG9yaXpvbnRhbExhYmVscygpfVxuICAgICAgICA+XG4gICAgICAgICAge3lMYWJlbH1cbiAgICAgICAgPC9UZXh0PlxuICAgICAgKTtcbiAgICB9KTtcbiAgfTtcblxuICByZW5kZXJWZXJ0aWNhbExhYmVscyA9ICh7XG4gICAgbGFiZWxzID0gW10sXG4gICAgd2lkdGgsXG4gICAgaGVpZ2h0LFxuICAgIHBhZGRpbmdSaWdodCxcbiAgICBwYWRkaW5nVG9wLFxuICAgIGhvcml6b250YWxPZmZzZXQgPSAwLFxuICAgIHhBeGlzSW50ZXJ2YWxDb3VudCxcbiAgICBzdGFja2VkQmFyID0gZmFsc2UsXG4gICAgdmVydGljYWxMYWJlbFJvdGF0aW9uID0gMCxcbiAgICBmb3JtYXRYTGFiZWwgPSAoeExhYmVsKSA9PiB4TGFiZWwsXG4gICAgdmVydGljYWxMYWJlbHNIZWlnaHRQZXJjZW50YWdlID0gREVGQVVMVF9YX0xBQkVMU19IRUlHSFRfUEVSQ0VOVEFHRVxuICB9OiBQaWNrPFxuICAgIEFic3RyYWN0Q2hhcnRDb25maWcsXG4gICAgfCBcImxhYmVsc1wiXG4gICAgfCBcIndpZHRoXCJcbiAgICB8IFwiaGVpZ2h0XCJcbiAgICB8IFwicGFkZGluZ1JpZ2h0XCJcbiAgICB8IFwicGFkZGluZ1RvcFwiXG4gICAgfCBcImhvcml6b250YWxPZmZzZXRcIlxuICAgIHwgXCJ4QXhpc0ludGVydmFsQ291bnRcIlxuICAgIHwgXCJzdGFja2VkQmFyXCJcbiAgICB8IFwidmVydGljYWxMYWJlbFJvdGF0aW9uXCJcbiAgICB8IFwiZm9ybWF0WExhYmVsXCJcbiAgICB8IFwidmVydGljYWxMYWJlbHNIZWlnaHRQZXJjZW50YWdlXCJcbiAgPikgPT4ge1xuICAgIGNvbnN0IHtcbiAgICAgIHhBeGlzTGFiZWwgPSBcIlwiLFxuICAgICAgeExhYmVsc09mZnNldCA9IDAsXG4gICAgICBoaWRlUG9pbnRzQXRJbmRleCA9IFtdXG4gICAgfSA9IHRoaXMucHJvcHM7XG5cbiAgICBjb25zdCBmb250U2l6ZSA9IDEyO1xuXG4gICAgbGV0IGZhYyA9IDE7XG4gICAgaWYgKHN0YWNrZWRCYXIpIHtcbiAgICAgIGZhYyA9IDAuNzE7XG4gICAgfVxuICAgIGNvbnN0IGxhYmVsSW50ZXJ2YWxDb3VudCA9IHhBeGlzSW50ZXJ2YWxDb3VudCA/PyBsYWJlbHMubGVuZ3RoO1xuICAgIGNvbnN0IHhBeGlzRGl2aXNvciA9IE1hdGgubWF4KGxhYmVsSW50ZXJ2YWxDb3VudCwgMSk7XG5cbiAgICByZXR1cm4gbGFiZWxzLm1hcCgobGFiZWwsIGkpID0+IHtcbiAgICAgIGlmIChoaWRlUG9pbnRzQXRJbmRleC5pbmNsdWRlcyhpKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaXNMYXN0TGFiZWwgPSBpID09PSBsYWJlbHMubGVuZ3RoIC0gMTtcbiAgICAgIGNvbnN0IGxhYmVsVGV4dCA9IGAke2Zvcm1hdFhMYWJlbChsYWJlbCl9JHt4QXhpc0xhYmVsfWA7XG4gICAgICBjb25zdCB4ID1cbiAgICAgICAgKCgod2lkdGggLSBwYWRkaW5nUmlnaHQpIC8geEF4aXNEaXZpc29yKSAqIGkgK1xuICAgICAgICAgIHBhZGRpbmdSaWdodCArXG4gICAgICAgICAgaG9yaXpvbnRhbE9mZnNldCkgKlxuICAgICAgICBmYWM7XG4gICAgICBjb25zdCByb3RhdGVkTGFiZWxSaWdodE92ZXJmbG93ID1cbiAgICAgICAgbGFiZWxUZXh0Lmxlbmd0aCAqXG4gICAgICAgIGZvbnRTaXplICpcbiAgICAgICAgMC42MiAqXG4gICAgICAgIE1hdGguY29zKChNYXRoLmFicyh2ZXJ0aWNhbExhYmVsUm90YXRpb24pICogTWF0aC5QSSkgLyAxODApO1xuICAgICAgY29uc3QgbGFiZWxYID1cbiAgICAgICAgaXNMYXN0TGFiZWwgJiYgaSA+IDAgJiYgdmVydGljYWxMYWJlbFJvdGF0aW9uICE9PSAwXG4gICAgICAgICAgPyBNYXRoLm1pbih4LCB3aWR0aCAtIHJvdGF0ZWRMYWJlbFJpZ2h0T3ZlcmZsb3cgLSA0KVxuICAgICAgICAgIDogeDtcblxuICAgICAgY29uc3QgeSA9XG4gICAgICAgIGhlaWdodCAqIHZlcnRpY2FsTGFiZWxzSGVpZ2h0UGVyY2VudGFnZSArXG4gICAgICAgIHBhZGRpbmdUb3AgK1xuICAgICAgICBmb250U2l6ZSAqIDIgK1xuICAgICAgICB4TGFiZWxzT2Zmc2V0O1xuXG4gICAgICByZXR1cm4gKFxuICAgICAgICA8VGV4dFxuICAgICAgICAgIG9yaWdpbj17YCR7bGFiZWxYfSwgJHt5fWB9XG4gICAgICAgICAgcm90YXRpb249e3ZlcnRpY2FsTGFiZWxSb3RhdGlvbn1cbiAgICAgICAgICBrZXk9e2B2ZXJ0aWNhbC1sYWJlbC0ke2l9LSR7bGFiZWx9YH1cbiAgICAgICAgICB4PXtsYWJlbFh9XG4gICAgICAgICAgeT17eX1cbiAgICAgICAgICB0ZXh0QW5jaG9yPXtcbiAgICAgICAgICAgIGlzTGFzdExhYmVsICYmXG4gICAgICAgICAgICBpID4gMCAmJlxuICAgICAgICAgICAgeEF4aXNJbnRlcnZhbENvdW50ICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgIHZlcnRpY2FsTGFiZWxSb3RhdGlvbiA9PT0gMFxuICAgICAgICAgICAgICA/IFwiZW5kXCJcbiAgICAgICAgICAgICAgOiB2ZXJ0aWNhbExhYmVsUm90YXRpb24gPT09IDBcbiAgICAgICAgICAgICAgICA/IFwibWlkZGxlXCJcbiAgICAgICAgICAgICAgICA6IFwic3RhcnRcIlxuICAgICAgICAgIH1cbiAgICAgICAgICB7Li4udGhpcy5nZXRQcm9wc0ZvckxhYmVscygpfVxuICAgICAgICAgIHsuLi50aGlzLmdldFByb3BzRm9yVmVydGljYWxMYWJlbHMoKX1cbiAgICAgICAgPlxuICAgICAgICAgIHtsYWJlbFRleHR9XG4gICAgICAgIDwvVGV4dD5cbiAgICAgICk7XG4gICAgfSk7XG4gIH07XG5cbiAgcmVuZGVyVmVydGljYWxMaW5lcyA9ICh7XG4gICAgZGF0YSxcbiAgICB3aWR0aCxcbiAgICBoZWlnaHQsXG4gICAgcGFkZGluZ1RvcCxcbiAgICBwYWRkaW5nUmlnaHQsXG4gICAgeEF4aXNJbnRlcnZhbENvdW50LFxuICAgIHZlcnRpY2FsTGFiZWxzSGVpZ2h0UGVyY2VudGFnZSA9IERFRkFVTFRfWF9MQUJFTFNfSEVJR0hUX1BFUkNFTlRBR0VcbiAgfTogT21pdDxcbiAgICBQaWNrPFxuICAgICAgQWJzdHJhY3RDaGFydENvbmZpZyxcbiAgICAgIHwgXCJkYXRhXCJcbiAgICAgIHwgXCJ3aWR0aFwiXG4gICAgICB8IFwiaGVpZ2h0XCJcbiAgICAgIHwgXCJwYWRkaW5nUmlnaHRcIlxuICAgICAgfCBcInBhZGRpbmdUb3BcIlxuICAgICAgfCBcInhBeGlzSW50ZXJ2YWxDb3VudFwiXG4gICAgICB8IFwidmVydGljYWxMYWJlbHNIZWlnaHRQZXJjZW50YWdlXCJcbiAgICA+LFxuICAgIFwiZGF0YVwiXG4gID4gJiB7IGRhdGE6IG51bWJlcltdIH0pID0+IHtcbiAgICBjb25zdCB7IHlBeGlzSW50ZXJ2YWwgPSAxIH0gPSB0aGlzLnByb3BzO1xuICAgIGNvbnN0IGxpbmVDb3VudCA9IE1hdGguY2VpbChkYXRhLmxlbmd0aCAvIHlBeGlzSW50ZXJ2YWwpO1xuICAgIGNvbnN0IHZlcnRpY2FsTGluZVN0ZXAgPVxuICAgICAgeEF4aXNJbnRlcnZhbENvdW50ID09PSB1bmRlZmluZWRcbiAgICAgICAgPyAod2lkdGggLSBwYWRkaW5nUmlnaHQpIC8gKGRhdGEubGVuZ3RoIC8geUF4aXNJbnRlcnZhbClcbiAgICAgICAgOiAoKHdpZHRoIC0gcGFkZGluZ1JpZ2h0KSAvIE1hdGgubWF4KHhBeGlzSW50ZXJ2YWxDb3VudCwgMSkpICpcbiAgICAgICAgICB5QXhpc0ludGVydmFsO1xuXG4gICAgcmV0dXJuIFsuLi5uZXcgQXJyYXkobGluZUNvdW50KV0ubWFwKChfLCBpKSA9PiB7XG4gICAgICBjb25zdCB4ID0gTWF0aC5mbG9vcih2ZXJ0aWNhbExpbmVTdGVwICogaSArIHBhZGRpbmdSaWdodCk7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8TGluZVxuICAgICAgICAgIGtleT17YHZlcnRpY2FsLWxpbmUtJHtpfWB9XG4gICAgICAgICAgeDE9e3h9XG4gICAgICAgICAgeTE9ezB9XG4gICAgICAgICAgeDI9e3h9XG4gICAgICAgICAgeTI9e2hlaWdodCAqIHZlcnRpY2FsTGFiZWxzSGVpZ2h0UGVyY2VudGFnZSArIHBhZGRpbmdUb3B9XG4gICAgICAgICAgey4uLnRoaXMuZ2V0UHJvcHNGb3JCYWNrZ3JvdW5kTGluZXMoKX1cbiAgICAgICAgLz5cbiAgICAgICk7XG4gICAgfSk7XG4gIH07XG5cbiAgcmVuZGVyVmVydGljYWxMaW5lID0gKHtcbiAgICBoZWlnaHQsXG4gICAgcGFkZGluZ1RvcCxcbiAgICBwYWRkaW5nUmlnaHQsXG4gICAgdmVydGljYWxMYWJlbHNIZWlnaHRQZXJjZW50YWdlID0gREVGQVVMVF9YX0xBQkVMU19IRUlHSFRfUEVSQ0VOVEFHRVxuICB9OiBQaWNrPFxuICAgIEFic3RyYWN0Q2hhcnRDb25maWcsXG4gICAgXCJoZWlnaHRcIiB8IFwicGFkZGluZ1JpZ2h0XCIgfCBcInBhZGRpbmdUb3BcIiB8IFwidmVydGljYWxMYWJlbHNIZWlnaHRQZXJjZW50YWdlXCJcbiAgPikgPT4gKFxuICAgIDxMaW5lXG4gICAgICBrZXk9XCJ2ZXJ0aWNhbC1saW5lXCJcbiAgICAgIHgxPXtNYXRoLmZsb29yKHBhZGRpbmdSaWdodCl9XG4gICAgICB5MT17MH1cbiAgICAgIHgyPXtNYXRoLmZsb29yKHBhZGRpbmdSaWdodCl9XG4gICAgICB5Mj17aGVpZ2h0ICogdmVydGljYWxMYWJlbHNIZWlnaHRQZXJjZW50YWdlICsgcGFkZGluZ1RvcH1cbiAgICAgIHsuLi50aGlzLmdldFByb3BzRm9yQmFja2dyb3VuZExpbmVzKCl9XG4gICAgLz5cbiAgKTtcblxuICByZW5kZXJEZWZzID0gKFxuICAgIGNvbmZpZzogUGljazxcbiAgICAgIFBhcnRpYWxCeTxcbiAgICAgICAgQWJzdHJhY3RDaGFydENvbmZpZyxcbiAgICAgICAgfCBcImJhY2tncm91bmRHcmFkaWVudEZyb21PcGFjaXR5XCJcbiAgICAgICAgfCBcImJhY2tncm91bmRHcmFkaWVudFRvT3BhY2l0eVwiXG4gICAgICAgIHwgXCJmaWxsU2hhZG93R3JhZGllbnRcIlxuICAgICAgICB8IFwiZmlsbFNoYWRvd0dyYWRpZW50T3BhY2l0eVwiXG4gICAgICAgIHwgXCJmaWxsU2hhZG93R3JhZGllbnRGcm9tXCJcbiAgICAgICAgfCBcImZpbGxTaGFkb3dHcmFkaWVudEZyb21PcGFjaXR5XCJcbiAgICAgICAgfCBcImZpbGxTaGFkb3dHcmFkaWVudEZyb21PZmZzZXRcIlxuICAgICAgICB8IFwiZmlsbFNoYWRvd0dyYWRpZW50VG9cIlxuICAgICAgICB8IFwiZmlsbFNoYWRvd0dyYWRpZW50VG9PcGFjaXR5XCJcbiAgICAgICAgfCBcImZpbGxTaGFkb3dHcmFkaWVudFRvT2Zmc2V0XCJcbiAgICAgID4sXG4gICAgICB8IFwid2lkdGhcIlxuICAgICAgfCBcImhlaWdodFwiXG4gICAgICB8IFwiYmFja2dyb3VuZEdyYWRpZW50RnJvbVwiXG4gICAgICB8IFwiYmFja2dyb3VuZEdyYWRpZW50VG9cIlxuICAgICAgfCBcInVzZVNoYWRvd0NvbG9yRnJvbURhdGFzZXRcIlxuICAgICAgfCBcImRhdGFcIlxuICAgICAgfCBcImJhY2tncm91bmRHcmFkaWVudEZyb21PcGFjaXR5XCJcbiAgICAgIHwgXCJiYWNrZ3JvdW5kR3JhZGllbnRUb09wYWNpdHlcIlxuICAgICAgfCBcImZpbGxTaGFkb3dHcmFkaWVudFwiXG4gICAgICB8IFwiZmlsbFNoYWRvd0dyYWRpZW50T3BhY2l0eVwiXG4gICAgICB8IFwiZmlsbFNoYWRvd0dyYWRpZW50RnJvbVwiXG4gICAgICB8IFwiZmlsbFNoYWRvd0dyYWRpZW50RnJvbU9wYWNpdHlcIlxuICAgICAgfCBcImZpbGxTaGFkb3dHcmFkaWVudEZyb21PZmZzZXRcIlxuICAgICAgfCBcImZpbGxTaGFkb3dHcmFkaWVudFRvXCJcbiAgICAgIHwgXCJmaWxsU2hhZG93R3JhZGllbnRUb09wYWNpdHlcIlxuICAgICAgfCBcImZpbGxTaGFkb3dHcmFkaWVudFRvT2Zmc2V0XCJcbiAgICA+XG4gICkgPT4ge1xuICAgIGNvbnN0IHtcbiAgICAgIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgYmFja2dyb3VuZEdyYWRpZW50RnJvbSxcbiAgICAgIGJhY2tncm91bmRHcmFkaWVudFRvLFxuICAgICAgdXNlU2hhZG93Q29sb3JGcm9tRGF0YXNldCxcbiAgICAgIGRhdGFcbiAgICB9ID0gY29uZmlnO1xuXG4gICAgY29uc3QgZnJvbU9wYWNpdHkgPSBjb25maWcuaGFzT3duUHJvcGVydHkoXCJiYWNrZ3JvdW5kR3JhZGllbnRGcm9tT3BhY2l0eVwiKVxuICAgICAgPyBjb25maWcuYmFja2dyb3VuZEdyYWRpZW50RnJvbU9wYWNpdHlcbiAgICAgIDogMS4wO1xuICAgIGNvbnN0IHRvT3BhY2l0eSA9IGNvbmZpZy5oYXNPd25Qcm9wZXJ0eShcImJhY2tncm91bmRHcmFkaWVudFRvT3BhY2l0eVwiKVxuICAgICAgPyBjb25maWcuYmFja2dyb3VuZEdyYWRpZW50VG9PcGFjaXR5XG4gICAgICA6IDEuMDtcblxuICAgIGNvbnN0IGZpbGxTaGFkb3dHcmFkaWVudCA9IGNvbmZpZy5oYXNPd25Qcm9wZXJ0eShcImZpbGxTaGFkb3dHcmFkaWVudFwiKVxuICAgICAgPyBjb25maWcuZmlsbFNoYWRvd0dyYWRpZW50XG4gICAgICA6IHRoaXMucHJvcHMuY2hhcnRDb25maWcuY29sb3IoMS4wKTtcblxuICAgIGNvbnN0IGZpbGxTaGFkb3dHcmFkaWVudE9wYWNpdHkgPSBjb25maWcuaGFzT3duUHJvcGVydHkoXG4gICAgICBcImZpbGxTaGFkb3dHcmFkaWVudE9wYWNpdHlcIlxuICAgIClcbiAgICAgID8gY29uZmlnLmZpbGxTaGFkb3dHcmFkaWVudE9wYWNpdHlcbiAgICAgIDogMC4xO1xuXG4gICAgY29uc3QgZmlsbFNoYWRvd0dyYWRpZW50RnJvbSA9IGNvbmZpZy5oYXNPd25Qcm9wZXJ0eShcbiAgICAgIFwiZmlsbFNoYWRvd0dyYWRpZW50RnJvbVwiXG4gICAgKVxuICAgICAgPyBjb25maWcuZmlsbFNoYWRvd0dyYWRpZW50RnJvbVxuICAgICAgOiBmaWxsU2hhZG93R3JhZGllbnQ7XG5cbiAgICBjb25zdCBmaWxsU2hhZG93R3JhZGllbnRGcm9tT3BhY2l0eSA9IGNvbmZpZy5oYXNPd25Qcm9wZXJ0eShcbiAgICAgIFwiZmlsbFNoYWRvd0dyYWRpZW50RnJvbU9wYWNpdHlcIlxuICAgIClcbiAgICAgID8gY29uZmlnLmZpbGxTaGFkb3dHcmFkaWVudEZyb21PcGFjaXR5XG4gICAgICA6IGZpbGxTaGFkb3dHcmFkaWVudE9wYWNpdHk7XG5cbiAgICBjb25zdCBmaWxsU2hhZG93R3JhZGllbnRGcm9tT2Zmc2V0ID0gY29uZmlnLmhhc093blByb3BlcnR5KFxuICAgICAgXCJmaWxsU2hhZG93R3JhZGllbnRGcm9tT2Zmc2V0XCJcbiAgICApXG4gICAgICA/IGNvbmZpZy5maWxsU2hhZG93R3JhZGllbnRGcm9tT2Zmc2V0XG4gICAgICA6IDA7XG5cbiAgICBjb25zdCBmaWxsU2hhZG93R3JhZGllbnRUbyA9IGNvbmZpZy5oYXNPd25Qcm9wZXJ0eShcImZpbGxTaGFkb3dHcmFkaWVudFRvXCIpXG4gICAgICA/IGNvbmZpZy5maWxsU2hhZG93R3JhZGllbnRUb1xuICAgICAgOiB0aGlzLnByb3BzLmNoYXJ0Q29uZmlnLmNvbG9yKDEuMCk7XG5cbiAgICBjb25zdCBmaWxsU2hhZG93R3JhZGllbnRUb09wYWNpdHkgPSBjb25maWcuaGFzT3duUHJvcGVydHkoXG4gICAgICBcImZpbGxTaGFkb3dHcmFkaWVudFRvT3BhY2l0eVwiXG4gICAgKVxuICAgICAgPyBjb25maWcuZmlsbFNoYWRvd0dyYWRpZW50VG9PcGFjaXR5XG4gICAgICA6IDAuMTtcblxuICAgIGNvbnN0IGZpbGxTaGFkb3dHcmFkaWVudFRvT2Zmc2V0ID0gY29uZmlnLmhhc093blByb3BlcnR5KFxuICAgICAgXCJmaWxsU2hhZG93R3JhZGllbnRUb09mZnNldFwiXG4gICAgKVxuICAgICAgPyBjb25maWcuZmlsbFNoYWRvd0dyYWRpZW50VG9PZmZzZXRcbiAgICAgIDogMTtcblxuICAgIHJldHVybiAoXG4gICAgICA8RGVmcz5cbiAgICAgICAgPExpbmVhckdyYWRpZW50XG4gICAgICAgICAgaWQ9e3RoaXMuZ2V0R3JhZGllbnRJZChcImJhY2tncm91bmRHcmFkaWVudFwiKX1cbiAgICAgICAgICB4MT17MH1cbiAgICAgICAgICB5MT17aGVpZ2h0fVxuICAgICAgICAgIHgyPXt3aWR0aH1cbiAgICAgICAgICB5Mj17MH1cbiAgICAgICAgICBncmFkaWVudFVuaXRzPVwidXNlclNwYWNlT25Vc2VcIlxuICAgICAgICA+XG4gICAgICAgICAgPFN0b3BcbiAgICAgICAgICAgIG9mZnNldD1cIjBcIlxuICAgICAgICAgICAgc3RvcENvbG9yPXtiYWNrZ3JvdW5kR3JhZGllbnRGcm9tfVxuICAgICAgICAgICAgc3RvcE9wYWNpdHk9e2Zyb21PcGFjaXR5fVxuICAgICAgICAgIC8+XG4gICAgICAgICAgPFN0b3BcbiAgICAgICAgICAgIG9mZnNldD1cIjFcIlxuICAgICAgICAgICAgc3RvcENvbG9yPXtiYWNrZ3JvdW5kR3JhZGllbnRUb31cbiAgICAgICAgICAgIHN0b3BPcGFjaXR5PXt0b09wYWNpdHl9XG4gICAgICAgICAgLz5cbiAgICAgICAgPC9MaW5lYXJHcmFkaWVudD5cbiAgICAgICAge3VzZVNoYWRvd0NvbG9yRnJvbURhdGFzZXQgJiYgZGF0YSA/IChcbiAgICAgICAgICBkYXRhLm1hcCgoZGF0YXNldCwgaW5kZXgpID0+IChcbiAgICAgICAgICAgIDxMaW5lYXJHcmFkaWVudFxuICAgICAgICAgICAgICBpZD17dGhpcy5nZXRHcmFkaWVudElkKGBmaWxsU2hhZG93R3JhZGllbnRGcm9tXyR7aW5kZXh9YCl9XG4gICAgICAgICAgICAgIGtleT17YCR7aW5kZXh9YH1cbiAgICAgICAgICAgICAgeDE9ezB9XG4gICAgICAgICAgICAgIHkxPXswfVxuICAgICAgICAgICAgICB4Mj17MH1cbiAgICAgICAgICAgICAgeTI9e2hlaWdodH1cbiAgICAgICAgICAgICAgZ3JhZGllbnRVbml0cz1cInVzZXJTcGFjZU9uVXNlXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPFN0b3BcbiAgICAgICAgICAgICAgICBvZmZzZXQ9e2ZpbGxTaGFkb3dHcmFkaWVudEZyb21PZmZzZXR9XG4gICAgICAgICAgICAgICAgc3RvcENvbG9yPXtcbiAgICAgICAgICAgICAgICAgIGRhdGFzZXQuY29sb3IgPyBkYXRhc2V0LmNvbG9yKDEuMCkgOiBmaWxsU2hhZG93R3JhZGllbnRGcm9tXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN0b3BPcGFjaXR5PXtmaWxsU2hhZG93R3JhZGllbnRGcm9tT3BhY2l0eX1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPFN0b3BcbiAgICAgICAgICAgICAgICBvZmZzZXQ9e2ZpbGxTaGFkb3dHcmFkaWVudFRvT2Zmc2V0fVxuICAgICAgICAgICAgICAgIHN0b3BDb2xvcj17XG4gICAgICAgICAgICAgICAgICBkYXRhc2V0LmNvbG9yXG4gICAgICAgICAgICAgICAgICAgID8gZGF0YXNldC5jb2xvcihmaWxsU2hhZG93R3JhZGllbnRGcm9tT3BhY2l0eSlcbiAgICAgICAgICAgICAgICAgICAgOiBmaWxsU2hhZG93R3JhZGllbnRGcm9tXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN0b3BPcGFjaXR5PXtmaWxsU2hhZG93R3JhZGllbnRUb09wYWNpdHkgfHwgMH1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDwvTGluZWFyR3JhZGllbnQ+XG4gICAgICAgICAgKSlcbiAgICAgICAgKSA6IChcbiAgICAgICAgICA8TGluZWFyR3JhZGllbnRcbiAgICAgICAgICAgIGlkPXt0aGlzLmdldEdyYWRpZW50SWQoXCJmaWxsU2hhZG93R3JhZGllbnRGcm9tXCIpfVxuICAgICAgICAgICAgeDE9ezB9XG4gICAgICAgICAgICB5MT17MH1cbiAgICAgICAgICAgIHgyPXswfVxuICAgICAgICAgICAgeTI9e2hlaWdodH1cbiAgICAgICAgICAgIGdyYWRpZW50VW5pdHM9XCJ1c2VyU3BhY2VPblVzZVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPFN0b3BcbiAgICAgICAgICAgICAgb2Zmc2V0PXtmaWxsU2hhZG93R3JhZGllbnRGcm9tT2Zmc2V0fVxuICAgICAgICAgICAgICBzdG9wQ29sb3I9e2ZpbGxTaGFkb3dHcmFkaWVudEZyb219XG4gICAgICAgICAgICAgIHN0b3BPcGFjaXR5PXtmaWxsU2hhZG93R3JhZGllbnRGcm9tT3BhY2l0eX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8U3RvcFxuICAgICAgICAgICAgICBvZmZzZXQ9e2ZpbGxTaGFkb3dHcmFkaWVudFRvT2Zmc2V0fVxuICAgICAgICAgICAgICBzdG9wQ29sb3I9e2ZpbGxTaGFkb3dHcmFkaWVudFRvIHx8IGZpbGxTaGFkb3dHcmFkaWVudEZyb219XG4gICAgICAgICAgICAgIHN0b3BPcGFjaXR5PXtmaWxsU2hhZG93R3JhZGllbnRUb09wYWNpdHkgfHwgMH1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9MaW5lYXJHcmFkaWVudD5cbiAgICAgICAgKX1cbiAgICAgIDwvRGVmcz5cbiAgICApO1xuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBBYnN0cmFjdENoYXJ0O1xuIl19