/*
https://en.wikipedia.org/wiki/Levenshtein_distance
计算两条path的编辑距离
334987
function(source, target) {
  const sourceLen = source.length;
  const targetLen = target.length;
  let sourceSegment,
    targetSegment;
  let temp = 0;
  if (sourceLen === 0 || targetLen === 0) {
    return null;
  }
  const dist = [];
  for (let i = 0; i <= sourceLen; i++) {
    dist[i] = [];
    dist[i][0] = { min: i };
  }
  for (let j = 0; j <= targetLen; j++) {
    dist[0][j] = { min: j };
  }

  for (let i = 1; i <= sourceLen; i++) {
    sourceSegment = source[i - 1];
    for (let j = 1; j <= targetLen; j++) {
      targetSegment = target[j - 1];
      if (isEqual(sourceSegment, targetSegment)) {
        temp = 0;
      } else {
        temp = 1;
      }
      const del = dist[i - 1][j].min + 1;
      const add = dist[i][j - 1].min + 1;
      const modify = dist[i - 1][j - 1].min + temp;
      dist[i][j] = getMinDiff(del, add, modify);
    }
  }
  return dist;
}
264084
function (path) {
        if (path[path.length - 1] === '/') {
            path = path.substr(0, path.length - 1);
        }
        return path;
    }
1292591
def levenshtein_distance_metric(a, b):
    
    return (levenshtein_distance(a, b) / (2.0 * max(len(a), len(b), 1)))
756228
function pathStrToPathArr(path) {
	path = path.substr(1).split('/').map(part => {
		// De-tokenize '/' characters in path name
		return part.replace(/~1/g, '/');
	});

	// For some reason, path arrays whose only item is an empty string cause errors.
	// In this case, we replace the path with an empty array, which seems to be fine.
	if (path.length === 1 && path[0] === '') {
		path = [];
	}

	return path;
}
602627
function calcRelPath(filePath, linkPath) {
    filePath = filePath.replace(`\\`, `/`);
    linkPath = linkPath.replace(`\\`, `/`);
    let RelPath = '',
        linkPathList = linkPath.split('/'),
        filePathList = filePath.split('/'),
        idx = 0;
    console.log(`File Path : ${filePath}, link path : ${linkPath}`);
    for (let i = 1; i < filePathList.length - 1; i++) {
        idx = i;
        if (filePathList[i] === linkPathList[i])
            break;
        RelPath += '../';
    }

    if (RelPath.length === 0) {
        RelPath += './';
        idx += 1;
    }

    if (idx === 0) idx += 1;

    for (let i = idx; i < linkPathList.length - 1; i++) {
        RelPath += linkPathList[i] + '/';
    }

    RelPath += linkPathList[linkPathList.length - 1];
    console.log(`RelPath : ${RelPath}`);
    return RelPath;
}
1169972
def levenshtein_norm(source, target):
    

    # Compute Levenshtein distance using helper function. The max is always
    # just the length of the longer string, so this is used to normalize result
    # before returning it
    distance = _levenshtein_compute(source, target, False)
    return float(distance) / max(len(source), len(target))
744102
function(p) {

            if (!p) return false;

            var segments = this.segments;
            var otherSegments = p.segments;

            var numSegments = segments.length;
            if (otherSegments.length !== numSegments) return false; // if the two paths have different number of segments, they cannot be equal

            for (var i = 0; i < numSegments; i++) {

                var segment = segments[i];
                var otherSegment = otherSegments[i];

                // as soon as an inequality is found in segments, return false
                if ((segment.type !== otherSegment.type) || (!segment.equals(otherSegment))) return false;
            }

            // if no inequality found in segments, return true
            return true;
        }
379583
def damerau_levenshtein_distance(self, s1, s2):
        
        d = {}
        lenstr1 = len(s1)
        lenstr2 = len(s2)
        for i in xrange(-1,lenstr1+1):
            d[(i,-1)] = i+1
        for j in xrange(-1,lenstr2+1):
            d[(-1,j)] = j+1
 
        for i in xrange(lenstr1):
            for j in xrange(lenstr2):
                if s1[i] == s2[j]:
                    cost = 0
                else:
                    cost = 1
                d[(i,j)] = min(
                               d[(i-1,j)] + 1, # deletion
                               d[(i,j-1)] + 1, # insertion
                               d[(i-1,j-1)] + cost, # substitution
                              )
                if i and j and s1[i]==s2[j-1] and s1[i-1] == s2[j]:
                    d[(i,j)] = min (d[(i,j)], d[i-2,j-2] + cost) # transposition
 
        return d[lenstr1-1,lenstr2-1]
1141000
function distance(str1, str2, options_p) {
        /**
         * Calculate levenshtein distance of the two strings.
         *
         * @function distance
         * @param {string} str1 - the first string.
         * @param {string} str2 - the second string.
         * @param {Object} [options_p] - Additional options.
         * @param {boolean} [options_p.useCollator] - Use `Intl.Collator` for locale-sensitive string comparison.
         * @param {boolean} [options_p.full_process] - Apply basic cleanup, non-alphanumeric to whitespace etc. if true. default true
         * @param {boolean} [options_p.force_ascii] - Strip non-ascii in full_process if true (non-ascii will not become whtespace), only applied if full_process is true as well, default true
         * @param {boolean} [options_p.collapseWhitespace] - Collapse consecutive white space during full_process, default true
         * @param {string} [options_p.wildcards] - characters that will be used as wildcards if provided
         * @returns {number} - the levenshtein distance (0 and above).
         */
        var options = _clone_and_set_option_defaults(options_p);
        str1 = options.full_process ? full_process(str1, options) : str1;
        str2 = options.full_process ? full_process(str2, options) : str2;
        if (typeof options.subcost === "undefined") options.subcost = 1;
        if (options.astral) return _iLeven(str1, str2, options, _toArray);
        else return _wildLeven(str1, str2, options, _leven); // falls back to _leven if no wildcards
    }
