kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
276 lines (271 loc) • 39.4 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.pointRequiredColumns = exports.pointPosAccessor = exports.pointColResolver = exports.heatmapVisConfigs = exports.geoarrowRequiredColumns = exports.geoarrowPosAccessor = exports["default"] = exports.MAX_ZOOM_LEVEL = exports.COLUMN_MODE_POINTS = exports.COLUMN_MODE_GEOARROW = 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 _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 _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _reselect = require("reselect");
var _constants = require("@kepler.gl/constants");
var _mapboxglLayer = _interopRequireDefault(require("../mapboxgl-layer"));
var _heatmapLayerIcon = _interopRequireDefault(require("./heatmap-layer-icon"));
var _utils = require("@kepler.gl/utils");
var _layerUtils = require("../layer-utils");
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 _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; } // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
var MAX_ZOOM_LEVEL = exports.MAX_ZOOM_LEVEL = 18;
var pointPosAccessor = exports.pointPosAccessor = function pointPosAccessor(_ref) {
var lat = _ref.lat,
lng = _ref.lng;
return function (dc) {
return function (d) {
return [dc.valueAt(d.index, lng.fieldIdx), dc.valueAt(d.index, lat.fieldIdx)];
};
};
};
var geoarrowPosAccessor = exports.geoarrowPosAccessor = function geoarrowPosAccessor(_ref2) {
var geoarrow = _ref2.geoarrow;
return function (dc) {
return function (d) {
var row = dc.valueAt(d.index, geoarrow.fieldIdx);
return [row.get(0), row.get(1)];
};
};
};
var pointColResolver = exports.pointColResolver = function pointColResolver(_ref3, columnMode) {
var lat = _ref3.lat,
lng = _ref3.lng,
geoarrow = _ref3.geoarrow;
if (columnMode === COLUMN_MODE_POINTS) {
return "".concat(lat.fieldIdx, "-").concat(lng.fieldIdx);
}
return "geoarrow-".concat(geoarrow.fieldIdx);
};
var heatmapVisConfigs = exports.heatmapVisConfigs = {
opacity: 'opacity',
colorRange: 'colorRange',
radius: 'heatmapRadius'
};
var pointRequiredColumns = exports.pointRequiredColumns = ['lat', 'lng'];
var geoarrowRequiredColumns = exports.geoarrowRequiredColumns = ['geoarrow'];
var COLUMN_MODE_POINTS = exports.COLUMN_MODE_POINTS = 'points';
var COLUMN_MODE_GEOARROW = exports.COLUMN_MODE_GEOARROW = 'geoarrow';
var SUPPORTED_COLUMN_MODES = [{
key: COLUMN_MODE_POINTS,
label: 'Points',
requiredColumns: pointRequiredColumns
}, {
key: COLUMN_MODE_GEOARROW,
label: 'Geoarrow Points',
requiredColumns: geoarrowRequiredColumns
}];
var DEFAULT_COLUMN_MODE = COLUMN_MODE_POINTS;
/**
*
* @param colorRange
* @return [
* 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 colors = ['#000000'].concat((0, _toConsumableArray2["default"])(colorRange.colors));
var colorDensity = [];
colors.forEach(function (color, index) {
colorDensity.push(index / colors.length);
colorDensity.push("rgb(".concat((0, _utils.hexToRgb)(color).join(','), ")"));
});
colorDensity[1] = 'rgba(0,0,0,0)';
return colorDensity;
};
var HeatmapLayer = /*#__PURE__*/function (_MapboxGLLayer) {
function HeatmapLayer(props) {
var _this;
(0, _classCallCheck2["default"])(this, HeatmapLayer);
_this = _callSuper(this, HeatmapLayer, [props]);
(0, _defineProperty2["default"])(_this, "columnsSelector", function (config) {
return pointColResolver(config.columns, config.columnMode);
});
(0, _defineProperty2["default"])(_this, "visConfigSelector", function (config) {
return config.visConfig;
});
(0, _defineProperty2["default"])(_this, "weightFieldSelector", function (config) {
return config.weightField ? config.weightField.name : null;
});
(0, _defineProperty2["default"])(_this, "weightDomainSelector", function (config) {
return config.weightDomain;
});
(0, _defineProperty2["default"])(_this, "paintSelector", (0, _reselect.createSelector)(_this.visConfigSelector, _this.weightFieldSelector, _this.weightDomainSelector, function (visConfig, weightField, weightDomain) {
return {
'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
};
}));
(0, _defineProperty2["default"])(_this, "computeHeatmapConfiguration", (0, _reselect.createSelector)(_this.sourceSelector, _this.filterSelector, _this.paintSelector, function (source, filter, paint) {
return _objectSpread({
type: 'heatmap',
id: _this.id,
source: source,
layout: {
visibility: 'visible'
},
paint: paint
}, _this.isValidFilter(filter) ? {
filter: filter
} : {});
}));
_this.registerVisConfig(heatmapVisConfigs);
_this.getPositionAccessor = function (dataContainer) {
switch (_this.config.columnMode) {
case COLUMN_MODE_GEOARROW:
return geoarrowPosAccessor(_this.config.columns)(dataContainer);
default:
// COLUMN_MODE_POINTS
return pointPosAccessor(_this.config.columns)(dataContainer);
}
};
return _this;
}
(0, _inherits2["default"])(HeatmapLayer, _MapboxGLLayer);
return (0, _createClass2["default"])(HeatmapLayer, [{
key: "type",
get: function get() {
return 'heatmap';
}
}, {
key: "supportedColumnModes",
get: function get() {
return SUPPORTED_COLUMN_MODES;
}
}, {
key: "hasAllColumns",
value: function hasAllColumns() {
var _this$config = this.config,
columns = _this$config.columns,
columnMode = _this$config.columnMode;
if (columnMode === COLUMN_MODE_GEOARROW) {
return this.hasColumnValue(columns.geoarrow);
}
return _superPropGet(HeatmapLayer, "hasAllColumns", this, 3)([]);
}
}, {
key: "visualChannels",
get: function get() {
return {
// @ts-expect-error
weight: {
property: 'weight',
field: 'weightField',
scale: 'weightScale',
domain: 'weightDomain',
key: 'weight',
// supportedFieldTypes can be determined by channelScaleType
// or specified here
defaultMeasure: 'property.density',
supportedFieldTypes: [_constants.ALL_FIELD_TYPES.real, _constants.ALL_FIELD_TYPES.integer],
channelScaleType: _constants.CHANNEL_SCALES.size
}
};
}
}, {
key: "layerIcon",
get: function get() {
return _heatmapLayerIcon["default"];
}
}, {
key: "getVisualChannelDescription",
value: function getVisualChannelDescription(channel) {
return channel === 'color' ? {
label: 'property.color',
measure: 'property.density'
} : {
label: 'property.weight',
measure: this.config.weightField ? this.config.weightField.name : 'property.density'
};
}
}, {
key: "getDefaultLayerConfig",
value: function getDefaultLayerConfig(props) {
var _props$columnMode;
// mapbox heatmap layer color is always based on density
// no need to set colorField, colorDomain and colorScale
// eslint-disable-next-line @typescript-eslint/no-unused-vars
var _superPropGet$columnM = _objectSpread(_objectSpread({}, _superPropGet(HeatmapLayer, "getDefaultLayerConfig", this, 3)([props])), {}, {
columnMode: (_props$columnMode = props === null || props === void 0 ? void 0 : props.columnMode) !== null && _props$columnMode !== void 0 ? _props$columnMode : DEFAULT_COLUMN_MODE,
weightField: null,
weightDomain: [0, 1],
weightScale: 'linear'
}),
colorField = _superPropGet$columnM.colorField,
colorDomain = _superPropGet$columnM.colorDomain,
colorScale = _superPropGet$columnM.colorScale,
layerConfig = (0, _objectWithoutProperties2["default"])(_superPropGet$columnM, _excluded);
// @ts-expect-error
return layerConfig;
}
}, {
key: "updateLayerMeta",
value: function updateLayerMeta(dataset) {
var dataContainer = dataset.dataContainer;
var getPosition = this.getPositionAccessor(dataContainer);
var bounds = this.getPointsBounds(dataContainer, getPosition);
this.updateMeta({
bounds: bounds
});
}
}, {
key: "formatLayerData",
value: function formatLayerData(datasets, oldLayerData) {
if (this.config.dataId === null) {
return {};
}
var weightField = this.config.weightField;
var dataContainer = datasets[this.config.dataId].dataContainer;
var getPosition = this.getPositionAccessor(dataContainer);
var _this$updateData = this.updateData(datasets, oldLayerData),
data = _this$updateData.data;
// @ts-ignore
var newConfig = this.computeHeatmapConfiguration(this.config, datasets);
newConfig.id = this.id;
return {
columns: this.config.columns,
config: newConfig,
data: data,
weightField: weightField,
getPosition: getPosition
};
}
}], [{
key: "findDefaultLayerProps",
value: function findDefaultLayerProps(dataset) {
var altProps = (0, _layerUtils.getGeoArrowPointLayerProps)(dataset);
return {
props: [],
altProps: altProps
};
}
}]);
}(_mapboxglLayer["default"]);
var _default = exports["default"] = HeatmapLayer;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVzZWxlY3QiLCJyZXF1aXJlIiwiX2NvbnN0YW50cyIsIl9tYXBib3hnbExheWVyIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9oZWF0bWFwTGF5ZXJJY29uIiwiX3V0aWxzIiwiX2xheWVyVXRpbHMiLCJfZXhjbHVkZWQiLCJvd25LZXlzIiwiZSIsInIiLCJ0IiwiT2JqZWN0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsIm8iLCJmaWx0ZXIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJlbnVtZXJhYmxlIiwicHVzaCIsImFwcGx5IiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJkZWZpbmVQcm9wZXJ0eSIsIl9jYWxsU3VwZXIiLCJfZ2V0UHJvdG90eXBlT2YyIiwiX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yIiwiX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCIsIlJlZmxlY3QiLCJjb25zdHJ1Y3QiLCJjb25zdHJ1Y3RvciIsIkJvb2xlYW4iLCJwcm90b3R5cGUiLCJ2YWx1ZU9mIiwiY2FsbCIsIl9zdXBlclByb3BHZXQiLCJwIiwiX2dldDIiLCJNQVhfWk9PTV9MRVZFTCIsImV4cG9ydHMiLCJwb2ludFBvc0FjY2Vzc29yIiwiX3JlZiIsImxhdCIsImxuZyIsImRjIiwiZCIsInZhbHVlQXQiLCJpbmRleCIsImZpZWxkSWR4IiwiZ2VvYXJyb3dQb3NBY2Nlc3NvciIsIl9yZWYyIiwiZ2VvYXJyb3ciLCJyb3ciLCJnZXQiLCJwb2ludENvbFJlc29sdmVyIiwiX3JlZjMiLCJjb2x1bW5Nb2RlIiwiQ09MVU1OX01PREVfUE9JTlRTIiwiY29uY2F0IiwiaGVhdG1hcFZpc0NvbmZpZ3MiLCJvcGFjaXR5IiwiY29sb3JSYW5nZSIsInJhZGl1cyIsInBvaW50UmVxdWlyZWRDb2x1bW5zIiwiZ2VvYXJyb3dSZXF1aXJlZENvbHVtbnMiLCJDT0xVTU5fTU9ERV9HRU9BUlJPVyIsIlNVUFBPUlRFRF9DT0xVTU5fTU9ERVMiLCJrZXkiLCJsYWJlbCIsInJlcXVpcmVkQ29sdW1ucyIsIkRFRkFVTFRfQ09MVU1OX01PREUiLCJoZWF0bWFwRGVuc2l0eSIsImNvbG9ycyIsIl90b0NvbnN1bWFibGVBcnJheTIiLCJjb2xvckRlbnNpdHkiLCJjb2xvciIsImhleFRvUmdiIiwiam9pbiIsIkhlYXRtYXBMYXllciIsIl9NYXBib3hHTExheWVyIiwicHJvcHMiLCJfdGhpcyIsIl9jbGFzc0NhbGxDaGVjazIiLCJjb25maWciLCJjb2x1bW5zIiwidmlzQ29uZmlnIiwid2VpZ2h0RmllbGQiLCJuYW1lIiwid2VpZ2h0RG9tYWluIiwiY3JlYXRlU2VsZWN0b3IiLCJ2aXNDb25maWdTZWxlY3RvciIsIndlaWdodEZpZWxkU2VsZWN0b3IiLCJ3ZWlnaHREb21haW5TZWxlY3RvciIsInNvdXJjZVNlbGVjdG9yIiwiZmlsdGVyU2VsZWN0b3IiLCJwYWludFNlbGVjdG9yIiwic291cmNlIiwicGFpbnQiLCJ0eXBlIiwiaWQiLCJsYXlvdXQiLCJ2aXNpYmlsaXR5IiwiaXNWYWxpZEZpbHRlciIsInJlZ2lzdGVyVmlzQ29uZmlnIiwiZ2V0UG9zaXRpb25BY2Nlc3NvciIsImRhdGFDb250YWluZXIiLCJfaW5oZXJpdHMyIiwiX2NyZWF0ZUNsYXNzMiIsInZhbHVlIiwiaGFzQWxsQ29sdW1ucyIsIl90aGlzJGNvbmZpZyIsImhhc0NvbHVtblZhbHVlIiwid2VpZ2h0IiwicHJvcGVydHkiLCJmaWVsZCIsInNjYWxlIiwiZG9tYWluIiwiZGVmYXVsdE1lYXN1cmUiLCJzdXBwb3J0ZWRGaWVsZFR5cGVzIiwiQUxMX0ZJRUxEX1RZUEVTIiwicmVhbCIsImludGVnZXIiLCJjaGFubmVsU2NhbGVUeXBlIiwiQ0hBTk5FTF9TQ0FMRVMiLCJzaXplIiwiSGVhdG1hcExheWVySWNvbiIsImdldFZpc3VhbENoYW5uZWxEZXNjcmlwdGlvbiIsImNoYW5uZWwiLCJtZWFzdXJlIiwiZ2V0RGVmYXVsdExheWVyQ29uZmlnIiwiX3Byb3BzJGNvbHVtbk1vZGUiLCJfc3VwZXJQcm9wR2V0JGNvbHVtbk0iLCJ3ZWlnaHRTY2FsZSIsImNvbG9yRmllbGQiLCJjb2xvckRvbWFpbiIsImNvbG9yU2NhbGUiLCJsYXllckNvbmZpZyIsIl9vYmplY3RXaXRob3V0UHJvcGVydGllczIiLCJ1cGRhdGVMYXllck1ldGEiLCJkYXRhc2V0IiwiZ2V0UG9zaXRpb24iLCJib3VuZHMiLCJnZXRQb2ludHNCb3VuZHMiLCJ1cGRhdGVNZXRhIiwiZm9ybWF0TGF5ZXJEYXRhIiwiZGF0YXNldHMiLCJvbGRMYXllckRhdGEiLCJkYXRhSWQiLCJfdGhpcyR1cGRhdGVEYXRhIiwidXBkYXRlRGF0YSIsImRhdGEiLCJuZXdDb25maWciLCJjb21wdXRlSGVhdG1hcENvbmZpZ3VyYXRpb24iLCJmaW5kRGVmYXVsdExheWVyUHJvcHMiLCJhbHRQcm9wcyIsImdldEdlb0Fycm93UG9pbnRMYXllclByb3BzIiwiTWFwYm94R0xMYXllciIsIl9kZWZhdWx0Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hlYXRtYXAtbGF5ZXIvaGVhdG1hcC1sYXllci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge2NyZWF0ZVNlbGVjdG9yfSBmcm9tICdyZXNlbGVjdCc7XG5pbXBvcnQge0NIQU5ORUxfU0NBTEVTLCBBTExfRklFTERfVFlQRVN9IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcbmltcG9ydCBNYXBib3hHTExheWVyLCB7TWFwYm94TGF5ZXJHTENvbmZpZ30gZnJvbSAnLi4vbWFwYm94Z2wtbGF5ZXInO1xuaW1wb3J0IEhlYXRtYXBMYXllckljb24gZnJvbSAnLi9oZWF0bWFwLWxheWVyLWljb24nO1xuaW1wb3J0IHtMYXllckJhc2VDb25maWdQYXJ0aWFsLCBMYXllcldlaWdodENvbmZpZywgVmlzdWFsQ2hhbm5lbHN9IGZyb20gJy4uL2Jhc2UtbGF5ZXInO1xuaW1wb3J0IHtcbiAgQ29sb3JSYW5nZSxcbiAgVmlzQ29uZmlnQ29sb3JSYW5nZSxcbiAgVmlzQ29uZmlnTnVtYmVyLFxuICBIZXhDb2xvcixcbiAgTWVyZ2UsXG4gIExheWVyQ29sdW1uXG59IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuaW1wb3J0IHtoZXhUb1JnYiwgRGF0YUNvbnRhaW5lckludGVyZmFjZX0gZnJvbSAnQGtlcGxlci5nbC91dGlscyc7XG5pbXBvcnQge0tlcGxlclRhYmxlfSBmcm9tICdAa2VwbGVyLmdsL3RhYmxlJztcblxuaW1wb3J0IHtnZXRHZW9BcnJvd1BvaW50TGF5ZXJQcm9wcywgRmluZERlZmF1bHRMYXllclByb3BzUmV0dXJuVmFsdWV9IGZyb20gJy4uL2xheWVyLXV0aWxzJztcblxuZXhwb3J0IHR5cGUgSGVhdG1hcExheWVyVmlzQ29uZmlnU2V0dGluZ3MgPSB7XG4gIG9wYWNpdHk6IFZpc0NvbmZpZ051bWJlcjtcbiAgY29sb3JSYW5nZTogVmlzQ29uZmlnQ29sb3JSYW5nZTtcbiAgcmFkaXVzOiBWaXNDb25maWdOdW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBIZWF0bWFwTGF5ZXJDb2x1bW5zQ29uZmlnID0ge1xuICAvLyBDT0xVTU5fTU9ERV9QT0lOVFNcbiAgbGF0OiBMYXllckNvbHVtbjtcbiAgbG5nOiBMYXllckNvbHVtbjtcblxuICAvLyBDT0xVTU5fTU9ERV9HRU9BUlJPV1xuICBnZW9hcnJvdzogTGF5ZXJDb2x1bW47XG59O1xuXG5leHBvcnQgdHlwZSBIZWF0bWFwTGF5ZXJWaXNDb25maWcgPSB7XG4gIG9wYWNpdHk6IG51bWJlcjtcbiAgY29sb3JSYW5nZTogQ29sb3JSYW5nZTtcbiAgcmFkaXVzOiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBIZWF0bWFwTGF5ZXJWaXN1YWxDaGFubmVsQ29uZmlnID0gTGF5ZXJXZWlnaHRDb25maWc7XG5leHBvcnQgdHlwZSBIZWF0bWFwTGF5ZXJDb25maWcgPSBNZXJnZTxcbiAgTWFwYm94TGF5ZXJHTENvbmZpZyxcbiAge2NvbHVtbnM6IEhlYXRtYXBMYXllckNvbHVtbnNDb25maWc7IHZpc0NvbmZpZzogSGVhdG1hcExheWVyVmlzQ29uZmlnfVxuPiAmXG4gIEhlYXRtYXBMYXllclZpc3VhbENoYW5uZWxDb25maWc7XG5cbmV4cG9ydCBjb25zdCBNQVhfWk9PTV9MRVZFTCA9IDE4O1xuXG5leHBvcnQgY29uc3QgcG9pbnRQb3NBY2Nlc3NvciA9XG4gICh7bGF0LCBsbmd9OiBIZWF0bWFwTGF5ZXJDb2x1bW5zQ29uZmlnKSA9PlxuICAoZGM6IERhdGFDb250YWluZXJJbnRlcmZhY2UpID0+XG4gIChkOiB7aW5kZXg6IG51bWJlcn0pOiBudW1iZXJbXSA9PlxuICAgIFtkYy52YWx1ZUF0KGQuaW5kZXgsIGxuZy5maWVsZElkeCksIGRjLnZhbHVlQXQoZC5pbmRleCwgbGF0LmZpZWxkSWR4KV07XG5cbmV4cG9ydCBjb25zdCBnZW9hcnJvd1Bvc0FjY2Vzc29yID1cbiAgKHtnZW9hcnJvd306IEhlYXRtYXBMYXllckNvbHVtbnNDb25maWcpID0+XG4gIChkYzogRGF0YUNvbnRhaW5lckludGVyZmFjZSkgPT5cbiAgKGQ6IHtpbmRleDogbnVtYmVyfSk6IG51bWJlcltdID0+IHtcbiAgICBjb25zdCByb3cgPSBkYy52YWx1ZUF0KGQuaW5kZXgsIGdlb2Fycm93LmZpZWxkSWR4KTtcbiAgICByZXR1cm4gW3Jvdy5nZXQoMCksIHJvdy5nZXQoMSldO1xuICB9O1xuXG5leHBvcnQgY29uc3QgcG9pbnRDb2xSZXNvbHZlciA9ICh7bGF0LCBsbmcsIGdlb2Fycm93fTogSGVhdG1hcExheWVyQ29sdW1uc0NvbmZpZywgY29sdW1uTW9kZSkgPT4ge1xuICBpZiAoY29sdW1uTW9kZSA9PT0gQ09MVU1OX01PREVfUE9JTlRTKSB7XG4gICAgcmV0dXJuIGAke2xhdC5maWVsZElkeH0tJHtsbmcuZmllbGRJZHh9YDtcbiAgfVxuICByZXR1cm4gYGdlb2Fycm93LSR7Z2VvYXJyb3cuZmllbGRJZHh9YDtcbn07XG5cbmV4cG9ydCBjb25zdCBoZWF0bWFwVmlzQ29uZmlnczoge1xuICBvcGFjaXR5OiAnb3BhY2l0eSc7XG4gIGNvbG9yUmFuZ2U6ICdjb2xvclJhbmdlJztcbiAgcmFkaXVzOiAnaGVhdG1hcFJhZGl1cyc7XG59ID0ge1xuICBvcGFjaXR5OiAnb3BhY2l0eScsXG4gIGNvbG9yUmFuZ2U6ICdjb2xvclJhbmdlJyxcbiAgcmFkaXVzOiAnaGVhdG1hcFJhZGl1cydcbn07XG5cbmV4cG9ydCBjb25zdCBwb2ludFJlcXVpcmVkQ29sdW1ucyA9IFsnbGF0JywgJ2xuZyddO1xuZXhwb3J0IGNvbnN0IGdlb2Fycm93UmVxdWlyZWRDb2x1bW5zID0gWydnZW9hcnJvdyddO1xuXG5leHBvcnQgY29uc3QgQ09MVU1OX01PREVfUE9JTlRTID0gJ3BvaW50cyc7XG5leHBvcnQgY29uc3QgQ09MVU1OX01PREVfR0VPQVJST1cgPSAnZ2VvYXJyb3cnO1xuY29uc3QgU1VQUE9SVEVEX0NPTFVNTl9NT0RFUyA9IFtcbiAge1xuICAgIGtleTogQ09MVU1OX01PREVfUE9JTlRTLFxuICAgIGxhYmVsOiAnUG9pbnRzJyxcbiAgICByZXF1aXJlZENvbHVtbnM6IHBvaW50UmVxdWlyZWRDb2x1bW5zXG4gIH0sXG4gIHtcbiAgICBrZXk6IENPTFVNTl9NT0RFX0dFT0FSUk9XLFxuICAgIGxhYmVsOiAnR2VvYXJyb3cgUG9pbnRzJyxcbiAgICByZXF1aXJlZENvbHVtbnM6IGdlb2Fycm93UmVxdWlyZWRDb2x1bW5zXG4gIH1cbl07XG5jb25zdCBERUZBVUxUX0NPTFVNTl9NT0RFID0gQ09MVU1OX01PREVfUE9JTlRTO1xuXG4vKipcbiAqXG4gKiBAcGFyYW0gY29sb3JSYW5nZVxuICogQHJldHVybiBbXG4gKiAgMCwgXCJyZ2JhKDMzLDEwMiwxNzIsMClcIixcbiAqICAwLjIsIFwicmdiKDEwMywxNjksMjA3KVwiLFxuICogIDAuNCwgXCJyZ2IoMjA5LDIyOSwyNDApXCIsXG4gKiAgMC42LCBcInJnYigyNTMsMjE5LDE5OSlcIixcbiAqICAwLjgsIFwicmdiKDIzOSwxMzgsOTgpXCIsXG4gKiAgMSwgXCJyZ2IoMTc4LDI0LDQzKVwiXG4gKiBdXG4gKi9cbmNvbnN0IGhlYXRtYXBEZW5zaXR5ID0gKGNvbG9yUmFuZ2U6IENvbG9yUmFuZ2UpOiAoc3RyaW5nIHwgbnVtYmVyKVtdID0+IHtcbiAgY29uc3QgY29sb3JzOiBIZXhDb2xvcltdID0gWycjMDAwMDAwJywgLi4uY29sb3JSYW5nZS5jb2xvcnNdO1xuXG4gIGNvbnN0IGNvbG9yRGVuc2l0eTogKHN0cmluZyB8IG51bWJlcilbXSA9IFtdO1xuICBjb2xvcnMuZm9yRWFjaCgoY29sb3IsIGluZGV4KSA9PiB7XG4gICAgY29sb3JEZW5zaXR5LnB1c2goaW5kZXggLyBjb2xvcnMubGVuZ3RoKTtcbiAgICBjb2xvckRlbnNpdHkucHVzaChgcmdiKCR7aGV4VG9SZ2IoY29sb3IpLmpvaW4oJywnKX0pYCk7XG4gIH0pO1xuXG4gIGNvbG9yRGVuc2l0eVsxXSA9ICdyZ2JhKDAsMCwwLDApJztcbiAgcmV0dXJuIGNvbG9yRGVuc2l0eTtcbn07XG5cbmNsYXNzIEhlYXRtYXBMYXllciBleHRlbmRzIE1hcGJveEdMTGF5ZXIge1xuICBkZWNsYXJlIHZpc0NvbmZpZ1NldHRpbmdzOiBIZWF0bWFwTGF5ZXJWaXNDb25maWdTZXR0aW5ncztcbiAgZGVjbGFyZSBjb25maWc6IEhlYXRtYXBMYXllckNvbmZpZztcblxuICBjb25zdHJ1Y3Rvcihwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnJlZ2lzdGVyVmlzQ29uZmlnKGhlYXRtYXBWaXNDb25maWdzKTtcblxuICAgIHRoaXMuZ2V0UG9zaXRpb25BY2Nlc3NvciA9IChkYXRhQ29udGFpbmVyOiBEYXRhQ29udGFpbmVySW50ZXJmYWNlKSA9PiB7XG4gICAgICBzd2l0Y2ggKHRoaXMuY29uZmlnLmNvbHVtbk1vZGUpIHtcbiAgICAgICAgY2FzZSBDT0xVTU5fTU9ERV9HRU9BUlJPVzpcbiAgICAgICAgICByZXR1cm4gZ2VvYXJyb3dQb3NBY2Nlc3Nvcih0aGlzLmNvbmZpZy5jb2x1bW5zKShkYXRhQ29udGFpbmVyKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAvLyBDT0xVTU5fTU9ERV9QT0lOVFNcbiAgICAgICAgICByZXR1cm4gcG9pbnRQb3NBY2Nlc3Nvcih0aGlzLmNvbmZpZy5jb2x1bW5zKShkYXRhQ29udGFpbmVyKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgZ2V0IHR5cGUoKTogJ2hlYXRtYXAnIHtcbiAgICByZXR1cm4gJ2hlYXRtYXAnO1xuICB9XG5cbiAgZ2V0IHN1cHBvcnRlZENvbHVtbk1vZGVzKCkge1xuICAgIHJldHVybiBTVVBQT1JURURfQ09MVU1OX01PREVTO1xuICB9XG5cbiAgaGFzQWxsQ29sdW1ucygpIHtcbiAgICBjb25zdCB7Y29sdW1ucywgY29sdW1uTW9kZX0gPSB0aGlzLmNvbmZpZztcbiAgICBpZiAoY29sdW1uTW9kZSA9PT0gQ09MVU1OX01PREVfR0VPQVJST1cpIHtcbiAgICAgIHJldHVybiB0aGlzLmhhc0NvbHVtblZhbHVlKGNvbHVtbnMuZ2VvYXJyb3cpO1xuICAgIH1cbiAgICByZXR1cm4gc3VwZXIuaGFzQWxsQ29sdW1ucygpO1xuICB9XG5cbiAgc3RhdGljIGZpbmREZWZhdWx0TGF5ZXJQcm9wcyhkYXRhc2V0OiBLZXBsZXJUYWJsZSk6IEZpbmREZWZhdWx0TGF5ZXJQcm9wc1JldHVyblZhbHVlIHtcbiAgICBjb25zdCBhbHRQcm9wcyA9IGdldEdlb0Fycm93UG9pbnRMYXllclByb3BzKGRhdGFzZXQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHByb3BzOiBbXSxcbiAgICAgIGFsdFByb3BzXG4gICAgfTtcbiAgfVxuXG4gIGdldCB2aXN1YWxDaGFubmVscygpOiBWaXN1YWxDaGFubmVscyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgIHdlaWdodDoge1xuICAgICAgICBwcm9wZXJ0eTogJ3dlaWdodCcsXG4gICAgICAgIGZpZWxkOiAnd2VpZ2h0RmllbGQnLFxuICAgICAgICBzY2FsZTogJ3dlaWdodFNjYWxlJyxcbiAgICAgICAgZG9tYWluOiAnd2VpZ2h0RG9tYWluJyxcbiAgICAgICAga2V5OiAnd2VpZ2h0JyxcbiAgICAgICAgLy8gc3VwcG9ydGVkRmllbGRUeXBlcyBjYW4gYmUgZGV0ZXJtaW5lZCBieSBjaGFubmVsU2NhbGVUeXBlXG4gICAgICAgIC8vIG9yIHNwZWNpZmllZCBoZXJlXG4gICAgICAgIGRlZmF1bHRNZWFzdXJlOiAncHJvcGVydHkuZGVuc2l0eScsXG4gICAgICAgIHN1cHBvcnRlZEZpZWxkVHlwZXM6IFtBTExfRklFTERfVFlQRVMucmVhbCwgQUxMX0ZJRUxEX1RZUEVTLmludGVnZXJdLFxuICAgICAgICBjaGFubmVsU2NhbGVUeXBlOiBDSEFOTkVMX1NDQUxFUy5zaXplXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIGdldCBsYXllckljb24oKSB7XG4gICAgcmV0dXJuIEhlYXRtYXBMYXllckljb247XG4gIH1cblxuICBnZXRWaXN1YWxDaGFubmVsRGVzY3JpcHRpb24oY2hhbm5lbCkge1xuICAgIHJldHVybiBjaGFubmVsID09PSAnY29sb3InXG4gICAgICA/IHtcbiAgICAgICAgICBsYWJlbDogJ3Byb3BlcnR5LmNvbG9yJyxcbiAgICAgICAgICBtZWFzdXJlOiAncHJvcGVydHkuZGVuc2l0eSdcbiAgICAgICAgfVxuICAgICAgOiB7XG4gICAgICAgICAgbGFiZWw6ICdwcm9wZXJ0eS53ZWlnaHQnLFxuICAgICAgICAgIG1lYXN1cmU6IHRoaXMuY29uZmlnLndlaWdodEZpZWxkID8gdGhpcy5jb25maWcud2VpZ2h0RmllbGQubmFtZSA6ICdwcm9wZXJ0eS5kZW5zaXR5J1xuICAgICAgICB9O1xuICB9XG5cbiAgZ2V0RGVmYXVsdExheWVyQ29uZmlnKHByb3BzOiBMYXllckJhc2VDb25maWdQYXJ0aWFsKTogSGVhdG1hcExheWVyQ29uZmlnIHtcbiAgICAvLyBtYXBib3ggaGVhdG1hcCBsYXllciBjb2xvciBpcyBhbHdheXMgYmFzZWQgb24gZGVuc2l0eVxuICAgIC8vIG5vIG5lZWQgdG8gc2V0IGNvbG9yRmllbGQsIGNvbG9yRG9tYWluIGFuZCBjb2xvclNjYWxlXG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgY29uc3Qge2NvbG9yRmllbGQsIGNvbG9yRG9tYWluLCBjb2xvclNjYWxlLCAuLi5sYXllckNvbmZpZ30gPSB7XG4gICAgICAuLi5zdXBlci5nZXREZWZhdWx0TGF5ZXJDb25maWcocHJvcHMpLFxuICAgICAgY29sdW1uTW9kZTogcHJvcHM/LmNvbHVtbk1vZGUgPz8gREVGQVVMVF9DT0xVTU5fTU9ERSxcblxuICAgICAgd2VpZ2h0RmllbGQ6IG51bGwsXG4gICAgICB3ZWlnaHREb21haW46IFswLCAxXSxcbiAgICAgIHdlaWdodFNjYWxlOiAnbGluZWFyJ1xuICAgIH07XG5cbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgcmV0dXJuIGxheWVyQ29uZmlnO1xuICB9XG5cbiAgdXBkYXRlTGF5ZXJNZXRhKGRhdGFzZXQ6IEtlcGxlclRhYmxlKSB7XG4gICAgY29uc3Qge2RhdGFDb250YWluZXJ9ID0gZGF0YXNldDtcblxuICAgIGNvbnN0IGdldFBvc2l0aW9uID0gdGhpcy5nZXRQb3NpdGlvbkFjY2Vzc29yKGRhdGFDb250YWluZXIpO1xuICAgIGNvbnN0IGJvdW5kcyA9IHRoaXMuZ2V0UG9pbnRzQm91bmRzKGRhdGFDb250YWluZXIsIGdldFBvc2l0aW9uKTtcbiAgICB0aGlzLnVwZGF0ZU1ldGEoe2JvdW5kc30pO1xuICB9XG5cbiAgY29sdW1uc1NlbGVjdG9yID0gY29uZmlnID0+IHBvaW50Q29sUmVzb2x2ZXIoY29uZmlnLmNvbHVtbnMsIGNvbmZpZy5jb2x1bW5Nb2RlKTtcbiAgdmlzQ29uZmlnU2VsZWN0b3IgPSBjb25maWcgPT4gY29uZmlnLnZpc0NvbmZpZztcbiAgd2VpZ2h0RmllbGRTZWxlY3RvciA9IGNvbmZpZyA9PiAoY29uZmlnLndlaWdodEZpZWxkID8gY29uZmlnLndlaWdodEZpZWxkLm5hbWUgOiBudWxsKTtcbiAgd2VpZ2h0RG9tYWluU2VsZWN0b3IgPSBjb25maWcgPT4gY29uZmlnLndlaWdodERvbWFpbjtcblxuICBwYWludFNlbGVjdG9yID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy52aXNDb25maWdTZWxlY3RvcixcbiAgICB0aGlzLndlaWdodEZpZWxkU2VsZWN0b3IsXG4gICAgdGhpcy53ZWlnaHREb21haW5TZWxlY3RvcixcbiAgICAodmlzQ29uZmlnLCB3ZWlnaHRGaWVsZCwgd2VpZ2h0RG9tYWluKSA9PiAoe1xuICAgICAgJ2hlYXRtYXAtd2VpZ2h0Jzogd2VpZ2h0RmllbGRcbiAgICAgICAgPyBbJ2ludGVycG9sYXRlJywgWydsaW5lYXInXSwgWydnZXQnLCB3ZWlnaHRGaWVsZF0sIHdlaWdodERvbWFpblswXSwgMCwgd2VpZ2h0RG9tYWluWzFdLCAxXVxuICAgICAgICA6IDEsXG4gICAgICAnaGVhdG1hcC1pbnRlbnNpdHknOiBbJ2ludGVycG9sYXRlJywgWydsaW5lYXInXSwgWyd6b29tJ10sIDAsIDEsIE1BWF9aT09NX0xFVkVMLCAzXSxcbiAgICAgICdoZWF0bWFwLWNvbG9yJzogW1xuICAgICAgICAnaW50ZXJwb2xhdGUnLFxuICAgICAgICBbJ2xpbmVhciddLFxuICAgICAgICBbJ2hlYXRtYXAtZGVuc2l0eSddLFxuICAgICAgICAuLi5oZWF0bWFwRGVuc2l0eSh2aXNDb25maWcuY29sb3JSYW5nZSlcbiAgICAgIF0sXG4gICAgICAnaGVhdG1hcC1yYWRpdXMnOiBbXG4gICAgICAgICdpbnRlcnBvbGF0ZScsXG4gICAgICAgIFsnbGluZWFyJ10sXG4gICAgICAgIFsnem9vbSddLFxuICAgICAgICAwLFxuICAgICAgICAyLFxuICAgICAgICBNQVhfWk9PTV9MRVZFTCxcbiAgICAgICAgdmlzQ29uZmlnLnJhZGl1cyAvLyByYWRpdXNcbiAgICAgIF0sXG4gICAgICAnaGVhdG1hcC1vcGFjaXR5JzogdmlzQ29uZmlnLm9wYWNpdHlcbiAgICB9KVxuICApO1xuXG4gIGNvbXB1dGVIZWF0bWFwQ29uZmlndXJhdGlvbiA9IGNyZWF0ZVNlbGVjdG9yKFxuICAgIHRoaXMuc291cmNlU2VsZWN0b3IsXG4gICAgdGhpcy5maWx0ZXJTZWxlY3RvcixcbiAgICB0aGlzLnBhaW50U2VsZWN0b3IsXG4gICAgKHNvdXJjZSwgZmlsdGVyLCBwYWludCkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2hlYXRtYXAnLFxuICAgICAgICBpZDogdGhpcy5pZCxcbiAgICAgICAgc291cmNlLFxuICAgICAgICBsYXlvdXQ6IHtcbiAgICAgICAgICB2aXNpYmlsaXR5OiAndmlzaWJsZSdcbiAgICAgICAgfSxcbiAgICAgICAgcGFpbnQsXG4gICAgICAgIC4uLih0aGlzLmlzVmFsaWRGaWx0ZXIoZmlsdGVyKSA/IHtmaWx0ZXJ9IDoge30pXG4gICAgICB9O1xuICAgIH1cbiAgKTtcblxuICBmb3JtYXRMYXllckRhdGEoZGF0YXNldHMsIG9sZExheWVyRGF0YSkge1xuICAgIGlmICh0aGlzLmNvbmZpZy5kYXRhSWQgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY29uc3Qge3dlaWdodEZpZWxkfSA9IHRoaXMuY29uZmlnO1xuICAgIGNvbnN0IHtkYXRhQ29udGFpbmVyfSA9IGRhdGFzZXRzW3RoaXMuY29uZmlnLmRhdGFJZF07XG4gICAgY29uc3QgZ2V0UG9zaXRpb24gPSB0aGlzLmdldFBvc2l0aW9uQWNjZXNzb3IoZGF0YUNvbnRhaW5lcik7XG4gICAgY29uc3Qge2RhdGF9ID0gdGhpcy51cGRhdGVEYXRhKGRhdGFzZXRzLCBvbGRMYXllckRhdGEpO1xuXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IG5ld0NvbmZpZyA9IHRoaXMuY29tcHV0ZUhlYXRtYXBDb25maWd1cmF0aW9uKHRoaXMuY29uZmlnLCBkYXRhc2V0cyk7XG4gICAgbmV3Q29uZmlnLmlkID0gdGhpcy5pZDtcblxuICAgIHJldHVybiB7XG4gICAgICBjb2x1bW5zOiB0aGlzLmNvbmZpZy5jb2x1bW5zLFxuICAgICAgY29uZmlnOiBuZXdDb25maWcsXG4gICAgICBkYXRhLFxuICAgICAgd2VpZ2h0RmllbGQsXG4gICAgICBnZXRQb3NpdGlvblxuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSGVhdG1hcExheWVyO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBR0EsSUFBQUEsU0FBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsVUFBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsY0FBQSxHQUFBQyxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQUksaUJBQUEsR0FBQUQsc0JBQUEsQ0FBQUgsT0FBQTtBQVVBLElBQUFLLE1BQUEsR0FBQUwsT0FBQTtBQUdBLElBQUFNLFdBQUEsR0FBQU4sT0FBQTtBQUE0RixJQUFBTyxTQUFBO0FBQUEsU0FBQUMsUUFBQUMsQ0FBQSxFQUFBQyxDQUFBLFFBQUFDLENBQUEsR0FBQUMsTUFBQSxDQUFBQyxJQUFBLENBQUFKLENBQUEsT0FBQUcsTUFBQSxDQUFBRSxxQkFBQSxRQUFBQyxDQUFBLEdBQUFILE1BQUEsQ0FBQUUscUJBQUEsQ0FBQUwsQ0FBQSxHQUFBQyxDQUFBLEtBQUFLLENBQUEsR0FBQUEsQ0FBQSxDQUFBQyxNQUFBLFdBQUFOLENBQUEsV0FBQUUsTUFBQSxDQUFBSyx3QkFBQSxDQUFBUixDQUFBLEVBQUFDLENBQUEsRUFBQVEsVUFBQSxPQUFBUCxDQUFBLENBQUFRLElBQUEsQ0FBQUMsS0FBQSxDQUFBVCxDQUFBLEVBQUFJLENBQUEsWUFBQUosQ0FBQTtBQUFBLFNBQUFVLGNBQUFaLENBQUEsYUFBQUMsQ0FBQSxNQUFBQSxDQUFB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
;