kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
164 lines (155 loc) • 21.8 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.computeDeckEffects = computeDeckEffects;
exports.fixEffectOrder = void 0;
exports.reorderEffectOrder = reorderEffectOrder;
exports.validateEffectParameters = validateEffectParameters;
var _suncalc = _interopRequireDefault(require("suncalc"));
var _cloneDeep = _interopRequireDefault(require("lodash/cloneDeep"));
var _constants = require("@kepler.gl/constants");
var _commonUtils = require("@kepler.gl/common-utils");
var _utils = require("./utils");
var _dataUtils = require("./data-utils");
// SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
// TODO isolate types - depends on @kepler.gl/schemas
function computeDeckEffects(_ref) {
var visState = _ref.visState,
mapState = _ref.mapState;
// TODO: 1) deck effects per deck context 2) preserved between draws
return visState.effectOrder.map(function (effectId) {
var effect = (0, _utils.findById)(effectId)(visState.effects);
if (effect !== null && effect !== void 0 && effect.isEnabled && effect.deckEffect) {
updateEffect({
visState: visState,
mapState: mapState,
effect: effect
});
return effect.deckEffect;
}
return null;
}).filter(function (effect) {
return effect;
});
}
/**
* Always keep light & shadow effect at the top
*/
var fixEffectOrder = exports.fixEffectOrder = function fixEffectOrder(effects, effectOrder) {
var lightShadowEffect = effects.find(function (effect) {
return effect.type === _constants.LIGHT_AND_SHADOW_EFFECT.type;
});
if (lightShadowEffect) {
var ind = effectOrder.indexOf(lightShadowEffect.id);
if (ind > 0) {
effectOrder.splice(ind, 1);
effectOrder.unshift(lightShadowEffect.id);
}
}
return effectOrder;
};
function reorderEffectOrder(effectOrder, originEffectId, destinationEffectId) {
var activeIndex = effectOrder.indexOf(originEffectId);
var overIndex = effectOrder.indexOf(destinationEffectId);
return (0, _commonUtils.arrayMove)(effectOrder, activeIndex, overIndex);
}
/**
* Check if the current time is daytime at the given location
* @param {number} lat Latitude
* @param {number} lon Longitude
* @param {number} timestamp Milliseconds since the Unix Epoch
* @returns boolean
*/
function isDaytime(lat, lon, timestamp) {
var date = new Date(timestamp);
var _SunCalc$getTimes = _suncalc["default"].getTimes(date, lat, lon),
sunrise = _SunCalc$getTimes.sunrise,
sunset = _SunCalc$getTimes.sunset;
return date >= sunrise && date <= sunset;
}
/**
* Update effect to match latest vis and map states
*/
function updateEffect(_ref2) {
var visState = _ref2.visState,
mapState = _ref2.mapState,
effect = _ref2.effect;
if (effect.type === _constants.LIGHT_AND_SHADOW_EFFECT.type) {
var timestamp = effect.parameters.timestamp;
var timeMode = effect.parameters.timeMode;
var sunLight = effect.deckEffect.directionalLights[0];
// set timestamp for shadow
if (timeMode === _constants.LIGHT_AND_SHADOW_EFFECT_TIME_MODES.current) {
timestamp = Date.now();
sunLight.timestamp = timestamp;
} else if (timeMode === _constants.LIGHT_AND_SHADOW_EFFECT_TIME_MODES.animation) {
var _visState$animationCo;
timestamp = (_visState$animationCo = visState.animationConfig.currentTime) !== null && _visState$animationCo !== void 0 ? _visState$animationCo : 0;
if (!timestamp) {
var filter = visState.filters.find(function (filter) {
return filter.type === _constants.FILTER_TYPES.timeRange && (filter.view === _constants.FILTER_VIEW_TYPES.enlarged || filter.syncedWithLayerTimeline);
});
if (filter) {
var _filter$value$, _filter$value;
timestamp = (_filter$value$ = (_filter$value = filter.value) === null || _filter$value === void 0 ? void 0 : _filter$value[0]) !== null && _filter$value$ !== void 0 ? _filter$value$ : 0;
}
}
sunLight.timestamp = timestamp;
}
// output uniform shadow during nighttime
if (isDaytime(mapState.latitude, mapState.longitude, timestamp)) {
effect.deckEffect.outputUniformShadow = false;
sunLight.intensity = effect.parameters.sunLightIntensity;
} else {
effect.deckEffect.outputUniformShadow = true;
sunLight.intensity = 0;
}
}
}
/**
* Validates parameters for an effect, clamps numbers to allowed ranges
* or applies default values in case of wrong non-numeric values.
* All unknown properties aren't modified.
* @param parameters Parameters candidate for an effect.
* @param effectDescription Description of an effect.
* @returns
*/
function validateEffectParameters() {
var parameters = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var effectDescription = arguments.length > 1 ? arguments[1] : undefined;
var result = (0, _cloneDeep["default"])(parameters);
effectDescription.forEach(function (description) {
var defaultValue = description.defaultValue,
name = description.name,
type = description.type,
min = description.min,
max = description.max;
if (!Object.prototype.hasOwnProperty.call(result, name)) return;
var property = result[name];
if (type === 'color' || type === 'array') {
if (!Array.isArray(defaultValue)) return;
if (property.length !== (defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.length)) {
result[name] = defaultValue;
return;
}
defaultValue.forEach(function (v, i) {
var _defaultValue$i;
var value = property[i];
value = Number.isFinite(value) ? (0, _dataUtils.clamp)([min, max], value) : (_defaultValue$i = defaultValue[i]) !== null && _defaultValue$i !== void 0 ? _defaultValue$i : min;
if (value !== undefined) {
property[i] = value;
}
});
return;
}
var value = Number.isFinite(property) ? (0, _dataUtils.clamp)([min, max], property) : defaultValue !== null && defaultValue !== void 0 ? defaultValue : min;
if (value !== undefined) {
result[name] = value;
}
});
return result;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfc3VuY2FsYyIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX2Nsb25lRGVlcCIsIl9jb25zdGFudHMiLCJfY29tbW9uVXRpbHMiLCJfdXRpbHMiLCJfZGF0YVV0aWxzIiwiY29tcHV0ZURlY2tFZmZlY3RzIiwiX3JlZiIsInZpc1N0YXRlIiwibWFwU3RhdGUiLCJlZmZlY3RPcmRlciIsIm1hcCIsImVmZmVjdElkIiwiZWZmZWN0IiwiZmluZEJ5SWQiLCJlZmZlY3RzIiwiaXNFbmFibGVkIiwiZGVja0VmZmVjdCIsInVwZGF0ZUVmZmVjdCIsImZpbHRlciIsImZpeEVmZmVjdE9yZGVyIiwiZXhwb3J0cyIsImxpZ2h0U2hhZG93RWZmZWN0IiwiZmluZCIsInR5cGUiLCJMSUdIVF9BTkRfU0hBRE9XX0VGRkVDVCIsImluZCIsImluZGV4T2YiLCJpZCIsInNwbGljZSIsInVuc2hpZnQiLCJyZW9yZGVyRWZmZWN0T3JkZXIiLCJvcmlnaW5FZmZlY3RJZCIsImRlc3RpbmF0aW9uRWZmZWN0SWQiLCJhY3RpdmVJbmRleCIsIm92ZXJJbmRleCIsImFycmF5TW92ZSIsImlzRGF5dGltZSIsImxhdCIsImxvbiIsInRpbWVzdGFtcCIsImRhdGUiLCJEYXRlIiwiX1N1bkNhbGMkZ2V0VGltZXMiLCJTdW5DYWxjIiwiZ2V0VGltZXMiLCJzdW5yaXNlIiwic3Vuc2V0IiwiX3JlZjIiLCJwYXJhbWV0ZXJzIiwidGltZU1vZGUiLCJzdW5MaWdodCIsImRpcmVjdGlvbmFsTGlnaHRzIiwiTElHSFRfQU5EX1NIQURPV19FRkZFQ1RfVElNRV9NT0RFUyIsImN1cnJlbnQiLCJub3ciLCJhbmltYXRpb24iLCJfdmlzU3RhdGUkYW5pbWF0aW9uQ28iLCJhbmltYXRpb25Db25maWciLCJjdXJyZW50VGltZSIsImZpbHRlcnMiLCJGSUxURVJfVFlQRVMiLCJ0aW1lUmFuZ2UiLCJ2aWV3IiwiRklMVEVSX1ZJRVdfVFlQRVMiLCJlbmxhcmdlZCIsInN5bmNlZFdpdGhMYXllclRpbWVsaW5lIiwiX2ZpbHRlciR2YWx1ZSQiLCJfZmlsdGVyJHZhbHVlIiwidmFsdWUiLCJsYXRpdHVkZSIsImxvbmdpdHVkZSIsIm91dHB1dFVuaWZvcm1TaGFkb3ciLCJpbnRlbnNpdHkiLCJzdW5MaWdodEludGVuc2l0eSIsInZhbGlkYXRlRWZmZWN0UGFyYW1ldGVycyIsImFyZ3VtZW50cyIsImxlbmd0aCIsInVuZGVmaW5lZCIsImVmZmVjdERlc2NyaXB0aW9uIiwicmVzdWx0IiwiY2xvbmVEZWVwIiwiZm9yRWFjaCIsImRlc2NyaXB0aW9uIiwiZGVmYXVsdFZhbHVlIiwibmFtZSIsIm1pbiIsIm1heCIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInByb3BlcnR5IiwiQXJyYXkiLCJpc0FycmF5IiwidiIsImkiLCJfZGVmYXVsdFZhbHVlJGkiLCJOdW1iZXIiLCJpc0Zpbml0ZSIsImNsYW1wIl0sInNvdXJjZXMiOlsiLi4vc3JjL2VmZmVjdC11dGlscy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQgU3VuQ2FsYyBmcm9tICdzdW5jYWxjJztcbmltcG9ydCBjbG9uZURlZXAgZnJvbSAnbG9kYXNoL2Nsb25lRGVlcCc7XG5cbmltcG9ydCB7UG9zdFByb2Nlc3NFZmZlY3R9IGZyb20gJ0BkZWNrLmdsL2NvcmUvdHlwZWQnO1xuXG5pbXBvcnQge1xuICBMSUdIVF9BTkRfU0hBRE9XX0VGRkVDVCxcbiAgTElHSFRfQU5EX1NIQURPV19FRkZFQ1RfVElNRV9NT0RFUyxcbiAgRklMVEVSX1RZUEVTLFxuICBGSUxURVJfVklFV19UWVBFU1xufSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5pbXBvcnQge2FycmF5TW92ZX0gZnJvbSAnQGtlcGxlci5nbC9jb21tb24tdXRpbHMnO1xuaW1wb3J0IHtNYXBTdGF0ZSwgRWZmZWN0LCBFZmZlY3RQcm9wcywgRWZmZWN0RGVzY3JpcHRpb259IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuaW1wb3J0IHtmaW5kQnlJZH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQge2NsYW1wfSBmcm9tICcuL2RhdGEtdXRpbHMnO1xuXG4vLyBUT0RPIGlzb2xhdGUgdHlwZXMgLSBkZXBlbmRzIG9uIEBrZXBsZXIuZ2wvc2NoZW1hc1xudHlwZSBWaXNTdGF0ZSA9IGFueTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNvbXB1dGVEZWNrRWZmZWN0cyh7XG4gIHZpc1N0YXRlLFxuICBtYXBTdGF0ZVxufToge1xuICB2aXNTdGF0ZTogVmlzU3RhdGU7XG4gIG1hcFN0YXRlOiBNYXBTdGF0ZTtcbn0pOiBQb3N0UHJvY2Vzc0VmZmVjdFtdIHtcbiAgLy8gVE9ETzogMSkgZGVjayBlZmZlY3RzIHBlciBkZWNrIGNvbnRleHQgMikgcHJlc2VydmVkIGJldHdlZW4gZHJhd3NcbiAgcmV0dXJuIHZpc1N0YXRlLmVmZmVjdE9yZGVyXG4gICAgLm1hcChlZmZlY3RJZCA9PiB7XG4gICAgICBjb25zdCBlZmZlY3QgPSBmaW5kQnlJZChlZmZlY3RJZCkodmlzU3RhdGUuZWZmZWN0cykgYXMgRWZmZWN0IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKGVmZmVjdD8uaXNFbmFibGVkICYmIGVmZmVjdC5kZWNrRWZmZWN0KSB7XG4gICAgICAgIHVwZGF0ZUVmZmVjdCh7dmlzU3RhdGUsIG1hcFN0YXRlLCBlZmZlY3R9KTtcbiAgICAgICAgcmV0dXJuIGVmZmVjdC5kZWNrRWZmZWN0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSlcbiAgICAuZmlsdGVyKGVmZmVjdCA9PiBlZmZlY3QpO1xufVxuXG4vKipcbiAqIEFsd2F5cyBrZWVwIGxpZ2h0ICYgc2hhZG93IGVmZmVjdCBhdCB0aGUgdG9wXG4gKi9cbmV4cG9ydCBjb25zdCBmaXhFZmZlY3RPcmRlciA9IChlZmZlY3RzOiBFZmZlY3RbXSwgZWZmZWN0T3JkZXI6IHN0cmluZ1tdKTogc3RyaW5nW10gPT4ge1xuICBjb25zdCBsaWdodFNoYWRvd0VmZmVjdCA9IGVmZmVjdHMuZmluZChlZmZlY3QgPT4gZWZmZWN0LnR5cGUgPT09IExJR0hUX0FORF9TSEFET1dfRUZGRUNULnR5cGUpO1xuICBpZiAobGlnaHRTaGFkb3dFZmZlY3QpIHtcbiAgICBjb25zdCBpbmQgPSBlZmZlY3RPcmRlci5pbmRleE9mKGxpZ2h0U2hhZG93RWZmZWN0LmlkKTtcbiAgICBpZiAoaW5kID4gMCkge1xuICAgICAgZWZmZWN0T3JkZXIuc3BsaWNlKGluZCwgMSk7XG4gICAgICBlZmZlY3RPcmRlci51bnNoaWZ0KGxpZ2h0U2hhZG93RWZmZWN0LmlkKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGVmZmVjdE9yZGVyO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlb3JkZXJFZmZlY3RPcmRlcihcbiAgZWZmZWN0T3JkZXI6IHN0cmluZ1tdLFxuICBvcmlnaW5FZmZlY3RJZDogc3RyaW5nLFxuICBkZXN0aW5hdGlvbkVmZmVjdElkOiBzdHJpbmdcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgYWN0aXZlSW5kZXggPSBlZmZlY3RPcmRlci5pbmRleE9mKG9yaWdpbkVmZmVjdElkKTtcbiAgY29uc3Qgb3ZlckluZGV4ID0gZWZmZWN0T3JkZXIuaW5kZXhPZihkZXN0aW5hdGlvbkVmZmVjdElkKTtcbiAgcmV0dXJuIGFycmF5TW92ZShlZmZlY3RPcmRlciwgYWN0aXZlSW5kZXgsIG92ZXJJbmRleCk7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhlIGN1cnJlbnQgdGltZSBpcyBkYXl0aW1lIGF0IHRoZSBnaXZlbiBsb2NhdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IGxhdCBMYXRpdHVkZVxuICogQHBhcmFtIHtudW1iZXJ9IGxvbiBMb25naXR1ZGVcbiAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lc3RhbXAgTWlsbGlzZWNvbmRzIHNpbmNlIHRoZSBVbml4IEVwb2NoXG4gKiBAcmV0dXJucyBib29sZWFuXG4gKi9cbmZ1bmN0aW9uIGlzRGF5dGltZShsYXQsIGxvbiwgdGltZXN0YW1wKSB7XG4gIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh0aW1lc3RhbXApO1xuICBjb25zdCB7c3VucmlzZSwgc3Vuc2V0fSA9IFN1bkNhbGMuZ2V0VGltZXMoZGF0ZSwgbGF0LCBsb24pO1xuICByZXR1cm4gZGF0ZSA+PSBzdW5yaXNlICYmIGRhdGUgPD0gc3Vuc2V0O1xufVxuXG4vKipcbiAqIFVwZGF0ZSBlZmZlY3QgdG8gbWF0Y2ggbGF0ZXN0IHZpcyBhbmQgbWFwIHN0YXRlc1xuICovXG5mdW5jdGlvbiB1cGRhdGVFZmZlY3Qoe3Zpc1N0YXRlLCBtYXBTdGF0ZSwgZWZmZWN0fSkge1xuICBpZiAoZWZmZWN0LnR5cGUgPT09IExJR0hUX0FORF9TSEFET1dfRUZGRUNULnR5cGUpIHtcbiAgICBsZXQge3RpbWVzdGFtcH0gPSBlZmZlY3QucGFyYW1ldGVycztcbiAgICBjb25zdCB7dGltZU1vZGV9ID0gZWZmZWN0LnBhcmFtZXRlcnM7XG4gICAgY29uc3Qgc3VuTGlnaHQgPSBlZmZlY3QuZGVja0VmZmVjdC5kaXJlY3Rpb25hbExpZ2h0c1swXTtcblxuICAgIC8vIHNldCB0aW1lc3RhbXAgZm9yIHNoYWRvd1xuICAgIGlmICh0aW1lTW9kZSA9PT0gTElHSFRfQU5EX1NIQURPV19FRkZFQ1RfVElNRV9NT0RFUy5jdXJyZW50KSB7XG4gICAgICB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICAgICAgc3VuTGlnaHQudGltZXN0YW1wID0gdGltZXN0YW1wO1xuICAgIH0gZWxzZSBpZiAodGltZU1vZGUgPT09IExJR0hUX0FORF9TSEFET1dfRUZGRUNUX1RJTUVfTU9ERVMuYW5pbWF0aW9uKSB7XG4gICAgICB0aW1lc3RhbXAgPSB2aXNTdGF0ZS5hbmltYXRpb25Db25maWcuY3VycmVudFRpbWUgPz8gMDtcbiAgICAgIGlmICghdGltZXN0YW1wKSB7XG4gICAgICAgIGNvbnN0IGZpbHRlciA9IHZpc1N0YXRlLmZpbHRlcnMuZmluZChcbiAgICAgICAgICBmaWx0ZXIgPT5cbiAgICAgICAgICAgIGZpbHRlci50eXBlID09PSBGSUxURVJfVFlQRVMudGltZVJhbmdlICYmXG4gICAgICAgICAgICAoZmlsdGVyLnZpZXcgPT09IEZJTFRFUl9WSUVXX1RZUEVTLmVubGFyZ2VkIHx8IGZpbHRlci5zeW5jZWRXaXRoTGF5ZXJUaW1lbGluZSlcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGZpbHRlcikge1xuICAgICAgICAgIHRpbWVzdGFtcCA9IGZpbHRlci52YWx1ZT8uWzBdID8/IDA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN1bkxpZ2h0LnRpbWVzdGFtcCA9IHRpbWVzdGFtcDtcbiAgICB9XG5cbiAgICAvLyBvdXRwdXQgdW5pZm9ybSBzaGFkb3cgZHVyaW5nIG5pZ2h0dGltZVxuICAgIGlmIChpc0RheXRpbWUobWFwU3RhdGUubGF0aXR1ZGUsIG1hcFN0YXRlLmxvbmdpdHVkZSwgdGltZXN0YW1wKSkge1xuICAgICAgZWZmZWN0LmRlY2tFZmZlY3Qub3V0cHV0VW5pZm9ybVNoYWRvdyA9IGZhbHNlO1xuICAgICAgc3VuTGlnaHQuaW50ZW5zaXR5ID0gZWZmZWN0LnBhcmFtZXRlcnMuc3VuTGlnaHRJbnRlbnNpdHk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVmZmVjdC5kZWNrRWZmZWN0Lm91dHB1dFVuaWZvcm1TaGFkb3cgPSB0cnVlO1xuICAgICAgc3VuTGlnaHQuaW50ZW5zaXR5ID0gMDtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgcGFyYW1ldGVycyBmb3IgYW4gZWZmZWN0LCBjbGFtcHMgbnVtYmVycyB0byBhbGxvd2VkIHJhbmdlc1xuICogb3IgYXBwbGllcyBkZWZhdWx0IHZhbHVlcyBpbiBjYXNlIG9mIHdyb25nIG5vbi1udW1lcmljIHZhbHVlcy5cbiAqIEFsbCB1bmtub3duIHByb3BlcnRpZXMgYXJlbid0IG1vZGlmaWVkLlxuICogQHBhcmFtIHBhcmFtZXRlcnMgUGFyYW1ldGVycyBjYW5kaWRhdGUgZm9yIGFuIGVmZmVjdC5cbiAqIEBwYXJhbSBlZmZlY3REZXNjcmlwdGlvbiBEZXNjcmlwdGlvbiBvZiBhbiBlZmZlY3QuXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVFZmZlY3RQYXJhbWV0ZXJzKFxuICBwYXJhbWV0ZXJzOiBFZmZlY3RQcm9wc1sncGFyYW1ldGVycyddID0ge30sXG4gIGVmZmVjdERlc2NyaXB0aW9uOiBFZmZlY3REZXNjcmlwdGlvblsncGFyYW1ldGVycyddXG4pOiBFZmZlY3RQcm9wc1sncGFyYW1ldGVycyddIHtcbiAgY29uc3QgcmVzdWx0ID0gY2xvbmVEZWVwKHBhcmFtZXRlcnMpO1xuICBlZmZlY3REZXNjcmlwdGlvbi5mb3JFYWNoKGRlc2NyaXB0aW9uID0+IHtcbiAgICBjb25zdCB7ZGVmYXVsdFZhbHVlLCBuYW1lLCB0eXBlLCBtaW4sIG1heH0gPSBkZXNjcmlwdGlvbjtcblxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwgbmFtZSkpIHJldHVybjtcbiAgICBjb25zdCBwcm9wZXJ0eSA9IHJlc3VsdFtuYW1lXTtcblxuICAgIGlmICh0eXBlID09PSAnY29sb3InIHx8IHR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShkZWZhdWx0VmFsdWUpKSByZXR1cm47XG4gICAgICBpZiAocHJvcGVydHkubGVuZ3RoICE9PSBkZWZhdWx0VmFsdWU/Lmxlbmd0aCkge1xuICAgICAgICByZXN1bHRbbmFtZV0gPSBkZWZhdWx0VmFsdWU7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGRlZmF1bHRWYWx1ZS5mb3JFYWNoKCh2LCBpKSA9PiB7XG4gICAgICAgIGxldCB2YWx1ZSA9IHByb3BlcnR5W2ldO1xuICAgICAgICB2YWx1ZSA9IE51bWJlci5pc0Zpbml0ZSh2YWx1ZSkgPyBjbGFtcChbbWluLCBtYXhdLCB2YWx1ZSkgOiBkZWZhdWx0VmFsdWVbaV0gPz8gbWluO1xuICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHByb3BlcnR5W2ldID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0gTnVtYmVyLmlzRmluaXRlKHByb3BlcnR5KSA/IGNsYW1wKFttaW4sIG1heF0sIHByb3BlcnR5KSA6IGRlZmF1bHRWYWx1ZSA/PyBtaW47XG5cbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVzdWx0W25hbWVdID0gdmFsdWU7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUdBLElBQUFBLFFBQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLFVBQUEsR0FBQUYsc0JBQUEsQ0FBQUMsT0FBQTtBQUlBLElBQUFFLFVBQUEsR0FBQUYsT0FBQTtBQU1BLElBQUFHLFlBQUEsR0FBQUgsT0FBQTtBQUVBLElBQUFJLE1BQUEsR0FBQUosT0FBQTtBQUNBLElBQUFLLFVBQUEsR0FBQUwsT0FBQTtBQWpCQTtBQUNBOztBQWtCQTs7QUFHTyxTQUFTTSxrQkFBa0JBLENBQUFDLElBQUEsRUFNVjtFQUFBLElBTHRCQyxRQUFRLEdBQUFELElBQUEsQ0FBUkMsUUFBUTtJQUNSQyxRQUFRLEdBQUFGLElBQUEsQ0FBUkUsUUFBUTtFQUtSO0VBQ0EsT0FBT0QsUUFBUSxDQUFDRSxXQUFXLENBQ3hCQyxHQUFHLENBQUMsVUFBQUMsUUFBUSxFQUFJO0lBQ2YsSUFBTUMsTUFBTSxHQUFHLElBQUFDLGVBQVEsRUFBQ0YsUUFBUSxDQUFDLENBQUNKLFFBQVEsQ0FBQ08sT0FBTyxDQUF1QjtJQUN6RSxJQUFJRixNQUFNLGFBQU5BLE1BQU0sZUFBTkEsTUFBTSxDQUFFRyxTQUFTLElBQUlILE1BQU0sQ0FBQ0ksVUFBVSxFQUFFO01B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
;