js-angusj-clipper
Version:
Polygon and line clipping and offsetting library for Javascript / Typescript - a port of Angus Johnson's clipper to WebAssembly / Asm.JS
296 lines • 36 kB
JavaScript
;
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.scalePaths = exports.scalePath = exports.simplifyPolygons = exports.simplifyPolygon = exports.reversePaths = exports.reversePath = exports.polyTreeToPaths = exports.pointInPolygon = exports.orientation = exports.openPathsFromPolyTree = exports.minkowskiSumPaths = exports.minkowskiSumPath = exports.minkowskiDiff = exports.closedPathsFromPolyTree = exports.cleanPolygons = exports.cleanPolygon = exports.area = void 0;
var enums_1 = require("./enums");
var nativeEnumConversion_1 = require("./native/nativeEnumConversion");
var PathsToNativePaths_1 = require("./native/PathsToNativePaths");
var PathToNativePath_1 = require("./native/PathToNativePath");
function tryDelete() {
var e_1, _a;
var objs = [];
for (var _i = 0; _i < arguments.length; _i++) {
objs[_i] = arguments[_i];
}
try {
for (var objs_1 = __values(objs), objs_1_1 = objs_1.next(); !objs_1_1.done; objs_1_1 = objs_1.next()) {
var obj = objs_1_1.value;
if (!obj.isDeleted()) {
obj.delete();
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (objs_1_1 && !objs_1_1.done && (_a = objs_1.return)) _a.call(objs_1);
}
finally { if (e_1) throw e_1.error; }
}
}
function area(path) {
// we use JS since copying structures is slower than actually doing it
var cnt = path.length;
if (cnt < 3) {
return 0;
}
var a = 0;
for (var i = 0, j = cnt - 1; i < cnt; ++i) {
a += (path[j].x + path[i].x) * (path[j].y - path[i].y);
j = i;
}
return -a * 0.5;
}
exports.area = area;
function cleanPolygon(nativeLib, path, distance) {
if (distance === void 0) { distance = 1.1415; }
var nativePath = PathToNativePath_1.pathToNativePath(nativeLib, path);
try {
nativeLib.cleanPolygon(nativePath, distance);
return PathToNativePath_1.nativePathToPath(nativeLib, nativePath, true); // frees nativePath
}
finally {
tryDelete(nativePath);
}
}
exports.cleanPolygon = cleanPolygon;
function cleanPolygons(nativeLib, paths, distance) {
if (distance === void 0) { distance = 1.1415; }
var nativePaths = PathsToNativePaths_1.pathsToNativePaths(nativeLib, paths);
try {
nativeLib.cleanPolygons(nativePaths, distance);
return PathsToNativePaths_1.nativePathsToPaths(nativeLib, nativePaths, true); // frees nativePath
}
finally {
tryDelete(nativePaths);
}
}
exports.cleanPolygons = cleanPolygons;
function addPolyNodeToPaths(polynode, nt, paths) {
var match = true;
switch (nt) {
case 1 /* Open */:
return;
case 2 /* Closed */:
match = !polynode.isOpen;
break;
default:
break;
}
if (polynode.contour.length > 0 && match) {
paths.push(polynode.contour);
}
for (var ii = 0, max = polynode.childs.length; ii < max; ii++) {
var pn = polynode.childs[ii];
addPolyNodeToPaths(pn, nt, paths);
}
}
function closedPathsFromPolyTree(polyTree) {
// we do this in JS since copying path is more expensive than just doing it
var result = [];
// result.Capacity = polytree.Total;
addPolyNodeToPaths(polyTree, 2 /* Closed */, result);
return result;
}
exports.closedPathsFromPolyTree = closedPathsFromPolyTree;
function minkowskiDiff(nativeLib, poly1, poly2) {
var nativePath1 = PathToNativePath_1.pathToNativePath(nativeLib, poly1);
var nativePath2 = PathToNativePath_1.pathToNativePath(nativeLib, poly2);
var outNativePaths = new nativeLib.Paths();
try {
nativeLib.minkowskiDiff(nativePath1, nativePath2, outNativePaths);
tryDelete(nativePath1, nativePath2);
return PathsToNativePaths_1.nativePathsToPaths(nativeLib, outNativePaths, true); // frees outNativePaths
}
finally {
tryDelete(nativePath1, nativePath2, outNativePaths);
}
}
exports.minkowskiDiff = minkowskiDiff;
function minkowskiSumPath(nativeLib, pattern, path, pathIsClosed) {
var patternNativePath = PathToNativePath_1.pathToNativePath(nativeLib, pattern);
var nativePath = PathToNativePath_1.pathToNativePath(nativeLib, path);
var outNativePaths = new nativeLib.Paths();
try {
nativeLib.minkowskiSumPath(patternNativePath, nativePath, outNativePaths, pathIsClosed);
tryDelete(patternNativePath, nativePath);
return PathsToNativePaths_1.nativePathsToPaths(nativeLib, outNativePaths, true); // frees outNativePaths
}
finally {
tryDelete(patternNativePath, nativePath, outNativePaths);
}
}
exports.minkowskiSumPath = minkowskiSumPath;
function minkowskiSumPaths(nativeLib, pattern, paths, pathIsClosed) {
// TODO: im not sure if for this method we can reuse the input/output path
var patternNativePath = PathToNativePath_1.pathToNativePath(nativeLib, pattern);
var nativePaths = PathsToNativePaths_1.pathsToNativePaths(nativeLib, paths);
try {
nativeLib.minkowskiSumPaths(patternNativePath, nativePaths, nativePaths, pathIsClosed);
tryDelete(patternNativePath);
return PathsToNativePaths_1.nativePathsToPaths(nativeLib, nativePaths, true); // frees nativePaths
}
finally {
tryDelete(patternNativePath, nativePaths);
}
}
exports.minkowskiSumPaths = minkowskiSumPaths;
function openPathsFromPolyTree(polyTree) {
// we do this in JS since copying path is more expensive than just doing it
var result = [];
var len = polyTree.childs.length;
result.length = len;
var resultLength = 0;
for (var i = 0; i < len; i++) {
if (polyTree.childs[i].isOpen) {
result[resultLength++] = polyTree.childs[i].contour;
}
}
result.length = resultLength;
return result;
}
exports.openPathsFromPolyTree = openPathsFromPolyTree;
function orientation(path) {
return area(path) >= 0;
}
exports.orientation = orientation;
function pointInPolygon(point, path) {
// we do this in JS since copying path is more expensive than just doing it
// returns 0 if false, +1 if true, -1 if pt ON polygon boundary
// See "The Point in Polygon Problem for Arbitrary Polygons" by Hormann & Agathos
// http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.5498&rep=rep1&type=pdf
var result = 0;
var cnt = path.length;
if (cnt < 3) {
return 0;
}
var ip = path[0];
for (var i = 1; i <= cnt; ++i) {
var ipNext = i === cnt ? path[0] : path[i];
if (ipNext.y === point.y) {
if (ipNext.x === point.x || (ip.y === point.y && ipNext.x > point.x === ip.x < point.x)) {
return -1;
}
}
if (ip.y < point.y !== ipNext.y < point.y) {
if (ip.x >= point.x) {
if (ipNext.x > point.x) {
result = 1 - result;
}
else {
var d = (ip.x - point.x) * (ipNext.y - point.y) - (ipNext.x - point.x) * (ip.y - point.y);
if (d === 0) {
return -1;
}
else if (d > 0 === ipNext.y > ip.y) {
result = 1 - result;
}
}
}
else {
if (ipNext.x > point.x) {
var d = (ip.x - point.x) * (ipNext.y - point.y) - (ipNext.x - point.x) * (ip.y - point.y);
if (d === 0) {
return -1;
}
else if (d > 0 === ipNext.y > ip.y) {
result = 1 - result;
}
}
}
}
ip = ipNext;
}
return result;
}
exports.pointInPolygon = pointInPolygon;
function polyTreeToPaths(polyTree) {
// we do this in JS since copying path is more expensive than just doing it
var result = [];
// result.Capacity = polytree.total;
addPolyNodeToPaths(polyTree, 0 /* Any */, result);
return result;
}
exports.polyTreeToPaths = polyTreeToPaths;
function reversePath(path) {
// we use JS since copying structures is slower than actually doing it
path.reverse();
}
exports.reversePath = reversePath;
function reversePaths(paths) {
// we use JS since copying structures is slower than actually doing it
for (var i = 0, max = paths.length; i < max; i++) {
reversePath(paths[i]);
}
}
exports.reversePaths = reversePaths;
function simplifyPolygon(nativeLib, path, fillType) {
if (fillType === void 0) { fillType = enums_1.PolyFillType.EvenOdd; }
var nativePath = PathToNativePath_1.pathToNativePath(nativeLib, path);
var outNativePaths = new nativeLib.Paths();
try {
nativeLib.simplifyPolygon(nativePath, outNativePaths, nativeEnumConversion_1.polyFillTypeToNative(nativeLib, fillType));
tryDelete(nativePath);
return PathsToNativePaths_1.nativePathsToPaths(nativeLib, outNativePaths, true); // frees outNativePaths
}
finally {
tryDelete(nativePath, outNativePaths);
}
}
exports.simplifyPolygon = simplifyPolygon;
function simplifyPolygons(nativeLib, paths, fillType) {
if (fillType === void 0) { fillType = enums_1.PolyFillType.EvenOdd; }
var nativePaths = PathsToNativePaths_1.pathsToNativePaths(nativeLib, paths);
try {
nativeLib.simplifyPolygonsOverwrite(nativePaths, nativeEnumConversion_1.polyFillTypeToNative(nativeLib, fillType));
return PathsToNativePaths_1.nativePathsToPaths(nativeLib, nativePaths, true); // frees nativePaths
}
finally {
tryDelete(nativePaths);
}
}
exports.simplifyPolygons = simplifyPolygons;
function scalePath(path, scale) {
var sol = [];
var i = path.length;
while (i--) {
var p = path[i];
sol.push({
x: Math.round(p.x * scale),
y: Math.round(p.y * scale)
});
}
return sol;
}
exports.scalePath = scalePath;
/**
* Scales all inner paths by multiplying all its coordinates by a number and then rounding them.
*
* @param paths - Paths to scale
* @param scale - Scale multiplier
* @return {Paths} - The scaled paths
*/
function scalePaths(paths, scale) {
if (scale === 0) {
return [];
}
var sol = [];
var i = paths.length;
while (i--) {
var p = paths[i];
sol.push(scalePath(p, scale));
}
return sol;
}
exports.scalePaths = scalePaths;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVuY3Rpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Z1bmN0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFBLGlDQUE2RDtBQUk3RCxzRUFBcUU7QUFDckUsa0VBQXFGO0FBQ3JGLDhEQUErRTtBQU0vRSxTQUFTLFNBQVM7O0lBQUMsY0FBMEI7U0FBMUIsVUFBMEIsRUFBMUIscUJBQTBCLEVBQTFCLElBQTBCO1FBQTFCLHlCQUEwQjs7O1FBQzNDLEtBQWtCLElBQUEsU0FBQSxTQUFBLElBQUksQ0FBQSwwQkFBQSw0Q0FBRTtZQUFuQixJQUFNLEdBQUcsaUJBQUE7WUFDWixJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxFQUFFO2dCQUNwQixHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7YUFDZDtTQUNGOzs7Ozs7Ozs7QUFDSCxDQUFDO0FBRUQsU0FBZ0IsSUFBSSxDQUFDLElBQWtCO0lBQ3JDLHNFQUFzRTtJQUN0RSxJQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3hCLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRTtRQUNYLE9BQU8sQ0FBQyxDQUFDO0tBQ1Y7SUFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDVixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFO1FBQ3pDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkQsQ0FBQyxHQUFHLENBQUMsQ0FBQztLQUNQO0lB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QUUsS0FBYTtJQUM1RCxJQUFJLEtBQUssS0FBSyxDQUFDLEVBQUU7UUFDZixPQUFPLEVBQUUsQ0FBQztLQUNYO0lBRUQsSUFBTSxHQUFHLEdBQVUsRUFBRSxDQUFDO0lBQ3RCLElBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDckIsT0FBTyxDQUFDLEVBQUUsRUFBRTtRQUNWLElBQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQixHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztLQUMvQjtJQUNELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQVpELGdDQVlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUG9pbnRJblBvbHlnb25SZXN1bHQsIFBvbHlGaWxsVHlwZSB9IGZyb20gXCIuL2VudW1zXCI7XHJcbmltcG9ydCB7IEludFBvaW50IH0gZnJvbSBcIi4vSW50UG9pbnRcIjtcclxuaW1wb3J0IHsgTmF0aXZlQ2xpcHBlckxpYkluc3RhbmNlIH0gZnJvbSBcIi4vbmF0aXZlL05hdGl2ZUNsaXBwZXJMaWJJbnN0YW5jZVwiO1xyXG5pbXBvcnQgeyBOYXRpdmVEZWxldGFibGUgfSBmcm9tIFwiLi9uYXRpdmUvTmF0aXZlRGVsZXRhYmxlXCI7XHJcbmltcG9ydCB7IHBvbHlGaWxsVHlwZVRvTmF0aXZlIH0gZnJvbSBcIi4vbmF0aXZlL25hdGl2ZUVudW1Db252ZXJzaW9uXCI7XHJcbmltcG9ydCB7IG5hdGl2ZVBhdGhzVG9QYXRocywgcGF0aHNUb05hdGl2ZVBhdGhzIH0gZnJvbSBcIi4vbmF0aXZlL1BhdGhzVG9OYXRpdmVQYXRoc1wiO1xyXG5pbXBvcnQgeyBuYXRpdmVQYXRoVG9QYXRoLCBwYXRoVG9OYXRpdmVQYXRoIH0gZnJvbSBcIi4vbmF0aXZlL1BhdGhUb05hdGl2ZVBhdGhcIjtcclxuaW1wb3J0IHsgUGF0aCwgUmVhZG9ubHlQYXRoIH0gZnJvbSBcIi4vUGF0aFwiO1xyXG5pbXBvcnQgeyBQYXRocywgUmVhZG9ubHlQYXRocyB9IGZyb20gXCIuL1BhdGhzXCI7XHJcbmltcG9ydCB7IFBvbHlOb2RlIH0gZnJvbSBcIi4vUG9seU5vZGVcIjtcclxuaW1wb3J0IHsgUG9seVRyZWUgfSBmcm9tIFwiLi9Qb2x5VHJlZVwiO1xyXG5cclxuZnVuY3Rpb24gdHJ5RGVsZXRlKC4uLm9ianM6IE5hdGl2ZURlbGV0YWJsZVtdKSB7XHJcbiAgZm9yIChjb25zdCBvYmogb2Ygb2Jqcykge1xyXG4gICAgaWYgKCFvYmouaXNEZWxldGVkKCkpIHtcclxuICAgICAgb2JqLmRlbGV0ZSgpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGFyZWEocGF0aDogUmVhZG9ubHlQYXRoKTogbnVtYmVyIHtcclxuICAvLyB3ZSB1c2UgSlMgc2luY2UgY29weWluZyBzdHJ1Y3R1cmVzIGlzIHNsb3dlciB0aGFuIGFjdHVhbGx5IGRvaW5nIGl0XHJcbiAgY29uc3QgY250ID0gcGF0aC5sZW5ndGg7XHJcbiAgaWYgKGNudCA8IDMpIHtcclxuICAgIHJldHVybiAwO1xyXG4gIH1cclxuICBsZXQgYSA9IDA7XHJcbiAgZm9yIChsZXQgaSA9IDAsIGogPSBjbnQgLSAxOyBpIDwgY250OyArK2kpIHtcclxuICAgIGEgKz0gKHBhdGhbal0ueCArIHBhdGhbaV0ueCkgKiAocGF0aFtqXS55IC0gcGF0aFtpXS55KTtcclxuICAgIGogPSBpO1xyXG4gIH1cclxuICByZXR1cm4gLWEgKiAwLjU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjbGVhblBvbHlnb24oXHJcbiAgbmF0aXZlTGliOiBOYXRpdmVDbGlwcGVyTGliSW5zdGFuY2UsXHJcbiAgcGF0aDogUmVhZG9ubHlQYXRoLFxyXG4gIGRpc3RhbmNlID0gMS4xNDE1XHJcbik6IFBhdGgge1xyXG4gIGNvbnN0IG5hdGl2ZVBhdGggPSBwYXRoVG9OYXRpdmVQYXRoKG5hdGl2ZUxpYiwgcGF0aCk7XHJcbiAgdHJ5IHtcclxuICAgIG5hdGl2ZUxpYi5jbGVhblBvbHlnb24obmF0aXZlUGF0aCwgZGlzdGFuY2UpO1xyXG4gICAgcmV0dXJuIG5hdGl2ZVBhdGhUb1BhdGgobmF0aXZlTGliLCBuYXRpdmVQYXRoLCB0cnVlKTsgLy8gZnJlZXMgbmF0aXZlUGF0aFxyXG4gIH0gZmluYWxseSB7XHJcbiAgICB0cnlEZWxldGUobmF0aXZlUGF0aCk7XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY2xlYW5Qb2x5Z29ucyhcclxuICBuYXRpdmVMaWI6IE5hdGl2ZUNsaXBwZXJMaWJJbnN0YW5jZSxcclxuICBwYXRoczogUmVhZG9ubHlQYXRocyxcclxuICBkaXN0YW5jZSA9IDEuMTQxNVxyXG4pOiBQYXRocyB7XHJcbiAgY29uc3QgbmF0aXZlUGF0aHMgPSBwYXRoc1RvTmF0aXZlUGF0aHMobmF0aXZlTGliLCBwYXRocyk7XHJcbiAgdHJ5IHtcclxuICAgIG5hdGl2ZUxpYi5jbGVhblBvbHlnb25zKG5hdGl2ZVBhdGhzLCBkaXN0YW5jZSk7XHJcbiAgICByZXR1cm4gbmF0aXZlUGF0aHNUb1BhdGhzKG5hdGl2ZUxpYiwgbmF0aXZlUGF0aHMsIHRydWUpOyAvLyBmcmVlcyBuYXRpdmVQYXRoXHJcbiAgfSBmaW5hbGx5IHtcclxuICAgIHRyeURlbGV0ZShuYXRpdmVQYXRocyk7XHJcbiAgfVxyXG59XHJcblxyXG5jb25zdCBlbnVtIE5vZGVUeXBlIHtcclxuICBBbnksXHJcbiAgT3BlbixcclxuICBDbG9zZWRcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkUG9seU5vZGVUb1BhdGhzKHBvbHlub2RlOiBQb2x5Tm9kZSwgbnQ6IE5vZGVUeXBlLCBwYXRoczogUmVhZG9ubHlQYXRoW10pOiB2b2lkIHtcclxuICBsZXQgbWF0Y2ggPSB0cnVlO1xyXG4gIHN3aXRjaCAobnQpIHtcclxuICAgIGNhc2UgTm9kZVR5cGUuT3BlbjpcclxuICAgICAgcmV0dXJuO1xyXG4gICAgY2FzZSBOb2RlVHlwZS5DbG9zZWQ6XHJcbiAgICAgIG1hdGNoID0gIXBvbHlub2RlLmlzT3BlbjtcclxuICAgICAgYnJlYWs7XHJcbiAgICBkZWZhdWx0OlxyXG4gICAgICBicmVhaztcclxuICB9XHJcblxyXG4gIGlmIChwb2x5bm9kZS5jb250b3VyLmxlbmd0aCA+IDAgJiYgbWF0Y2gpIHtcclxuICAgIHBhdGhzLnB1c2gocG9seW5vZGUuY29udG91cik7XHJcbiAgfVxyXG4gIGZvciAobGV0IGlpID0gMCwgbWF4ID0gcG9seW5vZGUuY2hpbGRzLmxlbmd0aDsgaWkgPCBtYXg7IGlpKyspIHtcclxuICAgIGNvbnN0IHBuID0gcG9seW5vZGUuY2hpbGRzW2lpXTtcclxuICAgIGFkZFBvbHlOb2RlVG9QYXRocyhwbiwgbnQsIHBhdGhzKTtcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjbG9zZWRQYXRoc0Zyb21Qb2x5VHJlZShwb2x5VHJlZTogUG9seVRyZWUpOiBQYXRocyB7XHJcbiAgLy8gd2UgZG8gdGhpcyBpbiBKUyBzaW5jZSBjb3B5aW5nIHBhdGggaXMgbW9yZSBleHBlbnNpdmUgdGhhbiBqdXN0IGRvaW5nIGl0XHJcblxyXG4gIGNvbnN0IHJlc3VsdDogUGF0aHMgPSBbXTtcclxuICAvLyByZXN1bHQuQ2FwYWNpdHkgPSBwb2x5dHJlZS5Ub3RhbDtcclxuICBhZGRQb2x5Tm9kZVRvUGF0aHMocG9seVRyZWUsIE5vZGVUeXBlLkNsb3NlZCwgcmVzdWx0KTtcclxuICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbWlua293c2tpRGlmZihcclxuICBuYXRpdmVMaWI6IE5hdGl2ZUNsaXBwZXJMaWJJbnN0YW5jZSxcclxuICBwb2x5MTogUmVhZG9ubHlQYXRoLFxyXG4gIHBvbHkyOiBSZWFkb25seVBhdGhcclxuKTogUGF0aHMge1xyXG4gIGNvbnN0IG5hdGl2ZVBhdGgxID0gcGF0aFRvTmF0aXZlUGF0aChuYXRpdmVMaWIsIHBvbHkxKTtcclxuICBjb25zdCBuYXRpdmVQYXRoMiA9IHBhdGhUb05hdGl2ZVBhdGgobmF0aXZlTGliLCBwb2x5Mik7XHJcbiAgY29uc3Qgb3V0TmF0aXZlUGF0aHMgPSBuZXcgbmF0aXZlTGliLlBhdGhzKCk7XHJcblxyXG4gIHRyeSB7XHJcbiAgICBuYXRpdmVMaWIubWlua293c2tpRGlmZihuYXRpdmVQYXRoMSwgbmF0aXZlUGF0aDIsIG91dE5hdGl2ZVBhdGhzKTtcclxuICAgIHRyeURlbGV0ZShuYXRpdmVQYXRoMSwgbmF0aXZlUGF0aDIpO1xyXG4gICAgcmV0dXJuIG5hdGl2ZVBhdGhzVG9QYXRocyhuYXRpdmVMaWIsIG91dE5hdGl2ZVBhdGhzLCB0cnVlKTsgLy8gZnJlZXMgb3V0TmF0aXZlUGF0aHNcclxuICB9IGZpbmFsbHkge1xyXG4gICAgdHJ5RGVsZXRlKG5hdGl2ZVBhdGgxLCBuYXRpdmVQYXRoMiwgb3V0TmF0aXZlUGF0aHMpO1xyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG1pbmtvd3NraVN1bVBhdGgoXHJcbiAgbmF0aXZlTGliOiBOYXRpdmVDbGlwcGVyTGliSW5zdGFuY2UsXHJcbiAgcGF0dGVybjogUmVhZG9ubHlQYXRoLFxyXG4gIHBhdGg6IFJlYWRvbmx5UGF0aCxcclxuICBwYXRoSXNDbG9zZWQ6IGJvb2xlYW5cclxuKTogUGF0aHMge1xyXG4gIGNvbnN0IHBhdHRlcm5OYXRpdmVQYXRoID0gcGF0aFRvTmF0aXZlUGF0aChuYXRpdmVMaWIsIHBhdHRlcm4pO1xyXG4gIGNvbnN0IG5hdGl2ZVBhdGggPSBwYXRoVG9OYXRpdmVQYXRoKG5hdGl2ZUxpYiwgcGF0aCk7XHJcbiAgY29uc3Qgb3V0TmF0aXZlUGF0aHMgPSBuZXcgbmF0aXZlTGliLlBhdGhzKCk7XHJcblxyXG4gIHRyeSB7XHJcbiAgICBuYXRpdmVMaWIubWlua293c2tpU3VtUGF0aChwYXR0ZXJuTmF0aXZlUGF0aCwgbmF0aXZlUGF0aCwgb3V0TmF0aXZlUGF0aHMsIHBhdGhJc0Nsb3NlZCk7XHJcbiAgICB0cnlEZWxldGUocGF0dGVybk5hdGl2ZVBhdGgsIG5hdGl2ZVBhdGgpO1xyXG4gICAgcmV0dXJuIG5hdGl2ZVBhdGhzVG9QYXRocyhuYXRpdmVMaWIsIG91dE5hdGl2ZVBhdGhzLCB0cnVlKTsgLy8gZnJlZXMgb3V0TmF0aXZlUGF0aHNcclxuICB9IGZpbmFsbHkge1xyXG4gICAgdHJ5RGVsZXRlKHBhdHRlcm5OYXRpdmVQYXRoLCBuYXRpdmVQYXRoLCBvdXROYXRpdmVQYXRocyk7XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbWlua293c2tpU3VtUGF0aHMoXHJcbiAgbmF0aXZlTGliOiBOYXRpdmVDbGlwcGVyTGliSW5zdGFuY2UsXHJcbiAgcGF0dGVybjogUmVhZG9ubHlQYXRoLFxyXG4gIHBhdGhzOiBSZWFkb25seVBhdGhzLFxyXG4gIHBhdGhJc0Nsb3NlZDogYm9vbGVhblxyXG4pOiBQYXRocyB7XHJcbiAgLy8gVE9ETzogaW0gbm90IHN1cmUgaWYgZm9yIHRoaXMgbWV0aG9kIHdlIGNhbiByZXVzZSB0aGUgaW5wdXQvb3V0cHV0IHBhdGhcclxuXHJcbiAgY29uc3QgcGF0dGVybk5hdGl2ZVBhdGggPSBwYXRoVG9OYXRpdmVQYXRoKG5hdGl2ZUxpYiwgcGF0dGVybik7XHJcbiAgY29uc3QgbmF0aXZlUGF0aHMgPSBwYXRoc1RvTmF0aXZlUGF0aHMobmF0aXZlTGliLCBwYXRocyk7XHJcblxyXG4gIHRyeSB7XHJcbiAgICBuYXRpdmVMaWIubWlua293c2tpU3VtUGF0aHMocGF0dGVybk5hdGl2ZVBhdGgsIG5hdGl2ZVBhdGhzLCBuYXRpdmVQYXRocywgcGF0aElzQ2xvc2VkKTtcclxuICAgIHRyeURlbGV0ZShwYXR0ZXJuTmF0aXZlUGF0aCk7XHJcbiAgICByZXR1cm4gbmF0aXZlUGF0aHNUb1BhdGhzKG5hdGl2ZUxpYiwgbmF0aXZlUGF0aHMsIHRydWUpOyAvLyBmcmVlcyBuYXRpdmVQYXRoc1xyXG4gIH0gZmluYWxseSB7XHJcbiAgICB0cnlEZWxldGUocGF0dGVybk5hdGl2ZVBhdGgsIG5hdGl2ZVBhdGhzKTtcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBvcGVuUGF0aHNGcm9tUG9seVRyZWUocG9seVRyZWU6IFBvbHlUcmVlKTogUmVhZG9ubHlQYXRoW10ge1xyXG4gIC8vIHdlIGRvIHRoaXMgaW4gSlMgc2luY2UgY29weWluZyBwYXRoIGlzIG1vcmUgZXhwZW5zaXZlIHRoYW4ganVzdCBkb2luZyBpdFxyXG5cclxuICBjb25zdCByZXN1bHQgPSBbXTtcclxuICBjb25zdCBsZW4gPSBwb2x5VHJlZS5jaGlsZHMubGVuZ3RoO1xyXG4gIHJlc3VsdC5sZW5ndGggPSBsZW47XHJcbiAgbGV0IHJlc3VsdExlbmd0aCA9IDA7XHJcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xyXG4gICAgaWYgKHBvbHlUcmVlLmNoaWxkc1tpXS5pc09wZW4pIHtcclxuICAgICAgcmVzdWx0W3Jlc3VsdExlbmd0aCsrXSA9IHBvbHlUcmVlLmNoaWxkc1tpXS5jb250b3VyO1xyXG4gICAgfVxyXG4gIH1cclxuICByZXN1bHQubGVuZ3RoID0gcmVzdWx0TGVuZ3RoO1xyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBvcmllbnRhdGlvbihwYXRoOiBSZWFkb25seVBhdGgpOiBib29sZWFuIHtcclxuICByZXR1cm4gYXJlYShwYXRoKSA+PSAwO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gcG9pbnRJblBvbHlnb24oXHJcbiAgcG9pbnQ6IFJlYWRvbmx5PEludFBvaW50PixcclxuICBwYXRoOiBSZWFkb25seVBhdGhcclxuKTogUG9pbnRJblBvbHlnb25SZXN1bHQge1xyXG4gIC8vIHdlIGRvIHRoaXMgaW4gSlMgc2luY2UgY29weWluZyBwYXRoIGlzIG1vcmUgZXhwZW5zaXZlIHRoYW4ganVzdCBkb2luZyBpdFxyXG5cclxuICAvLyByZXR1cm5zIDAgaWYgZmFsc2UsICsxIGlmIHRydWUsIC0xIGlmIHB0IE9OIHBvbHlnb24gYm91bmRhcnlcclxuICAvLyBTZWUgXCJUaGUgUG9pbnQgaW4gUG9seWdvbiBQcm9ibGVtIGZvciBBcmJpdHJhcnkgUG9seWdvbnNcIiBieSBIb3JtYW5uICYgQWdhdGhvc1xyXG4gIC8vIGh0dHA6Ly9jaXRlc2VlcnguaXN0LnBzdS5lZHUvdmlld2RvYy9kb3dubG9hZD9kb2k9MTAuMS4xLjg4LjU0OTgmcmVwPXJlcDEmdHlwZT1wZGZcclxuICBsZXQgcmVzdWx0ID0gMDtcclxuICBjb25zdCBjbnQgPSBwYXRoLmxlbmd0aDtcclxuICBpZiAoY250IDwgMykge1xyXG4gICAgcmV0dXJuIDA7XHJcbiAgfVxyXG4gIGxldCBpcCA9IHBhdGhbMF07XHJcbiAgZm9yIChsZXQgaSA9IDE7IGkgPD0gY250OyArK2kpIHtcclxuICAgIGNvbnN0IGlwTmV4dCA9IGkgPT09IGNudCA/IHBhdGhbMF0gOiBwYXRoW2ldO1xyXG4gICAgaWYgKGlwTmV4dC55ID09PSBwb2ludC55KSB7XHJcbiAgICAgIGlmIChpcE5leHQueCA9PT0gcG9pbnQueCB8fCAoaXAueSA9PT0gcG9pbnQueSAmJiBpcE5leHQueCA+IHBvaW50LnggPT09IGlwLnggPCBwb2ludC54KSkge1xyXG4gICAgICAgIHJldHVybiAtMTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGlwLnkgPCBwb2ludC55ICE9PSBpcE5leHQueSA8IHBvaW50LnkpIHtcclxuICAgICAgaWYgKGlwLnggPj0gcG9pbnQueCkge1xyXG4gICAgICAgIGlmIChpcE5leHQueCA+IHBvaW50LngpIHtcclxuICAgICAgICAgIHJlc3VsdCA9IDEgLSByZXN1bHQ7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGNvbnN0IGQgPVxyXG4gICAgICAgICAgICAoaXAueCAtIHBvaW50LngpICogKGlwTmV4dC55IC0gcG9pbnQueSkgLSAoaXBOZXh0LnggLSBwb2ludC54KSAqIChpcC55IC0gcG9pbnQueSk7XHJcbiAgICAgICAgICBpZiAoZCA9PT0gMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKGQgPiAwID09PSBpcE5leHQueSA+IGlwLnkpIHtcclxuICAgICAgICAgICAgcmVzdWx0ID0gMSAtIHJlc3VsdDtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaWYgKGlwTmV4dC54ID4gcG9pbnQueCkge1xyXG4gICAgICAgICAgY29uc3QgZCA9XHJcbiAgICAgICAgICAgIChpcC54IC0gcG9pbnQueCkgKiAoaXBOZXh0LnkgLSBwb2ludC55KSAtIChpcE5leHQueCAtIHBvaW50LngpICogKGlwLnkgLSBwb2ludC55KTtcclxuICAgICAgICAgIGlmIChkID09PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoZCA+IDAgPT09IGlwTmV4dC55ID4gaXAueSkge1xyXG4gICAgICAgICAgICByZXN1bHQgPSAxIC0gcmVzdWx0O1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaXAgPSBpcE5leHQ7XHJcbiAgfVxyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBwb2x5VHJlZVRvUGF0aHMocG9seVRyZWU6IFBvbHlUcmVlKTogUGF0aHMge1xyXG4gIC8vIHdlIGRvIHRoaXMgaW4gSlMgc2luY2UgY29weWluZyBwYXRoIGlzIG1vcmUgZXhwZW5zaXZlIHRoYW4ganVzdCBkb2luZyBpdFxyXG5cclxuICBjb25zdCByZXN1bHQ6IFBhdGhzID0gW107XHJcbiAgLy8gcmVzdWx0LkNhcGFjaXR5ID0gcG9seXRyZWUudG90YWw7XHJcbiAgYWRkUG9seU5vZGVUb1BhdGhzKHBvbHlUcmVlLCBOb2RlVHlwZS5BbnksIHJlc3VsdCk7XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHJldmVyc2VQYXRoKHBhdGg6IFBhdGgpOiB2b2lkIHtcclxuICAvLyB3ZSB1c2UgSlMgc2luY2UgY29weWluZyBzdHJ1Y3R1cmVzIGlzIHNsb3dlciB0aGFuIGFjdHVhbGx5IGRvaW5nIGl0XHJcbiAgcGF0aC5yZXZlcnNlKCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiByZXZlcnNlUGF0aHMocGF0aHM6IFBhdGhzKTogdm9pZCB7XHJcbiAgLy8gd2UgdXNlIEpTIHNpbmNlIGNvcHlpbmcgc3RydWN0dXJlcyBpcyBzbG93ZXIgdGhhbiBhY3R1YWxseSBkb2luZyBpdFxyXG4gIGZvciAobGV0IGkgPSAwLCBtYXggPSBwYXRocy5sZW5ndGg7IGkgPCBtYXg7IGkrKykge1xyXG4gICAgcmV2ZXJzZVBhdGgocGF0aHNbaV0pO1xyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHNpbXBsaWZ5UG9seWdvbihcclxuICBuYXRpdmVMaWI6IE5hdGl2ZUNsaXBwZXJMaWJJbnN0YW5jZSxcclxuICBwYXRoOiBSZWFkb25seVBhdGgsXHJcbiAgZmlsbFR5cGU6IFBvbHlGaWxsVHlwZSA9IFBvbHlGaWxsVHlwZS5FdmVuT2RkXHJcbik6IFBhdGhzIHtcclxuICBjb25zdCBuYXRpdmVQYXRoID0gcGF0aFRvTmF0aXZlUGF0aChuYXRpdmVMaWIsIHBhdGgpO1xyXG4gIGNvbnN0IG91dE5hdGl2ZVBhdGhzID0gbmV3IG5hdGl2ZUxpYi5QYXRocygpO1xyXG4gIHRyeSB7XHJcbiAgICBuYXRpdmVMaWIuc2ltcGxpZnlQb2x5Z29uKFxyXG4gICAgICBuYXRpdmVQYXRoLFxyXG4gICAgICBvdXROYXRpdmVQYXRocyxcclxuICAgICAgcG9seUZpbGxUeXBlVG9OYXRpdmUobmF0aXZlTGliLCBmaWxsVHlwZSlcclxuICAgICk7XHJcbiAgICB0cnlEZWxldGUobmF0aXZlUGF0aCk7XHJcbiAgICByZXR1cm4gbmF0aXZlUGF0aHNUb1BhdGhzKG5hdGl2ZUxpYiwgb3V0TmF0aXZlUGF0aHMsIHRydWUpOyAvLyBmcmVlcyBvdXROYXRpdmVQYXRoc1xyXG4gIH0gZmluYWxseSB7XHJcbiAgICB0cnlEZWxldGUobmF0aXZlUGF0aCwgb3V0TmF0aXZlUGF0aHMpO1xyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHNpbXBsaWZ5UG9seWdvbnMoXHJcbiAgbmF0aXZlTGliOiBOYXRpdmVDbGlwcGVyTGliSW5zdGFuY2UsXHJcbiAgcGF0aHM6IFJlYWRvbmx5UGF0aHMsXHJcbiAgZmlsbFR5cGU6IFBvbHlGaWxsVHlwZSA9IFBvbHlGaWxsVHlwZS5FdmVuT2RkXHJcbik6IFBhdGhzIHtcclxuICBjb25zdCBuYXRpdmVQYXRocyA9IHBhdGhzVG9OYXRpdmVQYXRocyhuYXRpdmVMaWIsIHBhdGhzKTtcclxuICB0cnkge1xyXG4gICAgbmF0aXZlTGliLnNpbXBsaWZ5UG9seWdvbnNPdmVyd3JpdGUobmF0aXZlUGF0aHMsIHBvbHlGaWxsVHlwZVRvTmF0aXZlKG5hdGl2ZUxpYiwgZmlsbFR5cGUpKTtcclxuICAgIHJldHVybiBuYXRpdmVQYXRoc1RvUGF0aHMobmF0aXZlTGliLCBuYXRpdmVQYXRocywgdHJ1ZSk7IC8vIGZyZWVzIG5hdGl2ZVBhdGhzXHJcbiAgfSBmaW5hbGx5IHtcclxuICAgIHRyeURlbGV0ZShuYXRpdmVQYXRocyk7XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc2NhbGVQYXRoKHBhdGg6IFJlYWRvbmx5UGF0aCwgc2NhbGU6IG51bWJlcik6IFBhdGgge1xyXG4gIGNvbnN0IHNvbDogUGF0aCA9IFtdO1xyXG4gIGxldCBpID0gcGF0aC5sZW5ndGg7XHJcbiAgd2hpbGUgKGktLSkge1xyXG4gICAgY29uc3QgcCA9IHBhdGhbaV07XHJcbiAgICBzb2wucHVzaCh7XHJcbiAgICAgIHg6IE1hdGgucm91bmQocC54ICogc2NhbGUpLFxyXG4gICAgICB5OiBNYXRoLnJvdW5kKHAueSAqIHNjYWxlKVxyXG4gICAgfSk7XHJcbiAgfVxyXG4gIHJldHVybiBzb2w7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBTY2FsZXMgYWxsIGlubmVyIHBhdGhzIGJ5IG11bHRpcGx5aW5nIGFsbCBpdHMgY29vcmRpbmF0ZXMgYnkgYSBudW1iZXIgYW5kIHRoZW4gcm91bmRpbmcgdGhlbS5cclxuICpcclxuICogQHBhcmFtIHBhdGhzIC0gUGF0aHMgdG8gc2NhbGVcclxuICogQHBhcmFtIHNjYWxlIC0gU2NhbGUgbXVsdGlwbGllclxyXG4gKiBAcmV0dXJuIHtQYXRoc30gLSBUaGUgc2NhbGVkIHBhdGhzXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gc2NhbGVQYXRocyhwYXRoczogUmVhZG9ubHlQYXRocywgc2NhbGU6IG51bWJlcik6IFBhdGhzIHtcclxuICBpZiAoc2NhbGUgPT09IDApIHtcclxuICAgIHJldHVybiBbXTtcclxuICB9XHJcblxyXG4gIGNvbnN0IHNvbDogUGF0aHMgPSBbXTtcclxuICBsZXQgaSA9IHBhdGhzLmxlbmd0aDtcclxuICB3aGlsZSAoaS0tKSB7XHJcbiAgICBjb25zdCBwID0gcGF0aHNbaV07XHJcbiAgICBzb2wucHVzaChzY2FsZVBhdGgocCwgc2NhbGUpKTtcclxuICB9XHJcbiAgcmV0dXJuIHNvbDtcclxufVxyXG4iXX0=