kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
396 lines (392 loc) • 54.1 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.hexIdRequiredColumns = exports.hexIdAccessor = exports.defaultElevation = exports.defaultCoverage = exports["default"] = exports.HexagonIdVisConfigs = void 0;
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 _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 _baseLayer = _interopRequireDefault(require("../base-layer"));
var _extensions = require("@deck.gl/extensions");
var _layers = require("@deck.gl/layers");
var _geoLayers = require("@deck.gl/geo-layers");
var _deckglLayers = require("@kepler.gl/deckgl-layers");
var _commonUtils = require("@kepler.gl/common-utils");
var _utils = require("@kepler.gl/utils");
var _h3HexagonLayerIcon = _interopRequireDefault(require("./h3-hexagon-layer-icon"));
var _constants = require("@kepler.gl/constants");
var _layerTextLabel = require("../layer-text-label");
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_LINE_SCALE_VALUE = 8;
var hexIdRequiredColumns = exports.hexIdRequiredColumns = ['hex_id'];
var hexIdAccessor = exports.hexIdAccessor = function hexIdAccessor(_ref) {
var hex_id = _ref.hex_id;
return function (dc) {
return function (d) {
return dc.valueAt(d.index, hex_id.fieldIdx);
};
};
};
var defaultElevation = exports.defaultElevation = 500;
var defaultCoverage = exports.defaultCoverage = 1;
var HexagonIdVisConfigs = exports.HexagonIdVisConfigs = {
colorRange: 'colorRange',
filled: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.filled), {}, {
defaultValue: true
}),
opacity: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.opacity), {}, {
label: 'Fill Opacity',
range: [0, 1],
property: 'opacity'
}),
outline: 'outline',
strokeColor: 'strokeColor',
strokeColorRange: 'strokeColorRange',
strokeOpacity: _objectSpread(_objectSpread({}, _constants.LAYER_VIS_CONFIGS.opacity), {}, {
label: 'Stroke Opacity',
range: [0, 1],
property: 'strokeOpacity'
}),
thickness: 'thickness',
coverage: 'coverage',
enable3d: 'enable3d',
sizeRange: 'elevationRange',
coverageRange: 'coverageRange',
elevationScale: 'elevationScale',
enableElevationZoomFactor: 'enableElevationZoomFactor',
fixedHeight: 'fixedHeight'
};
var brushingExtension = new _extensions.BrushingExtension();
var HexagonIdLayer = exports["default"] = /*#__PURE__*/function (_Layer) {
function HexagonIdLayer(props) {
var _this;
(0, _classCallCheck2["default"])(this, HexagonIdLayer);
_this = _callSuper(this, HexagonIdLayer, [props]);
(0, _defineProperty2["default"])(_this, "dataToFeature", void 0);
_this.dataToFeature = {
centroids: []
};
_this.registerVisConfig(HexagonIdVisConfigs);
_this.getPositionAccessor = function (dataContainer) {
return hexIdAccessor(_this.config.columns)(dataContainer);
};
return _this;
}
(0, _inherits2["default"])(HexagonIdLayer, _Layer);
return (0, _createClass2["default"])(HexagonIdLayer, [{
key: "type",
get: function get() {
return 'hexagonId';
}
}, {
key: "name",
get: function get() {
return 'H3';
}
}, {
key: "requiredLayerColumns",
get: function get() {
return hexIdRequiredColumns;
}
}, {
key: "layerIcon",
get: function get() {
// use hexagon layer icon for now
return _h3HexagonLayerIcon["default"];
}
}, {
key: "visualChannels",
get: function get() {
var visualChannels = _superPropGet(HexagonIdLayer, "visualChannels", this, 1);
return {
color: _objectSpread(_objectSpread({}, visualChannels.color), {}, {
accessor: 'getFillColor',
condition: function condition(config) {
return config.visConfig.filled;
}
}),
strokeColor: {
property: 'strokeColor',
key: 'strokeColor',
field: 'strokeColorField',
scale: 'strokeColorScale',
domain: 'strokeColorDomain',
range: 'strokeColorRange',
channelScaleType: _constants.CHANNEL_SCALES.color,
accessor: 'getLineColor',
condition: function condition(config) {
return config.visConfig.outline;
},
defaultValue: function defaultValue(config) {
return config.visConfig.strokeColor || config.color;
}
},
size: _objectSpread(_objectSpread({}, visualChannels.size), {}, {
property: 'height',
accessor: 'getElevation',
nullValue: 0,
condition: function condition(config) {
return config.visConfig.enable3d;
},
defaultValue: defaultElevation
}),
coverage: {
property: 'coverage',
field: 'coverageField',
scale: 'coverageScale',
domain: 'coverageDomain',
range: 'coverageRange',
key: 'coverage',
channelScaleType: _constants.CHANNEL_SCALES.radius,
accessor: 'getCoverage',
nullValue: 0,
defaultValue: defaultCoverage
}
};
}
}, {
key: "setInitialLayerConfig",
value: function setInitialLayerConfig(dataset) {
if (!dataset.dataContainer.numRows()) {
return this;
}
var defaultColorField = (0, _utils.findDefaultColorField)(dataset);
if (defaultColorField) {
this.updateLayerConfig({
colorField: defaultColorField
});
this.updateLayerVisualChannel(dataset, 'color');
}
return this;
}
}, {
key: "getDefaultLayerConfig",
value: function getDefaultLayerConfig(props) {
var defaultLayerConfig = _superPropGet(HexagonIdLayer, "getDefaultLayerConfig", this, 3)([props]);
return _objectSpread(_objectSpread({}, defaultLayerConfig), {}, {
// add stroke color visual channel
strokeColorField: null,
strokeColorDomain: [0, 1],
strokeColorScale: 'quantile',
colorUI: _objectSpread(_objectSpread({}, defaultLayerConfig.colorUI), {}, {
strokeColorRange: _constants.DEFAULT_COLOR_UI
}),
// add radius visual channel
coverageField: null,
coverageDomain: [0, 1],
coverageScale: 'linear',
// modify default textLabel anchor position to be appropriate for a hexagon shape
textLabel: [_objectSpread(_objectSpread({}, _constants.DEFAULT_TEXT_LABEL), {}, {
anchor: 'middle'
})]
});
}
}, {
key: "calculateDataAttribute",
value: function calculateDataAttribute(_ref2, getHexId) {
var filteredIndex = _ref2.filteredIndex;
var data = [];
for (var i = 0; i < filteredIndex.length; i++) {
var index = filteredIndex[i];
var id = getHexId({
index: index
});
var centroid = this.dataToFeature.centroids[index];
if (centroid) {
data.push({
index: index,
id: id,
centroid: centroid
});
}
}
return data;
}
// TODO: fix complexity
/* eslint-disable complexity */
}, {
key: "formatLayerData",
value: function formatLayerData(datasets, oldLayerData) {
if (this.config.dataId === null) {
return {};
}
var _datasets$this$config = datasets[this.config.dataId],
gpuFilter = _datasets$this$config.gpuFilter,
dataContainer = _datasets$this$config.dataContainer;
var getHexId = this.getPositionAccessor(dataContainer);
var _this$updateData = this.updateData(datasets, oldLayerData),
data = _this$updateData.data,
triggerChanged = _this$updateData.triggerChanged;
var accessors = this.getAttributeAccessors({
dataContainer: dataContainer
});
var textLabel = this.config.textLabel;
// get all distinct characters in the text labels
var textLabels = (0, _layerTextLabel.formatTextLabelData)({
textLabel: textLabel,
triggerChanged: triggerChanged,
oldLayerData: oldLayerData,
data: data,
dataContainer: dataContainer
});
return _objectSpread({
data: data,
getHexId: getHexId,
getFilterValue: gpuFilter.filterValueAccessor(dataContainer)(),
textLabels: textLabels,
getPosition: function getPosition(d) {
return d.centroid;
}
}, accessors);
}
/* eslint-enable complexity */
}, {
key: "updateLayerMeta",
value: function updateLayerMeta(dataset, getHexId) {
var dataContainer = dataset.dataContainer;
var centroids = dataContainer.map(function (d, index) {
var id = getHexId({
index: index
});
if (!(0, _commonUtils.h3IsValid)(id)) {
return null;
}
// save a reference of centroids to dataToFeature
// so we don't have to re calculate it again
return (0, _commonUtils.getCentroid)({
id: id
});
}, true);
var centroidsDataContainer = (0, _utils.createDataContainer)(centroids);
var bounds = this.getPointsBounds(centroidsDataContainer, function (d, dc) {
return [dc.valueAt(d.index, 0), dc.valueAt(d.index, 1)];
});
this.dataToFeature = {
centroids: centroids
};
this.updateMeta({
bounds: bounds
});
}
}, {
key: "renderLayer",
value: function renderLayer(opts) {
var data = opts.data,
gpuFilter = opts.gpuFilter,
objectHovered = opts.objectHovered,
mapState = opts.mapState,
interactionConfig = opts.interactionConfig;
var zoomFactor = this.getZoomFactor(mapState);
var eleZoomFactor = this.getElevationZoomFactor(mapState);
var config = this.config;
var visConfig = config.visConfig;
var updateTriggers = this.getVisualChannelUpdateTriggers();
var h3HexagonLayerTriggers = {
getHexagon: this.config.columns,
getFillColor: updateTriggers.getFillColor,
getLineColor: updateTriggers.getLineColor,
getElevation: updateTriggers.getElevation,
getFilterValue: gpuFilter.filterValueUpdateTriggers
};
var columnLayerTriggers = {
getCoverage: updateTriggers.getCoverage
};
var defaultLayerProps = this.getDefaultDeckLayerProps(opts);
var hoveredObject = this.hasHoveredObject(objectHovered);
// getPixelOffset with no radius
var radiusScale = 1.0;
var getRaidus = null;
var getPixelOffset = (0, _layerTextLabel.getTextOffsetByRadius)(radiusScale, getRaidus, mapState);
var brushingProps = this.getBrushingExtensionProps(interactionConfig);
var extensions = [].concat((0, _toConsumableArray2["default"])(defaultLayerProps.extensions), [brushingExtension]);
var sharedProps = _objectSpread({
getFilterValue: data.getFilterValue,
extensions: extensions,
filterRange: defaultLayerProps.filterRange,
visible: defaultLayerProps.visible
}, brushingProps);
return [new _geoLayers.H3HexagonLayer(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, defaultLayerProps), data), brushingProps), {}, {
extensions: extensions,
wrapLongitude: false,
filled: visConfig.filled,
stroked: visConfig.outline,
lineWidthScale: visConfig.thickness,
getHexagon: function getHexagon(x) {
return x.id;
},
// coverage
coverage: config.coverageField ? 1 : visConfig.coverage,
// highlight
autoHighlight: visConfig.enable3d,
highlightColor: _constants.HIGHLIGH_COLOR_3D,
// elevation
extruded: visConfig.enable3d,
elevationScale: visConfig.elevationScale * eleZoomFactor,
// render
updateTriggers: h3HexagonLayerTriggers,
_subLayerProps: {
'hexagon-cell': {
type: _deckglLayers.EnhancedColumnLayer,
getCoverage: data.getCoverage,
updateTriggers: columnLayerTriggers,
strokeOpacity: visConfig.strokeOpacity
}
}
}))].concat((0, _toConsumableArray2["default"])(hoveredObject && !config.sizeField ? [new _layers.GeoJsonLayer(_objectSpread(_objectSpread({}, this.getDefaultHoverLayerProps()), {}, {
visible: defaultLayerProps.visible,
data: [(0, _commonUtils.idToPolygonGeo)(hoveredObject)],
getLineColor: config.highlightColor,
lineWidthScale: DEFAULT_LINE_SCALE_VALUE * zoomFactor,
wrapLongitude: false
}))] : []), (0, _toConsumableArray2["default"])(this.renderTextLabelLayer({
getPosition: data.getPosition,
sharedProps: sharedProps,
getPixelOffset: getPixelOffset,
updateTriggers: updateTriggers
}, opts)));
}
}], [{
key: "findDefaultLayerProps",
value: function findDefaultLayerProps(_ref3) {
var _ref3$fields = _ref3.fields,
fields = _ref3$fields === void 0 ? [] : _ref3$fields,
dataContainer = _ref3.dataContainer,
label = _ref3.label;
var hexFields = (0, _commonUtils.getHexFields)(fields, dataContainer);
if (!hexFields.length) {
return {
props: []
};
}
return {
props: hexFields.map(function (f) {
return {
isVisible: true,
// default layer name should be dataset name
label: label,
columns: {
hex_id: {
value: f.name,
fieldIdx: fields.findIndex(function (fid) {
return fid.name === f.name;
})
}
}
};
})
};
}
}]);
}(_baseLayer["default"]);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfYmFzZUxheWVyIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfZXh0ZW5zaW9ucyIsIl9sYXllcnMiLCJfZ2VvTGF5ZXJzIiwiX2RlY2tnbExheWVycyIsIl9jb21tb25VdGlscyIsIl91dGlscyIsIl9oM0hleGFnb25MYXllckljb24iLCJfY29uc3RhbnRzIiwiX2xheWVyVGV4dExhYmVsIiwiX2NhbGxTdXBlciIsInQiLCJvIiwiZSIsIl9nZXRQcm90b3R5cGVPZjIiLCJfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjIiLCJfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0IiwiUmVmbGVjdCIsImNvbnN0cnVjdCIsImNvbnN0cnVjdG9yIiwiYXBwbHkiLCJCb29sZWFuIiwicHJvdG90eXBlIiwidmFsdWVPZiIsImNhbGwiLCJfc3VwZXJQcm9wR2V0IiwiciIsInAiLCJfZ2V0MiIsIm93bktleXMiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwiZmlsdGVyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwiZW51bWVyYWJsZSIsInB1c2giLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiREVGQVVMVF9MSU5FX1NDQUxFX1ZBTFVFIiwiaGV4SWRSZXF1aXJlZENvbHVtbnMiLCJleHBvcnRzIiwiaGV4SWRBY2Nlc3NvciIsIl9yZWYiLCJoZXhfaWQiLCJkYyIsImQiLCJ2YWx1ZUF0IiwiaW5kZXgiLCJmaWVsZElkeCIsImRlZmF1bHRFbGV2YXRpb24iLCJkZWZhdWx0Q292ZXJhZ2UiLCJIZXhhZ29uSWRWaXNDb25maWdzIiwiY29sb3JSYW5nZSIsImZpbGxlZCIsIkxBWUVSX1ZJU19DT05GSUdTIiwiZGVmYXVsdFZhbHVlIiwib3BhY2l0eSIsImxhYmVsIiwicmFuZ2UiLCJwcm9wZXJ0eSIsIm91dGxpbmUiLCJzdHJva2VDb2xvciIsInN0cm9rZUNvbG9yUmFuZ2UiLCJzdHJva2VPcGFjaXR5IiwidGhpY2tuZXNzIiwiY292ZXJhZ2UiLCJlbmFibGUzZCIsInNpemVSYW5nZSIsImNvdmVyYWdlUmFuZ2UiLCJlbGV2YXRpb25TY2FsZSIsImVuYWJsZUVsZXZhdGlvblpvb21GYWN0b3IiLCJmaXhlZEhlaWdodCIsImJydXNoaW5nRXh0ZW5zaW9uIiwiQnJ1c2hpbmdFeHRlbnNpb24iLCJIZXhhZ29uSWRMYXllciIsIl9MYXllciIsInByb3BzIiwiX3RoaXMiLCJfY2xhc3NDYWxsQ2hlY2syIiwiZGF0YVRvRmVhdHVyZSIsImNlbnRyb2lkcyIsInJlZ2lzdGVyVmlzQ29uZmlnIiwiZ2V0UG9zaXRpb25BY2Nlc3NvciIsImRhdGFDb250YWluZXIiLCJjb25maWciLCJjb2x1bW5zIiwiX2luaGVyaXRzMiIsIl9jcmVhdGVDbGFzczIiLCJrZXkiLCJnZXQiLCJIM0hleGFnb25MYXllckljb24iLCJ2aXN1YWxDaGFubmVscyIsImNvbG9yIiwiYWNjZXNzb3IiLCJjb25kaXRpb24iLCJ2aXNDb25maWciLCJmaWVsZCIsInNjYWxlIiwiZG9tYWluIiwiY2hhbm5lbFNjYWxlVHlwZSIsIkNIQU5ORUxfU0NBTEVTIiwic2l6ZSIsIm51bGxWYWx1ZSIsInJhZGl1cyIsInZhbHVlIiwic2V0SW5pdGlhbExheWVyQ29uZmlnIiwiZGF0YXNldCIsIm51bVJvd3MiLCJkZWZhdWx0Q29sb3JGaWVsZCIsImZpbmREZWZhdWx0Q29sb3JGaWVsZCIsInVwZGF0ZUxheWVyQ29uZmlnIiwiY29sb3JGaWVsZCIsInVwZGF0ZUxheWVyVmlzdWFsQ2hhbm5lbCIsImdldERlZmF1bHRMYXllckNvbmZpZyIsImRlZmF1bHRMYXllckNvbmZpZyIsInN0cm9rZUNvbG9yRmllbGQiLCJzdHJva2VDb2xvckRvbWFpbiIsInN0cm9rZUNvbG9yU2NhbGUiLCJjb2xvclVJIiwiREVGQVVMVF9DT0xPUl9VSSIsImNvdmVyYWdlRmllbGQiLCJjb3ZlcmFnZURvbWFpbiIsImNvdmVyYWdlU2NhbGUiLCJ0ZXh0TGFiZWwiLCJERUZBVUxUX1RFWFRfTEFCRUwiLCJhbmNob3IiLCJjYWxjdWxhdGVEYXRhQXR0cmlidXRlIiwiX3JlZjIiLCJnZXRIZXhJZCIsImZpbHRlcmVkSW5kZXgiLCJkYXRhIiwiaSIsImlkIiwiY2VudHJvaWQiLCJmb3JtYXRMYXllckRhdGEiLCJkYXRhc2V0cyIsIm9sZExheWVyRGF0YSIsImRhdGFJZCIsIl9kYXRhc2V0cyR0aGlzJGNvbmZpZyIsImdwdUZpbHRlciIsIl90aGlzJHVwZGF0ZURhdGEiLCJ1cGRhdGVEYXRhIiwidHJpZ2dlckNoYW5nZWQiLCJhY2Nlc3NvcnMiLCJnZXRBdHRyaWJ1dGVBY2Nlc3NvcnMiLCJ0ZXh0TGFiZWxzIiwiZm9ybWF0VGV4dExhYmVsRGF0YSIsImdldEZpbHRlclZhbHVlIiwiZmlsdGVyVmFsdWVBY2Nlc3NvciIsImdldFBvc2l0aW9uIiwidXBkYXRlTGF5ZXJNZXRhIiwibWFwIiwiaDNJc1ZhbGlkIiwiZ2V0Q2VudHJvaWQiLCJjZW50cm9pZHNEYXRhQ29udGFpbmVyIiwiY3JlYXRlRGF0YUNvbnRhaW5lciIsImJvdW5kcyIsImdldFBvaW50c0JvdW5kcyIsInVwZGF0ZU1ldGEiLCJyZW5kZXJMYXllciIsIm9wdHMiLCJvYmplY3RIb3ZlcmVkIiwibWFwU3RhdGUiLCJpbnRlcmFjdGlvbkNvbmZpZyIsInpvb21GYWN0b3IiLCJnZXRab29tRmFjdG9yIiwiZWxlWm9vbUZhY3RvciIsImdldEVsZXZhdGlvblpvb21GYWN0b3IiLCJ1cGRhdGVUcmlnZ2VycyIsImdldFZpc3VhbENoYW5uZWxVcGRhdGVUcmlnZ2VycyIsImgzSGV4YWdvbkxheWVyVHJpZ2dlcnMiLCJnZXRIZXhhZ29uIiwiZ2V0RmlsbENvbG9yIiwiZ2V0TGluZUNvbG9yIiwiZ2V0RWxldmF0aW9uIiwiZmlsdGVyVmFsdWVVcGRhdGVUcmlnZ2VycyIsImNvbHVtbkxheWVyVHJpZ2dlcnMiLCJnZXRDb3ZlcmFnZSIsImRlZmF1bHRMYXllclByb3BzIiwiZ2V0RGVmYXVsdERlY2tMYXllclByb3BzIiwiaG92ZXJlZE9iamVjdCIsImhhc0hvdmVyZWRPYmplY3QiLCJyYWRpdXNTY2FsZSIsImdldFJhaWR1cyIsImdldFBpeGVsT2Zmc2V0IiwiZ2V0VGV4dE9mZnNldEJ5UmFkaXVzIiwiYnJ1c2hpbmdQcm9wcyIsImdldEJydXNoaW5nRXh0ZW5zaW9uUHJvcHMiLCJleHRlbnNpb25zIiwiY29uY2F0IiwiX3RvQ29uc3VtYWJsZUFycmF5MiIsInNoYXJlZFByb3BzIiwiZmlsdGVyUmFuZ2UiLCJ2aXNpYmxlIiwiSDNIZXhhZ29uTGF5ZXIiLCJ3cmFwTG9uZ2l0dWRlIiwic3Ryb2tlZCIsImxpbmVXaWR0aFNjYWxlIiwieCIsImF1dG9IaWdobGlnaHQiLCJoaWdobGlnaHRDb2xvciIsIkhJR0hMSUdIX0NPTE9SXzNEIiwiZXh0cnVkZWQiLCJfc3ViTGF5ZXJQcm9wcyIsInR5cGUiLCJFbmhhbmNlZENvbHVtbkxheWVyIiwic2l6ZUZpZWxkIiwiR2VvSnNvbkxheWVyIiwiZ2V0RGVmYXVsdEhvdmVyTGF5ZXJQcm9wcyIsImlkVG9Qb2x5Z29uR2VvIiwicmVuZGVyVGV4dExhYmVsTGF5ZXIiLCJmaW5kRGVmYXVsdExheWVyUHJvcHMiLCJfcmVmMyIsIl9yZWYzJGZpZWxkcyIsImZpZWxkcyIsImhleEZpZWxkcyIsImdldEhleEZpZWxkcyIsImYiLCJpc1Zpc2libGUiLCJuYW1lIiwiZmluZEluZGV4IiwiZmlkIiwiTGF5ZXIiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvaDMtaGV4YWdvbi1sYXllci9oMy1oZXhhZ29uLWxheWVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbmltcG9ydCBMYXllciwge1xuICBMYXllckJhc2VDb25maWcsXG4gIExheWVyQmFzZUNvbmZpZ1BhcnRpYWwsXG4gIExheWVyQ29sb3JDb25maWcsXG4gIExheWVyQ292ZXJhZ2VDb25maWcsXG4gIExheWVyU2l6ZUNvbmZpZ1xufSBmcm9tICcuLi9iYXNlLWxheWVyJztcbmltcG9ydCB7QnJ1c2hpbmdFeHRlbnNpb259IGZyb20gJ0BkZWNrLmdsL2V4dGVuc2lvbnMnO1xuaW1wb3J0IHtHZW9Kc29uTGF5ZXJ9IGZyb20gJ0BkZWNrLmdsL2xheWVycyc7XG5pbXBvcnQge0gzSGV4YWdvbkxheWVyfSBmcm9tICdAZGVjay5nbC9nZW8tbGF5ZXJzJztcbmltcG9ydCB7RW5oYW5jZWRDb2x1bW5MYXllcn0gZnJvbSAnQGtlcGxlci5nbC9kZWNrZ2wtbGF5ZXJzJztcbmltcG9ydCB7XG4gIGdldENlbnRyb2lkLFxuICBpZFRvUG9seWdvbkdlbyxcbiAgaDNJc1ZhbGlkLFxuICBnZXRIZXhGaWVsZHMsXG4gIENlbnRyb2lkXG59IGZyb20gJ0BrZXBsZXIuZ2wvY29tbW9uLXV0aWxzJztcbmltcG9ydCB7ZmluZERlZmF1bHRDb2xvckZpZWxkLCBEYXRhQ29udGFpbmVySW50ZXJmYWNlLCBjcmVhdGVEYXRhQ29udGFpbmVyfSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcbmltcG9ydCBIM0hleGFnb25MYXllckljb24gZnJvbSAnLi9oMy1oZXhhZ29uLWxheWVyLWljb24nO1xuaW1wb3J0IHtcbiAgQ0hBTk5FTF9TQ0FMRVMsXG4gIEhJR0hMSUdIX0NPTE9SXzNELFxuICBERUZBVUxUX0NPTE9SX1VJLFxuICBERUZBVUxUX1RFWFRfTEFCRUwsXG4gIExBWUVSX1ZJU19DT05GSUdTXG59IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcblxuaW1wb3J0IHtcbiAgQ29sb3JSYW5nZSxcbiAgVmlzQ29uZmlnQm9vbGVhbixcbiAgVmlzQ29uZmlnQ29sb3JSYW5nZSxcbiAgVmlzQ29uZmlnTnVtYmVyLFxuICBWaXNDb25maWdSYW5nZSxcbiAgTWVyZ2UsXG4gIExheWVyQ29sdW1uXG59IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuaW1wb3J0IHtLZXBsZXJUYWJsZX0gZnJvbSAnQGtlcGxlci5nbC90YWJsZSc7XG5cbmltcG9ydCB7Z2V0VGV4dE9mZnNldEJ5UmFkaXVzLCBmb3JtYXRUZXh0TGFiZWxEYXRhfSBmcm9tICcuLi9sYXllci10ZXh0LWxhYmVsJztcblxuZXhwb3J0IHR5cGUgSGV4YWdvbklkTGF5ZXJDb2x1bW5zQ29uZmlnID0ge1xuICBoZXhfaWQ6IExheWVyQ29sdW1uO1xufTtcblxuZXhwb3J0IHR5cGUgSGV4YWdvbklkTGF5ZXJWaXNDb25maWdTZXR0aW5ncyA9IHtcbiAgb3BhY2l0eTogVmlzQ29uZmlnTnVtYmVyO1xuICBzdHJva2VPcGFjaXR5OiBWaXNDb25maWdOdW1iZXI7XG4gIGNvbG9yUmFuZ2U6IFZpc0NvbmZpZ0NvbG9yUmFuZ2U7XG4gIGNvdmVyYWdlOiBWaXNDb25maWdOdW1iZXI7XG4gIGVuYWJsZTNkOiBWaXNDb25maWdCb29sZWFuO1xuICBzaXplUmFuZ2U6IFZpc0NvbmZpZ1JhbmdlO1xuICBjb3ZlcmFnZVJhbmdlOiBWaXNDb25maWdSYW5nZTtcbiAgZWxldmF0aW9uU2NhbGU6IFZpc0NvbmZpZ051bWJlcjtcbiAgZW5hYmxlRWxldmF0aW9uWm9vbUZhY3RvcjogVmlzQ29uZmlnQm9vbGVhbjtcbiAgZmlsbGVkOiBWaXNDb25maWdCb29sZWFuO1xuICBvdXRsaW5lOiBWaXNDb25maWdCb29sZWFuO1xuICB0aGlja25lc3M6IFZpc0NvbmZpZ051bWJlcjtcbn07XG5cbmV4cG9ydCB0eXBlIEhleGFnb25JZExheWVyVmlzQ29uZmlnID0ge1xuICBvcGFjaXR5OiBudW1iZXI7XG4gIHN0cm9rZU9wYWNpdHk6IG51bWJlcjtcbiAgY29sb3JSYW5nZTogQ29sb3JSYW5nZTtcbiAgY292ZXJhZ2U6IG51bWJlcjtcbiAgZW5hYmxlM2Q6IGJvb2xlYW47XG4gIHNpemVSYW5nZTogW251bWJlciwgbnVtYmVyXTtcbiAgY292ZXJhZ2VSYW5nZTogW251bWJlciwgbnVtYmVyXTtcbiAgZWxldmF0aW9uU2NhbGU6IG51bWJlcjtcbiAgZW5hYmxlRWxldmF0aW9uWm9vbUZhY3RvcjogYm9vbGVhbjtcbiAgZmlsbGVkOiBib29sZWFuO1xuICBvdXRsaW5lOiBib29sZWFuO1xuICB0aGlja25lc3M6IG51bWJlcjtcbn07XG5cbmV4cG9ydCB0eXBlIEhleGFnb25JZExheWVyVmlzdWFsQ2hhbm5lbENvbmZpZyA9IExheWVyQ29sb3JDb25maWcgJlxuICBMYXllclNpemVDb25maWcgJlxuICBMYXllckNvdmVyYWdlQ29uZmlnO1xuZXhwb3J0IHR5cGUgSGV4YWdvbklkTGF5ZXJDb25maWcgPSBNZXJnZTxcbiAgTGF5ZXJCYXNlQ29uZmlnLFxuICB7Y29sdW1uczogSGV4YWdvbklkTGF5ZXJDb2x1bW5zQ29uZmlnOyB2aXNDb25maWc6IEhleGFnb25JZExheWVyVmlzQ29uZmlnfVxuPiAmXG4gIEhleGFnb25JZExheWVyVmlzdWFsQ2hhbm5lbENvbmZpZztcblxuZXhwb3J0IHR5cGUgSGV4YWdvbklkTGF5ZXJEYXRhID0ge2luZGV4OiBudW1iZXI7IGlkOyBjZW50cm9pZDogQ2VudHJvaWR9O1xuXG5jb25zdCBERUZBVUxUX0xJTkVfU0NBTEVfVkFMVUUgPSA4O1xuXG5leHBvcnQgY29uc3QgaGV4SWRSZXF1aXJlZENvbHVtbnM6IFsnaGV4X2lkJ10gPSBbJ2hleF9pZCddO1xuZXhwb3J0IGNvbnN0IGhleElkQWNjZXNzb3IgPVxuICAoe2hleF9pZH06IEhleGFnb25JZExheWVyQ29sdW1uc0NvbmZpZykgPT5cbiAgKGRjOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlKSA9PlxuICBkID0+XG4gICAgZGMudmFsdWVBdChkLmluZGV4LCBoZXhfaWQuZmllbGRJZHgpO1xuXG5leHBvcnQgY29uc3QgZGVmYXVsdEVsZXZhdGlvbiA9IDUwMDtcbmV4cG9ydCBjb25zdCBkZWZhdWx0Q292ZXJhZ2UgPSAxO1xuXG5leHBvcnQgY29uc3QgSGV4YWdvbklkVmlzQ29uZmlnczoge1xuICBvcGFjaXR5OiBWaXNDb25maWdOdW1iZXI7XG4gIHN0cm9rZU9wYWNpdHk6IFZpc0NvbmZpZ051bWJlcjtcbiAgY29sb3JSYW5nZTogJ2NvbG9yUmFuZ2UnO1xuICBmaWxsZWQ6IFZpc0NvbmZpZ0Jvb2xlYW47XG4gIG91dGxpbmU6ICdvdXRsaW5lJztcbiAgc3Ryb2tlQ29sb3I6ICdzdHJva2VDb2xvcic7XG4gIHN0cm9rZUNvbG9yUmFuZ2U6ICdzdHJva2VDb2xvclJhbmdlJztcbiAgdGhpY2tuZXNzOiAndGhpY2tuZXNzJztcbiAgY292ZXJhZ2U6ICdjb3ZlcmFnZSc7XG4gIGVuYWJsZTNkOiAnZW5hYmxlM2QnO1xuICBzaXplUmFuZ2U6ICdlbGV2YXRpb25SYW5nZSc7XG4gIGNvdmVyYWdlUmFuZ2U6ICdjb3ZlcmFnZVJhbmdlJztcbiAgZWxldmF0aW9uU2NhbGU6ICdlbGV2YXRpb25TY2FsZSc7XG4gIGVuYWJsZUVsZXZhdGlvblpvb21GYWN0b3I6ICdlbmFibGVFbGV2YXRpb25ab29tRmFjdG9yJztcbiAgZml4ZWRIZWlnaHQ6ICdmaXhlZEhlaWdodCc7XG59ID0ge1xuICBjb2xvclJhbmdlOiAnY29sb3JSYW5nZScsXG4gIGZpbGxlZDoge1xuICAgIC4uLkxBWUVSX1ZJU19DT05GSUdTLmZpbGxlZCxcbiAgICBkZWZhdWx0VmFsdWU6IHRydWVcbiAgfSxcbiAgb3BhY2l0eToge1xuICAgIC4uLkxBWUVSX1ZJU19DT05GSUdTLm9wYWNpdHksXG4gICAgbGFiZWw6ICdGaWxsIE9wYWNpdHknLFxuICAgIHJhbmdlOiBbMCwgMV0sXG4gICAgcHJvcGVydHk6ICdvcGFjaXR5J1xuICB9LFxuICBvdXRsaW5lOiAnb3V0bGluZScsXG4gIHN0cm9rZUNvbG9yOiAnc3Ryb2tlQ29sb3InLFxuICBzdHJva2VDb2xvclJhbmdlOiAnc3Ryb2tlQ29sb3JSYW5nZScsXG4gIHN0cm9rZU9wYWNpdHk6IHtcbiAgICAuLi5MQVlFUl9WSVNfQ09ORklHUy5vcGFjaXR5LFxuICAgIGxhYmVsOiAnU3Ryb2tlIE9wYWNpdHknLFxuICAgIHJhbmdlOiBbMCwgMV0sXG4gICAgcHJvcGVydHk6ICdzdHJva2VPcGFjaXR5J1xuICB9LFxuICB0aGlja25lc3M6ICd0aGlja25lc3MnLFxuICBjb3ZlcmFnZTogJ2NvdmVyYWdlJyxcbiAgZW5hYmxlM2Q6ICdlbmFibGUzZCcsXG4gIHNpemVSYW5nZTogJ2VsZXZhdGlvblJhbmdlJyxcbiAgY292ZXJhZ2VSYW5nZTogJ2NvdmVyYWdlUmFuZ2UnLFxuICBlbGV2YXRpb25TY2FsZTogJ2VsZXZhdGlvblNjYWxlJyxcbiAgZW5hYmxlRWxldmF0aW9uWm9vbUZhY3RvcjogJ2VuYWJsZUVsZXZhdGlvblpvb21GYWN0b3InLFxuICBmaXhlZEhlaWdodDogJ2ZpeGVkSGVpZ2h0J1xufTtcblxuY29uc3QgYnJ1c2hpbmdFeHRlbnNpb24gPSBuZXcgQnJ1c2hpbmdFeHRlbnNpb24oKTtcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEhleGFnb25JZExheWVyIGV4dGVuZHMgTGF5ZXIge1xuICBkYXRhVG9GZWF0dXJlOiB7Y2VudHJvaWRzOiBDZW50cm9pZFtdfTtcblxuICBkZWNsYXJlIGNvbmZpZzogSGV4YWdvbklkTGF5ZXJDb25maWc7XG4gIGRlY2xhcmUgdmlzQ29uZmlnU2V0dGluZ3M6IEhleGFnb25JZExheWVyVmlzQ29uZmlnU2V0dGluZ3M7XG4gIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICAgIHRoaXMuZGF0YVRvRmVhdHVyZSA9IHtjZW50cm9pZHM6IFtdfTtcbiAgICB0aGlzLnJlZ2lzdGVyVmlzQ29uZmlnKEhleGFnb25JZFZpc0NvbmZpZ3MpO1xuICAgIHRoaXMuZ2V0UG9zaXRpb25BY2Nlc3NvciA9IChkYXRhQ29udGFpbmVyOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlKSA9PlxuICAgICAgaGV4SWRBY2Nlc3Nvcih0aGlzLmNvbmZpZy5jb2x1bW5zKShkYXRhQ29udGFpbmVyKTtcbiAgfVxuXG4gIGdldCB0eXBlKCk6ICdoZXhhZ29uSWQnIHtcbiAgICByZXR1cm4gJ2hleGFnb25JZCc7XG4gIH1cblxuICBnZXQgbmFtZSgpOiAnSDMnIHtcbiAgICByZXR1cm4gJ0gzJztcbiAgfVxuXG4gIGdldCByZXF1aXJlZExheWVyQ29sdW1ucygpIHtcbiAgICByZXR1cm4gaGV4SWRSZXF1aXJlZENvbHVtbnM7XG4gIH1cblxuICBnZXQgbGF5ZXJJY29uKCkge1xuICAgIC8vIHVzZSBoZXhhZ29uIGxheWVyIGljb24gZm9yIG5vd1xuICAgIHJldHVybiBIM0hleGFnb25MYXllckljb247XG4gIH1cblxuICBnZXQgdmlzdWFsQ2hhbm5lbHMoKSB7XG4gICAgY29uc3QgdmlzdWFsQ2hhbm5lbHMgPSBzdXBlci52aXN1YWxDaGFubmVscztcbiAgICByZXR1cm4ge1xuICAgICAgY29sb3I6IHtcbiAgICAgICAgLi4udmlzdWFsQ2hhbm5lbHMuY29sb3IsXG4gICAgICAgIGFjY2Vzc29yOiAnZ2V0RmlsbENvbG9yJyxcbiAgICAgICAgY29uZGl0aW9uOiBjb25maWcgPT4gY29uZmlnLnZpc0NvbmZpZy5maWxsZWRcbiAgICAgIH0sXG4gICAgICBzdHJva2VDb2xvcjoge1xuICAgICAgICBwcm9wZXJ0eTogJ3N0cm9rZUNvbG9yJyxcbiAgICAgICAga2V5OiAnc3Ryb2tlQ29sb3InLFxuICAgICAgICBmaWVsZDogJ3N0cm9rZUNvbG9yRmllbGQnLFxuICAgICAgICBzY2FsZTogJ3N0cm9rZUNvbG9yU2NhbGUnLFxuICAgICAgICBkb21haW46ICdzdHJva2VDb2xvckRvbWFpbicsXG4gICAgICAgIHJhbmdlOiAnc3Ryb2tlQ29sb3JSYW5nZScsXG4gICAgICAgIGNoYW5uZWxTY2FsZVR5cGU6IENIQU5ORUxfU0NBTEVTLmNvbG9yLFxuICAgICAgICBhY2Nlc3NvcjogJ2dldExpbmVDb2xvcicsXG4gICAgICAgIGNvbmRpdGlvbjogY29uZmlnID0+IGNvbmZpZy52aXNDb25maWcub3V0bGluZSxcbiAgICAgICAgZGVmYXVsdFZhbHVlOiBjb25maWcgPT4gY29uZmlnLnZpc0NvbmZpZy5zdHJva2VDb2xvciB8fCBjb25maWcuY29sb3JcbiAgICAgIH0sXG4gICAgICBzaXplOiB7XG4gICAgICAgIC4uLnZpc3VhbENoYW5uZWxzLnNpemUsXG4gICAgICAgIHByb3BlcnR5OiAnaGVpZ2h0JyxcbiAgICAgICAgYWNjZXNzb3I6ICdnZXRFbGV2YXRpb24nLFxuICAgICAgICBudWxsVmFsdWU6IDAsXG4gICAgICAgIGNvbmRpdGlvbjogY29uZmlnID0+IGNvbmZpZy52aXNDb25maWcuZW5hYmxlM2QsXG4gICAgICAgIGRlZmF1bHRWYWx1ZTogZGVmYXVsdEVsZXZhdGlvblxuICAgICAgfSxcbiAgICAgIGNvdmVyYWdlOiB7XG4gICAgICAgIHByb3BlcnR5OiAnY292ZXJhZ2UnLFxuICAgICAgICBmaWVsZDogJ2NvdmVyYWdlRmllbGQnLFxuICAgICAgICBzY2FsZTogJ2NvdmVyYWdlU2NhbGUnLFxuICAgICAgICBkb21haW46ICdjb3ZlcmFnZURvbWFpbicsXG4gICAgICAgIHJhbmdlOiAnY292ZXJhZ2VSYW5nZScsXG4gICAgICAgIGtleTogJ2NvdmVyYWdlJyxcbiAgICAgICAgY2hhbm5lbFNjYWxlVHlwZTogQ0hBTk5FTF9TQ0FMRVMucmFkaXVzLFxuICAgICAgICBhY2Nlc3NvcjogJ2dldENvdmVyYWdlJyxcbiAgICAgICAgbnVsbFZhbHVlOiAwLFxuICAgICAgICBkZWZhdWx0VmFsdWU6IGRlZmF1bHRDb3ZlcmFnZVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBzZXRJbml0aWFsTGF5ZXJDb25maWcoZGF0YXNldCkge1xuICAgIGlmICghZGF0YXNldC5kYXRhQ29udGFpbmVyLm51bVJvd3MoKSkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNvbnN0IGRlZmF1bHRDb2xvckZpZWxkID0gZmluZERlZmF1bHRDb2xvckZpZWxkKGRhdGFzZXQpO1xuXG4gICAgaWYgKGRlZmF1bHRDb2xvckZpZWxkKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxheWVyQ29uZmlnPEhleGFnb25JZExheWVyQ29uZmlnPih7XG4gICAgICAgIGNvbG9yRmllbGQ6IGRlZmF1bHRDb2xvckZpZWxkXG4gICAgICB9KTtcbiAgICAgIHRoaXMudXBkYXRlTGF5ZXJWaXN1YWxDaGFubmVsKGRhdGFzZXQsICdjb2xvcicpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGZpbmREZWZhdWx0TGF5ZXJQcm9wcyh7ZmllbGRzID0gW10sIGRhdGFDb250YWluZXIsIGxhYmVsfTogS2VwbGVyVGFibGUpIHtcbiAgICBjb25zdCBoZXhGaWVsZHMgPSBnZXRIZXhGaWVsZHMoZmllbGRzLCBkYXRhQ29udGFpbmVyKTtcbiAgICBpZiAoIWhleEZpZWxkcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB7cHJvcHM6IFtdfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcHJvcHM6IGhleEZpZWxkcy5tYXAoZiA9PiAoe1xuICAgICAgICBpc1Zpc2libGU6IHRydWUsXG4gICAgICAgIC8vIGRlZmF1bHQgbGF5ZXIgbmFtZSBzaG91bGQgYmUgZGF0YXNldCBuYW1lXG4gICAgICAgIGxhYmVsLFxuICAgICAgICBjb2x1bW5zOiB7XG4gICAgICAgICAgaGV4X2lkOiB7XG4gICAgICAgICAgICB2YWx1ZTogZi5uYW1lLFxuICAgICAgICAgICAgZmllbGRJZHg6IGZpZWxkcy5maW5kSW5kZXgoZmlkID0+IGZpZC5uYW1lID09PSBmLm5hbWUpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KSlcbiAgICB9O1xuICB9XG5cbiAgZ2V0RGVmYXVsdExheWVyQ29uZmlnKHByb3BzOiBMYXllckJhc2VDb25maWdQYXJ0aWFsKSB7XG4gICAgY29uc3QgZGVmYXVsdExheWVyQ29uZmlnID0gc3VwZXIuZ2V0RGVmYXVsdExheWVyQ29uZmlnKHByb3BzKTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5kZWZhdWx0TGF5ZXJDb25maWcsXG5cbiAgICAgIC8vIGFkZCBzdHJva2UgY29sb3IgdmlzdWFsIGNoYW5uZWxcbiAgICAgIHN0cm9rZUNvbG9yRmllbGQ6IG51bGwsXG4gICAgICBzdHJva2VDb2xvckRvbWFpbjogWzAsIDFdLFxuICAgICAgc3Ryb2tlQ29sb3JTY2FsZTogJ3F1YW50aWxlJyxcbiAgICAgIGNvbG9yVUk6IHtcbiAgICAgICAgLi4uZGVmYXVsdExheWVyQ29uZmlnLmNvbG9yVUksXG4gICAgICAgIHN0cm9rZUNvbG9yUmFuZ2U6IERFRkFVTFRfQ09MT1JfVUlcbiAgICAgIH0sXG5cbiAgICAgIC8vIGFkZCByYWRpdXMgdmlzdWFsIGNoYW5uZWxcbiAgICAgIGNvdmVyYWdlRmllbGQ6IG51bGwsXG4gICAgICBjb3ZlcmFnZURvbWFpbjogWzAsIDFdLFxuICAgICAgY292ZXJhZ2VTY2FsZTogJ2xpbmVhcicsXG5cbiAgICAgIC8vIG1vZGlmeSBkZWZhdWx0IHRleHRMYWJlbCBhbmNob3IgcG9zaXRpb24gdG8gYmUgYXBwcm9wcmlhdGUgZm9yIGEgaGV4YWdvbiBzaGFwZVxuICAgICAgdGV4dExhYmVsOiBbXG4gICAgICAgIHtcbiAgICAgICAgICAuLi5ERUZBVUxUX1RFWFRfTEFCRUwsXG4gICAgICAgICAgYW5jaG9yOiAnbWlkZGxlJ1xuICAgICAgICB9XG4gICAgICBdXG4gICAgfTtcbiAgfVxuXG4gIGNhbGN1bGF0ZURhdGFBdHRyaWJ1dGUoe2ZpbHRlcmVkSW5kZXh9OiBLZXBsZXJUYWJsZSwgZ2V0SGV4SWQpIHtcbiAgICBjb25zdCBkYXRhOiBIZXhhZ29uSWRMYXllckRhdGFbXSA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWx0ZXJlZEluZGV4Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpbmRleCA9IGZpbHRlcmVkSW5kZXhbaV07XG4gICAgICBjb25zdCBpZCA9IGdldEhleElkKHtpbmRleH0pO1xuICAgICAgY29uc3QgY2VudHJvaWQgPSB0aGlzLmRhdGFUb0ZlYXR1cmUuY2VudHJvaWRzW2luZGV4XTtcblxuICAgICAgaWYgKGNlbnRyb2lkKSB7XG4gICAgICAgIGRhdGEucHVzaCh7XG4gICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgaWQsXG4gICAgICAgICAgY2VudHJvaWRcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgLy8gVE9ETzogZml4IGNvbXBsZXhpdHlcbiAgLyogZXNsaW50LWRpc2FibGUgY29tcGxleGl0eSAqL1xuICBmb3JtYXRMYXllckRhdGEoZGF0YXNldHMsIG9sZExheWVyRGF0YSkge1xuICAgIGlmICh0aGlzLmNvbmZpZy5kYXRhSWQgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY29uc3Qge2dwdUZpbHRlciwgZGF0YUNvbnRhaW5lcn0gPSBkYXRhc2V0c1t0aGlzLmNvbmZpZy5kYXRhSWRdO1xuICAgIGNvbnN0IGdldEhleElkID0gdGhpcy5nZXRQb3NpdGlvbkFjY2Vzc29yKGRhdGFDb250YWluZXIpO1xuICAgIGNvbnN0IHtkYXRhLCB0cmlnZ2VyQ2hhbmdlZH0gPSB0aGlzLnVwZGF0ZURhdGEoZGF0YXNldHMsIG9sZExheWVyRGF0YSk7XG4gICAgY29uc3QgYWNjZXNzb3JzID0gdGhpcy5nZXRBdHRyaWJ1dGVBY2Nlc3NvcnMoe2RhdGFDb250YWluZXJ9KTtcbiAgICBjb25zdCB7dGV4dExhYmVsfSA9IHRoaXMuY29uZmlnO1xuXG4gICAgLy8gZ2V0IGFsbCBkaXN0aW5jdCBjaGFyYWN0ZXJzIGluIHRoZSB0ZXh0IGxhYmVsc1xuICAgIGNvbnN0IHRleHRMYWJlbHMgPSBmb3JtYXRUZXh0TGFiZWxEYXRhKHtcbiAgICAgIHRleHRMYWJlbCxcbiAgICAgIHRyaWdnZXJDaGFuZ2VkLFxuICAgICAgb2xkTGF5ZXJEYXRhLFxuICAgICAgZGF0YSxcbiAgICAgIGRhdGFDb250YWluZXJcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBkYXRhLFxuICAgICAgZ2V0SGV4SWQsXG4gICAgICBnZXRGaWx0ZXJWYWx1ZTogZ3B1RmlsdGVyLmZpbHRlclZhbHVlQWNjZXNzb3IoZGF0YUNvbnRhaW5lcikoKSxcbiAgICAgIHRleHRMYWJlbHMsXG4gICAgICBnZXRQb3NpdGlvbjogZCA9PiBkLmNlbnRyb2lkLFxuICAgICAgLi4uYWNjZXNzb3JzXG4gICAgfTtcbiAgfVxuICAvKiBlc2xpbnQtZW5hYmxlIGNvbXBsZXhpdHkgKi9cblxuICB1cGRhdGVMYXllck1ldGEoZGF0YXNldDogS2VwbGVyVGFibGUsIGdldEhleElkKSB7XG4gICAgY29uc3Qge2RhdGFDb250YWluZXJ9ID0gZGF0YXNldDtcblxuICAgIGNvbnN0IGNlbnRyb2lkcyA9IGRhdGFDb250YWluZXIubWFwKChkLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgaWQgPSBnZXRIZXhJZCh7aW5kZXh9KTtcbiAgICAgIGlmICghaDNJc1ZhbGlkKGlkKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIHNhdmUgYSByZWZlcmVuY2Ugb2YgY2VudHJvaWRzIHRvIGRhdGFUb0ZlYXR1cmVcbiAgICAgIC8vIHNvIHdlIGRvbid0IGhhdmUgdG8gcmUgY2FsY3VsYXRlIGl0IGFnYWluXG4gICAgICByZXR1cm4gZ2V0Q2VudHJvaWQoe2lkfSk7XG4gICAgfSwgdHJ1ZSk7XG5cbiAgICBjb25zdCBjZW50cm9pZHNEYXRhQ29udGFpbmVyID0gY3JlYXRlRGF0YUNvbnRhaW5lcihjZW50cm9pZHMpO1xuXG4gICAgY29uc3QgYm91bmRzID0gdGhpcy5nZXRQb2ludHNCb3VuZHMoXG4gICAgICBjZW50cm9pZHNEYXRhQ29udGFpbmVyLFxuICAgICAgKGQ6IGFueSwgZGM6IERhdGFDb250YWluZXJJbnRlcmZhY2UpID0+IHtcbiAgICAgICAgcmV0dXJuIFtkYy52YWx1ZUF0KGQuaW5kZXgsIDApLCBkYy52YWx1ZUF0KGQuaW5kZXgsIDEpXTtcbiAgICAgIH1cbiAgICApO1xuICAgIHRoaXMuZGF0YVRvRmVhdHVyZSA9IHtjZW50cm9pZHN9O1xuICAgIHRoaXMudXBkYXRlTWV0YSh7Ym91bmRzfSk7XG4gIH1cblxuICByZW5kZXJMYXllcihvcHRzKSB7XG4gICAgY29uc3Qge2RhdGEsIGdwdUZpbHRlciwgb2JqZWN0SG92ZXJlZCwgbWFwU3RhdGUsIGludGVyYWN0aW9uQ29uZmlnfSA9IG9wdHM7XG5cbiAgICBjb25zdCB6b29tRmFjdG9yID0gdGhpcy5nZXRab29tRmFjdG9yKG1hcFN0YXRlKTtcbiAgICBjb25zdCBlbGVab29tRmFjdG9yID0gdGhpcy5nZXRFbGV2YXRpb25ab29tRmFjdG9yKG1hcFN0YXRlKTtcbiAgICBjb25zdCB7Y29uZmlnfSA9IHRoaXM7XG4gICAgY29uc3Qge3Zpc0NvbmZpZ30gPSBjb25maWc7XG4gICAgY29uc3QgdXBkYXRlVHJpZ2dlcnMgPSB0aGlzLmdldFZpc3VhbENoYW5uZWxVcGRhdGVUcmlnZ2VycygpO1xuXG4gICAgY29uc3QgaDNIZXhhZ29uTGF5ZXJUcmlnZ2VycyA9IHtcbiAgICAgIGdldEhleGFnb246IHRoaXMuY29uZmlnLmNvbHVtbnMsXG4gICAgICBnZXRGaWxsQ29sb3I6IHVwZGF0ZVRyaWdnZXJzLmdldEZpbGxDb2xvcixcbiAgICAgIGdldExpbmVDb2xvcjogdXBkYXRlVHJpZ2dlcnMuZ2V0TGluZUNvbG9yLFxuICAgICAgZ2V0RWxldmF0aW9uOiB1cGRhdGVUcmlnZ2Vycy5nZXRFbGV2YXRpb24sXG4gICAgICBnZXRGaWx0ZXJWYWx1ZTogZ3B1RmlsdGVyLmZpbHRlclZhbHVlVXBkYXRlVHJpZ2dlcnNcbiAgICB9O1xuXG4gICAgY29uc3QgY29sdW1uTGF5ZXJUcmlnZ2VycyA9IHtcbiAgICAgIGdldENvdmVyYWdlOiB1cGRhdGVUcmlnZ2Vycy5nZXRDb3ZlcmFnZVxuICAgIH07XG5cbiAgICBjb25zdCBkZWZhdWx0TGF5ZXJQcm9wcyA9IHRoaXMuZ2V0RGVmYXVsdERlY2tMYXllclByb3BzKG9wdHMpO1xuICAgIGNvbnN0IGhvdmVyZWRPYmplY3QgPSB0aGlzLmhhc0hvdmVyZWRPYmplY3Qob2JqZWN0SG92ZXJlZCk7XG5cbiAgICAvLyBnZXRQaXhlbE9mZnNldCB3aXRoIG5vIHJhZGl1c1xuICAgIGNvbnN0IHJhZGl1c1NjYWxlID0gMS4wO1xuICAgIGNvbnN0IGdldFJhaWR1cyA9IG51bGw7XG4gICAgY29uc3QgZ2V0UGl4ZWxPZmZzZXQgPSBnZXRUZXh0T2Zmc2V0QnlSYWRpdXMocmFkaXVzU2NhbGUsIGdldFJhaWR1cywgbWFwU3RhdGUpO1xuXG4gICAgY29uc3QgYnJ1c2hpbmdQcm9wcyA9IHRoaXMuZ2V0QnJ1c2hpbmdFeHRlbnNpb25Qcm9wcyhpbnRlcmFjdGlvbkNvbmZpZyk7XG4gICAgY29uc3QgZXh0ZW5zaW9ucyA9IFsuLi5kZWZhdWx0TGF5ZXJQcm9wcy5leHRlbnNpb25zLCBicnVzaGluZ0V4dGVuc2lvbl07XG4gICAgY29uc3Qgc2hhcmVkUHJvcHMgPSB7XG4gICAgICBnZXRGaWx0ZXJWYWx1ZTogZGF0YS5nZXRGaWx0ZXJWYWx1ZSxcbiAgICAgIGV4dGVuc2lvbnMsXG4gICAgICBmaWx0ZXJSYW5nZTogZGVmYXVsdExheWVyUHJvcHMuZmlsdGVyUmFuZ2UsXG4gICAgICB2aXNpYmxlOiBkZWZhdWx0TGF5ZXJQcm9wcy52aXNpYmxlLFxuICAgICAgLi4uYnJ1c2hpbmdQcm9wc1xuICAgIH07XG5cbiAgICByZXR1cm4gW1xuICAgICAgbmV3IEgzSGV4YWdvbkxheWVyKHtcbiAgICAgICAgLi4uZGVmYXVsdExheWVyUHJvcHMsXG4gICAgICAgIC4uLmRhdGEsXG4gICAgICAgIC4uLmJydXNoaW5nUHJvcHMsXG4gICAgICAgIGV4dGVuc2lvbnMsXG4gICAgICAgIHdyYXBMb25naXR1ZGU6IGZhbHNlLFxuXG4gICAgICAgIGZpbGxlZDogdmlzQ29uZmlnLmZpbGxlZCxcbiAgICAgICAgc3Ryb2tlZDogdmlzQ29uZmlnLm91dGxpbmUsXG4gICAgICAgIGxpbmVXaWR0aFNjYWxlOiB2aXNDb25maWcudGhpY2tuZXNzLFxuXG4gICAgICAgIGdldEhleGFnb246ICh4OiBhbnkpID0+IHguaWQsXG5cbiAgICAgICAgLy8gY292ZXJhZ2VcbiAgICAgICAgY292ZXJhZ2U6IGNvbmZpZy5jb3ZlcmFnZUZpZWxkID8gMSA6IHZpc0NvbmZpZy5jb3ZlcmFnZSxcblxuICAgICAgICAvLyBoaWdobGlnaHRcbiAgICAgICAgYXV0b0hpZ2hsaWdodDogdmlzQ29uZmlnLmVuYWJsZTNkLFxuICAgICAgICBoaWdobGlnaHRDb2xvcjogSElHSExJR0hfQ09MT1JfM0QsXG5cbiAgICAgICAgLy8gZWxldmF0aW9uXG4gICAgICAgIGV4dHJ1ZGVkOiB2aXNDb25maWcuZW5hYmxlM2QsXG4gICAgICAgIGVsZXZhdGlvblNjYWxlOiB2aXNDb25maWcuZWxldmF0aW9uU2NhbGUgKiBlbGVab29tRmFjdG9yLFxuXG4gICAgICAgIC8vIHJlbmRlclxuICAgICAgICB1cGRhdGVUcmlnZ2VyczogaDNIZXhhZ29uTGF5ZXJUcmlnZ2VycyxcbiAgICAgICAgX3N1YkxheWVyUHJvcHM6IHtcbiAgICAgICAgICAnaGV4YWdvbi1jZWxsJzoge1xuICAgICAgICAgICAgdHlwZTogRW5oYW5jZWRDb2x1bW5MYXllcixcbiAgICAgICAgICAgIGdldENvdmVyYWdlOiBkYXRhLmdldENvdmVyYWdlLFxuICAgICAgICAgICAgdXBkYXRlVHJpZ2dlcnM6IGNvbHVtbkxheWVyVHJpZ2dlcnMsXG4gICAgICAgICAgICBzdHJva2VPcGFjaXR5OiB2aXNDb25maWcuc3Ryb2tlT3BhY2l0eVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgICAvLyBob3ZlciBsYXllclxuICAgICAgLi4uKGhvdmVyZWRPYmplY3QgJiYgIWNvbmZpZy5zaXplRmllbGRcbiAgICAgICAgPyBbXG4gICAgICAgICAgICBuZXcgR2VvSnNvbkxheWVyKHtcbiAgICAgICAgICAgICAgLi4udGhpcy5nZXREZWZhdWx0SG92ZXJMYXllclByb3BzKCksXG4gICAgICAgICAgICAgIHZpc2libGU6IGRlZmF1bHRMYXllclByb3BzLnZpc2libGUsXG4gICAgICAgICAgICAgIGRhdGE6IFtpZFRvUG9seWdvbkdlbyhob3ZlcmVkT2JqZWN0KV0sXG4gICAgICAgICAgICAgIGdldExpbmVDb2xvcjogY29uZmlnLmhpZ2hsaWdodENvbG9yLFxuICAgICAgICAgICAgICBsaW5lV2lkdGhTY2FsZTogREVGQVVMVF9MSU5FX1NDQUxFX1ZBTFVFICogem9vbUZhY3RvcixcbiAgICAgICAgICAgICAgd3JhcExvbmdpdHVkZTogZmFsc2VcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgXVxuICAgICAgICA6IFtdKSxcbiAgICAgIC8vIHRleHQgbGFiZWwgbGF5ZXJcbiAgICAgIC4uLnRoaXMucmVuZGVyVGV4dExhYmVsTGF5ZXIoXG4gICAgICAgIHtcbiAgICAgICAgICBnZXRQb3NpdGlvbjogZGF0YS5nZXRQb3NpdGlvbixcbiAgICAgICAgICBzaGFyZWRQcm9wcyxcbiAgICAgICAgICBnZXRQaXhlbE9mZnNldCxcbiAgICAgICAgICB1cGRhdGVUcmlnZ2Vyc1xuICAgICAgICB9LFxuICAgICAgICBvcHRzXG4gICAgICApXG4gICAgXTtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFHQSxJQUFBQSxVQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFPQSxJQUFBQyxXQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxPQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxVQUFBLEdBQUFILE9BQUE7QUFDQSxJQUFBSSxhQUFBLEdBQUFKLE9BQUE7QUFDQSxJQUFBSyxZQUFBLEdBQUFMLE9BQUE7QUFPQSxJQUFBTSxNQUFBLEdBQUFOLE9BQUE7QUFDQSxJQUFBTyxtQkFBQSxHQUFBUixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQVEsVUFBQSxHQUFBUixPQUFBO0FBbUJBLElBQUFTLGVBQUEsR0FBQVQsT0FBQTtBQUErRSxTQUFBVSxXQUFBQyxDQUFBLEVBQUFDLENBQUEsRUFBQUMsQ0FBQSxX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