diff --git a/src/uxbox/util/geom/path_impl_simplify.js b/src/uxbox/util/geom/path_impl_simplify.js
new file mode 100644
index 000000000..b6956d70f
--- /dev/null
+++ b/src/uxbox/util/geom/path_impl_simplify.js
@@ -0,0 +1,122 @@
+/**
+ * Simplify.js, a high-performance JS polyline simplification library.
+ *
+ * Is a modified and google closure adapted implementation of
+ * https://github.com/mourner/simplify-js
+ *
+ * @author Vladimir Agafonkin, 2013
+ * @author Andrey Antukh <niwi@niwi.nz>, 2016
+ * @license BSD License <https://opensource.org/licenses/BSD-2-Clause>
+ */
+
+"use strict";
+
+goog.provide("uxbox.util.geom.path_impl_simplify");
+
+goog.scope(function() {
+  const self = uxbox.util.geom.path_impl_simplify;
+
+  // square distance between 2 points
+  function getSqDist(p1, p2) {
+    const dx = p1.x - p2.x;
+    const dy = p1.y - p2.y;
+    return dx * dx + dy * dy;
+  }
+
+  // square distance from a point to a segment
+  function getSqSegDist(p, p1, p2) {
+    let x = p1.x;
+    let y = p1.y;
+    let dx = p2.x - x;
+    let dy = p2.y - y;
+
+    if (dx !== 0 || dy !== 0) {
+      const t = ((p.x - x) * dx + (p.y - y) * dy) / (dx * dx + dy * dy);
+
+      if (t > 1) {
+        x = p2.x;
+        y = p2.y;
+
+      } else if (t > 0) {
+        x += dx * t;
+        y += dy * t;
+      }
+    }
+
+    dx = p.x - x;
+    dy = p.y - y;
+
+    return dx * dx + dy * dy;
+  }
+  // rest of the code doesn't care about point format
+
+  // basic distance-based simplification
+  function simplifyRadialDist(points, sqTolerance) {
+    let prevPoint = points[0];
+    let newPoints = [prevPoint];
+    let point;
+
+    for (let i = 1, len = points.length; i < len; i++) {
+      point = points[i];
+
+      if (getSqDist(point, prevPoint) > sqTolerance) {
+        newPoints.push(point);
+        prevPoint = point;
+      }
+    }
+
+    if (prevPoint !== point) {
+      newPoints.push(point);
+    }
+
+    return newPoints;
+  }
+
+  function simplifyDPStep(points, first, last, sqTolerance, simplified) {
+    let maxSqDist = sqTolerance;
+    let index;
+
+    for (let i = first + 1; i < last; i++) {
+      let sqDist = getSqSegDist(points[i], points[first], points[last]);
+
+      if (sqDist > maxSqDist) {
+        index = i;
+        maxSqDist = sqDist;
+      }
+    }
+
+    if (maxSqDist > sqTolerance) {
+      if (index - first > 1) {
+        simplifyDPStep(points, first, index, sqTolerance, simplified);
+      }
+      simplified.push(points[index]);
+      if (last - index > 1) {
+        simplifyDPStep(points, index, last, sqTolerance, simplified);
+      }
+    }
+  }
+
+  // simplification using Ramer-Douglas-Peucker algorithm
+  function simplifyDouglasPeucker(points, sqTolerance) {
+    let last = points.length - 1;
+
+    let simplified = [points[0]];
+    simplifyDPStep(points, 0, last, sqTolerance, simplified);
+    simplified.push(points[last]);
+    return simplified;
+  }
+
+  // both algorithms combined for awesome performance
+  function simplify(points, tolerance, highestQuality) {
+    if (points.length <= 2) {
+      return points;
+    }
+
+    var sqTolerance = tolerance !== undefined ? tolerance * tolerance : 1;
+    points = highestQuality ? points : simplifyRadialDist(points, sqTolerance);
+    points = simplifyDouglasPeucker(points, sqTolerance);
+    return points;
+  }
+
+  self.simplify = simplify;
+});