UNPKG

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
"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=