UNPKG

@nebula.gl/layers

Version:

A suite of 3D-enabled data editing layers, suitable for deck.gl

235 lines (183 loc) 24.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.toDeckColor = toDeckColor; exports.recursivelyTraverseNestedArrays = recursivelyTraverseNestedArrays; exports.generatePointsParallelToLinePoints = generatePointsParallelToLinePoints; exports.distance2d = distance2d; exports.mix = mix; exports.nearestPointOnProjectedLine = nearestPointOnProjectedLine; exports.insertBefore = insertBefore; var _destination = _interopRequireDefault(require("@turf/destination")); var _bearing = _interopRequireDefault(require("@turf/bearing")); var _pointToLineDistance = _interopRequireDefault(require("@turf/point-to-line-distance")); var _helpers = require("@turf/helpers"); var _viewportMercatorProject = _interopRequireDefault(require("viewport-mercator-project")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function toDeckColor(color) { var defaultColor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [255, 0, 0, 255]; if (!Array.isArray(color)) { return defaultColor; } return [color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]; } // // a GeoJSON helper function that calls the provided function with // an argument that is the most deeply-nested array having elements // that are arrays of primitives as an argument, e.g. // // { // "type": "MultiPolygon", // "coordinates": [ // [ // [[30, 20], [45, 40], [10, 40], [30, 20]] // ], // [ // [[15, 5], [40, 10], [10, 20], [5, 10], [15, 5]] // ] // ] // } // // the function would be called on: // // [[30, 20], [45, 40], [10, 40], [30, 20]] // // and // // [[15, 5], [40, 10], [10, 20], [5, 10], [15, 5]] // function recursivelyTraverseNestedArrays(array, prefix, fn) { if (!Array.isArray(array[0])) { return true; } for (var i = 0; i < array.length; i++) { if (recursivelyTraverseNestedArrays(array[i], [].concat(_toConsumableArray(prefix), [i]), fn)) { fn(array, prefix); break; } } return false; } function generatePointsParallelToLinePoints(p1, p2, groundCoords) { var lineString = { type: 'LineString', coordinates: [p1, p2] }; var pt = (0, _helpers.point)(groundCoords); var ddistance = (0, _pointToLineDistance["default"])(pt, lineString); var lineBearing = (0, _bearing["default"])(p1, p2); // Check if current point is to the left or right of line // Line from A=(x1,y1) to B=(x2,y2) a point P=(x,y) // then (x−x1)(y2−y1)−(y−y1)(x2−x1) var isPointToLeftOfLine = (groundCoords[0] - p1[0]) * (p2[1] - p1[1]) - (groundCoords[1] - p1[1]) * (p2[0] - p1[0]); // Bearing to draw perpendicular to the line string var orthogonalBearing = isPointToLeftOfLine < 0 ? lineBearing - 90 : lineBearing - 270; // Get coordinates for the point p3 and p4 which are perpendicular to the lineString // Add the distance as the current position moves away from the lineString var p3 = (0, _destination["default"])(p2, ddistance, orthogonalBearing); var p4 = (0, _destination["default"])(p1, ddistance, orthogonalBearing); //@ts-ignore return [p3.geometry.coordinates, p4.geometry.coordinates]; } function distance2d(x1, y1, x2, y2) { var dx = x1 - x2; var dy = y1 - y2; return Math.sqrt(dx * dx + dy * dy); } function mix(a, b, ratio) { return b * ratio + a * (1 - ratio); } function nearestPointOnProjectedLine(line, inPoint, viewport) { var wmViewport = new _viewportMercatorProject["default"](viewport); // Project the line to viewport, then find the nearest point var coordinates = line.geometry.coordinates; var projectedCoords = coordinates.map(function (_ref) { var _ref2 = _slicedToArray(_ref, 3), x = _ref2[0], y = _ref2[1], _ref2$ = _ref2[2], z = _ref2$ === void 0 ? 0 : _ref2$; return wmViewport.project([x, y, z]); }); //@ts-ignore var _wmViewport$project = wmViewport.project(inPoint.geometry.coordinates), _wmViewport$project2 = _slicedToArray(_wmViewport$project, 2), x = _wmViewport$project2[0], y = _wmViewport$project2[1]; // console.log('projectedCoords', JSON.stringify(projectedCoords)); var minDistance = Infinity; var minPointInfo = {}; projectedCoords.forEach(function (_ref3, index) { var _ref4 = _slicedToArray(_ref3, 2), x2 = _ref4[0], y2 = _ref4[1]; if (index === 0) { return; } var _projectedCoords = _slicedToArray(projectedCoords[index - 1], 2), x1 = _projectedCoords[0], y1 = _projectedCoords[1]; // line from projectedCoords[index - 1] to projectedCoords[index] // convert to Ax + By + C = 0 var A = y1 - y2; var B = x2 - x1; var C = x1 * y2 - x2 * y1; // https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line var div = A * A + B * B; var distance = Math.abs(A * x + B * y + C) / Math.sqrt(div); // TODO: Check if inside bounds if (distance < minDistance) { minDistance = distance; minPointInfo = { index: index, x0: (B * (B * x - A * y) - A * C) / div, y0: (A * (-B * x + A * y) - B * C) / div }; } }); //@ts-ignore var _minPointInfo = minPointInfo, index = _minPointInfo.index, x0 = _minPointInfo.x0, y0 = _minPointInfo.y0; var _projectedCoords2 = _slicedToArray(projectedCoords[index - 1], 3), x1 = _projectedCoords2[0], y1 = _projectedCoords2[1], _projectedCoords2$ = _projectedCoords2[2], z1 = _projectedCoords2$ === void 0 ? 0 : _projectedCoords2$; var _projectedCoords$inde = _slicedToArray(projectedCoords[index], 3), x2 = _projectedCoords$inde[0], y2 = _projectedCoords$inde[1], _projectedCoords$inde2 = _projectedCoords$inde[2], z2 = _projectedCoords$inde2 === void 0 ? 0 : _projectedCoords$inde2; // calculate what ratio of the line we are on to find the proper z var lineLength = distance2d(x1, y1, x2, y2); var startToPointLength = distance2d(x1, y1, x0, y0); var ratio = startToPointLength / lineLength; var z0 = mix(z1, z2, ratio); return { type: 'Feature', geometry: { type: 'Point', coordinates: wmViewport.unproject([x0, y0, z0]) }, properties: { // TODO: calculate the distance in proper units dist: minDistance, index: index - 1 } }; } /** * Inserts toInsert string into base string before insertBefore string. * @param base A string to insert into. * @param insertBefore A sub string in `base` string to insert before. * @param toInsert A string to insert. * @returns Combined string. `base` string if `insertBefore` string isn't found. */ function insertBefore(base, insertBefore, toInsert) { var at = base.indexOf(insertBefore); if (at < 0) { return base; } return base.slice(0, at) + toInsert + base.slice(at); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy91dGlscy50cyJdLCJuYW1lcyI6WyJ0b0RlY2tDb2xvciIsImNvbG9yIiwiZGVmYXVsdENvbG9yIiwiQXJyYXkiLCJpc0FycmF5IiwicmVjdXJzaXZlbHlUcmF2ZXJzZU5lc3RlZEFycmF5cyIsImFycmF5IiwicHJlZml4IiwiZm4iLCJpIiwibGVuZ3RoIiwiZ2VuZXJhdGVQb2ludHNQYXJhbGxlbFRvTGluZVBvaW50cyIsInAxIiwicDIiLCJncm91bmRDb29yZHMiLCJsaW5lU3RyaW5nIiwidHlwZSIsImNvb3JkaW5hdGVzIiwicHQiLCJkZGlzdGFuY2UiLCJsaW5lQmVhcmluZyIsImlzUG9pbnRUb0xlZnRPZkxpbmUiLCJvcnRob2dvbmFsQmVhcmluZyIsInAzIiwicDQiLCJnZW9tZXRyeSIsImRpc3RhbmNlMmQiLCJ4MSIsInkxIiwieDIiLCJ5MiIsImR4IiwiZHkiLCJNYXRoIiwic3FydCIsIm1peCIsImEiLCJiIiwicmF0aW8iLCJuZWFyZXN0UG9pbnRPblByb2plY3RlZExpbmUiLCJsaW5lIiwiaW5Qb2ludCIsInZpZXdwb3J0Iiwid21WaWV3cG9ydCIsIldlYk1lcmNhdG9yVmlld3BvcnQiLCJwcm9qZWN0ZWRDb29yZHMiLCJtYXAiLCJ4IiwieSIsInoiLCJwcm9qZWN0IiwibWluRGlzdGFuY2UiLCJJbmZpbml0eSIsIm1pblBvaW50SW5mbyIsImZvckVhY2giLCJpbmRleCIsIkEiLCJCIiwiQyIsImRpdiIsImRpc3RhbmNlIiwiYWJzIiwieDAiLCJ5MCIsInoxIiwiejIiLCJsaW5lTGVuZ3RoIiwic3RhcnRUb1BvaW50TGVuZ3RoIiwiejAiLCJ1bnByb2plY3QiLCJwcm9wZXJ0aWVzIiwiZGlzdCIsImluc2VydEJlZm9yZSIsImJhc2UiLCJ0b0luc2VydCIsImF0IiwiaW5kZXhPZiIsInNsaWNlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBU0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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VUFBVSxDQUFDMEIsU0FBWCxDQUFxQixDQUFDUCxFQUFELEVBQUtDLEVBQUwsRUFBU0ssRUFBVCxDQUFyQjtBQUZMLEtBRkw7QUFNTEUsSUFBQUEsVUFBVSxFQUFFO0FBQ1Y7QUFDQUMsTUFBQUEsSUFBSSxFQUFFcEIsV0FGSTtBQUdWSSxNQUFBQSxLQUFLLEVBQUVBLEtBQUssR0FBRztBQUhMO0FBTlAsR0FBUDtBQVlEO0FBRUQ7Ozs7Ozs7OztBQU9PLFNBQVNpQixZQUFULENBQXNCQyxJQUF0QixFQUFvQ0QsWUFBcEMsRUFBMERFLFFBQTFELEVBQW9GO0FBQ3pGLE1BQU1DLEVBQUUsR0FBR0YsSUFBSSxDQUFDRyxPQUFMLENBQWFKLFlBQWIsQ0FBWDs7QUFDQSxNQUFJRyxFQUFFLEdBQUcsQ0FBVCxFQUFZO0FBQ1YsV0FBT0YsSUFBUDtBQUNEOztBQUNELFNBQU9BLElBQUksQ0FBQ0ksS0FBTCxDQUFXLENBQVgsRUFBY0YsRUFBZCxJQUFvQkQsUUFBcEIsR0FBK0JELElBQUksQ0FBQ0ksS0FBTCxDQUFXRixFQUFYLENBQXRDO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZGVzdGluYXRpb24gZnJvbSAnQHR1cmYvZGVzdGluYXRpb24nO1xuaW1wb3J0IGJlYXJpbmcgZnJvbSAnQHR1cmYvYmVhcmluZyc7XG5pbXBvcnQgcG9pbnRUb0xpbmVEaXN0YW5jZSBmcm9tICdAdHVyZi9wb2ludC10by1saW5lLWRpc3RhbmNlJztcbmltcG9ydCB7IHBvaW50IH0gZnJvbSAnQHR1cmYvaGVscGVycyc7XG5pbXBvcnQge1xuICBQb3NpdGlvbixcbiAgUG9pbnQsXG4gIExpbmVTdHJpbmcsXG4gIEZlYXR1cmVPZixcbiAgRmVhdHVyZVdpdGhQcm9wcyxcbiAgVmlld3BvcnQsXG59IGZyb20gJ0BuZWJ1bGEuZ2wvZWRpdC1tb2Rlcyc7XG5pbXBvcnQgV2ViTWVyY2F0b3JWaWV3cG9ydCBmcm9tICd2aWV3cG9ydC1tZXJjYXRvci1wcm9qZWN0JztcblxuLy8gVE9ETyBlZGl0LW1vZGVzOiBkZWxldGUgYW5kIHVzZSBlZGl0LW1vZGVzL3V0aWxzIGluc3RlYWRcblxuZXhwb3J0IHR5cGUgTmVhcmVzdFBvaW50VHlwZSA9IEZlYXR1cmVXaXRoUHJvcHM8UG9pbnQsIHsgZGlzdDogbnVtYmVyOyBpbmRleDogbnVtYmVyIH0+O1xuXG5leHBvcnQgZnVuY3Rpb24gdG9EZWNrQ29sb3IoXG4gIGNvbG9yPzogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gfCBudW1iZXIsXG4gIGRlZmF1bHRDb2xvcjogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMjU1LCAwLCAwLCAyNTVdXG4pOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShjb2xvcikpIHtcbiAgICByZXR1cm4gZGVmYXVsdENvbG9yO1xuICB9XG4gIHJldHVybiBbY29sb3JbMF0gKiAyNTUsIGNvbG9yWzFdICogMjU1LCBjb2xvclsyXSAqIDI1NSwgY29sb3JbM10gKiAyNTVdO1xufVxuXG4vL1xuLy8gYSBHZW9KU09OIGhlbHBlciBmdW5jdGlvbiB0aGF0IGNhbGxzIHRoZSBwcm92aWRlZCBmdW5jdGlvbiB3aXRoXG4vLyBhbiBhcmd1bWVudCB0aGF0IGlzIHRoZSBtb3N0IGRlZXBseS1uZXN0ZWQgYXJyYXkgaGF2aW5nIGVsZW1lbnRzXG4vLyB0aGF0IGFyZSBhcnJheXMgb2YgcHJpbWl0aXZlcyBhcyBhbiBhcmd1bWVudCwgZS5nLlxuLy9cbi8vIHtcbi8vICAgXCJ0eXBlXCI6IFwiTXVsdGlQb2x5Z29uXCIsXG4vLyAgIFwiY29vcmRpbmF0ZXNcIjogW1xuLy8gICAgICAgW1xuLy8gICAgICAgICAgIFtbMzAsIDIwXSwgWzQ1LCA0MF0sIFsxMCwgNDBdLCBbMzAsIDIwXV1cbi8vICAgICAgIF0sXG4vLyAgICAgICBbXG4vLyAgICAgICAgICAgW1sxNSwgNV0sIFs0MCwgMTBdLCBbMTAsIDIwXSwgWzUsIDEwXSwgWzE1LCA1XV1cbi8vICAgICAgIF1cbi8vICAgXVxuLy8gfVxuLy9cbi8vIHRoZSBmdW5jdGlvbiB3b3VsZCBiZSBjYWxsZWQgb246XG4vL1xuLy8gW1szMCwgMjBdLCBbNDUsIDQwXSwgWzEwLCA0MF0sIFszMCwgMjBdXVxuLy9cbi8vIGFuZFxuLy9cbi8vIFtbMTUsIDVdLCBbNDAsIDEwXSwgWzEwLCAyMF0sIFs1LCAxMF0sIFsxNSwgNV1dXG4vL1xuZXhwb3J0IGZ1bmN0aW9uIHJlY3Vyc2l2ZWx5VHJhdmVyc2VOZXN0ZWRBcnJheXMoXG4gIGFycmF5OiBBcnJheTxhbnk+LFxuICBwcmVmaXg6IEFycmF5PG51bWJlcj4sXG4gIGZuOiBGdW5jdGlvblxuKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShhcnJheVswXSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHJlY3Vyc2l2ZWx5VHJhdmVyc2VOZXN0ZWRBcnJheXMoYXJyYXlbaV0sIFsuLi5wcmVmaXgsIGldLCBmbikpIHtcbiAgICAgIGZuKGFycmF5LCBwcmVmaXgpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlUG9pbnRzUGFyYWxsZWxUb0xpbmVQb2ludHMoXG4gIHAxOiBQb3NpdGlvbixcbiAgcDI6IFBvc2l0aW9uLFxuICBncm91bmRDb29yZHM6IFBvc2l0aW9uXG4pOiBQb3NpdGlvbltdIHtcbiAgY29uc3QgbGluZVN0cmluZzogTGluZVN0cmluZyA9IHtcbiAgICB0eXBlOiAnTGluZVN0cmluZycsXG4gICAgY29vcmRpbmF0ZXM6IFtwMSwgcDJdLFxuICB9O1xuICBjb25zdCBwdCA9IHBvaW50KGdyb3VuZENvb3Jkcyk7XG4gIGNvbnN0IGRkaXN0YW5jZSA9IHBvaW50VG9MaW5lRGlzdGFuY2UocHQsIGxpbmVTdHJpbmcpO1xuICBjb25zdCBsaW5lQmVhcmluZyA9IGJlYXJpbmcocDEsIHAyKTtcblxuICAvLyBDaGVjayBpZiBjdXJyZW50IHBvaW50IGlzIHRvIHRoZSBsZWZ0IG9yIHJpZ2h0IG9mIGxpbmVcbiAgLy8gTGluZSBmcm9tIEE9KHgxLHkxKSB0byBCPSh4Mix5MikgYSBwb2ludCBQPSh4LHkpXG4gIC8vIHRoZW4gKHjiiJJ4MSkoeTLiiJJ5MSniiJIoeeKIknkxKSh4MuKIkngxKVxuICBjb25zdCBpc1BvaW50VG9MZWZ0T2ZMaW5lID1cbiAgICAoZ3JvdW5kQ29vcmRzWzBdIC0gcDFbMF0pICogKHAyWzFdIC0gcDFbMV0pIC0gKGdyb3VuZENvb3Jkc1sxXSAtIHAxWzFdKSAqIChwMlswXSAtIHAxWzBdKTtcblxuICAvLyBCZWFyaW5nIHRvIGRyYXcgcGVycGVuZGljdWxhciB0byB0aGUgbGluZSBzdHJpbmdcbiAgY29uc3Qgb3J0aG9nb25hbEJlYXJpbmcgPSBpc1BvaW50VG9MZWZ0T2ZMaW5lIDwgMCA/IGxpbmVCZWFyaW5nIC0gOTAgOiBsaW5lQmVhcmluZyAtIDI3MDtcblxuICAvLyBHZXQgY29vcmRpbmF0ZXMgZm9yIHRoZSBwb2ludCBwMyBhbmQgcDQgd2hpY2ggYXJlIHBlcnBlbmRpY3VsYXIgdG8gdGhlIGxpbmVTdHJpbmdcbiAgLy8gQWRkIHRoZSBkaXN0YW5jZSBhcyB0aGUgY3VycmVudCBwb3NpdGlvbiBtb3ZlcyBhd2F5IGZyb20gdGhlIGxpbmVTdHJpbmdcbiAgY29uc3QgcDMgPSBkZXN0aW5hdGlvbihwMiwgZGRpc3RhbmNlLCBvcnRob2dvbmFsQmVhcmluZyk7XG4gIGNvbnN0IHA0ID0gZGVzdGluYXRpb24ocDEsIGRkaXN0YW5jZSwgb3J0aG9nb25hbEJlYXJpbmcpO1xuICAvL0B0cy1pZ25vcmVcbiAgcmV0dXJuIFtwMy5nZW9tZXRyeS5jb29yZGluYXRlcywgcDQuZ2VvbWV0cnkuY29vcmRpbmF0ZXNdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGlzdGFuY2UyZCh4MTogbnVtYmVyLCB5MTogbnVtYmVyLCB4MjogbnVtYmVyLCB5MjogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3QgZHggPSB4MSAtIHgyO1xuICBjb25zdCBkeSA9IHkxIC0geTI7XG4gIHJldHVybiBNYXRoLnNxcnQoZHggKiBkeCArIGR5ICogZHkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWl4KGE6IG51bWJlciwgYjogbnVtYmVyLCByYXRpbzogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIGIgKiByYXRpbyArIGEgKiAoMSAtIHJhdGlvKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5lYXJlc3RQb2ludE9uUHJvamVjdGVkTGluZShcbiAgbGluZTogRmVhdHVyZU9mPExpbmVTdHJpbmc+LFxuICBpblBvaW50OiBGZWF0dXJlT2Y8UG9pbnQ+LFxuICB2aWV3cG9ydDogVmlld3BvcnRcbik6IE5lYXJlc3RQb2ludFR5cGUge1xuICBjb25zdCB3bVZpZXdwb3J0ID0gbmV3IFdlYk1lcmNhdG9yVmlld3BvcnQodmlld3BvcnQpO1xuICAvLyBQcm9qZWN0IHRoZSBsaW5lIHRvIHZpZXdwb3J0LCB0aGVuIGZpbmQgdGhlIG5lYXJlc3QgcG9pbnRcbiAgY29uc3QgY29vcmRpbmF0ZXM6IEFycmF5PEFycmF5PG51bWJlcj4+ID0gbGluZS5nZW9tZXRyeS5jb29yZGluYXRlcyBhcyBhbnk7XG4gIGNvbnN0IHByb2plY3RlZENvb3JkcyA9IGNvb3JkaW5hdGVzLm1hcCgoW3gsIHksIHogPSAwXSkgPT4gd21WaWV3cG9ydC5wcm9qZWN0KFt4LCB5LCB6XSkpO1xuICAvL0B0cy1pZ25vcmVcbiAgY29uc3QgW3gsIHldID0gd21WaWV3cG9ydC5wcm9qZWN0KGluUG9pbnQuZ2VvbWV0cnkuY29vcmRpbmF0ZXMpO1xuICAvLyBjb25zb2xlLmxvZygncHJvamVjdGVkQ29vcmRzJywgSlNPTi5zdHJpbmdpZnkocHJvamVjdGVkQ29vcmRzKSk7XG5cbiAgbGV0IG1pbkRpc3RhbmNlID0gSW5maW5pdHk7XG4gIGxldCBtaW5Qb2ludEluZm8gPSB7fTtcblxuICBwcm9qZWN0ZWRDb29yZHMuZm9yRWFjaCgoW3gyLCB5Ml0sIGluZGV4KSA9PiB7XG4gICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgW3gxLCB5MV0gPSBwcm9qZWN0ZWRDb29yZHNbaW5kZXggLSAxXTtcblxuICAgIC8vIGxpbmUgZnJvbSBwcm9qZWN0ZWRDb29yZHNbaW5kZXggLSAxXSB0byBwcm9qZWN0ZWRDb29yZHNbaW5kZXhdXG4gICAgLy8gY29udmVydCB0byBBeCArIEJ5ICsgQyA9IDBcbiAgICBjb25zdCBBID0geTEgLSB5MjtcbiAgICBjb25zdCBCID0geDIgLSB4MTtcbiAgICBjb25zdCBDID0geDEgKiB5MiAtIHgyICogeTE7XG5cbiAgICAvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9EaXN0YW5jZV9mcm9tX2FfcG9pbnRfdG9fYV9saW5lXG4gICAgY29uc3QgZGl2ID0gQSAqIEEgKyBCICogQjtcbiAgICBjb25zdCBkaXN0YW5jZSA9IE1hdGguYWJzKEEgKiB4ICsgQiAqIHkgKyBDKSAvIE1hdGguc3FydChkaXYpO1xuXG4gICAgLy8gVE9ETzogQ2hlY2sgaWYgaW5zaWRlIGJvdW5kc1xuXG4gICAgaWYgKGRpc3RhbmNlIDwgbWluRGlzdGFuY2UpIHtcbiAgICAgIG1pbkRpc3RhbmNlID0gZGlzdGFuY2U7XG4gICAgICBtaW5Qb2ludEluZm8gPSB7XG4gICAgICAgIGluZGV4LFxuICAgICAgICB4MDogKEIgKiAoQiAqIHggLSBBICogeSkgLSBBICogQykgLyBkaXYsXG4gICAgICAgIHkwOiAoQSAqICgtQiAqIHggKyBBICogeSkgLSBCICogQykgLyBkaXYsXG4gICAgICB9O1xuICAgIH1cbiAgfSk7XG4gIC8vQHRzLWlnbm9yZVxuICBjb25zdCB7IGluZGV4LCB4MCwgeTAgfSA9IG1pblBvaW50SW5mbztcbiAgY29uc3QgW3gxLCB5MSwgejEgPSAwXSA9IHByb2plY3RlZENvb3Jkc1tpbmRleCAtIDFdO1xuICBjb25zdCBbeDIsIHkyLCB6MiA9IDBdID0gcHJvamVjdGVkQ29vcmRzW2luZGV4XTtcblxuICAvLyBjYWxjdWxhdGUgd2hhdCByYXRpbyBvZiB0aGUgbGluZSB3ZSBhcmUgb24gdG8gZmluZCB0aGUgcHJvcGVyIHpcbiAgY29uc3QgbGluZUxlbmd0aCA9IGRpc3RhbmNlMmQoeDEsIHkxLCB4MiwgeTIpO1xuICBjb25zdCBzdGFydFRvUG9pbnRMZW5ndGggPSBkaXN0YW5jZTJkKHgxLCB5MSwgeDAsIHkwKTtcbiAgY29uc3QgcmF0aW8gPSBzdGFydFRvUG9pbnRMZW5ndGggLyBsaW5lTGVuZ3RoO1xuICBjb25zdCB6MCA9IG1peCh6MSwgejIsIHJhdGlvKTtcblxuICByZXR1cm4ge1xuICAgIHR5cGU6ICdGZWF0dXJlJyxcbiAgICBnZW9tZXRyeToge1xuICAgICAgdHlwZTogJ1BvaW50JyxcbiAgICAgIGNvb3JkaW5hdGVzOiB3bVZpZXdwb3J0LnVucHJvamVjdChbeDAsIHkwLCB6MF0pLFxuICAgIH0sXG4gICAgcHJvcGVydGllczoge1xuICAgICAgLy8gVE9ETzogY2FsY3VsYXRlIHRoZSBkaXN0YW5jZSBpbiBwcm9wZXIgdW5pdHNcbiAgICAgIGRpc3Q6IG1pbkRpc3RhbmNlLFxuICAgICAgaW5kZXg6IGluZGV4IC0gMSxcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIEluc2VydHMgdG9JbnNlcnQgc3RyaW5nIGludG8gYmFzZSBzdHJpbmcgYmVmb3JlIGluc2VydEJlZm9yZSBzdHJpbmcuXG4gKiBAcGFyYW0gYmFzZSBBIHN0cmluZyB0byBpbnNlcnQgaW50by5cbiAqIEBwYXJhbSBpbnNlcnRCZWZvcmUgQSBzdWIgc3RyaW5nIGluIGBiYXNlYCBzdHJpbmcgdG8gaW5zZXJ0IGJlZm9yZS5cbiAqIEBwYXJhbSB0b0luc2VydCBBIHN0cmluZyB0byBpbnNlcnQuXG4gKiBAcmV0dXJucyBDb21iaW5lZCBzdHJpbmcuIGBiYXNlYCBzdHJpbmcgaWYgYGluc2VydEJlZm9yZWAgc3RyaW5nIGlzbid0IGZvdW5kLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5zZXJ0QmVmb3JlKGJhc2U6IHN0cmluZywgaW5zZXJ0QmVmb3JlOiBzdHJpbmcsIHRvSW5zZXJ0OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBhdCA9IGJhc2UuaW5kZXhPZihpbnNlcnRCZWZvcmUpO1xuICBpZiAoYXQgPCAwKSB7XG4gICAgcmV0dXJuIGJhc2U7XG4gIH1cbiAgcmV0dXJuIGJhc2Uuc2xpY2UoMCwgYXQpICsgdG9JbnNlcnQgKyBiYXNlLnNsaWNlKGF0KTtcbn1cbiJdfQ==