543863
function getPathDepth(p) {
  var parts = p.split(path.sep);
  // On *nix-based OS's, the root is '/'
  if(!parts[0]) {
    parts.unshift();
  }

  return p.split(path.sep).length;
}
190390
function getPathFromBase(href) {
  return base[0] == '#'
    ? (href || loc.href).split(base)[1] || ''
    : getPathFromRoot(href)[REPLACE](base, '')
}
1218113
public static boolean isAbsolutePath(String path) {
		if (StrUtil.isEmpty(path)) {
			return false;
		}

		if (StrUtil.C_SLASH == path.charAt(0) || path.matches("^[a-zA-Z]:[/\\\\].*")) {
			// 给定的路径已经是绝对路径了
			return true;
		}
		return false;
	}
616096
func LevenshteinDistanceMax(a, b string, max int) (int, bool) {
	v, wasMax, _ := LevenshteinDistanceMaxReuseSlice(a, b, max, nil)
	return v, wasMax
}
984998
function _gpfPathExtension (path) {
    var name = _gpfPathName(path),
        pos = name.lastIndexOf(".");
    if (pos === _GPF_NOT_FOUND) {
        return "";
    }
    return name.substring(pos);
}
413857
function matchPath(prefix, path) {
    // 如果缓存存在，则直接返回结果
    if (PATH_CACHE[path]) {
      return PATH_CACHE[path];
    }

    // 如果匹配规则是一个String则直接匹配
    if (typeof prefix == 'string') {
      let match = minimatch(path, prefix);
      if (!match) {
        return false;
      }

      PATH_CACHE[path] = formatPath(prefix, path);

      return PATH_CACHE[path];
    }

    // 如果匹配规则不是String则只能是Array
    if (!prefix.length || prefix.length < 1) {
      return false;
    }

    for (let i = 0; i < prefix.length; i++) {
      let match = minimatch(path, prefix[i]);
      if (match) {
        PATH_CACHE[path] = formatPath(prefix[i], path);
        return PATH_CACHE[path];
      }
    }

    return false;
  }
297816
function levenshteinDistance(source, target) {
  var sourceLen = source.length;
  var targetLen = target.length;
  var sourceSegment = void 0,
      targetSegment = void 0;
  var temp = 0;
  if (sourceLen === 0 || targetLen === 0) {
    return null;
  }
  var dist = [];
  for (var i = 0; i <= sourceLen; i++) {
    dist[i] = [];
    dist[i][0] = { min: i };
  }
  for (var j = 0; j <= targetLen; j++) {
    dist[0][j] = { min: j };
  }

  for (var _i4 = 1; _i4 <= sourceLen; _i4++) {
    sourceSegment = source[_i4 - 1];
    for (var _j2 = 1; _j2 <= targetLen; _j2++) {
      targetSegment = target[_j2 - 1];
      if (isEqual(sourceSegment, targetSegment)) {
        temp = 0;
      } else {
        temp = 1;
      }
      var del = dist[_i4 - 1][_j2].min + 1;
      var add = dist[_i4][_j2 - 1].min + 1;
      var modify = dist[_i4 - 1][_j2 - 1].min + temp;
      dist[_i4][_j2] = getMinDiff(del, add, modify);
    }
  }
  return dist;
}
1272855
function generatePathString(paths) {
  let pathString = '';

  if (!paths || !paths.length) return pathString;

  if (paths.length > 1) {
    pathString = paths.map(pathItem => filepathName(pathItem));
    // Trim long lists
    if (pathString.length > maxInputStringLength) {
      const remainder = pathString.length - maxInputStringLength;

      pathString = `${pathString
        .slice(0, maxInputStringLength)
        .join(', ')} ...and ${remainder} other${remainder > 1 ? 's' : ''}`;
    } else {
      pathString = pathString.join(', ');
    }
  } else {
    pathString = filepathName(paths[0]);
  }

  return pathString;
}