kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
191 lines (187 loc) • 23.8 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.DeckDistanceFogEffect = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _engine = require("@luma.gl/engine");
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; } // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
var DISTANCE_FOG_UNIFORM_BLOCK = /* glsl */"uniform distanceFogUniforms {\n float density;\n float fogStart;\n float fogRange;\n float nearPlane;\n float farPlane;\n vec3 fogColor;\n} distanceFog;\n";
var DISTANCE_FOG_FS = /* glsl */"#version 300 es\nprecision highp float;\n\nuniform sampler2D texSrc;\nuniform sampler2D texDepth;\n\nin vec2 position;\nin vec2 coordinate;\nin vec2 uv;\n\nout vec4 fragColor;\n\nvoid main() {\n vec4 color = texture(texSrc, coordinate);\n float depth = texture(texDepth, coordinate).r;\n\n float n = distanceFog.nearPlane;\n float f = distanceFog.farPlane;\n float eyeZ = n * f / (f - depth * (f - n));\n float linearDepth = (eyeZ - n) / (f - n);\n\n vec3 fogColor = distanceFog.fogColor / 255.0;\n float end = distanceFog.fogStart + distanceFog.fogRange;\n float fogFactor = smoothstep(distanceFog.fogStart, end, linearDepth) * distanceFog.density;\n\n fragColor = vec4(mix(color.rgb, fogColor, fogFactor), color.a);\n}\n";
var screenModule = {
name: 'screen',
fs: /* glsl */"uniform screenUniforms {\n vec2 texSize;\n} screen;\n",
uniformTypes: {
texSize: 'vec2<f32>'
}
};
var distanceFogModule = {
name: 'distanceFog',
fs: DISTANCE_FOG_UNIFORM_BLOCK,
uniformTypes: {
density: 'f32',
fogStart: 'f32',
fogRange: 'f32',
nearPlane: 'f32',
farPlane: 'f32',
fogColor: 'vec3<f32>'
},
defaultUniforms: {
density: 0.5,
fogStart: 0.3,
fogRange: 0.5,
nearPlane: 0.1,
farPlane: 1000,
fogColor: [217, 222, 230]
},
propTypes: {
density: {
value: 0.5,
min: 0,
max: 1
},
fogStart: {
value: 0.3,
min: 0,
max: 1
},
fogRange: {
value: 0.5,
min: 0.01,
max: 1
},
fogColor: {
value: [217, 222, 230]
},
nearPlane: {
value: 0.1,
"private": true
},
farPlane: {
value: 1000,
"private": true
}
}
};
/**
* Distance Fog Effect - uses the depth buffer to apply fog based on
* camera-to-fragment distance. The raw depth buffer values are linearized
* using the camera's near/far planes (extracted from the viewport projection
* matrix) so that the fog gradient is perceptually uniform with distance.
*/
var DeckDistanceFogEffect = exports.DeckDistanceFogEffect = /*#__PURE__*/function () {
function DeckDistanceFogEffect() {
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
(0, _classCallCheck2["default"])(this, DeckDistanceFogEffect);
(0, _defineProperty2["default"])(this, "id", 'distance-fog-effect');
(0, _defineProperty2["default"])(this, "props", void 0);
(0, _defineProperty2["default"])(this, "module", distanceFogModule);
(0, _defineProperty2["default"])(this, "model", null);
this.props = _objectSpread({
density: 0.5,
fogStart: 0.3,
fogRange: 0.5,
fogColor: [217, 222, 230]
}, props);
}
return (0, _createClass2["default"])(DeckDistanceFogEffect, [{
key: "setup",
value: function setup(_ref) {
var device = _ref.device;
this.model = new _engine.ClipSpace(device, {
id: 'distance-fog-pass',
fs: DISTANCE_FOG_FS,
modules: [distanceFogModule, screenModule],
parameters: {
depthWriteEnabled: false,
depthCompare: 'always',
blend: true,
blendColorSrcFactor: 'one',
blendColorDstFactor: 'one-minus-src-alpha',
blendAlphaSrcFactor: 'one',
blendAlphaDstFactor: 'one-minus-src-alpha',
blendColorOperation: 'add',
blendAlphaOperation: 'add'
}
});
}
}, {
key: "setProps",
value: function setProps(props) {
Object.assign(this.props, props);
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
}, {
key: "preRender",
value: function preRender() {}
}, {
key: "postRender",
value: function postRender(params) {
var _params$viewports;
var inputBuffer = params.inputBuffer,
swapBuffer = params.swapBuffer,
target = params.target;
var outputBuffer = target !== undefined ? target : swapBuffer;
if (!this.model) return inputBuffer;
// Distance fog always runs first among post-processing effects
// (enforced by fixEffectOrder), so inputBuffer is always the scene
// render target with valid depth data.
var depthAttachment = inputBuffer.depthStencilAttachment;
if (!depthAttachment) return inputBuffer;
var nearPlane = 0.1;
var farPlane = 1000;
if (((_params$viewports = params.viewports) === null || _params$viewports === void 0 ? void 0 : _params$viewports.length) > 0) {
var pm = params.viewports[0].projectionMatrix;
if (pm) {
var n = pm[14] / (pm[10] - 1);
var f = pm[14] / (pm[10] + 1);
if (Number.isFinite(n) && Number.isFinite(f) && n > 0 && f > n) {
nearPlane = n;
farPlane = f;
}
}
}
var texSize = [inputBuffer.width, inputBuffer.height];
this.model.shaderInputs.setProps({
screen: {
texSrc: inputBuffer.colorAttachments[0],
texSize: texSize
},
distanceFog: {
texDepth: depthAttachment,
density: this.props.density,
fogStart: this.props.fogStart,
fogRange: this.props.fogRange,
nearPlane: nearPlane,
farPlane: farPlane,
fogColor: this.props.fogColor
}
});
var renderPass = this.model.device.beginRenderPass({
framebuffer: outputBuffer,
parameters: {
viewport: [0, 0].concat(texSize)
},
clearColor: [0, 0, 0, 0],
clearDepth: 1
});
this.model.draw(renderPass);
renderPass.end();
return outputBuffer || inputBuffer;
}
}, {
key: "cleanup",
value: function cleanup() {
if (this.model) {
this.model.destroy();
this.model = null;
}
}
}]);
}();
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZW5naW5lIiwicmVxdWlyZSIsIm93bktleXMiLCJlIiwiciIsInQiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiRElTVEFOQ0VfRk9HX1VOSUZPUk1fQkxPQ0siLCJESVNUQU5DRV9GT0dfRlMiLCJzY3JlZW5Nb2R1bGUiLCJuYW1lIiwiZnMiLCJ1bmlmb3JtVHlwZXMiLCJ0ZXhTaXplIiwiZGlzdGFuY2VGb2dNb2R1bGUiLCJkZW5zaXR5IiwiZm9nU3RhcnQiLCJmb2dSYW5nZSIsIm5lYXJQbGFuZSIsImZhclBsYW5lIiwiZm9nQ29sb3IiLCJkZWZhdWx0VW5pZm9ybXMiLCJwcm9wVHlwZXMiLCJ2YWx1ZSIsIm1pbiIsIm1heCIsIkRlY2tEaXN0YW5jZUZvZ0VmZmVjdCIsImV4cG9ydHMiLCJwcm9wcyIsInVuZGVmaW5lZCIsIl9jbGFzc0NhbGxDaGVjazIiLCJfY3JlYXRlQ2xhc3MyIiwia2V5Iiwic2V0dXAiLCJfcmVmIiwiZGV2aWNlIiwibW9kZWwiLCJDbGlwU3BhY2UiLCJpZCIsIm1vZHVsZXMiLCJwYXJhbWV0ZXJzIiwiZGVwdGhXcml0ZUVuYWJsZWQiLCJkZXB0aENvbXBhcmUiLCJibGVuZCIsImJsZW5kQ29sb3JTcmNGYWN0b3IiLCJibGVuZENvbG9yRHN0RmFjdG9yIiwiYmxlbmRBbHBoYVNyY0ZhY3RvciIsImJsZW5kQWxwaGFEc3RGYWN0b3IiLCJibGVuZENvbG9yT3BlcmF0aW9uIiwiYmxlbmRBbHBoYU9wZXJhdGlvbiIsInNldFByb3BzIiwiYXNzaWduIiwicHJlUmVuZGVyIiwicG9zdFJlbmRlciIsInBhcmFtcyIsIl9wYXJhbXMkdmlld3BvcnRzIiwiaW5wdXRCdWZmZXIiLCJzd2FwQnVmZmVyIiwidGFyZ2V0Iiwib3V0cHV0QnVmZmVyIiwiZGVwdGhBdHRhY2htZW50IiwiZGVwdGhTdGVuY2lsQXR0YWNobWVudCIsInZpZXdwb3J0cyIsInBtIiwicHJvamVjdGlvbk1hdHJpeCIsIm4iLCJmIiwiTnVtYmVyIiwiaXNGaW5pdGUiLCJ3aWR0aCIsImhlaWdodCIsInNoYWRlcklucHV0cyIsInNjcmVlbiIsInRleFNyYyIsImNvbG9yQXR0YWNobWVudHMiLCJkaXN0YW5jZUZvZyIsInRleERlcHRoIiwicmVuZGVyUGFzcyIsImJlZ2luUmVuZGVyUGFzcyIsImZyYW1lYnVmZmVyIiwidmlld3BvcnQiLCJjb25jYXQiLCJjbGVhckNvbG9yIiwiY2xlYXJEZXB0aCIsImRyYXciLCJlbmQiLCJjbGVhbnVwIiwiZGVzdHJveSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zaGFkZXItcGFzc2VzL2Rpc3RhbmNlLWZvZy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge0NsaXBTcGFjZX0gZnJvbSAnQGx1bWEuZ2wvZW5naW5lJztcbmltcG9ydCB0eXBlIHtTaGFkZXJNb2R1bGV9IGZyb20gJ0BsdW1hLmdsL3NoYWRlcnRvb2xzJztcblxuZXhwb3J0IHR5cGUgRGlzdGFuY2VGb2dQcm9wcyA9IHtcbiAgZGVuc2l0eTogbnVtYmVyO1xuICBmb2dTdGFydDogbnVtYmVyO1xuICBmb2dSYW5nZTogbnVtYmVyO1xuICBmb2dDb2xvcjogW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xufTtcblxuY29uc3QgRElTVEFOQ0VfRk9HX1VOSUZPUk1fQkxPQ0sgPSAvKiBnbHNsICovIGBcXFxudW5pZm9ybSBkaXN0YW5jZUZvZ1VuaWZvcm1zIHtcbiAgZmxvYXQgZGVuc2l0eTtcbiAgZmxvYXQgZm9nU3RhcnQ7XG4gIGZsb2F0IGZvZ1JhbmdlO1xuICBmbG9hdCBuZWFyUGxhbmU7XG4gIGZsb2F0IGZhclBsYW5lO1xuICB2ZWMzIGZvZ0NvbG9yO1xufSBkaXN0YW5jZUZvZztcbmA7XG5cbmNvbnN0IERJU1RBTkNFX0ZPR19GUyA9IC8qIGdsc2wgKi8gYFxcXG4jdmVyc2lvbiAzMDAgZXNcbnByZWNpc2lvbiBoaWdocCBmbG9hdDtcblxudW5pZm9ybSBzYW1wbGVyMkQgdGV4U3JjO1xudW5pZm9ybSBzYW1wbGVyMkQgdGV4RGVwdGg7XG5cbmluIHZlYzIgcG9zaXRpb247XG5pbiB2ZWMyIGNvb3JkaW5hdGU7XG5pbiB2ZWMyIHV2O1xuXG5vdXQgdmVjNCBmcmFnQ29sb3I7XG5cbnZvaWQgbWFpbigpIHtcbiAgdmVjNCBjb2xvciA9IHRleHR1cmUodGV4U3JjLCBjb29yZGluYXRlKTtcbiAgZmxvYXQgZGVwdGggPSB0ZXh0dXJlKHRleERlcHRoLCBjb29yZGluYXRlKS5yO1xuXG4gIGZsb2F0IG4gPSBkaXN0YW5jZUZvZy5uZWFyUGxhbmU7XG4gIGZsb2F0IGYgPSBkaXN0YW5jZUZvZy5mYXJQbGFuZTtcbiAgZmxvYXQgZXllWiA9IG4gKiBmIC8gKGYgLSBkZXB0aCAqIChmIC0gbikpO1xuICBmbG9hdCBsaW5lYXJEZXB0aCA9IChleWVaIC0gbikgLyAoZiAtIG4pO1xuXG4gIHZlYzMgZm9nQ29sb3IgPSBkaXN0YW5jZUZvZy5mb2dDb2xvciAvIDI1NS4wO1xuICBmbG9hdCBlbmQgPSBkaXN0YW5jZUZvZy5mb2dTdGFydCArIGRpc3RhbmNlRm9nLmZvZ1JhbmdlO1xuICBmbG9hdCBmb2dGYWN0b3IgPSBzbW9vdGhzdGVwKGRpc3RhbmNlRm9nLmZvZ1N0YXJ0LCBlbmQsIGxpbmVhckRlcHRoKSAqIGRpc3RhbmNlRm9nLmRlbnNpdHk7XG5cbiAgZnJhZ0NvbG9yID0gdmVjNChtaXgoY29sb3IucmdiLCBmb2dDb2xvciwgZm9nRmFjdG9yKSwgY29sb3IuYSk7XG59XG5gO1xuXG5jb25zdCBzY3JlZW5Nb2R1bGUgPSB7XG4gIG5hbWU6ICdzY3JlZW4nLFxuICBmczogLyogZ2xzbCAqLyBgXFxcbnVuaWZvcm0gc2NyZWVuVW5pZm9ybXMge1xuICB2ZWMyIHRleFNpemU7XG59IHNjcmVlbjtcbmAsXG4gIHVuaWZvcm1UeXBlczoge1xuICAgIHRleFNpemU6ICd2ZWMyPGYzMj4nXG4gIH1cbn0gYXMgY29uc3Qgc2F0aXNmaWVzIFNoYWRlck1vZHVsZTtcblxuY29uc3QgZGlzdGFuY2VGb2dNb2R1bGUgPSB7XG4gIG5hbWU6ICdkaXN0YW5jZUZvZycsXG4gIGZzOiBESVNUQU5DRV9GT0dfVU5JRk9STV9CTE9DSyxcbiAgdW5pZm9ybVR5cGVzOiB7XG4gICAgZGVuc2l0eTogJ2YzMicsXG4gICAgZm9nU3RhcnQ6ICdmMzInLFxuICAgIGZvZ1JhbmdlOiAnZjMyJyxcbiAgICBuZWFyUGxhbmU6ICdmMzInLFxuICAgIGZhclBsYW5lOiAnZjMyJyxcbiAgICBmb2dDb2xvcjogJ3ZlYzM8ZjMyPidcbiAgfSxcbiAgZGVmYXVsdFVuaWZvcm1zOiB7XG4gICAgZGVuc2l0eTogMC41LFxuICAgIGZvZ1N0YXJ0OiAwLjMsXG4gICAgZm9nUmFuZ2U6IDAuNSxcbiAgICBuZWFyUGxhbmU6IDAuMSxcbiAgICBmYXJQbGFuZTogMTAwMCxcbiAgICBmb2dDb2xvcjogWzIxNywgMjIyLCAyMzBdXG4gIH0sXG4gIHByb3BUeXBlczoge1xuICAgIGRlbnNpdHk6IHt2YWx1ZTogMC41LCBtaW46IDAsIG1heDogMX0sXG4gICAgZm9nU3RhcnQ6IHt2YWx1ZTogMC4zLCBtaW46IDAsIG1heDogMX0sXG4gICAgZm9nUmFuZ2U6IHt2YWx1ZTogMC41LCBtaW46IDAuMDEsIG1heDogMX0sXG4gICAgZm9nQ29sb3I6IHt2YWx1ZTogWzIxNywgMjIyLCAyMzBdfSxcbiAgICBuZWFyUGxhbmU6IHt2YWx1ZTogMC4xLCBwcml2YXRlOiB0cnVlfSxcbiAgICBmYXJQbGFuZToge3ZhbHVlOiAxMDAwLCBwcml2YXRlOiB0cnVlfVxuICB9XG59IGFzIGNvbnN0IHNhdGlzZmllcyBTaGFkZXJNb2R1bGU7XG5cbi8qKlxuICogRGlzdGFuY2UgRm9nIEVmZmVjdCAtIHVzZXMgdGhlIGRlcHRoIGJ1ZmZlciB0byBhcHBseSBmb2cgYmFzZWQgb25cbiAqIGNhbWVyYS10by1mcmFnbWVudCBkaXN0YW5jZS4gVGhlIHJhdyBkZXB0aCBidWZmZXIgdmFsdWVzIGFyZSBsaW5lYXJpemVkXG4gKiB1c2luZyB0aGUgY2FtZXJhJ3MgbmVhci9mYXIgcGxhbmVzIChleHRyYWN0ZWQgZnJvbSB0aGUgdmlld3BvcnQgcHJvamVjdGlvblxuICogbWF0cml4KSBzbyB0aGF0IHRoZSBmb2cgZ3JhZGllbnQgaXMgcGVyY2VwdHVhbGx5IHVuaWZvcm0gd2l0aCBkaXN0YW5jZS5cbiAqL1xuZXhwb3J0IGNsYXNzIERlY2tEaXN0YW5jZUZvZ0VmZmVjdCB7XG4gIGlkID0gJ2Rpc3RhbmNlLWZvZy1lZmZlY3QnO1xuICBwcm9wczogRGlzdGFuY2VGb2dQcm9wcztcbiAgbW9kdWxlID0gZGlzdGFuY2VGb2dNb2R1bGU7XG4gIHByaXZhdGUgbW9kZWw6IEluc3RhbmNlVHlwZTx0eXBlb2YgQ2xpcFNwYWNlPiB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBQYXJ0aWFsPERpc3RhbmNlRm9nUHJvcHM+ID0ge30pIHtcbiAgICB0aGlzLnByb3BzID0ge1xuICAgICAgZGVuc2l0eTogMC41LFxuICAgICAgZm9nU3RhcnQ6IDAuMyxcbiAgICAgIGZvZ1JhbmdlOiAwLjUsXG4gICAgICBmb2dDb2xvcjogWzIxNywgMjIyLCAyMzBdLFxuICAgICAgLi4ucHJvcHNcbiAgICB9O1xuICB9XG5cbiAgc2V0dXAoe2RldmljZX0pIHtcbiAgICB0aGlzLm1vZGVsID0gbmV3IENsaXBTcGFjZShkZXZpY2UsIHtcbiAgICAgIGlkOiAnZGlzdGFuY2UtZm9nLXBhc3MnLFxuICAgICAgZnM6IERJU1RBTkNFX0ZPR19GUyxcbiAgICAgIG1vZHVsZXM6IFtkaXN0YW5jZUZvZ01vZHVsZSwgc2NyZWVuTW9kdWxlXSxcbiAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgZGVwdGhXcml0ZUVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICBkZXB0aENvbXBhcmU6ICdhbHdheXMnIGFzIGNvbnN0LFxuICAgICAgICBibGVuZDogdHJ1ZSxcbiAgICAgICAgYmxlbmRDb2xvclNyY0ZhY3RvcjogJ29uZScgYXMgY29uc3QsXG4gICAgICAgIGJsZW5kQ29sb3JEc3RGYWN0b3I6ICdvbmUtbWludXMtc3JjLWFscGhhJyBhcyBjb25zdCxcbiAgICAgICAgYmxlbmRBbHBoYVNyY0ZhY3RvcjogJ29uZScgYXMgY29uc3QsXG4gICAgICAgIGJsZW5kQWxwaGFEc3RGYWN0b3I6ICdvbmUtbWludXMtc3JjLWFscGhhJyBhcyBjb25zdCxcbiAgICAgICAgYmxlbmRDb2xvck9wZXJhdGlvbjogJ2FkZCcgYXMgY29uc3QsXG4gICAgICAgIGJsZW5kQWxwaGFPcGVyYXRpb246ICdhZGQnIGFzIGNvbnN0XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBzZXRQcm9wcyhwcm9wczogUGFydGlhbDxEaXN0YW5jZUZvZ1Byb3BzPikge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5wcm9wcywgcHJvcHMpO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvblxuICBwcmVSZW5kZXIoKTogdm9pZCB7fVxuXG4gIHBvc3RSZW5kZXIocGFyYW1zOiBhbnkpOiBhbnkge1xuICAgIGNvbnN0IHtpbnB1dEJ1ZmZlciwgc3dhcEJ1ZmZlciwgdGFyZ2V0fSA9IHBhcmFtcztcbiAgICBjb25zdCBvdXRwdXRCdWZmZXIgPSB0YXJnZXQgIT09IHVuZGVmaW5lZCA/IHRhcmdldCA6IHN3YXBCdWZmZXI7XG5cbiAgICBpZiAoIXRoaXMubW9kZWwpIHJldHVybiBpbnB1dEJ1ZmZlcjtcblxuICAgIC8vIERpc3RhbmNlIGZvZyBhbHdheXMgcnVucyBmaXJzdCBhbW9uZyBwb3N0LXByb2Nlc3NpbmcgZWZmZWN0c1xuICAgIC8vIChlbmZvcmNlZCBieSBmaXhFZmZlY3RPcmRlciksIHNvIGlucHV0QnVmZmVyIGlzIGFsd2F5cyB0aGUgc2NlbmVcbiAgICAvLyByZW5kZXIgdGFyZ2V0IHdpdGggdmFsaWQgZGVwdGggZGF0YS5cbiAgICBjb25zdCBkZXB0aEF0dGFjaG1lbnQgPSBpbnB1dEJ1ZmZlci5kZXB0aFN0ZW5jaWxBdHRhY2htZW50O1xuICAgIGlmICghZGVwdGhBdHRhY2htZW50KSByZXR1cm4gaW5wdXRCdWZmZXI7XG5cbiAgICBsZXQgbmVhclBsYW5lID0gMC4xO1xuICAgIGxldCBmYXJQbGFuZSA9IDEwMDA7XG4gICAgaWYgKHBhcmFtcy52aWV3cG9ydHM/Lmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHBtID0gcGFyYW1zLnZpZXdwb3J0c1swXS5wcm9qZWN0aW9uTWF0cml4O1xuICAgICAgaWYgKHBtKSB7XG4gICAgICAgIGNvbnN0IG4gPSBwbVsxNF0gLyAocG1bMTBdIC0gMSk7XG4gICAgICAgIGNvbnN0IGYgPSBwbVsxNF0gLyAocG1bMTBdICsgMSk7XG4gICAgICAgIGlmIChOdW1iZXIuaXNGaW5pdGUobikgJiYgTnVtYmVyLmlzRmluaXRlKGYpICYmIG4gPiAwICYmIGYgPiBuKSB7XG4gICAgICAgICAgbmVhclBsYW5lID0gbjtcbiAgICAgICAgICBmYXJQbGFuZSA9IGY7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB0ZXhTaXplOiBbbnVtYmVyLCBudW1iZXJdID0gW2lucHV0QnVmZmVyLndpZHRoLCBpbnB1dEJ1ZmZlci5oZWlnaHRdO1xuXG4gICAgdGhpcy5tb2RlbC5zaGFkZXJJbnB1dHMuc2V0UHJvcHMoe1xuICAgICAgc2NyZWVuOiB7XG4gICAgICAgIHRleFNyYzogaW5wdXRCdWZmZXIuY29sb3JBdHRhY2htZW50c1swXSxcbiAgICAgICAgdGV4U2l6ZVxuICAgICAgfSxcbiAgICAgIGRpc3RhbmNlRm9nOiB7XG4gICAgICAgIHRleERlcHRoOiBkZXB0aEF0dGFjaG1lbnQsXG4gICAgICAgIGRlbnNpdHk6IHRoaXMucHJvcHMuZGVuc2l0eSxcbiAgICAgICAgZm9nU3RhcnQ6IHRoaXMucHJvcHMuZm9nU3RhcnQsXG4gICAgICAgIGZvZ1JhbmdlOiB0aGlzLnByb3BzLmZvZ1JhbmdlLFxuICAgICAgICBuZWFyUGxhbmUsXG4gICAgICAgIGZhclBsYW5lLFxuICAgICAgICBmb2dDb2xvcjogdGhpcy5wcm9wcy5mb2dDb2xvclxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVuZGVyUGFzcyA9IHRoaXMubW9kZWwuZGV2aWNlLmJlZ2luUmVuZGVyUGFzcyh7XG4gICAgICBmcmFtZWJ1ZmZlcjogb3V0cHV0QnVmZmVyLFxuICAgICAgcGFyYW1ldGVyczoge3ZpZXdwb3J0OiBbMCwgMCwgLi4udGV4U2l6ZV19LFxuICAgICAgY2xlYXJDb2xvcjogWzAsIDAsIDAsIDBdLFxuICAgICAgY2xlYXJEZXB0aDogMVxuICAgIH0pO1xuICAgIHRoaXMubW9kZWwuZHJhdyhyZW5kZXJQYXNzKTtcbiAgICByZW5kZXJQYXNzLmVuZCgpO1xuXG4gICAgcmV0dXJuIG91dHB1dEJ1ZmZlciB8fCBpbnB1dEJ1ZmZlcjtcbiAgfVxuXG4gIGNsZWFudXAoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubW9kZWwpIHtcbiAgICAgIHRoaXMubW9kZWwuZGVzdHJveSgpO1xuICAgICAgdGhpcy5tb2RlbCA9IG51bGw7XG4gICAgfVxuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFHQSxJQUFBQSxPQUFBLEdBQUFDLE9BQUE7QUFBMEMsU0FBQUMsUUFBQUMsQ0FBQSxFQUFBQyxDQUFBLFFBQUFDLENBQUEsR0FBQUMsTUFBQSxDQUFBQyxJQUFBLENBQUFKLENBQUEsT0FBQUcsTUFBQSxDQUFBRSxxQkFBQSxRQUFBQyxDQUFBLEdBQUFI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