kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
272 lines (262 loc) • 38.5 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");
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; } // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
// TODO isolate types - depends on @kepler.gl/schemas
// Retains the last LightingEffect deckEffect so we can keep it in the
// effects array (with shadows disabled) after the user removes the
// Light & Shadow effect from the UI. Without this, deck.gl calls
// cleanup() which removes the shadow shader module, but existing layer
// models still have shadow_uShadowMap bindings → texture errors.
var _lastLightingDeckEffect = null;
function computeDeckEffects(_ref) {
var visState = _ref.visState,
mapState = _ref.mapState,
isExport = _ref.isExport;
// TODO: 1) deck effects per deck context 2) preserved between draws
var hasLightingShadow = false;
var deckEffects = visState.effectOrder.map(function (effectId) {
var effect = (0, _utils.findById)(effectId)(visState.effects);
if (effect !== null && effect !== void 0 && effect.deckEffect) {
if (effect.isEnabled) {
updateEffect({
visState: visState,
mapState: mapState,
effect: effect
});
} else if (effect.type === _constants.LIGHT_AND_SHADOW_EFFECT.type) {
// Keep lighting effects in the array even when disabled to avoid
// removing the shadow shader module. Composite layer sublayers
// don't regenerate models when default shader modules change,
// leaving stale pipelines with shadow_uShadowMap bindings.
// Disabling shadow on the lights avoids visual effects.
disableLightingEffect(effect);
}
if (effect.isEnabled || effect.type === _constants.LIGHT_AND_SHADOW_EFFECT.type) {
if (effect.type === _constants.LIGHT_AND_SHADOW_EFFECT.type) {
hasLightingShadow = true;
if (!isExport) {
_lastLightingDeckEffect = effect.deckEffect;
}
}
return effect.deckEffect;
}
}
return null;
}).filter(function (effect) {
return effect;
});
if (!hasLightingShadow && _lastLightingDeckEffect) {
disableDeckLightingEffect(_lastLightingDeckEffect);
deckEffects.unshift(_lastLightingDeckEffect);
}
return deckEffects;
}
/**
* Always keep light & shadow effect at the top, then distance fog and
* surface fog right after it (before other post-processing effects).
* Both fog effects read the depth buffer from renderBuffers[0];
* subsequent effects clear depth during their render passes, so fog
* must run before that happens.
*/
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);
}
}
var distanceFogEffect = effects.find(function (effect) {
return effect.type === _constants.DISTANCE_FOG_TYPE;
});
if (distanceFogEffect) {
var _ind = effectOrder.indexOf(distanceFogEffect.id);
var targetPos = lightShadowEffect ? 1 : 0;
if (_ind > targetPos) {
effectOrder.splice(_ind, 1);
effectOrder.splice(targetPos, 0, distanceFogEffect.id);
}
}
var surfaceFogEffect = effects.find(function (effect) {
return effect.type === _constants.SURFACE_FOG_TYPE;
});
if (surfaceFogEffect) {
var _ind2 = effectOrder.indexOf(surfaceFogEffect.id);
var _targetPos = 0;
if (lightShadowEffect) _targetPos++;
if (distanceFogEffect) _targetPos++;
if (_ind2 > _targetPos) {
effectOrder.splice(_ind2, 1);
effectOrder.splice(_targetPos, 0, surfaceFogEffect.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;
}
/**
* Disable shadow rendering on a lighting effect without removing it.
* This keeps the shadow shader module registered and prevents stale
* texture binding errors in composite layer sublayers.
*/
function disableLightingEffect(effect) {
var deckEffect = effect.deckEffect;
if (!deckEffect) return;
disableDeckLightingEffect(deckEffect);
}
/**
* Disable shadow rendering directly on a deck.gl LightingEffect instance.
*/
function disableDeckLightingEffect(deckEffect) {
deckEffect.shadow = false;
deckEffect.outputUniformShadow = false;
var _iterator = _createForOfIteratorHelper(deckEffect.directionalLights || []),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var light = _step.value;
light.shadow = false;
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
/**
* 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 _deckEffect$direction, _deckEffect$direction2;
// Re-enable shadow rendering in case it was previously disabled
var deckEffect = effect.deckEffect;
var _iterator2 = _createForOfIteratorHelper(deckEffect.directionalLights || []),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var light = _step2.value;
light.shadow = true;
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
deckEffect.shadow = (_deckEffect$direction = (_deckEffect$direction2 = deckEffect.directionalLights) === null || _deckEffect$direction2 === void 0 ? void 0 : _deckEffect$direction2.some(function (l) {
return l.shadow;
})) !== null && _deckEffect$direction !== void 0 ? _deckEffect$direction : false;
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,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfc3VuY2FsYyIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX2Nsb25lRGVlcCIsIl9jb25zdGFudHMiLCJfY29tbW9uVXRpbHMiLCJfdXRpbHMiLCJfZGF0YVV0aWxzIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJyIiwiZSIsInQiLCJTeW1ib2wiLCJpdGVyYXRvciIsIkFycmF5IiwiaXNBcnJheSIsIl91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSIsImxlbmd0aCIsIl9uIiwiRiIsInMiLCJuIiwiZG9uZSIsInZhbHVlIiwiZiIsIlR5cGVFcnJvciIsIm8iLCJhIiwidSIsImNhbGwiLCJuZXh0IiwiX2FycmF5TGlrZVRvQXJyYXkiLCJ0b1N0cmluZyIsInNsaWNlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiZnJvbSIsInRlc3QiLCJfbGFzdExpZ2h0aW5nRGVja0VmZmVjdCIsImNvbXB1dGVEZWNrRWZmZWN0cyIsIl9yZWYiLCJ2aXNTdGF0ZSIsIm1hcFN0YXRlIiwiaXNFeHBvcnQiLCJoYXNMaWdodGluZ1NoYWRvdyIsImRlY2tFZmZlY3RzIiwiZWZmZWN0T3JkZXIiLCJtYXAiLCJlZmZlY3RJZCIsImVmZmVjdCIsImZpbmRCeUlkIiwiZWZmZWN0cyIsImRlY2tFZmZlY3QiLCJpc0VuYWJsZWQiLCJ1cGRhdGVFZmZlY3QiLCJ0eXBlIiwiTElHSFRfQU5EX1NIQURPV19FRkZFQ1QiLCJkaXNhYmxlTGlnaHRpbmdFZmZlY3QiLCJmaWx0ZXIiLCJkaXNhYmxlRGVja0xpZ2h0aW5nRWZmZWN0IiwidW5zaGlmdCIsImZpeEVmZmVjdE9yZGVyIiwiZXhwb3J0cyIsImxpZ2h0U2hhZG93RWZmZWN0IiwiZmluZCIsImluZCIsImluZGV4T2YiLCJpZCIsInNwbGljZSIsImRpc3RhbmNlRm9nRWZmZWN0IiwiRElTVEFOQ0VfRk9HX1RZUEUiLCJ0YXJnZXRQb3MiLCJzdXJmYWNlRm9nRWZmZWN0IiwiU1VSRkFDRV9GT0dfVFlQRSIsInJlb3JkZXJFZmZlY3RPcmRlciIsIm9yaWdpbkVmZmVjdElkIiwiZGVzdGluYXRpb25FZmZlY3RJZCIsImFjdGl2ZUluZGV4Iiwib3ZlckluZGV4IiwiYXJyYXlNb3ZlIiwiaXNEYXl0aW1lIiwibGF0IiwibG9uIiwidGltZXN0YW1wIiwiZGF0ZSIsIkRhdGUiLCJfU3VuQ2FsYyRnZXRUaW1lcyIsIlN1bkNhbGMiLCJnZXRUaW1lcyIsInN1bnJpc2UiLCJzdW5zZXQiLCJzaGFkb3ciLCJvdXRwdXRVbmlmb3JtU2hhZG93IiwiX2l0ZXJhdG9yIiwiZGlyZWN0aW9uYWxMaWdodHMiLCJfc3RlcCIsImxpZ2h0IiwiZXJyIiwiX3JlZjIiLCJfZGVja0VmZmVjdCRkaXJlY3Rpb24iLCJfZGVja0VmZmVjdCRkaXJlY3Rpb24yIiwiX2l0ZXJhdG9yMiIsIl9zdGVwMiIsInNvbWUiLCJsIiwicGFyYW1ldGVycyIsInRpbWVNb2RlIiwic3VuTGlnaHQiLCJMSUdIVF9BTkRfU0hBRE9XX0VGRkVDVF9USU1FX01PREVTIiwiY3VycmVudCIsIm5vdyIsImFuaW1hdGlvbiIsIl92aXNTdGF0ZSRhbmltYXRpb25DbyIsImFuaW1hdGlvbkNvbmZpZyIsImN1cnJlbnRUaW1lIiwiZmlsdGVycyIsIkZJTFRFUl9UWVBFUyIsInRpbWVSYW5nZSIsInZpZXciLCJGSUxURVJfVklFV19UWVBFUyIsImVubGFyZ2VkIiwic3luY2VkV2l0aExheWVyVGltZWxpbmUiLCJfZmlsdGVyJHZhbHVlJCIsIl9maWx0ZXIkdmFsdWUiLCJsYXRpdHVkZSIsImxvbmdpdHVkZSIsImludGVuc2l0eSIsInN1bkxpZ2h0SW50ZW5zaXR5IiwidmFsaWRhdGVFZmZlY3RQYXJhbWV0ZXJzIiwiYXJndW1lbnRzIiwidW5kZWZpbmVkIiwiZWZmZWN0RGVzY3JpcHRpb24iLCJyZXN1bHQiLCJjbG9uZURlZXAiLCJmb3JFYWNoIiwiZGVzY3JpcHRpb24iLCJkZWZhdWx0VmFsdWUiLCJtaW4iLCJtYXgiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsInByb3BlcnR5IiwidiIsImkiLCJfZGVmYXVsdFZhbHVlJGkiLCJOdW1iZXIiLCJpc0Zpbml0ZSIsImNsYW1wIl0sInNvdXJjZXMiOlsiLi4vc3JjL2VmZmVjdC11dGlscy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQgU3VuQ2FsYyBmcm9tICdzdW5jYWxjJztcbmltcG9ydCBjbG9uZURlZXAgZnJvbSAnbG9kYXNoL2Nsb25lRGVlcCc7XG5cbmltcG9ydCB0eXBlIHtFZmZlY3QgYXMgRGVja0VmZmVjdH0gZnJvbSAnQGRlY2suZ2wvY29yZSc7XG5cbmltcG9ydCB7XG4gIExJR0hUX0FORF9TSEFET1dfRUZGRUNULFxuICBMSUdIVF9BTkRfU0hBRE9XX0VGRkVDVF9USU1FX01PREVTLFxuICBGSUxURVJfVFlQRVMsXG4gIEZJTFRFUl9WSUVXX1RZUEVTLFxuICBESVNUQU5DRV9GT0dfVFlQRSxcbiAgU1VSRkFDRV9GT0dfVFlQRVxufSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5pbXBvcnQge2FycmF5TW92ZX0gZnJvbSAnQGtlcGxlci5nbC9jb21tb24tdXRpbHMnO1xuaW1wb3J0IHtNYXBTdGF0ZSwgRWZmZWN0LCBFZmZlY3RQcm9wcywgRWZmZWN0RGVzY3JpcHRpb259IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuaW1wb3J0IHtmaW5kQnlJZH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQge2NsYW1wfSBmcm9tICcuL2RhdGEtdXRpbHMnO1xuXG4vLyBUT0RPIGlzb2xhdGUgdHlwZXMgLSBkZXBlbmRzIG9uIEBrZXBsZXIuZ2wvc2NoZW1hc1xudHlwZSBWaXNTdGF0ZSA9IGFueTtcblxuLy8gUmV0YWlucyB0aGUgbGFzdCBMaWdodGluZ0VmZmVjdCBkZWNrRWZmZWN0IHNvIHdlIGNhbiBrZWVwIGl0IGluIHRoZVxuLy8gZWZmZWN0cyBhcnJheSAod2l0aCBzaGFkb3dzIGRpc2FibGVkKSBhZnRlciB0aGUgdXNlciByZW1vdmVzIHRoZVxuLy8gTGlnaHQgJiBTaGFkb3cgZWZmZWN0IGZyb20gdGhlIFVJLiBXaXRob3V0IHRoaXMsIGRlY2suZ2wgY2FsbHNcbi8vIGNsZWFudXAoKSB3aGljaCByZW1vdmVzIHRoZSBzaGFkb3cgc2hhZGVyIG1vZHVsZSwgYnV0IGV4aXN0aW5nIGxheWVyXG4vLyBtb2RlbHMgc3RpbGwgaGF2ZSBzaGFkb3dfdVNoYWRvd01hcCBiaW5kaW5ncyDihpIgdGV4dHVyZSBlcnJvcnMuXG5sZXQgX2xhc3RMaWdodGluZ0RlY2tFZmZlY3Q6IGFueSA9IG51bGw7XG5cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlRGVja0VmZmVjdHMoe1xuICB2aXNTdGF0ZSxcbiAgbWFwU3RhdGUsXG4gIGlzRXhwb3J0XG59OiB7XG4gIHZpc1N0YXRlOiBWaXNTdGF0ZTtcbiAgbWFwU3RhdGU6IE1hcFN0YXRlO1xuICBpc0V4cG9ydD86IGJvb2xlYW47XG59KTogRGVja0VmZmVjdFtdIHtcbiAgLy8gVE9ETzogMSkgZGVjayBlZmZlY3RzIHBlciBkZWNrIGNvbnRleHQgMikgcHJlc2VydmVkIGJldHdlZW4gZHJhd3NcbiAgbGV0IGhhc0xpZ2h0aW5nU2hhZG93ID0gZmFsc2U7XG5cbiAgY29uc3QgZGVja0VmZmVjdHMgPSB2aXNTdGF0ZS5lZmZlY3RPcmRlclxuICAgIC5tYXAoZWZmZWN0SWQgPT4ge1xuICAgICAgY29uc3QgZWZmZWN0ID0gZmluZEJ5SWQoZWZmZWN0SWQpKHZpc1N0YXRlLmVmZmVjdHMpIGFzIEVmZmVjdCB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChlZmZlY3Q/LmRlY2tFZmZlY3QpIHtcbiAgICAgICAgaWYgKGVmZmVjdC5pc0VuYWJsZWQpIHtcbiAgICAgICAgICB1cGRhdGVFZmZlY3Qoe3Zpc1N0YXRlLCBtYXBTdGF0ZSwgZWZmZWN0fSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZWZmZWN0LnR5cGUgPT09IExJR0hUX0FORF9TSEFET1dfRUZGRUNULnR5cGUpIHtcbiAgICAgICAgICAvLyBLZWVwIGxpZ2h0aW5nIGVmZmVjdHMgaW4gdGhlIGFycmF5IGV2ZW4gd2hlbiBkaXNhYmxlZCB0byBhdm9pZFxuICAgICAgICAgIC8vIHJlbW92aW5nIHRoZSBzaGFkb3cgc2hhZGVyIG1vZHVsZS4gQ29tcG9zaXRlIGxheWVyIHN1YmxheWVyc1xuICAgICAgICAgIC8vIGRvbid0IHJlZ2VuZXJhdGUgbW9kZWxzIHdoZW4gZGVmYXVsdCBzaGFkZXIgbW9kdWxlcyBjaGFuZ2UsXG4gICAgICAgICAgLy8gbGVhdmluZyBzdGFsZSBwaXBlbGluZXMgd2l0aCBzaGFkb3dfdVNoYWRvd01hcCBiaW5kaW5ncy5cbiAgICAgICAgICAvLyBEaXNhYmxpbmcgc2hhZG93IG9uIHRoZSBsaWdodHMgYXZvaWRzIHZpc3VhbCBlZmZlY3RzLlxuICAgICAgICAgIGRpc2FibGVMaWdodGluZ0VmZmVjdChlZmZlY3QpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlZmZlY3QuaXNFbmFibGVkIHx8IGVmZmVjdC50eXBlID09PSBMSUdIVF9BTkRfU0hBRE9XX0VGRkVDVC50eXBlKSB7XG4gICAgICAgICAgaWYgKGVmZmVjdC50eXBlID09PSBMSUdIVF9BTkRfU0hBRE9XX0VGRkVDVC50eXBlKSB7XG4gICAgICAgICAgICBoYXNMaWdodGluZ1NoYWRvdyA9IHRydWU7XG4gICAgICAgICAgICBpZiAoIWlzRXhwb3J0KSB7XG4gICAgICAgICAgICAgIF9sYXN0TGlnaHRpbmdEZWNrRWZmZWN0ID0gZWZmZWN0LmRlY2tFZmZlY3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBlZmZlY3QuZGVja0VmZmVjdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSlcbiAgICAuZmlsdGVyKGVmZmVjdCA9PiBlZmZlY3QpO1xuXG4gIGlmICghaGFzTGlnaHRpbmdTaGFkb3cgJiYgX2xhc3RMaWdodGluZ0RlY2tFZmZlY3QpIHtcbiAgICBkaXNhYmxlRGVja0xpZ2h0aW5nRWZmZWN0KF9sYXN0TGlnaHRpbmdEZWNrRWZmZWN0KTtcbiAgICBkZWNrRWZmZWN0cy51bnNoaWZ0KF9sYXN0TGlnaHRpbmdEZWNrRWZmZWN0KTtcbiAgfVxuXG4gIHJldHVybiBkZWNrRWZmZWN0cztcbn1cblxuLyoqXG4gKiBBbHdheXMga2VlcCBsaWdodCAmIHNoYWRvdyBlZmZlY3QgYXQgdGhlIHRvcCwgdGhlbiBkaXN0YW5jZSBmb2cgYW5kXG4gKiBzdXJmYWNlIGZvZyByaWdodCBhZnRlciBpdCAoYmVmb3JlIG90aGVyIHBvc3QtcHJvY2Vzc2luZyBlZmZlY3RzKS5cbiAqIEJvdGggZm9nIGVmZmVjdHMgcmVhZCB0aGUgZGVwdGggYnVmZmVyIGZyb20gcmVuZGVyQnVmZmVyc1swXTtcbiAqIHN1YnNlcXVlbnQgZWZmZWN0cyBjbGVhciBkZXB0aCBkdXJpbmcgdGhlaXIgcmVuZGVyIHBhc3Nlcywgc28gZm9nXG4gKiBtdXN0IHJ1biBiZWZvcmUgdGhhdCBoYXBwZW5zLlxuICovXG5leHBvcnQgY29uc3QgZml4RWZmZWN0T3JkZXIgPSAoZWZmZWN0czogRWZmZWN0W10sIGVmZmVjdE9yZGVyOiBzdHJpbmdbXSk6IHN0cmluZ1tdID0+IHtcbiAgY29uc3QgbGlnaHRTaGFkb3dFZmZlY3QgPSBlZmZlY3RzLmZpbmQoZWZmZWN0ID0+IGVmZmVjdC50eXBlID09PSBMSUdIVF9BTkRfU0hBRE9XX0VGRkVDVC50eXBlKTtcbiAgaWYgKGxpZ2h0U2hhZG93RWZmZWN0KSB7XG4gICAgY29uc3QgaW5kID0gZWZmZWN0T3JkZXIuaW5kZXhPZihsaWdodFNoYWRvd0VmZmVjdC5pZCk7XG4gICAgaWYgKGluZCA+IDApIHtcbiAgICAgIGVmZmVjdE9yZGVyLnNwbGljZShpbmQsIDEpO1xuICAgICAgZWZmZWN0T3JkZXIudW5zaGlmdChsaWdodFNoYWRvd0VmZmVjdC5pZCk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZGlzdGFuY2VGb2dFZmZlY3QgPSBlZmZlY3RzLmZpbmQoZWZmZWN0ID0+IGVmZmVjdC50eXBlID09PSBESVNUQU5DRV9GT0dfVFlQRSk7XG4gIGlmIChkaXN0YW5jZUZvZ0VmZmVjdCkge1xuICAgIGNvbnN0IGluZCA9IGVmZmVjdE9yZGVyLmluZGV4T2YoZGlzdGFuY2VGb2dFZmZlY3QuaWQpO1xuICAgIGNvbnN0IHRhcmdldFBvcyA9IGxpZ2h0U2hhZG93RWZmZWN0ID8gMSA6IDA7XG4gICAgaWYgKGluZCA+IHRhcmdldFBvcykge1xuICAgICAgZWZmZWN0T3JkZXIuc3BsaWNlKGluZCwgMSk7XG4gICAgICBlZmZlY3RPcmRlci5zcGxpY2UodGFyZ2V0UG9zLCAwLCBkaXN0YW5jZUZvZ0VmZmVjdC5pZCk7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc3VyZmFjZUZvZ0VmZmVjdCA9IGVmZmVjdHMuZmluZChlZmZlY3QgPT4gZWZmZWN0LnR5cGUgPT09IFNVUkZBQ0VfRk9HX1RZUEUpO1xuICBpZiAoc3VyZmFjZUZvZ0VmZmVjdCkge1xuICAgIGNvbnN0IGluZCA9IGVmZmVjdE9yZGVyLmluZGV4T2Yoc3VyZmFjZUZvZ0VmZmVjdC5pZCk7XG4gICAgbGV0IHRhcmdldFBvcyA9IDA7XG4gICAgaWYgKGxpZ2h0U2hhZG93RWZmZWN0KSB0YXJnZXRQb3MrKztcbiAgICBpZiAoZGlzdGFuY2VGb2dFZmZlY3QpIHRhcmdldFBvcysrO1xuICAgIGlmIChpbmQgPiB0YXJnZXRQb3MpIHtcbiAgICAgIGVmZmVjdE9yZGVyLnNwbGljZShpbmQsIDEpO1xuICAgICAgZWZmZWN0T3JkZXIuc3BsaWNlKHRhcmdldFBvcywgMCwgc3VyZmFjZUZvZ0VmZmVjdC5pZCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVmZmVjdE9yZGVyO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlb3JkZXJFZmZlY3RPcmRlcihcbiAgZWZmZWN0T3JkZXI6IHN0cmluZ1tdLFxuICBvcmlnaW5FZmZlY3RJZDogc3RyaW5nLFxuICBkZXN0aW5hdGlvbkVmZmVjdElkOiBzdHJpbmdcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgYWN0aXZlSW5kZXggPSBlZmZlY3RPcmRlci5pbmRleE9mKG9yaWdpbkVmZmVjdElkKTtcbiAgY29uc3Qgb3ZlckluZGV4ID0gZWZmZWN0T3JkZXIuaW5kZXhPZihkZXN0aW5hdGlvbkVmZmVjdElkKTtcbiAgcmV0dXJuIGFycmF5TW92ZShlZmZlY3RPcmRlciwgYWN0aXZlSW5kZXgsIG92ZXJJbmRleCk7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhlIGN1cnJlbnQgdGltZSBpcyBkYXl0aW1lIGF0IHRoZSBnaXZlbiBsb2NhdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IGxhdCBMYXRpdHVkZVxuICogQHBhcmFtIHtudW1iZXJ9IGxvbiBMb25naXR1ZGVcbiAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lc3RhbXAgTWlsbGlzZWNvbmRzIHNpbmNlIHRoZSBVbml4IEVwb2NoXG4gKiBAcmV0dXJucyBib29sZWFuXG4gKi9cbmZ1bmN0aW9uIGlzRGF5dGltZShsYXQsIGxvbiwgdGltZXN0YW1wKSB7XG4gIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh0aW1lc3RhbXApO1xuICBjb25zdCB7c3VucmlzZSwgc3Vuc2V0fSA9IFN1bkNhbGMuZ2V0VGltZXMoZGF0ZSwgbGF0LCBsb24pO1xuICByZXR1cm4gZGF0ZSA+PSBzdW5yaXNlICYmIGRhdGUgPD0gc3Vuc2V0O1xufVxuXG4vKipcbiAqIERpc2FibGUgc2hhZG93IHJlbmRlcmluZyBvbiBhIGxpZ2h0aW5nIGVmZmVjdCB3aXRob3V0IHJlbW92aW5nIGl0LlxuICogVGhpcyBrZWVwcyB0aGUgc2hhZG93IHNoYWRlciBtb2R1bGUgcmVnaXN0ZXJlZCBhbmQgcHJldmVudHMgc3RhbGVcbiAqIHRleHR1cmUgYmluZGluZyBlcnJvcnMgaW4gY29tcG9zaXRlIGxheWVyIHN1YmxheWVycy5cbiAqL1xuZnVuY3Rpb24gZGlzYWJsZUxpZ2h0aW5nRWZmZWN0KGVmZmVjdDogRWZmZWN0KSB7XG4gIGNvbnN0IGRlY2tFZmZlY3QgPSBlZmZlY3QuZGVja0VmZmVjdDtcbiAgaWYgKCFkZWNrRWZmZWN0KSByZXR1cm47XG4gIGRpc2FibGVEZWNrTGlnaHRpbmdFZmZlY3QoZGVja0VmZmVjdCk7XG59XG5cbi8qKlxuICogRGlzYWJsZSBzaGFkb3cgcmVuZGVyaW5nIGRpcmVjdGx5IG9uIGEgZGVjay5nbCBMaWdodGluZ0VmZmVjdCBpbnN0YW5jZS5cbiAqL1xuZnVuY3Rpb24gZGlzYWJsZURlY2tMaWdodGluZ0VmZmVjdChkZWNrRWZmZWN0OiBhbnkpIHtcbiAgZGVja0VmZmVjdC5zaGFkb3cgPSBmYWxzZTtcbiAgZGVja0VmZmVjdC5vdXRwdXRVbmlmb3JtU2hhZG93ID0gZmFsc2U7XG4gIGZvciAoY29uc3QgbGlnaHQgb2YgZGVja0VmZmVjdC5kaXJlY3Rpb25hbExpZ2h0cyB8fCBbXSkge1xuICAgIGxpZ2h0LnNoYWRvdyA9IGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogVXBkYXRlIGVmZmVjdCB0byBtYXRjaCBsYXRlc3QgdmlzIGFuZCBtYXAgc3RhdGVzXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZUVmZmVjdCh7dmlzU3RhdGUsIG1hcFN0YXRlLCBlZmZlY3R9KSB7XG4gIGlmIChlZmZlY3QudHlwZSA9PT0gTElHSFRfQU5EX1NIQURPV19FRkZFQ1QudHlwZSkge1xuICAgIC8vIFJlLWVuYWJsZSBzaGFkb3cgcmVuZGVyaW5nIGluIGNhc2UgaXQgd2FzIHByZXZpb3VzbHkgZGlzYWJsZWRcbiAgICBjb25zdCBkZWNrRWZmZWN0ID0gZWZmZWN0LmRlY2tFZmZlY3Q7XG4gICAgZm9yIChjb25zdCBsaWdodCBvZiBkZWNrRWZmZWN0LmRpcmVjdGlvbmFsTGlnaHRzIHx8IFtdKSB7XG4gICAgICBsaWdodC5zaGFkb3cgPSB0cnVlO1xuICAgIH1cbiAgICBkZWNrRWZmZWN0LnNoYWRvdyA9IGRlY2tFZmZlY3QuZGlyZWN0aW9uYWxMaWdodHM/LnNvbWUobCA9PiBsLnNoYWRvdykgPz8gZmFsc2U7XG5cbiAgICBsZXQge3RpbWVzdGFtcH0gPSBlZmZlY3QucGFyYW1ldGVycztcbiAgICBjb25zdCB7dGltZU1vZGV9ID0gZWZmZWN0LnBhcmFtZXRlcnM7XG4gICAgY29uc3Qgc3VuTGlnaHQgPSBlZmZlY3QuZGVja0VmZmVjdC5kaXJlY3Rpb25hbExpZ2h0c1swXTtcblxuICAgIC8vIHNldCB0aW1lc3RhbXAgZm9yIHNoYWRvd1xuICAgIGlmICh0aW1lTW9kZSA9PT0gTElHSFRfQU5EX1NIQURPV19FRkZFQ1RfVElNRV9NT0RFUy5jdXJyZW50KSB7XG4gICAgICB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICAgICAgc3VuTGlnaHQudGltZXN0YW1wID0gdGltZXN0YW1wO1xuICAgIH0gZWxzZSBpZiAodGltZU1vZGUgPT09IExJR0hUX0FORF9TSEFET1dfRUZGRUNUX1RJTUVfTU9ERVMuYW5pbWF0aW9uKSB7XG4gICAgICB0aW1lc3RhbXAgPSB2aXNTdGF0ZS5hbmltYXRpb25Db25maWcuY3VycmVudFRpbWUgPz8gMDtcbiAgICAgIGlmICghdGltZXN0YW1wKSB7XG4gICAgICAgIGNvbnN0IGZpbHRlciA9IHZpc1N0YXRlLmZpbHRlcnMuZmluZChcbiAgICAgICAgICBmaWx0ZXIgPT5cbiAgICAgICAgICAgIGZpbHRlci50eXBlID09PSBGSUxURVJfVFlQRVMudGltZVJhbmdlICYmXG4gICAgICAgICAgICAoZmlsdGVyLnZpZXcgPT09IEZJTFRFUl9WSUVXX1RZUEVTLmVubGFyZ2VkIHx8IGZpbHRlci5zeW5jZWRXaXRoTGF5ZXJUaW1lbGluZSlcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGZpbHRlcikge1xuICAgICAgICAgIHRpbWVzdGFtcCA9IGZpbHRlci52YWx1ZT8uWzBdID8/IDA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN1bkxpZ2h0LnRpbWVzdGFtcCA9IHRpbWVzdGFtcDtcbiAgICB9XG5cbiAgICAvLyBvdXRwdXQgdW5pZm9ybSBzaGFkb3cgZHVyaW5nIG5pZ2h0dGltZVxuICAgIGlmIChpc0RheXRpbWUobWFwU3RhdGUubGF0aXR1ZGUsIG1hcFN0YXRlLmxvbmdpdHVkZSwgdGltZXN0YW1wKSkge1xuICAgICAgZWZmZWN0LmRlY2tFZmZlY3Qub3V0cHV0VW5pZm9ybVNoYWRvdyA9IGZhbHNlO1xuICAgICAgc3VuTGlnaHQuaW50ZW5zaXR5ID0gZWZmZWN0LnBhcmFtZXRlcnMuc3VuTGlnaHRJbnRlbnNpdHk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVmZmVjdC5kZWNrRWZmZWN0Lm91dHB1dFVuaWZvcm1TaGFkb3cgPSB0cnVlO1xuICAgICAgc3VuTGlnaHQuaW50ZW5zaXR5ID0gMDtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgcGFyYW1ldGVycyBmb3IgYW4gZWZmZWN0LCBjbGFtcHMgbnVtYmVycyB0byBhbGxvd2VkIHJhbmdlc1xuICogb3IgYXBwbGllcyBkZWZhdWx0IHZhbHVlcyBpbiBjYXNlIG9mIHdyb25nIG5vbi1udW1lcmljIHZhbHVlcy5cbiAqIEFsbCB1bmtub3duIHByb3BlcnRpZXMgYXJlbid0IG1vZGlmaWVkLlxuICogQHBhcmFtIHBhcmFtZXRlcnMgUGFyYW1ldGVycyBjYW5kaWRhdGUgZm9yIGFuIGVmZmVjdC5cbiAqIEBwYXJhbSBlZmZlY3REZXNjcmlwdGlvbiBEZXNjcmlwdGlvbiBvZiBhbiBlZmZlY3QuXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVFZmZlY3RQYXJhbWV0ZXJzKFxuICBwYXJhbWV0ZXJzOiBFZmZlY3RQcm9wc1sncGFyYW1ldGVycyddID0ge30sXG4gIGVmZmVjdERlc2NyaXB0aW9uOiBFZmZlY3REZXNjcmlwdGlvblsncGFyYW1ldGVycyddXG4pOiBFZmZlY3RQcm9wc1sncGFyYW1ldGVycyddIHtcbiAgY29uc3QgcmVzdWx0ID0gY2xvbmVEZWVwKHBhcmFtZXRlcnMpO1xuICBlZmZlY3REZXNjcmlwdGlvbi5mb3JFYWNoKGRlc2NyaXB0aW9uID0+IHtcbiAgICBjb25zdCB7ZGVmYXVsdFZhbHVlLCBuYW1lLCB0eXBlLCBtaW4sIG1heH0gPSBkZXNjcmlwdGlvbjtcblxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwgbmFtZSkpIHJldHVybjtcbiAgICBjb25zdCBwcm9wZXJ0eSA9IHJlc3VsdFtuYW1lXTtcblxuICAgIGlmICh0eXBlID09PSAnY29sb3InIHx8IHR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShkZWZhdWx0VmFsdWUpKSByZXR1cm47XG4gICAgICBpZiAocHJvcGVydHkubGVuZ3RoICE9PSBkZWZhdWx0VmFsdWU/Lmxlbmd0aCkge1xuICAgICAgICByZXN1bHRbbmFtZV0gPSBkZWZhdWx0VmFsdWU7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGRlZmF1bHRWYWx1ZS5mb3JFYWNoKCh2LCBpKSA9PiB7XG4gICAgICAgIGxldCB2YWx1ZSA9IHByb3BlcnR5W2ldO1xuICAgICAgICB2YWx1ZSA9IE51bWJlci5pc0Zpbml0ZSh2YWx1ZSkgPyBjbGFtcChbbWluLCBtYXhdLCB2YWx1ZSkgOiBkZWZhdWx0VmFsdWVbaV0gPz8gbWluO1xuICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHByb3BlcnR5W2ldID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0gTnVtYmVyLmlzRmluaXRlKHByb3BlcnR5KSA/IGNsYW1wKFttaW4sIG1heF0sIHByb3BlcnR5KSA6IGRlZmF1bHRWYWx1ZSA/PyBtaW47XG5cbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVzdWx0W25hbWVdID0gdmFsdWU7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUdBLElBQUFBLFFBQUEs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