You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					392 lines
				
				9.0 KiB
			
		
		
			
		
	
	
					392 lines
				
				9.0 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const utils = require('./utils');
							 | 
						||
| 
								 | 
							
								const {
							 | 
						||
| 
								 | 
							
								  CHAR_ASTERISK,             /* * */
							 | 
						||
| 
								 | 
							
								  CHAR_AT,                   /* @ */
							 | 
						||
| 
								 | 
							
								  CHAR_BACKWARD_SLASH,       /* \ */
							 | 
						||
| 
								 | 
							
								  CHAR_COMMA,                /* , */
							 | 
						||
| 
								 | 
							
								  CHAR_DOT,                  /* . */
							 | 
						||
| 
								 | 
							
								  CHAR_EXCLAMATION_MARK,     /* ! */
							 | 
						||
| 
								 | 
							
								  CHAR_FORWARD_SLASH,        /* / */
							 | 
						||
| 
								 | 
							
								  CHAR_LEFT_CURLY_BRACE,     /* { */
							 | 
						||
| 
								 | 
							
								  CHAR_LEFT_PARENTHESES,     /* ( */
							 | 
						||
| 
								 | 
							
								  CHAR_LEFT_SQUARE_BRACKET,  /* [ */
							 | 
						||
| 
								 | 
							
								  CHAR_PLUS,                 /* + */
							 | 
						||
| 
								 | 
							
								  CHAR_QUESTION_MARK,        /* ? */
							 | 
						||
| 
								 | 
							
								  CHAR_RIGHT_CURLY_BRACE,    /* } */
							 | 
						||
| 
								 | 
							
								  CHAR_RIGHT_PARENTHESES,    /* ) */
							 | 
						||
| 
								 | 
							
								  CHAR_RIGHT_SQUARE_BRACKET  /* ] */
							 | 
						||
| 
								 | 
							
								} = require('./constants');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const isPathSeparator = code => {
							 | 
						||
| 
								 | 
							
								  return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const depth = token => {
							 | 
						||
| 
								 | 
							
								  if (token.isPrefix !== true) {
							 | 
						||
| 
								 | 
							
								    token.depth = token.isGlobstar ? Infinity : 1;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Quickly scans a glob pattern and returns an object with a handful of
							 | 
						||
| 
								 | 
							
								 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
							 | 
						||
| 
								 | 
							
								 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not
							 | 
						||
| 
								 | 
							
								 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * ```js
							 | 
						||
| 
								 | 
							
								 * const pm = require('picomatch');
							 | 
						||
| 
								 | 
							
								 * console.log(pm.scan('foo/bar/*.js'));
							 | 
						||
| 
								 | 
							
								 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
							 | 
						||
| 
								 | 
							
								 * ```
							 | 
						||
| 
								 | 
							
								 * @param {String} `str`
							 | 
						||
| 
								 | 
							
								 * @param {Object} `options`
							 | 
						||
| 
								 | 
							
								 * @return {Object} Returns an object with tokens and regex source string.
							 | 
						||
| 
								 | 
							
								 * @api public
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const scan = (input, options) => {
							 | 
						||
| 
								 | 
							
								  const opts = options || {};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const length = input.length - 1;
							 | 
						||
| 
								 | 
							
								  const scanToEnd = opts.parts === true || opts.scanToEnd === true;
							 | 
						||
| 
								 | 
							
								  const slashes = [];
							 | 
						||
| 
								 | 
							
								  const tokens = [];
							 | 
						||
| 
								 | 
							
								  const parts = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  let str = input;
							 | 
						||
| 
								 | 
							
								  let index = -1;
							 | 
						||
| 
								 | 
							
								  let start = 0;
							 | 
						||
| 
								 | 
							
								  let lastIndex = 0;
							 | 
						||
| 
								 | 
							
								  let isBrace = false;
							 | 
						||
| 
								 | 
							
								  let isBracket = false;
							 | 
						||
| 
								 | 
							
								  let isGlob = false;
							 | 
						||
| 
								 | 
							
								  let isExtglob = false;
							 | 
						||
| 
								 | 
							
								  let isGlobstar = false;
							 | 
						||
| 
								 | 
							
								  let braceEscaped = false;
							 | 
						||
| 
								 | 
							
								  let backslashes = false;
							 | 
						||
| 
								 | 
							
								  let negated = false;
							 | 
						||
| 
								 | 
							
								  let negatedExtglob = false;
							 | 
						||
| 
								 | 
							
								  let finished = false;
							 | 
						||
| 
								 | 
							
								  let braces = 0;
							 | 
						||
| 
								 | 
							
								  let prev;
							 | 
						||
| 
								 | 
							
								  let code;
							 | 
						||
| 
								 | 
							
								  let token = { value: '', depth: 0, isGlob: false };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const eos = () => index >= length;
							 | 
						||
| 
								 | 
							
								  const peek = () => str.charCodeAt(index + 1);
							 | 
						||
| 
								 | 
							
								  const advance = () => {
							 | 
						||
| 
								 | 
							
								    prev = code;
							 | 
						||
| 
								 | 
							
								    return str.charCodeAt(++index);
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  while (index < length) {
							 | 
						||
| 
								 | 
							
								    code = advance();
							 | 
						||
| 
								 | 
							
								    let next;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (code === CHAR_BACKWARD_SLASH) {
							 | 
						||
| 
								 | 
							
								      backslashes = token.backslashes = true;
							 | 
						||
| 
								 | 
							
								      code = advance();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (code === CHAR_LEFT_CURLY_BRACE) {
							 | 
						||
| 
								 | 
							
								        braceEscaped = true;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      continue;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {
							 | 
						||
| 
								 | 
							
								      braces++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      while (eos() !== true && (code = advance())) {
							 | 
						||
| 
								 | 
							
								        if (code === CHAR_BACKWARD_SLASH) {
							 | 
						||
| 
								 | 
							
								          backslashes = token.backslashes = true;
							 | 
						||
| 
								 | 
							
								          advance();
							 | 
						||
| 
								 | 
							
								          continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (code === CHAR_LEFT_CURLY_BRACE) {
							 | 
						||
| 
								 | 
							
								          braces++;
							 | 
						||
| 
								 | 
							
								          continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {
							 | 
						||
| 
								 | 
							
								          isBrace = token.isBrace = true;
							 | 
						||
| 
								 | 
							
								          isGlob = token.isGlob = true;
							 | 
						||
| 
								 | 
							
								          finished = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (scanToEnd === true) {
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (braceEscaped !== true && code === CHAR_COMMA) {
							 | 
						||
| 
								 | 
							
								          isBrace = token.isBrace = true;
							 | 
						||
| 
								 | 
							
								          isGlob = token.isGlob = true;
							 | 
						||
| 
								 | 
							
								          finished = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (scanToEnd === true) {
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (code === CHAR_RIGHT_CURLY_BRACE) {
							 | 
						||
| 
								 | 
							
								          braces--;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (braces === 0) {
							 | 
						||
| 
								 | 
							
								            braceEscaped = false;
							 | 
						||
| 
								 | 
							
								            isBrace = token.isBrace = true;
							 | 
						||
| 
								 | 
							
								            finished = true;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (scanToEnd === true) {
							 | 
						||
| 
								 | 
							
								        continue;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (code === CHAR_FORWARD_SLASH) {
							 | 
						||
| 
								 | 
							
								      slashes.push(index);
							 | 
						||
| 
								 | 
							
								      tokens.push(token);
							 | 
						||
| 
								 | 
							
								      token = { value: '', depth: 0, isGlob: false };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (finished === true) continue;
							 | 
						||
| 
								 | 
							
								      if (prev === CHAR_DOT && index === (start + 1)) {
							 | 
						||
| 
								 | 
							
								        start += 2;
							 | 
						||
| 
								 | 
							
								        continue;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      lastIndex = index + 1;
							 | 
						||
| 
								 | 
							
								      continue;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (opts.noext !== true) {
							 | 
						||
| 
								 | 
							
								      const isExtglobChar = code === CHAR_PLUS
							 | 
						||
| 
								 | 
							
								        || code === CHAR_AT
							 | 
						||
| 
								 | 
							
								        || code === CHAR_ASTERISK
							 | 
						||
| 
								 | 
							
								        || code === CHAR_QUESTION_MARK
							 | 
						||
| 
								 | 
							
								        || code === CHAR_EXCLAMATION_MARK;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {
							 | 
						||
| 
								 | 
							
								        isGlob = token.isGlob = true;
							 | 
						||
| 
								 | 
							
								        isExtglob = token.isExtglob = true;
							 | 
						||
| 
								 | 
							
								        finished = true;
							 | 
						||
| 
								 | 
							
								        if (code === CHAR_EXCLAMATION_MARK && index === start) {
							 | 
						||
| 
								 | 
							
								          negatedExtglob = true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (scanToEnd === true) {
							 | 
						||
| 
								 | 
							
								          while (eos() !== true && (code = advance())) {
							 | 
						||
| 
								 | 
							
								            if (code === CHAR_BACKWARD_SLASH) {
							 | 
						||
| 
								 | 
							
								              backslashes = token.backslashes = true;
							 | 
						||
| 
								 | 
							
								              code = advance();
							 | 
						||
| 
								 | 
							
								              continue;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (code === CHAR_RIGHT_PARENTHESES) {
							 | 
						||
| 
								 | 
							
								              isGlob = token.isGlob = true;
							 | 
						||
| 
								 | 
							
								              finished = true;
							 | 
						||
| 
								 | 
							
								              break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								          continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (code === CHAR_ASTERISK) {
							 | 
						||
| 
								 | 
							
								      if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;
							 | 
						||
| 
								 | 
							
								      isGlob = token.isGlob = true;
							 | 
						||
| 
								 | 
							
								      finished = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (scanToEnd === true) {
							 | 
						||
| 
								 | 
							
								        continue;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (code === CHAR_QUESTION_MARK) {
							 | 
						||
| 
								 | 
							
								      isGlob = token.isGlob = true;
							 | 
						||
| 
								 | 
							
								      finished = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (scanToEnd === true) {
							 | 
						||
| 
								 | 
							
								        continue;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (code === CHAR_LEFT_SQUARE_BRACKET) {
							 | 
						||
| 
								 | 
							
								      while (eos() !== true && (next = advance())) {
							 | 
						||
| 
								 | 
							
								        if (next === CHAR_BACKWARD_SLASH) {
							 | 
						||
| 
								 | 
							
								          backslashes = token.backslashes = true;
							 | 
						||
| 
								 | 
							
								          advance();
							 | 
						||
| 
								 | 
							
								          continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (next === CHAR_RIGHT_SQUARE_BRACKET) {
							 | 
						||
| 
								 | 
							
								          isBracket = token.isBracket = true;
							 | 
						||
| 
								 | 
							
								          isGlob = token.isGlob = true;
							 | 
						||
| 
								 | 
							
								          finished = true;
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (scanToEnd === true) {
							 | 
						||
| 
								 | 
							
								        continue;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {
							 | 
						||
| 
								 | 
							
								      negated = token.negated = true;
							 | 
						||
| 
								 | 
							
								      start++;
							 | 
						||
| 
								 | 
							
								      continue;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {
							 | 
						||
| 
								 | 
							
								      isGlob = token.isGlob = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (scanToEnd === true) {
							 | 
						||
| 
								 | 
							
								        while (eos() !== true && (code = advance())) {
							 | 
						||
| 
								 | 
							
								          if (code === CHAR_LEFT_PARENTHESES) {
							 | 
						||
| 
								 | 
							
								            backslashes = token.backslashes = true;
							 | 
						||
| 
								 | 
							
								            code = advance();
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if (code === CHAR_RIGHT_PARENTHESES) {
							 | 
						||
| 
								 | 
							
								            finished = true;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        continue;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (isGlob === true) {
							 | 
						||
| 
								 | 
							
								      finished = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (scanToEnd === true) {
							 | 
						||
| 
								 | 
							
								        continue;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (opts.noext === true) {
							 | 
						||
| 
								 | 
							
								    isExtglob = false;
							 | 
						||
| 
								 | 
							
								    isGlob = false;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  let base = str;
							 | 
						||
| 
								 | 
							
								  let prefix = '';
							 | 
						||
| 
								 | 
							
								  let glob = '';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (start > 0) {
							 | 
						||
| 
								 | 
							
								    prefix = str.slice(0, start);
							 | 
						||
| 
								 | 
							
								    str = str.slice(start);
							 | 
						||
| 
								 | 
							
								    lastIndex -= start;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (base && isGlob === true && lastIndex > 0) {
							 | 
						||
| 
								 | 
							
								    base = str.slice(0, lastIndex);
							 | 
						||
| 
								 | 
							
								    glob = str.slice(lastIndex);
							 | 
						||
| 
								 | 
							
								  } else if (isGlob === true) {
							 | 
						||
| 
								 | 
							
								    base = '';
							 | 
						||
| 
								 | 
							
								    glob = str;
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    base = str;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (base && base !== '' && base !== '/' && base !== str) {
							 | 
						||
| 
								 | 
							
								    if (isPathSeparator(base.charCodeAt(base.length - 1))) {
							 | 
						||
| 
								 | 
							
								      base = base.slice(0, -1);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (opts.unescape === true) {
							 | 
						||
| 
								 | 
							
								    if (glob) glob = utils.removeBackslashes(glob);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (base && backslashes === true) {
							 | 
						||
| 
								 | 
							
								      base = utils.removeBackslashes(base);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const state = {
							 | 
						||
| 
								 | 
							
								    prefix,
							 | 
						||
| 
								 | 
							
								    input,
							 | 
						||
| 
								 | 
							
								    start,
							 | 
						||
| 
								 | 
							
								    base,
							 | 
						||
| 
								 | 
							
								    glob,
							 | 
						||
| 
								 | 
							
								    isBrace,
							 | 
						||
| 
								 | 
							
								    isBracket,
							 | 
						||
| 
								 | 
							
								    isGlob,
							 | 
						||
| 
								 | 
							
								    isExtglob,
							 | 
						||
| 
								 | 
							
								    isGlobstar,
							 | 
						||
| 
								 | 
							
								    negated,
							 | 
						||
| 
								 | 
							
								    negatedExtglob
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (opts.tokens === true) {
							 | 
						||
| 
								 | 
							
								    state.maxDepth = 0;
							 | 
						||
| 
								 | 
							
								    if (!isPathSeparator(code)) {
							 | 
						||
| 
								 | 
							
								      tokens.push(token);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    state.tokens = tokens;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (opts.parts === true || opts.tokens === true) {
							 | 
						||
| 
								 | 
							
								    let prevIndex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (let idx = 0; idx < slashes.length; idx++) {
							 | 
						||
| 
								 | 
							
								      const n = prevIndex ? prevIndex + 1 : start;
							 | 
						||
| 
								 | 
							
								      const i = slashes[idx];
							 | 
						||
| 
								 | 
							
								      const value = input.slice(n, i);
							 | 
						||
| 
								 | 
							
								      if (opts.tokens) {
							 | 
						||
| 
								 | 
							
								        if (idx === 0 && start !== 0) {
							 | 
						||
| 
								 | 
							
								          tokens[idx].isPrefix = true;
							 | 
						||
| 
								 | 
							
								          tokens[idx].value = prefix;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          tokens[idx].value = value;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        depth(tokens[idx]);
							 | 
						||
| 
								 | 
							
								        state.maxDepth += tokens[idx].depth;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if (idx !== 0 || value !== '') {
							 | 
						||
| 
								 | 
							
								        parts.push(value);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      prevIndex = i;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (prevIndex && prevIndex + 1 < input.length) {
							 | 
						||
| 
								 | 
							
								      const value = input.slice(prevIndex + 1);
							 | 
						||
| 
								 | 
							
								      parts.push(value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (opts.tokens) {
							 | 
						||
| 
								 | 
							
								        tokens[tokens.length - 1].value = value;
							 | 
						||
| 
								 | 
							
								        depth(tokens[tokens.length - 1]);
							 | 
						||
| 
								 | 
							
								        state.maxDepth += tokens[tokens.length - 1].depth;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    state.slashes = slashes;
							 | 
						||
| 
								 | 
							
								    state.parts = parts;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return state;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = scan;
							 |