kepler.gl.geoiq
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
299 lines (253 loc) • 33.1 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.pointPosAccessor = exports.pointColResolver = exports.heatmapVisConfigs = exports["default"] = void 0;
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _reselect = require("reselect");
var _lodash = _interopRequireDefault(require("lodash.memoize"));
var _defaultSettings = require("../../constants/default-settings");
var _colorUtils = require("../../utils/color-utils");
var _mapboxUtils = require("../mapbox-utils");
var _mapboxglLayer = _interopRequireDefault(require("../mapboxgl-layer"));
var _heatmapLayerIcon = _interopRequireDefault(require("./heatmap-layer-icon"));
var _excluded = ["colorField", "colorDomain", "colorScale"];
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; }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
var MAX_ZOOM_LEVEL = 18;
var pointPosAccessor = exports.pointPosAccessor = function pointPosAccessor(_ref) {
var lat = _ref.lat,
lng = _ref.lng;
return function (d) {
return [// lng
d.data[lng.fieldIdx], // lat
d.data[lat.fieldIdx]];
};
};
var pointColResolver = exports.pointColResolver = function pointColResolver(_ref2) {
var lat = _ref2.lat,
lng = _ref2.lng;
return "".concat(lat.fieldIdx, "-").concat(lng.fieldIdx);
};
var heatmapVisConfigs = exports.heatmapVisConfigs = {
opacity: 'opacity',
colorRange: 'colorRange',
radius: 'heatmapRadius'
};
/**
*
* @param {Object} colorRange
* @return {Array} [
* 0, "rgba(33,102,172,0)",
* 0.2, "rgb(103,169,207)",
* 0.4, "rgb(209,229,240)",
* 0.6, "rgb(253,219,199)",
* 0.8, "rgb(239,138,98)",
* 1, "rgb(178,24,43)"
* ]
*/
var heatmapDensity = function heatmapDensity(colorRange) {
var scaleFunction = _defaultSettings.SCALE_FUNC.quantize;
var colors = ['#000000'].concat((0, _toConsumableArray2["default"])(colorRange.colors));
var scale = scaleFunction().domain([0, 1]).range(colors);
var colorDensity = scale.range().reduce(function (bands, level) {
var invert = scale.invertExtent(level);
return [].concat((0, _toConsumableArray2["default"])(bands), [invert[0], // first value in the range
"rgb(".concat((0, _colorUtils.hexToRgb)(level).join(','), ")") // color
]);
}, []);
colorDensity[1] = 'rgba(0,0,0,0)';
return colorDensity;
};
var shouldRebuild = function shouldRebuild(sameData, sameConfig) {
return !(sameData && sameConfig);
};
var HeatmapLayer = /*#__PURE__*/function (_MapboxGLLayer) {
(0, _inherits2["default"])(HeatmapLayer, _MapboxGLLayer);
var _super = _createSuper(HeatmapLayer);
function HeatmapLayer(props) {
var _this;
(0, _classCallCheck2["default"])(this, HeatmapLayer);
_this = _super.call(this, props);
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "isSameData", function (_ref3, config) {
var allData = _ref3.allData,
filteredIndex = _ref3.filteredIndex,
oldLayerData = _ref3.oldLayerData,
_ref3$opt = _ref3.opt,
opt = _ref3$opt === void 0 ? {} : _ref3$opt;
return Boolean(oldLayerData && oldLayerData.columns === config.columns && opt.sameData);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "isSameConfig", function (_ref4) {
var oldLayerData = _ref4.oldLayerData,
config = _ref4.config;
// columns must use the same filedIdx
// this is a fast way to compare columns object
var columns = config.columns,
weightField = config.weightField;
if (!oldLayerData) {
return false;
}
var sameColumns = columns === oldLayerData.columns;
var sameWeightField = weightField === oldLayerData.weightField;
return sameColumns && sameWeightField;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "datasetSelector", function (config) {
return config.dataId;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "columnsSelector", function (config) {
return pointColResolver(config.columns);
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "visConfigSelector", function (config) {
return config.visConfig;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "weightFieldSelector", function (config) {
return config.weightField ? config.weightField.name : null;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "weightDomainSelector", function (config) {
return config.weightDomain;
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "computeHeatmapConfiguration", (0, _reselect.createSelector)(_this.datasetSelector, _this.columnsSelector, _this.visConfigSelector, _this.weightFieldSelector, _this.weightDomainSelector, function (datasetId, columns, visConfig, weightField, weightDomain) {
return {
type: 'heatmap',
id: _this.id,
source: "".concat(datasetId, "-").concat(columns),
layout: {
visibility: 'visible'
},
maxzoom: MAX_ZOOM_LEVEL,
paint: {
'heatmap-weight': weightField ? ['interpolate', ['linear'], ['get', weightField], weightDomain[0], 0, weightDomain[1], 1] : 1,
'heatmap-intensity': ['interpolate', ['linear'], ['zoom'], 0, 1, MAX_ZOOM_LEVEL, 3],
'heatmap-color': ['interpolate', ['linear'], ['heatmap-density']].concat((0, _toConsumableArray2["default"])(heatmapDensity(visConfig.colorRange))),
'heatmap-radius': ['interpolate', ['linear'], ['zoom'], 0, 2, MAX_ZOOM_LEVEL, visConfig.radius // radius
],
'heatmap-opacity': visConfig.opacity
}
};
}));
_this.registerVisConfig(heatmapVisConfigs);
_this.getPosition = (0, _lodash["default"])(pointPosAccessor, pointColResolver);
return _this;
}
(0, _createClass2["default"])(HeatmapLayer, [{
key: "type",
get: function get() {
return 'heatmap';
}
}, {
key: "visualChannels",
get: function get() {
return {
weight: {
property: 'weight',
field: 'weightField',
scale: 'weightScale',
domain: 'weightDomain',
key: 'weight',
// supportedFieldTypes can be determined by channelScaleType
// or specified here
defaultMeasure: 'density',
supportedFieldTypes: [_defaultSettings.ALL_FIELD_TYPES.real, _defaultSettings.ALL_FIELD_TYPES.integer],
channelScaleType: _defaultSettings.CHANNEL_SCALES.size
}
};
}
}, {
key: "layerIcon",
get: function get() {
return _heatmapLayerIcon["default"];
}
}, {
key: "getVisualChannelDescription",
value: function getVisualChannelDescription(channel) {
return channel === 'color' ? {
label: 'color',
measure: 'Density'
} : {
label: 'weight',
measure: this.config.weightField ? this.config.weightField.name : 'Density'
};
}
}, {
key: "getDefaultLayerConfig",
value: function getDefaultLayerConfig() {
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
// mapbox heatmap layer color is always based on density
// no need to set colorField, colorDomain and colorScale
/* eslint-disable no-unused-vars */
var _get$call$weightField = _objectSpread(_objectSpread({}, (0, _get2["default"])((0, _getPrototypeOf2["default"])(HeatmapLayer.prototype), "getDefaultLayerConfig", this).call(this, props)), {}, {
weightField: null,
weightDomain: [0, 1],
weightScale: 'linear'
}),
colorField = _get$call$weightField.colorField,
colorDomain = _get$call$weightField.colorDomain,
colorScale = _get$call$weightField.colorScale,
layerConfig = (0, _objectWithoutProperties2["default"])(_get$call$weightField, _excluded);
/* eslint-enable no-unused-vars */
return layerConfig;
}
}, {
key: "getPositionAccessor",
value: function getPositionAccessor() {
return this.getPosition(this.config.columns);
}
}, {
key: "updateLayerMeta",
value: function updateLayerMeta(allData) {
var getPosition = this.getPositionAccessor();
var bounds = this.getPointsBounds(allData, function (d) {
return getPosition({
data: d
});
});
this.updateMeta({
bounds: bounds
});
}
}, {
key: "formatLayerData",
value: function formatLayerData(_, allData, filteredIndex, oldLayerData) {
var opt = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
var options = {
allData: allData,
filteredIndex: filteredIndex,
oldLayerData: oldLayerData,
opt: opt,
config: this.config
};
var weightField = this.config.weightField;
var isSameData = this.isSameData(options, this.config);
var isSameConfig = this.isSameConfig(options);
var getPosition = this.getPositionAccessor();
if (!oldLayerData || oldLayerData.getPosition !== getPosition) {
this.updateLayerMeta(allData, getPosition);
}
var data = !shouldRebuild(isSameData, isSameConfig) ? oldLayerData.data : (0, _mapboxUtils.geojsonFromPoints)(allData, filteredIndex, this.config.columns, weightField ? [weightField] : []);
var newConfig = this.computeHeatmapConfiguration(this.config);
newConfig.id = this.id;
return {
columns: this.config.columns,
config: newConfig,
data: data,
weightField: weightField,
getPosition: getPosition
};
}
}]);
return HeatmapLayer;
}(_mapboxglLayer["default"]);
var _default = exports["default"] = HeatmapLayer;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9sYXllcnMvaGVhdG1hcC1sYXllci9oZWF0bWFwLWxheWVyLmpzIl0sIm5hbWVzIjpbIk1BWF9aT09NX0xFVkVMIiwicG9pbnRQb3NBY2Nlc3NvciIsImxhdCIsImxuZyIsImQiLCJkYXRhIiwiZmllbGRJZHgiLCJwb2ludENvbFJlc29sdmVyIiwiaGVhdG1hcFZpc0NvbmZpZ3MiLCJvcGFjaXR5IiwiY29sb3JSYW5nZSIsInJhZGl1cyIsImhlYXRtYXBEZW5zaXR5Iiwic2NhbGVGdW5jdGlvbiIsIlNDQUxFX0ZVTkMiLCJxdWFudGl6ZSIsImNvbG9ycyIsInNjYWxlIiwiZG9tYWluIiwicmFuZ2UiLCJjb2xvckRlbnNpdHkiLCJyZWR1Y2UiLCJiYW5kcyIsImxldmVsIiwiaW52ZXJ0IiwiaW52ZXJ0RXh0ZW50Iiwiam9pbiIsInNob3VsZFJlYnVpbGQiLCJzYW1lRGF0YSIsInNhbWVDb25maWciLCJIZWF0bWFwTGF5ZXIiLCJwcm9wcyIsImNvbmZpZyIsImFsbERhdGEiLCJmaWx0ZXJlZEluZGV4Iiwib2xkTGF5ZXJEYXRhIiwib3B0IiwiQm9vbGVhbiIsImNvbHVtbnMiLCJ3ZWlnaHRGaWVsZCIsInNhbWVDb2x1bW5zIiwic2FtZVdlaWdodEZpZWxkIiwiZGF0YUlkIiwidmlzQ29uZmlnIiwibmFtZSIsIndlaWdodERvbWFpbiIsImRhdGFzZXRTZWxlY3RvciIsImNvbHVtbnNTZWxlY3RvciIsInZpc0NvbmZpZ1NlbGVjdG9yIiwid2VpZ2h0RmllbGRTZWxlY3RvciIsIndlaWdodERvbWFpblNlbGVjdG9yIiwiZGF0YXNldElkIiwidHlwZSIsImlkIiwic291cmNlIiwibGF5b3V0IiwidmlzaWJpbGl0eSIsIm1heHpvb20iLCJwYWludCIsInJlZ2lzdGVyVmlzQ29uZmlnIiwiZ2V0UG9zaXRpb24iLCJ3ZWlnaHQiLCJwcm9wZXJ0eSIsImZpZWxkIiwia2V5IiwiZGVmYXVsdE1lYXN1cmUiLCJzdXBwb3J0ZWRGaWVsZFR5cGVzIiwiQUxMX0ZJRUxEX1RZUEVTIiwicmVhbCIsImludGVnZXIiLCJjaGFubmVsU2NhbGVUeXBlIiwiQ0hBTk5FTF9TQ0FMRVMiLCJzaXplIiwiSGVhdG1hcExheWVySWNvbiIsImNoYW5uZWwiLCJsYWJlbCIsIm1lYXN1cmUiLCJ3ZWlnaHRTY2FsZSIsImNvbG9yRmllbGQiLCJjb2xvckRvbWFpbiIsImNvbG9yU2NhbGUiLCJsYXllckNvbmZpZyIsImdldFBvc2l0aW9uQWNjZXNzb3IiLCJib3VuZHMiLCJnZXRQb2ludHNCb3VuZHMiLCJ1cGRhdGVNZXRhIiwiXyIsIm9wdGlvbnMiLCJpc1NhbWVEYXRhIiwiaXNTYW1lQ29uZmlnIiwidXBkYXRlTGF5ZXJNZXRhIiwibmV3Q29uZmlnIiwiY29tcHV0ZUhlYXRtYXBDb25maWd1cmF0aW9uIiwiTWFwYm94R0xMYXllciJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFvQkE7O0FBQ0E7O0FBQ0E7O0FBS0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7OztBQUVBLElBQU1BLGNBQWMsR0FBRyxFQUF2Qjs7QUFFTyxJQUFNQyxnQkFBZ0IsOEJBQUcsU0FBbkJBLGdCQUFtQjtBQUFBLE1BQUVDLEdBQUYsUUFBRUEsR0FBRjtBQUFBLE1BQU9DLEdBQVAsUUFBT0EsR0FBUDtBQUFBLFNBQWdCLFVBQUFDLENBQUM7QUFBQSxXQUFJLENBQ25EO0FBQ0FBLElBQUFBLENBQUMsQ0FBQ0MsSUFBRixDQUFPRixHQUFHLENBQUNHLFFBQVgsQ0FGbUQsRUFHbkQ7QUFDQUYsSUFBQUEsQ0FBQyxDQUFDQyxJQUFGLENBQU9ILEdBQUcsQ0FBQ0ksUUFBWCxDQUptRCxDQUFKO0FBQUEsR0FBakI7QUFBQSxDQUF6Qjs7QUFPQSxJQUFNQyxnQkFBZ0IsOEJBQUcsU0FBbkJBLGdCQUFtQjtBQUFBLE1BQUVMLEdBQUYsU0FBRUEsR0FBRjtBQUFBLE1BQU9DLEdBQVAsU0FBT0EsR0FBUDtBQUFBLG1CQUMzQkQsR0FBRyxDQUFDSSxRQUR1QixjQUNYSCxH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QUEsSUFBSSxFQUFKQSxJQUhLO0FBSUxrQyxRQUFBQSxXQUFXLEVBQVhBLFdBSks7QUFLTHFCLFFBQUFBLFdBQVcsRUFBWEE7QUFMSyxPQUFQO0FBT0Q7OztFQW5Nd0JpQyx5Qjs7b0NBc01aL0QsWSIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgMjAyMyBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCB7Y3JlYXRlU2VsZWN0b3J9IGZyb20gJ3Jlc2VsZWN0JztcbmltcG9ydCBtZW1vaXplIGZyb20gJ2xvZGFzaC5tZW1vaXplJztcbmltcG9ydCB7XG4gIENIQU5ORUxfU0NBTEVTLFxuICBTQ0FMRV9GVU5DLFxuICBBTExfRklFTERfVFlQRVNcbn0gZnJvbSAnY29uc3RhbnRzL2RlZmF1bHQtc2V0dGluZ3MnO1xuaW1wb3J0IHtoZXhUb1JnYn0gZnJvbSAndXRpbHMvY29sb3ItdXRpbHMnO1xuaW1wb3J0IHtnZW9qc29uRnJvbVBvaW50c30gZnJvbSAnLi4vbWFwYm94LXV0aWxzJztcbmltcG9ydCBNYXBib3hHTExheWVyIGZyb20gJy4uL21hcGJveGdsLWxheWVyJztcbmltcG9ydCBIZWF0bWFwTGF5ZXJJY29uIGZyb20gJy4vaGVhdG1hcC1sYXllci1pY29uJztcblxuY29uc3QgTUFYX1pPT01fTEVWRUwgPSAxODtcblxuZXhwb3J0IGNvbnN0IHBvaW50UG9zQWNjZXNzb3IgPSAoe2xhdCwgbG5nfSkgPT4gZCA9PiBbXG4gIC8vIGxuZ1xuICBkLmRhdGFbbG5nLmZpZWxkSWR4XSxcbiAgLy8gbGF0XG4gIGQuZGF0YVtsYXQuZmllbGRJZHhdXG5dO1xuXG5leHBvcnQgY29uc3QgcG9pbnRDb2xSZXNvbHZlciA9ICh7bGF0LCBsbmd9KSA9PlxuICBgJHtsYXQuZmllbGRJZHh9LSR7bG5nLmZpZWxkSWR4fWA7XG5cbmV4cG9ydCBjb25zdCBoZWF0bWFwVmlzQ29uZmlncyA9IHtcbiAgb3BhY2l0eTogJ29wYWNpdHknLFxuICBjb2xvclJhbmdlOiAnY29sb3JSYW5nZScsXG4gIHJhZGl1czogJ2hlYXRtYXBSYWRpdXMnXG59O1xuXG4vKipcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29sb3JSYW5nZVxuICogQHJldHVybiB7QXJyYXl9IFtcbiAqICAwLCBcInJnYmEoMzMsMTAyLDE3MiwwKVwiLFxuICogIDAuMiwgXCJyZ2IoMTAzLDE2OSwyMDcpXCIsXG4gKiAgMC40LCBcInJnYigyMDksMjI5LDI0MClcIixcbiAqICAwLjYsIFwicmdiKDI1MywyMTksMTk5KVwiLFxuICogIDAuOCwgXCJyZ2IoMjM5LDEzOCw5OClcIixcbiAqICAxLCBcInJnYigxNzgsMjQsNDMpXCJcbiAqIF1cbiAqL1xuY29uc3QgaGVhdG1hcERlbnNpdHkgPSBjb2xvclJhbmdlID0+IHtcbiAgY29uc3Qgc2NhbGVGdW5jdGlvbiA9IFNDQUxFX0ZVTkMucXVhbnRpemU7XG5cbiAgY29uc3QgY29sb3JzID0gWycjMDAwMDAwJywgLi4uY29sb3JSYW5nZS5jb2xvcnNdO1xuXG4gIGNvbnN0IHNjYWxlID0gc2NhbGVGdW5jdGlvbigpXG4gICAgLmRvbWFpbihbMCwgMV0pXG4gICAgLnJhbmdlKGNvbG9ycyk7XG5cbiAgY29uc3QgY29sb3JEZW5zaXR5ID0gc2NhbGUucmFuZ2UoKS5yZWR1Y2UoKGJhbmRzLCBsZXZlbCkgPT4ge1xuICAgIGNvbnN0IGludmVydCA9IHNjYWxlLmludmVydEV4dGVudChsZXZlbCk7XG4gICAgcmV0dXJuIFtcbiAgICAgIC4uLmJhbmRzLFxuICAgICAgaW52ZXJ0WzBdLCAvLyBmaXJzdCB2YWx1ZSBpbiB0aGUgcmFuZ2VcbiAgICAgIGByZ2IoJHtoZXhUb1JnYihsZXZlbCkuam9pbignLCcpfSlgIC8vIGNvbG9yXG4gICAgXTtcbiAgfSwgW10pO1xuICBjb2xvckRlbnNpdHlbMV0gPSAncmdiYSgwLDAsMCwwKSc7XG4gIHJldHVybiBjb2xvckRlbnNpdHk7XG59O1xuXG5jb25zdCBzaG91bGRSZWJ1aWxkID0gKHNhbWVEYXRhLCBzYW1lQ29uZmlnKSA9PiAhKHNhbWVEYXRhICYmIHNhbWVDb25maWcpO1xuXG5jbGFzcyBIZWF0bWFwTGF5ZXIgZXh0ZW5kcyBNYXBib3hHTExheWVyIHtcbiAgY29uc3RydWN0b3IocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5yZWdpc3RlclZpc0NvbmZpZyhoZWF0bWFwVmlzQ29uZmlncyk7XG4gICAgdGhpcy5nZXRQb3NpdGlvbiA9IG1lbW9pemUocG9pbnRQb3NBY2Nlc3NvciwgcG9pbnRDb2xSZXNvbHZlcik7XG4gIH1cblxuICBnZXQgdHlwZSgpIHtcbiAgICByZXR1cm4gJ2hlYXRtYXAnO1xuICB9XG5cbiAgZ2V0IHZpc3VhbENoYW5uZWxzKCkge1xuICAgIHJldHVybiB7XG4gICAgICB3ZWlnaHQ6IHtcbiAgICAgICAgcHJvcGVydHk6ICd3ZWlnaHQnLFxuICAgICAgICBmaWVsZDogJ3dlaWdodEZpZWxkJyxcbiAgICAgICAgc2NhbGU6ICd3ZWlnaHRTY2FsZScsXG4gICAgICAgIGRvbWFpbjogJ3dlaWdodERvbWFpbicsXG4gICAgICAgIGtleTogJ3dlaWdodCcsXG4gICAgICAgIC8vIHN1cHBvcnRlZEZpZWxkVHlwZXMgY2FuIGJlIGRldGVybWluZWQgYnkgY2hhbm5lbFNjYWxlVHlwZVxuICAgICAgICAvLyBvciBzcGVjaWZpZWQgaGVyZVxuICAgICAgICBkZWZhdWx0TWVhc3VyZTogJ2RlbnNpdHknLFxuICAgICAgICBzdXBwb3J0ZWRGaWVsZFR5cGVzOiBbQUxMX0ZJRUxEX1RZUEVTLnJlYWwsIEFMTF9GSUVMRF9UWVBFUy5pbnRlZ2VyXSxcbiAgICAgICAgY2hhbm5lbFNjYWxlVHlwZTogQ0hBTk5FTF9TQ0FMRVMuc2l6ZVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBnZXQgbGF5ZXJJY29uKCkge1xuICAgIHJldHVybiBIZWF0bWFwTGF5ZXJJY29uO1xuICB9XG5cbiAgZ2V0VmlzdWFsQ2hhbm5lbERlc2NyaXB0aW9uKGNoYW5uZWwpIHtcbiAgICByZXR1cm4gY2hhbm5lbCA9PT0gJ2NvbG9yJ1xuICAgICAgPyB7XG4gICAgICAgICAgbGFiZWw6ICdjb2xvcicsXG4gICAgICAgICAgbWVhc3VyZTogJ0RlbnNpdHknXG4gICAgICAgIH1cbiAgICAgIDoge1xuICAgICAgICAgIGxhYmVsOiAnd2VpZ2h0JyxcbiAgICAgICAgICBtZWFzdXJlOiB0aGlzLmNvbmZpZy53ZWlnaHRGaWVsZFxuICAgICAgICAgICAgPyB0aGlzLmNvbmZpZy53ZWlnaHRGaWVsZC5uYW1lXG4gICAgICAgICAgICA6ICdEZW5zaXR5J1xuICAgICAgICB9O1xuICB9XG5cbiAgZ2V0RGVmYXVsdExheWVyQ29uZmlnKHByb3BzID0ge30pIHtcbiAgICAvLyBtYXBib3ggaGVhdG1hcCBsYXllciBjb2xvciBpcyBhbHdheXMgYmFzZWQgb24gZGVuc2l0eVxuICAgIC8vIG5vIG5lZWQgdG8gc2V0IGNvbG9yRmllbGQsIGNvbG9yRG9tYWluIGFuZCBjb2xvclNjYWxlXG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi9cbiAgICBjb25zdCB7Y29sb3JGaWVsZCwgY29sb3JEb21haW4sIGNvbG9yU2NhbGUsIC4uLmxheWVyQ29uZmlnfSA9IHtcbiAgICAgIC4uLnN1cGVyLmdldERlZmF1bHRMYXllckNvbmZpZyhwcm9wcyksXG5cbiAgICAgIHdlaWdodEZpZWxkOiBudWxsLFxuICAgICAgd2VpZ2h0RG9tYWluOiBbMCwgMV0sXG4gICAgICB3ZWlnaHRTY2FsZTogJ2xpbmVhcidcbiAgICB9O1xuICAgIC8qIGVzbGludC1lbmFibGUgbm8tdW51c2VkLXZhcnMgKi9cblxuICAgIHJldHVybiBsYXllckNvbmZpZztcbiAgfVxuXG4gIGlzU2FtZURhdGEgPSAoe2FsbERhdGEsIGZpbHRlcmVkSW5kZXgsIG9sZExheWVyRGF0YSwgb3B0ID0ge319LCBjb25maWcpID0+IHtcbiAgICByZXR1cm4gQm9vbGVhbihcbiAgICAgIG9sZExheWVyRGF0YSAmJiBvbGRMYXllckRhdGEuY29sdW1ucyA9PT0gY29uZmlnLmNvbHVtbnMgJiYgb3B0LnNhbWVEYXRhXG4gICAgKTtcbiAgfTtcblxuICBpc1NhbWVDb25maWcgPSAoe29sZExheWVyRGF0YSwgY29uZmlnfSkgPT4ge1xuICAgIC8vIGNvbHVtbnMgbXVzdCB1c2UgdGhlIHNhbWUgZmlsZWRJZHhcbiAgICAvLyB0aGlzIGlzIGEgZmFzdCB3YXkgdG8gY29tcGFyZSBjb2x1bW5zIG9iamVjdFxuICAgIGNvbnN0IHtjb2x1bW5zLCB3ZWlnaHRGaWVsZH0gPSBjb25maWc7XG5cbiAgICBpZiAoIW9sZExheWVyRGF0YSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IHNhbWVDb2x1bW5zID0gY29sdW1ucyA9PT0gb2xkTGF5ZXJEYXRhLmNvbHVtbnM7XG4gICAgY29uc3Qgc2FtZVdlaWdodEZpZWxkID0gd2VpZ2h0RmllbGQgPT09IG9sZExheWVyRGF0YS53ZWlnaHRGaWVsZDtcbiAgICByZXR1cm4gc2FtZUNvbHVtbnMgJiYgc2FtZVdlaWdodEZpZWxkO1xuICB9O1xuXG4gIGRhdGFzZXRTZWxlY3RvciA9IGNvbmZpZyA9PiBjb25maWcuZGF0YUlkO1xuICBjb2x1bW5zU2VsZWN0b3IgPSBjb25maWcgPT4gcG9pbnRDb2xSZXNvbHZlcihjb25maWcuY29sdW1ucyk7XG4gIHZpc0NvbmZpZ1NlbGVjdG9yID0gY29uZmlnID0+IGNvbmZpZy52aXNDb25maWc7XG4gIHdlaWdodEZpZWxkU2VsZWN0b3IgPSBjb25maWcgPT5cbiAgICBjb25maWcud2VpZ2h0RmllbGQgPyBjb25maWcud2VpZ2h0RmllbGQubmFtZSA6IG51bGw7XG4gIHdlaWdodERvbWFpblNlbGVjdG9yID0gY29uZmlnID0+IGNvbmZpZy53ZWlnaHREb21haW47XG5cbiAgZ2V0UG9zaXRpb25BY2Nlc3NvcigpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRQb3NpdGlvbih0aGlzLmNvbmZpZy5jb2x1bW5zKTtcbiAgfVxuXG4gIHVwZGF0ZUxheWVyTWV0YShhbGxEYXRhKSB7XG4gICAgY29uc3QgZ2V0UG9zaXRpb24gPSB0aGlzLmdldFBvc2l0aW9uQWNjZXNzb3IoKTtcbiAgICBjb25zdCBib3VuZHMgPSB0aGlzLmdldFBvaW50c0JvdW5kcyhhbGxEYXRhLCBkID0+IGdldFBvc2l0aW9uKHtkYXRhOiBkfSkpO1xuICAgIHRoaXMudXBkYXRlTWV0YSh7Ym91bmRzfSk7XG4gIH1cblxuICBjb21wdXRlSGVhdG1hcENvbmZpZ3VyYXRpb24gPSBjcmVhdGVTZWxlY3RvcihcbiAgICB0aGlzLmRhdGFzZXRTZWxlY3RvcixcbiAgICB0aGlzLmNvbHVtbnNTZWxlY3RvcixcbiAgICB0aGlzLnZpc0NvbmZpZ1NlbGVjdG9yLFxuICAgIHRoaXMud2VpZ2h0RmllbGRTZWxlY3RvcixcbiAgICB0aGlzLndlaWdodERvbWFpblNlbGVjdG9yLFxuXG4gICAgKGRhdGFzZXRJZCwgY29sdW1ucywgdmlzQ29uZmlnLCB3ZWlnaHRGaWVsZCwgd2VpZ2h0RG9tYWluKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnaGVhdG1hcCcsXG4gICAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgICBzb3VyY2U6IGAke2RhdGFzZXRJZH0tJHtjb2x1bW5zfWAsXG4gICAgICAgIGxheW91dDoge1xuICAgICAgICAgIHZpc2liaWxpdHk6ICd2aXNpYmxlJ1xuICAgICAgICB9LFxuICAgICAgICBtYXh6b29tOiBNQVhfWk9PTV9MRVZFTCxcbiAgICAgICAgcGFpbnQ6IHtcbiAgICAgICAgICAnaGVhdG1hcC13ZWlnaHQnOiB3ZWlnaHRGaWVsZFxuICAgICAgICAgICAgPyBbXG4gICAgICAgICAgICAgICAgJ2ludGVycG9sYXRlJyxcbiAgICAgICAgICAgICAgICBbJ2xpbmVhciddLFxuICAgICAgICAgICAgICAgIFsnZ2V0Jywgd2VpZ2h0RmllbGRdLFxuICAgICAgICAgICAgICAgIHdlaWdodERvbWFpblswXSxcbiAgICAgICAgICAgICAgICAwLFxuICAgICAgICAgICAgICAgIHdlaWdodERvbWFpblsxXSxcbiAgICAgICAgICAgICAgICAxXG4gICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIDogMSxcbiAgICAgICAgICAnaGVhdG1hcC1pbnRlbnNpdHknOiBbXG4gICAgICAgICAgICAnaW50ZXJwb2xhdGUnLFxuICAgICAgICAgICAgWydsaW5lYXInXSxcbiAgICAgICAgICAgIFsnem9vbSddLFxuICAgICAgICAgICAgMCxcbiAgICAgICAgICAgIDEsXG4gICAgICAgICAgICBNQVhfWk9PTV9MRVZFTCxcbiAgICAgICAgICAgIDNcbiAgICAgICAgICBdLFxuICAgICAgICAgICdoZWF0bWFwLWNvbG9yJzogW1xuICAgICAgICAgICAgJ2ludGVycG9sYXRlJyxcbiAgICAgICAgICAgIFsnbGluZWFyJ10sXG4gICAgICAgICAgICBbJ2hlYXRtYXAtZGVuc2l0eSddLFxuICAgICAgICAgICAgLi4uaGVhdG1hcERlbnNpdHkodmlzQ29uZmlnLmNvbG9yUmFuZ2UpXG4gICAgICAgICAgXSxcbiAgICAgICAgICAnaGVhdG1hcC1yYWRpdXMnOiBbXG4gICAgICAgICAgICAnaW50ZXJwb2xhdGUnLFxuICAgICAgICAgICAgWydsaW5lYXInXSxcbiAgICAgICAgICAgIFsnem9vbSddLFxuICAgICAgICAgICAgMCxcbiAgICAgICAgICAgIDIsXG4gICAgICAgICAgICBNQVhfWk9PTV9MRVZFTCxcbiAgICAgICAgICAgIHZpc0NvbmZpZy5yYWRpdXMgLy8gcmFkaXVzXG4gICAgICAgICAgXSxcbiAgICAgICAgICAnaGVhdG1hcC1vcGFjaXR5JzogdmlzQ29uZmlnLm9wYWNpdHlcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICk7XG5cbiAgZm9ybWF0TGF5ZXJEYXRhKF8sIGFsbERhdGEsIGZpbHRlcmVkSW5kZXgsIG9sZExheWVyRGF0YSwgb3B0ID0ge30pIHtcbiAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgYWxsRGF0YSxcbiAgICAgIGZpbHRlcmVkSW5kZXgsXG4gICAgICBvbGRMYXllckRhdGEsXG4gICAgICBvcHQsXG4gICAgICBjb25maWc6IHRoaXMuY29uZmlnXG4gICAgfTtcblxuICAgIGNvbnN0IHt3ZWlnaHRGaWVsZH0gPSB0aGlzLmNvbmZpZztcbiAgICBjb25zdCBpc1NhbWVEYXRhID0gdGhpcy5pc1NhbWVEYXRhKG9wdGlvbnMsIHRoaXMuY29uZmlnKTtcbiAgICBjb25zdCBpc1NhbWVDb25maWcgPSB0aGlzLmlzU2FtZUNvbmZpZyhvcHRpb25zKTtcblxuICAgIGNvbnN0IGdldFBvc2l0aW9uID0gdGhpcy5nZXRQb3NpdGlvbkFjY2Vzc29yKCk7XG5cbiAgICBpZiAoIW9sZExheWVyRGF0YSB8fCBvbGRMYXllckRhdGEuZ2V0UG9zaXRpb24gIT09IGdldFBvc2l0aW9uKSB7XG4gICAgICB0aGlzLnVwZGF0ZUxheWVyTWV0YShhbGxEYXRhLCBnZXRQb3NpdGlvbik7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9ICFzaG91bGRSZWJ1aWxkKGlzU2FtZURhdGEsIGlzU2FtZUNvbmZpZylcbiAgICAgID8gb2xkTGF5ZXJEYXRhLmRhdGFcbiAgICAgIDogZ2VvanNvbkZyb21Qb2ludHMoXG4gICAgICAgICAgYWxsRGF0YSxcbiAgICAgICAgICBmaWx0ZXJlZEluZGV4LFxuICAgICAgICAgIHRoaXMuY29uZmlnLmNvbHVtbnMsXG4gICAgICAgICAgd2VpZ2h0RmllbGQgPyBbd2VpZ2h0RmllbGRdIDogW11cbiAgICAgICAgKTtcblxuICAgIGNvbnN0IG5ld0NvbmZpZyA9IHRoaXMuY29tcHV0ZUhlYXRtYXBDb25maWd1cmF0aW9uKHRoaXMuY29uZmlnKTtcbiAgICBuZXdDb25maWcuaWQgPSB0aGlzLmlkO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbHVtbnM6IHRoaXMuY29uZmlnLmNvbHVtbnMsXG4gICAgICBjb25maWc6IG5ld0NvbmZpZyxcbiAgICAgIGRhdGEsXG4gICAgICB3ZWlnaHRGaWVsZCxcbiAgICAgIGdldFBvc2l0aW9uXG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBIZWF0bWFwTGF5ZXI7XG4iXX0=