kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
415 lines (410 loc) • 56.8 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.hexIdRequiredColumns = exports.hexIdExAccessor = 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);
};
};
};
/** Accessor that tries to convert h3 indicies in decimal form to hex form */
var hexIdExAccessor = exports.hexIdExAccessor = function hexIdExAccessor(_ref2) {
var hex_id = _ref2.hex_id;
return function (dc) {
return function (d) {
var value = dc.valueAt(d.index, hex_id.fieldIdx);
if ((0, _commonUtils.h3IsValid)(value)) {
return value;
}
try {
return BigInt(value).toString(16);
} catch (_unused) {
return null;
}
};
};
};
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, dataset) {
var fieldType = dataset === null || dataset === void 0 ? void 0 : dataset.fields[_this.config.columns.hex_id.fieldIdx].type;
return fieldType === _constants.ALL_FIELD_TYPES.h3 ? hexIdAccessor(_this.config.columns)(dataContainer) : hexIdExAccessor(_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(_ref3, getHexId) {
var filteredIndex = _ref3.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 dataset = datasets[this.config.dataId];
var gpuFilter = dataset.gpuFilter,
dataContainer = dataset.dataContainer;
var getHexId = this.getPositionAccessor(dataContainer, dataset);
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(_ref4) {
var _ref4$fields = _ref4.fields,
fields = _ref4$fields === void 0 ? [] : _ref4$fields,
dataContainer = _ref4.dataContainer,
label = _ref4.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,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfYmFzZUxheWVyIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfZXh0ZW5zaW9ucyIsIl9sYXllcnMiLCJfZ2VvTGF5ZXJzIiwiX2RlY2tnbExheWVycyIsIl9jb21tb25VdGlscyIsIl91dGlscyIsIl9oM0hleGFnb25MYXllckljb24iLCJfY29uc3RhbnRzIiwiX2xheWVyVGV4dExhYmVsIiwiX2NhbGxTdXBlciIsInQiLCJvIiwiZSIsIl9nZXRQcm90b3R5cGVPZjIiLCJfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjIiLCJfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0IiwiUmVmbGVjdCIsImNvbnN0cnVjdCIsImNvbnN0cnVjdG9yIiwiYXBwbHkiLCJCb29sZWFuIiwicHJvdG90eXBlIiwidmFsdWVPZiIsImNhbGwiLCJfc3VwZXJQcm9wR2V0IiwiciIsInAiLCJfZ2V0MiIsIm93bktleXMiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwiZmlsdGVyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwiZW51bWVyYWJsZSIsInB1c2giLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiREVGQVVMVF9MSU5FX1NDQUxFX1ZBTFVFIiwiaGV4SWRSZXF1aXJlZENvbHVtbnMiLCJleHBvcnRzIiwiaGV4SWRBY2Nlc3NvciIsIl9yZWYiLCJoZXhfaWQiLCJkYyIsImQiLCJ2YWx1ZUF0IiwiaW5kZXgiLCJmaWVsZElkeCIsImhleElkRXhBY2Nlc3NvciIsIl9yZWYyIiwidmFsdWUiLCJoM0lzVmFsaWQiLCJCaWdJbnQiLCJ0b1N0cmluZyIsIl91bnVzZWQiLCJkZWZhdWx0RWxldmF0aW9uIiwiZGVmYXVsdENvdmVyYWdlIiwiSGV4YWdvbklkVmlzQ29uZmlncyIsImNvbG9yUmFuZ2UiLCJmaWxsZWQiLCJMQVlFUl9WSVNfQ09ORklHUyIsImRlZmF1bHRWYWx1ZSIsIm9wYWNpdHkiLCJsYWJlbCIsInJhbmdlIiwicHJvcGVydHkiLCJvdXRsaW5lIiwic3Ryb2tlQ29sb3IiLCJzdHJva2VDb2xvclJhbmdlIiwic3Ryb2tlT3BhY2l0eSIsInRoaWNrbmVzcyIsImNvdmVyYWdlIiwiZW5hYmxlM2QiLCJzaXplUmFuZ2UiLCJjb3ZlcmFnZVJhbmdlIiwiZWxldmF0aW9uU2NhbGUiLCJlbmFibGVFbGV2YXRpb25ab29tRmFjdG9yIiwiZml4ZWRIZWlnaHQiLCJicnVzaGluZ0V4dGVuc2lvbiIsIkJydXNoaW5nRXh0ZW5zaW9uIiwiSGV4YWdvbklkTGF5ZXIiLCJfTGF5ZXIiLCJwcm9wcyIsIl90aGlzIiwiX2NsYXNzQ2FsbENoZWNrMiIsImRhdGFUb0ZlYXR1cmUiLCJjZW50cm9pZHMiLCJyZWdpc3RlclZpc0NvbmZpZyIsImdldFBvc2l0aW9uQWNjZXNzb3IiLCJkYXRhQ29udGFpbmVyIiwiZGF0YXNldCIsImZpZWxkVHlwZSIsImZpZWxkcyIsImNvbmZpZyIsImNvbHVtbnMiLCJ0eXBlIiwiQUxMX0ZJRUxEX1RZUEVTIiwiaDMiLCJfaW5oZXJpdHMyIiwiX2NyZWF0ZUNsYXNzMiIsImtleSIsImdldCIsIkgzSGV4YWdvbkxheWVySWNvbiIsInZpc3VhbENoYW5uZWxzIiwiY29sb3IiLCJhY2Nlc3NvciIsImNvbmRpdGlvbiIsInZpc0NvbmZpZyIsImZpZWxkIiwic2NhbGUiLCJkb21haW4iLCJjaGFubmVsU2NhbGVUeXBlIiwiQ0hBTk5FTF9TQ0FMRVMiLCJzaXplIiwibnVsbFZhbHVlIiwicmFkaXVzIiwic2V0SW5pdGlhbExheWVyQ29uZmlnIiwibnVtUm93cyIsImRlZmF1bHRDb2xvckZpZWxkIiwiZmluZERlZmF1bHRDb2xvckZpZWxkIiwidXBkYXRlTGF5ZXJDb25maWciLCJjb2xvckZpZWxkIiwidXBkYXRlTGF5ZXJWaXN1YWxDaGFubmVsIiwiZ2V0RGVmYXVsdExheWVyQ29uZmlnIiwiZGVmYXVsdExheWVyQ29uZmlnIiwic3Ryb2tlQ29sb3JGaWVsZCIsInN0cm9rZUNvbG9yRG9tYWluIiwic3Ryb2tlQ29sb3JTY2FsZSIsImNvbG9yVUkiLCJERUZBVUxUX0NPTE9SX1VJIiwiY292ZXJhZ2VGaWVsZCIsImNvdmVyYWdlRG9tYWluIiwiY292ZXJhZ2VTY2FsZSIsInRleHRMYWJlbCIsIkRFRkFVTFRfVEVYVF9MQUJFTCIsImFuY2hvciIsImNhbGN1bGF0ZURhdGFBdHRyaWJ1dGUiLCJfcmVmMyIsImdldEhleElkIiwiZmlsdGVyZWRJbmRleCIsImRhdGEiLCJpIiwiaWQiLCJjZW50cm9pZCIsImZvcm1hdExheWVyRGF0YSIsImRhdGFzZXRzIiwib2xkTGF5ZXJEYXRhIiwiZGF0YUlkIiwiZ3B1RmlsdGVyIiwiX3RoaXMkdXBkYXRlRGF0YSIsInVwZGF0ZURhdGEiLCJ0cmlnZ2VyQ2hhbmdlZCIsImFjY2Vzc29ycyIsImdldEF0dHJpYnV0ZUFjY2Vzc29ycyIsInRleHRMYWJlbHMiLCJmb3JtYXRUZXh0TGFiZWxEYXRhIiwiZ2V0RmlsdGVyVmFsdWUiLCJmaWx0ZXJWYWx1ZUFjY2Vzc29yIiwiZ2V0UG9zaXRpb24iLCJ1cGRhdGVMYXllck1ldGEiLCJtYXAiLCJnZXRDZW50cm9pZCIsImNlbnRyb2lkc0RhdGFDb250YWluZXIiLCJjcmVhdGVEYXRhQ29udGFpbmVyIiwiYm91bmRzIiwiZ2V0UG9pbnRzQm91bmRzIiwidXBkYXRlTWV0YSIsInJlbmRlckxheWVyIiwib3B0cyIsIm9iamVjdEhvdmVyZWQiLCJtYXBTdGF0ZSIsImludGVyYWN0aW9uQ29uZmlnIiwiem9vbUZhY3RvciIsImdldFpvb21GYWN0b3IiLCJlbGVab29tRmFjdG9yIiwiZ2V0RWxldmF0aW9uWm9vbUZhY3RvciIsInVwZGF0ZVRyaWdnZXJzIiwiZ2V0VmlzdWFsQ2hhbm5lbFVwZGF0ZVRyaWdnZXJzIiwiaDNIZXhhZ29uTGF5ZXJUcmlnZ2VycyIsImdldEhleGFnb24iLCJnZXRGaWxsQ29sb3IiLCJnZXRMaW5lQ29sb3IiLCJnZXRFbGV2YXRpb24iLCJmaWx0ZXJWYWx1ZVVwZGF0ZVRyaWdnZXJzIiwiY29sdW1uTGF5ZXJUcmlnZ2VycyIsImdldENvdmVyYWdlIiwiZGVmYXVsdExheWVyUHJvcHMiLCJnZXREZWZhdWx0RGVja0xheWVyUHJvcHMiLCJob3ZlcmVkT2JqZWN0IiwiaGFzSG92ZXJlZE9iamVjdCIsInJhZGl1c1NjYWxlIiwiZ2V0UmFpZHVzIiwiZ2V0UGl4ZWxPZmZzZXQiLCJnZXRUZXh0T2Zmc2V0QnlSYWRpdXMiLCJicnVzaGluZ1Byb3BzIiwiZ2V0QnJ1c2hpbmdFeHRlbnNpb25Qcm9wcyIsImV4dGVuc2lvbnMiLCJjb25jYXQiLCJfdG9Db25zdW1hYmxlQXJyYXkyIiwic2hhcmVkUHJvcHMiLCJmaWx0ZXJSYW5nZSIsInZpc2libGUiLCJIM0hleGFnb25MYXllciIsIndyYXBMb25naXR1ZGUiLCJzdHJva2VkIiwibGluZVdpZHRoU2NhbGUiLCJ4IiwiYXV0b0hpZ2hsaWdodCIsImhpZ2hsaWdodENvbG9yIiwiSElHSExJR0hfQ09MT1JfM0QiLCJleHRydWRlZCIsIl9zdWJMYXllclByb3BzIiwiRW5oYW5jZWRDb2x1bW5MYXllciIsInNpemVGaWVsZCIsIkdlb0pzb25MYXllciIsImdldERlZmF1bHRIb3ZlckxheWVyUHJvcHMiLCJpZFRvUG9seWdvbkdlbyIsInJlbmRlclRleHRMYWJlbExheWVyIiwiZmluZERlZmF1bHRMYXllclByb3BzIiwiX3JlZjQiLCJfcmVmNCRmaWVsZHMiLCJoZXhGaWVsZHMiLCJnZXRIZXhGaWVsZHMiLCJmIiwiaXNWaXNpYmxlIiwibmFtZSIsImZpbmRJbmRleCIsImZpZCIsIkxheWVyIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2gzLWhleGFnb24tbGF5ZXIvaDMtaGV4YWdvbi1sYXllci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQgTGF5ZXIsIHtcbiAgTGF5ZXJCYXNlQ29uZmlnLFxuICBMYXllckJhc2VDb25maWdQYXJ0aWFsLFxuICBMYXllckNvbG9yQ29uZmlnLFxuICBMYXllckNvdmVyYWdlQ29uZmlnLFxuICBMYXllclNpemVDb25maWdcbn0gZnJvbSAnLi4vYmFzZS1sYXllcic7XG5pbXBvcnQge0JydXNoaW5nRXh0ZW5zaW9ufSBmcm9tICdAZGVjay5nbC9leHRlbnNpb25zJztcbmltcG9ydCB7R2VvSnNvbkxheWVyfSBmcm9tICdAZGVjay5nbC9sYXllcnMnO1xuaW1wb3J0IHtIM0hleGFnb25MYXllcn0gZnJvbSAnQGRlY2suZ2wvZ2VvLWxheWVycyc7XG5pbXBvcnQge0VuaGFuY2VkQ29sdW1uTGF5ZXJ9IGZyb20gJ0BrZXBsZXIuZ2wvZGVja2dsLWxheWVycyc7XG5pbXBvcnQge1xuICBnZXRDZW50cm9pZCxcbiAgaWRUb1BvbHlnb25HZW8sXG4gIGgzSXNWYWxpZCxcbiAgZ2V0SGV4RmllbGRzLFxuICBDZW50cm9pZFxufSBmcm9tICdAa2VwbGVyLmdsL2NvbW1vbi11dGlscyc7XG5pbXBvcnQge2ZpbmREZWZhdWx0Q29sb3JGaWVsZCwgRGF0YUNvbnRhaW5lckludGVyZmFjZSwgY3JlYXRlRGF0YUNvbnRhaW5lcn0gZnJvbSAnQGtlcGxlci5nbC91dGlscyc7XG5pbXBvcnQgSDNIZXhhZ29uTGF5ZXJJY29uIGZyb20gJy4vaDMtaGV4YWdvbi1sYXllci1pY29uJztcbmltcG9ydCB7XG4gIEFMTF9GSUVMRF9UWVBFUyxcbiAgQ0hBTk5FTF9TQ0FMRVMsXG4gIEhJR0hMSUdIX0NPTE9SXzNELFxuICBERUZBVUxUX0NPTE9SX1VJLFxuICBERUZBVUxUX1RFWFRfTEFCRUwsXG4gIExBWUVSX1ZJU19DT05GSUdTXG59IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcblxuaW1wb3J0IHtcbiAgQ29sb3JSYW5nZSxcbiAgVmlzQ29uZmlnQm9vbGVhbixcbiAgVmlzQ29uZmlnQ29sb3JSYW5nZSxcbiAgVmlzQ29uZmlnTnVtYmVyLFxuICBWaXNDb25maWdSYW5nZSxcbiAgTWVyZ2UsXG4gIExheWVyQ29sdW1uXG59IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuaW1wb3J0IHtEYXRhc2V0cywgS2VwbGVyVGFibGV9IGZyb20gJ0BrZXBsZXIuZ2wvdGFibGUnO1xuXG5pbXBvcnQge2dldFRleHRPZmZzZXRCeVJhZGl1cywgZm9ybWF0VGV4dExhYmVsRGF0YX0gZnJvbSAnLi4vbGF5ZXItdGV4dC1sYWJlbCc7XG5cbmV4cG9ydCB0eXBlIEhleGFnb25JZExheWVyQ29sdW1uc0NvbmZpZyA9IHtcbiAgaGV4X2lkOiBMYXllckNvbHVtbjtcbn07XG5cbmV4cG9ydCB0eXBlIEhleGFnb25JZExheWVyVmlzQ29uZmlnU2V0dGluZ3MgPSB7XG4gIG9wYWNpdHk6IFZpc0NvbmZpZ051bWJlcjtcbiAgc3Ryb2tlT3BhY2l0eTogVmlzQ29uZmlnTnVtYmVyO1xuICBjb2xvclJhbmdlOiBWaXNDb25maWdDb2xvclJhbmdlO1xuICBjb3ZlcmFnZTogVmlzQ29uZmlnTnVtYmVyO1xuICBlbmFibGUzZDogVmlzQ29uZmlnQm9vbGVhbjtcbiAgc2l6ZVJhbmdlOiBWaXNDb25maWdSYW5nZTtcbiAgY292ZXJhZ2VSYW5nZTogVmlzQ29uZmlnUmFuZ2U7XG4gIGVsZXZhdGlvblNjYWxlOiBWaXNDb25maWdOdW1iZXI7XG4gIGVuYWJsZUVsZXZhdGlvblpvb21GYWN0b3I6IFZpc0NvbmZpZ0Jvb2xlYW47XG4gIGZpbGxlZDogVmlzQ29uZmlnQm9vbGVhbjtcbiAgb3V0bGluZTogVmlzQ29uZmlnQm9vbGVhbjtcbiAgdGhpY2tuZXNzOiBWaXNDb25maWdOdW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBIZXhhZ29uSWRMYXllclZpc0NvbmZpZyA9IHtcbiAgb3BhY2l0eTogbnVtYmVyO1xuICBzdHJva2VPcGFjaXR5OiBudW1iZXI7XG4gIGNvbG9yUmFuZ2U6IENvbG9yUmFuZ2U7XG4gIGNvdmVyYWdlOiBudW1iZXI7XG4gIGVuYWJsZTNkOiBib29sZWFuO1xuICBzaXplUmFuZ2U6IFtudW1iZXIsIG51bWJlcl07XG4gIGNvdmVyYWdlUmFuZ2U6IFtudW1iZXIsIG51bWJlcl07XG4gIGVsZXZhdGlvblNjYWxlOiBudW1iZXI7XG4gIGVuYWJsZUVsZXZhdGlvblpvb21GYWN0b3I6IGJvb2xlYW47XG4gIGZpbGxlZDogYm9vbGVhbjtcbiAgb3V0bGluZTogYm9vbGVhbjtcbiAgdGhpY2tuZXNzOiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBIZXhhZ29uSWRMYXllclZpc3VhbENoYW5uZWxDb25maWcgPSBMYXllckNvbG9yQ29uZmlnICZcbiAgTGF5ZXJTaXplQ29uZmlnICZcbiAgTGF5ZXJDb3ZlcmFnZUNvbmZpZztcbmV4cG9ydCB0eXBlIEhleGFnb25JZExheWVyQ29uZmlnID0gTWVyZ2U8XG4gIExheWVyQmFzZUNvbmZpZyxcbiAge2NvbHVtbnM6IEhleGFnb25JZExheWVyQ29sdW1uc0NvbmZpZzsgdmlzQ29uZmlnOiBIZXhhZ29uSWRMYXllclZpc0NvbmZpZ31cbj4gJlxuICBIZXhhZ29uSWRMYXllclZpc3VhbENoYW5uZWxDb25maWc7XG5cbmV4cG9ydCB0eXBlIEhleGFnb25JZExheWVyRGF0YSA9IHtpbmRleDogbnVtYmVyOyBpZDsgY2VudHJvaWQ6IENlbnRyb2lkfTtcblxuY29uc3QgREVGQVVMVF9MSU5FX1NDQUxFX1ZBTFVFID0gODtcblxuZXhwb3J0IGNvbnN0IGhleElkUmVxdWlyZWRDb2x1bW5zOiBbJ2hleF9pZCddID0gWydoZXhfaWQnXTtcbmV4cG9ydCBjb25zdCBoZXhJZEFjY2Vzc29yID1cbiAgKHtoZXhfaWR9OiBIZXhhZ29uSWRMYXllckNvbHVtbnNDb25maWcpID0+XG4gIChkYzogRGF0YUNvbnRhaW5lckludGVyZmFjZSkgPT5cbiAgZCA9PlxuICAgIGRjLnZhbHVlQXQoZC5pbmRleCwgaGV4X2lkLmZpZWxkSWR4KTtcblxuLyoqIEFjY2Vzc29yIHRoYXQgdHJpZXMgdG8gY29udmVydCBoMyBpbmRpY2llcyBpbiBkZWNpbWFsIGZvcm0gdG8gaGV4IGZvcm0gKi9cbmV4cG9ydCBjb25zdCBoZXhJZEV4QWNjZXNzb3IgPVxuICAoe2hleF9pZH06IEhleGFnb25JZExheWVyQ29sdW1uc0NvbmZpZykgPT5cbiAgKGRjOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlKSA9PlxuICBkID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IGRjLnZhbHVlQXQoZC5pbmRleCwgaGV4X2lkLmZpZWxkSWR4KTtcbiAgICBpZiAoaDNJc1ZhbGlkKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEJpZ0ludCh2YWx1ZSkudG9TdHJpbmcoMTYpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9O1xuXG5leHBvcnQgY29uc3QgZGVmYXVsdEVsZXZhdGlvbiA9IDUwMDtcbmV4cG9ydCBjb25zdCBkZWZhdWx0Q292ZXJhZ2UgPSAxO1xuXG5leHBvcnQgY29uc3QgSGV4YWdvbklkVmlzQ29uZmlnczoge1xuICBvcGFjaXR5OiBWaXNDb25maWdOdW1iZXI7XG4gIHN0cm9rZU9wYWNpdHk6IFZpc0NvbmZpZ051bWJlcjtcbiAgY29sb3JSYW5nZTogJ2NvbG9yUmFuZ2UnO1xuICBmaWxsZWQ6IFZpc0NvbmZpZ0Jvb2xlYW47XG4gIG91dGxpbmU6ICdvdXRsaW5lJztcbiAgc3Ryb2tlQ29sb3I6ICdzdHJva2VDb2xvcic7XG4gIHN0cm9rZUNvbG9yUmFuZ2U6ICdzdHJva2VDb2xvclJhbmdlJztcbiAgdGhpY2tuZXNzOiAndGhpY2tuZXNzJztcbiAgY292ZXJhZ2U6ICdjb3ZlcmFnZSc7XG4gIGVuYWJsZTNkOiAnZW5hYmxlM2QnO1xuICBzaXplUmFuZ2U6ICdlbGV2YXRpb25SYW5nZSc7XG4gIGNvdmVyYWdlUmFuZ2U6ICdjb3ZlcmFnZVJhbmdlJztcbiAgZWxldmF0aW9uU2NhbGU6ICdlbGV2YXRpb25TY2FsZSc7XG4gIGVuYWJsZUVsZXZhdGlvblpvb21GYWN0b3I6ICdlbmFibGVFbGV2YXRpb25ab29tRmFjdG9yJztcbiAgZml4ZWRIZWlnaHQ6ICdmaXhlZEhlaWdodCc7XG59ID0ge1xuICBjb2xvclJhbmdlOiAnY29sb3JSYW5nZScsXG4gIGZpbGxlZDoge1xuICAgIC4uLkxBWUVSX1ZJU19DT05GSUdTLmZpbGxlZCxcbiAgICBkZWZhdWx0VmFsdWU6IHRydWVcbiAgfSxcbiAgb3BhY2l0eToge1xuICAgIC4uLkxBWUVSX1ZJU19DT05GSUdTLm9wYWNpdHksXG4gICAgbGFiZWw6ICdGaWxsIE9wYWNpdHknLFxuICAgIHJhbmdlOiBbMCwgMV0sXG4gICAgcHJvcGVydHk6ICdvcGFjaXR5J1xuICB9LFxuICBvdXRsaW5lOiAnb3V0bGluZScsXG4gIHN0cm9rZUNvbG9yOiAnc3Ryb2tlQ29sb3InLFxuICBzdHJva2VDb2xvclJhbmdlOiAnc3Ryb2tlQ29sb3JSYW5nZScsXG4gIHN0cm9rZU9wYWNpdHk6IHtcbiAgICAuLi5MQVlFUl9WSVNfQ09ORklHUy5vcGFjaXR5LFxuICAgIGxhYmVsOiAnU3Ryb2tlIE9wYWNpdHknLFxuICAgIHJhbmdlOiBbMCwgMV0sXG4gICAgcHJvcGVydHk6ICdzdHJva2VPcGFjaXR5J1xuICB9LFxuICB0aGlja25lc3M6ICd0aGlja25lc3MnLFxuICBjb3ZlcmFnZTogJ2NvdmVyYWdlJyxcbiAgZW5hYmxlM2Q6ICdlbmFibGUzZCcsXG4gIHNpemVSYW5nZTogJ2VsZXZhdGlvblJhbmdlJyxcbiAgY292ZXJhZ2VSYW5nZTogJ2NvdmVyYWdlUmFuZ2UnLFxuICBlbGV2YXRpb25TY2FsZTogJ2VsZXZhdGlvblNjYWxlJyxcbiAgZW5hYmxlRWxldmF0aW9uWm9vbUZhY3RvcjogJ2VuYWJsZUVsZXZhdGlvblpvb21GYWN0b3InLFxuICBmaXhlZEhlaWdodDogJ2ZpeGVkSGVpZ2h0J1xufTtcblxuY29uc3QgYnJ1c2hpbmdFeHRlbnNpb24gPSBuZXcgQnJ1c2hpbmdFeHRlbnNpb24oKTtcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEhleGFnb25JZExheWVyIGV4dGVuZHMgTGF5ZXIge1xuICBkYXRhVG9GZWF0dXJlOiB7Y2VudHJvaWRzOiBDZW50cm9pZFtdfTtcblxuICBkZWNsYXJlIGNvbmZpZzogSGV4YWdvbklkTGF5ZXJDb25maWc7XG4gIGRlY2xhcmUgdmlzQ29uZmlnU2V0dGluZ3M6IEhleGFnb25JZExheWVyVmlzQ29uZmlnU2V0dGluZ3M7XG4gIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICAgIHRoaXMuZGF0YVRvRmVhdHVyZSA9IHtjZW50cm9pZHM6IFtdfTtcbiAgICB0aGlzLnJlZ2lzdGVyVmlzQ29uZmlnKEhleGFnb25JZFZpc0NvbmZpZ3MpO1xuICAgIHRoaXMuZ2V0UG9zaXRpb25BY2Nlc3NvciA9IChkYXRhQ29udGFpbmVyOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlLCBkYXRhc2V0PzogS2VwbGVyVGFibGUpID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkVHlwZSA9IGRhdGFzZXQ/LmZpZWxkc1t0aGlzLmNvbmZpZy5jb2x1bW5zLmhleF9pZC5maWVsZElkeF0udHlwZTtcbiAgICAgIHJldHVybiBmaWVsZFR5cGUgPT09IEFMTF9GSUVMRF9UWVBFUy5oM1xuICAgICAgICA/IGhleElkQWNjZXNzb3IodGhpcy5jb25maWcuY29sdW1ucykoZGF0YUNvbnRhaW5lcilcbiAgICAgICAgOiBoZXhJZEV4QWNjZXNzb3IodGhpcy5jb25maWcuY29sdW1ucykoZGF0YUNvbnRhaW5lcik7XG4gICAgfTtcbiAgfVxuXG4gIGdldCB0eXBlKCk6ICdoZXhhZ29uSWQnIHtcbiAgICByZXR1cm4gJ2hleGFnb25JZCc7XG4gIH1cblxuICBnZXQgbmFtZSgpOiAnSDMnIHtcbiAgICByZXR1cm4gJ0gzJztcbiAgfVxuXG4gIGdldCByZXF1aXJlZExheWVyQ29sdW1ucygpIHtcbiAgICByZXR1cm4gaGV4SWRSZXF1aXJlZENvbHVtbnM7XG4gIH1cblxuICBnZXQgbGF5ZXJJY29uKCkge1xuICAgIC8vIHVzZSBoZXhhZ29uIGxheWVyIGljb24gZm9yIG5vd1xuICAgIHJldHVybiBIM0hleGFnb25MYXllckljb247XG4gIH1cblxuICBnZXQgdmlzdWFsQ2hhbm5lbHMoKSB7XG4gICAgY29uc3QgdmlzdWFsQ2hhbm5lbHMgPSBzdXBlci52aXN1YWxDaGFubmVscztcbiAgICByZXR1cm4ge1xuICAgICAgY29sb3I6IHtcbiAgICAgICAgLi4udmlzdWFsQ2hhbm5lbHMuY29sb3IsXG4gICAgICAgIGFjY2Vzc29yOiAnZ2V0RmlsbENvbG9yJyxcbiAgICAgICAgY29uZGl0aW9uOiBjb25maWcgPT4gY29uZmlnLnZpc0NvbmZpZy5maWxsZWRcbiAgICAgIH0sXG4gICAgICBzdHJva2VDb2xvcjoge1xuICAgICAgICBwcm9wZXJ0eTogJ3N0cm9rZUNvbG9yJyxcbiAgICAgICAga2V5OiAnc3Ryb2tlQ29sb3InLFxuICAgICAgICBmaWVsZDogJ3N0cm9rZUNvbG9yRmllbGQnLFxuICAgICAgICBzY2FsZTogJ3N0cm9rZUNvbG9yU2NhbGUnLFxuICAgICAgICBkb21haW46ICdzdHJva2VDb2xvckRvbWFpbicsXG4gICAgICAgIHJhbmdlOiAnc3Ryb2tlQ29sb3JSYW5nZScsXG4gICAgICAgIGNoYW5uZWxTY2FsZVR5cGU6IENIQU5ORUxfU0NBTEVTLmNvbG9yLFxuICAgICAgICBhY2Nlc3NvcjogJ2dldExpbmVDb2xvcicsXG4gICAgICAgIGNvbmRpdGlvbjogY29uZmlnID0+IGNvbmZpZy52aXNDb25maWcub3V0bGluZSxcbiAgICAgICAgZGVmYXVsdFZhbHVlOiBjb25maWcgPT4gY29uZmlnLnZpc0NvbmZpZy5zdHJva2VDb2xvciB8fCBjb25maWcuY29sb3JcbiAgICAgIH0sXG4gICAgICBzaXplOiB7XG4gICAgICAgIC4uLnZpc3VhbENoYW5uZWxzLnNpemUsXG4gICAgICAgIHByb3BlcnR5OiAnaGVpZ2h0JyxcbiAgICAgICAgYWNjZXNzb3I6ICdnZXRFbGV2YXRpb24nLFxuICAgICAgICBudWxsVmFsdWU6IDAsXG4gICAgICAgIGNvbmRpdGlvbjogY29uZmlnID0+IGNvbmZpZy52aXNDb25maWcuZW5hYmxlM2QsXG4gICAgICAgIGRlZmF1bHRWYWx1ZTogZGVmYXVsdEVsZXZhdGlvblxuICAgICAgfSxcbiAgICAgIGNvdmVyYWdlOiB7XG4gICAgICAgIHByb3BlcnR5OiAnY292ZXJhZ2UnLFxuICAgICAgICBmaWVsZDogJ2NvdmVyYWdlRmllbGQnLFxuICAgICAgICBzY2FsZTogJ2NvdmVyYWdlU2NhbGUnLFxuICAgICAgICBkb21haW46ICdjb3ZlcmFnZURvbWFpbicsXG4gICAgICAgIHJhbmdlOiAnY292ZXJhZ2VSYW5nZScsXG4gICAgICAgIGtleTogJ2NvdmVyYWdlJyxcbiAgICAgICAgY2hhbm5lbFNjYWxlVHlwZTogQ0hBTk5FTF9TQ0FMRVMucmFkaXVzLFxuICAgICAgICBhY2Nlc3NvcjogJ2dldENvdmVyYWdlJyxcbiAgICAgICAgbnVsbFZhbHVlOiAwLFxuICAgICAgICBkZWZhdWx0VmFsdWU6IGRlZmF1bHRDb3ZlcmFnZVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBzZXRJbml0aWFsTGF5ZXJDb25maWcoZGF0YXNldCkge1xuICAgIGlmICghZGF0YXNldC5kYXRhQ29udGFpbmVyLm51bVJvd3MoKSkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNvbnN0IGRlZmF1bHRDb2xvckZpZWxkID0gZmluZERlZmF1bHRDb2xvckZpZWxkKGRhdGFzZXQpO1xuXG4gICAgaWYgKGRlZmF1bHRDb2xvckZpZWxkKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxheWVyQ29uZmlnPEhleGFnb25JZExheWVyQ29uZmlnPih7XG4gICAgICAgIGNvbG9yRmllbGQ6IGRlZmF1bHRDb2xvckZpZWxkXG4gICAgICB9KTtcbiAgICAgIHRoaXMudXBkYXRlTGF5ZXJWaXN1YWxDaGFubmVsKGRhdGFzZXQsICdjb2xvcicpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RhdGljIGZpbmREZWZhdWx0TGF5ZXJQcm9wcyh7ZmllbGRzID0gW10sIGRhdGFDb250YWluZXIsIGxhYmVsfTogS2VwbGVyVGFibGUpIHtcbiAgICBjb25zdCBoZXhGaWVsZHMgPSBnZXRIZXhGaWVsZHMoZmllbGRzLCBkYXRhQ29udGFpbmVyKTtcbiAgICBpZiAoIWhleEZpZWxkcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB7cHJvcHM6IFtdfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcHJvcHM6IGhleEZpZWxkcy5tYXAoZiA9PiAoe1xuICAgICAgICBpc1Zpc2libGU6IHRydWUsXG4gICAgICAgIC8vIGRlZmF1bHQgbGF5ZXIgbmFtZSBzaG91bGQgYmUgZGF0YXNldCBuYW1lXG4gICAgICAgIGxhYmVsLFxuICAgICAgICBjb2x1bW5zOiB7XG4gICAgICAgICAgaGV4X2lkOiB7XG4gICAgICAgICAgICB2YWx1ZTogZi5uYW1lLFxuICAgICAgICAgICAgZmllbGRJZHg6IGZpZWxkcy5maW5kSW5kZXgoZmlkID0+IGZpZC5uYW1lID09PSBmLm5hbWUpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KSlcbiAgICB9O1xuICB9XG5cbiAgZ2V0RGVmYXVsdExheWVyQ29uZmlnKHByb3BzOiBMYXllckJhc2VDb25maWdQYXJ0aWFsKSB7XG4gICAgY29uc3QgZGVmYXVsdExheWVyQ29uZmlnID0gc3VwZXIuZ2V0RGVmYXVsdExheWVyQ29uZmlnKHByb3BzKTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5kZWZhdWx0TGF5ZXJDb25maWcsXG5cbiAgICAgIC8vIGFkZCBzdHJva2UgY29sb3IgdmlzdWFsIGNoYW5uZWxcbiAgICAgIHN0cm9rZUNvbG9yRmllbGQ6IG51bGwsXG4gICAgICBzdHJva2VDb2xvckRvbWFpbjogWzAsIDFdLFxuICAgICAgc3Ryb2tlQ29sb3JTY2FsZTogJ3F1YW50aWxlJyxcbiAgICAgIGNvbG9yVUk6IHtcbiAgICAgICAgLi4uZGVmYXVsdExheWVyQ29uZmlnLmNvbG9yVUksXG4gICAgICAgIHN0cm9rZUNvbG9yUmFuZ2U6IERFRkFVTFRfQ09MT1JfVUlcbiAgICAgIH0sXG5cbiAgICAgIC8vIGFkZCByYWRpdXMgdmlzdWFsIGNoYW5uZWxcbiAgICAgIGNvdmVyYWdlRmllbGQ6IG51bGwsXG4gICAgICBjb3ZlcmFnZURvbWFpbjogWzAsIDFdLFxuICAgICAgY292ZXJhZ2VTY2FsZTogJ2xpbmVhcicsXG5cbiAgICAgIC8vIG1vZGlmeSBkZWZhdWx0IHRleHRMYWJlbCBhbmNob3IgcG9zaXRpb24gdG8gYmUgYXBwcm9wcmlhdGUgZm9yIGEgaGV4YWdvbiBzaGFwZVxuICAgICAgdGV4dExhYmVsOiBbXG4gICAgICAgIHtcbiAgICAgICAgICAuLi5ERUZBVUxUX1RFWFRfTEFCRUwsXG4gICAgICAgICAgYW5jaG9yOiAnbWlkZGxlJ1xuICAgICAgICB9XG4gICAgICBdXG4gICAgfTtcbiAgfVxuXG4gIGNhbGN1bGF0ZURhdGFBdHRyaWJ1dGUoe2ZpbHRlcmVkSW5kZXh9OiBLZXBsZXJUYWJsZSwgZ2V0SGV4SWQpIHtcbiAgICBjb25zdCBkYXRhOiBIZXhhZ29uSWRMYXllckRhdGFbXSA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWx0ZXJlZEluZGV4Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpbmRleCA9IGZpbHRlcmVkSW5kZXhbaV07XG4gICAgICBjb25zdCBpZCA9IGdldEhleElkKHtpbmRleH0pO1xuICAgICAgY29uc3QgY2VudHJvaWQgPSB0aGlzLmRhdGFUb0ZlYXR1cmUuY2VudHJvaWRzW2luZGV4XTtcblxuICAgICAgaWYgKGNlbnRyb2lkKSB7XG4gICAgICAgIGRhdGEucHVzaCh7XG4gICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgaWQsXG4gICAgICAgICAgY2VudHJvaWRcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgLy8gVE9ETzogZml4IGNvbXBsZXhpdHlcbiAgLyogZXNsaW50LWRpc2FibGUgY29tcGxleGl0eSAqL1xuICBmb3JtYXRMYXllckRhdGEoZGF0YXNldHM6IERhdGFzZXRzLCBvbGRMYXllckRhdGEpIHtcbiAgICBpZiAodGhpcy5jb25maWcuZGF0YUlkID09PSBudWxsKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YXNldCA9IGRhdGFzZXRzW3RoaXMuY29uZmlnLmRhdGFJZF07XG4gICAgY29uc3Qge2dwdUZpbHRlciwgZGF0YUNvbnRhaW5lcn0gPSBkYXRhc2V0O1xuICAgIGNvbnN0IGdldEhleElkID0gdGhpcy5nZXRQb3NpdGlvbkFjY2Vzc29yKGRhdGFDb250YWluZXIsIGRhdGFzZXQpO1xuICAgIGNvbnN0IHtkYXRhLCB0cmlnZ2VyQ2hhbmdlZH0gPSB0aGlzLnVwZGF0ZURhdGEoZGF0YXNldHMsIG9sZExheWVyRGF0YSk7XG4gICAgY29uc3QgYWNjZXNzb3JzID0gdGhpcy5nZXRBdHRyaWJ1dGVBY2Nlc3NvcnMoe2RhdGFDb250YWluZXJ9KTtcbiAgICBjb25zdCB7dGV4dExhYmVsfSA9IHRoaXMuY29uZmlnO1xuXG4gICAgLy8gZ2V0IGFsbCBkaXN0aW5jdCBjaGFyYWN0ZXJzIGluIHRoZSB0ZXh0IGxhYmVsc1xuICAgIGNvbnN0IHRleHRMYWJlbHMgPSBmb3JtYXRUZXh0TGFiZWxEYXRhKHtcbiAgICAgIHRleHRMYWJlbCxcbiAgICAgIHRyaWdnZXJDaGFuZ2VkLFxuICAgICAgb2xkTGF5ZXJEYXRhLFxuICAgICAgZGF0YSxcbiAgICAgIGRhdGFDb250YWluZXJcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBkYXRhLFxuICAgICAgZ2V0SGV4SWQsXG4gICAgICBnZXRGaWx0ZXJWYWx1ZTogZ3B1RmlsdGVyLmZpbHRlclZhbHVlQWNjZXNzb3IoZGF0YUNvbnRhaW5lcikoKSxcbiAgICAgIHRleHRMYWJlbHMsXG4gICAgICBnZXRQb3NpdGlvbjogZCA9PiBkLmNlbnRyb2lkLFxuICAgICAgLi4uYWNjZXNzb3JzXG4gICAgfTtcbiAgfVxuICAvKiBlc2xpbnQtZW5hYmxlIGNvbXBsZXhpdHkgKi9cblxuICB1cGRhdGVMYXllck1ldGEoZGF0YXNldDogS2VwbGVyVGFibGUsIGdldEhleElkKSB7XG4gICAgY29uc3Qge2RhdGFDb250YWluZXJ9ID0gZGF0YXNldDtcblxuICAgIGNvbnN0IGNlbnRyb2lkcyA9IGRhdGFDb250YWluZXIubWFwKChkLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgaWQgPSBnZXRIZXhJZCh7aW5kZXh9KTtcbiAgICAgIGlmICghaDNJc1ZhbGlkKGlkKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIHNhdmUgYSByZWZlcmVuY2Ugb2YgY2VudHJvaWRzIHRvIGRhdGFUb0ZlYXR1cmVcbiAgICAgIC8vIHNvIHdlIGRvbid0IGhhdmUgdG8gcmUgY2FsY3VsYXRlIGl0IGFnYWluXG4gICAgICByZXR1cm4gZ2V0Q2VudHJvaWQoe2lkfSk7XG4gICAgfSwgdHJ1ZSk7XG5cbiAgICBjb25zdCBjZW50cm9pZHNEYXRhQ29udGFpbmVyID0gY3JlYXRlRGF0YUNvbnRhaW5lcihjZW50cm9pZHMpO1xuXG4gICAgY29uc3QgYm91bmRzID0gdGhpcy5nZXRQb2ludHNCb3VuZHMoXG4gICAgICBjZW50cm9pZHNEYXRhQ29udGFpbmVyLFxuICAgICAgKGQ6IGFueSwgZGM6IERhdGFDb250YWluZXJJbnRlcmZhY2UpID0+IHtcbiAgICAgICAgcmV0dXJuIFtkYy52YWx1ZUF0KGQuaW5kZXgsIDApLCBkYy52YWx1ZUF0KGQuaW5kZXgsIDEpXTtcbiAgICAgIH1cbiAgICApO1xuICAgIHRoaXMuZGF0YVRvRmVhdHVyZSA9IHtjZW50cm9pZHN9O1xuICAgIHRoaXMudXBkYXRlTWV0YSh7Ym91bmRzfSk7XG4gIH1cblxuICByZW5kZXJMYXllcihvcHRzKSB7XG4gICAgY29uc3Qge2RhdGEsIGdwdUZpbHRlciwgb2JqZWN0SG92ZXJlZCwgbWFwU3RhdGUsIGludGVyYWN0aW9uQ29uZmlnfSA9IG9wdHM7XG5cbiAgICBjb25zdCB6b29tRmFjdG9yID0gdGhpcy5nZXRab29tRmFjdG9yKG1hcFN0YXRlKTtcbiAgICBjb25zdCBlbGVab29tRmFjdG9yID0gdGhpcy5nZXRFbGV2YXRpb25ab29tRmFjdG9yKG1hcFN0YXRlKTtcbiAgICBjb25zdCB7Y29uZmlnfSA9IHRoaXM7XG4gICAgY29uc3Qge3Zpc0NvbmZpZ30gPSBjb25maWc7XG4gICAgY29uc3QgdXBkYXRlVHJpZ2dlcnMgPSB0aGlzLmdldFZpc3VhbENoYW5uZWxVcGRhdGVUcmlnZ2VycygpO1xuXG4gICAgY29uc3QgaDNIZXhhZ29uTGF5ZXJUcmlnZ2VycyA9IHtcbiAgICAgIGdldEhleGFnb246IHRoaXMuY29uZmlnLmNvbHVtbnMsXG4gICAgICBnZXRGaWxsQ29sb3I6IHVwZGF0ZVRyaWdnZXJzLmdldEZpbGxDb2xvcixcbiAgICAgIGdldExpbmVDb2xvcjogdXBkYXRlVHJpZ2dlcnMuZ2V0TGluZUNvbG9yLFxuICAgICAgZ2V0RWxldmF0aW9uOiB1cGRhdGVUcmlnZ2Vycy5nZXRFbGV2YXRpb24sXG4gICAgICBnZXRGaWx0ZXJWYWx1ZTogZ3B1RmlsdGVyLmZpbHRlclZhbHVlVXBkYXRlVHJpZ2dlcnNcbiAgICB9O1xuXG4gICAgY29uc3QgY29sdW1uTGF5ZXJUcmlnZ2VycyA9IHtcbiAgICAgIGdldENvdmVyYWdlOiB1cGRhdGVUcmlnZ2Vycy5nZXRDb3ZlcmFnZVxuICAgIH07XG5cbiAgICBjb25zdCBkZWZhdWx0TGF5ZXJQcm9wcyA9IHRoaXMuZ2V0RGVmYXVsdERlY2tMYXllclByb3BzKG9wdHMpO1xuICAgIGNvbnN0IGhvdmVyZWRPYmplY3QgPSB0aGlzLmhhc0hvdmVyZWRPYmplY3Qob2JqZWN0SG92ZXJlZCk7XG5cbiAgICAvLyBnZXRQaXhlbE9mZnNldCB3aXRoIG5vIHJhZGl1c1xuICAgIGNvbnN0IHJhZGl1c1NjYWxlID0gMS4wO1xuICAgIGNvbnN0IGdldFJhaWR1cyA9IG51bGw7XG4gICAgY29uc3QgZ2V0UGl4ZWxPZmZzZXQgPSBnZXRUZXh0T2Zmc2V0QnlSYWRpdXMocmFkaXVzU2NhbGUsIGdldFJhaWR1cywgbWFwU3RhdGUpO1xuXG4gICAgY29uc3QgYnJ1c2hpbmdQcm9wcyA9IHRoaXMuZ2V0QnJ1c2hpbmdFeHRlbnNpb25Qcm9wcyhpbnRlcmFjdGlvbkNvbmZpZyk7XG4gICAgY29uc3QgZXh0ZW5zaW9ucyA9IFsuLi5kZWZhdWx0TGF5ZXJQcm9wcy5leHRlbnNpb25zLCBicnVzaGluZ0V4dGVuc2lvbl07XG4gICAgY29uc3Qgc2hhcmVkUHJvcHMgPSB7XG4gICAgICBnZXRGaWx0ZXJWYWx1ZTogZGF0YS5nZXRGaWx0ZXJWYWx1ZSxcbiAgICAgIGV4dGVuc2lvbnMsXG4gICAgICBmaWx0ZXJSYW5nZTogZGVmYXVsdExheWVyUHJvcHMuZmlsdGVyUmFuZ2UsXG4gICAgICB2aXNpYmxlOiBkZWZhdWx0TGF5ZXJQcm9wcy52aXNpYmxlLFxuICAgICAgLi4uYnJ1c2hpbmdQcm9wc1xuICAgIH07XG5cbiAgICByZXR1cm4gW1xuICAgICAgbmV3IEgzSGV4YWdvbkxheWVyKHtcbiAgICAgICAgLi4uZGVmYXVsdExheWVyUHJvcHMsXG4gICAgICAgIC4uLmRhdGEsXG4gICAgICAgIC4uLmJydXNoaW5nUHJvcHMsXG4gICAgICAgIGV4dGVuc2lvbnMsXG4gICAgICAgIHdyYXBMb25naXR1ZGU6IGZhbHNlLFxuXG4gICAgICAgIGZpbGxlZDogdmlzQ29uZmlnLmZpbGxlZCxcbiAgICAgICAgc3Ryb2tlZDogdmlzQ29uZmlnLm91dGxpbmUsXG4gICAgICAgIGxpbmVXaWR0aFNjYWxlOiB2aXNDb25maWcudGhpY2tuZXNzLFxuXG4gICAgICAgIGdldEhleGFnb246ICh4OiBhbnkpID0+IHguaWQsXG5cbiAgICAgICAgLy8gY292ZXJhZ2VcbiAgICAgICAgY292ZXJhZ2U6IGNvbmZpZy5jb3ZlcmFnZUZpZWxkID8gMSA6IHZpc0NvbmZpZy5jb3ZlcmFnZSxcblxuICAgICAgICAvLyBoaWdobGlnaHRcbiAgICAgICAgYXV0b0hpZ2hsaWdodDogdmlzQ29uZmlnLmVuYWJsZTNkLFxuICAgICAgICBoaWdobGlnaHRDb2xvcjogSElHSExJR0hfQ09MT1JfM0QsXG5cbiAgICAgICAgLy8gZWxldmF0aW9uXG4gICAgICAgIGV4dHJ1ZGVkOiB2aXNDb25maWcuZW5hYmxlM2QsXG4gICAgICAgIGVsZXZhdGlvblNjYWxlOiB2aXNDb25maWcuZWxldmF0aW9uU2NhbGUgKiBlbGVab29tRmFjdG9yLFxuXG4gICAgICAgIC8vIHJlbmRlclxuICAgICAgICB1cGRhdGVUcmlnZ2VyczogaDNIZXhhZ29uTGF5ZXJUcmlnZ2VycyxcbiAgICAgICAgX3N1YkxheWVyUHJvcHM6IHtcbiAgICAgICAgICAnaGV4YWdvbi1jZWxsJzoge1xuICAgICAgICAgICAgdHlwZTogRW5oYW5jZWRDb2x1bW5MYXllcixcbiAgICAgICAgICAgIGdldENvdmVyYWdlOiBkYXRhLmdldENvdmVyYWdlLFxuICAgICAgICAgICAgdXBkYXRlVHJpZ2dlcnM6IGNvbHVtbkxheWVyVHJpZ2dlcnMsXG4gICAgICAgICAgICBzdHJva2VPcGFjaXR5OiB2aXNDb25maWcuc3Ryb2tlT3BhY2l0eVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgICAvLyBob3ZlciBsYXllclxuICAgICAgLi4uKGhvdmVyZWRPYmplY3QgJiYgIWNvbmZpZy5zaXplRmllbGRcbiAgICAgICAgPyBbXG4gICAgICAgICAgICBuZXcgR2VvSnNvbkxheWVyKHtcbiAgICAgICAgICAgICAgLi4udGhpcy5nZXREZWZhdWx0SG92ZXJMYXllclByb3BzKCksXG4gICAgICAgICAgICAgIHZpc2libGU6IGRlZmF1bHRMYXllclByb3BzLnZpc2libGUsXG4gICAgICAgICAgICAgIGRhdGE6IFtpZFRvUG9seWdvbkdlbyhob3ZlcmVkT2JqZWN0KV0sXG4gICAgICAgICAgICAgIGdldExpbmVDb2xvcjogY29uZmlnLmhpZ2hsaWdodENvbG9yLFxuICAgICAgICAgICAgICBsaW5lV2lkdGhTY2FsZTogREVGQVVMVF9MSU5FX1NDQUxFX1ZBTFVFICogem9vbUZhY3RvcixcbiAgICAgICAgICAgICAgd3JhcExvbmdpdHVkZTogZmFsc2VcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgXVxuICAgICAgICA6IFtdKSxcbiAgICAgIC8vIHRleHQgbGFiZWwgbGF5ZXJcbiAgICAgIC4uLnRoaXMucmVuZGVyVGV4dExhYmVsTGF5ZXIoXG4gICAgICAgIHtcbiAgICAgICAgICBnZXRQb3NpdGlvbjogZGF0YS5nZXRQb3NpdGlvbixcbiAgICAgICAgICBzaGFyZWRQcm9wcyxcbiAgICAgICAgICBnZXRQaXhlbE9mZnNldCxcbiAgICAgICAgICB1cGRhdGVUcmlnZ2Vyc1xuICAgICAgICB9LFxuICAgICAgICBvcHRzXG4gICAgICApXG4gICAgXTtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFHQSxJQUFBQSxVQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFPQSxJQUFBQyxXQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxPQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxVQUFBLEdBQUFILE9BQUE7QUFDQSxJQUFBSSxhQUFBLEdBQUFKLE9BQUE7QUFDQSxJQUFBSyxZQUFBLEdBQUFMLE9BQUE7QUFPQSxJQUFBTSxNQUFBLEdBQUFOLE9BQUE7QUFDQSxJQUFBTyxtQkFBQSxHQUFBUixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQVEsVUFBQSxHQUFBUixPQUFBO0FBb0JBLElBQUFTLGVBQUEsR0FBQVQsT0FBQTtBQUErRSxTQUFBVSxXQUFBQyxDQUFBLEVBQUFDLENBQUEsRUFBQUMsQ0FBQSxXQUFBRCxDQUFBLE9BQUFFLGdCQUFBLGFBQUFGLENBQUEsT0FBQUcsMkJBQUEsYUFBQUosQ0FBQSxFQUFBSyx5QkFBQSxLQUFBQyxPQUFBLENBQUFDLFNBQUEsQ0FBQU4sQ0FBQSxF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