kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
386 lines (383 loc) • 53.5 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.commonTileVisConfigs = exports.DEFAULT_RADIUS = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _throttle = _interopRequireDefault(require("lodash/throttle"));
var _commonUtils = require("@kepler.gl/common-utils");
var _constants = require("@kepler.gl/constants");
var _table = require("@kepler.gl/table");
var _utils = require("@kepler.gl/utils");
var _baseLayer = _interopRequireDefault(require("../base-layer"));
var _tileUtils = require("./common-tile/tile-utils");
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function _superPropGet(t, e, r, o) { var p = (0, _get2["default"])((0, _getPrototypeOf2["default"])(1 & o ? t.prototype : t), e, r); return 2 & o ? function (t) { return p.apply(r, t); } : p; }
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; } // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
var DEFAULT_ELEVATION = 500;
var DEFAULT_RADIUS = exports.DEFAULT_RADIUS = 1;
var commonTileVisConfigs = exports.commonTileVisConfigs = {
strokeColor: 'strokeColor',
strokeOpacity: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.opacity), {}, {
property: 'strokeOpacity'
}),
radius: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.radius), {}, {
range: [0.1, 100],
step: 0.1,
defaultValue: DEFAULT_RADIUS,
allowCustomValue: false
}),
radiusUnits: {
type: 'boolean',
defaultValue: true,
label: 'Radius in pixels',
group: '',
property: 'radiusUnits',
description: 'Radius in pixels or in meters'
},
enable3d: 'enable3d',
stroked: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.stroked), {}, {
defaultValue: false
}),
transition: {
type: 'boolean',
defaultValue: false,
label: 'Transition',
group: '',
property: 'transition',
description: 'Smoother transition during animation (enable transition will decrease performance)'
},
heightRange: 'elevationRange',
elevationScale: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.elevationScale), {}, {
allowCustomValue: false
}),
opacity: 'opacity',
colorRange: 'colorRange',
// TODO: figure out type for radiusByZoom vis config
radiusByZoom: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.radius), {}, {
defaultValue: {
enabled: false,
stops: null
}
}),
dynamicColor: {
type: 'boolean',
defaultValue: false,
label: 'Dynamic Color',
group: '',
property: 'dynamicColor',
description: 'Use a dynamic color scale based on data visible in the viewport'
}
};
/**
* Abstract tile layer, including common functionality for viewport-based datasets,
* dynamic scales, and tile-based animation
*/
var AbstractTileLayer = exports["default"] = /*#__PURE__*/function (_KeplerLayer) {
function AbstractTileLayer(props) {
var _this;
(0, _classCallCheck2["default"])(this, AbstractTileLayer);
_this = _callSuper(this, AbstractTileLayer, [props]);
(0, _defineProperty2["default"])(_this, "tileDataset", void 0);
(0, _defineProperty2["default"])(_this, "setLayerDomain", undefined);
/**
* Callback to invoke when the viewport changes
*/
(0, _defineProperty2["default"])(_this, "onViewportLoad", function (tiles) {
_this.tileDataset.updateTiles(tiles);
// Update dynamic color domain if required
if (_this.config.visConfig.dynamicColor) {
_this.setDynamicColorDomain();
}
});
(0, _defineProperty2["default"])(_this, "setDynamicColorDomain", (0, _throttle["default"])(function () {
var _this2 = _this,
config = _this2.config,
tileDataset = _this2.tileDataset,
setLayerDomain = _this2.setLayerDomain;
var field = config.colorField;
var colorDomain = config.colorDomain,
colorScale = config.colorScale;
if (!tileDataset || !setLayerDomain || !field) return;
if (colorScale === _constants.SCALE_TYPES.quantize) {
var _tileDataset$getExten = tileDataset.getExtent(field),
_tileDataset$getExten2 = (0, _slicedToArray2["default"])(_tileDataset$getExten, 2),
min = _tileDataset$getExten2[0],
max = _tileDataset$getExten2[1];
if (!Array.isArray(colorDomain) || min !== colorDomain[0] || max !== colorDomain[1]) {
setLayerDomain({
domain: [min, max]
});
}
} else if (colorScale === _constants.SCALE_TYPES.quantile) {
var domain = tileDataset.getQuantileSample(field);
setLayerDomain({
domain: domain
});
} else if (colorScale === _constants.SCALE_TYPES.ordinal) {
var _domain = tileDataset.getUniqueValues(field);
setLayerDomain({
domain: _domain
});
}
}, 500));
_this.registerVisConfig(commonTileVisConfigs);
_this.tileDataset = _this.initTileDataset();
return _this;
}
(0, _inherits2["default"])(AbstractTileLayer, _KeplerLayer);
return (0, _createClass2["default"])(AbstractTileLayer, [{
key: "requireData",
get: function get() {
return true;
}
}, {
key: "requiredLayerColumns",
get: function get() {
return [];
}
}, {
key: "visualChannels",
get: function get() {
return {
color: _objectSpread(_objectSpread({}, _superPropGet(AbstractTileLayer, "visualChannels", this, 1).color), {}, {
accessor: 'getFillColor',
defaultValue: function defaultValue(config) {
return config.color;
}
}),
height: {
property: 'height',
field: 'heightField',
scale: 'heightScale',
domain: 'heightDomain',
range: 'heightRange',
key: 'height',
channelScaleType: 'size',
accessor: 'getElevation',
condition: function condition(config) {
return config.visConfig.enable3d;
},
nullValue: 0,
defaultValue: DEFAULT_ELEVATION
}
};
}
}, {
key: "accessVSFieldValue",
value: function accessVSFieldValue(inputField, indexKey) {
return this.accessRowValue(inputField, indexKey);
}
}, {
key: "getScaleOptions",
value: function getScaleOptions(channelKey) {
if (channelKey === 'color') {
var _field$filterProps;
var channel = this.visualChannels.color;
var _field = this.config[channel.field];
if ((0, _tileUtils.isDomainQuantiles)(_field === null || _field === void 0 || (_field$filterProps = _field.filterProps) === null || _field$filterProps === void 0 ? void 0 : _field$filterProps.domainQuantiles) || this.config.visConfig.dynamicColor ||
// If we've set the scale to quantile, we need to include it - there's a loading
// period in which the visConfig isn't set yet, but if we don't return the right
// scale type we lose it
this.config.colorScale === _constants.SCALE_TYPES.quantile) {
return [_constants.SCALE_TYPES.quantize, _constants.SCALE_TYPES.quantile, _constants.SCALE_TYPES.custom];
}
return [_constants.SCALE_TYPES.quantize, _constants.SCALE_TYPES.custom];
}
return [_constants.SCALE_TYPES.linear];
}
}, {
key: "resetColorDomain",
value: function resetColorDomain() {
var _this$setLayerDomain;
var _this$meta = this.meta,
datasetId = _this$meta.datasetId,
datasets = _this$meta.datasets;
this.updateLayerVisualChannel(datasets === null || datasets === void 0 ? void 0 : datasets[datasetId || ''], 'color');
(_this$setLayerDomain = this.setLayerDomain) === null || _this$setLayerDomain === void 0 || _this$setLayerDomain.call(this, {
domain: this.config.colorDomain
});
}
}, {
key: "updateLayerConfig",
value: function updateLayerConfig(newConfig) {
var _this$config$visConfi,
_newConfig$visConfig$,
_newConfig$visConfig,
_this3 = this;
// When the dynamic color setting changes, we need to recalculate the layer domain
var old = (_this$config$visConfi = this.config.visConfig.dynamicColor) !== null && _this$config$visConfi !== void 0 ? _this$config$visConfi : false;
var next = (_newConfig$visConfig$ = (_newConfig$visConfig = newConfig.visConfig) === null || _newConfig$visConfig === void 0 ? void 0 : _newConfig$visConfig.dynamicColor) !== null && _newConfig$visConfig$ !== void 0 ? _newConfig$visConfig$ : old;
var scaleTypeChanged = newConfig.colorScale && this.config.colorScale !== newConfig.colorScale;
_superPropGet(AbstractTileLayer, "updateLayerConfig", this, 3)([newConfig]);
var colorField = this.config.colorField;
if (colorField) {
// When we switch from dynamic to non-dynamic or vice versa, we need to update
// the color domain. This is downstream from a dispatch call, so we use
// setTimeout to avoid "reducers may not dispatch actions" errors
if (next && (!old || scaleTypeChanged)) {
setTimeout(function () {
return _this3.setDynamicColorDomain();
}, 0);
} else if (old && !next) {
setTimeout(function () {
return _this3.resetColorDomain();
}, 0);
}
}
return this;
}
}, {
key: "animationDomain",
get: function get() {
return this.config.animation.domain;
}
}, {
key: "setInitialLayerConfig",
value: function setInitialLayerConfig(dataset) {
var defaultColorField = (0, _utils.findDefaultColorField)(dataset);
if (defaultColorField) {
this.updateLayerConfig({
colorField: defaultColorField
});
this.updateLayerVisualChannel(dataset, 'color');
}
return this;
}
}, {
key: "getDefaultLayerConfig",
value: function getDefaultLayerConfig(props) {
return _objectSpread(_objectSpread({}, _superPropGet(AbstractTileLayer, "getDefaultLayerConfig", this, 3)([props])), {}, {
colorScale: _constants.SCALE_TYPES.quantize,
// add height visual channel
heightField: null,
heightDomain: [0, 1],
heightScale: 'linear'
});
}
// We can render without columns, so we redefine this method
}, {
key: "shouldRenderLayer",
value: function shouldRenderLayer() {
return Boolean(this.type && this.config.isVisible);
}
}, {
key: "updateAnimationDomainByField",
value: function updateAnimationDomainByField(channel) {
var field = this.config[this.visualChannels[channel].field];
if ((0, _tileUtils.isIndexedField)(field) && field.indexBy.type === _constants.ALL_FIELD_TYPES.timestamp) {
var timeDomain = field.indexBy.timeDomain;
this.updateLayerConfig({
animation: _objectSpread(_objectSpread({}, timeDomain), {}, {
enabled: true,
startTime: timeDomain.domain[0]
})
});
}
}
}, {
key: "updateAnimationDomain",
value: function updateAnimationDomain(domain) {
this.updateLayerConfig({
animation: _objectSpread(_objectSpread({}, this.config.animation), {}, {
domain: domain
})
});
}
}, {
key: "updateLayerDomain",
value: function updateLayerDomain(datasets, newFilter) {
var _this4 = this;
_superPropGet(AbstractTileLayer, "updateLayerDomain", this, 3)([datasets, newFilter]);
if (newFilter) {
// invalidate cachedVisibleDataset when e.g. changing filters
this.tileDataset.invalidateCache();
}
Object.keys(this.visualChannels).forEach(function (channel) {
_this4.updateAnimationDomainByField(channel);
});
return this;
}
}, {
key: "updateLayerVisualChannel",
value: function updateLayerVisualChannel(dataset, channel) {
_superPropGet(AbstractTileLayer, "updateLayerVisualChannel", this, 3)([dataset, channel]);
// create animation if field is indexed by time
this.updateAnimationDomainByField(channel);
}
}, {
key: "formatLayerData",
value: function formatLayerData(datasets, oldLayerData, animationConfig) {
var dataId = this.config.dataId;
if (!(0, _commonUtils.notNullorUndefined)(dataId)) {
return {};
}
var dataset = datasets[dataId];
var dataUpdateTriggers = this.getDataUpdateTriggers(dataset);
var triggerChanged = this.getChangedTriggers(dataUpdateTriggers);
if (triggerChanged && triggerChanged.getMeta) {
this.updateLayerMeta(dataset, datasets);
}
var indexKey = this.config.animation.enabled ? animationConfig.currentTime : null;
var accessors = this.getAttributeAccessors({
dataAccessor: function dataAccessor() {
return function (d) {
return d;
};
},
dataContainer: dataset.dataContainer,
indexKey: indexKey
});
var metadata = dataset === null || dataset === void 0 ? void 0 : dataset.metadata;
var metadataToData = metadata ? {
minZoom: metadata.minZoom,
maxZoom: metadata.maxZoom,
bounds: metadata.bounds
} : {};
return _objectSpread(_objectSpread({}, metadataToData), accessors);
}
}, {
key: "getGpuFilterValueAccessor",
value: function getGpuFilterValueAccessor(_ref) {
var _this5 = this;
var gpuFilter = _ref.gpuFilter,
animationConfig = _ref.animationConfig;
var indexKey = this.config.animation.enabled ? animationConfig.currentTime : null;
var valueAccessor = function valueAccessor(dataContainer, d) {
return function (field) {
return _this5.accessVSFieldValue(field, indexKey)(field, d);
};
};
return gpuFilter.filterValueAccessor(null)(undefined, valueAccessor);
}
}], [{
key: "findDefaultLayerProps",
value: function findDefaultLayerProps(dataset) {
if (!(0, _table.isTileDataset)(dataset)) {
return {
props: []
};
}
var newLayerProp = {
dataId: dataset.id,
label: dataset.label,
isVisible: true
};
return {
props: [newLayerProp]
};
}
}]);
}(_baseLayer["default"]);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdGhyb3R0bGUiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9jb21tb25VdGlscyIsIl9jb25zdGFudHMiLCJfdGFibGUiLCJfdXRpbHMiLCJfYmFzZUxheWVyIiwiX3RpbGVVdGlscyIsIl9jYWxsU3VwZXIiLCJ0IiwibyIsImUiLCJfZ2V0UHJvdG90eXBlT2YyIiwiX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yIiwiX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCIsIlJlZmxlY3QiLCJjb25zdHJ1Y3QiLCJjb25zdHJ1Y3RvciIsImFwcGx5IiwiQm9vbGVhbiIsInByb3RvdHlwZSIsInZhbHVlT2YiLCJjYWxsIiwiX3N1cGVyUHJvcEdldCIsInIiLCJwIiwiX2dldDIiLCJvd25LZXlzIiwiT2JqZWN0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJkZWZpbmVQcm9wZXJ0eSIsIkRFRkFVTFRfRUxFVkFUSU9OIiwiREVGQVVMVF9SQURJVVMiLCJleHBvcnRzIiwiY29tbW9uVGlsZVZpc0NvbmZpZ3MiLCJzdHJva2VDb2xvciIsInN0cm9rZU9wYWNpdHkiLCJMQVlFUl9WSVNfQ09ORklHUyIsIm9wYWNpdHkiLCJwcm9wZXJ0eSIsInJhZGl1cyIsInJhbmdlIiwic3RlcCIsImRlZmF1bHRWYWx1ZSIsImFsbG93Q3VzdG9tVmFsdWUiLCJyYWRpdXNVbml0cyIsInR5cGUiLCJsYWJlbCIsImdyb3VwIiwiZGVzY3JpcHRpb24iLCJlbmFibGUzZCIsInN0cm9rZWQiLCJ0cmFuc2l0aW9uIiwiaGVpZ2h0UmFuZ2UiLCJlbGV2YXRpb25TY2FsZSIsImNvbG9yUmFuZ2UiLCJyYWRpdXNCeVpvb20iLCJlbmFibGVkIiwic3RvcHMiLCJkeW5hbWljQ29sb3IiLCJBYnN0cmFjdFRpbGVMYXllciIsIl9LZXBsZXJMYXllciIsInByb3BzIiwiX3RoaXMiLCJfY2xhc3NDYWxsQ2hlY2syIiwidW5kZWZpbmVkIiwidGlsZXMiLCJ0aWxlRGF0YXNldCIsInVwZGF0ZVRpbGVzIiwiY29uZmlnIiwidmlzQ29uZmlnIiwic2V0RHluYW1pY0NvbG9yRG9tYWluIiwidGhyb3R0bGUiLCJfdGhpczIiLCJzZXRMYXllckRvbWFpbiIsImZpZWxkIiwiY29sb3JGaWVsZCIsImNvbG9yRG9tYWluIiwiY29sb3JTY2FsZSIsIlNDQUxFX1RZUEVTIiwicXVhbnRpemUiLCJfdGlsZURhdGFzZXQkZ2V0RXh0ZW4iLCJnZXRFeHRlbnQiLCJfdGlsZURhdGFzZXQkZ2V0RXh0ZW4yIiwiX3NsaWNlZFRvQXJyYXkyIiwibWluIiwibWF4IiwiQXJyYXkiLCJpc0FycmF5IiwiZG9tYWluIiwicXVhbnRpbGUiLCJnZXRRdWFudGlsZVNhbXBsZSIsIm9yZGluYWwiLCJnZXRVbmlxdWVWYWx1ZXMiLCJyZWdpc3RlclZpc0NvbmZpZyIsImluaXRUaWxlRGF0YXNldCIsIl9pbmhlcml0czIiLCJfY3JlYXRlQ2xhc3MyIiwia2V5IiwiZ2V0IiwiY29sb3IiLCJhY2Nlc3NvciIsImhlaWdodCIsInNjYWxlIiwiY2hhbm5lbFNjYWxlVHlwZSIsImNvbmRpdGlvbiIsIm51bGxWYWx1ZSIsInZhbHVlIiwiYWNjZXNzVlNGaWVsZFZhbHVlIiwiaW5wdXRGaWVsZCIsImluZGV4S2V5IiwiYWNjZXNzUm93VmFsdWUiLCJnZXRTY2FsZU9wdGlvbnMiLCJjaGFubmVsS2V5IiwiX2ZpZWxkJGZpbHRlclByb3BzIiwiY2hhbm5lbCIsInZpc3VhbENoYW5uZWxzIiwiaXNEb21haW5RdWFudGlsZXMiLCJmaWx0ZXJQcm9wcyIsImRvbWFpblF1YW50aWxlcyIsImN1c3RvbSIsImxpbmVhciIsInJlc2V0Q29sb3JEb21haW4iLCJfdGhpcyRzZXRMYXllckRvbWFpbiIsIl90aGlzJG1ldGEiLCJtZXRhIiwiZGF0YXNldElkIiwiZGF0YXNldHMiLCJ1cGRhdGVMYXllclZpc3VhbENoYW5uZWwiLCJ1cGRhdGVMYXllckNvbmZpZyIsIm5ld0NvbmZpZyIsIl90aGlzJGNvbmZpZyR2aXNDb25maSIsIl9uZXdDb25maWckdmlzQ29uZmlnJCIsIl9uZXdDb25maWckdmlzQ29uZmlnIiwiX3RoaXMzIiwib2xkIiwibmV4dCIsInNjYWxlVHlwZUNoYW5nZWQiLCJzZXRUaW1lb3V0IiwiYW5pbWF0aW9uIiwic2V0SW5pdGlhbExheWVyQ29uZmlnIiwiZGF0YXNldCIsImRlZmF1bHRDb2xvckZpZWxkIiwiZmluZERlZmF1bHRDb2xvckZpZWxkIiwiZ2V0RGVmYXVsdExheWVyQ29uZmlnIiwiaGVpZ2h0RmllbGQiLCJoZWlnaHREb21haW4iLCJoZWlnaHRTY2FsZSIsInNob3VsZFJlbmRlckxheWVyIiwiaXNWaXNpYmxlIiwidXBkYXRlQW5pbWF0aW9uRG9tYWluQnlGaWVsZCIsImlzSW5kZXhlZEZpZWxkIiwiaW5kZXhCeSIsIkFMTF9GSUVMRF9UWVBFUyIsInRpbWVzdGFtcCIsInRpbWVEb21haW4iLCJzdGFydFRpbWUiLCJ1cGRhdGVBbmltYXRpb25Eb21haW4iLCJ1cGRhdGVMYXllckRvbWFpbiIsIm5ld0ZpbHRlciIsIl90aGlzNCIsImludmFsaWRhdGVDYWNoZSIsImZvcm1hdExheWVyRGF0YSIsIm9sZExheWVyRGF0YSIsImFuaW1hdGlvbkNvbmZpZyIsImRhdGFJZCIsIm5vdE51bGxvclVuZGVmaW5lZCIsImRhdGFVcGRhdGVUcmlnZ2VycyIsImdldERhdGFVcGRhdGVUcmlnZ2VycyIsInRyaWdnZXJDaGFuZ2VkIiwiZ2V0Q2hhbmdlZFRyaWdnZXJzIiwiZ2V0TWV0YSIsInVwZGF0ZUxheWVyTWV0YSIsImN1cnJlbnRUaW1lIiwiYWNjZXNzb3JzIiwiZ2V0QXR0cmlidXRlQWNjZXNzb3JzIiwiZGF0YUFjY2Vzc29yIiwiZCIsImRhdGFDb250YWluZXIiLCJtZXRhZGF0YSIsIm1ldGFkYXRhVG9EYXRhIiwibWluWm9vbSIsIm1heFpvb20iLCJib3VuZHMiLCJnZXRHcHVGaWx0ZXJWYWx1ZUFjY2Vzc29yIiwiX3JlZiIsIl90aGlzNSIsImdwdUZpbHRlciIsInZhbHVlQWNjZXNzb3IiLCJmaWx0ZXJWYWx1ZUFjY2Vzc29yIiwiZmluZERlZmF1bHRMYXllclByb3BzIiwiaXNUaWxlRGF0YXNldCIsIm5ld0xheWVyUHJvcCIsImlkIiwiS2VwbGVyTGF5ZXIiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdmVjdG9yLXRpbGUvYWJzdHJhY3QtdGlsZS1sYXllci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQgdGhyb3R0bGUgZnJvbSAnbG9kYXNoL3Rocm90dGxlJztcblxuaW1wb3J0IHtub3ROdWxsb3JVbmRlZmluZWR9IGZyb20gJ0BrZXBsZXIuZ2wvY29tbW9uLXV0aWxzJztcbmltcG9ydCB7U0NBTEVfVFlQRVMsIEFMTF9GSUVMRF9UWVBFUywgTEFZRVJfVklTX0NPTkZJR1N9IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcbmltcG9ydCB7XG4gIGlzVGlsZURhdGFzZXQsXG4gIEtlcGxlclRhYmxlIGFzIEtlcGxlckRhdGFzZXQsXG4gIERhdGFzZXRzIGFzIEtlcGxlckRhdGFzZXRzLFxuICBHcHVGaWx0ZXJcbn0gZnJvbSAnQGtlcGxlci5nbC90YWJsZSc7XG5pbXBvcnQge1xuICBBbmltYXRpb25Db25maWcsXG4gIEZpZWxkLFxuICBCaW5kZWRMYXllckNhbGxiYWNrcyxcbiAgVmlzQ29uZmlnQm9vbGVhbixcbiAgVmlzQ29uZmlnUmFuZ2UsXG4gIFZpc0NvbmZpZ0NvbG9yUmFuZ2UsXG4gIFZpc0NvbmZpZ051bWJlcixcbiAgVmlzQ29uZmlnQ29sb3JTZWxlY3QsXG4gIExheWVyQ29sb3JDb25maWcsXG4gIExheWVySGVpZ2h0Q29uZmlnLFxuICBGaWx0ZXIsXG4gIEZpZWxkIGFzIEtlcGxlckZpZWxkLFxuICBNYXBTdGF0ZSxcbiAgTWVyZ2UsXG4gIFpvb21TdG9wc0NvbmZpZ1xufSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcbmltcG9ydCB7ZmluZERlZmF1bHRDb2xvckZpZWxkLCBEYXRhQ29udGFpbmVySW50ZXJmYWNlfSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcblxuaW1wb3J0IHtcbiAgZGVmYXVsdCBhcyBLZXBsZXJMYXllcixcbiAgTGF5ZXJCYXNlQ29uZmlnLFxuICBMYXllckJhc2VDb25maWdQYXJ0aWFsLFxuICBWaXN1YWxDaGFubmVsLFxuICBWaXN1YWxDaGFubmVsRG9tYWluLFxuICBWaXN1YWxDaGFubmVsRmllbGRcbn0gZnJvbSAnLi4vYmFzZS1sYXllcic7XG5pbXBvcnQgVGlsZURhdGFzZXQgZnJvbSAnLi9jb21tb24tdGlsZS90aWxlLWRhdGFzZXQnO1xuaW1wb3J0IHtpc0luZGV4ZWRGaWVsZCwgaXNEb21haW5RdWFudGlsZXN9IGZyb20gJy4vY29tbW9uLXRpbGUvdGlsZS11dGlscyc7XG5pbXBvcnQge0ZpbmREZWZhdWx0TGF5ZXJQcm9wc1JldHVyblZhbHVlfSBmcm9tICcuLi9sYXllci11dGlscyc7XG5cbmNvbnN0IERFRkFVTFRfRUxFVkFUSU9OID0gNTAwO1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfUkFESVVTID0gMTtcblxuZXhwb3J0IHR5cGUgQWJzdHJhY3RUaWxlTGF5ZXJWaXNDb25maWdTZXR0aW5ncyA9IHtcbiAgc3Ryb2tlQ29sb3I6IFZpc0NvbmZpZ0NvbG9yU2VsZWN0O1xuICBzdHJva2VPcGFjaXR5OiBWaXNDb25maWdOdW1iZXI7XG4gIHJhZGl1czogVmlzQ29uZmlnTnVtYmVyO1xuICByYWRpdXNVbml0czogVmlzQ29uZmlnQm9vbGVhbjtcbiAgZW5hYmxlM2Q6IFZpc0NvbmZpZ0Jvb2xlYW47XG4gIHN0cm9rZWQ6IFZpc0NvbmZpZ0Jvb2xlYW47XG4gIHRyYW5zaXRpb246IFZpc0NvbmZpZ0Jvb2xlYW47XG4gIGhlaWdodFJhbmdlOiBWaXNDb25maWdSYW5nZTtcbiAgZWxldmF0aW9uU2NhbGU6IFZpc0NvbmZpZ051bWJlcjtcbiAgb3BhY2l0eTogVmlzQ29uZmlnTnVtYmVyO1xuICBjb2xvclJhbmdlOiBWaXNDb25maWdDb2xvclJhbmdlO1xuICAvLyBUT0RPOiBmaWd1cmUgb3V0IHR5cGUgZm9yIHJhZGl1c0J5Wm9vbSB2aXMgY29uZmlnXG4gIHJhZGl1c0J5Wm9vbTogYW55O1xuICBkeW5hbWljQ29sb3I6IFZpc0NvbmZpZ0Jvb2xlYW47XG59O1xuXG5leHBvcnQgdHlwZSBMYXllckRhdGEgPSB7XG4gIG1pblpvb20/OiBudW1iZXI7XG4gIG1heFpvb20/OiBudW1iZXI7XG4gIGJvdW5kcz86IG51bWJlcltdO1xuICBnZXRQb2ludFJhZGl1cz86ICgpID0+IG51bWJlcjtcbn07XG5cbmV4cG9ydCB0eXBlIExheWVyT3B0cyA9IHtcbiAgaWR4OiBudW1iZXI7XG4gIG1hcFN0YXRlOiBNYXBTdGF0ZTtcbiAgZGF0YTogTGF5ZXJEYXRhO1xuICBncHVGaWx0ZXI6IEdwdUZpbHRlcjtcbiAgYW5pbWF0aW9uQ29uZmlnOiBBbmltYXRpb25Db25maWc7XG4gIHRpbGVzZXREYXRhVXJsPzogc3RyaW5nIHwgbnVsbDtcbiAgbGF5ZXJDYWxsYmFja3M6IEJpbmRlZExheWVyQ2FsbGJhY2tzO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbW1vblRpbGVWaXNDb25maWdzID0ge1xuICBzdHJva2VDb2xvcjogJ3N0cm9rZUNvbG9yJyBhcyBjb25zdCxcbiAgc3Ryb2tlT3BhY2l0eToge1xuICAgIC4uLkxBWUVSX1ZJU19DT05GSUdTLm9wYWNpdHksXG4gICAgcHJvcGVydHk6ICdzdHJva2VPcGFjaXR5J1xuICB9LFxuICByYWRpdXM6IHtcbiAgICAuLi5MQVlFUl9WSVNfQ09ORklHUy5yYWRpdXMsXG4gICAgcmFuZ2U6IFswLjEsIDEwMF0sXG4gICAgc3RlcDogMC4xLFxuICAgIGRlZmF1bHRWYWx1ZTogREVGQVVMVF9SQURJVVMsXG4gICAgYWxsb3dDdXN0b21WYWx1ZTogZmFsc2VcbiAgfSBhcyBWaXNDb25maWdOdW1iZXIsXG4gIHJhZGl1c1VuaXRzOiB7XG4gICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgIGRlZmF1bHRWYWx1ZTogdHJ1ZSxcbiAgICBsYWJlbDogJ1JhZGl1cyBpbiBwaXhlbHMnLFxuICAgIGdyb3VwOiAnJyxcbiAgICBwcm9wZXJ0eTogJ3JhZGl1c1VuaXRzJyxcbiAgICBkZXNjcmlwdGlvbjogJ1JhZGl1cyBpbiBwaXhlbHMgb3IgaW4gbWV0ZXJzJ1xuICB9IGFzIFZpc0NvbmZpZ0Jvb2xlYW4sXG4gIGVuYWJsZTNkOiAnZW5hYmxlM2QnIGFzIGNvbnN0LFxuICBzdHJva2VkOiB7XG4gICAgLi4uTEFZRVJfVklTX0NPTkZJR1Muc3Ryb2tlZCxcbiAgICBkZWZhdWx0VmFsdWU6IGZhbHNlXG4gIH0sXG4gIHRyYW5zaXRpb246IHtcbiAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgZGVmYXVsdFZhbHVlOiBmYWxzZSxcbiAgICBsYWJlbDogJ1RyYW5zaXRpb24nLFxuICAgIGdyb3VwOiAnJyxcbiAgICBwcm9wZXJ0eTogJ3RyYW5zaXRpb24nLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgJ1Ntb290aGVyIHRyYW5zaXRpb24gZHVyaW5nIGFuaW1hdGlvbiAoZW5hYmxlIHRyYW5zaXRpb24gd2lsbCBkZWNyZWFzZSBwZXJmb3JtYW5jZSknXG4gIH0gYXMgVmlzQ29uZmlnQm9vbGVhbixcbiAgaGVpZ2h0UmFuZ2U6ICdlbGV2YXRpb25SYW5nZScgYXMgY29uc3QsXG4gIGVsZXZhdGlvblNjYWxlOiB7Li4uTEFZRVJfVklTX0NPTkZJR1MuZWxldmF0aW9uU2NhbGUsIGFsbG93Q3VzdG9tVmFsdWU6IGZhbHNlfSxcbiAgb3BhY2l0eTogJ29wYWNpdHknIGFzIGNvbnN0LFxuICBjb2xvclJhbmdlOiAnY29sb3JSYW5nZScgYXMgY29uc3QsXG4gIC8vIFRPRE86IGZpZ3VyZSBvdXQgdHlwZSBmb3IgcmFkaXVzQnlab29tIHZpcyBjb25maWdcbiAgcmFkaXVzQnlab29tOiB7XG4gICAgLi4uTEFZRVJfVklTX0NPTkZJR1MucmFkaXVzLFxuICAgIGRlZmF1bHRWYWx1ZToge1xuICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICBzdG9wczogbnVsbFxuICAgIH0gYXMgWm9vbVN0b3BzQ29uZmlnXG4gIH0gYXMgYW55LFxuICBkeW5hbWljQ29sb3I6IHtcbiAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgZGVmYXVsdFZhbHVlOiBmYWxzZSxcbiAgICBsYWJlbDogJ0R5bmFtaWMgQ29sb3InLFxuICAgIGdyb3VwOiAnJyxcbiAgICBwcm9wZXJ0eTogJ2R5bmFtaWNDb2xvcicsXG4gICAgZGVzY3JpcHRpb246ICdVc2UgYSBkeW5hbWljIGNvbG9yIHNjYWxlIGJhc2VkIG9uIGRhdGEgdmlzaWJsZSBpbiB0aGUgdmlld3BvcnQnXG4gIH0gYXMgVmlzQ29uZmlnQm9vbGVhblxufTtcblxuZXhwb3J0IHR5cGUgQWJzdHJhY3RUaWxlTGF5ZXJDb25maWcgPSBNZXJnZTxcbiAgTGF5ZXJCYXNlQ29uZmlnLFxuICB7Y29sb3JGaWVsZD86IFZpc3VhbENoYW5uZWxGaWVsZDsgY29sb3JTY2FsZT86IHN0cmluZzsgY29sb3JEb21haW4/OiBWaXN1YWxDaGFubmVsRG9tYWlufVxuPjtcblxuLyoqXG4gKiBBYnN0cmFjdCB0aWxlIGxheWVyLCBpbmNsdWRpbmcgY29tbW9uIGZ1bmN0aW9uYWxpdHkgZm9yIHZpZXdwb3J0LWJhc2VkIGRhdGFzZXRzLFxuICogZHluYW1pYyBzY2FsZXMsIGFuZCB0aWxlLWJhc2VkIGFuaW1hdGlvblxuICovXG5leHBvcnQgZGVmYXVsdCBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdFRpbGVMYXllcjxcbiAgLy8gVHlwZSBvZiB0aGUgdGlsZSBpdHNlbGZcbiAgVCxcbiAgLy8gVHlwZSBvZiB0aGUgaXRlcmFibGUgZGF0YSBvYmplY3RcbiAgSSBleHRlbmRzIEl0ZXJhYmxlPGFueT4gPSBUIGV4dGVuZHMgSXRlcmFibGU8YW55PiA/IFQgOiBuZXZlclxuPiBleHRlbmRzIEtlcGxlckxheWVyIHtcbiAgZGVjbGFyZSBjb25maWc6IEFic3RyYWN0VGlsZUxheWVyQ29uZmlnO1xuICBkZWNsYXJlIHZpc0NvbmZpZ1NldHRpbmdzOiBBYnN0cmFjdFRpbGVMYXllclZpc0NvbmZpZ1NldHRpbmdzO1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBDb25zdHJ1Y3RvclBhcmFtZXRlcnM8dHlwZW9mIEtlcGxlckxheWVyPlswXSkge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnJlZ2lzdGVyVmlzQ29uZmlnKGNvbW1vblRpbGVWaXNDb25maWdzKTtcbiAgICB0aGlzLnRpbGVEYXRhc2V0ID0gdGhpcy5pbml0VGlsZURhdGFzZXQoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB0aWxlRGF0YXNldDogVGlsZURhdGFzZXQ8VCwgST47XG4gIHByb3RlY3RlZCBzZXRMYXllckRvbWFpbjogQmluZGVkTGF5ZXJDYWxsYmFja3NbJ29uU2V0TGF5ZXJEb21haW4nXSA9IHVuZGVmaW5lZDtcblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgaW5pdFRpbGVEYXRhc2V0KCk6IFRpbGVEYXRhc2V0PFQsIEk+O1xuXG4gIHN0YXRpYyBmaW5kRGVmYXVsdExheWVyUHJvcHMoZGF0YXNldDogS2VwbGVyRGF0YXNldCk6IEZpbmREZWZhdWx0TGF5ZXJQcm9wc1JldHVyblZhbHVlIHtcbiAgICBpZiAoIWlzVGlsZURhdGFzZXQoZGF0YXNldCkpIHtcbiAgICAgIHJldHVybiB7cHJvcHM6IFtdfTtcbiAgICB9XG5cbiAgICBjb25zdCBuZXdMYXllclByb3AgPSB7XG4gICAgICBkYXRhSWQ6IGRhdGFzZXQuaWQsXG4gICAgICBsYWJlbDogZGF0YXNldC5sYWJlbCxcbiAgICAgIGlzVmlzaWJsZTogdHJ1ZVxuICAgIH07XG5cbiAgICByZXR1cm4ge3Byb3BzOiBbbmV3TGF5ZXJQcm9wXX07XG4gIH1cblxuICBnZXQgcmVxdWlyZURhdGEoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBnZXQgcmVxdWlyZWRMYXllckNvbHVtbnMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGdldCB2aXN1YWxDaGFubmVscygpOiBSZWNvcmQ8c3RyaW5nLCBWaXN1YWxDaGFubmVsPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbG9yOiB7XG4gICAgICAgIC4uLnN1cGVyLnZpc3VhbENoYW5uZWxzLmNvbG9yLFxuICAgICAgICBhY2Nlc3NvcjogJ2dldEZpbGxDb2xvcicsXG4gICAgICAgIGRlZmF1bHRWYWx1ZTogY29uZmlnID0+IGNvbmZpZy5jb2xvclxuICAgICAgfSxcbiAgICAgIGhlaWdodDoge1xuICAgICAgICBwcm9wZXJ0eTogJ2hlaWdodCcsXG4gICAgICAgIGZpZWxkOiAnaGVpZ2h0RmllbGQnLFxuICAgICAgICBzY2FsZTogJ2hlaWdodFNjYWxlJyxcbiAgICAgICAgZG9tYWluOiAnaGVpZ2h0RG9tYWluJyxcbiAgICAgICAgcmFuZ2U6ICdoZWlnaHRSYW5nZScsXG4gICAgICAgIGtleTogJ2hlaWdodCcsXG4gICAgICAgIGNoYW5uZWxTY2FsZVR5cGU6ICdzaXplJyxcbiAgICAgICAgYWNjZXNzb3I6ICdnZXRFbGV2YXRpb24nLFxuICAgICAgICBjb25kaXRpb246IGNvbmZpZyA9PiBjb25maWcudmlzQ29uZmlnLmVuYWJsZTNkLFxuICAgICAgICBudWxsVmFsdWU6IDAsXG4gICAgICAgIGRlZmF1bHRWYWx1ZTogREVGQVVMVF9FTEVWQVRJT05cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSB2aWV3cG9ydCBjaGFuZ2VzXG4gICAqL1xuICBvblZpZXdwb3J0TG9hZCA9ICh0aWxlczogVFtdKTogdm9pZCA9PiB7XG4gICAgdGhpcy50aWxlRGF0YXNldC51cGRhdGVUaWxlcyh0aWxlcyk7XG4gICAgLy8gVXBkYXRlIGR5bmFtaWMgY29sb3IgZG9tYWluIGlmIHJlcXVpcmVkXG4gICAgaWYgKHRoaXMuY29uZmlnLnZpc0NvbmZpZy5keW5hbWljQ29sb3IpIHtcbiAgICAgIHRoaXMuc2V0RHluYW1pY0NvbG9yRG9tYWluKCk7XG4gICAgfVxuICB9O1xuXG4gIGFic3RyYWN0IGFjY2Vzc1Jvd1ZhbHVlKFxuICAgIGZpZWxkPzogS2VwbGVyRmllbGQsXG4gICAgaW5kZXhLZXk/OiBudW1iZXIgfCBudWxsXG4gICk6IChmaWVsZDogS2VwbGVyRmllbGQsIGRhdHVtOiBUIGV4dGVuZHMgSXRlcmFibGU8aW5mZXIgVj4gPyBWIDogbmV2ZXIpID0+IHN0cmluZyB8IG51bWJlciB8IG51bGw7XG5cbiAgYWNjZXNzVlNGaWVsZFZhbHVlKGlucHV0RmllbGQ/OiBGaWVsZCwgaW5kZXhLZXk/OiBudW1iZXIgfCBudWxsKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5hY2Nlc3NSb3dWYWx1ZShpbnB1dEZpZWxkLCBpbmRleEtleSk7XG4gIH1cblxuICBnZXRTY2FsZU9wdGlvbnMoY2hhbm5lbEtleTogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIGlmIChjaGFubmVsS2V5ID09PSAnY29sb3InKSB7XG4gICAgICBjb25zdCBjaGFubmVsID0gdGhpcy52aXN1YWxDaGFubmVscy5jb2xvcjtcbiAgICAgIGNvbnN0IGZpZWxkID0gdGhpcy5jb25maWdbY2hhbm5lbC5maWVsZF07XG5cbiAgICAgIGlmIChcbiAgICAgICAgaXNEb21haW5RdWFudGlsZXMoZmllbGQ/LmZpbHRlclByb3BzPy5kb21haW5RdWFudGlsZXMpIHx8XG4gICAgICAgIHRoaXMuY29uZmlnLnZpc0NvbmZpZy5keW5hbWljQ29sb3IgfHxcbiAgICAgICAgLy8gSWYgd2UndmUgc2V0IHRoZSBzY2FsZSB0byBxdWFudGlsZSwgd2UgbmVlZCB0byBpbmNsdWRlIGl0IC0gdGhlcmUncyBhIGxvYWRpbmdcbiAgICAgICAgLy8gcGVyaW9kIGluIHdoaWNoIHRoZSB2aXNDb25maWcgaXNuJ3Qgc2V0IHlldCwgYnV0IGlmIHdlIGRvbid0IHJldHVybiB0aGUgcmlnaHRcbiAgICAgICAgLy8gc2NhbGUgdHlwZSB3ZSBsb3NlIGl0XG4gICAgICAgIHRoaXMuY29uZmlnLmNvbG9yU2NhbGUgPT09IFNDQUxFX1RZUEVTLnF1YW50aWxlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIFtTQ0FMRV9UWVBFUy5xdWFudGl6ZSwgU0NBTEVfVFlQRVMucXVhbnRpbGUsIFNDQUxFX1RZUEVTLmN1c3RvbV07XG4gICAgICB9XG4gICAgICByZXR1cm4gW1NDQUxFX1RZUEVTLnF1YW50aXplLCBTQ0FMRV9UWVBFUy5jdXN0b21dO1xuICAgIH1cblxuICAgIHJldHVybiBbU0NBTEVfVFlQRVMubGluZWFyXTtcbiAgfVxuXG4gIHNldER5bmFtaWNDb2xvckRvbWFpbiA9IHRocm90dGxlKCgpOiB2b2lkID0+IHtcbiAgICBjb25zdCB7Y29uZmlnLCB0aWxlRGF0YXNldCwgc2V0TGF5ZXJEb21haW59ID0gdGhpcztcbiAgICBjb25zdCBmaWVsZCA9IGNvbmZpZy5jb2xvckZpZWxkO1xuICAgIGNvbnN0IHtjb2xvckRvbWFpbiwgY29sb3JTY2FsZX0gPSBjb25maWc7XG4gICAgaWYgKCF0aWxlRGF0YXNldCB8fCAhc2V0TGF5ZXJEb21haW4gfHwgIWZpZWxkKSByZXR1cm47XG5cbiAgICBpZiAoY29sb3JTY2FsZSA9PT0gU0NBTEVfVFlQRVMucXVhbnRpemUpIHtcbiAgICAgIGNvbnN0IFttaW4sIG1heF0gPSB0aWxlRGF0YXNldC5nZXRFeHRlbnQoZmllbGQpO1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGNvbG9yRG9tYWluKSB8fCBtaW4gIT09IGNvbG9yRG9tYWluWzBdIHx8IG1heCAhPT0gY29sb3JEb21haW5bMV0pIHtcbiAgICAgICAgc2V0TGF5ZXJEb21haW4oe2RvbWFpbjogW21pbiwgbWF4XX0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY29sb3JTY2FsZSA9PT0gU0NBTEVfVFlQRVMucXVhbnRpbGUpIHtcbiAgICAgIGNvbnN0IGRvbWFpbiA9IHRpbGVEYXRhc2V0LmdldFF1YW50aWxlU2FtcGxlKGZpZWxkKTtcbiAgICAgIHNldExheWVyRG9tYWluKHtkb21haW59KTtcbiAgICB9IGVsc2UgaWYgKGNvbG9yU2NhbGUgPT09IFNDQUxFX1RZUEVTLm9yZGluYWwpIHtcbiAgICAgIGNvbnN0IGRvbWFpbiA9IHRpbGVEYXRhc2V0LmdldFVuaXF1ZVZhbHVlcyhmaWVsZCk7XG4gICAgICBzZXRMYXllckRvbWFpbih7ZG9tYWlufSk7XG4gICAgfVxuICB9LCA1MDApO1xuXG4gIHJlc2V0Q29sb3JEb21haW4oKTogdm9pZCB7XG4gICAgY29uc3Qge2RhdGFzZXRJZCwgZGF0YXNldHN9ID0gdGhpcy5tZXRhO1xuICAgIHRoaXMudXBkYXRlTGF5ZXJWaXN1YWxDaGFubmVsKGRhdGFzZXRzPy5bZGF0YXNldElkIHx8ICcnXSwgJ2NvbG9yJyk7XG4gICAgdGhpcy5zZXRMYXllckRvbWFpbj8uKHtkb21haW46IHRoaXMuY29uZmlnLmNvbG9yRG9tYWlufSk7XG4gIH1cblxuICB1cGRhdGVMYXllckNvbmZpZyhcbiAgICBuZXdDb25maWc6IFBhcnRpYWw8TGF5ZXJCYXNlQ29uZmlnPiAmIFBhcnRpYWw8TGF5ZXJDb2xvckNvbmZpZz5cbiAgKTogQWJzdHJhY3RUaWxlTGF5ZXI8VCwgST4ge1xuICAgIC8vIFdoZW4gdGhlIGR5bmFtaWMgY29sb3Igc2V0dGluZyBjaGFuZ2VzLCB3ZSBuZWVkIHRvIHJlY2FsY3VsYXRlIHRoZSBsYXllciBkb21haW5cbiAgICBjb25zdCBvbGQgPSB0aGlzLmNvbmZpZy52aXNDb25maWcuZHluYW1pY0NvbG9yID8/IGZhbHNlO1xuICAgIGNvbnN0IG5leHQgPSBuZXdDb25maWcudmlzQ29uZmlnPy5keW5hbWljQ29sb3IgPz8gb2xkO1xuICAgIGNvbnN0IHNjYWxlVHlwZUNoYW5nZWQgPVxuICAgICAgbmV3Q29uZmlnLmNvbG9yU2NhbGUgJiYgdGhpcy5jb25maWcuY29sb3JTY2FsZSAhPT0gbmV3Q29uZmlnLmNvbG9yU2NhbGU7XG5cbiAgICBzdXBlci51cGRhdGVMYXllckNvbmZpZyhuZXdDb25maWcpO1xuICAgIGNvbnN0IHtjb2xvckZpZWxkfSA9IHRoaXMuY29uZmlnO1xuXG4gICAgaWYgKGNvbG9yRmllbGQpIHtcbiAgICAgIC8vIFdoZW4gd2Ugc3dpdGNoIGZyb20gZHluYW1pYyB0byBub24tZHluYW1pYyBvciB2aWNlIHZlcnNhLCB3ZSBuZWVkIHRvIHVwZGF0ZVxuICAgICAgLy8gdGhlIGNvbG9yIGRvbWFpbi4gVGhpcyBpcyBkb3duc3RyZWFtIGZyb20gYSBkaXNwYXRjaCBjYWxsLCBzbyB3ZSB1c2VcbiAgICAgIC8vIHNldFRpbWVvdXQgdG8gYXZvaWQgXCJyZWR1Y2VycyBtYXkgbm90IGRpc3BhdGNoIGFjdGlvbnNcIiBlcnJvcnNcbiAgICAgIGlmIChuZXh0ICYmICghb2xkIHx8IHNjYWxlVHlwZUNoYW5nZWQpKSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZXREeW5hbWljQ29sb3JEb21haW4oKSwgMCk7XG4gICAgICB9IGVsc2UgaWYgKG9sZCAmJiAhbmV4dCkge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMucmVzZXRDb2xvckRvbWFpbigpLCAwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGdldCBhbmltYXRpb25Eb21haW4oKTogW251bWJlciwgbnVtYmVyXSB8IG51bGwgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5hbmltYXRpb24uZG9tYWluO1xuICB9XG5cbiAgc2V0SW5pdGlhbExheWVyQ29uZmlnKGRhdGFzZXQ6IEtlcGxlckRhdGFzZXQpOiBBYnN0cmFjdFRpbGVMYXllcjxULCBJPiB7XG4gICAgY29uc3QgZGVmYXVsdENvbG9yRmllbGQgPSBmaW5kRGVmYXVsdENvbG9yRmllbGQoZGF0YXNldCk7XG5cbiAgICBpZiAoZGVmYXVsdENvbG9yRmllbGQpIHtcbiAgICAgIHRoaXMudXBkYXRlTGF5ZXJDb25maWcoe1xuICAgICAgICBjb2xvckZpZWxkOiBkZWZhdWx0Q29sb3JGaWVsZFxuICAgICAgfSk7XG4gICAgICB0aGlzLnVwZGF0ZUxheWVyVmlzdWFsQ2hhbm5lbChkYXRhc2V0LCAnY29sb3InKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGdldERlZmF1bHRMYXllckNvbmZpZyhcbiAgICBwcm9wczogTGF5ZXJCYXNlQ29uZmlnUGFydGlhbFxuICApOiBMYXllckJhc2VDb25maWcgJiBQYXJ0aWFsPExheWVyQ29sb3JDb25maWcgJiBMYXllckhlaWdodENvbmZpZz4ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5zdXBlci5nZXREZWZhdWx0TGF5ZXJDb25maWcocHJvcHMpLFxuICAgICAgY29sb3JTY2FsZTogU0NBTEVfVFlQRVMucXVhbnRpemUsXG5cbiAgICAgIC8vIGFkZCBoZWlnaHQgdmlzdWFsIGNoYW5uZWxcbiAgICAgIGhlaWdodEZpZWxkOiBudWxsLFxuICAgICAgaGVpZ2h0RG9tYWluOiBbMCwgMV0sXG4gICAgICBoZWlnaHRTY2FsZTogJ2xpbmVhcidcbiAgICB9O1xuICB9XG5cbiAgLy8gV2UgY2FuIHJlbmRlciB3aXRob3V0IGNvbHVtbnMsIHNvIHdlIHJlZGVmaW5lIHRoaXMgbWV0aG9kXG4gIHNob3VsZFJlbmRlckxheWVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBCb29sZWFuKHRoaXMudHlwZSAmJiB0aGlzLmNvbmZpZy5pc1Zpc2libGUpO1xuICB9XG5cbiAgdXBkYXRlQW5pbWF0aW9uRG9tYWluQnlGaWVsZChjaGFubmVsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBmaWVsZCA9IHRoaXMuY29uZmlnW3RoaXMudmlzdWFsQ2hhbm5lbHNbY2hhbm5lbF0uZmllbGRdO1xuXG4gICAgaWYgKGlzSW5kZXhlZEZpZWxkKGZpZWxkKSAmJiBmaWVsZC5pbmRleEJ5LnR5cGUgPT09IEFMTF9GSUVMRF9UWVBFUy50aW1lc3RhbXApIHtcbiAgICAgIGNvbnN0IHt0aW1lRG9tYWlufSA9IGZpZWxkLmluZGV4Qnk7XG5cbiAgICAgIHRoaXMudXBkYXRlTGF5ZXJDb25maWcoe1xuICAgICAgICBhbmltYXRpb246IHtcbiAgICAgICAgICAuLi50aW1lRG9tYWluLFxuICAgICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgICAgc3RhcnRUaW1lOiB0aW1lRG9tYWluLmRvbWFpblswXVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGVBbmltYXRpb25Eb21haW4oZG9tYWluOiBbbnVtYmVyLCBudW1iZXJdIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlTGF5ZXJDb25maWcoe1xuICAgICAgYW5pbWF0aW9uOiB7XG4gICAgICAgIC4uLnRoaXMuY29uZmlnLmFuaW1hdGlvbixcbiAgICAgICAgZG9tYWluXG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICB1cGRhdGVMYXllckRvbWFpbihkYXRhc2V0czogS2VwbGVyRGF0YXNldHMsIG5ld0ZpbHRlcj86IEZpbHRlcik6IEFic3RyYWN0VGlsZUxheWVyPFQsIEk+IHtcbiAgICBzdXBlci51cGRhdGVMYXllckRvbWFpbihkYXRhc2V0cywgbmV3RmlsdGVyKTtcbiAgICBpZiAobmV3RmlsdGVyKSB7XG4gICAgICAvLyBpbnZhbGlkYXRlIGNhY2hlZFZpc2libGVEYXRhc2V0IHdoZW4gZS5nLiBjaGFuZ2luZyBmaWx0ZXJzXG4gICAgICB0aGlzLnRpbGVEYXRhc2V0LmludmFsaWRhdGVDYWNoZSgpO1xuICAgIH1cbiAgICBPYmplY3Qua2V5cyh0aGlzLnZpc3VhbENoYW5uZWxzKS5mb3JFYWNoKGNoYW5uZWwgPT4ge1xuICAgICAgdGhpcy51cGRhdGVBbmltYXRpb25Eb21haW5CeUZpZWxkKGNoYW5uZWwpO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdXBkYXRlTGF5ZXJWaXN1YWxDaGFubmVsKGRhdGFzZXQ6IEtlcGxlckRhdGFzZXQsIGNoYW5uZWw6IHN0cmluZyk6IHZvaWQge1xuICAgIHN1cGVyLnVwZGF0ZUxheWVyVmlzdWFsQ2hhbm5lbChkYXRhc2V0LCBjaGFubmVsKTtcblxuICAgIC8vIGNyZWF0ZSBhbmltYXRpb24gaWYgZmllbGQgaXMgaW5kZXhlZCBieSB0aW1lXG4gICAgdGhpcy51cGRhdGVBbmltYXRpb25Eb21haW5CeUZpZWxkKGNoYW5uZWwpO1xuICB9XG5cbiAgZm9ybWF0TGF5ZXJEYXRhKFxuICAgIGRhdGFzZXRzOiBLZXBsZXJEYXRhc2V0cyxcbiAgICBvbGRMYXllckRhdGE6IHVua25vd24sXG4gICAgYW5pbWF0aW9uQ29uZmlnOiBBbmltYXRpb25Db25maWdcbiAgKTogTGF5ZXJEYXRhIHtcbiAgICBjb25zdCB7ZGF0YUlkfSA9IHRoaXMuY29uZmlnO1xuICAgIGlmICghbm90TnVsbG9yVW5kZWZpbmVkKGRhdGFJZCkpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY29uc3QgZGF0YXNldCA9IGRhdGFzZXRzW2RhdGFJZF07XG5cbiAgICBjb25zdCBkYXRhVXBkYXRlVHJpZ2dlcnMgPSB0aGlzLmdldERhdGFVcGRhdGVUcmlnZ2VycyhkYXRhc2V0KTtcbiAgICBjb25zdCB0cmlnZ2VyQ2hhbmdlZCA9IHRoaXMuZ2V0Q2hhbmdlZFRyaWdnZXJzKGRhdGFVcGRhdGVUcmlnZ2Vycyk7XG5cbiAgICBpZiAodHJpZ2dlckNoYW5nZWQgJiYgdHJpZ2dlckNoYW5nZWQuZ2V0TWV0YSkge1xuICAgICAgdGhpcy51cGRhdGVMYXllck1ldGEoZGF0YXNldCwgZGF0YXNldHMpO1xuICAgIH1cblxuICAgIGNvbnN0IGluZGV4S2V5ID0gdGhpcy5jb25maWcuYW5pbWF0aW9uLmVuYWJsZWQgPyBhbmltYXRpb25Db25maWcuY3VycmVudFRpbWUgOiBudWxsO1xuICAgIGNvbnN0IGFjY2Vzc29ycyA9IHRoaXMuZ2V0QXR0cmlidXRlQWNjZXNzb3JzKHtcbiAgICAgIGRhdGFBY2Nlc3NvcjogKCkgPT4gZCA9PiBkLFxuICAgICAgZGF0YUNvbnRhaW5lcjogZGF0YXNldC5kYXRhQ29udGFpbmVyLFxuICAgICAgaW5kZXhLZXlcbiAgICB9KTtcblxuICAgIGNvbnN0IG1ldGFkYXRhID0gZGF0YXNldD8ubWV0YWRhdGEgYXMgTGF5ZXJEYXRhIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IG1ldGFkYXRhVG9EYXRhID0gbWV0YWRhdGFcbiAgICAgID8ge1xuICAgICAgICAgIG1pblpvb206IG1ldGFkYXRhLm1pblpvb20sXG4gICAgICAgICAgbWF4Wm9vbTogbWV0YWRhdGEubWF4Wm9vbSxcbiAgICAgICAgICBib3VuZHM6IG1ldGFkYXRhLmJvdW5kc1xuICAgICAgICB9XG4gICAgICA6IHt9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLm1ldGFkYXRhVG9EYXRhLFxuICAgICAgLi4uYWNjZXNzb3JzXG4gICAgfTtcbiAgfVxuXG4gIGdldEdwdUZpbHRlclZhbHVlQWNjZXNzb3Ioe2dwdUZpbHRlciwgYW5pbWF0aW9uQ29uZmlnfTogTGF5ZXJPcHRzKTogYW55IHtcbiAgICBjb25zdCBpbmRleEtleSA9IHRoaXMuY29uZmlnLmFuaW1hdGlvbi5lbmFibGVkID8gYW5pbWF0aW9uQ29uZmlnLmN1cnJlbnRUaW1lIDogbnVsbDtcbiAgICBjb25zdCB2YWx1ZUFjY2Vzc29yID0gKGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2UsIGQpID0+IGZpZWxkID0+XG4gICAgICB0aGlzLmFjY2Vzc1ZTRmllbGRWYWx1ZShmaWVsZCwgaW5kZXhLZXkpKGZpZWxkLCBkKTtcbiAgICByZXR1cm4gZ3B1RmlsdGVyLmZpbHRlclZhbHVlQWNjZXNzb3IobnVsbCBhcyBhbnkpKHVuZGVmaW5lZCwgdmFsdWVBY2Nlc3Nvcik7XG4gIH1cbn1cbiJd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