function extname(path) {
  assertPath(path);
  let start = 0;
  let startDot = -1;
  let startPart = 0;
  let end = -1;
  let matchedSlash = true;
  // Track the state of characters (if any) we see before our first dot and
  // after any path separator we find
  let preDotState = 0;
  // Check for a drive letter prefix so as not to mistake the following
  // path separator as an extra separator at the end of the path that can be
  // disregarded
  if (
    path.length >= 2 && path.charCodeAt(1) === CHAR_COLON &&
    isWindowsDeviceRoot(path.charCodeAt(0))
  ) {
    start = startPart = 2;
  }
  for (let i = path.length - 1; i >= start; --i) {
    const code = path.charCodeAt(i);
    if (isPathSeparator(code)) {
      // If we reached a path separator that was not part of a set of path
      // separators at the end of the string, stop now
      if (!matchedSlash) {
        startPart = i + 1;
        break;
      }
      continue;
    }
    if (end === -1) {
      // We saw the first non-path separator, mark this as the end of our
      // extension
      matchedSlash = false;
      end = i + 1;
    }
    if (code === CHAR_DOT) {
      // If this is our first dot, mark it as the start of our extension
      if (startDot === -1) startDot = i;
      else if (preDotState !== 1) preDotState = 1;
    } else if (startDot !== -1) {
      // We saw a non-dot and non-path separator before our dot, so we should
      // have a good chance at having a non-empty extension
      preDotState = -1;
    }
  }
  if (
    startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot
    preDotState === 0 || // The (right-most) trimmed path component is exactly '..'
    (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)
  ) {
    return "";
  }
  return path.slice(startDot, end);
}
/**
 * Return the extension of the `path`.
 * @param path with extension
 */
Return the extension of the `path`.
@param path with extension
Return the extension of the ` path ` . @param path with extension
function extname(path) {
  assertPath(path);
  let start = 0;
  let startDot = -1;
  let startPart = 0;
  let end = -1;
  let matchedSlash = true;
  let preDotState = 0;
  if (
    path.length >= 2 && path.charCodeAt(1) === CHAR_COLON &&
    isWindowsDeviceRoot(path.charCodeAt(0))
  ) {
    start = startPart = 2;
  }
  for (let i = path.length - 1; i >= start; --i) {
    const code = path.charCodeAt(i);
    if (isPathSeparator(code)) {
      if (!matchedSlash) {
        startPart = i + 1;
        break;
      }
      continue;
    }
    if (end === -1) {
      matchedSlash = false;
      end = i + 1;
    }
    if (code === CHAR_DOT) {
      if (startDot === -1) startDot = i;
      else if (preDotState !== 1) preDotState = 1;
    } else if (startDot !== -1) {
      preDotState = -1;
    }
  }
  if (
    startDot === -1 || end === -1 || 
    preDotState === 0 || 
    (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)
  ) {
    return "";
  }
  return path.slice(startDot, end);
}
function extname ( path ) { assertPath ( path ) ; let start = 0 ; let startDot = - 1 ; let startPart = 0 ; let end = - 1 ; let matchedSlash = true ; let preDotState = 0 ; if ( path . length >= 2 && path . charCodeAt ( 1 ) === CHAR_COLON && isWindowsDeviceRoot ( path . charCodeAt ( 0 ) ) ) { start = startPart = 2 ; } for ( let i = path . length - 1 ; i >= start ; -- i ) { const code = path . charCodeAt ( i ) ; if ( isPathSeparator ( code ) ) { if ( ! matchedSlash ) { startPart = i + 1 ; break ; } continue ; } if ( end === - 1 ) { matchedSlash = false ; end = i + 1 ; } if ( code === CHAR_DOT ) { if ( startDot === - 1 ) startDot = i ; else if ( preDotState !== 1 ) preDotState = 1 ; } else if ( startDot !== - 1 ) { preDotState = - 1 ; } } if ( startDot === - 1 || end === - 1 || preDotState === 0 || ( preDotState === 1 && startDot === end - 1 && startDot === startPart + 1 ) ) { return "" ; } return path . slice ( startDot , end ) ; }
Return the extension of the `path`.
Return the extension of the ` path ` .
// Track the state of characters (if any) we see before our first dot and // after any path separator we find // Check for a drive letter prefix so as not to mistake the following // path separator as an extra separator at the end of the path that can be // disregarded // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now // We saw the first non-path separator, mark this as the end of our // extension // If this is our first dot, mark it as the start of our extension // We saw a non-dot and non-path separator before our dot, so we should // have a good chance at having a non-empty extension // We saw a non-dot character immediately before the dot // The (right-most) trimmed path component is exactly '..'