whole_func_string: function splitSegments(polygon) {
      if (typeof polygon !== "string") {
          throw new Error("Polygon should be a path string");
      }
  
      var start = null;
      var position = null;
      var result = [];
      var input = polygon;
  
      function stripWhitespace() {
          polygon = polygon.trim();
      }
  
      function readCharSeq(n) {
          var c = polygon.charCodeAt(n);
          while (c >= 48 && c <= 57) {
              n++;
              c = polygon.charCodeAt(n);
          }
          return n;
      }
  
      function readNumber() {
          stripWhitespace();
  
          var start = 0;
          var end = 0;
          if (polygon[start] === ",") {
              start++;
              end++;
          }
  
          if (polygon[start] === "-") {
              end++;
          }
  
          end = readCharSeq(end);
          if (polygon[end] === ".") {
              end++;
              end = readCharSeq(end);
          }
  
          var s = polygon.substring(start, end);
          if (s !== "") {
              var num = toFloat(s);
              polygon = polygon.substring(end);
              if (polygon.length && polygon[0].toLowerCase() === "e") {
                  var f = 1;
                  var expEnd = 0;
                  if (polygon.length > 1 && polygon[1] === "-") {
                      f = -1;
                      expEnd = readCharSeq(2);
                  } else {
                      expEnd = readCharSeq(1);
                  }
                  var exp = toFloat(polygon.substring(1, expEnd));
                  if (mathAbs(exp) > 0) {
                      num *= mathPow(10, exp);
                  }
                  polygon = polygon.substring(expEnd);
              }
              return num;
          } else {
              throw new Error("Expected number: " + polygon);
          }
      }
  
      function readNumbers(n, fn) {
          stripWhitespace();
          var index = 0;
          var c = polygon.charCodeAt(0);
          while ((c >= 48 && c <= 57) || c === 44 || c === 45) {
              var numbers = [];
              for (var i = 0; i < n; i++) {
                  numbers.push(readNumber());
              }
              fn(numbers, index);
  
              stripWhitespace();
              c = polygon.charCodeAt(0);
              index++;
          }
      }
  
      function readCoords(n, fn) {
          readNumbers(n * 2, function (numbers, index) {
              var coords = [];
              for (var i = 0; i < n; i++) {
                  coords.push(numbers.splice(0, 2));
              }
              fn(coords, index);
          });
      }
  
      function pushType(itemType, offset) {
          return function (c) {
              if (offset) {
                  c = c.map(function (c) {
                      return [x(c) + x(offset), y(c) + y(offset)];
                  });
              }
              c.unshift(position);
              result.push({
                  type: itemType,
                  coords: c,
              });
              position = c[c.length - 1];
          };
      }
  
      function calculateCubicControlPoints(coords) {
          return [coords[0], [
              x(coords[0]) + 2.0 / 3.0 * (x(coords[1]) - x(coords[0])),
              y(coords[0]) + 2.0 / 3.0 * (y(coords[1]) - y(coords[0])),
          ], [
              x(coords[2]) + 2.0 / 3.0 * (x(coords[1]) - x(coords[2])),
              y(coords[2]) + 2.0 / 3.0 * (y(coords[1]) - y(coords[2])),
          ], coords[2],
          ];
      }
  
      function calculateBezierControlPoint() {
          var lastBezier = result[result.length - 1];
          var controlPoint = null;
          if (!lastBezier || lastBezier.type !== bezier3Type) {
              controlPoint = position;
          } else {
              // Calculate the mirror point of the last control point
              var lastPoint = lastBezier.coords[2];
              var xOffset = x(position) - x(lastPoint);
              var yOffset = y(position) - y(lastPoint);
  
              controlPoint = [x(position) + xOffset, y(position) + yOffset];
          }
  
          return controlPoint;
      }
  
      function handleArcSegment(relative) {
          readNumbers(7, function (numbers) {
              var c2 = coordAdd(numbers.slice(5, 7), relative);
              var args = [position].concat(numbers.slice(0, 5)).concat([c2]);
              var curve = arcToCurve.apply(null, args);
              for (var i = 0; i < curve.length; i++) {
                  pushType(bezier3Type)(curve[i]);
              }
          });
      }
  
      function readSegment() {
          stripWhitespace();
          if (polygon === "") {
              return;
          }
  
          var operator = polygon[0];
          polygon = polygon.substring(1);
  
          var pushLine = pushType(lineType);
          var origin = [0, 0];
  
          switch (operator) {
              case "M":
                  readCoords(1, function (c, i) {
                      if (i === 0) {
                          position = c[0];
                          if (!start) {
                              start = position;
                          }
                      } else {
                          pushType(lineType)(c);
                      }
                  });
                  break;
              case "m":
                  readCoords(1, function (c, i) {
                      if (i === 0) {
                          if (!position) {
                              position = c[0];
                          } else {
                              position = coordAdd(c, position);
                          }
  
                          if (!start) {
                              start = position;
                          }
                      } else {
                          var c0 = c[0];
                          pushType(lineType)([coordAdd(c0, position)]);
                      }
                  });
                  break;
              case "C":
                  readCoords(3, pushType(bezier3Type));
                  break;
              case "c":
                  readCoords(3, pushType(bezier3Type, position));
                  break;
              case "Q":
                  readCoords(2, function (coords) {
                      coords.unshift(position);
                      coords = calculateCubicControlPoints(coords);
                      coords.shift();
                      pushType(bezier3Type)(coords);
                  });
                  break;
              case "q":
                  readCoords(2, function (coords) {
                      coords = coords.map(function (c) { return coordAdd(c, position); });
                      coords.unshift(position);
                      coords = calculateCubicControlPoints(coords);
                      coords.shift();
                      pushType(bezier3Type)(coords);
                  });
                  break;
              case "S":
                  readCoords(2, function (coords) {
                      var controlPoint = calculateBezierControlPoint();
                      coords.unshift(controlPoint);
                      pushType(bezier3Type)(coords);
                  });
                  break;
              case "s":
                  readCoords(2, function (coords) {
                      var controlPoint = calculateBezierControlPoint();
                      coords = coords.map(function (c) { return coordAdd(c, position); });
                      coords.unshift(controlPoint);
                      pushType(bezier3Type)(coords);
                  });
                  break;
              case "A":
                  handleArcSegment(origin);
                  break;
              case "a":
                  handleArcSegment(position);
                  break;
              case "L":
                  readCoords(1, pushType(lineType));
                  break;
              case "l":
                  readCoords(1, function (c) {
                      pushLine([[x(c[0]) + x(position), y(c[0]) + y(position)]]);
                  });
                  break;
              case "H":
                  pushType(lineType)([[readNumber(), y(position)]]);
                  break;
              case "h":
                  pushType(lineType, position)([[readNumber(), 0]]);
                  break;
              case "V":
                  pushType(lineType)([[x(position), readNumber()]]);
                  break;
              case "v":
                  pushType(lineType, position)([[0, readNumber()]]);
                  break;
              case "Z":
              case "z":
                  if (!coordEqual(position, start)) {
                      pushType(lineType)([start]);
                  }
                  break;
              default:
                  throw new Error("Unknown operator: " + operator + " for polygon '" + input + "'");
          }
      }
  
      while (polygon.length > 0) {
          readSegment();
      }
  
      // Remove zero-length lines
      for (var i = 0; i < result.length; i++) {
          var segment = result[i];
          if (segment.type === lineType && coordEqual(segment.coords[0], segment.coords[1])) {
              result.splice(i, 1);
              i--;
          }
      }
  
      return result;
  }
