kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
881 lines (859 loc) • 121 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getNumRasterTilesBeingLoaded = exports["default"] = exports.LOAD_ELEVATION_AFTER_ZOOM = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
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 _typed = require("@deck.gl/core/typed");
var _typed2 = require("@deck.gl/geo-layers/typed");
var _pmtiles = require("@loaders.gl/pmtiles");
var _memoize = _interopRequireDefault(require("lodash/memoize"));
var _typed3 = require("@deck.gl/layers/typed");
var _constants = require("@kepler.gl/constants");
var _deckglLayers = require("@kepler.gl/deckgl-layers");
var _commonUtils = require("@kepler.gl/common-utils");
var _utils = require("@kepler.gl/utils");
var _config = require("./config");
var _gpuUtils = require("./gpu-utils");
var _image = require("./image");
var _rasterTileIcon = _interopRequireDefault(require("./raster-tile-icon"));
var _rasterTileUtils = require("./raster-tile-utils");
var _baseLayer = _interopRequireDefault(require("../base-layer"));
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
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
// Adjust tileSize to devicePixelRatio, but not higher than 2 to reduce requests to server
var devicePixelRatio = Math.min(2, typeof window !== 'undefined' && window.devicePixelRatio || 1);
// Global counter that represents the number of tiles currently being loaded across all the raster tile layers
var tilesBeingLoaded = 0;
// This is a temp solution to track loading
var getNumRasterTilesBeingLoaded = exports.getNumRasterTilesBeingLoaded = function getNumRasterTilesBeingLoaded() {
return tilesBeingLoaded;
};
var LOAD_ELEVATION_AFTER_ZOOM = exports.LOAD_ELEVATION_AFTER_ZOOM = 8.9;
var getShouldLoadTerrain = function getShouldLoadTerrain(stac, mapState, visConfig) {
var _stac$rasterTileServe;
return Boolean(
// we need a raster tile server for elevations even when we user PMTiles
((_stac$rasterTileServe = stac.rasterTileServerUrls) === null || _stac$rasterTileServe === void 0 ? void 0 : _stac$rasterTileServe.length) > 0 &&
// check the switch from the layer configurator
visConfig.enableTerrain && (
// disabled in Top view by default
mapState.dragRotate || visConfig.enableTerrainTopView) && (0, _utils.getApplicationConfig)().rasterServerSupportsElevation);
};
var RasterTileLayer = exports["default"] = /*#__PURE__*/function (_KeplerLayer) {
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function RasterTileLayer(props) {
var _this;
(0, _classCallCheck2["default"])(this, RasterTileLayer);
_this = _callSuper(this, RasterTileLayer, [props]);
/** Min bands image data value, based on the current viewport */
(0, _defineProperty2["default"])(_this, "minViewportPixelValue", Infinity);
/** Max bands image data value, based on the current viewport */
(0, _defineProperty2["default"])(_this, "maxViewportPixelValue", -Infinity);
/** Memoized method that calculates data source params */
(0, _defineProperty2["default"])(_this, "getDataSourceParams", void 0);
_this.registerVisConfig(_config.rasterVisConfigs);
// No two STAC ids may be the same within a single collection, though it's conceivably possible
// across multiple STAC collections there could be an id collision. Note: STAC Collection
// objects don't have a `collection` key; STAC Item objects have a `collection` key (which
// matches the collection's `id`).
var resolver = function resolver(stac, preset, presetOptions) {
var _presetOptions$single, _presetOptions$single2;
return "".concat(stac.id, "-").concat(stac.collection, "-").concat(preset, "-").concat((_presetOptions$single = presetOptions.singleBand) === null || _presetOptions$single === void 0 ? void 0 : _presetOptions$single.assetId, "-").concat((_presetOptions$single2 = presetOptions.singleBand) === null || _presetOptions$single2 === void 0 ? void 0 : _presetOptions$single2.bandIndex);
};
_this.getDataSourceParams = (0, _memoize["default"])(function (stac, preset, presetOptions) {
return (0, _rasterTileUtils.getDataSourceParams)(stac, preset, presetOptions);
}, resolver);
_this.meta = {
zRange: null
};
return _this;
}
(0, _inherits2["default"])(RasterTileLayer, _KeplerLayer);
return (0, _createClass2["default"])(RasterTileLayer, [{
key: "type",
get: function get() {
return _constants.LAYER_TYPES.rasterTile;
}
}, {
key: "name",
get: function get() {
return 'Raster Tile';
}
}, {
key: "layerIcon",
get: function get() {
return _rasterTileIcon["default"];
}
}, {
key: "supportedDatasetTypes",
get: function get() {
return [_constants.DatasetType.RASTER_TILE];
}
}, {
key: "visualChannels",
get: function get() {
var categoricalColorLegends = this.config.visConfig.colorRange.colorLegends;
if (categoricalColorLegends) {
return {
color: _superPropGet(RasterTileLayer, "visualChannels", this, 1).color
};
} else {
return {};
}
}
}, {
key: "requireData",
get: function get() {
return true;
}
}, {
key: "getDefaultLayerConfig",
value: function getDefaultLayerConfig(props) {
return _objectSpread(_objectSpread({}, _superPropGet(RasterTileLayer, "getDefaultLayerConfig", this, 3)([props])), {}, {
colorField: {
analyzerType: '',
name: 'Category',
format: '',
type: 'string',
fieldIdx: -1,
valueAccessor: function valueAccessor() {
return '';
},
displayName: 'Category'
}
});
}
}, {
key: "getHoverData",
value: function getHoverData() {
return null;
}
// We can render without columns, so we redefine this method
}, {
key: "shouldRenderLayer",
value: function shouldRenderLayer() {
return Boolean(this.type && this.config.isVisible);
}
}, {
key: "formatLayerData",
value: function formatLayerData(datasets, oldLayerData) {
var _dataset$metadata;
var dataId = this.config.dataId;
if (!(0, _commonUtils.notNullorUndefined)(dataId)) {
return {};
}
var dataset = datasets[dataId];
// call updateData to updateLayerMeta
var dataUpdateTriggers = this.getDataUpdateTriggers(dataset);
var triggerChanged = this.getChangedTriggers(dataUpdateTriggers);
if (triggerChanged && triggerChanged.getMeta) {
this.updateLayerMeta(dataset);
}
var tileSource = null;
if (((_dataset$metadata = dataset.metadata) === null || _dataset$metadata === void 0 ? void 0 : _dataset$metadata.pmtilesType) === _constants.PMTilesType.RASTER) {
var metadataUrl = dataset.metadata.metadataUrl;
// use the old tile source if it exists and matches the new metadataUrl
var _ref = oldLayerData || {},
oldDataset = _ref.dataset,
oldTileSource = _ref.tileSource;
if (oldDataset === dataset && (oldTileSource === null || oldTileSource === void 0 ? void 0 : oldTileSource.data) === metadataUrl) {
tileSource = oldLayerData.tileSource;
} else {
tileSource = metadataUrl ? _pmtiles.PMTilesSource.createDataSource(metadataUrl, {}) : null;
}
}
return {
dataset: dataset,
tileSource: tileSource
};
}
}, {
key: "updateLayerMeta",
value: function updateLayerMeta(dataset) {
if (dataset.type !== _constants.DatasetType.RASTER_TILE) {
return;
}
var stac = dataset.metadata;
if (stac.pmtilesType === _constants.PMTilesType.RASTER) {
return this.updateMeta({
bounds: stac.bounds
});
}
var bounds = (0, _rasterTileUtils.getSTACBounds)(stac);
if (bounds) {
// If a STAC Item (i.e. stac.type === 'Feature'), then set map bounds.
// But we don't want to set bounds for Landsat or Sentinel because it would zoom out to zoom
// 0, and we don't have low-zoom tiles.
if (stac.type === 'Feature') {
this.updateMeta({
bounds: bounds
});
}
}
}
/**
* Run when adding a new dataset
*/
}, {
key: "setInitialLayerConfig",
value: function setInitialLayerConfig(dataset) {
var stac = dataset === null || dataset === void 0 ? void 0 : dataset.metadata;
if (!stac) {
return this;
}
if (stac.pmtilesType === _constants.PMTilesType.RASTER) {
return this;
}
// When a STAC Collection is added, useStacSearching should be true to prevent a black screen
this.updateLayerVisConfig({
useSTACSearching: stac.type === 'Collection'
});
// Set singleBandName if there is only one band
var availableBands = (0, _rasterTileUtils.getEOBands)(stac) || [];
if ((availableBands === null || availableBands === void 0 ? void 0 : availableBands.length) === 1) {
this.updateLayerVisConfig({
singleBandName: availableBands[0].name
});
}
// Change the preset if the default one is not allowed
var availablePresets = (0, _rasterTileUtils.filterAvailablePresets)(stac, _config.PRESET_OPTIONS);
if (availablePresets !== null && availablePresets !== void 0 && availablePresets.length && !(availablePresets !== null && availablePresets !== void 0 && availablePresets.includes(this.visConfigSettings.preset.defaultValue))) {
this.updateLayerVisConfig({
preset: availablePresets[0]
});
}
// Apply improved image processing props only for non single band modes
var preset = this.config.visConfig.preset;
var colorDefaults = _config.DATA_SOURCE_COLOR_DEFAULTS[stac.id];
if (colorDefaults && preset !== 'singleBand') {
this.updateLayerVisConfig(colorDefaults);
}
/*
LandSat specifies temporal bounds but the valid data is after end date
const updatedDates = timeRangeToStacTemporalInterval(
stac as StacTypes.STACCollection,
this.config.visConfig.startDate,
this.config.visConfig.endDate
);
this.updateLayerVisConfig(updatedDates);
*/
return this;
}
/**
* Update zRange of viewport. This is necessary so that tiles in extruded mode are shown properly
* at high elevations: https://github.com/foursquare/studio-monorepo/pull/1892/files
* Derived from https://github.com/visgl/deck.gl/blob/8d824a4b836fee3bfebe6fc962e0f03d8c1dbd0d/modules/geo-layers/src/terrain-layer/terrain-layer.js#L173-L196
*
* @param tiles Array of tiles in current viewport
*/
}, {
key: "onViewportLoad",
value: function onViewportLoad(tiles) {
this.updateMinMaxPixelValue(tiles);
var newZRange = (0, _rasterTileUtils.computeZRange)(tiles);
if (!newZRange) {
return;
}
var zRange = this.meta.zRange;
if (!zRange || newZRange[0] < zRange[0] || newZRange[1] > zRange[1]) {
this.meta.zRange = newZRange;
}
}
/**
* Update viewport-related minPxelValue and maxPixelValue
* @param tiles - deck.gl tiles
*/
}, {
key: "updateMinMaxPixelValue",
value: function updateMinMaxPixelValue(tiles) {
var _getMinMaxFromTile2DH = (0, _rasterTileUtils.getMinMaxFromTile2DHeaders)(tiles),
_getMinMaxFromTile2DH2 = (0, _slicedToArray2["default"])(_getMinMaxFromTile2DH, 2),
min = _getMinMaxFromTile2DH2[0],
max = _getMinMaxFromTile2DH2[1];
this.minViewportPixelValue = min;
this.maxViewportPixelValue = max;
}
/**
* Calculate min and max values of input raster band image properties
* and update `minBandsValue` and `maxBandsValue`
* @param images - raster band image properties
* @return [min, max] pixel values for the tile
*/
}, {
key: "getMinMaxPixelValues",
value: function getMinMaxPixelValues(images) {
var minPixelValue = Infinity;
var maxPixelValue = -Infinity;
if (images) {
var _iterator = _createForOfIteratorHelper(images),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var image = _step.value;
var _getImageMinMax = (0, _rasterTileUtils.getImageMinMax)(image.data),
_getImageMinMax2 = (0, _slicedToArray2["default"])(_getImageMinMax, 2),
min = _getImageMinMax2[0],
max = _getImageMinMax2[1];
if (typeof min === 'number') {
minPixelValue = Math.min(min, minPixelValue);
}
if (typeof max === 'number') {
maxPixelValue = Math.max(max, maxPixelValue);
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
return [minPixelValue, maxPixelValue];
}
// generate a deck layer
}, {
key: "renderLayer",
value: function renderLayer(opts) {
var _data$dataset;
var data = opts.data;
if ((data === null || data === void 0 || (_data$dataset = data.dataset) === null || _data$dataset === void 0 || (_data$dataset = _data$dataset.metadata) === null || _data$dataset === void 0 ? void 0 : _data$dataset.pmtilesType) === _constants.PMTilesType.RASTER) {
return this.renderPMTilesLayer(opts);
}
return this.renderStacLayer(opts);
}
}, {
key: "renderStacLayer",
value: function renderStacLayer(opts) {
var _data$dataset2,
_this2 = this;
var data = opts.data,
mapState = opts.mapState,
experimentalContext = opts.experimentalContext;
var stac = data === null || data === void 0 || (_data$dataset2 = data.dataset) === null || _data$dataset2 === void 0 ? void 0 : _data$dataset2.metadata;
// If a tabular dataset is loaded, and then the layer type is switched from Point to Raster Tile
// layer, this `stac` object will exist but will not be raster metadata
if (!stac || !stac.stac_version) {
return [];
}
var visConfig = this.config.visConfig;
var _this$getDefaultDeckL = this.getDefaultDeckLayerProps(opts),
id = _this$getDefaultDeckL.id,
opacity = _this$getDefaultDeckL.opacity,
visible = _this$getDefaultDeckL.visible;
var hasShadowEffect = experimentalContext === null || experimentalContext === void 0 ? void 0 : experimentalContext.hasShadowEffect;
var preset = visConfig.preset,
colormapId = visConfig.colormapId,
linearRescaling = visConfig.linearRescaling,
linearRescalingFactor = visConfig.linearRescalingFactor,
nonLinearRescaling = visConfig.nonLinearRescaling,
gammaContrastFactor = visConfig.gammaContrastFactor,
sigmoidalContrastFactor = visConfig.sigmoidalContrastFactor,
sigmoidalBiasFactor = visConfig.sigmoidalBiasFactor,
saturationValue = visConfig.saturationValue,
filterEnabled = visConfig.filterEnabled,
filterRange = visConfig.filterRange,
useSTACSearching = visConfig.useSTACSearching,
stacSearchProvider = visConfig.stacSearchProvider,
startDate = visConfig.startDate,
endDate = visConfig.endDate,
_stacQuery = visConfig._stacQuery,
singleBandName = visConfig.singleBandName,
categoricalColorMap = visConfig.colorRange.colorMap,
dynamicColor = visConfig.dynamicColor;
var shouldLoadTerrain = getShouldLoadTerrain(stac, mapState, visConfig);
if (new Date(endDate) < new Date(startDate)) {
return [];
}
var bandCombination = _config.PRESET_OPTIONS[preset].bandCombination;
var singleBand = (0, _rasterTileUtils.getSingleBandPresetOptions)(stac, singleBandName);
var dataSourceParams = this.getDataSourceParams(stac, preset, {
singleBand: singleBand
});
if (!dataSourceParams) {
return [];
}
var minZoom = dataSourceParams.minZoom,
maxZoom = dataSourceParams.maxZoom,
globalBounds = dataSourceParams.globalBounds,
loadAssetIds = dataSourceParams.loadAssetIds,
loadBandIndexes = dataSourceParams.loadBandIndexes,
renderBandIndexes = dataSourceParams.renderBandIndexes,
dataType = dataSourceParams.dataType,
dsMinPixelValue = dataSourceParams.minPixelValue,
dsMaxPixelValue = dataSourceParams.maxPixelValue,
minCategoricalBandValue = dataSourceParams.minCategoricalBandValue,
maxCategoricalBandValue = dataSourceParams.maxCategoricalBandValue;
var minPixelValue = !dynamicColor && Number.isFinite(dsMinPixelValue) ? dsMinPixelValue : this.minViewportPixelValue;
var maxPixelValue = !dynamicColor && Number.isFinite(dsMaxPixelValue) ? dsMaxPixelValue : this.maxViewportPixelValue;
var getTileDataCustomProps = {
stac: stac,
loadAssetIds: loadAssetIds,
loadBandIndexes: loadBandIndexes,
colormapId: colormapId,
shouldLoadTerrain: shouldLoadTerrain,
globalBounds: globalBounds,
useSTACSearching: useSTACSearching,
stacSearchProvider: stacSearchProvider,
startDate: startDate,
endDate: endDate,
_stacQuery: _stacQuery,
categoricalColorMap: categoricalColorMap,
minCategoricalBandValue: minCategoricalBandValue,
maxCategoricalBandValue: maxCategoricalBandValue
};
var tileLayer = new _typed2.TileLayer(_objectSpread(_objectSpread({
id: id,
minZoom: minZoom,
maxZoom: maxZoom,
tileSize: 512 / devicePixelRatio,
getTileData: function getTileData(args) {
return _this2.getTileData(_objectSpread(_objectSpread({}, args), getTileDataCustomProps));
},
onViewportLoad: this.onViewportLoad.bind(this),
// @ts-expect-error - TS doesn't know we'll pass appropriate props here
renderSubLayers: renderSubLayersStac,
maxRequests: (0, _rasterTileUtils.getMaxRequests)(stac.rasterTileServerUrls || []),
// Passing visible on to TileLayer is necessary for split view to work
visible: visible,
updateTriggers: {
getTileData: [shouldLoadTerrain,
// Colormap has changed
colormapId].concat((0, _toConsumableArray2["default"])(loadAssetIds), (0, _toConsumableArray2["default"])(loadBandIndexes), [useSTACSearching, stacSearchProvider, startDate, endDate, _stacQuery, categoricalColorMap, minCategoricalBandValue, maxCategoricalBandValue])
}
}, shouldLoadTerrain ? {
zRange: this.meta.zRange || null,
refinementStrategy: 'no-overlap'
} : {}), {}, {
renderBandIndexes: renderBandIndexes,
opacity: opacity,
linearRescaling: linearRescaling,
linearRescalingFactor: linearRescalingFactor,
nonLinearRescaling: nonLinearRescaling,
minPixelValue: minPixelValue,
maxPixelValue: maxPixelValue,
gammaContrastFactor: gammaContrastFactor,
sigmoidalContrastFactor: sigmoidalContrastFactor,
sigmoidalBiasFactor: sigmoidalBiasFactor,
saturationValue: saturationValue,
bandCombination: bandCombination,
filterEnabled: filterEnabled,
filterRange: filterRange,
dataType: dataType,
minCategoricalBandValue: minCategoricalBandValue,
maxCategoricalBandValue: maxCategoricalBandValue,
hasCategoricalColorMap: Boolean(categoricalColorMap),
hasShadowEffect: hasShadowEffect
}));
return [tileLayer];
}
}, {
key: "renderPMTilesLayer",
value: function renderPMTilesLayer(opts) {
var _data$dataset3,
_this3 = this;
var _this$getDefaultDeckL2 = this.getDefaultDeckLayerProps(opts),
id = _this$getDefaultDeckL2.id,
opacity = _this$getDefaultDeckL2.opacity,
visible = _this$getDefaultDeckL2.visible;
var data = opts.data,
mapState = opts.mapState;
var metadata = data === null || data === void 0 || (_data$dataset3 = data.dataset) === null || _data$dataset3 === void 0 ? void 0 : _data$dataset3.metadata;
var visConfig = this.config.visConfig;
var tileSource = data.tileSource;
var showTileBorders = false;
var minZoom = metadata.minZoom || 0;
var maxZoom = metadata.maxZoom || 30;
var shouldLoadTerrain = getShouldLoadTerrain(metadata, mapState, visConfig);
return [new _typed2.TileLayer(_objectSpread({
id: id,
getTileData: function getTileData(args) {
return _this3.getTileDataPMTiles(_objectSpread(_objectSpread({}, args), {}, {
shouldLoadTerrain: shouldLoadTerrain,
metadata: metadata
}), tileSource);
},
// Assume the pmtiles file support HTTP/2, so we aren't limited by the browser to a certain number per domain.
maxRequests: 20,
pickable: true,
autoHighlight: showTileBorders,
onViewportLoad: this.onViewportLoad.bind(this),
minZoom: minZoom,
maxZoom: maxZoom,
tileSize: 512 / devicePixelRatio,
zoomOffset: devicePixelRatio === 1 ? -1 : 0,
// @ts-expect-error - TS doesn't know we'll pass appropriate props here
renderSubLayers: renderSubLayersPMTiles,
tileSource: tileSource,
showTileBorders: showTileBorders,
visible: visible,
opacity: opacity,
updateTriggers: {
getTileData: [shouldLoadTerrain]
}
}, shouldLoadTerrain ? {
zRange: this.meta.zRange || null,
refinementStrategy: 'no-overlap'
} : {}))];
}
}, {
key: "getTileData",
value: function () {
var _getTileData = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(props) {
var shouldLoadTerrain, globalBounds, _props$bbox, west, south, east, north, zoom, assetRequests, terrain, _yield$Promise$all, _yield$Promise$all2, images, _terrain, _this$getMinMaxPixelV, _this$getMinMaxPixelV2, min, max;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
shouldLoadTerrain = props.shouldLoadTerrain, globalBounds = props.globalBounds, _props$bbox = props.bbox, west = _props$bbox.west, south = _props$bbox.south, east = _props$bbox.east, north = _props$bbox.north, zoom = props.index.z;
if (!(globalBounds && !(0, _rasterTileUtils.bboxIntersects)(globalBounds, [west, south, east, north]))) {
_context.next = 3;
break;
}
return _context.abrupt("return", null);
case 3:
_context.next = 5;
return (0, _image.getSTACImageRequests)(props);
case 5:
assetRequests = _context.sent;
if (assetRequests) {
_context.next = 14;
break;
}
_context.t0 = shouldLoadTerrain && LOAD_ELEVATION_AFTER_ZOOM < zoom;
if (!_context.t0) {
_context.next = 12;
break;
}
_context.next = 11;
return (0, _image.loadTerrain)({
boundsForGeometry: [west, north, east, south],
index: props.index,
signal: props.signal,
rasterTileServerUrls: props.stac.rasterTileServerUrls || []
});
case 11:
_context.t0 = _context.sent;
case 12:
terrain = _context.t0;
return _context.abrupt("return", _objectSpread({
images: null
}, terrain ? {
terrain: terrain
} : {}));
case 14:
tilesBeingLoaded++;
// Wrap loading images into a try/catch because tiles that are only briefly in view will be
// aborted. The `AbortController.abort()` creates a DOMException error.
// Note that since loading is async, try/catch will only work when awaited inside the try block
_context.prev = 15;
_context.next = 18;
return Promise.all([(0, _image.loadImages)(assetRequests, props.colormapId, {
colorMap: props.categoricalColorMap,
minValue: props.minCategoricalBandValue,
maxValue: props.maxCategoricalBandValue
}), shouldLoadTerrain && LOAD_ELEVATION_AFTER_ZOOM < zoom ? (0, _image.loadTerrain)({
boundsForGeometry: [west, north, east, south],
index: props.index,
signal: props.signal,
rasterTileServerUrls: props.stac.rasterTileServerUrls || []
}) : null]);
case 18:
_yield$Promise$all = _context.sent;
_yield$Promise$all2 = (0, _slicedToArray2["default"])(_yield$Promise$all, 2);
images = _yield$Promise$all2[0];
_terrain = _yield$Promise$all2[1];
_this$getMinMaxPixelV = this.getMinMaxPixelValues(images.imageBands), _this$getMinMaxPixelV2 = (0, _slicedToArray2["default"])(_this$getMinMaxPixelV, 2), min = _this$getMinMaxPixelV2[0], max = _this$getMinMaxPixelV2[1];
tilesBeingLoaded--;
// Add terrain data only if we requested it above
return _context.abrupt("return", _objectSpread(_objectSpread({
images: images
}, _terrain ? {
terrain: _terrain
} : {}), {}, {
minPixelValue: min,
maxPixelValue: max
}));
case 27:
_context.prev = 27;
_context.t1 = _context["catch"](15);
tilesBeingLoaded--;
if (!(_context.t1.name === 'AbortError')) {
_context.next = 32;
break;
}
return _context.abrupt("return", null);
case 32:
throw _context.t1;
case 33:
case "end":
return _context.stop();
}
}, _callee, this, [[15, 27]]);
}));
function getTileData(_x) {
return _getTileData.apply(this, arguments);
}
return getTileData;
}()
}, {
key: "getTileDataPMTiles",
value: function () {
var _getTileDataPMTiles = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(props, tileSource) {
var shouldLoadTerrain, globalBounds, _props$bbox2, west, south, east, north, zoom, metadata, _yield$Promise$all3, _yield$Promise$all4, image, terrain, minPixelValue, maxPixelValue, _this$getMinMaxPixelV3, _this$getMinMaxPixelV4, min, max;
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
shouldLoadTerrain = props.shouldLoadTerrain, globalBounds = props.globalBounds, _props$bbox2 = props.bbox, west = _props$bbox2.west, south = _props$bbox2.south, east = _props$bbox2.east, north = _props$bbox2.north, zoom = props.index.z, metadata = props.metadata;
if (!(globalBounds && !(0, _rasterTileUtils.bboxIntersects)(globalBounds, [west, south, east, north]))) {
_context2.next = 3;
break;
}
return _context2.abrupt("return", null);
case 3:
tilesBeingLoaded++;
_context2.prev = 4;
_context2.next = 7;
return Promise.all([tileSource.getTileData(props)]);
case 7:
_yield$Promise$all3 = _context2.sent;
_yield$Promise$all4 = (0, _slicedToArray2["default"])(_yield$Promise$all3, 1);
image = _yield$Promise$all4[0];
if (!(image && shouldLoadTerrain && LOAD_ELEVATION_AFTER_ZOOM < zoom)) {
_context2.next = 16;
break;
}
_context2.next = 13;
return (0, _image.loadTerrain)({
boundsForGeometry: [west, north, east, south],
index: props.index,
signal: props.signal,
rasterTileServerUrls: metadata.rasterTileServerUrls
});
case 13:
_context2.t0 = _context2.sent;
_context2.next = 17;
break;
case 16:
_context2.t0 = null;
case 17:
terrain = _context2.t0;
minPixelValue = null;
maxPixelValue = null;
if (image) {
_this$getMinMaxPixelV3 = this.getMinMaxPixelValues([{
data: image
}]), _this$getMinMaxPixelV4 = (0, _slicedToArray2["default"])(_this$getMinMaxPixelV3, 2), min = _this$getMinMaxPixelV4[0], max = _this$getMinMaxPixelV4[1];
minPixelValue = min;
maxPixelValue = max;
}
tilesBeingLoaded--;
// Add terrain data only if we requested it above
return _context2.abrupt("return", _objectSpread({
image: image,
minPixelValue: minPixelValue,
maxPixelValue: maxPixelValue
}, terrain ? {
terrain: terrain
} : {}));
case 25:
_context2.prev = 25;
_context2.t1 = _context2["catch"](4);
tilesBeingLoaded--;
if (!(_context2.t1.name === 'AbortError')) {
_context2.next = 30;
break;
}
return _context2.abrupt("return", null);
case 30:
throw _context2.t1;
case 31:
case "end":
return _context2.stop();
}
}, _callee2, this, [[4, 25]]);
}));
function getTileDataPMTiles(_x2, _x3) {
return _getTileDataPMTiles.apply(this, arguments);
}
return getTileDataPMTiles;
}()
}], [{
key: "findDefaultLayerProps",
value: function findDefaultLayerProps(dataset) {
if (dataset.type !== _constants.DatasetType.RASTER_TILE) {
return {
props: []
};
}
var newLayerProp = {
dataId: dataset.id,
label: dataset.label,
isVisible: true
};
return {
props: [newLayerProp]
};
}
}]);
}(_baseLayer["default"]);
function renderSubLayersStac(props) {
var tile = props.tile,
data = props.data,
globalMinPixelValue = props.minPixelValue,
globalMaxPixelValue = props.maxPixelValue;
var bbox = tile.bbox;
var west = bbox.west,
south = bbox.south,
east = bbox.east,
north = bbox.north;
if (!data) {
return [];
}
var images = data.images,
terrain = data.terrain,
tileMinPixelValue = data.minPixelValue,
tileMaxPixelValue = data.maxPixelValue;
if (!images || Array.isArray(images) && images.length === 0) {
return [];
}
var minPixelValue = Number.isFinite(globalMinPixelValue) ? globalMinPixelValue : tileMinPixelValue;
var maxPixelValue = Number.isFinite(globalMaxPixelValue) ? globalMaxPixelValue : tileMaxPixelValue;
if (typeof minPixelValue !== 'number' || typeof maxPixelValue !== 'number') {
return [];
}
var _getModules = (0, _gpuUtils.getModules)({
images: images,
props: _objectSpread(_objectSpread({}, props), {}, {
minPixelValue: minPixelValue,
maxPixelValue: maxPixelValue
})
}),
modules = _getModules.modules,
moduleProps = _getModules.moduleProps;
var idSuffix = props.hasShadowEffect ? 'shadow' : '';
return terrain ? new _deckglLayers.RasterMeshLayer(props, {
id: "raster-3d-layer-".concat(props.id, "-").concat(idSuffix),
// Dummy data
data: [1],
mesh: terrain,
images: images,
modules: modules,
moduleProps: moduleProps,
getPolygonOffset: null,
coordinateSystem: _typed.COORDINATE_SYSTEM.LNGLAT,
// Color to use if surfaceImage is unavailable
getColor: [255, 255, 255]
// material: false
}) : new _deckglLayers.RasterLayer(props, {
id: "raster-2d-layer-".concat(props.id, "-").concat(idSuffix),
images: images,
modules: modules,
moduleProps: moduleProps,
bounds: [west, south, east, north],
_imageCoordinateSystem: _typed.COORDINATE_SYSTEM.CARTESIAN
});
}
function renderSubLayersPMTiles(props) {
var _props$data;
var tileSource = props.tileSource,
showTileBorders = props.showTileBorders,
minZoom = props.minZoom,
maxZoom = props.maxZoom,
_props$tile = props.tile,
zoom = _props$tile.index.z,
_props$tile$bbox = _props$tile.bbox,
west = _props$tile$bbox.west,
south = _props$tile$bbox.south,
east = _props$tile$bbox.east,
north = _props$tile$bbox.north;
var layers = [];
if ((_props$data = props.data) !== null && _props$data !== void 0 && _props$data.image) {
switch (tileSource.mimeType) {
case 'image/png':
case 'image/jpeg':
case 'image/webp':
case 'image/avif':
layers.push(getRasterLayerPMTiles(props));
break;
default:
break;
}
}
// Debug tile borders
var borderColor = zoom <= minZoom || zoom >= maxZoom ? [255, 0, 0, 255] : [0, 0, 255, 255];
if (showTileBorders) {
layers.push(new _typed3.PathLayer({
id: "".concat(props.id, "-border"),
data: [[[west, north], [west, south], [east, south], [east, north], [west, north]]],
getPath: function getPath(d) {
return d;
},
getColor: borderColor,
widthMinPixels: 4
}));
}
return layers;
}
function getRasterLayerPMTiles(props) {
var tile = props.tile,
data = props.data;
var bbox = tile.bbox;
var west = bbox.west,
south = bbox.south,
east = bbox.east,
north = bbox.north;
if (!(data !== null && data !== void 0 && data.image)) {
return [];
}
var images = {
imageRgba: {
data: data.image
}
};
var terrain = data.terrain;
var _getModules2 = (0, _gpuUtils.getModules)({
images: images
}),
modules = _getModules2.modules,
moduleProps = _getModules2.moduleProps;
return terrain ? new _deckglLayers.RasterMeshLayer(props, {
id: "raster-3d-layer-".concat(props.id),
// Dummy data
data: [1],
mesh: terrain,
images: images,
modules: modules,
moduleProps: moduleProps,
getPolygonOffset: null,
coordinateSystem: _typed.COORDINATE_SYSTEM.LNGLAT,
// Color to use if surfaceImage is unavailable
getColor: [255, 255, 255]
// material: false
}) : new _deckglLayers.RasterLayer(props, {
id: "raster-2d-layer-".concat(props.id),
data: null,
images: images,
modules: modules,
moduleProps: moduleProps,
bounds: [west, south, east, north],
_imageCoordinateSystem: _typed.COORDINATE_SYSTEM.CARTESIAN
});
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdHlwZWQiLCJyZXF1aXJlIiwiX3R5cGVkMiIsIl9wbXRpbGVzIiwiX21lbW9pemUiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX3R5cGVkMyIsIl9jb25zdGFudHMiLCJfZGVja2dsTGF5ZXJzIiwiX2NvbW1vblV0aWxzIiwiX3V0aWxzIiwiX2NvbmZpZyIsIl9ncHVVdGlscyIsIl9pbWFnZSIsIl9yYXN0ZXJUaWxlSWNvbiIsIl9yYXN0ZXJUaWxlVXRpbHMiLCJfYmFzZUxheWVyIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJyIiwiZSIsInQiLCJTeW1ib2wiLCJpdGVyYXRvciIsIkFycmF5IiwiaXNBcnJheSIsIl91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSIsImxlbmd0aCIsIl9uIiwiRiIsInMiLCJuIiwiZG9uZSIsInZhbHVlIiwiZiIsIlR5cGVFcnJvciIsIm8iLCJhIiwidSIsImNhbGwiLCJuZXh0IiwiX2FycmF5TGlrZVRvQXJyYXkiLCJ0b1N0cmluZyIsInNsaWNlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiZnJvbSIsInRlc3QiLCJvd25LZXlzIiwiT2JqZWN0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiX2NhbGxTdXBlciIsIl9nZXRQcm90b3R5cGVPZjIiLCJfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjIiLCJfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0IiwiUmVmbGVjdCIsImNvbnN0cnVjdCIsIkJvb2xlYW4iLCJwcm90b3R5cGUiLCJ2YWx1ZU9mIiwiX3N1cGVyUHJvcEdldCIsInAiLCJfZ2V0MiIsImRldmljZVBpeGVsUmF0aW8iLCJNYXRoIiwibWluIiwid2luZG93IiwidGlsZXNCZWluZ0xvYWRlZCIsImdldE51bVJhc3RlclRpbGVzQmVpbmdMb2FkZWQiLCJleHBvcnRzIiwiTE9BRF9FTEVWQVRJT05fQUZURVJfWk9PTSIsImdldFNob3VsZExvYWRUZXJyYWluIiwic3RhYyIsIm1hcFN0YXRlIiwidmlzQ29uZmlnIiwiX3N0YWMkcmFzdGVyVGlsZVNlcnZlIiwicmFzdGVyVGlsZVNlcnZlclVybHMiLCJlbmFibGVUZXJyYWluIiwiZHJhZ1JvdGF0ZSIsImVuYWJsZVRlcnJhaW5Ub3BWaWV3IiwiZ2V0QXBwbGljYXRpb25Db25maWciLCJyYXN0ZXJTZXJ2ZXJTdXBwb3J0c0VsZXZhdGlvbiIsIlJhc3RlclRpbGVMYXllciIsIl9LZXBsZXJMYXllciIsInByb3BzIiwiX3RoaXMiLCJfY2xhc3NDYWxsQ2hlY2syIiwiSW5maW5pdHkiLCJyZWdpc3RlclZpc0NvbmZpZyIsInJhc3RlclZpc0NvbmZpZ3MiLCJyZXNvbHZlciIsInByZXNldCIsInByZXNldE9wdGlvbnMiLCJfcHJlc2V0T3B0aW9ucyRzaW5nbGUiLCJfcHJlc2V0T3B0aW9ucyRzaW5nbGUyIiwiY29uY2F0IiwiaWQiLCJjb2xsZWN0aW9uIiwic2luZ2xlQmFuZCIsImFzc2V0SWQiLCJiYW5kSW5kZXgiLCJnZXREYXRhU291cmNlUGFyYW1zIiwibWVtb2l6ZSIsIm1ldGEiLCJ6UmFuZ2UiLCJfaW5oZXJpdHMyIiwiX2NyZWF0ZUNsYXNzMiIsImtleSIsImdldCIsIkxBWUVSX1RZUEVTIiwicmFzdGVyVGlsZSIsIlJhc3Rlckljb24iLCJEYXRhc2V0VHlwZSIsIlJBU1RFUl9USUxFIiwiY2F0ZWdvcmljYWxDb2xvckxlZ2VuZHMiLCJjb25maWciLCJjb2xvclJhbmdlIiwiY29sb3JMZWdlbmRzIiwiY29sb3IiLCJnZXREZWZhdWx0TGF5ZXJDb25maWciLCJjb2xvckZpZWxkIiwiYW5hbHl6ZXJUeXBlIiwiZm9ybWF0IiwidHlwZSIsImZpZWxkSWR4IiwidmFsdWVBY2Nlc3NvciIsImRpc3BsYXlOYW1lIiwiZ2V0SG92ZXJEYXRhIiwic2hvdWxkUmVuZGVyTGF5ZXIiLCJpc1Zpc2libGUiLCJmb3JtYXRMYXllckRhdGEiLCJkYXRhc2V0cyIsIm9sZExheWVyRGF0YSIsIl9kYXRhc2V0JG1ldGFkYXRhIiwiZGF0YUlkIiwibm90TnVsbG9yVW5kZWZpbmVkIiwiZGF0YXNldCIsImRhdGFVcGRhdGVUcmlnZ2VycyIsImdldERhdGFVcGRhdGVUcmlnZ2VycyIsInRyaWdnZXJDaGFuZ2VkIiwiZ2V0Q2hhbmdlZFRyaWdnZXJzIiwiZ2V0TWV0YSIsInVwZGF0ZUxheWVyTWV0YSIsInRpbGVTb3VyY2UiLCJtZXRhZGF0YSIsInBtdGlsZXNUeXBlIiwiUE1UaWxlc1R5cGUiLCJSQVNURVIiLCJtZXRhZGF0YVVybCIsIl9yZWYiLCJvbGREYXRhc2V0Iiwib2xkVGlsZVNvdXJjZSIsImRhdGEiLCJQTVRpbGVzU291cmNlIiwiY3JlYXRlRGF0YVNvdXJjZSIsInVwZGF0ZU1ldGEiLCJib3VuZHMiLCJnZXRTVEFDQm91bmRzIiwic2V0SW5pdGlhbExheWVyQ29uZmlnIiwidXBkYXRlTGF5ZXJWaXNDb25maWciLCJ1c2VTVEFDU2VhcmNoaW5nIiwiYXZhaWxhYmxlQmFuZHMiLCJnZXRFT0JhbmRzIiwic2luZ2xlQmFuZE5hbWUiLCJhdmFpbGFibGVQcmVzZXRzIiwiZmlsdGVyQXZhaWxhYmxlUHJlc2V0cyIsIlBSRVNFVF9PUFRJT05TIiwiaW5jbHVkZXMiLCJ2aXNDb25maWdTZXR0aW5ncyIsImRlZmF1bHRWYWx1ZSIsImNvbG9yRGVmYXVsdHMiLCJEQVRBX1NPVVJDRV9DT0xPUl9ERUZBVUxUUyIsIm9uVmlld3BvcnRMb2FkIiwidGlsZXMiLCJ1cGRhdGVNaW5NYXhQaXhlbFZhbHVlIiwibmV3WlJhbmdlIiwiY29tcHV0ZVpSYW5nZSIsIl9nZXRNaW5NYXhGcm9tVGlsZTJESCIsImdldE1pbk1heEZyb21UaWxlMkRIZWFkZXJzIiwiX2dldE1pbk1heEZyb21UaWxlMkRIMiIsIl9zbGljZWRUb0FycmF5MiIsIm1heCIsIm1pblZpZXdwb3J0UGl4ZWxWYWx1ZSIsIm1heFZpZXdwb3J0UGl4ZWxWYWx1ZSIsImdldE1pbk1heFBpeGVsVmFsdWVzIiwiaW1hZ2VzIiwibWluUGl4ZWxWYWx1ZSIsIm1heFBpeGVsVmFsdWUiLCJfaXRlcmF0b3IiLCJfc3RlcCIsImltYWdlIiwiX2dldEltYWdlTWluTWF4IiwiZ2V0SW1hZ2VNaW5NYXgiLCJfZ2V0SW1hZ2VNaW5NYXgyIiwiZXJyIiwicmVuZGVyTGF5ZXIiLCJvcHRzIiwiX2RhdGEkZGF0YXNldCIsInJlbmRlclBNVGlsZXNMYXllciIsInJlbmRlclN0YWNMYXllciIsIl9kYXRhJGRhdGFzZXQyIiwiX3RoaXMyIiwiZXhwZXJpbWVudGFsQ29udGV4dCIsInN0YWNfdmVyc2lvbiIsIl90aGlzJGdldERlZmF1bHREZWNrTCIsImdldERlZmF1bHREZWNrTGF5ZXJQcm9wcyIsIm9wYWNpdHkiLCJ2aXNpYmxlIiwiaGFzU2hhZG93RWZmZWN0IiwiY29sb3JtYXBJZCIsImxpbmVhclJlc2NhbGluZyIsImxpbmVhclJlc2NhbGluZ0ZhY3RvciIsIm5vbkxpbmVhclJlc2NhbGluZyIsImdhbW1hQ29udHJhc3RGYWN0b3IiLCJzaWdtb2lkYWxDb250cmFzdEZhY3RvciIsInNpZ21vaWRhbEJpYXNGYWN0b3IiLCJzYXR1cmF0aW9uVmFsdWUiLCJmaWx0ZXJFbmFibGVkIiwiZmlsdGVyUmFuZ2UiLCJzdGFjU2VhcmNoUHJvdmlkZXIiLCJzdGFydERhdGUiLCJlbmREYXRlIiwiX3N0YWNRdWVyeSIsImNhdGVnb3JpY2FsQ29sb3JNYXAiLCJjb2xvck1hcCIsImR5bmFtaWNDb2xvciIsInNob3VsZExvYWRUZXJyYWluIiwiRGF0ZSIsImJhbmRDb21iaW5hdGlvbiIsImdldFNpbmdsZUJhbmRQcmVzZXRPcHRpb25zIiwiZGF0YVNvdXJjZVBhcmFtcyIsIm1pblpvb20iLCJtYXhab29tIiwiZ2xvYmFsQm91bmRzIiwibG9hZEFzc2V0SWRzIiwibG9hZEJhbmRJbmRleGVzIiwicmVuZGVyQmFuZEluZGV4ZXMiLCJkYXRhVHlwZSIsImRzTWluUGl4ZWxWYWx1ZSIsImRzTWF4UGl4ZWxWYWx1ZSIsIm1pbkNhdGVnb3JpY2FsQmFuZFZhbHVlIiwibWF4Q2F0ZWdvcmljYWxCYW5kVmFsdWUiLCJOdW1iZXIiLCJpc0Zpbml0ZSIsImdldFRpbGVEYXRhQ3VzdG9tUHJvcHMiLCJ0aWxlTGF5ZXIiLCJUaWxlTGF5ZXIiLCJ0aWxlU2l6ZSIsImdldFRpbGVEYXRhIiwiYXJncyIsImJpbmQiLCJyZW5kZXJTdWJMYXllcnMiLCJyZW5kZXJTdWJMYXllcnNTdGFjIiwibWF4UmVxdWVzdHMiLCJnZXRNYXhSZXF1ZXN0cyIsInVwZGF0ZVRyaWdnZXJzIiwiX3RvQ29uc3VtYWJsZUFycmF5MiIsInJlZmluZW1lbnRTdHJhdGVneSIsImhhc0NhdGVnb3JpY2FsQ29sb3JNYXAiLCJfZGF0YSRkYXRhc2V0MyIsIl90aGlzMyIsIl90aGlzJGdldERlZmF1bHREZWNrTDIiLCJzaG93VGlsZUJvcmRlcnMiLCJnZXRUaWxlRGF0YVBNVGlsZXMiLCJwaWNrYWJsZSIsImF1dG9IaWdobGlnaHQiLCJ6b29tT2Zmc2V0IiwicmVuZGVyU3ViTGF5ZXJzUE1UaWxlcyIsIl9nZXRUaWxlRGF0YSIsIl9hc3luY1RvR2VuZXJhdG9yMiIsIl9yZWdlbmVyYXRvciIsIm1hcmsiLCJfY2FsbGVlIiwiX3Byb3BzJGJib3giLCJ3ZXN0Iiwic291dGgiLCJlYXN0Iiwibm9ydGgiLCJ6b29tIiwiYXNzZXRSZXF1ZXN0cyIsInRlcnJhaW4iLCJfeWllbGQkUHJvbWlzZSRhbGwiLCJfeWllbGQkUHJvbWlzZSRhbGwyIiwiX3RlcnJhaW4iLCJfdGhpcyRnZXRNaW5NYXhQaXhlbFYiLCJfdGhpcyRnZXRNaW5NYXhQaXhlbFYyIiwid3JhcCIsIl9jYWxsZWUkIiwiX2NvbnRleHQiLCJwcmV2IiwiYmJveCIsImluZGV4IiwieiIsImJib3hJbnRlcnNlY3RzIiwiYWJydXB0IiwiZ2V0U1RBQ0ltYWdlUmVxdWVzdHMiLCJzZW50IiwidDAiLCJsb2FkVGVycmFpbiIsImJvdW5kc0Zvckdlb21ldHJ5Iiwic2lnbmFsIiwiUHJvbWlzZSIsImFsbCIsImxvYWRJbWFnZXMiLCJtaW5WYWx1ZSIsIm1heFZhbHVlIiwiaW1hZ2VCYW5kcyIsInQxIiwic3RvcCIsIl94IiwiX2dldFRpbGVEYXRhUE1UaWxlcyIsIl9jYWxsZWUyIiwiX3Byb3BzJGJib3gyIiwiX3lpZWxkJFByb21pc2UkYWxsMyIsIl95aWVsZCRQcm9taXNlJGFsbDQiLCJfdGhpcyRnZXRNaW5NYXhQaXhlbFYzIiwiX3RoaXMkZ2V0TWluTWF4UGl4ZWxWNCIsIl9jYWxsZWUyJCIsIl9jb250ZXh0MiIsIl94MiIsIl94MyIsImZpbmREZWZhdWx0TGF5ZXJQcm9wcyIsIm5ld0xheWVyUHJvcCIsImxhYmVsIiwiS2VwbGVyTGF5ZXIiLCJ0aWxlIiwiZ2xvYmFsTWluUGl4ZWxWYWx1ZSIsImdsb2JhbE1heFBpeGVsVmFsdWUiLCJ0aWxlTWluUGl4ZWxWYWx1ZSIsInRpbGVNYXhQaXhlbFZhbHVlIiwiX2dldE1vZHVsZXMiLCJnZXRNb2R1bGVzIiwibW9kdWxlcyIsIm1vZHVsZVByb3BzIiwiaWRTdWZmaXgiLCJSYXN0ZXJNZXNoTGF5ZXIiLCJtZXNoIiwiZ2V0UG9seWdvbk9mZnNldCIsImNvb3JkaW5hdGVTeXN0ZW0iLCJDT09SRElOQVRFX1NZU1RFTSIsIkxOR0xBVCIsImdldENvbG9yIiwiUmFzdGVyTGF5ZXIiLCJfaW1hZ2VDb29yZGluYXRlU3lzdGVtIiwiQ0FSVEVTSUFOIiwiX3Byb3BzJGRhdGEiLCJfcHJvcHMkdGlsZSIsIl9wcm9wcyR0aWxlJGJib3giLCJsYXllcnMiLCJtaW1lVHlwZSIsImdldFJhc3RlckxheWVyUE1UaWxlcyIsImJvcmRlckNvbG9yIiwiUGF0aExheWVyIiwiZ2V0UGF0aCIsImQiLCJ3aWR0aE1pblBpeGVscyIsImltYWdlUmdiYSIsIl9nZXRNb2R1bGVzMiJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yYXN0ZXItdGlsZS9yYXN0ZXItdGlsZS1sYXllci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge0NPT1JESU5BVEVfU1lTVEVNLCBMYXllciBhcyBEZWNrTGF5ZXJ9IGZyb20gJ0BkZWNrLmdsL2NvcmUvdHlwZWQnO1xuaW1wb3J0IHtUaWxlTGF5ZXIsIEdlb0JvdW5kaW5nQm94fSBmcm9tICdAZGVjay5nbC9nZW8tbGF5ZXJzL3R5cGVkJztcbmltcG9ydCB7UE1UaWxlc1NvdXJjZSwgUE1UaWxlc1RpbGVTb3VyY2V9IGZyb20gJ0Bsb2FkZXJzLmdsL3BtdGlsZXMnO1xuaW1wb3J0IHtUZXh0dXJlMkRQcm9wc30gZnJvbSAnQGx1bWEuZ2wvd2ViZ2wnO1xuaW1wb3J0IG1lbW9pemUgZnJvbSAnbG9kYXNoL21lbW9pemUnO1xuXG5pbXBvcnQge1BhdGhMYXllcn0gZnJvbSAnQGRlY2suZ2wvbGF5ZXJzL3R5cGVkJztcbmltcG9ydCB7RGF0YXNldFR5cGUsIFBNVGlsZXNUeXBlLCBMQVlFUl9UWVBFU30gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHtSYXN0ZXJMYXllciwgUmFzdGVyTWVzaExheWVyfSBmcm9tICdAa2VwbGVyLmdsL2RlY2tnbC1sYXllcnMnO1xuaW1wb3J0IHtcbiAgTGF5ZXJCYXNlQ29uZmlnLFxuICBMYXllckNvbG9yQ29uZmlnLFxuICBMYXllckhlaWdodENvbmZpZyxcbiAgVmlzdWFsQ2hhbm5lbCxcbiAgVmlzQ29uZmlnQ29sb3JSYW5nZSxcbiAgVmlzQ29uZmlnU2VsZWN0aW9uLFxuICBWaXNDb25maWdCb29sZWFuLFxuICBWaXNDb25maWdJbnB1dCxcbiAgVmlzQ29uZmlnUmFuZ2UsXG4gIFZpc0NvbmZpZ051bWJlclxufSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcblxuaW1wb3J0IHtub3ROdWxsb3JVbmRlZmluZWR9IGZyb20gJ0BrZXBsZXIuZ2wvY29tbW9uLXV0aWxzJztcbmltcG9ydCB7RGF0YXNldHMsIEtlcGxlclRhYmxlIGFzIEtlcGxlckRhdGFzZXQsIFZlY3RvclRpbGVNZXRhZGF0YX0gZnJvbSAnQGtlcGxlci5nbC90YWJsZSc7XG5pbXBvcnQge2dldEFwcGxpY2F0aW9uQ29uZmlnfSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcblxuaW1wb3J0IHtyYXN0ZXJWaXNDb25maWdzLCBQUkVTRVRfT1BUSU9OUywgREFUQV9TT1VSQ0VfQ09MT1JfREVGQVVMVFN9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB7Z2V0TW9kdWxlc30gZnJvbSAnLi9ncHUtdXRpbHMnO1xuaW1wb3J0IHtnZXRTVEFDSW1hZ2VSZXF1ZXN0cywgbG9hZEltYWdlcywgbG9hZFRlcnJhaW59IGZyb20gJy4vaW1hZ2UnO1xuaW1wb3J0IFJhc3Rlckljb24gZnJvbSAnLi9yYXN0ZXItdGlsZS1pY29uJztcbmltcG9ydCB7XG4gIGdldERhdGFTb3VyY2VQYXJhbXMsXG4gIGdldE1heFJlcXVlc3RzLFxuICBiYm94SW50ZXJzZWN0cyxcbiAgY29tcHV0ZVpSYW5nZSxcbiAgZ2V0U1RBQ0JvdW5kcyxcbiAgZ2V0RU9CYW5kcyxcbiAgZmlsdGVyQXZhaWxhYmxlUHJlc2V0cyxcbiAgZ2V0U2luZ2xlQmFuZFByZXNldE9wdGlvbnMsXG4gIGdldEltYWdlTWluTWF4LFxuICBnZXRNaW5NYXhGcm9tVGlsZTJESGVhZGVyc1xufSBmcm9tICcuL3Jhc3Rlci10aWxlLXV0aWxzJztcbmltcG9ydCB7XG4gIEdldFRpbGVEYXRhQ3VzdG9tUHJvcHMsXG4gIEdldFRpbGVEYXRhRGVmYXVsdFByb3BzLFxuICBHZXRUaWxlRGF0YVByb3BzLFxuICBSZW5kZXJTdWJMYXllcnNQcm9wcyxcbiAgR2V0VGlsZURhdGFPdXRwdXQsXG4gIERhdGFTb3VyY2VQYXJhbXMsXG4gIEtlcGxlclJhc3RlckRhdGFzZXQsXG4gIFRpbGUyREhlYWRlcixcbiAgUHJlc2V0T3B0aW9uLFxuICBDb21wbGV0ZVNUQUNPYmplY3Rcbn0gZnJvbSAnLi90eXBlcyc7XG5cbmltcG9ydCB7RmluZERlZmF1bHRMYXllclByb3BzUmV0dXJuVmFsdWV9IGZyb20gJy4uL2xheWVyLXV0aWxzJztcbmltcG9ydCB7ZGVmYXVsdCBhcyBLZXBsZXJMYXllciwgTGF5ZXJCYXNlQ29uZmlnUGFydGlhbH0gZnJvbSAnLi4vYmFzZS1sYXllcic7XG5cbi8vIEFkanVzdCB0aWxlU2l6ZSB0byBkZXZpY2VQaXhlbFJhdGlvLCBidXQgbm90IGhpZ2hlciB0aGFuIDIgdG8gcmVkdWNlIHJlcXVlc3RzIHRvIHNlcnZlclxuY29uc3QgZGV2aWNlUGl4ZWxSYXRpbzogbnVtYmVyID0gTWF0aC5taW4oXG4gIDIsXG4gICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbykgfHwgMVxuKTtcblxuLy8gR2xvYmFsIGNvdW50ZXIgdGhhdCByZXByZXNlbnRzIHRoZSBudW1iZXIgb2YgdGlsZXMgY3VycmVudGx5IGJlaW5nIGxvYWRlZCBhY3Jvc3MgYWxsIHRoZSByYXN0ZXIgdGlsZSBsYXllcnNcbmxldCB0aWxlc0JlaW5nTG9hZGVkID0gMDtcblxuLy8gVGhpcyBpcyBhIHRlbXAgc29sdXRpb24gdG8gdHJhY2sgbG9hZGluZ1xuZXhwb3J0IGNvbnN0IGdldE51bVJhc3RlclRpbGVzQmVpbmdMb2FkZWQgPSAoKSA9PiB7XG4gIHJldHVybiB0aWxlc0JlaW5nTG9hZGVkO1xufTtcblxuZXhwb3J0IGNvbnN0IExPQURfRUxFVkFUSU9OX0FGVEVSX1pPT00gPSA4Ljk7XG5cbmNvbnN0IGdldFNob3VsZExvYWRUZXJyYWluID0gKHN0YWMsIG1hcFN0YXRlLCB2aXNDb25maWcpID0+IHtcbiAgcmV0dXJuIEJvb2xlYW4oXG4gICAgLy8gd2UgbmVlZCBhIHJhc3RlciB0aWxlIHNlcnZlciBmb3IgZWxldmF0aW9ucyBldmVuIHdoZW4gd2UgdXNlciBQTVRpbGVzXG4gICAgc3RhYy5yYXN0ZXJUaWxlU2VydmVyVXJscz8ubGVuZ3RoID4gMCAmJlxuICAgICAgLy8gY2hlY2sgdGhlIHN3aXRjaCBmcm9tIHRoZSBsYXllciBj