text: /* Helper methods */
  String.prototype.f = function () {
      var s = this,
          i = arguments.length;
  
      while (i--) {
          s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
      }
      return s;
  };
  
  String.prototype.repeat = function (num) {
      return new Array(num + 1).join(this);
  };
  
  function pushUnique(array, item) {
      if (array.indexOf(item) == -1) {
          array.push(item);
          return true;
      }
      return false;
  }
  
  
  function toBool(s, defValue) {
      if (typeof s === "undefined") {
          return typeof defValue !== "undefined" ? defValue : false;
      }
      return "false" !== s;
  }
  
  if (typeof String.prototype.endsWith !== 'function') {
      String.prototype.endsWith = function (suffix) {
          return this.indexOf(suffix, this.length - suffix.length) !== -1;
      };
  }
  
  if (typeof String.prototype.startsWith !== 'function') {
      String.prototype.startsWith = function (str) {
          return this.indexOf(str) == 0;
      };
  }
  
  jQuery.fn.reverse = [].reverse;
  
  /* ------ */
  
  var groupData = { groupSize:0, zip:null, log:[], errors:0, files:[]};
  
  var fileReaderOpts = {
      dragClass: "drag", readAsDefault: "Text", on: {
          load: function (e, file) {
              if (groupData.groupSize == 1) {
                  loadFile(e, file, false)
              } else {
                  groupData.files.push({e: e, file: file});
              }
          },
          groupstart: function (g) {
              resetGroupData();
              groupData.zip = new JSZip();
              groupData.groupSize = g.files.length;
          },
          groupend: function (g) {
              //Multiple files
              if (groupData.groupSize > 1) {
                  groupData.groupSize = 0;
                  var dlg = $('#dlg-files');
                  var btnPrimary = dlg.find(".btn-primary");
  
                  refreshSettings();
                  dlg.find("#files-count").text(groupData.files.length);
                  btnPrimary.text("Export");
                  dlg.modal().on();
  
                  btnPrimary.removeClass("disabled");
  
                  btnPrimary.unbind("click");
                  btnPrimary.on("click", function () {
                      if (btnPrimary.hasClass("disabled")) return;
  
                      btnPrimary.addClass("disabled");
                      btnPrimary.text("Please wait ...");
  
                      //To prevent UI lag
                      setTimeout(function () {
                          for (var i = 0; i < groupData.files.length; i++) {
                              var f = groupData.files[i];
                              loadFile(f.e, f.file, true);
                          }
  
                          groupData.log = "<h2>Files converted: " +  (groupData.files.length - groupData.errors) + " / " + groupData.files.length + "</h2>" + groupData.log;
                          groupData.zip.file("log.html", groupData.log);
  
                          saveAs(groupData.zip.generate({type: "blob"}), "export.zip");
                          dlg.modal("hide");
                      }, 250);
                  });
  
                  dlg.unbind("hidden.bs.modal");
                  dlg.on("hidden.bs.modal", function () {
                      resetGroupData();
                  })
              }
          }
      }
  };
  
  if (typeof FileReader === "undefined") {
      $('#dropzone, #dropzone-dialog').hide();
      $('#compat-error').show();
  } else {
      $('#dropzone, #dropzone-dialog').fileReaderJS(fileReaderOpts);
  }
  
  //Copy settings to dialog
  var dlg = $('#dlg-files');
  dlg.find('.modal-body').html($("#settings-area").clone());
  
  /* ------ */
  
  var DRAW_LINE = "l"; //used as default parameter when no found in path
  var START_PATH = "M";
  var END_PATH = "Z";
  var INDENT = "    ";
  
  var pathsParsedCount = 0;
  var generatedOutput = "";
  var lastFileName = "";
  var lastFileData;
  var warnings = [];
  var svgStyles = {};
  
  function loadFile(e, file, multipleFiles) {
      lastFileName = file.name;
      refreshSettings();
  
      if (multipleFiles) {
          parseMultipleFiles(e.target.result)
      } else {
          parseSingleFile(e.target.result);
      }
  }
  
  function resetGroupData() {
      groupData.zip = new JSZip();
      groupData.log = [];
      groupData.files = [];
      groupData.errors = 0;
      groupData.groupSize = 0;
  }
  
  function refreshSettings() {
      $(".opt-id-as-name").prop("checked", toBool(localStorage.useIdAsName));
      $(".bake-transforms").prop("checked", toBool(localStorage.bakeTransforms));
      $(".clear-groups").prop("checked", toBool(localStorage.clearGroups, true));
  }
  
  function extractFileNameWithoutExt(filename) {
      var dotIndex = filename.lastIndexOf(".");
      if (dotIndex > -1) {
          return filename.substr(0, dotIndex);
      } else {
          return filename;
      }
  }
  
  //Main parse & convert logic
  function recursiveTreeWalk(parent, groupLevel) {
      parent.children().each(function () {
          var current = $(this);
          if (current.is("g") && current.children().length > 0) { //Group tag, ignore empty groups
              var group = parseGroup(current);
              var ignoreGroup = !(toBool(localStorage.clearGroups, true) && !group.isSet);
              if (ignoreGroup) printGroupStart(group, groupLevel);
  
              if (ignoreGroup) groupLevel++;
              recursiveTreeWalk(current, groupLevel);
              if (ignoreGroup) groupLevel--;
  
              if (ignoreGroup) printGroupEnd(groupLevel);
          } else if (current.is("path")) {
              var pathD = parsePathD(current);
              if (pathD != null) {
                  printPath(pathD, getStyles(current), groupLevel);
              } else {
                  pushUnique(warnings, "found path(s) without data (empty or invalid parameter <i>d</i>)");
              }
          } else if (current.is("line")) {
              printPath(ShapeConverter.convertLine(current), getStyles(current), groupLevel);
          } else if (current.is("rect")) {
              printPath(ShapeConverter.convertRect(current), getStyles(current), groupLevel);
          } else if (current.is("circle")) {
              printPath(ShapeConverter.convertCircle(current), getStyles(current), groupLevel);
          } else if (current.is("ellipse")) {
              printPath(ShapeConverter.convertEllipse(current), getStyles(current), groupLevel);
          } else if (current.is("polyline")) {
              printPath(ShapeConverter.convertPolygon(current, true), getStyles(current), groupLevel);
          } else if (current.is("polygon")) {
              printPath(ShapeConverter.convertPolygon(current, false), getStyles(current), groupLevel);
          } else if (current.is("text")) {
              pushUnique(warnings, "<i>text</i> element is not supported, export all text into path");
          } else if (current.is("image")) {
              pushUnique(warnings, "<i>image</i> element is not supported, you must vectorize raster image");
          }
      });
  }
  
  function preprocessReferences(svg, grouplevel) {
      svg.find("use").each(function () {
          var current = $(this);
          substituteUseRef(svg, current);
      });
  }
  
  function getStyles(el) {
      var styles = parseStyles(el);
  
      var parentStyles = null;
  
      //Inherit all parent group styles in reversed order (to override them correctly)
      el.parents("g").reverse().each(function () {
          var current = $(this);
          if (parentStyles == null) {
              parentStyles = [];
          }
          jQuery.extend(parentStyles, parseStyles(current));
      });
  
      //Do not propagate id from group to childrens
      if (parentStyles != null && typeof parentStyles["id"] !== "undefined") {
          parentStyles["id"] = undefined;
      }
  
      return [styles, parentStyles];
  }
  
  function substituteUseRef(parent, current) {
      var href = current.attr("xlink:href");
      if (typeof href !== "undefined") {
          href = href.trim();
          //Check if valid href
          if (href.length > 1 && href.startsWith("#")) {
              //Find definition in svg
              var defs = $(parent).find("[id='" + href.substr(1) + "']");
              if (defs.length) {
                  defs = defs.clone();
  
                  //Copy overriding attributes into children
                  $.each(current.prop("attributes"), function () {
                      defs.attr(this.name, this.value);
                  });
  
                  current.replaceWith(defs);
              } else {
                  console.warn("Found <use> tag but did not found appropriate block in <defs> for id " + href);
              }
          }
      }
  }
  
  function parseGroup(groupTag) {
      var transform = groupTag.attr("transform");
      var id = groupTag.attr("id");
      var groupTransform = {transformX: 0, transformY: 0, scaleX: 1, scaleY: 1, rotate:0, rotatePivotX:-1, rotatePivotY:-1, id:"", isSet:false};
      if (typeof transform !== "undefined") {
          var regex = /((\w|\s)+)\(([^)]+)/mg;
          var result;
          while (result = regex.exec(transform)) {
              var split = result[3].split(/[,\s]+/);
              var transformName = result[1].trim();
              if (transformName == "translate") {
                  groupTransform.transformX = split[0];
                  groupTransform.transformY = split[1] || 0;
                  groupTransform.isSet = true;
              } else if (transformName == "scale") {
                  groupTransform.scaleX = split[0];
                  groupTransform.scaleY = split[1] || 0;
                  groupTransform.isSet = true;
              } else if (transformName == "rotate") {
                  groupTransform.rotate = split[0];
                  groupTransform.rotatePivotX = split[1] || -1;
                  groupTransform.rotatePivotY = split[2] || -1;
                  groupTransform.isSet = true;
              } else {
                  pushUnique(warnings, "group transform '<i>" + transformName + "</i>' is not supported, use option <i>Bake transforms into path</i>")
              }
          }
      }
      if (typeof id !== "undefined") {
          groupTransform.id = id;
      }
  
      return groupTransform;
  }
  
  function parsePathD(pathData) {
      var path = pathData.attr("d");
  
      if (typeof path === "undefined") {
          return null;
      }
  
      path = path.replace(/\s{2,}/g, " "); //replace extra spaces
  
      if (path.match(/-?\d*\.?\d+e[+-]?\d+/g)) {
          pushUnique(warnings, "found some numbers with scientific E notation in pathData which Android probably does not support. " +
          "Please fix It manually by editing your editor precision or manually by editing pathData");
      }
  
      //Check path If contains draw otherwise use default l
      var pathStart = false, bigM = false, skipMove = false, stop = false;
      var pathRebuild = "";
      path.split(" ").forEach(function (t) {
          if (stop) {
              pathRebuild += t + " ";
              return;
          }
  
          if (t.toUpperCase() == START_PATH) {
              pathStart = true;
              bigM = t == START_PATH;
          } else if (skipMove && pathStart) {
              if (!(t.indexOf(",") == -1 && isNaN(t))) {
                  t = (bigM ? DRAW_LINE.toUpperCase() : DRAW_LINE) + " " + t;
              }
              stop = true;
          } else if (pathStart) {
              skipMove = true;
          }
  
          pathRebuild += t + " ";
      });
  
      path = fixPathPositioning(pathRebuild);
      path = fixNumberFormatting(path);
  
      if (!path.endsWith(" ")) {
          path += " ";
      }
  
      return wordwrap(path.trim(), 80, "\n");
  }
  
  
  function parseStyles(path) {
      //Convert attributes to style
      var attributes = path[0].attributes;
      var stylesArray = {};
      for (var n = 0; n < attributes.length; n++) {
          var name = attributes[n].name;
          var value = attributes[n].value;
          if (name == "style") {
              //Fix CSSJSON bug
              if (!value.endsWith(";")) {
                  value += ";"
              }
              var cssAttributes = CSSJSON.toJSON(value).attributes;
              parseCssAttributes(stylesArray, cssAttributes);
          } else if (name == "class") {
              var val = "." + value.trim();
              if (typeof svgStyles.children !== "undefined" && typeof svgStyles.children[val] !== "undefined") {
                  parseCssAttributes(stylesArray, svgStyles.children[val].attributes);
              }
          } else {
              stylesArray[name] = value;
              checkAttribute(name, value);
          }
      }
  
      return stylesArray;
  }
  
  function parseCssAttributes(stylesArray, cssAttributes) {
      for (var key in cssAttributes) {
          if (cssAttributes.hasOwnProperty(key)) {
              stylesArray[key] = cssAttributes[key];
  
              checkAttribute(key, cssAttributes[key]);
          }
      }
  }
  
  function checkAttribute(key, val) {
      if ((key == "fill" || key == "stroke") && val.startsWith("url")) {
          pushUnique(warnings, "found fill(s) or stroke(s) which uses <i>url()</i> (gradients and patterns are not supported in Android)");
      } else if ((key == "fill-rule") && val == "evenodd") {
          pushUnique(warnings, "found attribute 'fill-rule:evenodd' which is not supported in Android - sometimes can cause that svg will be not rendered correctly (<a target='_blank' href='https://github.com/inloop/svg2android/issues/44'>more info</a>)");
      }
  }
  
  function printGroupStart(groupTransform, groupLevel) {
      generatedOutput += INDENT.repeat(groupLevel + 1) + '<group\n';
      if (toBool(localStorage.useIdAsName)) generatedOutput += generateAttr("name", groupTransform.id, groupLevel + 1, "");
      generatedOutput += generateAttr("translateX", groupTransform.transformX, groupLevel + 1, 0);
      generatedOutput += generateAttr("translateY", groupTransform.transformY, groupLevel + 1, 0);
      generatedOutput += generateAttr("scaleX", groupTransform.scaleX, groupLevel + 1, 1);
      generatedOutput += generateAttr("scaleY", groupTransform.scaleY, groupLevel + 1, 1);
      if (generatedOutput.endsWith("\n")) {
          generatedOutput = generatedOutput.substr(0, generatedOutput.length - 1);
      }
      generatedOutput += ">\n";
  }
  
  function printGroupEnd(groupLevel) {
      generatedOutput += INDENT.repeat(groupLevel + 1) + '</group>\n';
  }
  
  function printPath(pathData, stylesArray, groupLevel) {
      var styles = stylesArray[0];
      var parentGroupStyles = stylesArray[1];
  
      if (pathData == null) {
          return;
      }
  
      if (styles.hasOwnProperty("transform")) {
          pushUnique(warnings, "transforms on path are not supported, use option <i>Bake transforms into path</i>")
      }
  
      if (parentGroupStyles != null) {
          //Inherit styles from group first
          for (var styleName in parentGroupStyles) {
              if (typeof styles[styleName] === "undefined") {
                  styles[styleName] = parentGroupStyles[styleName];
              }
          }
      }
      //Parent opacity setting - multiply fill-opacity and stroke-opacity
      var opacity = styles["opacity"];
      if (typeof opacity !== "undefined") {
          if (typeof styles["fill-opacity"] !== "undefined") {
              styles["fill-opacity"] *= opacity;
          } else {
              styles["fill-opacity"] = opacity;
          }
          if (typeof styles["stroke-opacity"] !== "undefined") {
              styles["stroke-opacity"] *= opacity;
          } else {
              styles["stroke-opacity"] = opacity;
          }
      }
  
      //If fill is omitted use default black
      if (typeof styles["fill"] === "undefined") {
          styles["fill"] = "#000000";
      }
  
      generatedOutput += INDENT.repeat(groupLevel + 1) + '<path\n';
      if (toBool(localStorage.useIdAsName)) generatedOutput += generateAttr('name', styles["id"], groupLevel, "");
      generatedOutput += generateAttr('fillColor', parseColorToHex(styles["fill"]), groupLevel, "none");
      generatedOutput += generateAttr('fillAlpha', styles["fill-opacity"], groupLevel, "1");
      generatedOutput += generateAttr('strokeColor', parseColorToHex(styles["stroke"]), groupLevel, "none");
      generatedOutput += generateAttr('strokeAlpha', styles["stroke-opacity"], groupLevel, "1");
      generatedOutput += generateAttr('strokeWidth', removeNonNumeric(styles["stroke-width"]), groupLevel, "0");
      generatedOutput += generateAttr('strokeLineJoin', styles["stroke-linejoin"], groupLevel, "miter");
      generatedOutput += generateAttr('strokeMiterLimit', styles["stroke-miterlimit"], groupLevel, "4");
      generatedOutput += generateAttr('strokeLineCap', styles["stroke-linecap"], groupLevel, "butt");
      generatedOutput += generateAttr('pathData', pathData, groupLevel, null, true);
      pathsParsedCount++;
  }
  
  function generateCode(inputXml) {
      var resultData = { error:null, warnings:null, code:null };
  
      var xml;
      try {
          xml = $($.parseXML(inputXml));
      } catch (e) {
          resultData.error = "<b>Error:</b> not valid SVG file.";
          return resultData;
      }
  
      //Reset previous
      pathsParsedCount = 0;
      warnings = [];
      svgStyles = {};
  
      var svg = xml.find("svg");
  
      preprocessReferences(svg);
  
      if (toBool(localStorage.bakeTransforms)) {
          try {
              flatten(svg[0], false, true);
          } catch (e) {
              console.error(e);
              resultData.error = "<b>Error:</b> problem during parsing svg (flatten failed).";
              return resultData;
          }
      }
  
      var cssStyle = svg.find("style");
      if (cssStyle.length) {
          svgStyles = CSSJSON.toJSON(cssStyle.text().trim());
      }
  
      //Parse dimensions
      var dimensions = getDimensions(svg);
      var width = dimensions.width;
      var height = dimensions.height;
  
      //XML Vector start
      generatedOutput = '<?xml version="1.0" encoding="utf-8"?>\n';
      generatedOutput += '<vector xmlns:android="http://schemas.android.com/apk/res/android"';
  
      generatedOutput += '\n' + INDENT + 'android:width="{0}dp"\n'.f(width);
      generatedOutput += INDENT + 'android:height="{0}dp"\n'.f(height);
  
      generatedOutput += INDENT + 'android:viewportWidth="{0}"\n'.f(width);
      generatedOutput += INDENT + 'android:viewportHeight="{0}"'.f(height);
  
      generatedOutput += '>\n\n';
  
      //XML Vector content
      //Iterate through groups and paths
      recursiveTreeWalk(svg, 0);
  
      //XML Vector end
      generatedOutput += '</vector>';
  
      if (warnings.length == 1) {
          resultData.warnings = "<b>Warning:</b> " + warnings[0];
      } else if (warnings.length > 1) {
          var warnText = "";
          warnings.forEach(function (w, i) {
              warnText += "<tr><td><b>Warning #" + (i + 1) + ":</b></td><td>" + w + "</td></tr>";
          });
          resultData.warnings = "<table class='info-items'>" + warnText + "</table>";
      }
  
      //SVG must contain path(s)
      if (pathsParsedCount == 0) {
          resultData.error = "No shape elements found in svg.";
          return resultData;
      }
  
      resultData.code = generatedOutput;
  
      return resultData;
  }
  
  function parseSingleFile(inputXml) {
      lastFileData = inputXml;
  
      $(".alert").hide();
  
      var data = generateCode(inputXml);
  
      if (data.warnings !== null) {
          setMessage(data.warnings, "alert-warning");
      }
  
      if (data.error !== null) {
          setMessage(data.error, "alert-danger");
          $("#output-box").hide();
      } else {
          $("#output-code").text(data.code).animate({scrollTop: 0}, "fast");
          $("#output-box").fadeIn();
          $(".nouploadinfo").hide();
          $("#dropzone").animate({height: 50}, 500);
          $("#success-box").show();
      }
  }
  
  function parseMultipleFiles(inputXml) {
      var data = generateCode(inputXml);
  
      groupData.log += "<br><h4>" + lastFileName + "</h4>";
      if (data.warnings !== null) {
          groupData.log += data.warnings + "<br>";
      }
  
      if (data.error !== null) {
          groupData.log += data.error + "<br>";
          groupData.errors++;
      } else {
          if (data.warnings === null) {
              groupData.log += "OK<br>";
          }
          groupData.zip.file(extractFileNameWithoutExt(lastFileName) + ".xml", data.code);
      }
  }
  
  function fixPathPositioning(path) {
      return path.replace(/^\s*m/, START_PATH).replace(/^\s*z/, END_PATH);
  }
  
  function fixNumberFormatting(path) {
      return path.replace(/(\.\d+)(\.\d+)\s?/g, "\$1 \$2 ");
  }
  
  function getDimensions(svg) {
      var widthAttr = svg.attr("width");
      var heightAttr = svg.attr("height");
      var viewBoxAttr = svg.attr("viewBox");
  
      if (typeof viewBoxAttr === "undefined") {
          if (typeof widthAttr === "undefined" || typeof heightAttr === "undefined") {
              pushUnique(warnings, "width or height not set for svg (set -1)");
              return {width: -1, height: -1};
          } else {
              return {width: convertDimensionToPx(widthAttr), height: convertDimensionToPx(heightAttr)};
          }
      } else {
          var viewBoxAttrParts = viewBoxAttr.split(/[,\s]+/);
          if (viewBoxAttrParts[0] > 0 || viewBoxAttrParts[1] > 0) {
              pushUnique(warnings, "viewbox minx/miny is other than 0 (not supported)");
          }
          return {width: viewBoxAttrParts[2], height: viewBoxAttrParts[3]};
      }
  
  }
  
  function removeNonNumeric(input) {
      if (typeof input === "undefined") return input;
      return input.replace(/[^0-9.]/g, "");
  }
  
  
  function generateAttr(name, val, groupLevel, def, end) {
      if (typeof val === "undefined" || val == def || val == "null") return "";
  
      var result = INDENT.repeat(groupLevel + 2) + 'android:{0}="{1}"'.f(name, val);
  
      if (end) {
          result += ' />';
      }
      result += '\n';
      return result;
  }
  
  function selectAll() {
      var el = $("#output-code")[0];
      if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
          var range = document.createRange();
          range.selectNodeContents(el);
          var sel = window.getSelection();
          sel.removeAllRanges();
          sel.addRange(range);
      } else if (typeof document.selection != "undefined" && typeof document.body.createTextRange != "undefined") {
          var textRange = document.body.createTextRange();
          textRange.moveToElementText(el);
          textRange.select();
      }
  }
  
  function download() {
      var blob = new Blob([$("#output-code").text()], {type: "text/xml;charset=utf-8"});
      var filename = extractFileNameWithoutExt(lastFileName) || "";
      saveAs(blob, filename.length > 0 ? (filename + ".xml") : "vector.xml", true);
  }
  
  function dropzoneClick() {
      $("#dropzone-dialog").click();
  }
  
  function setMessage(text, type) {
      var info = $("." + type + ".box");
      info.html(text);
      info.removeClass();
      info.addClass("alert");
      info.addClass("box");
      info.addClass(type);
      info.show();
  }
  
  function useIdAsName(el) {
      localStorage.useIdAsName = el.checked;
      if (groupData.groupSize == 1) parseSingleFile(lastFileData);
  }
  
  function bakeTransforms(el) {
      localStorage.bakeTransforms = el.checked;
      if (groupData.groupSize == 1) parseSingleFile(lastFileData);
  }
  
  function clearGroups(el) {
      localStorage.clearGroups = el.checked;
      if (groupData.groupSize == 1) parseSingleFile(lastFileData);
  }
  
  function wordwrap(str, width, brk, cut) {
      brk = brk || '\n';
      width = width || 75;
      cut = cut || false;
  
      if (!str) {
          return str;
      }
  
      var regex = '.{1,' + width + '}(\\s|$)' + (cut ? '|.{' + width + '}|.+$' : '|\\S+?(\\s|$)');
  
      var matches = str.match(new RegExp(regex, 'g'));
      // trim off leading/trailing spaces from the matched strings
      for (i = 0; i < matches.length; i++) {
          matches[i] = matches[i].trim();
      }
  
      return matches.join(brk);
  }
  
  //Parse rgb, named colors to hex
  function parseColorToHex(color) {
      if (typeof color === "undefined") return color;
      color = color.replace(/\s/g, "");
  
      //Is hex already
      if (color.substr(0, 1) === "#") {
          return color;
      } else {
          if (color.startsWith("rgb(")) {
              var match = /rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/.exec(color);
              return match !== null && match.length >= 4 ? $c.rgb2hex(parseInt(match[1]), parseInt(match[2]), parseInt(match[3])) : color;
          } else {
              var hexClr = $c.name2hex(color);
              return !hexClr.startsWith("Invalid") ? hexClr : color;
          }
      }
  }
  
  function convertDimensionToPx(dimen) {
      var val = removeNonNumeric(dimen);
      var METER_TO_PX = 3543.30709;
      var INCH_TO_PX = 90;
      var PT_TO_PX = 1.25;
      var PC_TO_PX = 15;
      var FT_TO_PX = 1080;
  
      if (dimen.endsWith("mm")) {
          return val * (METER_TO_PX / 1000);
      } else if (dimen.endsWith("cm")) {
          return val * (METER_TO_PX / 100);
      } else if (dimen.endsWith("m")) {
          return val * METER_TO_PX;
      } else if (dimen.endsWith("in")) {
          return val * INCH_TO_PX;
      } else if (dimen.endsWith("pt")) {
          return val * PT_TO_PX;
      } else if (dimen.endsWith("pc")) {
          return val * PC_TO_PX;
      } else if (dimen.endsWith("ft")) {
          return val * FT_TO_PX;
      } else {
          return val;
      }
  }