func_code_string: function splitSegments(polygon) {
      if (typeof polygon !== "string") {
          throw new Error("Polygon should be a path string");
      }
  
      var start = null;
      var position = null;
      var result = [];
      var input = polygon;
  
      function stripWhitespace() {
          polygon = polygon.trim();
      }
  
      function readCharSeq(n) {
          var c = polygon.charCodeAt(n);
          while (c >= 48 && c <= 57) {
              n++;
              c = polygon.charCodeAt(n);
          }
          return n;
      }
  
      function readNumber() {
          stripWhitespace();
  
          var start = 0;
          var end = 0;
          if (polygon[start] === ",") {
              start++;
              end++;
          }
  
          if (polygon[start] === "-") {
              end++;
          }
  
          end = readCharSeq(end);
          if (polygon[end] === ".") {
              end++;
              end = readCharSeq(end);
          }
  
          var s = polygon.substring(start, end);
          if (s !== "") {
              var num = toFloat(s);
              polygon = polygon.substring(end);
              if (polygon.length && polygon[0].toLowerCase() === "e") {
                  var f = 1;
                  var expEnd = 0;
                  if (polygon.length > 1 && polygon[1] === "-") {
                      f = -1;
                      expEnd = readCharSeq(2);
                  } else {
                      expEnd = readCharSeq(1);
                  }
                  var exp = toFloat(polygon.substring(1, expEnd));
                  if (mathAbs(exp) > 0) {
                      num *= mathPow(10, exp);
                  }
                  polygon = polygon.substring(expEnd);
              }
              return num;
          } else {
              throw new Error("Expected number: " + polygon);
          }
      }
  
      function readNumbers(n, fn) {
          stripWhitespace();
          var index = 0;
          var c = polygon.charCodeAt(0);
          while ((c >= 48 && c <= 57) || c === 44 || c === 45) {
              var numbers = [];
              for (var i = 0; i < n; i++) {
                  numbers.push(readNumber());
              }
              fn(numbers, index);
  
              stripWhitespace();
              c = polygon.charCodeAt(0);
              index++;
          }
      }
  
      function readCoords(n, fn) {
          readNumbers(n * 2, function (numbers, index) {
              var coords = [];
              for (var i = 0; i < n; i++) {
                  coords.push(numbers.splice(0, 2));
              }
              fn(coords, index);
          });
      }
  
      function pushType(itemType, offset) {
          return function (c) {
              if (offset) {
                  c = c.map(function (c) {
                      return [x(c) + x(offset), y(c) + y(offset)];
                  });
              }
              c.unshift(position);
              result.push({
                  type: itemType,
                  coords: c,
              });
              position = c[c.length - 1];
          };
      }
  
      function calculateCubicControlPoints(coords) {
          return [coords[0], [
              x(coords[0]) + 2.0 / 3.0 * (x(coords[1]) - x(coords[0])),
              y(coords[0]) + 2.0 / 3.0 * (y(coords[1]) - y(coords[0])),
          ], [
              x(coords[2]) + 2.0 / 3.0 * (x(coords[1]) - x(coords[2])),
              y(coords[2]) + 2.0 / 3.0 * (y(coords[1]) - y(coords[2])),
          ], coords[2],
          ];
      }
  
      function calculateBezierControlPoint() {
          var lastBezier = result[result.length - 1];
          var controlPoint = null;
          if (!lastBezier || lastBezier.type !== bezier3Type) {
              controlPoint = position;
          } else {
              // Calculate the mirror point of the last control point
              var lastPoint = lastBezier.coords[2];
              var xOffset = x(position) - x(lastPoint);
              var yOffset = y(position) - y(lastPoint);
  
              controlPoint = [x(position) + xOffset, y(position) + yOffset];
          }
  
          return controlPoint;
      }
  
      function handleArcSegment(relative) {
          readNumbers(7, function (numbers) {
              var c2 = coordAdd(numbers.slice(5, 7), relative);
              var args = [position].concat(numbers.slice(0, 5)).concat([c2]);
              var curve = arcToCurve.apply(null, args);
              for (var i = 0; i < curve.length; i++) {
                  pushType(bezier3Type)(curve[i]);
              }
          });
      }
  
      function readSegment() {
          stripWhitespace();
          if (polygon === "") {
              return;
          }
  
          var operator = polygon[0];
          polygon = polygon.substring(1);
  
          var pushLine = pushType(lineType);
          var origin = [0, 0];
  
          switch (operator) {
              case "M":
                  readCoords(1, function (c, i) {
                      if (i === 0) {
                          position = c[0];
                          if (!start) {
                              start = position;
                          }
                      } else {
                          pushType(lineType)(c);
                      }
                  });
                  break;
              case "m":
                  readCoords(1, function (c, i) {
                      if (i === 0) {
                          if (!position) {
                              position = c[0];
                          } else {
                              position = coordAdd(c, position);
                          }
  
                          if (!start) {
                              start = position;
                          }
                      } else {
                          var c0 = c[0];
                          pushType(lineType)([coordAdd(c0, position)]);
                      }
                  });
                  break;
              case "C":
                  readCoords(3, pushType(bezier3Type));
                  break;
              case "c":
                  readCoords(3, pushType(bezier3Type, position));
                  break;
              case "Q":
                  readCoords(2, function (coords) {
                      coords.unshift(position);
                      coords = calculateCubicControlPoints(coords);
                      coords.shift();
                      pushType(bezier3Type)(coords);
                  });
                  break;
              case "q":
                  readCoords(2, function (coords) {
                      coords = coords.map(function (c) { return coordAdd(c, position); });
                      coords.unshift(position);
                      coords = calculateCubicControlPoints(coords);
                      coords.shift();
                      pushType(bezier3Type)(coords);
                  });
                  break;
              case "S":
                  readCoords(2, function (coords) {
                      var controlPoint = calculateBezierControlPoint();
                      coords.unshift(controlPoint);
                      pushType(bezier3Type)(coords);
                  });
                  break;
              case "s":
                  readCoords(2, function (coords) {
                      var controlPoint = calculateBezierControlPoint();
                      coords = coords.map(function (c) { return coordAdd(c, position); });
                      coords.unshift(controlPoint);
                      pushType(bezier3Type)(coords);
                  });
                  break;
              case "A":
                  handleArcSegment(origin);
                  break;
              case "a":
                  handleArcSegment(position);
                  break;
              case "L":
                  readCoords(1, pushType(lineType));
                  break;
              case "l":
                  readCoords(1, function (c) {
                      pushLine([[x(c[0]) + x(position), y(c[0]) + y(position)]]);
                  });
                  break;
              case "H":
                  pushType(lineType)([[readNumber(), y(position)]]);
                  break;
              case "h":
                  pushType(lineType, position)([[readNumber(), 0]]);
                  break;
              case "V":
                  pushType(lineType)([[x(position), readNumber()]]);
                  break;
              case "v":
                  pushType(lineType, position)([[0, readNumber()]]);
                  break;
              case "Z":
              case "z":
                  if (!coordEqual(position, start)) {
                      pushType(lineType)([start]);
                  }
                  break;
              default:
                  throw new Error("Unknown operator: " + operator + " for polygon '" + input + "'");
          }
      }
  
      while (polygon.length > 0) {
          readSegment();
      }
  
      // Remove zero-length lines
      for (var i = 0; i < result.length; i++) {
          var segment = result[i];
          if (segment.type === lineType && coordEqual(segment.coords[0], segment.coords[1])) {
              result.splice(i, 1);
              i--;
          }
      }
  
      return result;
  }
func_documentation_string: Unpack an SVG path string into different curves and lines  https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d