kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
1,538 lines • 213 kB
JavaScript
"use strict";
var _typeof3 = require("@babel/runtime/helpers/typeof");
var _regeneratorRuntime2 = require("@babel/runtime/regenerator");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.layerColors = exports.defaultGetFieldValue = exports["default"] = exports.colorMaker = exports.OVERLAY_TYPE_CONST = exports.LAYER_ID_LENGTH = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _core = require("@deck.gl/core");
var _deckglArrowLayers = require("@kepler.gl/deckgl-arrow-layers");
var _extensions = require("@deck.gl/extensions");
var _layers = require("@deck.gl/layers");
var _window = require("global/window");
var _keymirror = _interopRequireDefault(require("keymirror"));
var arrow = _interopRequireWildcard(require("apache-arrow"));
var _defaultLayerIcon = _interopRequireDefault(require("./default-layer-icon"));
var _layerUpdate = require("./layer-update");
var _layerUtils = require("./layer-utils");
var _constants = require("@kepler.gl/constants");
var _utils = require("@kepler.gl/utils");
var _commonUtils = require("@kepler.gl/common-utils");
var _lodash = _interopRequireDefault(require("lodash.memoize"));
var _getApplicationConfig; // 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" != _typeof3(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 _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
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 _marked = /*#__PURE__*/_regeneratorRuntime2.mark(generateColor);
/**
* Approx. number of points to sample in a large data set
*/
var LAYER_ID_LENGTH = exports.LAYER_ID_LENGTH = 6;
var MAX_SAMPLE_SIZE = 5000;
var defaultDomain = [0, 1];
var dataFilterExtension = new _extensions.DataFilterExtension({
filterSize: _constants.MAX_GPU_FILTERS,
// `countItems` option. It enables the GPU to report the number of objects that pass the filter criteria via the `onFilteredItemsChange` callback.
// @ts-expect-error not typed
countItems: (_getApplicationConfig = (0, _utils.getApplicationConfig)().useOnFilteredItemsChange) !== null && _getApplicationConfig !== void 0 ? _getApplicationConfig : false
});
// eslint-disable-next-line @typescript-eslint/no-unused-vars
var defaultDataAccessor = function defaultDataAccessor(dc) {
return function (d) {
return d;
};
};
var identity = function identity(d) {
return d;
};
// Can't use fiedValueAccesor because need the raw data to render tooltip
// SHAN: Revisit here
var defaultGetFieldValue = exports.defaultGetFieldValue = function defaultGetFieldValue(field, d) {
return field.valueAccessor(d);
};
var OVERLAY_TYPE_CONST = exports.OVERLAY_TYPE_CONST = (0, _keymirror["default"])({
deckgl: null,
mapboxgl: null
});
var layerColors = exports.layerColors = Object.values(_constants.DataVizColors).map(_utils.hexToRgb);
function generateColor() {
var index;
return _regenerator["default"].wrap(function generateColor$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
index = 0;
case 1:
if (!(index < layerColors.length + 1)) {
_context.next = 7;
break;
}
if (index === layerColors.length) {
index = 0;
}
_context.next = 5;
return layerColors[index++];
case 5:
_context.next = 1;
break;
case 7:
case "end":
return _context.stop();
}
}, _marked);
}
var colorMaker = exports.colorMaker = generateColor();
var Layer = /*#__PURE__*/function () {
function Layer(props) {
(0, _classCallCheck2["default"])(this, Layer);
(0, _defineProperty2["default"])(this, "id", void 0);
(0, _defineProperty2["default"])(this, "meta", void 0);
(0, _defineProperty2["default"])(this, "visConfigSettings", void 0);
(0, _defineProperty2["default"])(this, "config", void 0);
// TODO: define _oldDataUpdateTriggers
(0, _defineProperty2["default"])(this, "_oldDataUpdateTriggers", void 0);
(0, _defineProperty2["default"])(this, "isValid", void 0);
(0, _defineProperty2["default"])(this, "errorMessage", void 0);
(0, _defineProperty2["default"])(this, "filteredItemCount", void 0);
this.id = props.id || (0, _commonUtils.generateHashId)(LAYER_ID_LENGTH);
// meta
this.meta = {};
// visConfigSettings
this.visConfigSettings = {};
this.config = this.getDefaultLayerConfig(props);
// set columnMode from supported columns
if (!this.config.columnMode) {
var supportedColumnModes = this.supportedColumnModes;
if (supportedColumnModes !== null && supportedColumnModes !== void 0 && supportedColumnModes.length) {
var _supportedColumnModes;
this.config.columnMode = (_supportedColumnModes = supportedColumnModes[0]) === null || _supportedColumnModes === void 0 ? void 0 : _supportedColumnModes.key;
}
}
// then set column, columnMode should already been set
this.config.columns = this.getLayerColumns(props.columns);
// false indicates that the layer caused an error, and was disabled
this.isValid = true;
this.errorMessage = null;
// item count
this.filteredItemCount = {};
}
return (0, _createClass2["default"])(Layer, [{
key: "layerIcon",
get: function get() {
return _defaultLayerIcon["default"];
}
}, {
key: "overlayType",
get: function get() {
return OVERLAY_TYPE_CONST.deckgl;
}
}, {
key: "type",
get: function get() {
return null;
}
}, {
key: "name",
get: function get() {
return this.type;
}
}, {
key: "isAggregated",
get: function get() {
return false;
}
}, {
key: "requiredLayerColumns",
get: function get() {
var supportedColumnModes = this.supportedColumnModes;
if (supportedColumnModes) {
return supportedColumnModes.reduce(function (acc, obj) {
return obj.requiredColumns ? acc.concat(obj.requiredColumns) : acc;
}, []);
}
return [];
}
}, {
key: "optionalColumns",
get: function get() {
var supportedColumnModes = this.supportedColumnModes;
if (supportedColumnModes) {
return supportedColumnModes.reduce(function (acc, obj) {
return obj.optionalColumns ? acc.concat(obj.optionalColumns) : acc;
}, []);
}
return [];
}
}, {
key: "noneLayerDataAffectingProps",
get: function get() {
return ['label', 'opacity', 'thickness', 'isVisible', 'hidden'];
}
}, {
key: "visualChannels",
get: function get() {
return {
color: {
property: 'color',
field: 'colorField',
scale: 'colorScale',
domain: 'colorDomain',
range: 'colorRange',
key: 'color',
channelScaleType: _constants.CHANNEL_SCALES.color,
nullValue: _constants.NO_VALUE_COLOR,
defaultValue: function defaultValue(config) {
return config.color;
}
},
size: {
property: 'size',
field: 'sizeField',
scale: 'sizeScale',
domain: 'sizeDomain',
range: 'sizeRange',
key: 'size',
channelScaleType: _constants.CHANNEL_SCALES.size,
nullValue: 0,
defaultValue: 1
}
};
}
}, {
key: "columnValidators",
get: function get() {
return {};
}
/*
* Column pairs maps layer column to a specific field pairs,
* By default, it is set to null
*/
}, {
key: "columnPairs",
get: function get() {
return null;
}
/**
* Column labels if its different than column key
*/
}, {
key: "columnLabels",
get: function get() {
return null;
}
/*
* Default point column pairs, can be used for point based layers: point, icon etc.
*/
}, {
key: "defaultPointColumnPairs",
get: function get() {
return {
lat: {
pair: ['lng', 'altitude'],
fieldPairKey: 'lat'
},
lng: {
pair: ['lat', 'altitude'],
fieldPairKey: 'lng'
},
altitude: {
pair: ['lng', 'lat'],
fieldPairKey: 'altitude'
}
};
}
/*
* Default link column pairs, can be used for link based layers: arc, line etc
*/
}, {
key: "defaultLinkColumnPairs",
get: function get() {
return {
lat: {
pair: ['lng', 'alt'],
fieldPairKey: 'lat'
},
lng: {
pair: ['lat', 'alt'],
fieldPairKey: 'lng'
},
alt: {
pair: ['lng', 'lat'],
fieldPairKey: 'altitude'
},
lat0: {
pair: 'lng0',
fieldPairKey: 'lat'
},
lng0: {
pair: 'lat0',
fieldPairKey: 'lng'
},
alt0: {
pair: ['lng0', 'lat0'],
fieldPairKey: 'altitude'
},
lat1: {
pair: 'lng1',
fieldPairKey: 'lat'
},
lng1: {
pair: 'lat1',
fieldPairKey: 'lng'
},
alt1: {
pair: ['lng1', 'lat1'],
fieldPairKey: 'altitude'
}
};
}
/**
* Return a React component for to render layer instructions in a modal
* @returns {object} - an object
* @example
* return {
* id: 'iconInfo',
* template: IconInfoModal,
* modalProps: {
* title: 'How to draw icons'
* };
* }
*/
}, {
key: "layerInfoModal",
get: function get() {
return null;
}
/**
* Returns which column modes this layer supports
*/
}, {
key: "supportedColumnModes",
get: function get() {
return null;
}
}, {
key: "supportedDatasetTypes",
get: function get() {
return null;
}
/*
* Given a dataset, automatically find props to create layer based on it
* and return the props and previous found layers.
* By default, no layers will be found
*/
}, {
key: "getDefaultLayerConfig",
value: function getDefaultLayerConfig(props) {
var _props$isVisible, _props$isConfigActive, _props$hidden;
return _objectSpread({
dataId: props.dataId,
label: props.label || _constants.DEFAULT_LAYER_LABEL,
color: props.color || colorMaker.next().value,
// set columns later
columns: {},
isVisible: (_props$isVisible = props.isVisible) !== null && _props$isVisible !== void 0 ? _props$isVisible : true,
isConfigActive: (_props$isConfigActive = props.isConfigActive) !== null && _props$isConfigActive !== void 0 ? _props$isConfigActive : false,
highlightColor: props.highlightColor || _constants.DEFAULT_HIGHLIGHT_COLOR,
hidden: (_props$hidden = props.hidden) !== null && _props$hidden !== void 0 ? _props$hidden : false,
// TODO: refactor this into separate visual Channel config
// color by field, domain is set by filters, field, scale type
colorField: null,
colorDomain: [0, 1],
colorScale: _constants.SCALE_TYPES.quantile,
// color by size, domain is set by filters, field, scale type
sizeDomain: [0, 1],
sizeScale: _constants.SCALE_TYPES.linear,
sizeField: null,
visConfig: {},
textLabel: [_constants.DEFAULT_TEXT_LABEL],
colorUI: {
color: _constants.DEFAULT_COLOR_UI,
colorRange: _constants.DEFAULT_COLOR_UI
},
animation: {
enabled: false
}
}, props.columnMode ? {
columnMode: props.columnMode
} : {});
}
/**
* Get the description of a visualChannel config
* @param key
* @returns
*/
}, {
key: "getVisualChannelDescription",
value: function getVisualChannelDescription(key) {
// e.g. label: Color, measure: Vehicle Type
var channel = this.visualChannels[key];
if (!channel) return {
label: '',
measure: undefined
};
var rangeSettings = this.visConfigSettings[channel.range];
var fieldSettings = this.config[channel.field];
var label = rangeSettings === null || rangeSettings === void 0 ? void 0 : rangeSettings.label;
return {
label: typeof label === 'function' ? label(this.config) : label || '',
measure: fieldSettings ? fieldSettings.displayName || fieldSettings.name : channel.defaultMeasure
};
}
/**
* Assign a field to layer column, return column config
*/
}, {
key: "assignColumn",
value: function assignColumn(key, field) {
var _this$config$columns;
// field value could be null for optional columns
var update = field ? {
value: field.name,
fieldIdx: field.fieldIdx
} : {
value: null,
fieldIdx: -1
};
return _objectSpread(_objectSpread({}, this.config.columns), {}, (0, _defineProperty2["default"])({}, key, _objectSpread(_objectSpread({}, (_this$config$columns = this.config.columns) === null || _this$config$columns === void 0 ? void 0 : _this$config$columns[key]), update)));
}
/**
* Assign a field pair to column config, return column config
*/
}, {
key: "assignColumnPairs",
value: function assignColumnPairs(key, fieldPairs) {
var _this$columnPairs, _this$columnPairs2;
if (!this.columnPairs || !((_this$columnPairs = this.columnPairs) !== null && _this$columnPairs !== void 0 && _this$columnPairs[key])) {
// should not end in this state
return this.config.columns;
}
// key = 'lat'
var _ref = ((_this$columnPairs2 = this.columnPairs) === null || _this$columnPairs2 === void 0 ? void 0 : _this$columnPairs2[key]) || {},
pair = _ref.pair,
fieldPairKey = _ref.fieldPairKey;
if (typeof fieldPairKey === 'string' && !fieldPairs[fieldPairKey]) {
// do not allow `key: undefined` to creep into the `updatedColumn` object
return this.config.columns;
}
// pair = ['lng', 'alt] | 'lng'
var updatedColumn = _objectSpread(_objectSpread({}, this.config.columns), {}, (0, _defineProperty2["default"])({}, key, fieldPairs[fieldPairKey]));
var partnerKeys = (0, _commonUtils.toArray)(pair);
var _iterator = _createForOfIteratorHelper(partnerKeys),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var _this$columnPairs3, _this$columnPairs4;
var partnerKey = _step.value;
if (this.config.columns[partnerKey] && (_this$columnPairs3 = this.columnPairs) !== null && _this$columnPairs3 !== void 0 && _this$columnPairs3[partnerKey] &&
// @ts-ignore
fieldPairs[(_this$columnPairs4 = this.columnPairs) === null || _this$columnPairs4 === void 0 ? void 0 : _this$columnPairs4[partnerKey].fieldPairKey]) {
var _this$columnPairs5;
// @ts-ignore
updatedColumn[partnerKey] = fieldPairs[(_this$columnPairs5 = this.columnPairs) === null || _this$columnPairs5 === void 0 ? void 0 : _this$columnPairs5[partnerKey].fieldPairKey];
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return updatedColumn;
}
/**
* Calculate a radius zoom multiplier to render points, so they are visible in all zoom level
* @param {object} mapState
* @param {number} mapState.zoom - actual zoom
* @param {number | void} mapState.zoomOffset - zoomOffset when render in the plot container for export image
* @returns {number}
*/
}, {
key: "getZoomFactor",
value: function getZoomFactor(_ref2) {
var zoom = _ref2.zoom,
_ref2$zoomOffset = _ref2.zoomOffset,
zoomOffset = _ref2$zoomOffset === void 0 ? 0 : _ref2$zoomOffset;
return Math.pow(2, Math.max(14 - zoom + zoomOffset, 0));
}
/**
* Calculate a elevation zoom multiplier to render points, so they are visible in all zoom level
* @param {object} mapState
* @param {number} mapState.zoom - actual zoom
* @param {number=} mapState.zoomOffset - zoomOffset when render in the plot container for export image
* @returns {number}
*/
}, {
key: "getElevationZoomFactor",
value: function getElevationZoomFactor(_ref3) {
var zoom = _ref3.zoom,
_ref3$zoomOffset = _ref3.zoomOffset,
zoomOffset = _ref3$zoomOffset === void 0 ? 0 : _ref3$zoomOffset;
// enableElevationZoomFactor is used to support existing maps
var _this$config$visConfi = this.config.visConfig,
fixedHeight = _this$config$visConfi.fixedHeight,
enableElevationZoomFactor = _this$config$visConfi.enableElevationZoomFactor;
return fixedHeight || enableElevationZoomFactor === false ? 1 : Math.pow(2, Math.max(8 - zoom + zoomOffset, 0));
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
}, {
key: "formatLayerData",
value: function formatLayerData(datasets, oldLayerData, animationConfig) {
return {};
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
}, {
key: "renderLayer",
value: function renderLayer() {
return [];
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
}, {
key: "getHoverData",
value: function getHoverData(object, dataContainer,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
fields,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
animationConfig,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
hoverInfo) {
if (!object) {
return null;
}
// By default, each entry of layerData should have an index of a row in the original data container.
// Each layer can implement its own getHoverData method
return dataContainer.row(object.index);
}
}, {
key: "getFilteredItemCount",
value: function getFilteredItemCount() {
// use first layer
if (Object.keys(this.filteredItemCount).length) {
var firstLayer = Object.keys(this.filteredItemCount)[0];
return this.filteredItemCount[firstLayer];
}
return null;
}
/**
* When change layer type, try to copy over layer configs as much as possible
* @param configToCopy - config to copy over
* @param visConfigSettings - visConfig settings of config to copy
* @param datasets - current datasets.
* @param defaultLayerProps - default layer creation configurations for current layer and datasets.
*/
}, {
key: "assignConfigToLayer",
value: function assignConfigToLayer(configToCopy, visConfigSettings, datasets, defaultLayerProps) {
var _this = this;
// don't deep merge visualChannel field
// don't deep merge color range, reversed: is not a key by default
var shallowCopy = ['colorRange', 'strokeColorRange'].concat(Object.values(this.visualChannels).map(function (v) {
return v.field;
}));
// don't copy over domain and animation
var notToCopy = ['animation'].concat(Object.values(this.visualChannels).map(function (v) {
return v.domain;
}));
// if range is for the same property group copy it, otherwise, not to copy
Object.values(this.visualChannels).forEach(function (v) {
if (configToCopy.visConfig[v.range] && _this.visConfigSettings[v.range] && visConfigSettings[v.range].group !== _this.visConfigSettings[v.range].group) {
notToCopy.push(v.range);
}
});
// don't copy over visualChannel range
var currentConfig = this.config;
var copied = this.copyLayerConfig(currentConfig, configToCopy, {
shallowCopy: shallowCopy,
notToCopy: notToCopy
});
// update columNode based on new columns
if (this.config.columnMode && this.supportedColumnModes) {
var _satisfiedColumnMode;
var dataset = datasets === null || datasets === void 0 ? void 0 : datasets[this.config.dataId];
// try to find a mode with all requied columns from the source config
var satisfiedColumnMode = (0, _layerUtils.getSatisfiedColumnMode)(this.supportedColumnModes, copied.columns, dataset === null || dataset === void 0 ? void 0 : dataset.fields);
// if no suitable column mode found or no such columMode exists for the layer
// then try use one of the automatically detected layer configs
if (!satisfiedColumnMode) {
var options = [].concat((0, _toConsumableArray2["default"])((defaultLayerProps === null || defaultLayerProps === void 0 ? void 0 : defaultLayerProps.props) || []), (0, _toConsumableArray2["default"])((defaultLayerProps === null || defaultLayerProps === void 0 ? void 0 : defaultLayerProps.altProps) || []));
if (options.length) {
// Use the first of the default configurations
var defaultColumnConfig = options[0].columns;
satisfiedColumnMode = (0, _layerUtils.getSatisfiedColumnMode)(this.supportedColumnModes, defaultColumnConfig, dataset === null || dataset === void 0 ? void 0 : dataset.fields);
if (satisfiedColumnMode) {
copied.columns = _objectSpread(_objectSpread({}, copied.columns), defaultColumnConfig);
}
}
}
copied.columnMode = ((_satisfiedColumnMode = satisfiedColumnMode) === null || _satisfiedColumnMode === void 0 ? void 0 : _satisfiedColumnMode.key) || copied.columnMode;
}
this.updateLayerConfig(copied);
// validate visualChannel field type and scale types
Object.keys(this.visualChannels).forEach(function (channel) {
_this.validateVisualChannel(channel);
});
}
/*
* Recursively copy config over to an empty layer
* when received saved config, or copy config over from a different layer type
* make sure to only copy over value to existing keys
* @param {object} currentConfig - existing config to be override
* @param {object} configToCopy - new Config to copy over
* @param {string[]} shallowCopy - array of properties to not to be deep copied
* @param {string[]} notToCopy - array of properties not to copy
* @returns {object} - copied config
*/
}, {
key: "copyLayerConfig",
value: function copyLayerConfig(currentConfig, configToCopy) {
var _this2 = this;
var _ref4 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
_ref4$shallowCopy = _ref4.shallowCopy,
shallowCopy = _ref4$shallowCopy === void 0 ? [] : _ref4$shallowCopy,
_ref4$notToCopy = _ref4.notToCopy,
notToCopy = _ref4$notToCopy === void 0 ? [] : _ref4$notToCopy;
var copied = {};
Object.keys(currentConfig).forEach(function (key) {
if ((0, _utils.isPlainObject)(currentConfig[key]) && (0, _utils.isPlainObject)(configToCopy[key]) && !shallowCopy.includes(key) && !notToCopy.includes(key)) {
// recursively assign object value
copied[key] = _this2.copyLayerConfig(currentConfig[key], configToCopy[key], {
shallowCopy: shallowCopy,
notToCopy: notToCopy
});
} else if ((0, _commonUtils.notNullorUndefined)(configToCopy[key]) && !notToCopy.includes(key)) {
// copy
copied[key] = configToCopy[key];
} else {
// keep existing
copied[key] = currentConfig[key];
}
});
return copied;
}
}, {
key: "registerVisConfig",
value: function registerVisConfig(layerVisConfigs) {
var _this3 = this;
Object.keys(layerVisConfigs).forEach(function (item) {
var configItem = layerVisConfigs[item];
if (typeof configItem === 'string' && _constants.LAYER_VIS_CONFIGS[configItem]) {
// if assigned one of default LAYER_CONFIGS
_this3.config.visConfig[item] = _constants.LAYER_VIS_CONFIGS[configItem].defaultValue;
_this3.visConfigSettings[item] = _constants.LAYER_VIS_CONFIGS[configItem];
} else if ((0, _typeof2["default"])(configItem) === 'object' && ['type', 'defaultValue'].every(function (p) {
return Object.prototype.hasOwnProperty.call(configItem, p);
})) {
// if provided customized visConfig, and has type && defaultValue
// TODO: further check if customized visConfig is valid
_this3.config.visConfig[item] = configItem.defaultValue;
_this3.visConfigSettings[item] = configItem;
}
});
}
}, {
key: "getLayerColumns",
value: function getLayerColumns() {
var propsColumns = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var columnValidators = this.columnValidators || {};
var required = this.requiredLayerColumns.reduce(function (accu, key) {
var _propsColumns$key$val, _propsColumns$key, _propsColumns$key$fie, _propsColumns$key2, _propsColumns$key$val2, _propsColumns$key3, _propsColumns$key$fie2, _propsColumns$key4;
return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, key, columnValidators[key] ? {
value: (_propsColumns$key$val = (_propsColumns$key = propsColumns[key]) === null || _propsColumns$key === void 0 ? void 0 : _propsColumns$key.value) !== null && _propsColumns$key$val !== void 0 ? _propsColumns$key$val : null,
fieldIdx: (_propsColumns$key$fie = (_propsColumns$key2 = propsColumns[key]) === null || _propsColumns$key2 === void 0 ? void 0 : _propsColumns$key2.fieldIdx) !== null && _propsColumns$key$fie !== void 0 ? _propsColumns$key$fie : -1,
validator: columnValidators[key]
} : {
value: (_propsColumns$key$val2 = (_propsColumns$key3 = propsColumns[key]) === null || _propsColumns$key3 === void 0 ? void 0 : _propsColumns$key3.value) !== null && _propsColumns$key$val2 !== void 0 ? _propsColumns$key$val2 : null,
fieldIdx: (_propsColumns$key$fie2 = (_propsColumns$key4 = propsColumns[key]) === null || _propsColumns$key4 === void 0 ? void 0 : _propsColumns$key4.fieldIdx) !== null && _propsColumns$key$fie2 !== void 0 ? _propsColumns$key$fie2 : -1
}));
}, {});
var optional = this.optionalColumns.reduce(function (accu, key) {
var _propsColumns$key$val3, _propsColumns$key5, _propsColumns$key$fie3, _propsColumns$key6;
return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, key, {
value: (_propsColumns$key$val3 = (_propsColumns$key5 = propsColumns[key]) === null || _propsColumns$key5 === void 0 ? void 0 : _propsColumns$key5.value) !== null && _propsColumns$key$val3 !== void 0 ? _propsColumns$key$val3 : null,
fieldIdx: (_propsColumns$key$fie3 = (_propsColumns$key6 = propsColumns[key]) === null || _propsColumns$key6 === void 0 ? void 0 : _propsColumns$key6.fieldIdx) !== null && _propsColumns$key$fie3 !== void 0 ? _propsColumns$key$fie3 : -1,
optional: true
}));
}, {});
var columns = _objectSpread(_objectSpread({}, required), optional);
return columns;
}
}, {
key: "updateLayerConfig",
value: function updateLayerConfig(newConfig) {
this.config = _objectSpread(_objectSpread({}, this.config), newConfig);
return this;
}
}, {
key: "updateLayerVisConfig",
value: function updateLayerVisConfig(newVisConfig) {
this.config.visConfig = _objectSpread(_objectSpread({}, this.config.visConfig), newVisConfig);
return this;
}
}, {
key: "updateLayerColorUI",
value: function updateLayerColorUI(prop, newConfig) {
var _this$config = this.config,
previous = _this$config.colorUI,
visConfig = _this$config.visConfig;
if (!(0, _utils.isPlainObject)(newConfig) || typeof prop !== 'string') {
return this;
}
var colorUIProp = Object.entries(newConfig).reduce(function (accu, _ref5) {
var _ref6 = (0, _slicedToArray2["default"])(_ref5, 2),
key = _ref6[0],
value = _ref6[1];
return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, key, (0, _utils.isPlainObject)(accu[key]) && (0, _utils.isPlainObject)(value) ? _objectSpread(_objectSpread({}, accu[key]), value) : value));
}, previous[prop] || _constants.DEFAULT_COLOR_UI);
var colorUI = _objectSpread(_objectSpread({}, previous), {}, (0, _defineProperty2["default"])({}, prop, colorUIProp));
this.updateLayerConfig({
colorUI: colorUI
});
// if colorUI[prop] is colorRange
var isColorRange = visConfig[prop] && visConfig[prop].colors;
if (isColorRange) {
// if open dropdown and prop is color range
// Automatically set colorRangeConfig's step and reversed
this.updateColorUIByColorRange(newConfig, prop);
// if changes in UI is made to 'reversed', 'steps' or steps
// update current layer colorRange
this.updateColorRangeByColorUI(newConfig, previous, prop);
// if set colorRangeConfig to custom
// initiate customPalette to be edited in the ui
this.updateCustomPalette(newConfig, previous, prop);
}
return this;
}
// if set colorRangeConfig to custom palette or custom breaks
// initiate customPalette to be edited in the ui
}, {
key: "updateCustomPalette",
value: function updateCustomPalette(newConfig, previous, prop) {
var _newConfig$colorRange, _newConfig$colorRange2;
if (!((_newConfig$colorRange = newConfig.colorRangeConfig) !== null && _newConfig$colorRange !== void 0 && _newConfig$colorRange.custom) && !((_newConfig$colorRange2 = newConfig.colorRangeConfig) !== null && _newConfig$colorRange2 !== void 0 && _newConfig$colorRange2.customBreaks)) {
return;
}
if (newConfig.customPalette) {
// if new config also set customPalette, no need to initiate new
return;
}
var _this$config2 = this.config,
colorUI = _this$config2.colorUI,
visConfig = _this$config2.visConfig;
if (!visConfig[prop]) return;
// make copy of current color range to customPalette
var customPalette = _objectSpread({}, visConfig[prop]);
if (newConfig.colorRangeConfig.customBreaks && !customPalette.colorMap) {
// find visualChanel
var visualChannels = this.visualChannels;
var channelKey = Object.keys(visualChannels).find(function (key) {
return visualChannels[key].range === prop;
});
if (!channelKey) {
// should never happn
_window.console.warn("updateColorUI: Can't find visual channel which range is ".concat(prop));
return;
}
// add name|type|category to updateCustomPalette if customBreaks, so that
// colors will not be override as well when inverse palette with custom break
// initiate colorMap from current scale
var colorMap = (0, _utils.initializeLayerColorMap)(this, visualChannels[channelKey]);
customPalette = (0, _utils.initializeCustomPalette)(visConfig[prop], colorMap);
} else if (newConfig.colorRangeConfig.custom) {
customPalette = (0, _utils.initializeCustomPalette)(visConfig[prop]);
}
this.updateLayerConfig({
colorUI: _objectSpread(_objectSpread({}, colorUI), {}, (0, _defineProperty2["default"])({}, prop, _objectSpread(_objectSpread({}, colorUI[prop]), {}, {
customPalette: customPalette
})))
});
}
/**
* if open dropdown and prop is color range
* Automatically set colorRangeConfig's step and reversed
* @param {*} newConfig
* @param {*} prop
*/
}, {
key: "updateColorUIByColorRange",
value: function updateColorUIByColorRange(newConfig, prop) {
var _newConfig$customPale;
var _this$config3 = this.config,
colorUI = _this$config3.colorUI,
visConfig = _this$config3.visConfig;
// when custom palette adds/removes step, the number in "Steps" input control
// should be updated as well
var isCustom = ((_newConfig$customPale = newConfig.customPalette) === null || _newConfig$customPale === void 0 ? void 0 : _newConfig$customPale.category) === 'Custom';
var customStepsChanged = isCustom ? newConfig.customPalette.colors.length !== visConfig[prop].colors.length : false;
if (typeof newConfig.showDropdown !== 'number' && !customStepsChanged) return;
this.updateLayerConfig({
colorUI: _objectSpread(_objectSpread({}, colorUI), {}, (0, _defineProperty2["default"])({}, prop, _objectSpread(_objectSpread({}, colorUI[prop]), {}, {
colorRangeConfig: _objectSpread(_objectSpread({}, colorUI[prop].colorRangeConfig), {}, {
steps: customStepsChanged ? colorUI[prop].customPalette.colors.length : visConfig[prop].colors.length,
reversed: Boolean(visConfig[prop].reversed)
})
})))
});
}
}, {
key: "updateColorRangeByColorUI",
value: function updateColorRangeByColorUI(newConfig, previous, prop) {
// only update colorRange if changes in UI is made to 'reversed', 'steps' or steps
var shouldUpdate = newConfig.colorRangeConfig && ['reversed', 'steps', 'colorBlindSafe', 'type'].some(function (key) {
return Object.prototype.hasOwnProperty.call(newConfig.colorRangeConfig, key) && newConfig.colorRangeConfig[key] !== (previous[prop] || _constants.DEFAULT_COLOR_UI).colorRangeConfig[key];
});
if (!shouldUpdate) return;
var _this$config4 = this.config,
colorUI = _this$config4.colorUI,
visConfig = _this$config4.visConfig;
// for custom palette, one can only 'reverse' the colors in custom palette.
// changing 'steps', 'colorBindSafe', 'type' should fall back to predefined palette.
var isCustomColorReversed = visConfig.colorRange.category === 'Custom' && newConfig.colorRangeConfig && Object.prototype.hasOwnProperty.call(newConfig.colorRangeConfig, 'reversed');
var update = isCustomColorReversed ? (0, _utils.updateCustomColorRangeByColorUI)(visConfig[prop], colorUI[prop].colorRangeConfig) : (0, _utils.updateColorRangeByMatchingPalette)(visConfig[prop], colorUI[prop].colorRangeConfig);
if (update) {
this.updateLayerVisConfig((0, _defineProperty2["default"])({}, prop, update));
}
}
}, {
key: "hasColumnValue",
value: function hasColumnValue(column) {
return Boolean(column && column.value && column.fieldIdx > -1);
}
}, {
key: "hasRequiredColumn",
value: function hasRequiredColumn(column) {
return Boolean(column && (column.optional || this.hasColumnValue(column)));
}
/**
* Check whether layer has all columns
* @returns yes or no
*/
}, {
key: "hasAllColumns",
value: function hasAllColumns() {
var _this4 = this;
var _this$config5 = this.config,
columns = _this$config5.columns,
columnMode = _this$config5.columnMode;
// if layer has different column mode, check if have all required columns of current column Mode
if (columnMode) {
var _currentColumnModes$r;
var currentColumnModes = (this.supportedColumnModes || []).find(function (colMode) {
return colMode.key === columnMode;
});
return Boolean(currentColumnModes !== undefined && ((_currentColumnModes$r = currentColumnModes.requiredColumns) === null || _currentColumnModes$r === void 0 ? void 0 : _currentColumnModes$r.every(function (colKey) {
return _this4.hasColumnValue(columns[colKey]);
})));
}
return Boolean(columns && Object.values(columns).every(function (column) {
return _this4.hasRequiredColumn(column);
}));
}
/**
* Check whether layer has data
*
* @param {Array | Object} layerData
* @returns {boolean} yes or no
*/
}, {
key: "hasLayerData",
value: function hasLayerData(layerData) {
if (!layerData) {
return false;
}
return Boolean(layerData.data && (layerData.data.length || layerData.data.numRows));
}
}, {
key: "isValidToSave",
value: function isValidToSave() {
return Boolean(this.type && this.hasAllColumns());
}
}, {
key: "shouldRenderLayer",
value: function shouldRenderLayer(data) {
return Boolean(this.type) && this.hasAllColumns() && this.hasLayerData(data) && typeof this.renderLayer === 'function';
}
}, {
key: "getColorScale",
value: function getColorScale(colorScale, colorDomain, colorRange) {
if (colorScale === _constants.SCALE_TYPES.customOrdinal) {
return (0, _utils.getCategoricalColorScale)(colorDomain, colorRange);
}
if ((0, _utils.hasColorMap)(colorRange) && colorScale === _constants.SCALE_TYPES.custom) {
var _colorRange$colorMap;
var cMap = new Map();
(_colorRange$colorMap = colorRange.colorMap) === null || _colorRange$colorMap === void 0 || _colorRange$colorMap.forEach(function (_ref7) {
var _ref8 = (0, _slicedToArray2["default"])(_ref7, 2),
k = _ref8[0],
v = _ref8[1];
cMap.set(k, typeof v === 'string' ? (0, _utils.hexToRgb)(v) : v);
});
var scaleType = colorScale === _constants.SCALE_TYPES.custom ? colorScale : _constants.SCALE_TYPES.ordinal;
var scale = (0, _utils.getScaleFunction)(scaleType, cMap.values(), cMap.keys(), false);
scale.unknown(cMap.get(_constants.UNKNOWN_COLOR_KEY) || _constants.NO_VALUE_COLOR);
return scale;
}
return this.getVisChannelScale(colorScale, colorDomain, colorRange.colors.map(_utils.hexToRgb));
}
}, {
key: "accessVSFieldValue",
value: function accessVSFieldValue(_field, _indexKey) {
return defaultGetFieldValue;
}
/**
* Mapping from visual channels to deck.gl accesors
* @param param Parameters
* @param param.dataAccessor Access kepler.gl layer data from deck.gl layer
* @param param.dataContainer DataContainer to use use with dataAccessor
* @return {Object} attributeAccessors - deck.gl layer attribute accessors
*/
}, {
key: "getAttributeAccessors",
value: function getAttributeAccessors(_ref9) {
var _this5 = this;
var _ref9$dataAccessor = _ref9.dataAccessor,
dataAccessor = _ref9$dataAccessor === void 0 ? defaultDataAccessor : _ref9$dataAccessor,
dataContainer = _ref9.dataContainer,
indexKey = _ref9.indexKey;
var attributeAccessors = {};
Object.keys(this.visualChannels).forEach(function (channel) {
var _this5$visualChannels = _this5.visualChannels[channel],
field = _this5$visualChannels.field,
fixed = _this5$visualChannels.fixed,
scale = _this5$visualChannels.scale,
domain = _this5$visualChannels.domain,
range = _this5$visualChannels.range,
accessor = _this5$visualChannels.accessor,
defaultValue = _this5$visualChannels.defaultValue,
getAttributeValue = _this5$visualChannels.getAttributeValue,
nullValue = _this5$visualChannels.nullValue,
channelScaleType = _this5$visualChannels.channelScaleType;
if (accessor) {
var shouldGetScale = _this5.config[field];
if (shouldGetScale) {
var isFixed = fixed && _this5.config.visConfig[fixed];
var scaleFunction = channelScaleType === _constants.CHANNEL_SCALES.color ? _this5.getColorScale(_this5.config[scale], _this5.config[domain], _this5.config.visConfig[range]) : _this5.getVisChannelScale(_this5.config[scale], _this5.config[domain], _this5.config.visConfig[range], isFixed);
var getFieldValue = _this5.accessVSFieldValue(_this5.config[field], indexKey);
if (scaleFunction) {
attributeAccessors[accessor] = scaleFunction.byZoom ? (0, _lodash["default"])(function (z) {
var scaleFunc = scaleFunction(z);
return function (d) {
return _this5.getEncodedChannelValue(scaleFunc, dataAccessor(dataContainer)(d), _this5.config[field], nullValue, getFieldValue);
};
}) : function (d) {
return _this5.getEncodedChannelValue(scaleFunction, dataAccessor(dataContainer)(d), _this5.config[field], nullValue, getFieldValue);
};
// set getFillColorByZoom to true
if (scaleFunction.byZoom) {
attributeAccessors["".concat(accessor, "ByZoom")] = true;
}
}
} else if (typeof getAttributeValue === 'function') {
attributeAccessors[accessor] = getAttributeValue(_this5.config);
} else {
attributeAccessors[accessor] = typeof defaultValue === 'function' ? defaultValue(_this5.config) : defaultValue;
}
if (!attributeAccessors[accessor]) {
_window.console.warn("Failed to provide accessor function for ".concat(accessor || channel));
}
}
});
return attributeAccessors;
}
}, {
key: "getVisChannelScale",
value: function getVisChannelScale(scale, domain, range, fixed) {
// if quantile is provided per zoom
if ((0, _utils.isDomainQuantile)(domain) && scale === _constants.SCALE_TYPES.quantile) {
var zSteps = domain.z;
var getScale = function getScaleByZoom(z) {
var scaleDomain = (0, _utils.getDomainStepsbyZoom)(domain.quantiles, zSteps, z);
var thresholds = (0, _utils.getThresholdsFromQuantiles)(scaleDomain, range.length);
return (0, _utils.getScaleFunction)('threshold', range, thresholds, false);
};
getScale.byZoom = true;
return getScale;
} else if ((0, _utils.isDomainStops)(domain)) {
// color is based on zoom
var _zSteps = domain.z;
// get scale function by z
// {
// z: [z, z, z],
// stops: [[min, max], [min, max]],
// interpolation: 'interpolate'
// }
var _getScale = function getScaleByZoom(z) {
var scaleDomain = (0, _utils.getDomainStepsbyZoom)(domain.stops, _zSteps, z);
return (0, _utils.getScaleFunction)(scale, range, scaleDomain, fixed);
};
_getScale.byZoom = true;
return _getScale;
}
return _constants.SCALE_FUNC[fixed ? 'linear' : scale]().domain(domain).range(fixed ? domain : range);
}
/**
* Get longitude and latitude bounds of the data.
*/
}, {
key: "getPointsBounds",
value: function getPointsBounds(dataContainer) {
var getPosition = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : identity;
// no need to loop through the entire dataset
// get a sample of data to calculate bounds
var sampleData = dataContainer.numRows() > MAX_SAMPLE_SIZE ? (0, _utils.getSampleContainerData)(dataContainer, MAX_SAMPLE_SIZE) : dataContainer;
var points = getPosition ? sampleData.mapIndex(getPosition) : [];
var latBounds = (0, _utils.getLatLngBounds)(points, 1, [-90, 90]);
var lngBounds = (0, _utils.getLatLngBounds)(points, 0, [-180, 180]);
if (!latBounds || !lngBounds) {
return null;
}
return [lngBounds[0], latBounds[0], lngBounds[1], latBounds[1]];
}
}, {
key: "getChangedTriggers",
value: function getChangedTriggers(dataUpdateTriggers) {
var triggerChanged = (0, _layerUpdate.diffUpdateTriggers)(dataUpdateTriggers, this._oldDataUpdateTriggers);
this._oldDataUpdateTriggers = dataUpdateTriggers;
return triggerChanged;
}
}, {
key: "getEncodedChannelValue",
value: function getEncodedChannelValue(scale, data, field) {
var nullValue = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _constants.NO_VALUE_COLOR;
var getValue = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : defaultGetFieldValue;
var value = getValue(field, data);
if (!(0, _commonUtils.notNullorUndefined)(value)) {
return nullValue;
}
var attributeValue;
if (Array.isArray(value)) {
attributeValue = value.map(scale);
} else {
attributeValue = scale(value);
}
if (!(0, _commonUtils.notNullorUndefined)(attributeValue)) {
attributeValue = nullValue;
}
return attributeValue;
}
}, {
key: "updateMeta",
value: function updateMeta(meta) {
this.meta = _objectSpread(_objectSpread({}, this.meta), meta);
}
}, {
key: "getDataUpdateTriggers",
value: function getDataUpdateTriggers(_ref10) {
var filteredIndex = _ref10.filteredIndex,
id = _ref10.id,
dataContainer = _ref10.dataContainer;
var columns = this.config.columns;
return _objectSpread({
getData: {
datasetId: id,
dataContainer: dataContainer,
columns: columns,
filteredIndex: filteredIndex
},
getMeta: {
datasetId: id,
dataContainer: dataContainer,
columns: columns
}
}, (this.config.textLabel || []).reduce(function (accu, tl, i) {
return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, "getLabelCharacterSet-".concat(i), tl.field ? tl.field.name : null));
}, {}));
}
}, {
key: "updateData",
value: function updateData(datasets, oldLayerData) {
if (!this.config.dataId) {
return {};
}
var layerDataset = datasets[this.config.dataId];
var dataContainer = layerDataset.dataContainer;
var getPosition = this.getPositionAccessor(dataContainer);
var dataUpdateTriggers = this.getDataUpdateTriggers(layerDataset);
var triggerChanged = this.getChangedTriggers(dataUpdateTriggers);
if (triggerChanged && (triggerChanged.getMeta || triggerChanged.getData)) {
this.updateLayerMeta(layerDataset, getPosition);
// reset filteredItemCount
this.filteredItemCount = {};
}
var data = [];
if (!(triggerChanged && triggerChanged.getData) && oldLayerData && oldLayerData.data) {
// same data
data = oldLayerData.data;
} else {
data = this.calculateDataAttribute(layerDataset, getPosition);
}
return {
data: data,
triggerChanged: triggerChanged
};
}
/**
* helper function to update one layer domain when state.data changed
* if state.data change is due ot update filter, newFiler will be passed
* called by updateAllLayerDomainData
* @param datasets
* @param newFilter
* @returns layer
*/
}, {
key: "updateLayerDomain",
value: function updateLayerDomain(datasets, newFilter) {
var _this6 = this;
var table = this.getDataset(datasets);
if (!table) {
return this;
}
Object.values(this.visualChannels).forEach(function (channel) {
var scale = channel.scale;
var scaleType = _this6.config[scale];
// ordinal domain is based on dataContainer, if only filter changed
// no need to update ordinal domain
if (!newFilter || scaleType !== _constants.SCALE_TYPES.ordinal) {
var domain = channel.domain;
var updatedDomain = _this6.calculateLayerDomain(table, channel);
_this6.updateLayerConfig((0, _defineProperty2["default"])({}, domain, updatedDomain));
}
});
return this;
}
}, {
key: "getDataset",
value: function getDataset(datasets) {
return this.config.dataId ? datasets[this.config.dataId] : null;
}
/**
* Validate visual channel field and scales based on supported field & scale type
* @param channel
*/
}, {
key: "validateVisualChannel",
value: function validateVisualChannel(channel) {
this.validateFieldType(channel);
this.validateScale(channel);
}
/**
* Validate field type based on channelScaleType
*/
}, {
key: "validateFieldType",
value: function validateFieldType(channel) {
var visualChannel = this.visualChannels[channel];
var field = visualChannel.field,
channelScaleType = visualChannel.channelScaleType,
supportedFieldTypes = visualChannel.supportedFieldTypes;
if (this.config[field]) {
// if field is selected, check if field type is supported
var channelSupportedFieldTypes = supportedFieldTypes || _constants.CHANNEL_SCALE_SUPPORTED_FIELDS[channelScaleType];
if (!channelSupportedFieldTypes.includes(this.config[field].type)) {
// field type is not supported, set it back to null
// set scale back to default
this.updateLayerConfig((0, _defineProperty2["default"])({}, field, null));
}
}
}
/**
* Validate scale type based on aggregation
*/
}, {
key: "validateScale",
value: function validateScale(channel) {
var visualChannel = this.visualChannels[channel];
var scale = visualChannel.scale;
if (!scale) {
// visualChannel doesn't have scale
return;
}
var scaleOptions = this.getScaleOptions(channel);
// check if current selected scale is
// supported, if not, change to default
if (!scaleOptions.includes(this.config[scale])) {
this.updateLayerConfig((0, _defineProperty2["default"])({}, scale, scaleOptions[0]));
}
}
/**
* Get scale options based on current field
* @param {string} channel
* @returns {string[]}
*/
}, {
key: "getScaleOptions",
value: function getScaleOptions(channel) {
var visualChannel = this.visualChannels[channel];
var field = visualChannel.field,
scale = visualChannel.scale,
channelScaleType = visualChannel.channelScaleType;
return this.config[field] ? _constants.FIELD_OPTS[this.config[field].type].scale[channelScaleType] : [this.getDefaultLayerConfig({
dataId: ''
})[scale]];
}
}, {
key: "updateLayerVisualChannel",
value: function updateLayerVisualChannel(dataset, channel) {
var visualChannel = this.visualChannels[channel];
this.validateVisualChannel(channel);
// calculate layer channel domain
var updatedDomain = this.calculateLayerDomain(dataset, visualChannel);
this.updateLayerConfig((0, _defineProperty2["default"])({}, visualChannel.domain, updatedDomain));
}
}, {
key: "getVisualChannelUpdateTriggers",
value: function getVisualChannelUpdateTriggers() {
var _this7 = this;
var updateTriggers = {};
Object.values(this.visualChannels).forEach(function (visualChannel) {
// field range scale domain
var accessor = visualChannel.accessor,
field = visualChannel.field,
scale = visualChannel.scale,
domain = visualChannel.domain,
range = visualChannel.range,
defaultValue = visualChannel.defaultValue,
fixed = visualChannel.fixed;
if (accessor) {
updateTriggers[accessor] = _objectSpread((0, _defineProperty2["default"])((0, _defineProperty2["default"])((0, _defineProperty2["default"])((0, _defineProperty2["default"])((0, _defineProperty2["default"])({}, field, _this7.config[field]), scale, _this7.config[scale]), domain, _this7.config[domain]), range, _this7.config.visConfig[range]), "defaultValue", typeof defaultValue === 'function' ? defaultValue(_this7.config) : defaultValue), fixed ? (0, _defineProperty2["default"])({}, fixed, _this7.config.visConfig[fixed]) : {});
}
});
return updateTriggers;
}
}, {
key: "calculateLayerDomain",
value: function calculateLayerDomain(dataset, visualChannel) {
var scale = visualChannel.scale;
var scaleType = this.config[scale];
var field = this.config[visualChannel.field];
if (!field) {
// if colorField or sizeField were set back to null
return defaultDomain;
}
return dataset.getColumnLayerDomain(field, scaleType) || defaultDomain;
}
}, {
key: "hasHoveredObject",
value: function hasHoveredObject(objectInfo) {
return this.isLayerHovered(objectInfo) && objectInfo.object ? objectInfo.object : null;
}
}, {
key: "isLayerHovered",
value: function isLayerHovered(objectInfo) {
var _objectInfo$layer;
return (objectInfo === null || objectInfo === void 0 ? void 0 : objectInfo.picked) && (objectInfo === null || objectInfo === void 0 || (_objectInfo$layer = objectInfo.layer) === null || _objectInfo$layer === void 0 || (_objectInfo$layer = _objectInfo$layer.props) === null || _objectInfo$layer === void 0 ? void 0 : _objectInfo$layer.id) === this.id;
}
}, {
key: "getRadiusScaleByZoom",
value: function getRadiusScaleByZoom(mapState, fixedRadius) {
var radiusChannel = Object.values(this.visualChannels).find(function (vc) {
return vc.property === 'radius';
});
if (!radiusChannel) {
return 1;
}
var field = radiusChannel.field;
var fixed = fixedRadius === undefined ? this.config.visConfig.fixedRadius : fixedRadius;
var radius = this.config.visConfig.radius;
return fixed ? 1 : (this.config[field] ? 1 : radius) * this.getZoomFactor(mapState);
}
}, {
key: "shouldCalculateLayerData",
value: function shouldCalculateLayerData(props) {
var _this8 = this;
return props.some(function (p) {
return !_this8.noneLayerDataAffectingProps.includes(p);
});
}
}, {
key: "getBrushingExtensionProps",
value: function getBrushingExtensionProps(interactionConfig, brushingTarget) {
var brush = interactionConfig.brush;
return {
// brushing
autoHighlight: !brush.enabled,
brushingRadius: brush.config.size * 1000,
brushingTarget: brushingTarget || 'source',
brushingEnabled: brush.enabled
};
}
}, {
key: "getDefaultDeckLayerProps",
value: function getDefaultDeckLayerProps(_ref12) {
var idx = _ref12.idx,
gpuFilter = _ref12.gpuFilter,
mapState = _ref12.mapState,
layerCallbacks = _ref12.layerCallbacks,
visible = _ref12.visible;
return {
id: this.id,
idx: idx,
coordinateSystem: _core.COORDINATE_SYSTEM.LNGLAT,
pickable: true,
wrapLongitude: true,
parameters: {
depthTest: Boolean(mapState.dragRotate || this.config.visConfig.enable3d)
},
hidden: this.config.hidden,
// visconfig
opacity: this.config.visConfig.opacity,
highlightColor: this.config.highlightColor,
// data filtering
extensions: [dataFilterExtension],
filterRange: gpuFilter ? gpuFilter.filterRange : undefined,
onFilteredItemsChange: gpuFilter ? layerCallbacks === null || layerCallbacks === void 0 ? void 0 : layerCallbacks.onFilteredItemsChange : undefined,
// layer should be visible and if splitMap, shown in to one of panel
visible: this.config.isVisible && visible
};
}
}, {
key: "getDefaultHoverLayerProps",
value: function getDefaultHoverLayerProps() {
return {
id: "".concat(this.id, "-hovered"),
pickable: false,
wrapLongitude: true,
coordinateSystem: _core.COORDINATE_SYSTEM.LNGLAT
};
}
}, {
key: "renderTextLabelLayer",
value: function renderTextLabelLayer(_ref13, renderOpts) {
var _this9 = this;
var getPosition = _ref13.getPosition,
getFiltered = _ref13.getFiltered,
getPixelOffset = _ref13.getPixelOffset,
backgroundProps = _ref13.backgroundProps,
updateTriggers = _ref13.updateTriggers,
sharedProps = _ref13.sharedProps;
var data = renderOpts.data,
mapState = renderOpts.mapState;
var textLabel = this.config.textLabel;
var TextLayerClass = data.data instanceof arrow.Table ? _deckglArrowLayers.GeoArrowTextLayer : _layers.TextLayer;
return data.textLabels.reduce(function (accu, d, i) {
if (d.getText) {
var _textLabel$i$field, _textLabel$i$field2;
var background = textLabel[i].background || (backgroundProps === null || backgroundProps === void 0 ? void 0 : backgroundProps.background);
accu.push(
// @ts-expect-error
new TextLayerClass(_objectSpread(_objectSpread({}, sharedProps), {}, {
id: "".concat(_this9.id, "-label-").concat((_textLabel$i$field = textLabel[i].field) === null || _textLabel$i$field === void 0 ? void 0 : _textLabel$i$field.name),
data: data.data,
visible: _this9.config.isVisible,
getText: d.getText,
getPosition: getPosition,
getFiltered: getFiltered,
characterSet: d.characterSet,
getPixelOffset: getPixelOffset(textLabel[i]),
getSize: _constants.PROJECTED_PIXEL_SIZE_MULTIPLIER,
sizeScale: textLabel[i].size,
getTextAnchor: textLabel[i].anchor,
getAlignmentBaseline: textLabel[i].alignment,
getColor: textLabel[i].color,
outlineWidth: textLabel[i].outlineWidth * _constants.TEXT_OUTLINE_MULTIPLIER,
outlineColor: textLabel[i].outlineColor,
background: background,
getBackgroundColor: textLabel[i].backgroundColor,
fontSettings: {
sdf: textLabel[i].outlineWidth > 0
},
parameters: {
// text will always show on top of all layers
depthTest: false
},
getFilterValue: data.getFilterValue,
updateTriggers: _objectSpread(_objectSpread({}, updateTriggers), {}, {
getText: (_textLabel$i$field2 = textLabel[i].field) === null || _textLabel$i$field2 === void 0 ? void 0 : _textLabel$i$field2.name,
getPixelOffset: _objectSpread(_objectSpread({}, updateTriggers.getRadius), {}, {
mapState: mapState,
anchor: textLabel[i].anchor,
alignment: textLabel[i].alignment
}),
getTextAnchor: textLabel[i].anchor,
getAlignmentBaseline: textLabel[i].alignment,
getColor: textLabel[i].color
}),
_subLayerProps: _objectSpread({}, background ? {
background: {
parameters: {
cull: false
}
}
} : null)
})));
}
return accu;
}, []);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
}, {
key: "calculateDataAttribute",
value: function calculateDataAttribute(keplerTable, getPosition) {
// implemented in subclasses
return [];
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
}, {
key: "updateLayerMeta",
value: function updateLayerMeta(dataset, getPosition) {
// implemented in subclasses
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
}, {
key: "getPositionAccessor",
value: function getPositionAccessor(dataContainer) {
// implemented in subclasses
return function () {
return null;
};
}
}, {
key: "getLegendVisualChannels",
value: function getLegendVisualChannels() {
return this.visualChannels;
}
}], [{
key: "findDefaultLayerProps",
value: function findDefaultLayerProps(dataset, foundLayers) {
return {
props: [],
foundLayers: foundLayers
};
}
/**
* Given a array of preset required column names
* found field that has the same name to set as layer column
*
* @param {object} defaultFields
* @param {object[]} allFields
* @returns {object[] | null} all possible required layer column pairs
*/
}, {
key: "findDefaultColumnField",
value: function findDefaultColumnField(defaultFields, allFields) {
// find all matched fields for each required col
var requiredColumns = Object.keys(defaultFields).reduce(function (prev, key) {
var requiredFields = allFields.filter(function (f) {
return f.name === defaultFields[key] || defaultFields[key].includes(f.name);
});
prev[key] = requiredFields.length ? requiredFields.map(function (f) {
return {
value: f.name,
fieldIdx: f.fieldIdx
};
}) : null;
return prev;
}, {});
if (!Object.values(requiredColumns).every(Boolean)) {
// if any field missing, return null
return null;
}
return this.getAllPossibleColumnPairs(requiredColumns);
}
}, {
key: "getAllPossibleColumnPairs",
value: function getAllPossibleColumnPairs(requiredColumns) {
// for multiple matched field for one required column, return multiple
// combinations, e. g. if column a has 2 matched, column b has 3 matched
// 6 possible column pairs will be returned
var allKeys = Object.keys(requiredColumns);
var pointers = allKeys.map(function (k, i) {
return i === allKeys.length - 1 ? -1 : 0;
});
var countPerKey = allKeys.map(function (k) {
return requiredColumns[k].length;
});
// TODO: Better typings
var pairs = [];
/* eslint-disable no-loop-func */
while (incrementPointers(pointers, countPerKey, pointers.length - 1)) {
var newPair = pointers.reduce(function (prev, cuur, i) {
prev[allKeys[i]] = requiredColumns[allKeys[i]][cuur];
return prev;
}, {});
pairs.push(newPair);
}
/* eslint-enable no-loop-func */
// recursively increment pointers
function incrementPointers(pts, counts, index) {
if (index === 0 && pts[0] === counts[0] - 1) {
// nothing to increment
return false;
}
if (pts[index] + 1 < counts[index]) {
pts[index] = pts[index] + 1;
return true;
}
pts[index] = 0;
return incrementPointers(pts, counts, index - 1);
}
return pairs;
}
}, {
key: "hexToRgb",
value: function hexToRgb(c) {
return (0, _utils.hexToRgb)(c);
}
}]);
}();
var _default = exports["default"] = Layer;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29yZSIsInJlcXVpcmUiLCJfZGVja2dsQXJyb3dMYXllcnMiLCJfZXh0ZW5zaW9ucyIsIl9sYXllcnMiLCJfd2luZG93IiwiX2tleW1pcnJvciIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJhcnJvdyIsIl9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkIiwiX2RlZmF1bHRMYXllckljb24iLCJfbGF5ZXJVcGRhdGUiLCJfbGF5ZXJVdGlscyIsIl9jb25zdGFudHMiLCJfdXRpbHMiLCJfY29tbW9uVXRpbHMiLCJfbG9kYXNoIiwiX2dldEFwcGxpY2F0aW9uQ29uZmlnIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJfdHlwZW9mMyIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIl9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyIiwiU3ltYm9sIiwiaXRlcmF0b3IiLCJBcnJheSIsImlzQXJyYXkiLCJfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkiLCJsZW5ndGgiLCJfbiIsIkYiLCJzIiwiZG9uZSIsInZhbHVlIiwiZiIsIlR5cGVFcnJvciIsIm8iLCJuZXh0IiwiX2FycmF5TGlrZVRvQXJyYXkiLCJ0b1N0cmluZyIsInNsaWNlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiZnJvbSIsInRlc3QiLCJvd25LZXlzIiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsImZpbHRlciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsIl9tYXJrZWQiLCJfcmVnZW5lcmF0b3JSdW50aW1lMiIsIm1hcmsiLCJnZW5lcmF0ZUNvbG9yIiwiTEFZRVJfSURfTEVOR1RIIiwiZXhwb3J0cyIsIk1BWF9TQU1QTEVfU0laRSIsImRlZmF1bHREb21haW4iLCJkYXRhRmlsdGVyRXh0ZW5zaW9uIiwiRGF0YUZpbHRlckV4dGVuc2lvbiIsImZpbHRlclNpemUiLCJNQVhfR1BVX0ZJTFRFUlMiLCJjb3VudEl0ZW1zIiwiZ2V0QXBwbGljYXRpb25Db25maWciLCJ1c2VPbkZpbHRlcmVkSXRlbXNDaGFuZ2UiLCJkZWZhdWx0RGF0YUFjY2Vzc29yIiwiZGMiLCJkIiwiaWRlbnRpdHkiLCJkZWZhdWx0R2V0RmllbGRWYWx1ZSIsImZpZWxkIiwidmFsdWVBY2Nlc3NvciIsIk9WRVJMQVlfVFlQRV9DT05TVCIsImtleW1pcnJvciIsImRlY2tnbCIsIm1hcGJveGdsIiwibGF5ZXJDb2xvcnMiLCJ2YWx1ZXMiLCJEYXRhVml6Q29sb3JzIiwibWFwIiwiaGV4VG9SZ2IiLCJpbmRleCIsIl9yZWdlbmVyYXRvciIsIndyYXAiLCJnZW5lcmF0ZUNvbG9yJCIsIl9jb250ZXh0IiwicHJldiIsInN0b3AiLCJjb2xvck1ha2VyIiwiTGF5ZXIiLCJwcm9wcyIsIl9jbGFzc0NhbGxDaGVjazIiLCJpZCIsImdlbmVyYXRlSGFzaElkIiwibWV0YSIsInZpc0NvbmZpZ1NldHRpbmdzIiwiY29uZmlnIiwiZ2V0RGVmYXVsdExheWVyQ29uZmlnIiwiY29sdW1uTW9kZSIsInN1cHBvcnRlZENvbHVtbk1vZGVzIiwiX3N1cHBvcnRlZENvbHVtbk1vZGVzIiwia2V5IiwiY29sdW1ucyIsImdldExheWVyQ29sdW1ucyIsImlzVmFsaWQiLCJlcnJvck1lc3NhZ2UiLCJmaWx0ZXJlZEl0ZW1Db3VudCIsIl9jcmVhdGVDbGFzczIiLCJEZWZhdWx0TGF5ZXJJY29uIiwidHlwZSIsInJlZHVjZSIsImFjYyIsIm9iaiIsInJlcXVpcmVkQ29sdW1ucyIsImNvbmNhdCIsIm9wdGlvbmFsQ29sdW1ucyIsImNvbG9yIiwicHJvcGVydHkiLCJzY2FsZSIsImRvbWFpbiIsInJhbmdlIiwiY2hhbm5lbFNjYWxlVHlwZSIsIkNIQU5ORUxfU0NBTEVTIiwibnVsbFZhbHVlIiwiTk9fVkFMVUVfQ09MT1IiLCJkZWZhdWx0VmFsdWUiLCJzaXplIiwibGF0IiwicGFpciIsImZpZWxkUGFpcktleSIsImxuZyIsImFsdGl0dWRlIiwiYWx0IiwibGF0MCIsImxuZzAiLCJhbHQwIiwibGF0MSIsImxuZzEiLCJhbHQxIiwiX3Byb3BzJGlzVmlzaWJsZSIsIl9wcm9wcyRpc0NvbmZpZ0FjdGl2ZSIsIl9wcm9wcyRoaWRkZW4iLCJkYXRhSWQiLCJsYWJlbCIsIkRFRkFVTFRfTEFZRVJfTEFCRUwiLCJpc1Zpc2libGUiLCJpc0NvbmZpZ0FjdGl2ZSIsImhpZ2hsaWdodENvbG9yIiwiREVGQVVMVF9ISUdITElHSFRfQ09MT1IiLCJoaWRkZW4iLCJjb2xvckZpZWxkIiwiY29sb3JEb21haW4iLCJjb2xvclNjYWxlIiwiU0NBTEVfVFlQRVMiLCJxdWFudGlsZSIsInNpemVEb21haW4iLCJzaXplU2NhbGUiLCJsaW5lYXIiLCJzaXplRmllbGQiLCJ2aXNDb25maWciLCJ0ZXh0TGFiZWwiLCJERUZBVUxUX1RFWFRfTEFCRUwiLCJjb2xvclVJIiwiREVGQVVMVF9DT0xPUl9VSSIsImNvbG9yUmFuZ2UiLCJhbmltYXRpb24iLCJlbmFibGVkIiwiZ2V0VmlzdWFsQ2hhbm5lbERlc2NyaXB0aW9uIiwiY2hhbm5lbCIsInZpc3VhbENoYW5uZWxzIiwibWVhc3VyZSIsInVuZGVmaW5lZCIsInJhbmdlU2V0dGluZ3MiLCJmaWVsZFNldHRpbmdzIiwiZGlzcGxheU5hbWUiLCJkZWZhdWx0TWVhc3VyZSIsImFzc2lnbkNvbHVtbiIsIl90aGlzJGNvbmZpZyRjb2x1bW5zIiwidXBkYXRlIiwiZmllbGRJZHgiLCJhc3NpZ25Db2x1bW5QYWlycyIsImZpZWxkUGFpcnMiLCJfdGhpcyRjb2x1bW5QYWlycyIsIl90aGlzJGNvbHVtblBhaXJzMiIsImNvbHVtblBhaXJzIiwiX3JlZiIsInVwZGF0ZWRDb2x1bW4iLCJwYXJ0bmVyS2V5cyIsInRvQXJyYXkiLCJfaXRlcmF0b3IiLCJfc3RlcCIsIl90aGlzJGNvbHVtblBhaXJzMyIsIl90aGlzJGNvbHVtblBhaXJzNCIsInBhcnRuZXJLZXkiLCJfdGhpcyRjb2x1bW5QYWlyczUiLCJlcnIiLCJnZXRab29tRmFjdG9yIiwiX3JlZjIiLCJ6b29tIiwiX3JlZjIkem9vbU9mZnNldCIsInpvb21PZmZzZXQiLCJNYXRoIiwicG93IiwibWF4IiwiZ2V0RWxldmF0aW9uWm9vbUZhY3RvciIsIl9yZWYzIiwiX3JlZjMkem9vbU9mZnNldCIsIl90aGlzJGNvbmZpZyR2aXNDb25maSIsImZpeGVkSGVpZ2h0IiwiZW5hYmxlRWxldmF0aW9uWm9vbUZhY3RvciIsImZvcm1hdExheWVyRGF0YSIsImRhdGFzZXRzIiwib2xkTGF5ZXJEYXRhIiwiYW5pbWF0aW9uQ29uZmlnIiwicmVuZGVyTGF5ZXIiLCJnZXRIb3ZlckRhdGEiLCJvYmplY3QiLCJkYXRhQ29udGFpbmVyIiwiZmllbGRzIiwiaG92ZXJJbmZvIiwicm93IiwiZ2V0RmlsdGVyZWRJdGVtQ291bnQiLCJmaXJzdExheWVyIiwiYXNzaWduQ29uZmlnVG9MYXllciIsImNvbmZpZ1RvQ29weSIsImRlZmF1bHRMYXllclByb3BzIiwiX3RoaXMiLCJzaGFsbG93Q29weSIsInYiLCJub3RUb0NvcHkiLCJncm91cCIsImN1cnJlbnRDb25maWciLCJjb3BpZWQiLCJjb3B5TGF5ZXJDb25maWciLCJfc2F0aXNmaWVkQ29sdW1uTW9kZSIsImRhdGFzZXQiLCJzYXRpc2ZpZWRDb2x1bW5Nb2RlIiwiZ2V0U2F0aXNmaWVkQ29sdW1uTW9kZSIsIm9wdGlvbnMiLCJfdG9Db25zdW1hYmxlQXJyYXkyIiwiYWx0UHJvcHMiLCJkZWZhdWx0Q29sdW1uQ29uZmlnIiwidXBkYXRlTGF5ZXJDb25maWciLCJ2YWxpZGF0ZVZpc3VhbENoYW5uZWwiLCJfdGhpczIiLCJfcmVmNCIsIl9yZWY0JHNoYWxsb3dDb3B5IiwiX3JlZjQkbm90VG9Db3B5IiwiaXNQbGFpbk9iamVjdCIsImluY2x1ZGVzIiwibm90TnVsbG9yVW5kZWZpbmVkIiwicmVnaXN0ZXJWaXNDb25maWciLCJsYXllclZpc0NvbmZpZ3MiLCJfdGhpczMiLCJpdGVtIiwiY29uZmlnSXRlbSIsIkxBWUVSX1ZJU19DT05GSUdTIiwiX3R5cGVvZjIiLCJldmVyeSIsInAiLCJwcm90b3R5cGUiLCJwcm9wc0NvbHVtbnMiLCJjb2x1bW5WYWxpZGF0b3JzIiwicmVxdWlyZWQiLCJyZXF1aXJlZExheWVyQ29sdW1ucyIsImFjY3UiLCJfcHJvcHNDb2x1bW5zJGtleSR2YWwiLCJfcHJvcHNDb2x1bW5zJGtleSIsIl9wcm9wc0NvbHVtbnMka2V5JGZpZSIsIl9wcm9wc0NvbHVtbnMka2V5MiIsIl9wcm9wc0NvbHVtbnMka2V5JHZhbDIiLCJfcHJvcHNDb2x1bW5zJGtleTMiLCJfcHJvcHNDb2x1bW5zJGtleSRmaWUyIiwiX3Byb3BzQ29sdW1ucyRrZXk0IiwidmFsaWRhdG9yIiwib3B0aW9uYWwiLCJfcHJvcHNDb2x1bW5zJGtleSR2YWwzIiwiX3Byb3BzQ29sdW1ucyRrZXk1IiwiX3Byb3BzQ29sdW1ucyRrZXkkZmllMyIsIl9wcm9wc0NvbHVtbnMka2V5NiIsIm5ld0NvbmZpZyIsInVwZGF0ZUxheWVyVmlzQ29uZmlnIiwibmV3VmlzQ29uZmlnIiwidXBkYXRlTGF5ZXJDb2xvclVJIiwicHJvcCIsIl90aGlzJGNvbmZpZyIsInByZXZpb3VzIiwiY29sb3JVSVByb3AiLCJlbnRyaWVzIiwiX3JlZjUiLCJfcmVmNiIsIl9zbGljZWRUb0FycmF5MiIsImlzQ29sb3JSYW5nZSIsImNvbG9ycyIsInVwZGF0ZUNvbG9yVUlCeUNvbG9yUmFuZ2UiLCJ1cGRhdGVDb2xvclJhbmdlQnlDb2xvclVJIiwidXBkYXRlQ3VzdG9tUGFsZXR0ZSIsIl9uZXdDb25maWckY29sb3JSYW5nZSIsIl9uZXdDb25maWckY29sb3JSYW5nZTIiLCJjb2xvclJhbmdlQ29uZmlnIiwiY3VzdG9tIiwiY3VzdG9tQnJlYWtzIiwiY3VzdG9tUGFsZXR0ZSIsIl90aGlzJGNvbmZpZzIiLCJjb2xvck1hcCIsImNoYW5uZWxLZXkiLCJmaW5kIiwiQ29uc29sZSIsIndhcm4iLCJpbml0aWFsaXplTGF5ZXJDb2xvck1hcCIsImluaXRpYWxpemVDdXN0b21QYWxldHRlIiwiX25ld0NvbmZpZyRjdXN0b21QYWxlIiwiX3RoaXMkY29uZmlnMyIsImlzQ3VzdG9tIiwiY2F0ZWdvcnkiLCJjdXN0b21TdGVwc0NoYW5nZWQiLCJzaG93RHJvcGRvd24iLCJzdGVwcyIsInJldmVyc2VkIiwiQm9vbGVhbiIsInNob3VsZFVwZGF0ZSIsInNvbWUiLCJfdGhpcyRjb25maWc0IiwiaXNDdXN0b21Db2xvclJldmVyc2VkIiwidXBkYXRlQ3VzdG9tQ29sb3JSYW5nZUJ5Q29sb3JVSSIsInVwZGF0ZUNvbG9yUmFuZ2VCeU1hdGNoaW5nUGFsZXR0ZSIsImhhc0NvbHVtblZhbHVlIiwiY29sdW1uIiwiaGFzUmVxdWlyZWRDb2x1bW4iLCJoYXNBbGxDb2x1bW5zIiwiX3RoaXM0IiwiX3RoaXMkY29uZmlnNSIsIl9jdXJyZW50Q29sdW1uTW9kZXMkciIsImN1cnJlbnRDb2x1bW5Nb2RlcyIsImNvbE1vZGUiLCJjb2xLZXkiLCJoYXNMYXllckRhdGEiLCJsYXllckRhdGEiLCJkYXRhIiwibnVtUm93cyIsImlzVmFsaWRUb1NhdmUiLCJzaG91bGRSZW5kZXJMYXllciIsImdldENvbG9yU2NhbGUiLCJjdXN0b21PcmRpbmFsIiwiZ2V0Q2F0ZWdvcmljYWxDb2xvclNjYWxlIiwiaGFzQ29sb3JNYXAiLCJfY29sb3JSYW5nZSRjb2xvck1hcCIsImNNYXAiLCJNYXAiLCJfcmVmNyIsIl9yZWY4IiwiayIsInNjYWxlVHlwZSIsIm9yZGluYWwiLCJnZXRTY2FsZUZ1bmN0aW9uIiwidW5rbm93biIsIlVOS05PV05fQ09MT1JfS0VZIiwiZ2V0VmlzQ2hhbm5lbFNjYWxlIiwiYWNjZXNzVlNGaWVsZFZhbHVlIiwiX2ZpZWxkIiwiX2luZGV4S2V5IiwiZ2V0QXR0cmlidXRlQWNjZXNzb3JzIiwiX3JlZjkiLCJfdGhpczUiLCJfcmVmOSRkYXRhQWNjZXNzb3IiLCJkYXRhQWNjZXNzb3IiLCJpbmRleEtleSIsImF0dHJpYnV0ZUFjY2Vzc29ycyIsIl90aGlzNSR2aXN1YWxDaGFubmVscyIsImZpeGVkIiwiYWNjZXNzb3IiLCJnZXRBdHRyaWJ1dGVWYWx1ZSIsInNob3VsZEdldFNjYWxlIiwiaXNGaXhlZCIsInNjYWxlRnVuY3Rpb24iLCJnZXRGaWVsZFZhbHVlIiwiYnlab29tIiwibWVtb2l6ZSIsInoiLCJzY2FsZUZ1bmMiLCJnZXRFbmNvZGVkQ2hhbm5lbFZhbHVlIiwiaXNEb21haW5RdWFudGlsZSIsInpTdGVwcyIsImdldFNjYWxlIiwiZ2V0U2NhbGVCeVpvb20iLCJzY2FsZURvbWFpbiIsImdldERvbWFpblN0ZXBzYnlab29tIiwicXVhbnRpbGVzIiwidGhyZXNob2xkcyIsImdldFRocmVzaG9sZHNGcm9tUXVhbnRpbGVzIiwiaXNEb21haW5TdG9wcyIsInN0b3BzIiwiU0NBTEVfRlVOQyIsImdldFBvaW50c0JvdW5kcyIsImdldFBvc2l0aW9uIiwic2FtcGxlRGF0YSIsImdldFNhbXBsZUNvbnRhaW5lckRhdGEiLCJwb2ludHMiLCJtYXBJbmRleCIsImxhdEJvdW5kcyIsImdldExhdExuZ0JvdW5kcyIsImxuZ0JvdW5kcyIsImdldENoYW5nZWRUcmlnZ2VycyIsImRhdGFVcGRhdGVUcmlnZ2VycyIsInRyaWdnZXJDaGFuZ2VkIiwiZGlmZlVwZGF0ZVRyaWdnZXJzIiwiX29sZERhdGFVcGRhdGVUcmlnZ2VycyIsImdldFZhbHVlIiwiYXR0cmlidXRlVmFsdWUiLCJ1cGRhdGVNZXRhIiwiZ2V0RGF0YVVwZGF0ZVRyaWdnZXJzIiwiX3JlZjEwIiwiZmlsdGVyZWRJbmRleCIsImdldERhdGEiLCJkYXRhc2V0SWQiLCJnZXRNZXRhIiwidGwiLCJ1cGRhdGVEYXRhIiwibGF5ZXJEYXRhc2V0IiwiZ2V0UG9zaXRpb25BY2Nlc3NvciIsInVwZGF0ZUxheWVyTWV0YSIsImNhbGN1bGF0ZURhdGFBdHRyaWJ1dGUiLCJ1cGRhdGVMYXllckRvbWFpbiIsIm5ld0ZpbHRlciIsIl90aGlzNiIsInRhYmxlIiwiZ2V0RGF0YXNldCIsInVwZGF0ZWREb21haW4iLCJjYWxjdWxhdGVMYXllckRvbWFpbiIsInZhbGlkYXRlRmllbGRUeXBlIiwidmFsaWRhdGVTY2FsZSIsInZpc3VhbENoYW5uZWwiLCJzdXBwb3J0ZWRGaWVsZFR5cGVzIiwiY2hhbm5lbFN1cHBvcnRlZEZpZWxkVHlwZXMiLCJDSEFOTkVMX1NDQUxFX1NVUFBPUlRFRF9GSUVMRFMiLCJzY2FsZU9wdGlvbnMiLCJnZXRTY2FsZU9wdGlvbnMiLCJGSUVMRF9PUFRTIiwidXBkYXRlTGF5ZXJWaXN1YWxDaGFubmVsIiwiZ2V0VmlzdWFsQ2hhbm5lbFVwZGF0ZVRyaWdnZXJzIiwiX3RoaXM3IiwidXBkYXRlVHJpZ2dlcnMiLCJnZXRDb2x1bW5MYXllckRvbWFpbiIsImhhc0hvdmVyZWRPYmplY3QiLCJvYmplY3RJbmZvIiwiaXNMYXllckhvdmVyZWQiLCJfb2JqZWN0SW5mbyRsYXllciIsInBpY2tlZCIsImxheWVyIiwiZ2V0UmFkaXVzU2NhbGVCeVpvb20iLCJtYXBTdGF0ZSIsImZpeGVkUmFkaXVzIiwicmFkaXVzQ2hhbm5lbCIsInZjIiwicmFkaXVzIiwic2hvdWxkQ2FsY3VsYXRlTGF5ZXJEYXRhIiwiX3RoaXM4Iiwibm9uZUxheWVyRGF0YUFmZmVjdGluZ1Byb3BzIiwiZ2V0QnJ1c2hpbmdFeHRlbnNpb25Qcm9wcyIsImludGVyYWN0aW9uQ29uZmlnIiwiYnJ1c2hpbmdUYXJnZXQiLCJicnVzaCIsImF1dG9IaWdobGlnaHQiLCJicnVzaGluZ1JhZGl1cyIsImJydXNoaW5nRW5hYmxlZCIsImdldERlZmF1bHREZWNrTGF5ZXJQcm9wcyIsIl9yZWYxMiIsImlkeCIsImdwdUZpbHRlciIsImxheWVyQ2FsbGJhY2tzIiwidmlzaWJsZSIsImNvb3JkaW5hdGVTeXN0ZW0iLCJDT09SRElOQVRFX1NZU1RFTSIsIkxOR0xBVCIsInBpY2thYmxlIiwid3JhcExvbmdpdHVkZSIsInBhcmFtZXRlcnMiLCJkZXB0aFRlc3QiLCJkcmFnUm90YXRlIiwiZW5hYmxlM2QiLCJvcGFjaXR5IiwiZXh0ZW5zaW9ucyIsImZpbHRlclJhbmdlIiwib25GaWx0ZXJlZEl0ZW1zQ2hhbmdlIiwiZ2V0RGVmYXVsdEhvdmVyTGF5ZXJQcm9wcyIsInJlbmRlclRleHRMYWJlbExheWVyIiwiX3JlZjEzIiwicmVuZGVyT3B0cyIsIl90aGlzOSIsImdldEZpbHRlcmVkIiwiZ2V0UGl4ZWxPZmZzZXQiLCJiYWNrZ3JvdW5kUHJvcHMiLCJzaGFyZWRQcm9wcyIsIlRleHRMYXllckNsYXNzIiwiVGFibGUiLCJHZW9BcnJvd1RleHRMYXllciIsIlRleHRMYXllciIsInRleHRMYWJlbHMiLCJnZXRUZXh0IiwiX3RleHRMYWJlbCRpJGZpZWxkIiwiX3RleHRMYWJlbCRpJGZpZWxkMiIsImJhY2tncm91bmQiLCJjaGFyYWN0ZXJTZXQiLCJnZXRTaXplIiwiUFJPSkVDVEVEX1BJWEVMX1NJWkVfTVVMVElQTElFUiIsImdldFRleHRBbmNob3IiLCJhbmNob3IiLCJnZXRBbGlnbm1lbnRCYXNlbGluZSIsImFsaWdubWVudCIsImdldENvbG9yIiwib3V0bGluZVdpZHRoIiwiVEVYVF9PVVRMSU5FX01VTFRJUExJRVIiLCJvdXRsaW5lQ29sb3IiLCJnZXRCYWNrZ3JvdW5kQ29sb3IiLCJiYWNrZ3JvdW5kQ29sb3IiLCJmb250U2V0dGluZ3MiLCJzZGYiLCJnZXRGaWx0ZXJWYWx1ZSIsImdldFJhZGl1cyIsIl9zdWJMYXllclByb3BzIiwiY3VsbCIsImtlcGxlclRhYmxlIiwiZ2V0TGVnZW5kVmlzdWFsQ2hhbm5lbHMiLCJmaW5kRGVmYXVsdExheWVyUHJvcHMiLCJmb3VuZExheWVycyIsImZpbmREZWZhdWx0Q29sdW1uRmllbGQiLCJkZWZhdWx0RmllbGRzIiwiYWxsRmllbGRzIiwicmVxdWlyZWRGaWVsZHMiLCJnZXRBbGxQb3NzaWJsZUNvbHVtblBhaXJzIiwiYWxsS2V5cyIsInBvaW50ZXJzIiwiY291bnRQZXJLZXkiLCJwYWlycyIsImluY3JlbWVudFBvaW50ZXJzIiwibmV3UGFpciIsImN1dXIiLCJwdHMiLCJjb3VudHMiLCJjIiwiX2RlZmF1bHQiXSwic291cmNlcyI6WyIuLi9zcmMvYmFzZS1sYXllci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge0NPT1JESU5BVEVfU1lTVEVNfSBmcm9tICdAZGVjay5nbC9jb3JlJztcbmltcG9ydCB7R2VvQXJyb3dUZXh0TGF5ZXJ9IGZyb20gJ0BrZXBsZXIuZ2wvZGVja2dsLWFycm93LWxheWVycyc7XG5pbXBvcnQge0RhdGFGaWx0ZXJFeHRlbnNpb259IGZyb20gJ0BkZWNrLmdsL2V4dGVuc2lvbnMnO1xuaW1wb3J0IHtUZXh0TGF5ZXJ9IGZyb20gJ0BkZWNrLmdsL2xheWVycyc7XG5pbXBvcnQge2NvbnNvbGUgYXMgQ29uc29sZX0gZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5pbXBvcnQga2V5bWlycm9yIGZyb20gJ2tleW1pcnJvcic7XG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0ICogYXMgYXJyb3cgZnJvbSAnYXBhY2hlLWFycm93JztcbmltcG9ydCBEZWZhdWx0TGF5ZXJJY29uIGZyb20gJy4vZGVmYXVsdC1sYXllci1pY29uJztcbmltcG9ydCB7ZGlmZlVwZGF0ZVRyaWdnZXJzfSBmcm9tICcuL2xheWVyLXVwZGF0ZSc7XG5pbXBvcnQge2dldFNhdGlzZmllZENvbHVtbk1vZGUsIEZpbmREZWZhdWx0TGF5ZXJQcm9wc1JldHVyblZhbHVlfSBmcm9tICcuL2xheWVyLXV0aWxzJztcblxuaW1wb3J0IHtcbiAgQ0hBTk5FTF9TQ0FMRVMsXG4gIENIQU5ORUxfU0NBTEVfU1VQUE9SVEVEX0ZJRUxEUyxcbiAgREVGQVVMVF9DT0xPUl9VSSxcbiAgREVGQVVMVF9ISUdITElHSFRfQ09MT1IsXG4gIERFRkFVTFRfTEFZRVJfTEFCRUwsXG4gIERFRkFVTFRfVEVYVF9MQUJFTCxcbiAgRGF0YVZpekNvbG9ycyxcbiAgRklFTERfT1BUUyxcbiAgTEFZRVJfVklTX0NPTkZJR1MsXG4gIE1BWF9HUFVfRklMVEVSUyxcbiAgTk9fVkFMVUVfQ09MT1IsXG4gIFBST0pFQ1RFRF9QSVhFTF9TSVpFX01VTFRJUExJRVIsXG4gIFNDQUxFX0ZVTkMsXG4gIFNDQUxFX1RZUEVTLFxuICBURVhUX09VVExJTkVfTVVMVElQTElFUixcbiAgVU5LTk9XTl9DT0xPUl9LRVlcbn0gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHtcbiAgRGF0YUNvbnRhaW5lckludGVyZmFjZSxcbiAgRG9tYWluUXVhbnRpbGVzLFxuICBnZXRBcHBsaWNhdGlvbkNvbmZpZyxcbiAgZ2V0TGF0TG5nQm91bmRzLFxuICBnZXRTYW1wbGVDb250YWluZXJEYXRhLFxuICBoYXNDb2xvck1hcCxcbiAgaGV4VG9SZ2IsXG4gIGlzUGxhaW5PYmplY3QsXG4gIGlzRG9tYWluU3RvcHMsXG4gIHVwZGF0ZUNvbG9yUmFuZ2VCeU1hdGNoaW5nUGFsZXR0ZVxufSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcbmltcG9ydCB7Z2VuZXJhdGVIYXNoSWQsIHRvQXJyYXksIG5vdE51bGxvclVuZGVmaW5lZH0gZnJvbSAnQGtlcGxlci5nbC9jb21tb24tdXRpbHMnO1xuaW1wb3J0IHtEYXRhc2V0cywgR3B1RmlsdGVyLCBLZXBsZXJUYWJsZX0gZnJvbSAnQGtlcGxlci5nbC90YWJsZSc7XG5pbXBvcnQge1xuICBBZ2dyZWdhdGVkQmluLFxuICBDb2xvclJhbmdlLFxuICBDb2xvclVJLFxuICBGaWVsZCxcbiAgRmlsdGVyLFxuICBHZXRWaXNDaGFubmVsU2NhbGVSZXR1cm5UeXBlLFxuICBMYXllclZpc0NvbmZpZ1NldHRpbmdzLFxuICBNYXBTdGF0ZSxcbiAgQW5pbWF0aW9uQ29uZmlnLFxuICBLZXBsZXJMYXllcixcbiAgTGF5ZXJCYXNlQ29uZmlnLFxuICBMYXllckNvbHVtbnMsXG4gIExheWVyQ29sdW1uLFxuICBDb2x1bW5QYWlycyxcbiAgQ29sdW1uTGFiZWxzLFxuICBTdXBwb3J0ZWRDb2x1bW5Nb2RlLFxuICBGaWVsZFBhaXIsXG4gIE5lc3RlZFBhcnRpYWwsXG4gIFJHQkNvbG9yLFxuICBWYWx1ZU9mLFxuICBWaXN1YWxDaGFubmVsLFxuICBWaXN1YWxDaGFubmVscyxcbiAgVmlzdWFsQ2hhbm5lbERvbWFpbixcbiAgVmlzdWFsQ2hhbm5lbEZpZWxkLFxuICBWaXN1YWxDaGFubmVsU2NhbGVcbn0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5pbXBvcnQge1xuICBnZXRTY2FsZUZ1bmN0aW9uLFxuICBpbml0aWFsaXplTGF5ZXJDb2xvck1hcCxcbiAgZ2V0Q2F0ZWdvcmljYWxDb2xvclNjYWxlLFxuICB1cGRhdGVDdXN0b21Db2xvclJhbmdlQnlDb2xvclVJXG59IGZyb20gJ0BrZXBsZXIuZ2wvdXRpbHMnO1xuaW1wb3J0IG1lbW9pemUgZnJvbSAnbG9kYXNoLm1lbW9pemUnO1xuaW1wb3J0IHtcbiAgaW5pdGlhbGl6ZUN1c3RvbVBhbGV0dGUsXG4gIGlzRG9tYWluUXVhbnRpbGUsXG4gIGdldERvbWFpblN0ZXBzYnlab29tLFxuICBnZXRUaHJlc2hvbGRzRnJvbVF1YW50aWxlc1xufSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcblxuZXhwb3J0IHR5cGUge1xuICBBZ2dyZWdhdGVkQmluLFxuICBMYXllckJhc2VDb25maWcsXG4gIFZpc3VhbENoYW5uZWwsXG4gIFZpc3VhbENoYW5uZWxzLFxuICBWaXN1YWxDaGFubmVsRG9tYWluLFxuICBWaXN1YWxDaGFubmVsRmllbGQsXG4gIFZpc3VhbENoYW5uZWxTY2FsZVxufTtcblxuZXhwb3J0IHR5cGUgTGF5ZXJCYXNlQ29uZmlnUGFydGlhbCA9IHtkYXRhSWQ6IExheWVyQmFzZUNvbmZpZ1snZGF0YUlkJ119ICYgUGFydGlhbDxMYXllckJhc2VDb25maWc+O1xuXG5leHBvcnQgdHlwZSBMYXllckNvbG9yQ29uZmlnID0ge1xuICBjb2xvckZpZWxkOiBWaXN1YWxDaGFubmVsRmllbGQ7XG4gIGNvbG9yRG9tYWluOiBWaXN1YWxDaGFubmVsRG9tYWluO1xuICBjb2xvclNjYWxlOiBWaXN1YWxDaGFubmVsU2NhbGU7XG59O1xuZXhwb3J0IHR5cGUgTGF5ZXJTaXplQ29uZmlnID0ge1xuICAvLyBjb2xvciBieSBzaXplLCBkb21haW4gaXMgc2V0IGJ5IGZpbHRlcnMsIGZpZWxkLCBzY2FsZSB0eXBlXG4gIHNpemVEb21haW46IFZpc3VhbENoYW5uZWxEb21haW47XG4gIHNpemVTY2FsZTogVmlzdWFsQ2hhbm5lbFNjYWxlO1xuICBzaXplRmllbGQ6IFZpc3VhbENoYW5uZWxGaWVsZDtcbn07XG5leHBvcnQgdHlwZSBMYXllckhlaWdodENvbmZpZyA9IHtcbiAgaGVpZ2h0RmllbGQ6IFZpc3VhbENoYW5uZWxGaWVsZDtcbiAgaGVpZ2h0RG9tYWluOiBWaXN1YWxDaGFubmVsRG9tYWluO1xuICBoZWlnaHRTY2FsZTogVmlzdWFsQ2hhbm5lbFNjYWxlO1xufTtcbmV4cG9ydCB0eXBlIExheWVyU3Ryb2tlQ29sb3JDb25maWcgPSB7XG4gIHN0cm9rZUNvbG9yRmllbGQ6IFZpc3VhbENoYW5uZWxGaWVsZDtcbiAgc3Ryb2tlQ29sb3JEb21haW46IFZpc3VhbENoYW5uZWxEb21haW47XG4gIHN0cm9rZUNvbG9yU2NhbGU6IFZpc3VhbENoYW5uZWxTY2FsZTtcbn07XG5leHBvcnQgdHlwZSBMYXllckNvdmVyYWdlQ29uZmlnID0ge1xuICBjb3ZlcmFnZUZpZWxkOiBWaXN1YWxDaGFubmVsRmllbGQ7XG4gIGNvdmVyYWdlRG9tYWluOiBWaXN1YWxDaGFubmVsRG9tYWluO1xuICBjb3ZlcmFnZVNjYWxlOiBWaXN1YWxDaGFubmVsU2NhbGU7XG59O1xuZXhwb3J0IHR5cGUgTGF5ZXJSYWRpdXNDb25maWcgPSB7XG4gIHJhZGl1c0ZpZWxkOiBWaXN1YWxDaGFubmVsRmllbGQ7XG4gIHJhZGl1c0RvbWFpbjogVmlzdWFsQ2hhbm5lbERvbWFpbjtcbiAgcmFkaXVzU2NhbGU6IFZpc3VhbENoYW5uZWxTY2FsZTtcbn07XG5leHBvcnQgdHlwZSBMYXllcldlaWdodENvbmZpZyA9IHtcbiAgd2VpZ2h0RmllbGQ6IFZpc3VhbENoYW5uZWxGaWVsZDtcbn07XG5cbmV4cG9ydCB0eXBlIFZpc3VhbENoYW5uZWxEZXNjcmlwdGlvbiA9IHtcbiAgbGFiZWw6IHN0cmluZztcbiAgbWVhc3VyZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xufTtcblxudHlwZSBDb2x1bW5WYWxpZGF0b3IgPSAoY29sdW1uOiBMYXllckNvbHVtbiwgY29sdW1uczogTGF5ZXJDb2x1bW5zLCBhbGxGaWVsZHM6IEZpZWxkW10pID0+IGJvb2xlYW47XG5cbmV4cG9ydCB0eXBlIFVwZGF0ZVRyaWdnZXJzID0ge1xuICBba2V5OiBzdHJpbmddOiBVcGRhdGVUcmlnZ2VyO1xufTtcbmV4cG9ydCB0eXBlIFVwZGF0ZVRyaWdnZXIgPSB7XG4gIFtrZXk6IHN0cmluZ106IGFueTtcbn07XG5leHBvcnQgdHlwZSBMYXllckJvdW5kcyA9IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuXG4vKipcbiAqIEFwcHJveC4gbnVtYmVyIG9mIHBvaW50cyB0byBzYW1wbGUgaW4gYSBsYXJnZSBkYXRhIHNldFxuICovXG5leHBvcnQgY29uc3QgTEFZRVJfSURfTEVOR1RIID0gNjtcblxuY29uc3QgTUFYX1NBTVBMRV9TSVpFID0gNTAwMDtcbmNvbnN0IGRlZmF1bHREb21haW46IFtudW1iZXIsIG51bWJlcl0gPSBbMCwgMV07XG5jb25zdCBkYXRhRmlsdGVyRXh0ZW5zaW9uID0gbmV3IERhdGFGaWx0ZXJFeHRlbnNpb24oe1xuICBmaWx0ZXJTaXplOiBNQVhfR1BVX0ZJTFRFUlMsXG4gIC8vIGBjb3VudEl0ZW1zYCBvcHRpb24uIEl0IGVuYWJsZXMgdGhlIEdQVSB0byByZXBvcnQgdGhlIG51bWJlciBvZiBvYmplY3RzIHRoYXQgcGFzcyB0aGUgZmlsdGVyIGNyaXRlcmlhIHZpYSB0aGUgYG9uRmlsdGVyZWRJdGVtc0NoYW5nZWAgY2FsbGJhY2suXG4gIC8vIEB0cy1leHBlY3QtZXJyb3Igbm90IHR5cGVkXG4gIGNvdW50SXRlbXM6IGdldEFwcGxpY2F0aW9uQ29uZmlnKCkudXNlT25GaWx0ZXJlZEl0ZW1zQ2hhbmdlID8/IGZhbHNlXG59KTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuY29uc3QgZGVmYXVsdERhdGFBY2Nlc3NvciA9IGRjID0+IGQgPT4gZDtcbmNvbnN0IGlkZW50aXR5ID0gZCA9PiBkO1xuLy8gQ2FuJ3QgdXNlIGZpZWRWYWx1ZUFjY2Vzb3IgYmVjYXVzZSBuZWVkIHRoZSByYXcgZGF0YSB0byByZW5kZXIgdG9vbHRpcFxuLy8gU0hBTjogUmV2aXNpdCBoZXJlXG5leHBvcnQgY29uc3QgZGVmYXVsdEdldEZpZWxkVmFsdWUgPSAoZmllbGQsIGQpID0+IGZpZWxkLnZhbHVlQWNjZXNzb3IoZCk7XG5cbmV4cG9ydCBjb25zdCBPVkVSTEFZX1RZUEVfQ09OU1QgPSBrZXltaXJyb3Ioe1xuICBkZWNrZ2w6IG51bGwsXG4gIG1hcGJveGdsOiBudWxsXG59KTtcblxuZXhwb3J0IGNvbnN0IGxheWVyQ29sb3JzID0gT2JqZWN0LnZhbHVlcyhEYXRhVml6Q29sb3JzKS5tYXAoaGV4VG9SZ2IpO1xuZnVuY3Rpb24qIGdlbmVyYXRlQ29sb3IoKTogR2VuZXJhdG9yPFJHQkNvbG9yPiB7XG4gIGxldCBpbmRleCA9IDA7XG4gIHdoaWxlIChpbmRleCA8IGxheWVyQ29sb3JzLmxlbmd0aCArIDEpIHtcbiAgICBpZiAoaW5kZXggPT09IGxheWVyQ29sb3JzLmxlbmd0aCkge1xuICAgICAgaW5kZXggPSAwO1xuICAgIH1cbiAgICB5aWVsZCBsYXllckNvbG9yc1tpbmRleCsrXTtcbiAgfVxufVxuXG5leHBvcnQgdHlwZSBMYXllckluZm9Nb2RhbCA9IHtcbiAgaWQ6IHN0cmluZztcbiAgdGVtcGxhdGU6IFJlYWN0LkZDPHZvaWQ+O1xuICBtb2RhbFByb3BzOiB7XG4gICAgdGl0bGU6IHN0cmluZztcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjb2xvck1ha2VyID0gZ2VuZXJhdGVDb2xvcigpO1xuXG5leHBvcnQgdHlwZSBCYXNlTGF5ZXJDb25zdHJ1Y3RvclByb3BzID0ge1xuICBpZD86IHN0cmluZztcbn0gJiBMYXllckJhc2VDb25maWdQYXJ0aWFsO1xuXG5jbGFzcyBMYXllciBpbXBsZW1lbnRzIEtlcGxlckxheWVyIHtcbiAgaWQ6IHN0cmluZztcbiAgbWV0YTogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgdmlzQ29uZmlnU2V0dGluZ3M6IHtcbiAgICBba2V5OiBzdHJpbmddOiBWYWx1ZU9mPExheWVyVmlzQ29uZmlnU2V0dGluZ3M+O1xuICB9O1xuICBjb25maWc6IExheWVyQmFzZUNvbmZpZyAmIFBhcnRpYWw8TGF5ZXJDb2xvckNvbmZpZyAmIExheWVyU2l6ZUNvbmZpZz47XG4gIC8vIFRPRE86IGRlZmluZSBfb2xkRGF0YVVwZGF0ZVRyaWdnZXJzXG4gIF9vbGREYXRhVXBkYXRlVHJpZ2dlcnM6IGFueTtcblxuICBpc1ZhbGlkOiBib29sZWFuO1xuICBlcnJvck1lc3NhZ2U6IHN0cmluZyB8IG51bGw7XG4gIGZpbHRlcmVkSXRlbUNvdW50OiB7XG4gICAgW2RlY2tMYXllcklkOiBzdHJpbmddOiBudW1iZXI7XG4gIH07XG5cbiAgY29uc3RydWN0b3IocHJvcHM6IEJhc2VMYXllckNvbnN0cnVjdG9yUHJvcHMpIHtcbiAgICB0aGlzLmlkID0gcHJvcHMuaWQgfHwgZ2VuZXJhdGVIYXNoSWQoTEFZRVJfSURfTEVOR1RIKTtcbiAgICAvLyBtZXRhXG4gICAgdGhpcy5tZXRhID0ge307XG5cbiAgICAvLyB2aXNDb25maWdTZXR0aW5nc1xuICAgIHRoaXMudmlzQ29uZmlnU2V0dGluZ3MgPSB7fTtcblxuICAgIHRoaXMuY29uZmlnID0gdGhpcy5nZXREZWZhdWx0TGF5ZXJDb25maWcocHJvcHMpO1xuXG4gICAgLy8gc2V0IGNvbHVtbk1vZGUgZnJvbSBzdXBwb3J0ZWQgY29sdW1uc1xuICAgIGlmICghdGhpcy5jb25maWcuY29sdW1uTW9kZSkge1xuICAgICAgY29uc3Qge3N1cHBvcnRlZENvbHVtbk1vZGVzfSA9IHRoaXM7XG4gICAgICBpZiAoc3VwcG9ydGVkQ29sdW1uTW9kZXM/Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLmNvbmZpZy5jb2x1bW5Nb2RlID0gc3VwcG9ydGVkQ29sdW1uTW9kZXNbMF0/LmtleTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gdGhlbiBzZXQgY29sdW1uLCBjb2x1bW5Nb2RlIHNob3VsZCBhbHJlYWR5IGJlZW4gc2V0XG4gICAgdGhpcy5jb25maWcuY29sdW1ucyA9IHRoaXMuZ2V0TGF5ZXJDb2x1bW5zKHByb3BzLmNvbHVtbnMpO1xuXG4gICAgLy8gZmFsc2UgaW5kaWNhdGVzIHRoYXQgdGhlIGxheWVyIGNhdXNlZCBhbiBlcnJvciwgYW5kIHdhcyBkaXNhYmxlZFxuICAgIHRoaXMuaXNWYWxpZCA9IHRydWU7XG4gICAgdGhpcy5lcnJvck1lc3NhZ2UgPSBudWxsO1xuICAgIC8vIGl0ZW0gY291bnRcbiAgICB0aGlzLmZpbHRlcmVkSXRlbUNvdW50ID0ge307XG4gIH1cblxuICBnZXQgbGF5ZXJJY29uKCk6IFJlYWN0LkVsZW1lbnRUeXBlIHtcbiAgICByZXR1cm4gRGVmYXVsdExheWVySWNvbjtcbiAgfVxuXG4gIGdldCBvdmVybGF5VHlwZSgpOiBrZXlvZiB0eXBlb2YgT1ZFUkxBWV9UWVBFX0NPTlNUIHtcbiAgICByZXR1cm4gT1ZFUkxBWV9UWVBFX0NPTlNULmRlY2tnbDtcbiAgfVxuXG4gIGdldCB0eXBlKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZ2V0IG5hbWUoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMudHlwZTtcbiAgfVxuXG4gIGdldCBpc0FnZ3JlZ2F0ZWQoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZ2V0IHJlcXVpcmVkTGF5ZXJDb2x1bW5zKCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCB7c3VwcG9ydGVkQ29sdW1uTW9kZXN9ID0gdGhpcztcbiAgICBpZiAoc3VwcG9ydGVkQ29sdW1uTW9kZXMpIHtcbiAgICAgIHJldHVybiBzdXBwb3J0ZWRDb2x1bW5Nb2Rlcy5yZWR1Y2U8c3RyaW5nW10+KFxuICAgICAgICAoYWNjLCBvYmopID0+IChvYmoucmVxdWlyZWRDb2x1bW5zID8gYWNjLmNvbmNhdChvYmoucmVxdWlyZWRDb2x1bW5zKSA6IGFjYyksXG4gICAgICAgIFtdXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gW107XG4gIH1cblxuICBnZXQgb3B0aW9uYWxDb2x1bW5zKCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCB7c3VwcG9ydGVkQ29sdW1uTW9kZXN9ID0gdGhpcztcbiAgICBpZiAoc3VwcG9ydGVkQ29sdW1uTW9kZXMpIHtcbiAgICAgIHJldHVybiBzdXBwb3J0ZWRDb2x1bW5Nb2Rlcy5yZWR1Y2U8c3RyaW5nW10+KFxuICAgICAgICAoYWNjLCBvYmopID0+IChvYmoub3B0aW9uYWxDb2x1bW5zID8gYWNjLmNvbmNhdChvYmoub3B0aW9uYWxDb2x1bW5zKSA6IGFjYyksXG4gICAgICAgIFtdXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gW107XG4gIH1cblxuICBnZXQgbm9uZUxheWVyRGF0YUFmZmVjdGluZ1Byb3BzKCkge1xuICAgIHJldHVybiBbJ2xhYmVsJywgJ29wYWNpdHknLCAndGhpY2tuZXNzJywgJ2lzVmlzaWJsZScsICdoaWRkZW4nXTtcbiAgfVxuXG4gIGdldCB2aXN1YWxDaGFubmVscygpOiBWaXN1YWxDaGFubmVscyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbG9yOiB7XG4gICAgICAgIHByb3BlcnR5OiAnY29sb3InLFxuICAgICAgICBmaWVsZDogJ2NvbG9yRmllbGQnLFxuICAgICAgICBzY2FsZTogJ2NvbG9yU2NhbGUnLFxuICAgICAgICBkb21haW46ICdjb2xvckRvbWFpbicsXG4gICAgICAgIHJhbmdlOiAnY29sb3JSYW5nZScsXG4gICAgICAgIGtleTogJ2NvbG9yJyxcbiAgICAgICAgY2hhbm5lbFNjYWxlVHlwZTogQ0hBTk5FTF9TQ0FMRVMuY29sb3IsXG4gICAgICAgIG51bGxWYWx1ZTogTk9fVkFMVUVfQ09MT1IsXG4gICAgICAgIGRlZmF1bHRWYWx1ZTogY29uZmlnID0+IGNvbmZpZy5jb2xvclxuICAgICAgfSxcbiAgICAgIHNpemU6IHtcbiAgICAgICAgcHJvcGVydHk6ICdzaXplJyxcbiAgICAgICAgZmllbGQ6ICdzaXplRmllbGQnLFxuICAgICAgICBzY2FsZTogJ3NpemVTY2FsZScsXG4gICAgICAgIGRvbWFpbjogJ3NpemVEb21haW4nLFxuICAgICAgICByYW5nZTogJ3NpemVSYW5nZScsXG4gICAgICAgIGtleTogJ3NpemUnLFxuICAgICAgICBjaGFubmVsU2NhbGVUeXBlOiBDSEFOTkVMX1NDQUxFUy5zaXplLFxuICAgICAgICBudWxsVmFsdWU6IDAsXG4gICAgICAgIGRlZmF1bHRWYWx1ZTogMVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBnZXQgY29sdW1uVmFsaWRhdG9ycygpOiB7W2tleTogc3RyaW5nXTogQ29sdW1uVmFsaWRhdG9yfSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIC8qXG4gICAqIENvbHVtbiBwYWlycyBtYXBzIGxheWVyIGNvbHVtbiB0byBhIHNwZWNpZmljIGZpZWxkIHBhaXJzLFxuICAgKiBCeSBkZWZhdWx0LCBpdCBpcyBzZXQgdG8gbnVsbFxuICAgKi9cbiAgZ2V0IGNvbHVtblBhaXJzKCk6IENvbHVtblBhaXJzIHwgbnVsbCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogQ29sdW1uIGxhYmVscyBpZiBpdHMgZGlmZmVyZW50IHRoYW4gY29sdW1uIGtleVxuICAgKi9cbiAgZ2V0IGNvbHVtbkxhYmVscygpOiBDb2x1bW5MYWJlbHMgfCBudWxsIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qXG4gICAqIERlZmF1bHQgcG9pbnQgY29sdW1uIHBhaXJzLCBjYW4gYmUgdXNlZCBmb3IgcG9pbnQgYmFzZWQgbGF5ZXJzOiBwb2ludCwgaWNvbiBldGMuXG4gICAqL1xuICBnZXQgZGVmYXVsdFBvaW50Q29sdW1uUGFpcnMoKTogQ29sdW1uUGFpcnMge1xuICAgIHJldHVybiB7XG4gICAgICBsYXQ6IHtwYWlyOiBbJ2xuZycsICdhbHRpdHVkZSddLCBmaWVsZFBhaXJLZXk6ICdsYXQnfSxcbiAgICAgIGxuZzoge3BhaXI6IFsnbGF0JywgJ2FsdGl0dWRlJ10sIGZpZWxkUGFpcktleTogJ2xuZyd9LFxuICAgICAgYWx0aXR1ZGU6IHtwYWlyOiBbJ2xuZycsICdsYXQnXSwgZmllbGRQYWlyS2V5OiAnYWx0aXR1ZGUnfVxuICAgIH07XG4gIH1cblxuICAvKlxuICAgKiBEZWZhdWx0IGxpbmsgY29sdW1uIHBhaXJzLCBjYW4gYmUgdXNlZCBmb3IgbGluayBiYXNlZCBsYXllcnM6IGFyYywgbGluZSBldGNcbiAgICovXG4gIGdldCBkZWZhdWx0TGlua0NvbHVtblBhaXJzKCk6IENvbHVtblBhaXJzIHtcbiAgICByZXR1cm4ge1xuICAgICAgbGF0OiB7cGFpcjogWydsbmcnLCAnYWx0J10sIGZpZWxkUGFpcktleTogJ2xhdCd9LFxuICAgICAgbG5nOiB7cGFpcjogWydsYXQnLCAnYWx0J10sIGZpZWxkUGFpcktleTogJ2xuZyd9LFxuICAgICAgYWx0OiB7cGFpcjogWydsbmcnLCAnbGF0J10sIGZpZWxkUGFpcktleTogJ2FsdGl0dWRlJ30sXG5cbiAgICAgIGxhdDA6IHtwYWlyOiAnbG5nMCcsIGZpZWxkUGFpcktleTogJ2xhdCd9LFxuICAgICAgbG5nMDoge3BhaXI6ICdsYXQwJywgZmllbGRQYWlyS2V5OiAnbG5nJ30sXG4gICAgICBhbHQwOiB7cGFpcjogWydsbmcwJywgJ2xhdDAnXSwgZmllbGRQYWlyS2V5OiAnYWx0aXR1ZGUnfSxcblxuICAgICAgbGF0MToge3BhaXI6ICdsbmcxJywgZmllbGRQYWlyS2V5OiAnbGF0J30sXG4gICAgICBsbmcxOiB7cGFpcjogJ2xhdDEnLCBmaWVsZFBhaXJLZXk6ICdsbmcnfSxcbiAgICAgIGFsdDE6IHtwYWlyOiBbJ2xuZzEnLCAnbGF0MSddLCBmaWVsZFBhaXJLZXk6ICdhbHRpdHVkZSd9XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBSZWFjdCBjb21wb25lbnQgZm9yIHRvIHJlbmRlciBsYXllciBpbnN0cnVjdGlvbnMgaW4gYSBtb2RhbFxuICAgKiBAcmV0dXJucyB7b2JqZWN0fSAtIGFuIG9iamVjdFxuICAgKiBAZXhhbXBsZVxuICAgKiAgcmV0dXJuIHtcbiAgICogICAgaWQ6ICdpY29uSW5mbycsXG4gICAqICAgIHRlbXBsYXRlOiBJY29uSW5mb01vZGFsLFxuICAgKiAgICBtb2RhbFByb3BzOiB7XG4gICAqICAgICAgdGl0bGU6ICdIb3cgdG8gZHJhdyBpY29ucydcbiAgICogICB9O1xuICAgKiB9XG4gICAqL1xuICBnZXQgbGF5ZXJJbmZvTW9kYWwoKTogTGF5ZXJJbmZvTW9kYWwgfCBSZWNvcmQ8c3RyaW5nLCBMYXllckluZm9Nb2RhbD4gfCBudWxsIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoaWNoIGNvbHVtbiBtb2RlcyB0aGlzIGxheWVyIHN1cHBvcnRzXG4gICAqL1xuICBnZXQgc3VwcG9ydGVkQ29sdW1uTW9kZXMoKTogU3VwcG9ydGVkQ29sdW1uTW9kZVtdIHwgbnVsbCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBnZXQgc3VwcG9ydGVkRGF0YXNldFR5cGVzKCk6IHN0cmluZ1tdIHwgbnVsbCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKlxuICAgKiBHaXZlbiBhIGRhdGFzZXQsIGF1dG9tYXRpY2FsbHkgZmluZCBwcm9wcyB0byBjcmVhdGUgbGF5ZXIgYmFzZWQgb24gaXRcbiAgICogYW5kIHJldHVybiB0aGUgcHJvcHMgYW5kIHByZXZpb3VzIGZvdW5kIGxheWVycy5cbiAgICogQnkgZGVmYXVsdCwgbm8gbGF5ZXJzIHdpbGwgYmUgZm91bmRcbiAgICovXG4gIHN0YXRpYyBmaW5kRGVmYXVsdExheWVyUHJvcHMoXG4gICAgZGF0YXNldDogS2VwbGVyVGFibGUsXG4gICAgZm91bmRMYXllcnM/OiBhbnlbXVxuICApOiBGaW5kRGVmYXVsdExheWVyUHJvcHNSZXR1cm5WYWx1ZSB7XG4gICAgcmV0dXJuIHtwcm9wczogW10sIGZvdW5kTGF5ZXJzfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIGFycmF5IG9mIHByZXNldCByZXF1aXJlZCBjb2x1bW4gbmFtZXNcbiAgICogZm91bmQgZmllbGQgdGhhdCBoYXMgdGhlIHNhbWUgbmFtZSB0byBzZXQgYXMgbGF5ZXIgY29sdW1uXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBkZWZhdWx0RmllbGRzXG4gICAqIEBwYXJhbSB7b2JqZWN0W119IGFsbEZpZWxkc1xuICAgKiBAcmV0dXJucyB7b2JqZWN0W10gfCBudWxsfSBhbGwgcG9zc2libGUgcmVxdWlyZWQgbGF5ZXIgY29sdW1uIHBhaXJzXG4gICAqL1xuICBzdGF0aWMgZmluZERlZmF1bHRDb2x1bW5GaWVsZChkZWZhdWx0RmllbGRzLCBhbGxGaWVsZHMpIHtcbiAgICAvLyBmaW5kIGFsbCBtYXRjaGVkIGZpZWxkcyBmb3IgZWFjaCByZXF1aXJlZCBjb2xcbiAgICBjb25zdCByZXF1aXJlZENvbHVtbnMgPSBPYmplY3Qua2V5cyhkZWZhdWx0RmllbGRzKS5yZWR1Y2UoKHByZXYsIGtleSkgPT4ge1xuICAgICAgY29uc3QgcmVxdWlyZWRGaWVsZHMgPSBhbGxGaWVsZHMuZmlsdGVyKFxuICAgICAgICBmID0+IGYubmFtZSA9PT0gZGVmYXVsdEZpZWxkc1trZXldIHx8IGRlZmF1bHRGaWVsZHNba2V5XS5pbmNsdWRlcyhmLm5hbWUpXG4gICAgICApO1xuXG4gICAgICBwcmV2W2tleV0gPSByZXF1aXJlZEZpZWxkcy5sZW5ndGhcbiAgICAgICAgPyByZXF1aXJlZEZpZWxkcy5tYXAoZiA9PiAoe1xuICAgICAgICAgICAgdmFsdWU6IGYubmFtZSxcbiAgICAgICAgICAgIGZpZWxkSWR4OiBmLmZpZWxkSWR4XG4gICAgICAgICAgfSkpXG4gICAgICAgIDogbnVsbDtcbiAgICAgIHJldHVybiBwcmV2O1xuICAgIH0sIHt9KTtcblxuICAgIGlmICghT2JqZWN0LnZhbHVlcyhyZXF1aXJlZENvbHVtbnMpLmV2ZXJ5KEJvb2xlYW4pKSB7XG4gICAgICAvLyBpZiBhbnkgZmllbGQgbWlzc2luZywgcmV0dXJuIG51bGxcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmdldEFsbFBvc3NpYmxlQ29sdW1uUGFpcnMocmVxdWlyZWRDb2x1bW5zKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRBbGxQb3NzaWJsZUNvbHVtblBhaXJzKHJlcXVpcmVkQ29sdW1ucykge1xuICAgIC8vIGZvciBtdWx0aXBsZSBtYXRjaGVkIGZpZWxkIGZvciBvbmUgcmVxdWlyZWQgY29sdW1uLCByZXR1cm4gbXVsdGlwbGVcbiAgICAvLyBjb21iaW5hdGlvbnMsIGUuIGcuIGlmIGNvbHVtbiBhIGhhcyAyIG1hdGNoZWQsIGNvbHVtbiBiIGhhcyAzIG1hdGNoZWRcbiAgICAvLyA2IHBvc3NpYmxlIGNvbHVtbiBwYWlycyB3aWxsIGJlIHJldHVybmVkXG4gICAgY29uc3QgYWxsS2V5cyA9IE9iamVjdC5rZXlzKHJlcXVpcmVkQ29sdW1ucyk7XG4gICAgY29uc3QgcG9pbnRlcnMgPSBhbGxLZXlzLm1hcCgoaywgaSkgPT4gKGkgPT09IGFsbEtleXMubGVuZ3RoIC0gMSA/IC0xIDogMCkpO1xuICAgIGNvbnN0IGNvdW50UGVyS2V5ID0gYWxsS2V5cy5tYXAoayA9PiByZXF1aXJlZENvbHVtbnNba10ubGVuZ3RoKTtcbiAgICAvLyBUT0RPOiBCZXR0ZXIgdHlwaW5nc1xuICAgIGNvbnN0IHBhaXJzOiBhbnlbXSA9IFtdO1xuXG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tbG9vcC1mdW5jICovXG4gICAgd2hpbGUgKGluY3JlbWVudFBvaW50ZXJzKHBvaW50ZXJzLCBjb3VudFBlcktleSwgcG9pbnRlcnMubGVuZ3RoIC0gMSkpIHtcbiAgICAgIGNvbnN0IG5ld1BhaXIgPSBwb2ludGVycy5yZWR1Y2UoKHByZXYsIGN1dXIsIGkpID0+IHtcbiAgICAgICAgcHJldlthbGxLZXlzW2ldXSA9IHJlcXVpcmVkQ29sdW1uc1thbGxLZXlzW2ldXVtjdXVyXTtcbiAgICAgICAgcmV0dXJuIHByZXY7XG4gICAgICB9LCB7fSk7XG5cbiAgICAgIHBhaXJzLnB1c2gobmV3UGFpcik7XG4gICAgfVxuICAgIC8qIGVzbGludC1lbmFibGUgbm8tbG9vcC1mdW5jICovXG5cbiAgICAvLyByZWN1cnNpdmVseSBpbmNyZW1lbnQgcG9pbnRlcnNcbiAgICBmdW5jdGlvbiBpbmNyZW1lbnRQb2ludGVycyhwdHMsIGNvdW50cywgaW5kZXgpIHtcbiAgICAgIGlmIChpbmRleCA9PT0gMCAmJiBwdHNbMF0gPT09IGNvdW50c1swXSAtIDEpIHtcbiAgICAgICAgLy8gbm90aGluZyB0byBpbmNyZW1lbnRcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAocHRzW2luZGV4XSArIDEgPCBjb3VudHNbaW5kZXhdKSB7XG4gICAgICAgIHB0c1tpbmRleF0gPSBwdHNbaW5kZXhdICsgMTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHB0c1tpbmRleF0gPSAwO1xuICAgICAgcmV0dXJuIGluY3JlbWVudFBvaW50ZXJzKHB0cywgY291bnRzLCBpbmRleCAtIDEpO1xuICAgIH1cblxuICAgIHJldHVybiBwYWlycztcbiAgfVxuXG4gIHN0YXRpYyBoZXhUb1JnYihjKSB7XG4gICAgcmV0dXJuIGhleFRvUmdiKGMpO1xuICB9XG5cbiAgZ2V0RGVmYXVsdExheWVyQ29uZmlnKFxuICAgIHByb3BzOiBMYXllckJhc2VDb25maWdQYXJ0aWFsXG4gICk6IExheWVyQmFzZUNvbmZpZyAmIFBhcnRpYWw8TGF5ZXJDb2xvckNvbmZpZyAmIExheWVyU2l6ZUNvbmZpZz4ge1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhSWQ6IHByb3BzLmRhdGFJZCxcbiAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCB8fCBERUZBVUxUX0xBWUVSX0xBQkVMLFxuICAgICAgY29sb3I6IHByb3BzLmNvbG9yIHx8IGNvbG9yTWFrZXIubmV4dCgpLnZhbHVlLFxuICAgICAgLy8gc2V0IGNvbHVtbnMgbGF0ZXJcbiAgICAgIGNvbHVtbnM6IHt9LFxuICAgICAgaXNWaXNpYmxlOiBwcm9wcy5pc1Zpc2libGUgPz8gdHJ1ZSxcbiAgICAgIGlzQ29uZmlnQWN0aXZlOiBwcm9wcy5pc0NvbmZpZ0FjdGl2ZSA/PyBmYWxzZSxcbiAgICAgIGhpZ2hsaWdodENvbG9yOiBwcm9wcy5oaWdobGlnaHRDb2xvciB8fCBERUZBVUxUX0hJR0hMSUdIVF9DT0xPUixcbiAgICAgIGhpZGRlbjogcHJvcHMuaGlkZGVuID8/IGZhbHNlLFxuXG4gICAgICAvLyBUT0RPOiByZWZhY3RvciB0aGlzIGludG8gc2VwYXJhdGUgdmlzdWFsIENoYW5uZWwgY29uZmlnXG4gICAgICAvLyBjb2xvciBieSBmaWVsZCwgZG9tYWluIGlzIHNldCBieSBmaWx0ZXJzLCBmaWVsZCwgc2NhbGUgdHlwZVxuICAgICAgY29sb3JGaWVsZDogbnVsbCxcbiAgICAgIGNvbG9yRG9tYWluOiBbMCwgMV0sXG4gICAgICBjb2xvclNjYWxlOiBTQ0FMRV9UWVBFUy5xdWFudGlsZSxcblxuICAgICAgLy8gY29sb3IgYnkgc2l6ZSwgZG9tYWluIGlzIHNldCBieSBmaWx0ZXJzLCBmaWVsZCwgc2NhbGUgdHlwZVxuICAgICAgc2l6ZURvbWFpbjogWzAsIDFdLFxuICAgICAgc2l6ZVNjYWxlOiBTQ0FMRV9UWVBFUy5saW5lYXIsXG4gICAgICBzaXplRmllbGQ6IG51bGwsXG5cbiAgICAgIHZpc0NvbmZpZzoge30sXG5cbiAgICAgIHRleHRMYWJlbDogW0RFRkFVTFRfVEVYVF9MQUJFTF0sXG5cbiAgICAgIGNvbG9yVUk6IHtcbiAgICAgICAgY29sb3I6IERFRkFVTFRfQ09MT1JfVUksXG4gICAgICAgIGNvbG9yUmFuZ2U6IERFRkFVTFRfQ09MT1JfVUlcbiAgICAgIH0sXG4gICAgICBhbmltYXRpb246IHtlbmFibGVkOiBmYWxzZX0sXG4gICAgICAuLi4ocHJvcHMuY29sdW1uTW9kZSA/IHtjb2x1bW5Nb2RlOiBwcm9wcy5jb2x1bW5Nb2RlfSA6IHt9KVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBkZXNjcmlwdGlvbiBvZiBhIHZpc3VhbENoYW5uZWwgY29uZmlnXG4gICAqIEBwYXJhbSBrZXlcbiAgICogQHJldHVybnNcbiAgICovXG4gIGdldFZpc3VhbENoYW5uZWxEZXNjcmlwdGlvbihrZXk6IHN0cmluZyk6IFZpc3VhbENoYW5uZWxEZXNjcmlwdGlvbiB7XG4gICAgLy8gZS5nLiBsYWJlbDogQ29sb3IsIG1lYXN1cmU6IFZlaGljbGUgVHlwZVxuICAgIGNvbnN0IGNoYW5uZWwgPSB0aGlzLnZpc3VhbENoYW5uZWxzW2tleV07XG4gICAgaWYgKCFjaGFubmVsKSByZXR1cm4ge2xhYmVsOiAnJywgbWVhc3VyZTogdW5kZWZpbmVkfTtcbiAgICBjb25zdCByYW5nZVNldHRpbmdzID0gdGhpcy52aXNDb25maWdTZXR0aW5nc1tjaGFubmVsLnJhbmdlXTtcbiAgICBjb25zdCBmaWVsZFNldHRpbmdzID0gdGhpcy5jb25maWdbY2hhbm5lbC5maWVsZF07XG4gICAgY29uc3QgbGFiZWwgPSByYW5nZVNldHRpbmdzPy5sYWJlbDtcbiAgICByZXR1cm4ge1xuICAgICAgbGFiZWw6IHR5cGVvZiBsYWJlbCA9PT0gJ2Z1bmN0aW9uJyA/IGxhYmVsKHRoaXMuY29uZmlnKSA6IGxhYmVsIHx8ICcnLFxuICAgICAgbWVhc3VyZTogZmllbGRTZXR0aW5nc1xuICAgICAgICA/IGZpZWxkU2V0dGluZ3MuZGlzcGxheU5hbWUgfHwgZmllbGRTZXR0aW5ncy5uYW1lXG4gICAgICAgIDogY2hhbm5lbC5kZWZhdWx0TWVhc3VyZVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQXNzaWduIGEgZmllbGQgdG8gbGF5ZXIgY29sdW1uLCByZXR1cm4gY29sdW1uIGNvbmZpZ1xuICAgKi9cbiAgYXNzaWduQ29sdW1uKGtleTogc3RyaW5nLCBmaWVsZDoge25hbWU6IHN0cmluZzsgZmllbGRJZHg6IG51bWJlcn0pOiBMYXllckNvbHVtbnMge1xuICAgIC8vIGZpZWxkIHZhbHVlIGNvdWxkIGJlIG51bGwgZm9yIG9wdGlvbmFsIGNvbHVtbnNcbiAgICBjb25zdCB1cGRhdGUgPSBmaWVsZFxuICAgICAgPyB7XG4gICAgICAgICAgdmFsdWU6IGZpZWxkLm5hbWUsXG4gICAgICAgICAgZmllbGRJZHg6IGZpZWxkLmZpZWxkSWR4XG4gICAgICAgIH1cbiAgICAgIDoge3ZhbHVlOiBudWxsLCBmaWVsZElkeDogLTF9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMuY29uZmlnLmNvbHVtbnMsXG4gICAgICBba2V5XToge1xuICAgICAgICAuLi50aGlzLmNvbmZpZy5jb2x1bW5zPy5ba2V5XSxcbiAgICAgICAgLi4udXBkYXRlXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3NpZ24gYSBmaWVsZCBwYWlyIHRvIGNvbHVtbiBjb25maWcsIHJldHVybiBjb2x1bW4gY29uZmlnXG4gICAqL1xuICBhc3NpZ25Db2x1bW5QYWlycyhrZXk6IHN0cmluZywgZmllbGRQYWlyczogRmllbGRQYWlyKTogTGF5ZXJDb2x1bW5zIHtcbiAgICBpZiAoIXRoaXMuY29sdW1uUGFpcnMgfHwgIXRoaXMuY29sdW1uUGFpcnM/LltrZXldKSB7XG4gICAgICAvLyBzaG91bGQgbm90IGVuZCBpbiB0aGlzIHN0YXRlXG4gICAgICByZXR1cm4gdGhpcy5jb25maWcuY29sdW1ucztcbiAgICB9XG4gICAgLy8ga2V5ID0gJ2xhdCdcbiAgICBjb25zdCB7cGFpciwgZmllbGRQYWlyS2V5fSA9IHRoaXMuY29sdW1uUGFpcnM/LltrZXldIHx8IHt9O1xuXG4gICAgaWYgKHR5cGVvZiBmaWVsZFBhaXJLZXkgPT09ICdzdHJpbmcnICYmICFmaWVsZFBhaXJzW2ZpZWxkUGFpcktleV0pIHtcbiAgICAgIC8vIGRvIG5vdCBhbGxvdyBga2V5OiB1bmRlZmluZWRgIHRvIGNyZWVwIGludG8gdGhlIGB1cGRhdGVkQ29sdW1uYCBvYmplY3RcbiAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5jb2x1bW5zO1xuICAgIH1cblxuICAgIC8vIHBhaXIgPSBbJ2xuZycsICdhbHRdIHwgJ2xuZydcbiAgICBjb25zdCB1cGRhdGVkQ29sdW1uID0ge1xuICAgICAgLi4udGhpcy5jb25maWcuY29sdW1ucyxcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgZmllbGRQYWlyS2V5IGNhbiBiZSBzdHJpbmdbXSBoZXJlP1xuICAgICAgW2tleV06IGZpZWxkUGFpcnNbZmllbGRQYWlyS2V5XVxuICAgIH07XG5cbiAgICBjb25zdCBwYXJ0bmVyS2V5cyA9IHRvQXJyYXkocGFpcik7XG4gICAgZm9yIChjb25zdCBwYXJ0bmVyS2V5IG9mIHBhcnRuZXJLZXlzKSB7XG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuY29uZmlnLmNvbHVtbnNbcGFydG5lcktleV0gJiZcbiAgICAgICAgdGhpcy5jb2x1bW5QYWlycz8uW3BhcnRuZXJLZXldICYmXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgZmllbGRQYWlyc1t0aGlzLmNvbHVtblBhaXJzPy5bcGFydG5lcktleV0uZmllbGRQYWlyS2V5XVxuICAgICAgKSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdXBkYXRlZENvbHVtbltwYXJ0bmVyS2V5XSA9IGZpZWxkUGFpcnNbdGhpcy5jb2x1bW5QYWlycz8uW3BhcnRuZXJLZXldLmZpZWxkUGFpcktleV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHVwZGF0ZWRDb2x1bW47XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIGEgcmFkaXVzIHpvb20gbXVsdGlwbGllciB0byByZW5kZXIgcG9pbnRzLCBzbyB0aGV5IGFyZSB2aXNpYmxlIGluIGFsbCB6b29tIGxldmVsXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBtYXBTdGF0ZVxuICAgKiBAcGFyYW0ge251bWJlcn0gbWFwU3RhdGUuem9vbSAtIGFjdHVhbCB6b29tXG4gICAqIEBwYXJhbSB7bnVtYmVyIHwgdm9pZH0gbWFwU3RhdGUuem9vbU9mZnNldCAtIHpvb21PZmZzZXQgd2hlbiByZW5kZXIgaW4gdGhlIHBsb3QgY29udGFpbmVyIGZvciBleHBvcnQgaW1hZ2VcbiAgICogQHJldHVybnMge251bWJlcn1cbiAgICovXG4gIGdldFpvb21GYWN0b3Ioe3pvb20sIHpvb21PZmZzZXQgPSAwfSkge1xuICAgIHJldHVybiBNYXRoLnBvdygyLCBNYXRoLm1heCgxNCAtIHpvb20gKyB6b29tT2Zmc2V0LCAwKSk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIGEgZWxldmF0aW9uIHpvb20gbXVsdGlwbGllciB0byByZW5kZXIgcG9pbnRzLCBzbyB0aGV5IGFyZSB2aXNpYmxlIGluIGFsbCB6b29tIGxldmVsXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBtYXBTdGF0ZVxuICAgKiBAcGFyYW0ge251bWJlcn0gbWFwU3RhdGUuem9vbSAtIGFjdHVhbCB6b29tXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gbWFwU3RhdGUuem9vbU9mZnNldCAtIHpvb21PZmZzZXQgd2hlbiByZW5kZXIgaW4gdGhlIHBsb3QgY29udGFpbmVyIGZvciBleHBvcnQgaW1hZ2VcbiAgICogQHJldHVybnMge251bWJlcn1cbiAgICovXG4gIGdldEVsZXZhdGlvblpvb21GYWN0b3Ioe3pvb20sIHpvb21PZmZzZXQgPSAwfToge3pvb206IG51bWJlcjsgem9vbU9mZnNldD86IG51bWJlcn0pOiBudW1iZXIge1xuICAgIC8vIGVuYWJsZUVsZXZhdGlvblpvb21GYWN0b3IgaXMgdXNlZCB0byBzdXBwb3J0IGV4aXN0aW5nIG1hcHNcbiAgICBjb25zdCB7Zml4ZWRIZWlnaHQsIGVuYWJsZUVsZXZhdGlvblpvb21GYWN0b3J9ID0gdGhpcy5jb25maWcudmlzQ29uZmlnO1xuICAgIHJldHVybiBmaXhlZEhlaWdodCB8fCBlbmFibGVFbGV2YXRpb25ab29tRmFjdG9yID09PSBmYWxzZVxuICAgICAgPyAxXG4gICAgICA6IE1hdGgucG93KDIsIE1hdGgubWF4KDggLSB6b29tICsgem9vbU9mZnNldCwgMCkpO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBmb3JtYXRMYXllckRhdGEoZGF0YXNldHM6IERhdGFzZXRzLCBvbGRMYXllckRhdGE/OiB1bmtub3duLCBhbmltYXRpb25Db25maWc/OiBBbmltYXRpb25Db25maWcpIHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIHJlbmRlckxheWVyKC4uLmFyZ3M6IGFueVtdKTogYW55W10ge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgZ2V0SG92ZXJEYXRhKFxuICAgIG9iamVjdDogYW55LFxuICAgIGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2UsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIGZpZWxkcz86IEZpZWxkW10sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIGFuaW1hdGlvbkNvbmZpZz86IEFuaW1hdGlvbkNvbmZpZyxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgaG92ZXJJbmZvPzoge2luZGV4OiBudW1iZXJ9XG4gICk6IGFueSB7XG4gICAgaWYgKCFvYmplY3QpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIEJ5IGRlZmF1bHQsIGVhY2ggZW50cnkgb2YgbGF5ZXJEYXRhIHNob3VsZCBoYXZlIGFuIGluZGV4IG9mIGEgcm93IGluIHRoZSBvcmlnaW5hbCBkYXRhIGNvbnRhaW5lci5cbiAgICAvLyBFYWNoIGxheWVyIGNhbiBpbXBsZW1lbnQgaXRzIG93biBnZXRIb3ZlckRhdGEgbWV0aG9kXG4gICAgcmV0dXJuIGRhdGFDb250YWluZXIucm93KG9iamVjdC5pbmRleCk7XG4gIH1cblxuICBnZXRGaWx0ZXJlZEl0ZW1Db3VudCgpOiBudW1iZXIgfCBudWxsIHtcbiAgICAvLyB1c2UgZmlyc3QgbGF5ZXJcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5maWx0ZXJlZEl0ZW1Db3VudCkubGVuZ3RoKSB7XG4gICAgICBjb25zdCBmaXJzdExheWVyID0gT2JqZWN0LmtleXModGhpcy5maWx0ZXJlZEl0ZW1Db3VudClbMF07XG4gICAgICByZXR1cm4gdGhpcy5maWx0ZXJlZEl0ZW1Db3VudFtmaXJzdExheWVyXTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgLyoqXG4gICAqIFdoZW4gY2hhbmdlIGxheWVyIHR5cGUsIHRyeSB0byBjb3B5IG92ZXIgbGF5ZXIgY29uZmlncyBhcyBtdWNoIGFzIHBvc3NpYmxlXG4gICAqIEBwYXJhbSBjb25maWdUb0NvcHkgLSBjb25maWcgdG8gY29weSBvdmVyXG4gICAqIEBwYXJhbSB2aXNDb25maWdTZXR0aW5ncyAtIHZpc0NvbmZpZyBzZXR0aW5ncyBvZiBjb25maWcgdG8gY29weVxuICAgKiBAcGFyYW0gZGF0YXNldHMgLSBjdXJyZW50IGRhdGFzZXRzLlxuICAgKiBAcGFyYW0gZGVmYXVsdExheWVyUHJvcHMgLSBkZWZhdWx0IGxheWVyIGNyZWF0aW9uIGNvbmZpZ3VyYXRpb25zIGZvciBjdXJyZW50IGxheWVyIGFuZCBkYXRhc2V0cy5cbiAgICovXG4gIGFzc2lnbkNvbmZpZ1RvTGF5ZXIoXG4gICAgY29uZmlnVG9Db3B5OiBMYXllckJhc2VDb25maWcgJiBQYXJ0aWFsPExheWVyQ29sb3JDb25maWcgJiBMYXllclNpemVDb25maWc+LFxuICAgIHZpc0NvbmZpZ1NldHRpbmdzOiB7W2tleTogc3RyaW5nXTogVmFsdWVPZjxMYXllclZpc0NvbmZpZ1NldHRpbmdzPn0sXG4gICAgZGF0YXNldHM/OiBEYXRhc2V0cyxcbiAgICBkZWZhdWx0TGF5ZXJQcm9wcz86IEZpbmREZWZhdWx0TGF5ZXJQcm9wc1JldHVyblZhbHVlIHwgbnVsbFxuICApIHtcbiAgICAvLyBkb24ndCBkZWVwIG1lcmdlIHZpc3VhbENoYW5uZWwgZmllbGRcbiAgICAvLyBkb24ndCBkZWVwIG1lcmdlIGNvbG9yIHJhbmdlLCByZXZlcnNlZDogaXMgbm90IGEga2V5IGJ5IGRlZmF1bHRcbiAgICBjb25zdCBzaGFsbG93Q29weSA9IFsnY29sb3JSYW5nZScsICdzdHJva2VDb2xvclJhbmdlJ10uY29uY2F0KFxuICAgICAgT2JqZWN0LnZhbHVlcyh0aGlzLnZpc3VhbENoYW5uZWxzKS5tYXAodiA9PiB2LmZpZWxkKVxuICAgICk7XG5cbiAgICAvLyBkb24ndCBjb3B5IG92ZXIgZG9tYWluIGFuZCBhbmltYXRpb25cbiAgICBjb25zdCBub3RUb0NvcHkgPSBbJ2FuaW1hdGlvbiddLmNvbmNhdChPYmplY3QudmFsdWVzKHRoaXMudmlzdWFsQ2hhbm5lbHMpLm1hcCh2ID0+IHYuZG9tYWluKSk7XG4gICAgLy8gaWYgcmFuZ2UgaXMgZm9yIHRoZSBzYW1lIHByb3BlcnR5IGdyb3VwIGNvcHkgaXQsIG90aGVyd2lzZSwgbm90IHRvIGNvcHlcbiAgICBPYmplY3QudmFsdWVzKHRoaXMudmlzdWFsQ2hhbm5lbHMpLmZvckVhY2godiA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIGNvbmZpZ1RvQ29weS52aXNDb25maWdbdi5yYW5nZV0gJiZcbiAgICAgICAgdGhpcy52aXNDb25maWdTZXR0aW5nc1t2LnJhbmdlXSAmJlxuICAgICAgICB2aXNDb25maWdTZXR0aW5nc1t2LnJhbmdlXS5ncm91cCAhPT0gdGhpcy52aXNDb25maWdTZXR0aW5nc1t2LnJhbmdlXS5ncm91cFxuICAgICAgKSB7XG4gICAgICAgIG5vdFRvQ29weS5wdXNoKHYucmFuZ2UpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gZG9uJ3QgY29weSBvdmVyIHZpc3VhbENoYW5uZWwgcmFuZ2VcbiAgICBjb25zdCBjdXJyZW50Q29uZmlnID0gdGhpcy5jb25maWc7XG4gICAgY29uc3QgY29waWVkID0gdGhpcy5jb3B5TGF5ZXJDb25maWcoY3VycmVudENvbmZpZywgY29uZmlnVG9Db3B5LCB7XG4gICAgICBzaGFsbG93Q29weSxcbiAgICAgIG5vdFRvQ29weVxuICAgIH0pO1xuXG4gICAgLy8gdXBkYXRlIGNvbHVtTm9kZSBiYXNlZCBvbiBuZXcgY29sdW1uc1xuICAgIGlmICh0aGlzLmNvbmZpZy5jb2x1bW5Nb2RlICYmIHRoaXMuc3VwcG9ydGVkQ29sdW1uTW9kZXMpIHtcbiAgICAgIGNvbnN0IGRhdGFzZXQgPSBkYXRhc2V0cz8uW3RoaXMuY29uZmlnLmRhdGFJZF07XG4gICAgICAvLyB0cnkgdG8gZmluZCBhIG1vZGUgd2l0aCBhbGwgcmVxdWllZCBjb2x1bW5zIGZyb20gdGhlIHNvdXJjZSBjb25maWdcbiAgICAgIGxldCBzYXRpc2ZpZWRDb2x1bW5Nb2RlID0gZ2V0U2F0aXNmaWVkQ29sdW1uTW9kZShcbiAgICAgICAgdGhpcy5zdXBwb3J0ZWRDb2x1bW5Nb2RlcyxcbiAgICAgICAgY29waWVkLmNvbHVtbnMsXG4gICAgICAgIGRhdGFzZXQ/LmZpZWxkc1xuICAgICAgKTtcblxuICAgICAgLy8gaWYgbm8gc3VpdGFibGUgY29sdW1uIG1vZGUgZm91bmQgb3Igbm8gc3VjaCBjb2x1bU1vZGUgZXhpc3RzIGZvciB0aGUgbGF5ZXJcbiAgICAgIC8vIHRoZW4gdHJ5IHVzZSBvbmUgb2YgdGhlIGF1dG9tYXRpY2FsbHkgZGV0ZWN0ZWQgbGF5ZXIgY29uZmlnc1xuICAgICAgaWYgKCFzYXRpc2ZpZWRDb2x1bW5Nb2RlKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBbXG4gICAgICAgICAgLi4uKGRlZmF1bHRMYXllclByb3BzPy5wcm9wcyB8fCBbXSksXG4gICAgICAgICAgLi4uKGRlZmF1bHRMYXllclByb3BzPy5hbHRQcm9wcyB8fCBbXSlcbiAgICAgICAgXTtcbiAgICAgICAgaWYgKG9wdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgLy8gVXNlIHRoZSBmaXJzdCBvZiB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uc1xuICAgICAgICAgIGNvbnN0IGRlZmF1bHRDb2x1bW5Db25maWcgPSBvcHRpb25zWzBdLmNvbHVtbnM7XG5cbiAgICAgICAgICBzYXRpc2ZpZWRDb2x1bW5Nb2RlID0gZ2V0U2F0aXNmaWVkQ29sdW1uTW9kZShcbiAgICAgICAgICAgIHRoaXMuc3VwcG9ydGVkQ29sdW1uTW9kZXMsXG4gICAgICAgICAgICBkZWZhdWx0Q29sdW1uQ29uZmlnLFxuICAgICAgICAgICAgZGF0YXNldD8uZmllbGRzXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChzYXRpc2ZpZWRDb2x1bW5Nb2RlKSB7XG4gICAgICAgICAgICBjb3BpZWQuY29sdW1ucyA9IHtcbiAgICAgICAgICAgICAgLi4uY29waWVkLmNvbHVtbnMsXG4gICAgICAgICAgICAgIC4uLmRlZmF1bHRDb2x1bW5Db25maWdcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvcGllZC5jb2x1bW5Nb2RlID0gc2F0aXNmaWVkQ29sdW1uTW9kZT8ua2V5IHx8IGNvcGllZC5jb2x1bW5Nb2RlO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlTGF5ZXJDb25maWcoY29waWVkKTtcbiAgICAvLyB2YWxpZGF0ZSB2aXN1YWxDaGFubmVsIGZpZWxkIHR5cGUgYW5kIHNjYWxlIHR5cGVzXG4gICAgT2JqZWN0LmtleXModGhpcy52aXN1YWxDaGFubmVscykuZm9yRWFjaChjaGFubmVsID0+IHtcbiAgICAgIHRoaXMudmFsaWRhdGVWaXN1YWxDaGFubmVsKGNoYW5uZWwpO1xuICAgIH0pO1xuICB9XG5cbiAgLypcbiAgICogUmVjdXJzaXZlbHkgY29weSBjb25maWcgb3ZlciB0byBhbiBlbXB0eSBsYXllclxuICAgKiB3aGVuIHJlY2VpdmVkIHNhdmVkIGNvbmZpZywgb3IgY29weSBjb25maWcgb3ZlciBmcm9tIGEgZGlmZmVyZW50IGxheWVyIHR5cGVcbiAgICogbWFrZSBzdXJlIHRvIG9ubHkgY29weSBvdmVyIHZhbHVlIHRvIGV4aXN0aW5nIGtleXNcbiAgICogQHBhcmFtIHtvYmplY3R9IGN1cnJlbnRDb25maWcgLSBleGlzdGluZyBjb25maWcgdG8gYmUgb3ZlcnJpZGVcbiAgICogQHBhcmFtIHtvYmplY3R9IGNvbmZpZ1RvQ29weSAtIG5ldyBDb25maWcgdG8gY29weSBvdmVyXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IHNoYWxsb3dDb3B5IC0gYXJyYXkgb2YgcHJvcGVydGllcyB0byBub3QgdG8gYmUgZGVlcCBjb3BpZWRcbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gbm90VG9Db3B5IC0gYXJyYXkgb2YgcHJvcGVydGllcyBub3QgdG8gY29weVxuICAgKiBAcmV0dXJucyB7b2JqZWN0fSAtIGNvcGllZCBjb25maWdcbiAgICovXG4gIGNvcHlMYXllckNvbmZpZyhcbiAgICBjdXJyZW50Q29uZmlnLFxuICAgIGNvbmZpZ1RvQ29weSxcbiAgICB7c2hhbGxvd0NvcHkgPSBbXSwgbm90VG9Db3B5ID0gW119OiB7c2hhbGxvd0NvcHk/OiBzdHJpbmdbXTsgbm90VG9Db3B5Pzogc3RyaW5nW119ID0ge31cbiAgKSB7XG4gICAgY29uc3QgY29waWVkOiB7Y29sdW1uTW9kZT86IHN0cmluZzsgY29sdW1ucz86IExheWVyQ29sdW1uc30gPSB7fTtcbiAgICBPYmplY3Qua2V5cyhjdXJyZW50Q29uZmlnKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIGlzUGxhaW5PYmplY3QoY3VycmVudENvbmZpZ1trZXldKSAmJlxuICAgICAgICBpc1BsYWluT2JqZWN0KGNvbmZpZ1RvQ29weVtrZXldKSAmJlxuICAgICAgICAhc2hhbGxvd0NvcHkuaW5jbHVkZXMoa2V5KSAmJlxuICAgICAgICAhbm90VG9Db3B5LmluY2x1ZGVzKGtleSlcbiAgICAgICkge1xuICAgICAgICAvLyByZWN1cnNpdmVseSBhc3NpZ24gb2JqZWN0IHZhbHVlXG4gICAgICAgIGNvcGllZFtrZXldID0gdGhpcy5jb3B5TGF5ZXJDb25maWcoY3VycmVudENvbmZpZ1trZXldLCBjb25maWdUb0NvcHlba2V5XSwge1xuICAgICAgICAgIHNoYWxsb3dDb3B5LFxuICAgICAgICAgIG5vdFRvQ29weVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAobm90TnVsbG9yVW5kZWZpbmVkKGNvbmZpZ1RvQ29weVtrZXldKSAmJiAhbm90VG9Db3B5LmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgLy8gY29weVxuICAgICAgICBjb3BpZWRba2V5XSA9IGNvbmZpZ1RvQ29weVtrZXldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8ga2VlcCBleGlzdGluZ1xuICAgICAgICBjb3BpZWRba2V5XSA9IGN1cnJlbnRDb25maWdba2V5XTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBjb3BpZWQ7XG4gIH1cblxuICByZWdpc3RlclZpc0NvbmZpZyhsYXllclZpc0NvbmZpZ3M6IHtcbiAgICBba2V5OiBzdHJpbmddOiBrZXlvZiBMYXllclZpc0NvbmZpZ1NldHRpbmdzIHwgVmFsdWVPZjxMYXllclZpc0NvbmZpZ1NldHRpbmdzPjtcbiAgfSkge1xuICAgIE9iamVjdC5rZXlzKGxheWVyVmlzQ29uZmlncykuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZ0l0ZW0gPSBsYXllclZpc0NvbmZpZ3NbaXRlbV07XG4gICAgICBpZiAodHlwZW9mIGNvbmZpZ0l0ZW0gPT09ICdzdHJpbmcnICYmIExBWUVSX1ZJU19DT05GSUdTW2NvbmZpZ0l0ZW1dKSB7XG4gICAgICAgIC8vIGlmIGFzc2lnbmVkIG9uZSBvZiBkZWZhdWx0IExBWUVSX0NPTkZJR1NcbiAgICAgICAgdGhpcy5jb25maWcudmlzQ29uZmlnW2l0ZW1dID0gTEFZRVJfVklTX0NPTkZJR1NbY29uZmlnSXRlbV0uZGVmYXVsdFZhbHVlO1xuICAgICAgICB0aGlzLnZpc0NvbmZpZ1NldHRpbmdzW2l0ZW1dID0gTEFZRVJfVklTX0NPTkZJR1NbY29uZmlnSXRlbV07XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICB0eXBlb2YgY29uZmlnSXRlbSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgWyd0eXBlJywgJ2RlZmF1bHRWYWx1ZSddLmV2ZXJ5KHAgPT4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGNvbmZpZ0l0ZW0sIHApKVxuICAgICAgKSB7XG4gICAgICAgIC8vIGlmIHByb3ZpZGVkIGN1c3RvbWl6ZWQgdmlzQ29uZmlnLCBhbmQgaGFzIHR5cGUgJiYgZGVmYXVsdFZhbHVlXG4gICAgICAgIC8vIFRPRE86IGZ1cnRoZXIgY2hlY2sgaWYgY3VzdG9taXplZCB2aXNDb25maWcgaXMgdmFsaWRcbiAgICAgICAgdGhpcy5jb25maWcudmlzQ29uZmlnW2l0ZW1dID0gY29uZmlnSXRlbS5kZWZhdWx0VmFsdWU7XG4gICAgICAgIHRoaXMudmlzQ29uZmlnU2V0dGluZ3NbaXRlbV0gPSBjb25maWdJdGVtO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZ2V0TGF5ZXJDb2x1bW5zKHByb3BzQ29sdW1ucyA9IHt9KSB7XG4gICAgY29uc3QgY29sdW1uVmFsaWRhdG9ycyA9IHRoaXMuY29sdW1uVmFsaWRhdG9ycyB8fCB7fTtcbiAgICBjb25zdCByZXF1aXJlZCA9IHRoaXMucmVxdWlyZWRMYXllckNvbHVtbnMucmVkdWNlKFxuICAgICAgKGFjY3UsIGtleSkgPT4gKHtcbiAgICAgICAgLi4uYWNjdSxcbiAgICAgICAgW2tleV06IGNvbHVtblZhbGlkYXRvcnNba2V5XVxuICAgICAgICAgID8ge1xuICAgICAgICAgICAgICB2YWx1ZTogcHJvcHNDb2x1bW5zW2tleV0/LnZhbHVlID8/IG51bGwsXG4gICAgICAgICAgICAgIGZpZWxkSWR4OiBwcm9wc0NvbHVtbnNba2V5XT8uZmllbGRJZHggPz8gLTEsXG4gICAgICAgICAgICAgIHZhbGlkYXRvcjogY29sdW1uVmFsaWRhdG9yc1trZXldXG4gICAgICAgICAgICB9XG4gICAgICAgICAgOiB7dmFsdWU6IHByb3BzQ29sdW1uc1trZXldPy52YWx1ZSA/PyBudWxsLCBmaWVsZElkeDogcHJvcHNDb2x1bW5zW2tleV0/LmZpZWxkSWR4ID8/IC0xfVxuICAgICAgfSksXG4gICAgICB7fVxuICAgICk7XG4gICAgY29uc3Qgb3B0aW9uYWwgPSB0aGlzLm9wdGlvbmFsQ29sdW1ucy5yZWR1Y2UoXG4gICAgICAoYWNjdSwga2V5KSA9PiAoe1xuICAgICAgICAuLi5hY2N1LFxuICAgICAgICBba2V5XToge1xuICAgICAgICAgIHZhbHVlOiBwcm9wc0NvbHVtbnNba2V5XT8udmFsdWUgPz8gbnVsbCxcbiAgICAgICAgICBmaWVsZElkeDogcHJvcHNDb2x1bW5zW2tleV0/LmZpZWxkSWR4ID8/IC0xLFxuICAgICAgICAgIG9wdGlvbmFsOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAge31cbiAgICApO1xuXG4gICAgY29uc3QgY29sdW1ucyA9IHsuLi5yZXF1aXJlZCwgLi4ub3B0aW9uYWx9O1xuXG4gICAgcmV0dXJuIGNvbHVtbnM7XG4gIH1cblxuICB1cGRhdGVMYXllckNvbmZpZzxcbiAgICBMYXllckNvbmZpZyBleHRlbmRzIExheWVyQmFzZUNvbmZpZyAmXG4gICAgICBQYXJ0aWFsPExheWVyQ29sb3JDb25maWcgJiBMYXllclNpemVDb25maWc+ID0gTGF5ZXJCYXNlQ29uZmlnXG4gID4obmV3Q29uZmlnOiBQYXJ0aWFsPExheWVyQ29uZmlnPik6IExheWVyIHtcbiAgICB0aGlzLmNvbmZpZyA9IHsuLi50aGlzLmNvbmZpZywgLi4ubmV3Q29uZmlnfTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHVwZGF0ZUxheWVyVmlzQ29uZmlnKG5ld1Zpc0NvbmZpZykge1xuICAgIHRoaXMuY29uZmlnLnZpc0NvbmZpZyA9IHsuLi50aGlzLmNvbmZpZy52aXNDb25maWcsIC4uLm5ld1Zpc0NvbmZpZ307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB1cGRhdGVMYXllckNvbG9yVUkocHJvcDogc3RyaW5nLCBuZXdDb25maWc6IE5lc3RlZFBhcnRpYWw8Q29sb3JVST4pOiBMYXllciB7XG4gICAgY29uc3Qge2NvbG9yVUk6IHByZXZpb3VzLCB2aXNDb25maWd9ID0gdGhpcy5jb25maWc7XG5cbiAgICBpZiAoIWlzUGxhaW5PYmplY3QobmV3Q29uZmlnKSB8fCB0eXBlb2YgcHJvcCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbG9yVUlQcm9wID0gT2JqZWN0LmVudHJpZXMobmV3Q29uZmlnKS5yZWR1Y2UoKGFjY3UsIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uYWNjdSxcbiAgICAgICAgW2tleV06XG4gICAgICAgICAgaXNQbGFpbk9iamVjdChhY2N1W2tleV0pICYmIGlzUGxhaW5PYmplY3QodmFsdWUpXG4gICAgICAgICAgICA/IHsuLi5hY2N1W2tleV0sIC4uLih2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPil9XG4gICAgICAgICAgICA6IHZhbHVlXG4gICAgICB9O1xuICAgIH0sIHByZXZpb3VzW3Byb3BdIHx8IERFRkFVTFRfQ09MT1JfVUkpO1xuXG4gICAgY29uc3QgY29sb3JVSSA9IHtcbiAgICAgIC4uLnByZXZpb3VzLFxuICAgICAgW3Byb3BdOiBjb2xvclVJUHJvcFxuICAgIH07XG5cbiAgICB0aGlzLnVwZGF0ZUxheWVyQ29uZmlnKHtjb2xvclVJfSk7XG4gICAgLy8gaWYgY29sb3JVSVtwcm9wXSBpcyBjb2xvclJhbmdlXG4gICAgY29uc3QgaXNDb2xvclJhbmdlID0gdmlzQ29uZmlnW3Byb3BdICYmIHZpc0NvbmZpZ1twcm9wXS5jb2xvcnM7XG5cbiAgICBpZiAoaXNDb2xvclJhbmdlKSB7XG4gICAgICAvLyBpZiBvcGVuIGRyb3Bkb3duIGFuZCBwcm9wIGlzIGNvbG9yIHJhbmdlXG4gICAgICAvLyBBdXRvbWF0aWNhbGx5IHNldCBjb2xvclJhbmdlQ29uZmlnJ3Mgc3RlcCBhbmQgcmV2ZXJzZWRcbiAgICAgIHRoaXMudXBkYXRlQ29sb3JVSUJ5Q29sb3JSYW5nZShuZXdDb25maWcsIHByb3ApO1xuXG4gICAgICAvLyBpZiBjaGFuZ2VzIGluIFVJIGlzIG1hZGUgdG8gJ3JldmVyc2VkJywgJ3N0ZXBzJyBvciBzdGVwc1xuICAgICAgLy8gdXBkYXRlIGN1cnJlbnQgbGF5ZXIgY29sb3JSYW5nZVxuICAgICAgdGhpcy51cGRhdGVDb2xvclJhbmdlQnlDb2xvclVJKG5ld0NvbmZpZywgcHJldmlvdXMsIHByb3ApO1xuXG4gICAgICAvLyBpZiBzZXQgY29sb3JSYW5nZUNvbmZpZyB0byBjdXN0b21cbiAgICAgIC8vIGluaXRpYXRlIGN1c3RvbVBhbGV0dGUgdG8gYmUgZWRpdGVkIGluIHRoZSB1aVxuICAgICAgdGhpcy51cGRhdGVDdXN0b21QYWxldHRlKG5ld0NvbmZpZywgcHJldmlvdXMsIHByb3ApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gaWYgc2V0IGNvbG9yUmFuZ2VDb25maWcgdG8gY3VzdG9tIHBhbGV0dGUgb3IgY3VzdG9tIGJyZWFrc1xuICAvLyBpbml0aWF0ZSBjdXN0b21QYWxldHRlIHRvIGJlIGVkaXRlZCBpbiB0aGUgdWlcbiAgdXBkYXRlQ3VzdG9tUGFsZXR0ZShuZXdDb25maWcsIHByZXZpb3VzLCBwcm9wKSB7XG4gICAgaWYgKCFuZXdDb25maWcuY29sb3JSYW5nZUNvbmZpZz8uY3VzdG9tICYmICFuZXdDb25maWcuY29sb3JSYW5nZUNvbmZpZz8uY3VzdG9tQnJlYWtzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKG5ld0NvbmZpZy5jdXN0b21QYWxldHRlKSB7XG4gICAgICAvLyBpZiBuZXcgY29uZmlnIGFsc28gc2V0IGN1c3RvbVBhbGV0dGUsIG5vIG5lZWQgdG8gaW5pdGlhdGUgbmV3XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHtjb2xvclVJLCB2aXNDb25maWd9ID0gdGhpcy5jb25maWc7XG5cbiAgICBpZiAoIXZpc0NvbmZpZ1twcm9wXSkgcmV0dXJuO1xuICAgIC8vIG1ha2UgY29weSBvZiBjdXJyZW50IGNvbG9yIHJhbmdlIHRvIGN1c3RvbVBhbGV0dGVcbiAgICBsZXQgY3VzdG9tUGFsZXR0ZSA9IHtcbiAgICAgIC4uLnZpc0NvbmZpZ1twcm9wXVxuICAgIH07XG5cbiAgICBpZiAobmV3Q29uZmlnLmNvbG9yUmFuZ2VDb25maWcuY3VzdG9tQnJlYWtzICYmICFjdXN0b21QYWxldHRlLmNvbG9yTWFwKSB7XG4gICAgICAvLyBmaW5kIHZpc3VhbENoYW5lbFxuICAgICAgY29uc3QgdmlzdWFsQ2hhbm5lbHMgPSB0aGlzLnZpc3VhbENoYW5uZWxzO1xuICAgICAgY29uc3QgY2hhbm5lbEtleSA9IE9iamVjdC5rZXlzKHZpc3VhbENoYW5uZWxzKS5maW5kKFxuICAgICAgICBrZXkgPT4gdmlzdWFsQ2hhbm5lbHNba2V5XS5yYW5nZSA9PT0gcHJvcFxuICAgICAgKTtcbiAgICAgIGlmICghY2hhbm5lbEtleSkge1xuICAgICAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcG5cbiAgICAgICAgQ29uc29sZS53YXJuKGB1cGRhdGVDb2xvclVJOiBDYW4ndCBmaW5kIHZpc3VhbCBjaGFubmVsIHdoaWNoIHJhbmdlIGlzICR7cHJvcH1gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gYWRkIG5hbWV8dHlwZXxjYXRlZ29yeSB0byB1cGRhdGVDdXN0b21QYWxldHRlIGlmIGN1c3RvbUJyZWFrcywgc28gdGhhdFxuICAgICAgLy8gY29sb3JzIHdpbGwgbm90IGJlIG92ZXJyaWRlIGFzIHdlbGwgd2hlbiBpbnZlcnNlIHBhbGV0dGUgd2l0aCBjdXN0b20gYnJlYWtcbiAgICAgIC8vIGluaXRpYXRlIGNvbG9yTWFwIGZyb20gY3VycmVudCBzY2FsZVxuXG4gICAgICBjb25zdCBjb2xvck1hcCA9IGluaXRpYWxpemVMYXllckNvbG9yTWFwKHRoaXMsIHZpc3VhbENoYW5uZWxzW2NoYW5uZWxLZXldKTtcbiAgICAgIGN1c3RvbVBhbGV0dGUgPSBpbml0aWFsaXplQ3VzdG9tUGFsZXR0ZSh2aXNDb25maWdbcHJvcF0sIGNvbG9yTWFwKTtcbiAgICB9IGVsc2UgaWYgKG5ld0NvbmZpZy5jb2xvclJhbmdlQ29uZmlnLmN1c3RvbSkge1xuICAgICAgY3VzdG9tUGFsZXR0ZSA9IGluaXRpYWxpemVDdXN0b21QYWxldHRlKHZpc0NvbmZpZ1twcm9wXSk7XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVMYXllckNvbmZpZyh7XG4gICAgICBjb2xvclVJOiB7XG4gICAgICAgIC4uLmNvbG9yVUksXG4gICAgICAgIFtwcm9wXToge1xuICAgICAgICAgIC4uLmNvbG9yVUlbcHJvcF0sXG4gICAgICAgICAgY3VzdG9tUGFsZXR0ZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogaWYgb3BlbiBkcm9wZG93biBhbmQgcHJvcCBpcyBjb2xvciByYW5nZVxuICAgKiBBdXRvbWF0aWNhbGx5IHNldCBjb2xvclJhbmdlQ29uZmlnJ3Mgc3RlcCBhbmQgcmV2ZXJzZWRcbiAgICogQHBhcmFtIHsqfSBuZXdDb25maWdcbiAgICogQHBhcmFtIHsqfSBwcm9wXG4gICAqL1xuICB1cGRhdGVDb2xvclVJQnlDb2xvclJhbmdlKG5ld0NvbmZpZywgcHJvcCkge1xuICAgIGNvbnN0IHtjb2xvclVJLCB2aXNDb25maWd9ID0gdGhpcy5jb25maWc7XG5cbiAgICAvLyB3aGVuIGN1c3RvbSBwYWxldHRlIGFkZHMvcmVtb3ZlcyBzdGVwLCB0aGUgbnVtYmVyIGluIFwiU3RlcHNcIiBpbnB1dCBjb250cm9sXG4gICAgLy8gc2hvdWxkIGJlIHVwZGF0ZWQgYXMgd2VsbFxuICAgIGNvbnN0IGlzQ3VzdG9tID0gbmV3Q29uZmlnLmN1c3RvbVBhbGV0dGU/LmNhdGVnb3J5ID09PSAnQ3VzdG9tJztcbiAgICBjb25zdCBjdXN0b21TdGVwc0NoYW5nZWQgPSBpc0N1c3RvbVxuICAgICAgPyBuZXdDb25maWcuY3VzdG9tUGFsZXR0ZS5jb2xvcnMubGVuZ3RoICE9PSB2aXNDb25maWdbcHJvcF0uY29sb3JzLmxlbmd0aFxuICAgICAgOiBmYWxzZTtcblxuICAgIGlmICh0eXBlb2YgbmV3Q29uZmlnLnNob3dEcm9wZG93biAhPT0gJ251bWJlcicgJiYgIWN1c3RvbVN0ZXBzQ2hhbmdlZCkgcmV0dXJuO1xuXG4gICAgdGhpcy51cGRhdGVMYXllckNvbmZpZyh7XG4gICAgICBjb2xvclVJOiB7XG4gICAgICAgIC4uLmNvbG9yVUksXG4gICAgICAgIFtwcm9wXToge1xuICAgICAgICAgIC4uLmNvbG9yVUlbcHJvcF0sXG4gICAgICAgICAgY29sb3JSYW5nZUNvbmZpZzoge1xuICAgICAgICAgICAgLi4uY29sb3JVSVtwcm9wXS5jb2xvclJhbmdlQ29uZmlnLFxuICAgICAgICAgICAgc3RlcHM6IGN1c3RvbVN0ZXBzQ2hhbmdlZFxuICAgICAgICAgICAgICA/IGNvbG9yVUlbcHJvcF0uY3VzdG9tUGFsZXR0ZS5jb2xvcnMubGVuZ3RoXG4gICAgICAgICAgICAgIDogdmlzQ29uZmlnW3Byb3BdLmNvbG9ycy5sZW5ndGgsXG4gICAgICAgICAgICByZXZlcnNlZDogQm9vbGVhbih2aXNDb25maWdbcHJvcF0ucmV2ZXJzZWQpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICB1cGRhdGVDb2xvclJhbmdlQnlDb2xvclVJKG5ld0NvbmZpZywgcHJldmlvdXMsIHByb3ApIHtcbiAgICAvLyBvbmx5IHVwZGF0ZSBjb2xvclJhbmdlIGlmIGNoYW5nZXMgaW4gVUkgaXMgbWFkZSB0byAncmV2ZXJzZWQnLCAnc3RlcHMnIG9yIHN0ZXBzXG4gICAgY29uc3Qgc2hvdWxkVXBkYXRlID1cbiAgICAgIG5ld0NvbmZpZy5jb2xvclJhbmdlQ29uZmlnICYmXG4gICAgICBbJ3JldmVyc2VkJywgJ3N0ZXBzJywgJ2NvbG9yQmxpbmRTYWZlJywgJ3R5cGUnXS5zb21lKFxuICAgICAgICBrZXkgPT5cbiAgICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobmV3Q29uZmlnLmNvbG9yUmFuZ2VDb25maWcsIGtleSkgJiZcbiAgICAgICAgICBuZXdDb25maWcuY29sb3JSYW5nZUNvbmZpZ1trZXldICE9PVxuICAgICAgICAgICAgKHByZXZpb3VzW3Byb3BdIHx8IERFRkFVTFRfQ09MT1JfVUkpLmNvbG9yUmFuZ2VDb25maWdba2V5XVxuICAgICAgKTtcbiAgICBpZiAoIXNob3VsZFVwZGF0ZSkgcmV0dXJuO1xuXG4gICAgY29uc3Qge2NvbG9yVUksIHZpc0NvbmZpZ30gPSB0aGlzLmNvbmZpZztcblxuICAgIC8vIGZvciBjdXN0b20gcGFsZXR0ZSwgb25lIGNhbiBvbmx5ICdyZXZlcnNlJyB0aGUgY29sb3JzIGluIGN1c3RvbSBwYWxldHRlLlxuICAgIC8vIGNoYW5naW5nICdzdGVwcycsICdjb2xvckJpbmRTYWZlJywgJ3R5cGUnIHNob3VsZCBmYWxsIGJhY2sgdG8gcHJlZGVmaW5lZCBwYWxldHRlLlxuICAgIGNvbnN0IGlzQ3VzdG9tQ29sb3JSZXZlcnNlZCA9XG4gICAgICB2aXNDb25maWcuY29sb3JSYW5nZS5jYXRlZ29yeSA9PT0gJ0N1c3RvbScgJiZcbiAgICAgIG5ld0NvbmZpZy5jb2xvclJhbmdlQ29uZmlnICYmXG4gICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobmV3Q29uZmlnLmNvbG9yUmFuZ2VDb25maWcsICdyZXZlcnNlZCcpO1xuXG4gICAgY29uc3QgdXBkYXRlID0gaXNDdXN0b21Db2xvclJldmVyc2VkXG4gICAgICA/IHVwZGF0ZUN1c3RvbUNvbG9yUmFuZ2VCeUNvbG9yVUkodmlzQ29uZmlnW3Byb3BdLCBjb2xvclVJW3Byb3BdLmNvbG9yUmFuZ2VDb25maWcpXG4gICAgICA6IHVwZGF0ZUNvbG9yUmFuZ2VCeU1hdGNoaW5nUGFsZXR0ZSh2aXNDb25maWdbcHJvcF0sIGNvbG9yVUlbcHJvcF0uY29sb3JSYW5nZUNvbmZpZyk7XG5cbiAgICBpZiAodXBkYXRlKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxheWVyVmlzQ29uZmlnKHtbcHJvcF06IHVwZGF0ZX0pO1xuICAgIH1cbiAgfVxuICBoYXNDb2x1bW5WYWx1ZShjb2x1bW4/OiBMYXllckNvbHVtbikge1xuICAgIHJldHVybiBCb29sZWFuKGNvbHVtbiAmJiBjb2x1bW4udmFsdWUgJiYgY29sdW1uLmZpZWxkSWR4ID4gLTEpO1xuICB9XG4gIGhhc1JlcXVpcmVkQ29sdW1uKGNvbHVtbj86IExheWVyQ29sdW1uKSB7XG4gICAgcmV0dXJuIEJvb2xlYW4oY29sdW1uICYmIChjb2x1bW4ub3B0aW9uYWwgfHwgdGhpcy5oYXNDb2x1bW5WYWx1ZShjb2x1bW4pKSk7XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrIHdoZXRoZXIgbGF5ZXIgaGFzIGFsbCBjb2x1bW5zXG4gICAqIEByZXR1cm5zIHllcyBvciBub1xuICAgKi9cbiAgaGFzQWxsQ29sdW1ucygpOiBib29sZWFuIHtcbiAgICBjb25zdCB7Y29sdW1ucywgY29sdW1uTW9kZX0gPSB0aGlzLmNvbmZpZztcbiAgICAvLyBpZiBsYXllciBoYXMgZGlmZmVyZW50IGNvbHVtbiBtb2RlLCBjaGVjayBpZiBoYXZlIGFsbCByZXF1aXJlZCBjb2x1bW5zIG9mIGN1cnJlbnQgY29sdW1uIE1vZGVcbiAgICBpZiAoY29sdW1uTW9kZSkge1xuICAgICAgY29uc3QgY3VycmVudENvbHVtbk1vZGVzID0gKHRoaXMuc3VwcG9ydGVkQ29sdW1uTW9kZXMgfHwgW10pLmZpbmQoXG4gICAgICAgIGNvbE1vZGUgPT4gY29sTW9kZS5rZXkgPT09IGNvbHVtbk1vZGVcbiAgICAgICk7XG4gICAgICByZXR1cm4gQm9vbGVhbihcbiAgICAgICAgY3VycmVudENvbHVtbk1vZGVzICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICBjdXJyZW50Q29sdW1uTW9kZXMucmVxdWlyZWRDb2x1bW5zPy5ldmVyeShjb2xLZXkgPT4gdGhpcy5oYXNDb2x1bW5WYWx1ZShjb2x1bW5zW2NvbEtleV0pKVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIEJvb2xlYW4oXG4gICAgICBjb2x1bW5zICYmXG4gICAgICAgIE9iamVjdC52YWx1ZXMoY29sdW1ucykuZXZlcnkoKGNvbHVtbj86IExheWVyQ29sdW1uKSA9PiB0aGlzLmhhc1JlcXVpcmVkQ29sdW1uKGNvbHVtbikpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayB3aGV0aGVyIGxheWVyIGhhcyBkYXRhXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXkgfCBPYmplY3R9IGxheWVyRGF0YVxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0geWVzIG9yIG5vXG4gICAqL1xuICBoYXNMYXllckRhdGEobGF5ZXJEYXRhOiB7ZGF0YTogdW5rbm93bltdIHwgYXJyb3cuVGFibGV9KSB7XG4gICAgaWYgKCFsYXllckRhdGEpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gQm9vbGVhbihcbiAgICAgIGxheWVyRGF0YS5kYXRhICYmXG4gICAgICAgICgobGF5ZXJEYXRhLmRhdGEgYXMgdW5rbm93bltdKS5sZW5ndGggfHwgKGxheWVyRGF0YS5kYXRhIGFzIGFycm93LlRhYmxlKS5udW1Sb3dzKVxuICAgICk7XG4gIH1cblxuICBpc1ZhbGlkVG9TYXZlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBCb29sZWFuKHRoaXMudHlwZSAmJiB0aGlzLmhhc0FsbENvbHVtbnMoKSk7XG4gIH1cblxuICBzaG91bGRSZW5kZXJMYXllcihkYXRhKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIEJvb2xlYW4odGhpcy50eXBlKSAmJlxuICAgICAgdGhpcy5oYXNBbGxDb2x1bW5zKCkgJiZcbiAgICAgIHRoaXMuaGFzTGF5ZXJEYXRhKGRhdGEpICYmXG4gICAgICB0eXBlb2YgdGhpcy5yZW5kZXJMYXllciA9PT0gJ2Z1bmN0aW9uJ1xuICAgICk7XG4gIH1cblxuICBnZXRDb2xvclNjYWxlKFxuICAgIGNvbG9yU2NhbGU6IHN0cmluZyxcbiAgICBjb2xvckRvbWFpbjogVmlzdWFsQ2hhbm5lbERvbWFpbixcbiAgICBjb2xvclJhbmdlOiBDb2xvclJhbmdlXG4gICk6IEdldFZpc0NoYW5uZWxTY2FsZVJldHVyblR5cGUge1xuICAgIGlmIChjb2xvclNjYWxlID09PSBTQ0FMRV9UWVBFUy5jdXN0b21PcmRpbmFsKSB7XG4gICAgICByZXR1cm4gZ2V0Q2F0ZWdvcmljYWxDb2xvclNjYWxlKGNvbG9yRG9tYWluLCBjb2xvclJhbmdlKTtcbiAgICB9XG5cbiAgICBpZiAoaGFzQ29sb3JNYXAoY29sb3JSYW5nZSkgJiYgY29sb3JTY2FsZSA9PT0gU0NBTEVfVFlQRVMuY3VzdG9tKSB7XG4gICAgICBjb25zdCBjTWFwID0gbmV3IE1hcCgpO1xuICAgICAgY29sb3JSYW5nZS5jb2xvck1hcD8uZm9yRWFjaCgoW2ssIHZdKSA9PiB7XG4gICAgICAgIGNNYXAuc2V0KGssIHR5cGVvZiB2ID09PSAnc3RyaW5nJyA/IGhleFRvUmdiKHYpIDogdik7XG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc2NhbGVUeXBlID0gY29sb3JTY2FsZSA9PT0gU0NBTEVfVFlQRVMuY3VzdG9tID8gY29sb3JTY2FsZSA6IFNDQUxFX1RZUEVTLm9yZGluYWw7XG5cbiAgICAgIGNvbnN0IHNjYWxlID0gZ2V0U2NhbGVGdW5jdGlvbihzY2FsZVR5cGUsIGNNYXAudmFsdWVzKCksIGNNYXAua2V5cygpLCBmYWxzZSk7XG4gICAgICBzY2FsZS51bmtub3duKGNNYXAuZ2V0KFVOS05PV05fQ09MT1JfS0VZKSB8fCBOT19WQUxVRV9DT0xPUik7XG5cbiAgICAgIHJldHVybiBzY2FsZSBhcyBHZXRWaXNDaGFubmVsU2NhbGVSZXR1cm5UeXBlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5nZXRWaXNDaGFubmVsU2NhbGUoY29sb3JTY2FsZSwgY29sb3JEb21haW4sIGNvbG9yUmFuZ2UuY29sb3JzLm1hcChoZXhUb1JnYikpO1xuICB9XG5cbiAgYWNjZXNzVlNGaWVsZFZhbHVlKF9maWVsZCwgX2luZGV4S2V5KSB7XG4gICAgcmV0dXJuIGRlZmF1bHRHZXRGaWVsZFZhbHVlO1xuICB9XG4gIC8qKlxuICAgKiBNYXBwaW5nIGZyb20gdmlzdWFsIGNoYW5uZWxzIHRvIGRlY2suZ2wgYWNjZXNvcnNcbiAgICogQHBhcmFtIHBhcmFtIFBhcmFtZXRlcnNcbiAgICogQHBhcmFtIHBhcmFtLmRhdGFBY2Nlc3NvciBBY2Nlc3Mga2VwbGVyLmdsIGxheWVyIGRhdGEgZnJvbSBkZWNrLmdsIGxheWVyXG4gICAqIEBwYXJhbSBwYXJhbS5kYXRhQ29udGFpbmVyIERhdGFDb250YWluZXIgdG8gdXNlIHVzZSB3aXRoIGRhdGFBY2Nlc3NvclxuICAgKiBAcmV0dXJuIHtPYmplY3R9IGF0dHJpYnV0ZUFjY2Vzc29ycyAtIGRlY2suZ2wgbGF5ZXIgYXR0cmlidXRlIGFjY2Vzc29yc1xuICAgKi9cbiAgZ2V0QXR0cmlidXRlQWNjZXNzb3JzKHtcbiAgICBkYXRhQWNjZXNzb3IgPSBkZWZhdWx0RGF0YUFjY2Vzc29yLFxuICAgIGRhdGFDb250YWluZXIsXG4gICAgaW5kZXhLZXlcbiAgfToge1xuICAgIGRhdGFBY2Nlc3Nvcj86IHR5cGVvZiBkZWZhdWx0RGF0YUFjY2Vzc29yO1xuICAgIGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2U7XG4gICAgaW5kZXhLZXk/OiBudW1iZXIgfCBudWxsO1xuICB9KSB7XG4gICAgY29uc3QgYXR0cmlidXRlQWNjZXNzb3JzOiB7W2tleTogc3RyaW5nXTogYW55fSA9IHt9O1xuXG4gICAgT2JqZWN0LmtleXModGhpcy52aXN1YWxDaGFubmVscykuZm9yRWFjaChjaGFubmVsID0+IHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgZmllbGQsXG4gICAgICAgIGZpeGVkLFxuICAgICAgICBzY2FsZSxcbiAgICAgICAgZG9tYWluLFxuICAgICAgICByYW5nZSxcbiAgICAgICAgYWNjZXNzb3IsXG4gICAgICAgIGRlZmF1bHRWYWx1ZSxcbiAgICAgICAgZ2V0QXR0cmlidXRlVmFsdWUsXG4gICAgICAgIG51bGxWYWx1ZSxcbiAgICAgICAgY2hhbm5lbFNjYWxlVHlwZVxuICAgICAgfSA9IHRoaXMudmlzdWFsQ2hhbm5lbHNbY2hhbm5lbF07XG5cbiAgICAgIGlmIChhY2Nlc3Nvcikge1xuICAgICAgICBjb25zdCBzaG91bGRHZXRTY2FsZSA9IHRoaXMuY29uZmlnW2ZpZWxkXTtcblxuICAgICAgICBpZiAoc2hvdWxkR2V0U2NhbGUpIHtcbiAgICAgICAgICBjb25zdCBpc0ZpeGVkID0gZml4ZWQgJiYgdGhpcy5jb25maWcudmlzQ29uZmlnW2ZpeGVkXTtcblxuICAgICAgICAgIGNvbnN0IHNjYWxlRnVuY3Rpb24gPVxuICAgICAgICAgICAgY2hhbm5lbFNjYWxlVHlwZSA9PT0gQ0hBTk5FTF9TQ0FMRVMuY29sb3JcbiAgICAgICAgICAgICAgPyB0aGlzLmdldENvbG9yU2NhbGUoXG4gICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ1tzY2FsZV0sXG4gICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ1tkb21haW5dLFxuICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWcudmlzQ29uZmlnW3JhbmdlXVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgOiB0aGlzLmdldFZpc0NoYW5uZWxTY2FsZShcbiAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnW3NjYWxlXSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnW2RvbWFpbl0sXG4gICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy52aXNDb25maWdbcmFuZ2VdLFxuICAgICAgICAgICAgICAgICAgaXNGaXhlZFxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCBnZXRGaWVsZFZhbHVlID0gdGhpcy5hY2Nlc3NWU0ZpZWxkVmFsdWUodGhpcy5jb25maWdbZmllbGRdLCBpbmRleEtleSk7XG5cbiAgICAgICAgICBpZiAoc2NhbGVGdW5jdGlvbikge1xuICAgICAgICAgICAgYXR0cmlidXRlQWNjZXNzb3JzW2FjY2Vzc29yXSA9IHNjYWxlRnVuY3Rpb24uYnlab29tXG4gICAgICAgICAgICAgID8gbWVtb2l6ZSh6ID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHNjYWxlRnVuYyA9IHNjYWxlRnVuY3Rpb24oeik7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gZCA9PlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmdldEVuY29kZWRDaGFubmVsVmFsdWUoXG4gICAgICAgICAgICAgICAgICAgICAgc2NhbGVGdW5jLFxuICAgICAgICAgICAgICAgICAgICAgIGRhdGFBY2Nlc3NvcihkYXRhQ29udGFpbmVyKShkKSxcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ1tmaWVsZF0sXG4gICAgICAgICAgICAgICAgICAgICAgbnVsbFZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgIGdldEZpZWxkVmFsdWVcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICA6IGQgPT5cbiAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0RW5jb2RlZENoYW5uZWxWYWx1ZShcbiAgICAgICAgICAgICAgICAgICAgc2NhbGVGdW5jdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZGF0YUFjY2Vzc29yKGRhdGFDb250YWluZXIpKGQpLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ1tmaWVsZF0sXG4gICAgICAgICAgICAgICAgICAgIG51bGxWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgZ2V0RmllbGRWYWx1ZVxuICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgLy8gc2V0IGdldEZpbGxDb2xvckJ5Wm9vbSB0byB0cnVlXG4gICAgICAgICAgICBpZiAoc2NhbGVGdW5jdGlvbi5ieVpvb20pIHtcbiAgICAgICAgICAgICAgYXR0cmlidXRlQWNjZXNzb3JzW2Ake2FjY2Vzc29yfUJ5Wm9vbWBdID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGdldEF0dHJpYnV0ZVZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgYXR0cmlidXRlQWNjZXNzb3JzW2FjY2Vzc29yXSA9IGdldEF0dHJpYnV0ZVZhbHVlKHRoaXMuY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhdHRyaWJ1dGVBY2Nlc3NvcnNbYWNjZXNzb3JdID1cbiAgICAgICAgICAgIHR5cGVvZiBkZWZhdWx0VmFsdWUgPT09ICdmdW5jdGlvbicgPyBkZWZhdWx0VmFsdWUodGhpcy5jb25maWcpIDogZGVmYXVsdFZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFhdHRyaWJ1dGVBY2Nlc3NvcnNbYWNjZXNzb3JdKSB7XG4gICAgICAgICAgQ29uc29sZS53YXJuKGBGYWlsZWQgdG8gcHJvdmlkZSBhY2Nlc3NvciBmdW5jdGlvbiBmb3IgJHthY2Nlc3NvciB8fCBjaGFubmVsfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gYXR0cmlidXRlQWNjZXNzb3JzO1xuICB9XG5cbiAgZ2V0VmlzQ2hhbm5lbFNjYWxlKFxuICAgIHNjYWxlOiBzdHJpbmcsXG4gICAgZG9tYWluOiBWaXN1YWxDaGFubmVsRG9tYWluIHwgRG9tYWluUXVhbnRpbGVzLFxuICAgIHJhbmdlOiBhbnksXG4gICAgZml4ZWQ/OiBib29sZWFuXG4gICk6IEdldFZpc0NoYW5uZWxTY2FsZVJldHVyblR5cGUge1xuICAgIC8vIGlmIHF1YW50aWxlIGlzIHByb3ZpZGVkIHBlciB6b29tXG4gICAgaWYgKGlzRG9tYWluUXVhbnRpbGUoZG9tYWluKSAmJiBzY2FsZSA9PT0gU0NBTEVfVFlQRVMucXVhbnRpbGUpIHtcbiAgICAgIGNvbnN0IHpTdGVwcyA9IGRvbWFpbi56O1xuXG4gICAgICBjb25zdCBnZXRTY2FsZSA9IGZ1bmN0aW9uIGdldFNjYWxlQnlab29tKHopIHtcbiAgICAgICAgY29uc3Qgc2NhbGVEb21haW4gPSBnZXREb21haW5TdGVwc2J5Wm9vbShkb21haW4ucXVhbnRpbGVzLCB6U3RlcHMsIHopO1xuICAgICAgICBjb25zdCB0aHJlc2hvbGRzID0gZ2V0VGhyZXNob2xkc0Zyb21RdWFudGlsZXMoc2NhbGVEb21haW4sIHJhbmdlLmxlbmd0aCk7XG5cbiAgICAgICAgcmV0dXJuIGdldFNjYWxlRnVuY3Rpb24oJ3RocmVzaG9sZCcsIHJhbmdlLCB0aHJlc2hvbGRzLCBmYWxzZSk7XG4gICAgICB9O1xuXG4gICAgICBnZXRTY2FsZS5ieVpvb20gPSB0cnVlO1xuICAgICAgcmV0dXJuIGdldFNjYWxlO1xuICAgIH0gZWxzZSBpZiAoaXNEb21haW5TdG9wcyhkb21haW4pKSB7XG4gICAgICAvLyBjb2xvciBpcyBiYXNlZCBvbiB6b29tXG4gICAgICBjb25zdCB6U3RlcHMgPSBkb21haW4uejtcbiAgICAgIC8vIGdldCBzY2FsZSBmdW5jdGlvbiBieSB6XG4gICAgICAvLyB7XG4gICAgICAvLyAgejogW3osIHosIHpdLFxuICAgICAgLy8gIHN0b3BzOiBbW21pbiwgbWF4XSwgW21pbiwgbWF4XV0sXG4gICAgICAvLyAgaW50ZXJwb2xhdGlvbjogJ2ludGVycG9sYXRlJ1xuICAgICAgLy8gfVxuXG4gICAgICBjb25zdCBnZXRTY2FsZSA9IGZ1bmN0aW9uIGdldFNjYWxlQnlab29tKHopIHtcbiAgICAgICAgY29uc3Qgc2NhbGVEb21haW4gPSBnZXREb21haW5TdGVwc2J5Wm9vbShkb21haW4uc3RvcHMsIHpTdGVwcywgeik7XG5cbiAgICAgICAgcmV0dXJuIGdldFNjYWxlRnVuY3Rpb24oc2NhbGUsIHJhbmdlLCBzY2FsZURvbWFpbiwgZml4ZWQpO1xuICAgICAgfTtcblxuICAgICAgZ2V0U2NhbGUuYnlab29tID0gdHJ1ZTtcbiAgICAgIHJldHVybiBnZXRTY2FsZTtcbiAgICB9XG5cbiAgICByZXR1cm4gU0NBTEVfRlVOQ1tmaXhlZCA/ICdsaW5lYXInIDogc2NhbGVdKClcbiAgICAgIC5kb21haW4oZG9tYWluKVxuICAgICAgLnJhbmdlKGZpeGVkID8gZG9tYWluIDogcmFuZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBsb25naXR1ZGUgYW5kIGxhdGl0dWRlIGJvdW5kcyBvZiB0aGUgZGF0YS5cbiAgICovXG4gIGdldFBvaW50c0JvdW5kcyhcbiAgICBkYXRhQ29udGFpbmVyOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlLFxuICAgIGdldFBvc2l0aW9uOiAoeDogYW55LCBkYzogRGF0YUNvbnRhaW5lckludGVyZmFjZSkgPT4gbnVtYmVyW10gPSBpZGVudGl0eVxuICApOiBudW1iZXJbXSB8IG51bGwge1xuICAgIC8vIG5vIG5lZWQgdG8gbG9vcCB0aHJvdWdoIHRoZSBlbnRpcmUgZGF0YXNldFxuICAgIC8vIGdldCBhIHNhbXBsZSBvZiBkYXRhIHRvIGNhbGN1bGF0ZSBib3VuZHNcbiAgICBjb25zdCBzYW1wbGVEYXRhID1cbiAgICAgIGRhdGFDb250YWluZXIubnVtUm93cygpID4gTUFYX1NBTVBMRV9TSVpFXG4gICAgICAgID8gZ2V0U2FtcGxlQ29udGFpbmVyRGF0YShkYXRhQ29udGFpbmVyLCBNQVhfU0FNUExFX1NJWkUpXG4gICAgICAgIDogZGF0YUNvbnRhaW5lcjtcblxuICAgIGNvbnN0IHBvaW50cyA9IGdldFBvc2l0aW9uID8gc2FtcGxlRGF0YS5tYXBJbmRleChnZXRQb3NpdGlvbikgOiBbXTtcblxuICAgIGNvbnN0IGxhdEJvdW5kcyA9IGdldExhdExuZ0JvdW5kcyhwb2ludHMsIDEsIFstOTAsIDkwXSk7XG4gICAgY29uc3QgbG5nQm91bmRzID0gZ2V0TGF0TG5nQm91bmRzKHBvaW50cywgMCwgWy0xODAsIDE4MF0pO1xuXG4gICAgaWYgKCFsYXRCb3VuZHMgfHwgIWxuZ0JvdW5kcykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIFtsbmdCb3VuZHNbMF0sIGxhdEJvdW5kc1swXSwgbG5nQm91bmRzWzFdLCBsYXRCb3VuZHNbMV1dO1xuICB9XG5cbiAgZ2V0Q2hhbmdlZFRyaWdnZXJzKGRhdGFVcGRhdGVUcmlnZ2Vycykge1xuICAgIGNvbnN0IHRyaWdnZXJDaGFuZ2VkID0gZGlmZlVwZGF0ZVRyaWdnZXJzKGRhdGFVcGRhdGVUcmlnZ2VycywgdGhpcy5fb2xkRGF0YVVwZGF0ZVRyaWdnZXJzKTtcbiAgICB0aGlzLl9vbGREYXRhVXBkYXRlVHJpZ2dlcnMgPSBkYXRhVXBkYXRlVHJpZ2dlcnM7XG5cbiAgICByZXR1cm4gdHJpZ2dlckNoYW5nZWQ7XG4gIH1cblxuICBnZXRFbmNvZGVkQ2hhbm5lbFZhbHVlKFxuICAgIHNjYWxlOiAodmFsdWUpID0+IGFueSxcbiAgICBkYXRhOiBhbnlbXSxcbiAgICBmaWVsZDogVmlzdWFsQ2hhbm5lbEZpZWxkLFxuICAgIG51bGxWYWx1ZSA9IE5PX1ZBTFVFX0NPTE9SLFxuICAgIGdldFZhbHVlID0gZGVmYXVsdEdldEZpZWxkVmFsdWVcbiAgKSB7XG4gICAgY29uc3QgdmFsdWUgPSBnZXRWYWx1ZShmaWVsZCwgZGF0YSk7XG5cbiAgICBpZiAoIW5vdE51bGxvclVuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBudWxsVmFsdWU7XG4gICAgfVxuXG4gICAgbGV0IGF0dHJpYnV0ZVZhbHVlO1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgYXR0cmlidXRlVmFsdWUgPSB2YWx1ZS5tYXAoc2NhbGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhdHRyaWJ1dGVWYWx1ZSA9IHNjYWxlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBpZiAoIW5vdE51bGxvclVuZGVmaW5lZChhdHRyaWJ1dGVWYWx1ZSkpIHtcbiAgICAgIGF0dHJpYnV0ZVZhbHVlID0gbnVsbFZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBhdHRyaWJ1dGVWYWx1ZTtcbiAgfVxuXG4gIHVwZGF0ZU1ldGEobWV0YTogTGF5ZXJbJ21ldGEnXSkge1xuICAgIHRoaXMubWV0YSA9IHsuLi50aGlzLm1ldGEsIC4uLm1ldGF9O1xuICB9XG5cbiAgZ2V0RGF0YVVwZGF0ZVRyaWdnZXJzKHtmaWx0ZXJlZEluZGV4LCBpZCwgZGF0YUNvbnRhaW5lcn06IEtlcGxlclRhYmxlKTogYW55IHtcbiAgICBjb25zdCB7Y29sdW1uc30gPSB0aGlzLmNvbmZpZztcblxuICAgIHJldHVybiB7XG4gICAgICBnZXREYXRhOiB7ZGF0YXNldElkOiBpZCwgZGF0YUNvbnRhaW5lciwgY29sdW1ucywgZmlsdGVyZWRJbmRleH0sXG4gICAgICBnZXRNZXRhOiB7ZGF0YXNldElkOiBpZCwgZGF0YUNvbnRhaW5lciwgY29sdW1uc30sXG4gICAgICAuLi4odGhpcy5jb25maWcudGV4dExhYmVsIHx8IFtdKS5yZWR1Y2UoXG4gICAgICAgIChhY2N1LCB0bCwgaSkgPT4gKHtcbiAgICAgICAgICAuLi5hY2N1LFxuICAgICAgICAgIFtgZ2V0TGFiZWxDaGFyYWN0ZXJTZXQtJHtpfWBdOiB0bC5maWVsZCA/IHRsLmZpZWxkLm5hbWUgOiBudWxsXG4gICAgICAgIH0pLFxuICAgICAgICB7fVxuICAgICAgKVxuICAgIH07XG4gIH1cblxuICB1cGRhdGVEYXRhKGRhdGFzZXRzOiBEYXRhc2V0cywgb2xkTGF5ZXJEYXRhOiBhbnkpIHtcbiAgICBpZiAoIXRoaXMuY29uZmlnLmRhdGFJZCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjb25zdCBsYXllckRhdGFzZXQgPSBkYXRhc2V0c1t0aGlzLmNvbmZpZy5kYXRhSWRdO1xuICAgIGNvbnN0IHtkYXRhQ29udGFpbmVyfSA9IGxheWVyRGF0YXNldDtcblxuICAgIGNvbnN0IGdldFBvc2l0aW9uID0gdGhpcy5nZXRQb3NpdGlvbkFjY2Vzc29yKGRhdGFDb250YWluZXIpO1xuICAgIGNvbnN0IGRhdGFVcGRhdGVUcmlnZ2VycyA9IHRoaXMuZ2V0RGF0YVVwZGF0ZVRyaWdnZXJzKGxheWVyRGF0YXNldCk7XG4gICAgY29uc3QgdHJpZ2dlckNoYW5nZWQgPSB0aGlzLmdldENoYW5nZWRUcmlnZ2VycyhkYXRhVXBkYXRlVHJpZ2dlcnMpO1xuXG4gICAgaWYgKHRyaWdnZXJDaGFuZ2VkICYmICh0cmlnZ2VyQ2hhbmdlZC5nZXRNZXRhIHx8IHRyaWdnZXJDaGFuZ2VkLmdldERhdGEpKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxheWVyTWV0YShsYXllckRhdGFzZXQsIGdldFBvc2l0aW9uKTtcblxuICAgICAgLy8gcmVzZXQgZmlsdGVyZWRJdGVtQ291bnRcbiAgICAgIHRoaXMuZmlsdGVyZWRJdGVtQ291bnQgPSB7fTtcbiAgICB9XG5cbiAgICBsZXQgZGF0YSA9IFtdO1xuXG4gICAgaWYgKCEodHJpZ2dlckNoYW5nZWQgJiYgdHJpZ2dlckNoYW5nZWQuZ2V0RGF0YSkgJiYgb2xkTGF5ZXJEYXRhICYmIG9sZExheWVyRGF0YS5kYXRhKSB7XG4gICAgICAvLyBzYW1lIGRhdGFcbiAgICAgIGRhdGEgPSBvbGRMYXllckRhdGEuZGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YSA9IHRoaXMuY2FsY3VsYXRlRGF0YUF0dHJpYnV0ZShsYXllckRhdGFzZXQsIGdldFBvc2l0aW9uKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge2RhdGEsIHRyaWdnZXJDaGFuZ2VkfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBoZWxwZXIgZnVuY3Rpb24gdG8gdXBkYXRlIG9uZSBsYXllciBkb21haW4gd2hlbiBzdGF0ZS5kYXRhIGNoYW5nZWRcbiAgICogaWYgc3RhdGUuZGF0YSBjaGFuZ2UgaXMgZHVlIG90IHVwZGF0ZSBmaWx0ZXIsIG5ld0ZpbGVyIHdpbGwgYmUgcGFzc2VkXG4gICAqIGNhbGxlZCBieSB1cGRhdGVBbGxMYXllckRvbWFpbkRhdGFcbiAgICogQHBhcmFtIGRhdGFzZXRzXG4gICAqIEBwYXJhbSBuZXdGaWx0ZXJcbiAgICogQHJldHVybnMgbGF5ZXJcbiAgICovXG4gIHVwZGF0ZUxheWVyRG9tYWluKGRhdGFzZXRzOiBEYXRhc2V0cywgbmV3RmlsdGVyPzogRmlsdGVyKTogTGF5ZXIge1xuICAgIGNvbnN0IHRhYmxlID0gdGhpcy5nZXREYXRhc2V0KGRhdGFzZXRzKTtcbiAgICBpZiAoIXRhYmxlKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgT2JqZWN0LnZhbHVlcyh0aGlzLnZpc3VhbENoYW5uZWxzKS5mb3JFYWNoKGNoYW5uZWwgPT4ge1xuICAgICAgY29uc3Qge3NjYWxlfSA9IGNoYW5uZWw7XG4gICAgICBjb25zdCBzY2FsZVR5cGUgPSB0aGlzLmNvbmZpZ1tzY2FsZV07XG4gICAgICAvLyBvcmRpbmFsIGRvbWFpbiBpcyBiYXNlZCBvbiBkYXRhQ29udGFpbmVyLCBpZiBvbmx5IGZpbHRlciBjaGFuZ2VkXG4gICAgICAvLyBubyBuZWVkIHRvIHVwZGF0ZSBvcmRpbmFsIGRvbWFpblxuICAgICAgaWYgKCFuZXdGaWx0ZXIgfHwgc2NhbGVUeXBlICE9PSBTQ0FMRV9UWVBFUy5vcmRpbmFsKSB7XG4gICAgICAgIGNvbnN0IHtkb21haW59ID0gY2hhbm5lbDtcbiAgICAgICAgY29uc3QgdXBkYXRlZERvbWFpbiA9IHRoaXMuY2FsY3VsYXRlTGF5ZXJEb21haW4odGFibGUsIGNoYW5uZWwpO1xuICAgICAgICB0aGlzLnVwZGF0ZUxheWVyQ29uZmlnKHtbZG9tYWluXTogdXBkYXRlZERvbWFpbn0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBnZXREYXRhc2V0KGRhdGFzZXRzKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFJZCA/IGRhdGFzZXRzW3RoaXMuY29uZmlnLmRhdGFJZF0gOiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHZpc3VhbCBjaGFubmVsIGZpZWxkIGFuZCBzY2FsZXMgYmFzZWQgb24gc3VwcG9ydGVkIGZpZWxkICYgc2NhbGUgdHlwZVxuICAgKiBAcGFyYW0gY2hhbm5lbFxuICAgKi9cbiAgdmFsaWRhdGVWaXN1YWxDaGFubmVsKGNoYW5uZWw6IHN0cmluZykge1xuICAgIHRoaXMudmFsaWRhdGVGaWVsZFR5cGUoY2hhbm5lbCk7XG4gICAgdGhpcy52YWxpZGF0ZVNjYWxlKGNoYW5uZWwpO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIGZpZWxkIHR5cGUgYmFzZWQgb24gY2hhbm5lbFNjYWxlVHlwZVxuICAgKi9cbiAgdmFsaWRhdGVGaWVsZFR5cGUoY2hhbm5lbDogc3RyaW5nKSB7XG4gICAgY29uc3QgdmlzdWFsQ2hhbm5lbCA9IHRoaXMudmlzdWFsQ2hhbm5lbHNbY2hhbm5lbF07XG4gICAgY29uc3Qge2ZpZWxkLCBjaGFubmVsU2NhbGVUeXBlLCBzdXBwb3J0ZWRGaWVsZFR5cGVzfSA9IHZpc3VhbENoYW5uZWw7XG5cbiAgICBpZiAodGhpcy5jb25maWdbZmllbGRdKSB7XG4gICAgICAvLyBpZiBmaWVsZCBpcyBzZWxlY3RlZCwgY2hlY2sgaWYgZmllbGQgdHlwZSBpcyBzdXBwb3J0ZWRcbiAgICAgIGNvbnN0IGNoYW5uZWxTdXBwb3J0ZWRGaWVsZFR5cGVzID1cbiAgICAgICAgc3VwcG9ydGVkRmllbGRUeXBlcyB8fCBDSEFOTkVMX1NDQUxFX1NVUFBPUlRFRF9GSUVMRFNbY2hhbm5lbFNjYWxlVHlwZV07XG5cbiAgICAgIGlmICghY2hhbm5lbFN1cHBvcnRlZEZpZWxkVHlwZXMuaW5jbHVkZXModGhpcy5jb25maWdbZmllbGRdLnR5cGUpKSB7XG4gICAgICAgIC8vIGZpZWxkIHR5cGUgaXMgbm90IHN1cHBvcnRlZCwgc2V0IGl0IGJhY2sgdG8gbnVsbFxuICAgICAgICAvLyBzZXQgc2NhbGUgYmFjayB0byBkZWZhdWx0XG4gICAgICAgIHRoaXMudXBkYXRlTGF5ZXJDb25maWcoe1tmaWVsZF06IG51bGx9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgc2NhbGUgdHlwZSBiYXNlZCBvbiBhZ2dyZWdhdGlvblxuICAgKi9cbiAgdmFsaWRhdGVTY2FsZShjaGFubmVsKSB7XG4gICAgY29uc3QgdmlzdWFsQ2hhbm5lbCA9IHRoaXMudmlzdWFsQ2hhbm5lbHNbY2hhbm5lbF07XG4gICAgY29uc3Qge3NjYWxlfSA9IHZpc3VhbENoYW5uZWw7XG4gICAgaWYgKCFzY2FsZSkge1xuICAgICAgLy8gdmlzdWFsQ2hhbm5lbCBkb2Vzbid0IGhhdmUgc2NhbGVcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc2NhbGVPcHRpb25zID0gdGhpcy5nZXRTY2FsZU9wdGlvbnMoY2hhbm5lbCk7XG4gICAgLy8gY2hlY2sgaWYgY3VycmVudCBzZWxlY3RlZCBzY2FsZSBpc1xuICAgIC8vIHN1cHBvcnRlZCwgaWYgbm90LCBjaGFuZ2UgdG8gZGVmYXVsdFxuICAgIGlmICghc2NhbGVPcHRpb25zLmluY2x1ZGVzKHRoaXMuY29uZmlnW3NjYWxlXSkpIHtcbiAgICAgIHRoaXMudXBkYXRlTGF5ZXJDb25maWcoe1tzY2FsZV06IHNjYWxlT3B0aW9uc1swXX0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgc2NhbGUgb3B0aW9ucyBiYXNlZCBvbiBjdXJyZW50IGZpZWxkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaGFubmVsXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXX1cbiAgICovXG4gIGdldFNjYWxlT3B0aW9ucyhjaGFubmVsOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgdmlzdWFsQ2hhbm5lbCA9IHRoaXMudmlzdWFsQ2hhbm5lbHNbY2hhbm5lbF07XG4gICAgY29uc3Qge2ZpZWxkLCBzY2FsZSwgY2hhbm5lbFNjYWxlVHlwZX0gPSB2aXN1YWxDaGFubmVsO1xuXG4gICAgcmV0dXJuIHRoaXMuY29uZmlnW2ZpZWxkXVxuICAgICAgPyBGSUVMRF9PUFRTW3RoaXMuY29uZmlnW2ZpZWxkXS50eXBlXS5zY2FsZVtjaGFubmVsU2NhbGVUeXBlXVxuICAgICAgOiBbdGhpcy5nZXREZWZhdWx0TGF5ZXJDb25maWcoe2RhdGFJZDogJyd9KVtzY2FsZV1dO1xuICB9XG5cbiAgdXBkYXRlTGF5ZXJWaXN1YWxDaGFubmVsKGRhdGFzZXQ6IEtlcGxlclRhYmxlLCBjaGFubmVsOiBzdHJpbmcpIHtcbiAgICBjb25zdCB2aXN1YWxDaGFubmVsID0gdGhpcy52aXN1YWxDaGFubmVsc1tjaGFubmVsXTtcbiAgICB0aGlzLnZhbGlkYXRlVmlzdWFsQ2hhbm5lbChjaGFubmVsKTtcbiAgICAvLyBjYWxjdWxhdGUgbGF5ZXIgY2hhbm5lbCBkb21haW5cbiAgICBjb25zdCB1cGRhdGVkRG9tYWluID0gdGhpcy5jYWxjdWxhdGVMYXllckRvbWFpbihkYXRhc2V0LCB2aXN1YWxDaGFubmVsKTtcbiAgICB0aGlzLnVwZGF0ZUxheWVyQ29uZmlnKHtbdmlzdWFsQ2hhbm5lbC5kb21haW5dOiB1cGRhdGVkRG9tYWlufSk7XG4gIH1cblxuICBnZXRWaXN1YWxDaGFubmVsVXBkYXRlVHJpZ2dlcnMoKTogVXBkYXRlVHJpZ2dlcnMge1xuICAgIGNvbnN0IHVwZGF0ZVRyaWdnZXJzOiBVcGRhdGVUcmlnZ2VycyA9IHt9O1xuICAgIE9iamVjdC52YWx1ZXModGhpcy52aXN1YWxDaGFubmVscykuZm9yRWFjaCh2aXN1YWxDaGFubmVsID0+IHtcbiAgICAgIC8vIGZpZWxkIHJhbmdlIHNjYWxlIGRvbWFpblxuICAgICAgY29uc3Qge2FjY2Vzc29yLCBmaWVsZCwgc2NhbGUsIGRvbWFpbiwgcmFuZ2UsIGRlZmF1bHRWYWx1ZSwgZml4ZWR9ID0gdmlzdWFsQ2hhbm5lbDtcblxuICAgICAgaWYgKGFjY2Vzc29yKSB7XG4gICAgICAgIHVwZGF0ZVRyaWdnZXJzW2FjY2Vzc29yXSA9IHtcbiAgICAgICAgICBbZmllbGRdOiB0aGlzLmNvbmZpZ1tmaWVsZF0sXG4gICAgICAgICAgW3NjYWxlXTogdGhpcy5jb25maWdbc2NhbGVdLFxuICAgICAgICAgIFtkb21haW5dOiB0aGlzLmNvbmZpZ1tkb21haW5dLFxuICAgICAgICAgIFtyYW5nZV06IHRoaXMuY29uZmlnLnZpc0NvbmZpZ1tyYW5nZV0sXG4gICAgICAgICAgZGVmYXVsdFZhbHVlOlxuICAgICAgICAgICAgdHlwZW9mIGRlZmF1bHRWYWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IGRlZmF1bHRWYWx1ZSh0aGlzLmNvbmZpZykgOiBkZWZhdWx0VmFsdWUsXG4gICAgICAgICAgLi4uKGZpeGVkID8ge1tmaXhlZF06IHRoaXMuY29uZmlnLnZpc0NvbmZpZ1tmaXhlZF19IDoge30pXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHVwZGF0ZVRyaWdnZXJzO1xuICB9XG5cbiAgY2FsY3VsYXRlTGF5ZXJEb21haW4oZGF0YXNldCwgdmlzdWFsQ2hhbm5lbCkge1xuICAgIGNvbnN0IHtzY2FsZX0gPSB2aXN1YWxDaGFubmVsO1xuICAgIGNvbnN0IHNjYWxlVHlwZSA9IHRoaXMuY29uZmlnW3NjYWxlXTtcblxuICAgIGNvbnN0IGZpZWxkID0gdGhpcy5jb25maWdbdmlzdWFsQ2hhbm5lbC5maWVsZF07XG4gICAgaWYgKCFmaWVsZCkge1xuICAgICAgLy8gaWYgY29sb3JGaWVsZCBvciBzaXplRmllbGQgd2VyZSBzZXQgYmFjayB0byBudWxsXG4gICAgICByZXR1cm4gZGVmYXVsdERvbWFpbjtcbiAgICB9XG5cbiAgICByZXR1cm4gZGF0YXNldC5nZXRDb2x1bW5MYXllckRvbWFpbihmaWVsZCwgc2NhbGVUeXBlKSB8fCBkZWZhdWx0RG9tYWluO1xuICB9XG5cbiAgaGFzSG92ZXJlZE9iamVjdChvYmplY3RJbmZvKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNMYXllckhvdmVyZWQob2JqZWN0SW5mbykgJiYgb2JqZWN0SW5mby5vYmplY3QgPyBvYmplY3RJbmZvLm9iamVjdCA6IG51bGw7XG4gIH1cblxuICBpc0xheWVySG92ZXJlZChvYmplY3RJbmZvKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIG9iamVjdEluZm8/LnBpY2tlZCAmJiBvYmplY3RJbmZvPy5sYXllcj8ucHJvcHM/LmlkID09PSB0aGlzLmlkO1xuICB9XG5cbiAgZ2V0UmFkaXVzU2NhbGVCeVpvb20obWFwU3RhdGU6IE1hcFN0YXRlLCBmaXhlZFJhZGl1cz86IGJvb2xlYW4pIHtcbiAgICBjb25zdCByYWRpdXNDaGFubmVsID0gT2JqZWN0LnZhbHVlcyh0aGlzLnZpc3VhbENoYW5uZWxzKS5maW5kKHZjID0+IHZjLnByb3BlcnR5ID09PSAncmFkaXVzJyk7XG5cbiAgICBpZiAoIXJhZGl1c0NoYW5uZWwpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cblxuICAgIGNvbnN0IGZpZWxkID0gcmFkaXVzQ2hhbm5lbC5maWVsZDtcbiAgICBjb25zdCBmaXhlZCA9IGZpeGVkUmFkaXVzID09PSB1bmRlZmluZWQgPyB0aGlzLmNvbmZpZy52aXNDb25maWcuZml4ZWRSYWRpdXMgOiBmaXhlZFJhZGl1cztcbiAgICBjb25zdCB7cmFkaXVzfSA9IHRoaXMuY29uZmlnLnZpc0NvbmZpZztcblxuICAgIHJldHVybiBmaXhlZCA/IDEgOiAodGhpcy5jb25maWdbZmllbGRdID8gMSA6IHJhZGl1cykgKiB0aGlzLmdldFpvb21GYWN0b3IobWFwU3RhdGUpO1xuICB9XG5cbiAgc2hvdWxkQ2FsY3VsYXRlTGF5ZXJEYXRhKHByb3BzOiBzdHJpbmdbXSkge1xuICAgIHJldHVybiBwcm9wcy5zb21lKHAgPT4gIXRoaXMubm9uZUxheWVyRGF0YUFmZmVjdGluZ1Byb3BzLmluY2x1ZGVzKHApKTtcbiAgfVxuXG4gIGdldEJydXNoaW5nRXh0ZW5zaW9uUHJvcHMoaW50ZXJhY3Rpb25Db25maWcsIGJydXNoaW5nVGFyZ2V0Pykge1xuICAgIGNvbnN0IHticnVzaH0gPSBpbnRlcmFjdGlvbkNvbmZpZztcblxuICAgIHJldHVybiB7XG4gICAgICAvLyBicnVzaGluZ1xuICAgICAgYXV0b0hpZ2hsaWdodDogIWJydXNoLmVuYWJsZWQsXG4gICAgICBicnVzaGluZ1JhZGl1czogYnJ1c2guY29uZmlnLnNpemUgKiAxMDAwLFxuICAgICAgYnJ1c2hpbmdUYXJnZXQ6IGJydXNoaW5nVGFyZ2V0IHx8ICdzb3VyY2UnLFxuICAgICAgYnJ1c2hpbmdFbmFibGVkOiBicnVzaC5lbmFibGVkXG4gICAgfTtcbiAgfVxuXG4gIGdldERlZmF1bHREZWNrTGF5ZXJQcm9wcyh7XG4gICAgaWR4LFxuICAgIGdwdUZpbHRlcixcbiAgICBtYXBTdGF0ZSxcbiAgICBsYXllckNhbGxiYWNrcyxcbiAgICB2aXNpYmxlXG4gIH06IHtcbiAgICBpZHg6IG51bWJlcjtcbiAgICBncHVGaWx0ZXI6IEdwdUZpbHRlcjtcbiAgICBtYXBTdGF0ZTogTWFwU3RhdGU7XG4gICAgbGF5ZXJDYWxsYmFja3M6IGFueTtcbiAgICB2aXNpYmxlOiBib29sZWFuO1xuICB9KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgaWR4LFxuICAgICAgY29vcmRpbmF0ZVN5c3RlbTogQ09PUkRJTkFURV9TWVNURU0uTE5HTEFULFxuICAgICAgcGlja2FibGU6IHRydWUsXG4gICAgICB3cmFwTG9uZ2l0dWRlOiB0cnVlLFxuICAgICAgcGFyYW1ldGVyczoge2RlcHRoVGVzdDogQm9vbGVhbihtYXBTdGF0ZS5kcmFnUm90YXRlIHx8IHRoaXMuY29uZmlnLnZpc0NvbmZpZy5lbmFibGUzZCl9LFxuICAgICAgaGlkZGVuOiB0aGlzLmNvbmZpZy5oaWRkZW4sXG4gICAgICAvLyB2aXNjb25maWdcbiAgICAgIG9wYWNpdHk6IHRoaXMuY29uZmlnLnZpc0NvbmZpZy5vcGFjaXR5LFxuICAgICAgaGlnaGxpZ2h0Q29sb3I6IHRoaXMuY29uZmlnLmhpZ2hsaWdodENvbG9yLFxuICAgICAgLy8gZGF0YSBmaWx0ZXJpbmdcbiAgICAgIGV4dGVuc2lvbnM6IFtkYXRhRmlsdGVyRXh0ZW5zaW9uXSxcbiAgICAgIGZpbHRlclJhbmdlOiBncHVGaWx0ZXIgPyBncHVGaWx0ZXIuZmlsdGVyUmFuZ2UgOiB1bmRlZmluZWQsXG4gICAgICBvbkZpbHRlcmVkSXRlbXNDaGFuZ2U6IGdwdUZpbHRlciA/IGxheWVyQ2FsbGJhY2tzPy5vbkZpbHRlcmVkSXRlbXNDaGFuZ2UgOiB1bmRlZmluZWQsXG5cbiAgICAgIC8vIGxheWVyIHNob3VsZCBiZSB2aXNpYmxlIGFuZCBpZiBzcGxpdE1hcCwgc2hvd24gaW4gdG8gb25lIG9mIHBhbmVsXG4gICAgICB2aXNpYmxlOiB0aGlzLmNvbmZpZy5pc1Zpc2libGUgJiYgdmlzaWJsZVxuICAgIH07XG4gIH1cblxuICBnZXREZWZhdWx0SG92ZXJMYXllclByb3BzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBpZDogYCR7dGhpcy5pZH0taG92ZXJlZGAsXG4gICAgICBwaWNrYWJsZTogZmFsc2UsXG4gICAgICB3cmFwTG9uZ2l0dWRlOiB0cnVlLFxuICAgICAgY29vcmRpbmF0ZVN5c3RlbTogQ09PUkRJTkFURV9TWVNURU0uTE5HTEFUXG4gICAgfTtcbiAgfVxuXG4gIHJlbmRlclRleHRMYWJlbExheWVyKFxuICAgIHtcbiAgICAgIGdldFBvc2l0aW9uLFxuICAgICAgZ2V0RmlsdGVyZWQsXG4gICAgICBnZXRQaXhlbE9mZnNldCxcbiAgICAgIGJhY2tncm91bmRQcm9wcyxcbiAgICAgIHVwZGF0ZVRyaWdnZXJzLFxuICAgICAgc2hhcmVkUHJvcHNcbiAgICB9OiB7XG4gICAgICBnZXRQb3NpdGlvbj86ICgoZDogYW55KSA9PiBudW1iZXJbXSkgfCBhcnJvdy5WZWN0b3I7XG4gICAgICBnZXRGaWx0ZXJlZD86IChkYXRhOiB7aW5kZXg6IG51bWJlcn0sIG9iamVjdEluZm86IHtpbmRleDogbnVtYmVyfSkgPT4gbnVtYmVyO1xuICAgICAgZ2V0UGl4ZWxPZmZzZXQ6ICh0ZXh0TGFiZWw6IGFueSkgPT4gbnVtYmVyW10gfCAoKGQ6IGFueSkgPT4gbnVtYmVyW10pO1xuICAgICAgYmFja2dyb3VuZFByb3BzPzoge2JhY2tncm91bmQ6IGJvb2xlYW59O1xuICAgICAgdXBkYXRlVHJpZ2dlcnM6IHtcbiAgICAgICAgW2tleTogc3RyaW5nXTogYW55O1xuICAgICAgfTtcbiAgICAgIHNoYXJlZFByb3BzOiBhbnk7XG4gICAgfSxcbiAgICByZW5kZXJPcHRzXG4gICkge1xuICAgIGNvbnN0IHtkYXRhLCBtYXBTdGF0ZX0gPSByZW5kZXJPcHRzO1xuICAgIGNvbnN0IHt0ZXh0TGFiZWx9ID0gdGhpcy5jb25maWc7XG5cbiAgICBjb25zdCBUZXh0TGF5ZXJDbGFzcyA9IGRhdGEuZGF0YSBpbnN0YW5jZW9mIGFycm93LlRhYmxlID8gR2VvQXJyb3dUZXh0TGF5ZXIgOiBUZXh0TGF5ZXI7XG5cbiAgICByZXR1cm4gZGF0YS50ZXh0TGFiZWxzLnJlZHVjZSgoYWNjdSwgZCwgaSkgPT4ge1xuICAgICAgaWYgKGQuZ2V0VGV4dCkge1xuICAgICAgICBjb25zdCBiYWNrZ3JvdW5kID0gdGV4dExhYmVsW2ldLmJhY2tncm91bmQgfHwgYmFja2dyb3VuZFByb3BzPy5iYWNrZ3JvdW5kO1xuXG4gICAgICAgIGFjY3UucHVzaChcbiAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgbmV3IFRleHRMYXllckNsYXNzKHtcbiAgICAgICAgICAgIC4uLnNoYXJlZFByb3BzLFxuICAgICAgICAgICAgaWQ6IGAke3RoaXMuaWR9LWxhYmVsLSR7dGV4dExhYmVsW2ldLmZpZWxkPy5uYW1lfWAsXG4gICAgICAgICAgICBkYXRhOiBkYXRhLmRhdGEsXG4gICAgICAgICAgICB2aXNpYmxlOiB0aGlzLmNvbmZpZy5pc1Zpc2libGUsXG4gICAgICAgICAgICBnZXRUZXh0OiBkLmdldFRleHQsXG4gICAgICAgICAgICBnZXRQb3NpdGlvbixcbiAgICAgICAgICAgIGdldEZpbHRlcmVkLFxuICAgICAgICAgICAgY2hhcmFjdGVyU2V0OiBkLmNoYXJhY3RlclNldCxcbiAgICAgICAgICAgIGdldFBpeGVsT2Zmc2V0OiBnZXRQaXhlbE9mZnNldCh0ZXh0TGFiZWxbaV0pLFxuICAgICAgICAgICAgZ2V0U2l6ZTogUFJPSkVDVEVEX1BJWEVMX1NJWkVfTVVMVElQTElFUixcbiAgICAgICAgICAgIHNpemVTY2FsZTogdGV4dExhYmVsW2ldLnNpemUsXG4gICAgICAgICAgICBnZXRUZXh0QW5jaG9yOiB0ZXh0TGFiZWxbaV0uYW5jaG9yLFxuICAgICAgICAgICAgZ2V0QWxpZ25tZW50QmFzZWxpbmU6IHRleHRMYWJlbFtpXS5hbGlnbm1lbnQsXG4gICAgICAgICAgICBnZXRDb2xvcjogdGV4dExhYmVsW2ldLmNvbG9yLFxuICAgICAgICAgICAgb3V0bGluZVdpZHRoOiB0ZXh0TGFiZWxbaV0ub3V0bGluZVdpZHRoICogVEVYVF9PVVRMSU5FX01VTFRJUExJRVIsXG4gICAgICAgICAgICBvdXRsaW5lQ29sb3I6IHRleHRMYWJlbFtpXS5vdXRsaW5lQ29sb3IsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kLFxuICAgICAgICAgICAgZ2V0QmFja2dyb3VuZENvbG9yOiB0ZXh0TGFiZWxbaV0uYmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgICAgZm9udFNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIHNkZjogdGV4dExhYmVsW2ldLm91dGxpbmVXaWR0aCA+IDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAgIC8vIHRleHQgd2lsbCBhbHdheXMgc2hvdyBvbiB0b3Agb2YgYWxsIGxheWVyc1xuICAgICAgICAgICAgICBkZXB0aFRlc3Q6IGZhbHNlXG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBnZXRGaWx0ZXJWYWx1ZTogZGF0YS5nZXRGaWx0ZXJWYWx1ZSxcbiAgICAgICAgICAgIHVwZGF0ZVRyaWdnZXJzOiB7XG4gICAgICAgICAgICAgIC4uLnVwZGF0ZVRyaWdnZXJzLFxuICAgICAgICAgICAgICBnZXRUZXh0OiB0ZXh0TGFiZWxbaV0uZmllbGQ/Lm5hbWUsXG4gICAgICAgICAgICAgIGdldFBpeGVsT2Zmc2V0OiB7XG4gICAgICAgICAgICAgICAgLi4udXBkYXRlVHJpZ2dlcnMuZ2V0UmFkaXVzLFxuICAgICAgICAgICAgICAgIG1hcFN0YXRlLFxuICAgICAgICAgICAgICAgIGFuY2hvcjogdGV4dExhYmVsW2ldLmFuY2hvcixcbiAgICAgICAgICAgICAgICBhbGlnbm1lbnQ6IHRleHRMYWJlbFtpXS5hbGlnbm1lbnRcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgZ2V0VGV4dEFuY2hvcjogdGV4dExhYmVsW2ldLmFuY2hvcixcbiAgICAgICAgICAgICAgZ2V0QWxpZ25tZW50QmFzZWxpbmU6IHRleHRMYWJlbFtpXS5hbGlnbm1lbnQsXG4gICAgICAgICAgICAgIGdldENvbG9yOiB0ZXh0TGFiZWxbaV0uY29sb3JcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBfc3ViTGF5ZXJQcm9wczoge1xuICAgICAgICAgICAgICAuLi4oYmFja2dyb3VuZFxuICAgICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiB7XG4gICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgY3VsbDogZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA6IG51bGwpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2N1O1xuICAgIH0sIFtdKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgY2FsY3VsYXRlRGF0YUF0dHJpYnV0ZShrZXBsZXJUYWJsZTogS2VwbGVyVGFibGUsIGdldFBvc2l0aW9uKTogYW55IHtcbiAgICAvLyBpbXBsZW1lbnRlZCBpbiBzdWJjbGFzc2VzXG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICB1cGRhdGVMYXllck1ldGEoZGF0YXNldDogS2VwbGVyVGFibGUsIGdldFBvc2l0aW9uKSB7XG4gICAgLy8gaW1wbGVtZW50ZWQgaW4gc3ViY2xhc3Nlc1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBnZXRQb3NpdGlvbkFjY2Vzc29yKGRhdGFDb250YWluZXI/OiBEYXRhQ29udGFpbmVySW50ZXJmYWNlKTogKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkge1xuICAgIC8vIGltcGxlbWVudGVkIGluIHN1YmNsYXNzZXNcbiAgICByZXR1cm4gKCkgPT4gbnVsbDtcbiAgfVxuXG4gIGdldExlZ2VuZFZpc3VhbENoYW5uZWxzKCk6IHtba2V5OiBzdHJpbmddOiBWaXN1YWxDaGFubmVsfSB7XG4gICAgcmV0dXJuIHRoaXMudmlzdWFsQ2hhbm5lbHM7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTGF5ZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFHQSxJQUFBQSxLQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxrQkFBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsV0FBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcsT0FBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksT0FBQSxHQUFBSixPQUFBO0FBQ0EsSUFBQUssVUFBQSxHQUFBQyxzQkFBQSxDQUFBTixPQUFBO0FBRUEsSUFBQU8sS0FBQSxHQUFBQyx1QkFBQSxDQUFBUixPQUFBO0FBQ0EsSUFBQVMsaUJBQUEsR0FBQUgsc0JBQUEsQ0FBQU4sT0FBQTtBQUNBLElBQUFVLFlBQUEsR0FBQVYsT0FBQTtBQUNBLElBQUFXLFdBQUEsR0FBQVgsT0FBQTtBQUVBLElBQUFZLFVBQUEsR0FBQVosT0FBQTtBQWtCQSxJQUFBYSxNQUFBLEdBQUFiLE9BQUE7QUFZQSxJQUFBYyxZQUFBLEdBQUFkLE9BQUE7QUFtQ0EsSUFBQWUsT0FBQSxHQUFBVCxzQkFBQSxDQUFBTixPQUFBO0FBQXFDLElBQUFnQixxQkFBQSxFQWhGckM7QUFDQTtBQUFBLFNBQUFDLHlCQUFBQyxDQUFBLDZCQUFBQyxPQUFBLG1CQUFBQyxDQUFBLE9BQUFELE9BQUEsSUFBQUUsQ0FBQSxPQUFBRixPQUFBLFlBQUFGLHdCQUFBLFlBQUFBLHlCQUFBQyxDQUFBLFdBQUFBLENBQUEsR0FBQUcsQ0FBQSxHQUFBRCxDQUFBLEtBQUFGLENBQUE7QUFBQSxTQUFBVix3QkFBQVUsQ0FBQSxFQUFBRSxDQUFBLFNBQUFBLENBQUEsSUFBQUYsQ0FBQSxJQUFBQSxDQUFBLENBQUFJLFVBQUEsU0FBQUosQ0FBQSxlQUFBQSxDQUFBLGdCQUFBSyxRQUFBLENBQUFMLENBQUEsMEJBQUFBLENBQUEsc0JBQUFBLENBQUEsUUFBQUcsQ0FBQSxHQUFBSix3QkFBQSxDQUFBRyxD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