pax_global_header00006660000000000000000000000064144046637450014527gustar00rootroot0000000000000052 comment=90a77fcb4e3869bc45b61d332b852948b5982637 ret.js-0.5.0/000077500000000000000000000000001440466374500127365ustar00rootroot00000000000000ret.js-0.5.0/.eslintrc.yml000066400000000000000000000107201440466374500153620ustar00rootroot00000000000000env: es6: true node: true mocha: false extends: - 'eslint:recommended' - 'plugin:@typescript-eslint/eslint-recommended' - 'plugin:@typescript-eslint/recommended' parser: '@typescript-eslint/parser' parserOptions: ecmaVersion: 2017 plugins: - '@typescript-eslint' rules: no-await-in-loop: off no-compare-neg-zero: error no-extra-parens: - warn - all - nestedBinaryExpressions: false no-template-curly-in-string: error no-unsafe-negation: error valid-jsdoc: - warn - prefer: arg: param return: returns preferType: Boolean: boolean Number: number object: Object String: string requireReturn: false requireReturnType: true requireParamDescription: false requireReturnDescription: false requireParamType: true accessor-pairs: warn array-callback-return: error complexity: - off - max: 25 consistent-return: warn curly: - error - multi-line - consistent dot-location: - error - property dot-notation: error eqeqeq: error no-console: - error - allow: - warn no-empty-function: error no-floating-decimal: error no-implied-eval: error no-invalid-this: error no-lone-blocks: error no-multi-spaces: error no-new-func: error no-new-wrappers: error no-new: error no-octal-escape: error no-return-assign: off no-return-await: error no-self-compare: error no-sequences: error no-throw-literal: error no-unmodified-loop-condition: error no-unused-expressions: error no-useless-call: error no-useless-concat: error no-useless-escape: error no-useless-return: error no-void: error no-warning-comments: warn prefer-promise-reject-errors: error require-await: warn wrap-iife: error yoda: error no-label-var: error no-undef-init: error callback-return: error handle-callback-err: error no-mixed-requires: error no-new-require: error no-path-concat: error array-bracket-spacing: error block-spacing: error brace-style: - error - 1tbs - allowSingleLine: true capitalized-comments: - error - always - ignoreConsecutiveComments: true comma-dangle: - error - always-multiline comma-spacing: error comma-style: error computed-property-spacing: error consistent-this: - error - "$this" eol-last: error func-names: error func-name-matching: error func-style: - error - declaration - allowArrowFunctions: true indent: - error - 2 - SwitchCase: 1 key-spacing: error keyword-spacing: error max-depth: off max-len: - error - 120 - 2 max-nested-callbacks: - error - max: 4 max-statements-per-line: - error - max: 2 new-cap: off newline-per-chained-call: - error - ignoreChainWithDepth: 3 no-array-constructor: error no-inline-comments: error no-lonely-if: error no-mixed-operators: error no-multiple-empty-lines: - error - max: 2 maxEOF: 1 maxBOF: 0 no-new-object: error no-spaced-func: error no-trailing-spaces: error no-unneeded-ternary: error no-whitespace-before-property: error nonblock-statement-body-position: error object-curly-spacing: - error - always operator-assignment: error operator-linebreak: - error - after padded-blocks: - error - never quote-props: - error - as-needed quotes: - error - single - avoidEscape: true allowTemplateLiterals: true semi-spacing: error semi: error space-before-blocks: error space-before-function-paren: - error - never space-in-parens: error space-infix-ops: error space-unary-ops: error spaced-comment: error template-tag-spacing: error unicode-bom: error arrow-body-style: error arrow-parens: - error - as-needed arrow-spacing: error no-duplicate-imports: error no-useless-computed-key: error no-useless-constructor: error prefer-arrow-callback: error prefer-numeric-literals: error prefer-rest-params: error prefer-spread: error prefer-template: error rest-spread-spacing: error template-curly-spacing: error yield-star-spacing: error no-var: error prefer-const: off '@typescript-eslint/no-var-requires': off '@typescript-eslint/no-use-before-define': off '@typescript-eslint/explicit-function-return-type': off '@typescript-eslint/camelcase': off '@typescript-eslint/class-name-casing': off '@typescript-eslint/no-explicit-any': off '@typescript-eslint/no-namespace': off '@typescript-eslint/ban-ts-ignore': off '@typescript-eslint/no-unused-vars': off '@typescript-eslint/no-shadow': error ret.js-0.5.0/.github/000077500000000000000000000000001440466374500142765ustar00rootroot00000000000000ret.js-0.5.0/.github/FUNDING.yml000066400000000000000000000000371440466374500161130ustar00rootroot00000000000000github: fent tidelift: npm/ret ret.js-0.5.0/.github/workflows/000077500000000000000000000000001440466374500163335ustar00rootroot00000000000000ret.js-0.5.0/.github/workflows/lint.yml000066400000000000000000000005611440466374500200260ustar00rootroot00000000000000name: Lint on: [push, pull_request] jobs: eslint: name: Lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: 18.x - name: npm install, build, and lint run: | npm install npm run build --if-present npm run-script lint ret.js-0.5.0/.github/workflows/nodejs.yml000066400000000000000000000012401440466374500203350ustar00rootroot00000000000000name: Node CI on: [push, pull_request] jobs: test: name: Test on node ${{ matrix.node-version }} and ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: matrix: node-version: [14.x, 16.x, 18.x, 19.x] os: [ubuntu-latest] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - name: npm install, build, and test run: | npm install npm run build --if-present npm test - uses: codecov/codecov-action@v1 with: token: ${{ secrets.CODECOV_TOKEN }} ret.js-0.5.0/.github/workflows/release.yml000066400000000000000000000010471440466374500205000ustar00rootroot00000000000000name: Release on: push: branches: - master jobs: release: name: Release runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 with: fetch-depth: 0 - name: Setup Node.js uses: actions/setup-node@v2 with: node-version: 18 - name: Install dependencies run: npm ci - name: Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: npx semantic-release ret.js-0.5.0/.gitignore000066400000000000000000000000461440466374500147260ustar00rootroot00000000000000node_modules coverage .nyc_output distret.js-0.5.0/LICENSE000066400000000000000000000020511440466374500137410ustar00rootroot00000000000000MIT License Copyright (C) 2011 by fent Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ret.js-0.5.0/README.md000066400000000000000000000236061440466374500142240ustar00rootroot00000000000000# Regular Expression Tokenizer Tokenizes strings that represent a regular expressions. ![Depfu](https://img.shields.io/depfu/fent/ret.js) [![codecov](https://codecov.io/gh/fent/ret.js/branch/master/graph/badge.svg)](https://codecov.io/gh/fent/ret.js) # Usage ```js const ret = require('ret'); let tokens = ret(/foo|bar/.source); ``` `tokens` will contain the following object ```js { "type": ret.types.ROOT "options": [ [ { "type": ret.types.CHAR, "value", 102 }, { "type": ret.types.CHAR, "value", 111 }, { "type": ret.types.CHAR, "value", 111 } ], [ { "type": ret.types.CHAR, "value", 98 }, { "type": ret.types.CHAR, "value", 97 }, { "type": ret.types.CHAR, "value", 114 } ] ] } ``` # Reconstructing Regular Expressions from Tokens The `reconstruct` function accepts an *any* token and returns, as a string, the *component* of the regular expression that is associated with that token. ```ts import { reconstruct, types } from 'ret' const tokens = ret(/foo|bar/.source) const setToken = { "type": types.SET, "set": [ { "type": types.CHAR, "value": 97 }, { "type": types.CHAR, "value": 98 }, { "type": types.CHAR, "value": 99 } ], "not": true } reconstruct(tokens) // 'foo|bar' reconstruct({ "type": types.CHAR, "value": 102 }) // 'f' reconstruct(setToken) // '^abc' ``` # Token Types `ret.types` is a collection of the various token types exported by ret. ### ROOT Only used in the root of the regexp. This is needed due to the posibility of the root containing a pipe `|` character. In that case, the token will have an `options` key that will be an array of arrays of tokens. If not, it will contain a `stack` key that is an array of tokens. ```js { "type": ret.types.ROOT, "stack": [token1, token2...], } ``` ```js { "type": ret.types.ROOT, "options" [ [token1, token2...], [othertoken1, othertoken2...] ... ], } ``` ### GROUP Groups contain tokens that are inside of a parenthesis. If the group begins with `?` followed by another character, it's a special type of group. A ':' tells the group not to be remembered when `exec` is used. '=' means the previous token matches only if followed by this group, and '!' means the previous token matches only if NOT followed. Like root, it can contain an `options` key instead of `stack` if there is a pipe. ```js { "type": ret.types.GROUP, "remember" true, "followedBy": false, "notFollowedBy": false, "stack": [token1, token2...], } ``` ```js { "type": ret.types.GROUP, "remember" true, "followedBy": false, "notFollowedBy": false, "options" [ [token1, token2...], [othertoken1, othertoken2...] ... ], } ``` ### POSITION `\b`, `\B`, `^`, and `$` specify positions in the regexp. ```js { "type": ret.types.POSITION, "value": "^", } ``` ### SET Contains a key `set` specifying what tokens are allowed and a key `not` specifying if the set should be negated. A set can contain other sets, ranges, and characters. ```js { "type": ret.types.SET, "set": [token1, token2...], "not": false, } ``` ### RANGE Used in set tokens to specify a character range. `from` and `to` are character codes. ```js { "type": ret.types.RANGE, "from": 97, "to": 122, } ``` ### REPETITION ```js { "type": ret.types.REPETITION, "min": 0, "max": Infinity, "value": token, } ``` ### REFERENCE References a group token. `value` is 1-9. ```js { "type": ret.types.REFERENCE, "value": 1, } ``` ### CHAR Represents a single character token. `value` is the character code. This might seem a bit cluttering instead of concatenating characters together. But since repetition tokens only repeat the last token and not the last clause like the pipe, it's simpler to do it this way. ```js { "type": ret.types.CHAR, "value": 123, } ``` ## Errors ret.js will throw errors if given a string with an invalid regular expression. All possible errors are * Invalid group. When a group with an immediate `?` character is followed by an invalid character. It can only be followed by `!`, `=`, or `:`. Example: `/(?_abc)/` * Nothing to repeat. Thrown when a repetitional token is used as the first token in the current clause, as in right in the beginning of the regexp or group, or right after a pipe. Example: `/foo|?bar/`, `/{1,3}foo|bar/`, `/foo(+bar)/` * Unmatched ). A group was not opened, but was closed. Example: `/hello)2u/` * Unterminated group. A group was not closed. Example: `/(1(23)4/` * Unterminated character class. A custom character set was not closed. Example: `/[abc/` # Regular Expression Syntax Regular expressions follow the [JavaScript syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp). The following latest JavaScript additions are not supported yet: * `\p` and `\P`: [Unicode property escapes](https://github.com/tc39/proposal-regexp-unicode-property-escapes) * `(?)` and `\k`: [Named groups](https://github.com/tc39/proposal-regexp-named-groups) * `(?<=)` and `(? stack.map(reconstruct).join(''); const createAlternate = (token: Root | Group): string => { if ('options' in token) { return token.options.map(reduceStack).join('|'); } else if ('stack' in token) { return reduceStack(token.stack); } else { throw new Error(`options or stack must be Root or Group token`); } }; export const reconstruct = (token: Tokens): string => { switch (token.type) { case types.ROOT: return createAlternate(token); case types.CHAR: { const c = String.fromCharCode(token.value); // Note that the escaping for characters inside classes is handled // in the write-set-tokens module so '-' and ']' are not escaped here return (/[[\\{}$^.|?*+()]/.test(c) ? '\\' : '') + c; } case types.POSITION: if (token.value === '^' || token.value === '$') { return token.value; } else { return `\\${token.value}`; } case types.REFERENCE: return `\\${token.value}`; case types.SET: return writeSetTokens(token); case types.GROUP: { // Check token.remember const prefix = token.name ? `?<${token.name}>` : token.remember ? '' : token.followedBy ? '?=' : token.notFollowedBy ? '?!' : '?:'; return `(${prefix}${createAlternate(token)})`; } case types.REPETITION: { const { min, max } = token; let endWith; if (min === 0 && max === 1) { endWith = '?'; } else if (min === 1 && max === Infinity) { endWith = '+'; } else if (min === 0 && max === Infinity) { endWith = '*'; } else if (max === Infinity) { endWith = `{${min},}`; } else if (min === max) { endWith = `{${min}}`; } else { endWith = `{${min},${max}}`; } return `${reconstruct(token.value)}${endWith}`; } case types.RANGE: return `${setChar(token.from)}-${setChar(token.to)}`; default: throw new Error(`Invalid token type ${token}`); } }; ret.js-0.5.0/lib/sets-lookup.ts000066400000000000000000000016561440466374500163510ustar00rootroot00000000000000import * as Sets from './sets'; import { SetTokens, types, SetLookup } from './types'; function setToLookup(tokens: SetTokens): SetLookup { let lookup: Record = {}; let len = 0; for (const token of tokens) { if (token.type === types.CHAR) { lookup[token.value] = true; } // Note this is in an if statement because // the SetTokens type is (Char | Range | Set)[] // so a type error is thrown if it is not. // If the SetTokens type is modified the if statement // can be removed if (token.type === types.RANGE) { lookup[`${token.from}-${token.to}`] = true; } len += 1; } return { lookup: () => ({ ...lookup }), len, }; } export const INTS = setToLookup(Sets.ints().set); export const WORDS = setToLookup(Sets.words().set); export const WHITESPACE = setToLookup(Sets.whitespace().set); export const NOTANYCHAR = setToLookup(Sets.anyChar().set); ret.js-0.5.0/lib/sets.ts000066400000000000000000000034451440466374500150400ustar00rootroot00000000000000import { types, Set, Range, Char } from './types'; type SetsFunc = () => (Range | Char)[] export type SetFunc = () => Set const INTS: SetsFunc = () => [{ type: types.RANGE, from: 48, to: 57 }]; const WORDS: SetsFunc = () => [ { type: types.CHAR, value: 95 }, { type: types.RANGE, from: 97, to: 122 }, { type: types.RANGE, from: 65, to: 90 }, { type: types.RANGE, from: 48, to: 57 }, ]; const WHITESPACE: SetsFunc = () => [ { type: types.CHAR, value: 9 }, { type: types.CHAR, value: 10 }, { type: types.CHAR, value: 11 }, { type: types.CHAR, value: 12 }, { type: types.CHAR, value: 13 }, { type: types.CHAR, value: 32 }, { type: types.CHAR, value: 160 }, { type: types.CHAR, value: 5760 }, { type: types.RANGE, from: 8192, to: 8202 }, { type: types.CHAR, value: 8232 }, { type: types.CHAR, value: 8233 }, { type: types.CHAR, value: 8239 }, { type: types.CHAR, value: 8287 }, { type: types.CHAR, value: 12288 }, { type: types.CHAR, value: 65279 }, ]; const NOTANYCHAR: SetsFunc = () => [ { type: types.CHAR, value: 10 }, { type: types.CHAR, value: 13 }, { type: types.CHAR, value: 8232 }, { type: types.CHAR, value: 8233 }, ]; // Predefined class objects. export const words: SetFunc = () => ({ type: types.SET, set: WORDS(), not: false }); export const notWords: SetFunc = () => ({ type: types.SET, set: WORDS(), not: true }); export const ints: SetFunc = () => ({ type: types.SET, set: INTS(), not: false }); export const notInts: SetFunc = () => ({ type: types.SET, set: INTS(), not: true }); export const whitespace: SetFunc = () => ({ type: types.SET, set: WHITESPACE(), not: false }); export const notWhitespace: SetFunc = () => ({ type: types.SET, set: WHITESPACE(), not: true }); export const anyChar: SetFunc = () => ({ type: types.SET, set: NOTANYCHAR(), not: true }); ret.js-0.5.0/lib/tokenizer.ts000066400000000000000000000263631440466374500161000ustar00rootroot00000000000000import * as util from './util'; import { Group, types, Root, Token, Reference, Char } from './types'; import * as sets from './sets'; type ReferenceQueue = { reference: (Reference | Char), stack: Token[], index: number }[]; /** * Valid opening characters for capture group names. */ const captureGroupFirstChar = /^[a-zA-Z_$]$/i; /** * Valid characters for capture group names. */ const captureGroupChars = /^[a-zA-Z0-9_$]$/i; const digit = /\d/; /** * Tokenizes a regular expression (that is currently a string) * @param {string} regexpStr String of regular expression to be tokenized * * @returns {Root} */ export const tokenizer = (regexpStr: string): Root => { let i = 0, c: string; let start: Root = { type: types.ROOT, stack: [] }; // Keep track of last clause/group and stack. let lastGroup: Group | Root = start; let last: Token[] = start.stack; let groupStack: (Group | Root)[] = []; let referenceQueue: ReferenceQueue = []; let groupCount = 0; const repeatErr = (col: number) => { throw new SyntaxError( `Invalid regular expression: /${ regexpStr }/: Nothing to repeat at column ${col - 1}`, ); }; // Decode a few escaped characters. let str = util.strToChars(regexpStr); // Iterate through each character in string. while (i < str.length) { switch (c = str[i++]) { // Handle escaped characters, inclues a few sets. case '\\': if (i === str.length) { throw new SyntaxError( `Invalid regular expression: /${ regexpStr }/: \\ at end of pattern`, ); } switch (c = str[i++]) { case 'b': last.push({ type: types.POSITION, value: 'b' }); break; case 'B': last.push({ type: types.POSITION, value: 'B' }); break; case 'w': last.push(sets.words()); break; case 'W': last.push(sets.notWords()); break; case 'd': last.push(sets.ints()); break; case 'D': last.push(sets.notInts()); break; case 's': last.push(sets.whitespace()); break; case 'S': last.push(sets.notWhitespace()); break; default: // Check if c is integer. // In which case it's a reference. if (digit.test(c)) { let digits = c; while (i < str.length && digit.test(str[i])) { digits += str[i++]; } let value = parseInt(digits, 10); const reference: Reference = { type: types.REFERENCE, value }; last.push(reference); referenceQueue.push({ reference, stack: last, index: last.length - 1 }); // Escaped character. } else { last.push({ type: types.CHAR, value: c.charCodeAt(0) }); } } break; // Positionals. case '^': last.push({ type: types.POSITION, value: '^' }); break; case '$': last.push({ type: types.POSITION, value: '$' }); break; // Handle custom sets. case '[': { // Check if this class is 'anti' i.e. [^abc]. let not; if (str[i] === '^') { not = true; i++; } else { not = false; } // Get all the characters in class. let classTokens = util.tokenizeClass(str.slice(i), regexpStr); // Increase index by length of class. i += classTokens[1]; last.push({ type: types.SET, set: classTokens[0], not, }); break; } // Class of any character except \n. case '.': last.push(sets.anyChar()); break; // Push group onto stack. case '(': { // Create group. let group: Group = { type: types.GROUP, stack: [], remember: true, }; // If this is a special kind of group. if (str[i] === '?') { c = str[i + 1]; i += 2; // Match if followed by. if (c === '=') { group.followedBy = true; group.remember = false; // Match if not followed by. } else if (c === '!') { group.notFollowedBy = true; group.remember = false; } else if (c === '<') { let name = ''; if (captureGroupFirstChar.test(str[i])) { name += str[i]; i++; } else { throw new SyntaxError( `Invalid regular expression: /${ regexpStr }/: Invalid capture group name, character '${str[i]}'` + ` after '<' at column ${i + 1}`, ); } while (i < str.length && captureGroupChars.test(str[i])) { name += str[i]; i++; } if (!name) { throw new SyntaxError( `Invalid regular expression: /${ regexpStr }/: Invalid capture group name, character '${str[i]}'` + ` after '<' at column ${i + 1}`, ); } if (str[i] !== '>') { throw new SyntaxError( `Invalid regular expression: /${ regexpStr }/: Unclosed capture group name, expected '>', found` + ` '${str[i]}' at column ${i + 1}`, ); } group.name = name; i++; } else if (c === ':') { group.remember = false; } else { throw new SyntaxError( `Invalid regular expression: /${ regexpStr }/: Invalid group, character '${c}'` + ` after '?' at column ${i - 1}`, ); } } else { groupCount += 1; } // Insert subgroup into current group stack. last.push(group); // Remember the current group for when the group closes. groupStack.push(lastGroup); // Make this new group the current group. lastGroup = group; last = group.stack; break; } // Pop group out of stack. case ')': if (groupStack.length === 0) { throw new SyntaxError( `Invalid regular expression: /${ regexpStr }/: Unmatched ) at column ${i - 1}`, ); } lastGroup = groupStack.pop(); // Check if this group has a PIPE. // To get back the correct last stack. last = lastGroup.options ? lastGroup.options[lastGroup.options.length - 1] : lastGroup.stack; break; // Use pipe character to give more choices. case '|': { // Create array where options are if this is the first PIPE // in this clause. if (!lastGroup.options) { lastGroup.options = [lastGroup.stack]; delete lastGroup.stack; } // Create a new stack and add to options for rest of clause. let stack: Token[] = []; lastGroup.options.push(stack); last = stack; break; } // Repetition. // For every repetition, remove last element from last stack // then insert back a RANGE object. // This design is chosen because there could be more than // one repetition symbols in a regex i.e. `a?+{2,3}`. case '{': { let rs = /^(\d+)(,(\d+)?)?\}/.exec(str.slice(i)), min, max; if (rs !== null) { if (last.length === 0) { repeatErr(i); } min = parseInt(rs[1], 10); max = rs[2] ? rs[3] ? parseInt(rs[3], 10) : Infinity : min; i += rs[0].length; last.push({ type: types.REPETITION, min, max, value: last.pop(), }); } else { last.push({ type: types.CHAR, value: 123, }); } break; } case '?': if (last.length === 0) { repeatErr(i); } last.push({ type: types.REPETITION, min: 0, max: 1, value: last.pop(), }); break; case '+': if (last.length === 0) { repeatErr(i); } last.push({ type: types.REPETITION, min: 1, max: Infinity, value: last.pop(), }); break; case '*': if (last.length === 0) { repeatErr(i); } last.push({ type: types.REPETITION, min: 0, max: Infinity, value: last.pop(), }); break; // Default is a character that is not `\[](){}?+*^$`. default: last.push({ type: types.CHAR, value: c.charCodeAt(0), }); } } // Check if any groups have not been closed. if (groupStack.length !== 0) { throw new SyntaxError( `Invalid regular expression: /${ regexpStr }/: Unterminated group`, ); } updateReferences(referenceQueue, groupCount); return start; }; /** * This is a side effecting function that changes references to chars * if there are not enough capturing groups to reference * See: https://github.com/fent/ret.js/pull/39#issuecomment-1006475703 * See: https://github.com/fent/ret.js/issues/38 * @param {(Reference | Char)[]} referenceQueue * @param {number} groupCount * @returns {void} */ function updateReferences(referenceQueue: ReferenceQueue, groupCount: number) { // Note: We go through the queue in reverse order so // that index we use is correct even if we have to add // multiple tokens to one stack for (const elem of referenceQueue.reverse()) { if (groupCount < elem.reference.value) { // If there is nothing to reference then turn this into a char token elem.reference.type = types.CHAR; const valueString = elem.reference.value.toString(); elem.reference.value = parseInt(valueString, 8); // If the number is not octal then we need to create multiple tokens // https://github.com/fent/ret.js/pull/39#issuecomment-1008229226 if (!/^[0-7]+$/.test(valueString)) { let i = 0; while (valueString[i] !== '8' && valueString[i] !== '9') { i += 1; } if (i === 0) { // Handling case when escaped number starts with 8 or 9 elem.reference.value = valueString.charCodeAt(0); i += 1; } else { // If the escaped number does not start with 8 or 9, then all // 0-7 digits before the first 8/9 form the first character code // see: https://github.com/fent/ret.js/pull/39#discussion_r780747085 elem.reference.value = parseInt(valueString.slice(0, i), 8); } if (valueString.length > i) { const tail = elem.stack.splice(elem.index + 1); for (const char of valueString.slice(i)) { elem.stack.push({ type: types.CHAR, value: char.charCodeAt(0), }); } elem.stack.push(...tail); } } } } } ret.js-0.5.0/lib/types/000077500000000000000000000000001440466374500146505ustar00rootroot00000000000000ret.js-0.5.0/lib/types/index.ts000066400000000000000000000001211440466374500163210ustar00rootroot00000000000000export * from './tokens'; export * from './types'; export * from './set-lookup'; ret.js-0.5.0/lib/types/set-lookup.ts000066400000000000000000000002751440466374500173260ustar00rootroot00000000000000/** * The number of elements in a set lookup, and a * function that returns the lookup. */ export interface SetLookup { len: number; lookup: () => Record } ret.js-0.5.0/lib/types/tokens.ts000066400000000000000000000017641440466374500165330ustar00rootroot00000000000000import { types } from './types'; type Base = { type: T } & K type ValueType = Base export type Root = Base export type Group = Base export type Set = Base export type Range = Base export type Repetition = Base export type Position = ValueType export type Reference = ValueType export type Char = ValueType export type Token = Group | Position | Set | Range | Repetition | Reference | Char export type Tokens = Root | Token export type SetTokens = (Range | Char | Set)[] ret.js-0.5.0/lib/types/types.ts000066400000000000000000000001451440466374500163640ustar00rootroot00000000000000export enum types { ROOT, GROUP, POSITION, SET, RANGE, REPETITION, REFERENCE, CHAR } ret.js-0.5.0/lib/util.ts000066400000000000000000000042451440466374500150360ustar00rootroot00000000000000import { types, SetTokens } from './types'; import * as sets from './sets'; const CTRL = '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ ?'; /** * Finds character representations in str and convert all to * their respective characters. * * @param {string} str * @returns {string} */ export const strToChars = (str: string): string => { const charsRegex = /(\[\\b\])|(\\)?\\(?:u([A-F0-9]{4})|x([A-F0-9]{2})|c([@A-Z[\\\]^?])|([0tnvfr]))/g; type EscapedChar = '0' | 't' | 'n' | 'v' | 'f' | 'r' | undefined; return str.replace(charsRegex, (s, b, lbs, a16, b16, dctrl, eslsh : EscapedChar) => { if (lbs) { return s; } let code: number = b ? 8 : a16 ? parseInt(a16, 16) : b16 ? parseInt(b16, 16) : dctrl ? CTRL.indexOf(dctrl) : { 0: 0, t: 9, n: 10, v: 11, f: 12, r: 13, }[eslsh]; let c = String.fromCharCode(code); // Escape special regex characters. return /[[\]{}^$.|?*+()]/.test(c) ? `\\${c}` : c; }); }; /** * Turns class into tokens * reads str until it encounters a ] not preceeded by a \ * * @param {string} str * @param {string} regexpStr * @returns {Array., number>} */ export const tokenizeClass = (str: string, regexpStr: string): [SetTokens, number] => { let tokens: SetTokens = [], rs: string[] | null, c: string; const regexp = /\\(?:(w)|(d)|(s)|(W)|(D)|(S))|((?:(?:\\)(.)|([^\]\\]))-(((?:\\)])|(((?:\\)?([^\]])))))|(\])|(?:\\)?([^])/g; while ((rs = regexp.exec(str)) !== null) { const p = (rs[1] && sets.words()) ?? (rs[2] && sets.ints()) ?? (rs[3] && sets.whitespace()) ?? (rs[4] && sets.notWords()) ?? (rs[5] && sets.notInts()) ?? (rs[6] && sets.notWhitespace()) ?? (rs[7] && { type: types.RANGE, from: (rs[8] || rs[9]).charCodeAt(0), to: (c = rs[10]).charCodeAt(c.length - 1), }) ?? ((c = rs[16]) && { type: types.CHAR, value: c.charCodeAt(0) }); if (p) { tokens.push(p); } else { return [tokens, regexp.lastIndex]; } } throw new SyntaxError(`Invalid regular expression: /${regexpStr}/: Unterminated character class`); }; ret.js-0.5.0/lib/write-set-tokens.ts000066400000000000000000000052341440466374500173040ustar00rootroot00000000000000import { types, Set, Range, Char, SetTokens } from './types'; import * as sets from './sets-lookup'; import { SetLookup } from './types/set-lookup'; /** * Takes character code and returns character to be displayed in a set * @param {number} charCode Character code of set element * @returns {string} The string for the sets character */ export function setChar(charCode: number): string { return charCode === 94 ? '\\^' : charCode === 92 ? '\\\\' : charCode === 93 ? '\\]' : charCode === 45 ? '\\-' : String.fromCharCode(charCode); } /** * Test if a character set matches a 'set-lookup' * @param {SetTokens} set The set to be tested * @param {SetLookup} param The predefined 'set-lookup' & the number of elements in the lookup * @returns {boolean} True if the character set corresponds to the 'set-lookup' */ function isSameSet(set: SetTokens, { lookup, len }: SetLookup): boolean { // If the set and the lookup are not of the same length // then we immediately know that the lookup will be false if (len !== set.length) { return false; } const map = lookup(); for (const elem of set) { if (elem.type === types.SET) { return false; } const key = elem.type === types.CHAR ? elem.value : `${elem.from}-${elem.to}`; if (map[key]) { map[key] = false; } else { return false; } } return true; } /** * Writes the tokens for a set * @param {Set} set The set to display * @param {boolean} isNested Whether the token is nested inside another set token * @returns {string} The tokens for the set */ export function writeSetTokens(set: Set, isNested = false): string { if (isSameSet(set.set, sets.INTS)) { return set.not ? '\\D' : '\\d'; } if (isSameSet(set.set, sets.WORDS)) { return set.not ? '\\W' : '\\w'; } // Notanychar is only relevant when not nested inside another set token if (set.not && isSameSet(set.set, sets.NOTANYCHAR)) { return '.'; } if (isSameSet(set.set, sets.WHITESPACE)) { return set.not ? '\\S' : '\\s'; } let tokenString = ''; for (let i = 0; i < set.set.length; i++) { const subset = set.set[i]; tokenString += writeSetToken(subset); } const contents = `${set.not ? '^' : ''}${tokenString}`; return isNested ? contents : `[${contents}]`; } /** * Writes a token within a set * @param {Range | Char | Set} set The set token to display * @returns {string} The token as a string */ function writeSetToken(set: Range | Char | Set): string { if (set.type === types.CHAR) { return setChar(set.value); } else if (set.type === types.RANGE) { return `${setChar(set.from)}-${setChar(set.to)}`; } return writeSetTokens(set, true); } ret.js-0.5.0/package-lock.json000066400000000000000000002472111440466374500161610ustar00rootroot00000000000000{ "name": "ret", "version": "0.0.0-development", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { "version": "7.5.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "dev": true, "requires": { "@babel/highlight": "^7.0.0" } }, "@babel/generator": { "version": "7.6.4", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", "dev": true, "requires": { "@babel/types": "^7.6.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" } }, "@babel/helper-function-name": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.0.0", "@babel/template": "^7.1.0", "@babel/types": "^7.0.0" } }, "@babel/helper-get-function-arity": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@babel/helper-split-export-declaration": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", "dev": true, "requires": { "@babel/types": "^7.4.4" } }, "@babel/highlight": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" } }, "@babel/parser": { "version": "7.6.4", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", "dev": true }, "@babel/template": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.6.0", "@babel/types": "^7.6.0" } }, "@babel/traverse": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", "@babel/generator": "^7.6.3", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", "@babel/parser": "^7.6.3", "@babel/types": "^7.6.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } }, "@eslint/eslintrc": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.1.1", "espree": "^7.3.0", "globals": "^12.1.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^3.13.1", "lodash": "^4.17.19", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, "dependencies": { "globals": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", "dev": true, "requires": { "type-fest": "^0.8.1" } } } }, "@nodelib/fs.scandir": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", "dev": true, "requires": { "@nodelib/fs.stat": "2.0.4", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", "dev": true }, "@nodelib/fs.walk": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.4", "fastq": "^1.6.0" } }, "@types/json-schema": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", "dev": true }, "@types/node": { "version": "14.11.8", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.8.tgz", "integrity": "sha512-KPcKqKm5UKDkaYPTuXSx8wEP7vE9GnuaXIZKijwRYcePpZFDVuy2a57LarFKiORbHOuTOOwYzxVxcUzsh2P2Pw==", "dev": true }, "@typescript-eslint/eslint-plugin": { "version": "4.11.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.11.1.tgz", "integrity": "sha512-fABclAX2QIEDmTMk6Yd7Muv1CzFLwWM4505nETzRHpP3br6jfahD9UUJkhnJ/g2m7lwfz8IlswcwGGPGiq9exw==", "dev": true, "requires": { "@typescript-eslint/experimental-utils": "4.11.1", "@typescript-eslint/scope-manager": "4.11.1", "debug": "^4.1.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.0.0", "semver": "^7.3.2", "tsutils": "^3.17.1" }, "dependencies": { "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { "yallist": "^4.0.0" } }, "semver": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, "@typescript-eslint/experimental-utils": { "version": "4.11.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.11.1.tgz", "integrity": "sha512-mAlWowT4A6h0TC9F+J5pdbEhjNiEMO+kqPKQ4sc3fVieKL71dEqfkKgtcFVSX3cjSBwYwhImaQ/mXQF0oaI38g==", "dev": true, "requires": { "@types/json-schema": "^7.0.3", "@typescript-eslint/scope-manager": "4.11.1", "@typescript-eslint/types": "4.11.1", "@typescript-eslint/typescript-estree": "4.11.1", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" } }, "@typescript-eslint/parser": { "version": "4.11.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.11.1.tgz", "integrity": "sha512-BJ3jwPQu1jeynJ5BrjLuGfK/UJu6uwHxJ/di7sanqmUmxzmyIcd3vz58PMR7wpi8k3iWq2Q11KMYgZbUpRoIPw==", "dev": true, "requires": { "@typescript-eslint/scope-manager": "4.11.1", "@typescript-eslint/types": "4.11.1", "@typescript-eslint/typescript-estree": "4.11.1", "debug": "^4.1.1" } }, "@typescript-eslint/scope-manager": { "version": "4.11.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.11.1.tgz", "integrity": "sha512-Al2P394dx+kXCl61fhrrZ1FTI7qsRDIUiVSuN6rTwss6lUn8uVO2+nnF4AvO0ug8vMsy3ShkbxLu/uWZdTtJMQ==", "dev": true, "requires": { "@typescript-eslint/types": "4.11.1", "@typescript-eslint/visitor-keys": "4.11.1" } }, "@typescript-eslint/types": { "version": "4.11.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.11.1.tgz", "integrity": "sha512-5kvd38wZpqGY4yP/6W3qhYX6Hz0NwUbijVsX2rxczpY6OXaMxh0+5E5uLJKVFwaBM7PJe1wnMym85NfKYIh6CA==", "dev": true }, "@typescript-eslint/typescript-estree": { "version": "4.11.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.11.1.tgz", "integrity": "sha512-tC7MKZIMRTYxQhrVAFoJq/DlRwv1bnqA4/S2r3+HuHibqvbrPcyf858lNzU7bFmy4mLeIHFYr34ar/1KumwyRw==", "dev": true, "requires": { "@typescript-eslint/types": "4.11.1", "@typescript-eslint/visitor-keys": "4.11.1", "debug": "^4.1.1", "globby": "^11.0.1", "is-glob": "^4.0.1", "lodash": "^4.17.15", "semver": "^7.3.2", "tsutils": "^3.17.1" }, "dependencies": { "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { "yallist": "^4.0.0" } }, "semver": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, "@typescript-eslint/visitor-keys": { "version": "4.11.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.11.1.tgz", "integrity": "sha512-IrlBhD9bm4bdYcS8xpWarazkKXlE7iYb1HzRuyBP114mIaj5DJPo11Us1HgH60dTt41TCZXMaTCAW+OILIYPOg==", "dev": true, "requires": { "@typescript-eslint/types": "4.11.1", "eslint-visitor-keys": "^2.0.0" } }, "acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-jsx": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", "dev": true }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" } }, "append-transform": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", "dev": true, "requires": { "default-require-extensions": "^2.0.0" } }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { "sprintf-js": "~1.0.2" } }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "brace-expansion": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { "fill-range": "^7.0.1" } }, "caching-transform": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", "dev": true, "requires": { "hasha": "^3.0.0", "make-dir": "^2.0.0", "package-hash": "^3.0.0", "write-file-atomic": "^2.4.2" } }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", "wrap-ansi": "^5.1.0" } }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { "color-name": "1.1.3" } }, "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "convert-source-map": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", "dev": true, "requires": { "safe-buffer": "~5.1.1" } }, "cp-file": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", "dev": true, "requires": { "graceful-fs": "^4.1.2", "make-dir": "^2.0.0", "nested-error-stacks": "^2.0.0", "pify": "^4.0.1", "safe-buffer": "^5.0.1" } }, "cross-spawn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "dev": true, "requires": { "lru-cache": "^4.0.1", "which": "^1.2.9" } }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" } }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, "default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "dev": true, "requires": { "strip-bom": "^3.0.0" } }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "requires": { "path-type": "^4.0.0" }, "dependencies": { "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true } } }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" } }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, "enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, "requires": { "ansi-colors": "^4.1.1" } }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { "is-arrayish": "^0.2.1" } }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, "eslint": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.16.0.tgz", "integrity": "sha512-iVWPS785RuDA4dWuhhgXTNrGxHHK3a8HLSMBgbbU59ruJDubUraXN8N5rn7kb8tG6sjg74eE0RA3YWT51eusEw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@eslint/eslintrc": "^0.2.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", "enquirer": "^2.3.5", "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", "espree": "^7.3.1", "esquery": "^1.2.0", "esutils": "^2.0.2", "file-entry-cache": "^6.0.0", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", "globals": "^12.1.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash": "^4.17.19", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "progress": "^2.0.0", "regexpp": "^3.1.0", "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", "table": "^6.0.4", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" } }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" } }, "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "globals": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", "dev": true, "requires": { "type-fest": "^0.8.1" } }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { "yallist": "^4.0.0" } }, "semver": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" } }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "eslint-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" }, "dependencies": { "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } }, "eslint-visitor-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", "dev": true }, "espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", "eslint-visitor-keys": "^1.3.0" }, "dependencies": { "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "esquery": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", "dev": true, "requires": { "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true } } }, "esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { "estraverse": "^5.2.0" }, "dependencies": { "estraverse": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true } } }, "estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", "dev": true }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-glob": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.0", "merge2": "^1.3.0", "micromatch": "^4.0.2", "picomatch": "^2.2.1" } }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, "fastq": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz", "integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==", "dev": true, "requires": { "reusify": "^1.0.4" } }, "file-entry-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", "dev": true, "requires": { "flat-cache": "^3.0.4" } }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, "find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, "requires": { "commondir": "^1.0.1", "make-dir": "^2.0.0", "pkg-dir": "^3.0.0" } }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { "locate-path": "^3.0.0" } }, "flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { "flatted": "^3.1.0", "rimraf": "^3.0.2" }, "dependencies": { "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" } } } }, "flatted": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", "dev": true }, "foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "dev": true, "requires": { "cross-spawn": "^4", "signal-exit": "^3.0.0" } }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "glob-parent": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, "globby": { "version": "11.0.1", "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.1.1", "ignore": "^5.1.4", "merge2": "^1.3.0", "slash": "^3.0.0" }, "dependencies": { "ignore": { "version": "5.1.8", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true } } }, "graceful-fs": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", "dev": true }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", "dev": true, "requires": { "is-stream": "^1.0.1" } }, "hosted-git-info": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", "dev": true }, "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" } }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { "is-extglob": "^2.1.1" } }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "istanbul-lib-coverage": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "dev": true }, "istanbul-lib-hook": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", "dev": true, "requires": { "append-transform": "^1.0.0" } }, "istanbul-lib-instrument": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", "dev": true, "requires": { "@babel/generator": "^7.4.0", "@babel/parser": "^7.4.3", "@babel/template": "^7.4.0", "@babel/traverse": "^7.4.3", "@babel/types": "^7.4.0", "istanbul-lib-coverage": "^2.0.5", "semver": "^6.0.0" }, "dependencies": { "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "istanbul-lib-report": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", "dev": true, "requires": { "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "supports-color": "^6.1.0" }, "dependencies": { "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" } } } }, "istanbul-lib-source-maps": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "dev": true, "requires": { "debug": "^4.1.1", "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "rimraf": "^2.6.3", "source-map": "^0.6.1" }, "dependencies": { "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "istanbul-reports": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", "dev": true, "requires": { "html-escaper": "^2.0.0" } }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" } }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" }, "dependencies": { "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true } } }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, "requires": { "pify": "^4.0.1", "semver": "^5.6.0" } }, "merge-source-map": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", "dev": true, "requires": { "source-map": "^0.6.1" }, "dependencies": { "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" } }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { "minimist": "^1.2.5" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, "nested-error-stacks": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", "dev": true }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "nyc": { "version": "14.1.1", "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", "dev": true, "requires": { "archy": "^1.0.0", "caching-transform": "^3.0.2", "convert-source-map": "^1.6.0", "cp-file": "^6.2.0", "find-cache-dir": "^2.1.0", "find-up": "^3.0.0", "foreground-child": "^1.5.6", "glob": "^7.1.3", "istanbul-lib-coverage": "^2.0.5", "istanbul-lib-hook": "^2.0.7", "istanbul-lib-instrument": "^3.3.0", "istanbul-lib-report": "^2.0.8", "istanbul-lib-source-maps": "^3.0.6", "istanbul-reports": "^2.2.4", "js-yaml": "^3.13.1", "make-dir": "^2.1.0", "merge-source-map": "^1.1.0", "resolve-from": "^4.0.0", "rimraf": "^2.6.3", "signal-exit": "^3.0.2", "spawn-wrap": "^1.4.2", "test-exclude": "^5.2.3", "uuid": "^3.3.2", "yargs": "^13.2.2", "yargs-parser": "^13.0.0" } }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { "wrappy": "1" } }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.3" } }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "p-limit": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "dev": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { "p-limit": "^2.0.0" } }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "package-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", "dev": true, "requires": { "graceful-fs": "^4.1.15", "hasha": "^3.0.0", "lodash.flattendeep": "^4.4.0", "release-zalgo": "^1.0.0" } }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "requires": { "callsites": "^3.0.0" } }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" } }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { "pify": "^3.0.0" }, "dependencies": { "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true } } }, "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", "dev": true }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { "find-up": "^3.0.0" } }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", "path-type": "^3.0.0" } }, "read-pkg-up": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", "dev": true, "requires": { "find-up": "^3.0.0", "read-pkg": "^3.0.0" } }, "regexpp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", "dev": true, "requires": { "es6-error": "^4.0.1" } }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "resolve": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", "dev": true, "requires": { "path-parse": "^1.0.6" } }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" } }, "run-parallel": { "version": "1.1.10", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", "dev": true }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { "shebang-regex": "^3.0.0" } }, "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" }, "dependencies": { "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" } }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" } }, "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true } } }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "spawn-wrap": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", "dev": true, "requires": { "foreground-child": "^1.5.6", "mkdirp": "^0.5.0", "os-homedir": "^1.0.1", "rimraf": "^2.6.2", "signal-exit": "^3.0.2", "which": "^1.3.0" } }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", "dev": true }, "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "dev": true }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" } }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { "ansi-regex": "^4.1.0" } }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" } }, "table": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/table/-/table-6.0.4.tgz", "integrity": "sha512-sBT4xRLdALd+NFBvwOz8bw4b15htyythha+q+DVZqy2RS08PPC8O2sZFgJYEY7bJvbCFKccs+WIZ/cd+xxTWCw==", "dev": true, "requires": { "ajv": "^6.12.4", "lodash": "^4.17.20", "slice-ansi": "^4.0.0", "string-width": "^4.2.0" }, "dependencies": { "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.0" } }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" } } } }, "test-exclude": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", "dev": true, "requires": { "glob": "^7.1.3", "minimatch": "^3.0.4", "read-pkg-up": "^4.0.0", "require-main-filename": "^2.0.0" } }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { "is-number": "^7.0.0" } }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "tsutils": { "version": "3.17.1", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", "dev": true, "requires": { "tslib": "^1.8.1" } }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { "prelude-ls": "^1.2.1" } }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true }, "typescript": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.3.tgz", "integrity": "sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg==", "dev": true }, "uri-js": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", "dev": true, "requires": { "punycode": "^2.1.0" } }, "uuid": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", "dev": true }, "v8-compile-cache": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "dev": true }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "vows": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/vows/-/vows-0.8.3.tgz", "integrity": "sha512-PVIxa/ovXhrw5gA3mz6M+ZF3PHlqX4tutR2p/y9NWPAaFVKcWBE8b2ktfr0opQM/qFmcOVWKjSCJVjnYOvjXhw==", "dev": true, "requires": { "diff": "^4.0.1", "eyes": "~0.1.6", "glob": "^7.1.2" } }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { "isexe": "^2.0.0" } }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", "strip-ansi": "^5.0.0" } }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, "requires": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", "signal-exit": "^3.0.2" } }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, "yargs": { "version": "13.3.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^13.1.1" } }, "yargs-parser": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } } } } ret.js-0.5.0/package.json000066400000000000000000000020001440466374500152140ustar00rootroot00000000000000{ "name": "ret", "description": "Tokenizes a string that represents a regular expression.", "keywords": [ "regex", "regexp", "regular expression", "parser", "tokenizer" ], "version": "0.0.0-development", "repository": { "type": "git", "url": "git://github.com/fent/ret.js.git" }, "author": "fent (https://github.com/fent)", "main": "./dist/index.js", "files": [ "dist" ], "scripts": { "test": "nyc --extension .ts --reporter=lcov --reporter=text-summary vows -- --spec test/*-test.js", "build": "tsc", "prepare": "tsc", "lint": "eslint ./lib ./test", "lint:fix": "eslint --fix ./lib ./test" }, "devDependencies": { "@types/node": "^14.11.8", "@typescript-eslint/eslint-plugin": "^4.11.1", "@typescript-eslint/parser": "^4.11.1", "eslint": "^7.16.0", "nyc": "^14.1.1", "typescript": "^4.0.3", "vows": "^0.8.3" }, "engines": { "node": ">=10" }, "license": "MIT", "dependencies": {} } ret.js-0.5.0/test/000077500000000000000000000000001440466374500137155ustar00rootroot00000000000000ret.js-0.5.0/test/error-test.js000066400000000000000000000053271440466374500163700ustar00rootroot00000000000000const vows = require('vows'); const assert = require('assert'); const ret = require('../dist'); /** * @param {string} regexp * @returns {!Error} */ const topicMacro = regexp => { try { ret(regexp); return null; } catch (err) { return err; } }; /** * @param {string} regexp * @param {string} message * @returns {Function} */ const errMacro = (regexp, message) => { message = `Invalid regular expression: /${regexp}/: ${message}`; return err => { assert.isObject(err); assert.include(err, 'message'); assert.equal(err.message, message); }; }; /** * @param {string} regexp * @param {string} name * @param {string} message * @returns {Object} */ const macro = (regexp, name, message) => { let obj = { topic: topicMacro(regexp) }; obj[name] = errMacro(regexp, message); return obj; }; vows.describe('Regexp Tokenizer Errors') .addBatch({ 'Bad repetiion at beginning of': { regexp: macro('?what', 'Nothing to repeat', 'Nothing to repeat at column 0'), group: macro('foo(*\\w)', 'Nothing to repeat', 'Nothing to repeat at column 4'), pipe: macro('foo|+bar', 'Nothing to repeat', 'Nothing to repeat at column 4'), 'with custom repetitional': macro('ok({3}no)', 'Nothing to repeat', 'Nothing to repeat at column 3'), }, 'Bad grouping': { unmatched: macro('hey(yoo))', 'Unmatched )', 'Unmatched ) at column 8'), unclosed: macro('(', 'Unterminated group', 'Unterminated group'), }, 'Wrong group type': macro('abcde(?>hellow)', 'Invalid character', 'Invalid group, character \'>\' after \'?\' at column 7'), 'Empty group name': macro('(?<>\\d{4})', 'Invalid capture group name', 'Invalid capture group name, character \'>\' after \'<\' at column 4'), 'Bad group name': macro('(?<1year>\\d{4})', 'Invalid capture group name', 'Invalid capture group name, character \'1\' after \'<\' at column 4'), 'Unclosed group name': macro('(?\', found \'\\\' at column 7'), 'Unclosed group terminal': macro('(?\', found \'undefined\' at column 7'), 'Bad custom character set': macro('[abc', 'Unterminated character class', 'Unterminated character class'), 'End of pattern': { Backslash: macro('abc\\', 'Invalid Regular Expression', '\\ at end of pattern'), Groups: macro('(?', 'Invalid Regular Expression', "Invalid group, character 'undefined' after '?' at column 2"), Groups2: macro('(?=', 'Invalid Regular Expression', 'Unterminated group'), }, }) .export(module); ret.js-0.5.0/test/main-test.js000066400000000000000000000721311440466374500161600ustar00rootroot00000000000000const vows = require('vows'); const assert = require('assert'); const sets = require('../dist/sets'); const ret = require('../dist'); const types = ret.types; const char = c => ({ type: types.CHAR, value: c.charCodeAt(0) }); const charStr = str => str.split('').map(char); vows.describe('Regexp Tokenizer') .addBatch({ 'No special characters': { topic: ret('walnuts'), 'List of char tokens': t => { assert.deepEqual(t, { type: types.ROOT, stack: charStr('walnuts'), }); }, }, Positionals: { '^ and $ in': { 'one liner': { topic: ret('^yes$'), 'Positionals at beginning and end': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ { type: types.POSITION, value: '^' }, char('y'), char('e'), char('s'), { type: types.POSITION, value: '$' }, ], }); }, }, }, '\\b and \\B': { topic: ret('\\bbeginning\\B'), 'Word boundary at beginning': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ { type: types.POSITION, value: 'b' }, char('b'), char('e'), char('g'), char('i'), char('n'), char('n'), char('i'), char('n'), char('g'), { type: types.POSITION, value: 'B' }, ], }); }, }, }, 'Predefined sets': { topic: ret('\\w\\W\\d\\D\\s\\S.'), 'Words set': t => { assert.isArray(t.stack); assert.deepEqual(t.stack[0], sets.words()); }, 'Non-Words set': t => { assert.isArray(t.stack); assert.deepEqual(t.stack[1], sets.notWords()); }, 'Integer set': t => { assert.isArray(t.stack); assert.deepEqual(t.stack[2], sets.ints()); }, 'Non-Integer set': t => { assert.isArray(t.stack); assert.deepEqual(t.stack[3], sets.notInts()); }, 'Whitespace set': t => { assert.isArray(t.stack); assert.deepEqual(t.stack[4], sets.whitespace()); }, 'Non-Whitespace set': t => { assert.isArray(t.stack); assert.deepEqual(t.stack[5], sets.notWhitespace()); }, 'Any character set': t => { assert.isArray(t.stack); assert.deepEqual(t.stack[6], sets.anyChar()); }, }, 'Custom sets': { topic: ret('[$!a-z123] thing [^0-9]'), 'Class contains all characters and range': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ { type: types.SET, set: [ char('$'), char('!'), { type: types.RANGE, from: 'a'.charCodeAt(0), to: 'z'.charCodeAt(0), }, char('1'), char('2'), char('3'), ], not: false, }, char(' '), char('t'), char('h'), char('i'), char('n'), char('g'), char(' '), { type: types.SET, set: [{ type: types.RANGE, from: '0'.charCodeAt(0), to: '9'.charCodeAt(0), }], not: true, }, ], }); }, 'Whitespace characters': { topic: ret('[\t\r\n\u2028\u2029 ]'), 'Class contains some whitespace characters (not included in .)': t => { const LINE_SEPARATOR = '\u2028'; const PAGE_SEPARATOR = '\u2029'; assert.deepEqual(t, { type: types.ROOT, stack: [ { type: types.SET, set: [ char('\t'), char('\r'), char('\n'), char(LINE_SEPARATOR), char(PAGE_SEPARATOR), char(' '), ], not: false, }, ], }); }, }, }, 'Two sets in a row with dash in between': { topic: ret('[01]-[ab]'), 'Contains both classes and no range': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ { type: types.SET, set: charStr('01'), not: false, }, char('-'), { type: types.SET, set: charStr('ab'), not: false, }, ], }); }, }, '| (Pipe)': { topic: ret('foo|bar|za'), 'Returns root object with options': t => { assert.deepEqual(t, { type: types.ROOT, options: [ charStr('foo'), charStr('bar'), charStr('za'), ], }); }, }, Group: { 'with no special characters': { topic: ret('hey (there)'), 'Token list contains group token': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ char('h'), char('e'), char('y'), char(' '), { type: types.GROUP, remember: true, stack: charStr('there'), }, ], }); }, }, 'that is not remembered': { topic: ret('(?:loner)'), 'Remember is false on the group object': t => { assert.deepEqual(t, { type: types.ROOT, stack: [{ type: types.GROUP, remember: false, stack: charStr('loner'), }], }); }, }, 'matched previous clause if not followed by this': { topic: ret('what(?!ever)'), 'Returns a group': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ char('w'), char('h'), char('a'), char('t'), { type: types.GROUP, remember: false, notFollowedBy: true, stack: charStr('ever'), }, ], }); }, }, 'matched next clause': { topic: ret('hello(?= there)'), 'Returns a group': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ char('h'), char('e'), char('l'), char('l'), char('o'), { type: types.GROUP, remember: false, followedBy: true, stack: charStr(' there'), }, ], }); }, }, 'with subgroup': { topic: ret('a(b(c|(?:d))fg) @_@'), 'Groups within groups': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ char('a'), { type: types.GROUP, remember: true, stack: [ char('b'), { type: types.GROUP, remember: true, options: [ [char('c')], [{ type: types.GROUP, remember: false, stack: charStr('d') }], ] }, char('f'), char('g'), ] }, char(' '), char('@'), char('_'), char('@'), ], }); }, }, 'with name': { topic: ret('(?\\d{4})-(?\\d{2})-(?\\d{2})'), 'parse as groups': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ { type: types.GROUP, stack: [{ type: types.REPETITION, min: 4, max: 4, value: sets.ints() }], remember: true, name: 'year', }, char('-'), { type: types.GROUP, stack: [{ type: types.REPETITION, min: 2, max: 2, value: sets.ints() }], remember: true, name: 'month', }, char('-'), { type: types.GROUP, stack: [{ type: types.REPETITION, min: 2, max: 2, value: sets.ints() }], remember: true, name: 'day', }, ], }); }, }, }, 'Custom repetition with': { 'exact amount': { topic: ret('(?:pika){2}'), 'Min and max are the same': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ { type: types.REPETITION, min: 2, max: 2, value: { type: types.GROUP, remember: false, stack: charStr('pika'), }, }, ], }); }, }, 'minimum amount only': { topic: ret('NO{6,}'), 'To infinity': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ char('N'), { type: types.REPETITION, min: 6, max: Infinity, value: char('O') }, ], }); }, }, 'both minimum and maximum': { topic: ret('pika\\.\\.\\. chu{3,20}!{1,2}'), 'Min and max differ and min < max': t => { assert.deepEqual(t, { type: types.ROOT, stack: charStr('pika... ch').concat([ { type: types.REPETITION, min: 3, max: 20, value: char('u') }, { type: types.REPETITION, min: 1, max: 2, value: char('!') }, ]), }); }, }, 'Brackets around a non-repetitional': { topic: ret('a{mustache}'), 'Returns a non-repetitional': t => { assert.deepEqual(t, { type: types.ROOT, stack: charStr('a{mustache}'), }); }, }, }, 'Predefined repetitional': { '? (Optional)': { topic: ret('hey(?: you)?'), 'Get back correct min and max': t => { assert.deepEqual(t, { type: types.ROOT, stack: charStr('hey').concat([ { type: types.REPETITION, min: 0, max: 1, value: { type: types.GROUP, remember: false, stack: charStr(' you'), }, }, ]), }); }, }, '+ (At least one)': { topic: ret('(no )+'), 'Correct min and max': t => { assert.deepEqual(t, { type: types.ROOT, stack: [{ type: types.REPETITION, min: 1, max: Infinity, value: { type: types.GROUP, remember: true, stack: charStr('no '), }, }], }); }, }, '* (Any amount)': { topic: ret('XF*D'), '0 to Infinity': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ char('X'), { type: types.REPETITION, min: 0, max: Infinity, value: char('F') }, char('D'), ], }); }, }, }, Reference: { topic: ret('<(\\w+)>\\w*<\\1>'), 'Reference a group': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ char('<'), { type: types.GROUP, remember: true, stack: [{ type: types.REPETITION, min: 1, max: Infinity, value: sets.words() }] }, char('>'), { type: types.REPETITION, min: 0, max: Infinity, value: sets.words() }, char('<'), { type: types.REFERENCE, value: 1 }, char('>'), ], }); }, }, 'NOT Reference with more than one digit': { topic: ret('<(\\w+)>\\w*<\\10>'), 'Reference with more than one digit': t => { assert.deepEqual(t, { type: types.ROOT, stack: [ char('<'), { type: types.GROUP, remember: true, stack: [{ type: types.REPETITION, min: 1, max: Infinity, value: sets.words(), }], }, char('>'), { type: types.REPETITION, min: 0, max: Infinity, value: sets.words(), }, char('<'), { type: types.CHAR, value: 8 }, char('>'), ], }); }, }, 'Reference with more than one digit': { topic: ret('(a)(b)(c)(d)(e)(f)(g)(h)(i)(j) - \\10'), 'Reference with more than one digit': t => { assert.deepEqual(t, { type: 0, stack: [ { type: types.GROUP, stack: [char('a')], remember: true }, { type: types.GROUP, stack: [char('b')], remember: true }, { type: types.GROUP, stack: [char('c')], remember: true }, { type: types.GROUP, stack: [char('d')], remember: true }, { type: types.GROUP, stack: [char('e')], remember: true }, { type: types.GROUP, stack: [char('f')], remember: true }, { type: types.GROUP, stack: [char('g')], remember: true }, { type: types.GROUP, stack: [char('h')], remember: true }, { type: types.GROUP, stack: [char('i')], remember: true }, { type: types.GROUP, stack: [char('j')], remember: true }, char(' '), char('-'), char(' '), { type: types.REFERENCE, value: 10 }, ], }); }, }, 'NOT Reference with more than one digit (a)(b)(c)(d)(e)(f)(g)(h)(i) - \\10': { topic: ret('(a)(b)(c)(d)(e)(f)(g)(h)(i) - \\10'), 'Reference with more than one digit': t => { assert.deepEqual(t, { type: 0, stack: [ { type: types.GROUP, stack: [char('a')], remember: true }, { type: types.GROUP, stack: [char('b')], remember: true }, { type: types.GROUP, stack: [char('c')], remember: true }, { type: types.GROUP, stack: [char('d')], remember: true }, { type: types.GROUP, stack: [char('e')], remember: true }, { type: types.GROUP, stack: [char('f')], remember: true }, { type: types.GROUP, stack: [char('g')], remember: true }, { type: types.GROUP, stack: [char('h')], remember: true }, { type: types.GROUP, stack: [char('i')], remember: true }, char(' '), char('-'), char(' '), { type: types.CHAR, value: 8 }, ], }); }, }, 'Reference with more than one digit and referencing group after digit': { topic: ret('(a)(b)(c)(d)(e)(f)(g)(h)(i) - \\10 (j)'), 'Reference with more than one digit': t => { assert.deepEqual(t, { type: 0, stack: [ { type: types.GROUP, stack: [char('a')], remember: true }, { type: types.GROUP, stack: [char('b')], remember: true }, { type: types.GROUP, stack: [char('c')], remember: true }, { type: types.GROUP, stack: [char('d')], remember: true }, { type: types.GROUP, stack: [char('e')], remember: true }, { type: types.GROUP, stack: [char('f')], remember: true }, { type: types.GROUP, stack: [char('g')], remember: true }, { type: types.GROUP, stack: [char('h')], remember: true }, { type: types.GROUP, stack: [char('i')], remember: true }, char(' '), char('-'), char(' '), { type: types.REFERENCE, value: 10 }, char(' '), { type: types.GROUP, stack: [char('j')], remember: true }, ], }); }, }, // See https://github.com/fent/ret.js/pull/39#issuecomment-1007074351 'Nested capturing groups - \\1': { topic: ret('(a) ((b) (c)) - \\1'), 'Reference with more than one digit': t => { assert.deepEqual(t, { type: 0, stack: [ { type: types.GROUP, stack: [char('a')], remember: true }, char(' '), { type: types.GROUP, stack: [ { type: types.GROUP, stack: [char('b')], remember: true }, char(' '), { type: types.GROUP, stack: [char('c')], remember: true }, ], remember: true }, char(' '), char('-'), char(' '), { type: types.REFERENCE, value: 1 }, ], }); }, }, 'Nested capturing groups - \\2': { topic: ret('(a) ((b) (c)) - \\2'), 'Reference with more than one digit': t => { assert.deepEqual(t, { type: 0, stack: [ { type: types.GROUP, stack: [char('a')], remember: true }, char(' '), { type: types.GROUP, stack: [ { type: types.GROUP, stack: [char('b')], remember: true }, char(' '), { type: types.GROUP, stack: [char('c')], remember: true }, ], remember: true }, char(' '), char('-'), char(' '), { type: types.REFERENCE, value: 2 }, ], }); }, }, 'Nested capturing groups - \\3': { topic: ret('(a) ((b) (c)) - \\3'), 'Reference with more than one digit': t => { assert.deepEqual(t, { type: 0, stack: [ { type: types.GROUP, stack: [char('a')], remember: true }, char(' '), { type: types.GROUP, stack: [ { type: types.GROUP, stack: [char('b')], remember: true }, char(' '), { type: types.GROUP, stack: [char('c')], remember: true }, ], remember: true }, char(' '), char('-'), char(' '), { type: types.REFERENCE, value: 3 }, ], }); }, }, 'Nested capturing groups - \\4': { topic: ret('(a) ((b) (c)) - \\4'), 'Reference with more than one digit': t => { assert.deepEqual(t, { type: 0, stack: [ { type: types.GROUP, stack: [char('a')], remember: true }, char(' '), { type: types.GROUP, stack: [ { type: types.GROUP, stack: [char('b')], remember: true }, char(' '), { type: types.GROUP, stack: [char('c')], remember: true }, ], remember: true }, char(' '), char('-'), char(' '), { type: types.REFERENCE, value: 4 }, ], }); }, }, 'Nested capturing groups - \\5 (character)': { topic: ret('(a) ((b) (c)) - \\5'), 'Reference with more than one digit': t => { assert.deepEqual(t, { type: 0, stack: [ { type: types.GROUP, stack: [char('a')], remember: true }, char(' '), { type: types.GROUP, stack: [ { type: types.GROUP, stack: [char('b')], remember: true }, char(' '), { type: types.GROUP, stack: [char('c')], remember: true }, ], remember: true }, char(' '), char('-'), char(' '), { type: types.CHAR, value: 5 }, ], }); }, }, // https://github.com/fent/ret.js/pull/39#issuecomment-1008229226 'escaped octal numbers': { '\\10': { topic: ret('\\10'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [ { type: types.CHAR, value: 8 }, ], }); }, }, '\\18': { topic: ret('\\18'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [ { type: types.CHAR, value: 1 }, char('8'), ], }); }, }, '\\108': { topic: ret('\\108'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [ { type: types.CHAR, value: 8 }, char('8'), ], }); }, }, '\\107': { topic: ret('\\107'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [ { type: types.CHAR, value: 71 }, ], }); }, }, '\\2': { topic: ret('\\2'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [ { type: types.CHAR, value: 2 }, ], }); }, }, '\\9': { topic: ret('\\9'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [ char('9'), ], }); }, }, '\\90': { topic: ret('\\90'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [ char('9'), char('0'), ], }); }, }, }, 'Range (in set) test cases': { 'Testing complex range cases': { 'token.from is a hyphen and the range is preceded by a single character [a\\--\\-]': { topic: ret('[a\\--\\-]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.CHAR, value: 97 }, { type: types.RANGE, from: 45, to: 45 }, ], }], }); }, }, 'token.from is a hyphen and the range is preceded by a single character [a\\--\\/]': { topic: ret('[a\\--\\/]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.CHAR, value: 97 }, { type: types.RANGE, from: 45, to: 47 }, ], }], }); }, }, 'token.from is a hyphen and the range is preceded by a single character [c\\--a]': { topic: ret('[c\\--a]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.CHAR, value: 99 }, { type: types.RANGE, from: 45, to: 97 }, ], }], }); }, }, 'token.from is a hyphen and the range is preceded by a single character [\\-\\--\\-]': { topic: ret('[\\-\\--\\-]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.CHAR, value: 45 }, { type: types.RANGE, from: 45, to: 45 }, ], }], }); }, }, 'token.from is a hyphen and the range is preceded by a predefined set [\\w\\--\\-]': { topic: ret('[\\w\\--\\-]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.SET, not: false, set: [ { type: types.CHAR, value: 95 }, { type: types.RANGE, from: 97, to: 122 }, { type: types.RANGE, from: 65, to: 90 }, { type: types.RANGE, from: 48, to: 57 }, ], }, { type: types.RANGE, from: 45, to: 45 }, ], }], }); }, }, 'token.from is a caret and the range is the first item of the set [9-\\^]': { topic: ret('[9-\\^]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.RANGE, from: 57, to: 94 }, ], }], }); }, }, 'token.to is a closing square bracket [2-\\]]': { topic: ret('[2-\\]]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.RANGE, from: 50, to: 93 }, ], }], }); }, }, 'token.to is a closing square bracket [\\]-\\^]': { topic: ret('[\\]-\\^]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.RANGE, from: 93, to: 94 }, ], }], }); }, }, 'token.to is a closing square bracket [[-\\]]': { topic: ret('[[-\\]]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.RANGE, from: 91, to: 93 }, ], }], }); }, }, 'token.to is a closing square bracket [[-]]': { topic: ret('[[-]]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.CHAR, value: 91 }, { type: types.CHAR, value: 45 }, ], }, { type: types.CHAR, value: 93, }], }); }, }, 'token.from is a caret [\\^-_]': { topic: ret('[\\^-_]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.RANGE, from: 94, to: 95 }, ], }], }); }, }, 'token.from is a caret [\\^-^]': { topic: ret('[\\^-^]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.RANGE, from: 94, to: 94 }, ], }], }); }, }, 'token.from is a caret and set is negated [^\\^-_]': { topic: ret('[^\\^-_]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: true, set: [ { type: types.RANGE, from: 94, to: 95 }, ], }], }); }, }, 'token.from is a caret [\\^-^] and set is negated': { topic: ret('[^\\^-^]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: true, set: [ { type: types.RANGE, from: 94, to: 94 }, ], }], }); }, }, 'Contains emtpy set': { topic: ret('[]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [], }], }); }, }, 'Contains emtpy negated set': { topic: ret('[^]'), 'Tokenizes correctly': t => { assert.deepStrictEqual(t, { type: types.ROOT, stack: [{ type: types.SET, not: true, set: [], }], }); }, }, }, }, }) .export(module); ret.js-0.5.0/test/reconstruct-test.js000066400000000000000000000551361440466374500176150ustar00rootroot00000000000000const vows = require('vows'); const assert = require('assert'); const ret = require('../dist'); const reconstruct = require('../dist/reconstruct').reconstruct; const types = require('../dist/types').types; const similarToWhitespaceSet = [ { type: types.CHAR, value: 9 }, { type: types.CHAR, value: 10 }, { type: types.CHAR, value: 11 }, { type: types.CHAR, value: 12 }, { type: types.CHAR, value: 13 }, { type: types.CHAR, value: 32 }, { type: types.CHAR, value: 160 }, { type: types.CHAR, value: 5760 }, { type: types.RANGE, from: 8192, to: 8200 }, { type: types.CHAR, value: 8232 }, { type: types.CHAR, value: 8233 }, { type: types.CHAR, value: 8239 }, { type: types.CHAR, value: 8287 }, { type: types.CHAR, value: 12288 }, { type: types.CHAR, value: 65279 }, ].map(code => code.type === types.CHAR ? String.fromCharCode(code.value) : `${String.fromCharCode(code.from)}-${String.fromCharCode(code.to)}`).join(''); const inverseTestFactory = (regexp, expected) => ({ topic: ret(regexp), [`Checking ${regexp} reconstructs`]: t => { // Make sure there are no invalid test cases if ('stack' in t) { for (const elem of t.stack) { const badRange = elem.type === types.SET && elem.set.some(token => token.type === types.RANGE && token.to < token.from); assert.deepStrictEqual(badRange, false); } } // May need to do some sort of sanitisation here const reconstructed = reconstruct(t); assert.isString(reconstructed); if (expected) { assert.deepStrictEqual(reconstructed, expected); } else { assert.deepStrictEqual(reconstructed, regexp.replace(/\[\^0-9\]/g, '\\D') .replace(/\[0-9\]/g, '\\d') .replace(/\[\^_a-zA-Z0-9\]/g, '\\W') .replace(/\[_a-zA-Z0-9\]/g, '\\w'), ); } }, }); /* ! fromentries. MIT License. Feross Aboukhadijeh */ function fromEntries(iterable) { return [...iterable].reduce((obj, [key, val]) => { obj[key] = val; return obj; }, {}); } const multiInverseTestFactory = regexps => fromEntries( regexps.map(regexp => [regexp, inverseTestFactory(regexp)]), ); vows.describe('Regexp Reconstruction') .addBatch({ 'basic (using inverse of Ret)': multiInverseTestFactory([ '', 'a', '1', '.', ',', 'word', '//', '\\W', '\\D', '\\w\\W\\d\\D\\s\\S.', ]), 'testing start and finish flags (using inverse of Ret)': multiInverseTestFactory([ '$', '^', '$a^', '.^', '$,', '$word^', '$//^', '$\\W^', '$\\D^', '$\\w\\W\\d\\D\\s\\S.^', ]), 'testing handleing of escaped special characters': multiInverseTestFactory([ '\\$', '\\^', '\\[', '^\\^', '\\.', '\\|', '\\?', '\\(', '\\)', '\\{', '\\}', '\\\\', '\\$\\^\\[]\\.|', '$\\^\\[]\\.\\|', '\\$^\\[]\\.\\|', '\\$\\^\\[]\\.\\|', '\\$\\^[]\\.\\|', '\\$\\^[]\\.\\|', '\\$\\^\\[].\\|', '\\$\\^\\[]\\.|', '\\$\\^\\[]\\.|\\\\', '\\$\\^\\[]\\.\\\\|', '\\\\\\$\\^\\[]\\.|', ]), 'all main regexp expressions': { 'No special characters': inverseTestFactory('walnuts'), '^ and $ in': inverseTestFactory('^yes$'), '\\b and \\B': inverseTestFactory('\\bbeginning\\B'), 'Predefined sets': inverseTestFactory('\\w\\W\\d\\D\\s\\S.'), 'Custom Sets': multiInverseTestFactory([ '[$!a-z123] thing [^0-9]', '[^.]', '[^test]', ]), 'Whitespace characters': inverseTestFactory('[\t\r\n\u2028\u2029 ]'), 'Two sets in a row with dash in between': inverseTestFactory('[01]-[ab]'), '| (Pipe)': multiInverseTestFactory([ 'foo|bar|za', '(foo|bar|za)', '(foo|bar|za)|(^fe|fi|fo|fum)', ]), Group: { 'with no special characters': inverseTestFactory('hey (there)'), 'that is not remembered': inverseTestFactory('(?:loner)'), 'matched previous clause if not followed by this': inverseTestFactory('what(?!ever)'), 'matched next clause': inverseTestFactory('hello(?= there)'), 'with subgroup': inverseTestFactory('a(b(c|(?:d))fg) @_@'), 'with name': inverseTestFactory('(?\\d{4})-(?\\d{2})-(?\\d{2})'), }, 'Custom repetition with': { 'exact amount': inverseTestFactory('(?:pika){2}'), 'minimum amount only': inverseTestFactory('NO{6,}'), 'both minimum and maximum': inverseTestFactory('pika\\.\\.\\. chu{3,20}!{1,2}'), 'Brackets around a non-repetitional': inverseTestFactory('a{mustache}', 'a\\{mustache\\}'), 'Predefined repetitional': { '? (Optional)': inverseTestFactory('hey(?: you)?'), '+ (At least one)': inverseTestFactory('(no )+'), '* (Any amount)': inverseTestFactory('XF*D'), }, // 'Lookarounds': multiInverseTestFactory([ // '(?<=a)b', // '(?<=text)', // '(?\\w*<\\1>'), Simplifications: multiInverseTestFactory([ '[_a-zA-Z0-9]', '[0-9]', '[^_a-zA-Z0-9]', '[^0-9]', ]), // Testing for https://github.com/fent/ret.js/pull/25#discussion_r533492862 'Range (in set) test cases': { 'Testing complex range cases': { 'token.from is a hyphen and the range is preceded by a single character [a\\---]': { topic: { type: types.SET, not: false, set: [ { type: types.CHAR, value: 97 }, { type: types.RANGE, from: 45, to: 45 }, ], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[a\\--\\-]'); }, }, 'token.from is a hyphen and the range is preceded by a single character [a\\--/]': { topic: { type: types.SET, not: false, set: [ { type: types.CHAR, value: 97 }, { type: types.RANGE, from: 45, to: 47 }, ], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[a\\--/]'); }, }, 'token.from is a hyphen and the range is preceded by a single character [c\\--a]': { topic: { type: types.SET, not: false, set: [ { type: types.CHAR, value: 99 }, { type: types.RANGE, from: 45, to: 97 }, ], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[c\\--a]'); }, }, 'token.from is a hyphen and the range is preceded by a single character [\\-\\---]': { topic: { type: types.SET, not: false, set: [ { type: types.CHAR, value: 45 }, { type: types.RANGE, from: 45, to: 45 }, ], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[\\-\\--\\-]'); }, }, 'token.from is a hyphen and the range is preceded by a predefined set [\\w\\---]': { topic: { type: types.SET, not: false, set: [ { type: types.SET, not: false, set: [ { type: types.CHAR, value: 95 }, { type: types.RANGE, from: 97, to: 122 }, { type: types.RANGE, from: 65, to: 90 }, { type: types.RANGE, from: 48, to: 57 }, ], }, { type: types.RANGE, from: 45, to: 45 }, ], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[\\w\\--\\-]'); }, }, 'token.from is a caret and the range is the first item of the set [9-^]': { topic: { type: types.SET, not: false, set: [ { type: types.RANGE, from: 57, to: 94 }, ], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[9-\\^]'); }, }, 'token.to is a closing square bracket [2-\\]]': { topic: { type: types.SET, not: false, set: [ { type: types.RANGE, from: 50, to: 93 }, ], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[2-\\]]'); }, }, 'token.from is a closing square bracket [\\]-^]': { topic: { type: types.SET, not: false, set: [ { type: types.RANGE, from: 93, to: 94 }, ], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[\\]-\\^]'); }, }, 'token.to is a closing square bracket [[-\\]]': { topic: { type: types.SET, not: false, set: [ { type: types.RANGE, from: 91, to: 93 }, ], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[[-\\]]'); }, }, 'token.to is a closing square bracket [[-]]': { topic: { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.CHAR, value: 91 }, { type: types.CHAR, value: 45 }, ], }, { type: types.CHAR, value: 93, }], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[[\\-]]'); }, }, 'token.from is a caret [\\^-_]': { topic: { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.RANGE, from: 94, to: 95 }, ], }], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[\\^-_]'); }, }, 'token.from is a caret [\\^-^]': { topic: { type: types.ROOT, stack: [{ type: types.SET, not: false, set: [ { type: types.RANGE, from: 94, to: 94 }, ], }], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[\\^-\\^]'); }, }, 'token.from is a caret and set is negated [^^-_]': { topic: { type: types.ROOT, stack: [{ type: types.SET, not: true, set: [ { type: types.RANGE, from: 94, to: 95 }, ], }], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[^\\^-_]'); }, }, 'token.from is a caret [^^-^] and set is negated': { topic: { type: types.ROOT, stack: [{ type: types.SET, not: true, set: [ { type: types.RANGE, from: 94, to: 94 }, ], }], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[^\\^-\\^]'); }, }, 'Contains emtpy set': { topic: { type: types.SET, not: false, set: [], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[]'); }, }, 'Contains emtpy negated set': { topic: { type: types.SET, not: true, set: [], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[^]'); }, }, 'Contains emtpy nested set': { topic: { type: types.SET, not: false, set: [{ type: types.SET, not: false, set: [], }], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[]'); }, }, 'Contains emtpy nested set negated': { topic: { type: types.SET, not: true, set: [{ type: types.SET, not: false, set: [], }], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[^]'); }, }, 'Contains emtpy nested set and single char [a]': { topic: { type: types.SET, not: false, set: [ { type: types.SET, not: false, set: [] }, { type: types.CHAR, value: 97 }, ], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[a]'); }, }, 'Contains emtpy nested set (on right side) and single char [a]': { topic: { type: types.SET, not: false, set: [ { type: types.CHAR, value: 97 }, { type: types.SET, not: false, set: [] }, ], }, 'Reconstructs correctly': set => { assert.deepStrictEqual(reconstruct(set), '[a]'); }, }, }, 'Testing inverse relations': multiInverseTestFactory([ '[a\\--\\-]', '[a\\--/]', '[c\\--a]', '[\\-\\--\\-]', '[\\w\\--\\-]', '[9-\\^]', '[09\\--\\-]', '[2-\\]]', '[\\]-\\^]', '[\\^\\]-\\^]', '[^\\]-\\^]', '[^\\^-\\^]', '[[-\\]]', '[[\\-]]', '\\d', '\\D', '[\\\\-\\\\]', ]), 'Testing inverse relations with repitions': multiInverseTestFactory([ '[a\\--\\-]{3}', '[a\\--/]{5}\\}', '[c\\--a]{2}', '[\\-\\--\\-]\\{\\}', '[\\w\\--\\-]{1}', '[9-\\^]+', '[09\\--\\-]*', '[2-\\]]?', '[\\]-\\^]\\+', '[\\^\\]-\\^]\\*', '[^\\]-\\^]\\?', '[^\\^-\\^]\\{0\\}', '[[-\\]]{0,9}', '[[\\-]]\\{0,9\\}', '\\d?', '\\D?', '[\\\\-\\\\]?', ]), 'Similar to predefined sets': { 'Similar to ints': { topic: [{ type: types.RANGE, from: 48, to: 56 }], 'Set similar to simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: false }), '[0-8]'); }, 'Set similar to simplification works (nested)': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set: [{ type: types.SET, set, not: false }], not: false, }), '[0-8]'); }, 'Negative set similar to simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: true }), '[^0-8]'); }, }, 'Similar to words': { WORDS: { topic: [ { type: types.CHAR, value: 95 }, { type: types.RANGE, from: 97, to: 122 }, { type: types.RANGE, from: 48, to: 57 }, ], 'Set simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: false }), '[_a-z0-9]'); }, 'Negative set simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: true }), '[^_a-z0-9]'); }, }, }, 'Similar to words with nesed set': { WORDS: { topic: [ { type: types.CHAR, value: 95 }, { type: types.RANGE, from: 97, to: 122 }, { type: types.SET, not: false, set: [] }, { type: types.RANGE, from: 48, to: 57 }, ], 'Set simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: false }), '[_a-z0-9]'); }, 'Negative set simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: true }), '[^_a-z0-9]'); }, }, }, 'Similar to whitespace': { topic: [ { type: types.CHAR, value: 9 }, { type: types.CHAR, value: 10 }, { type: types.CHAR, value: 11 }, { type: types.CHAR, value: 12 }, { type: types.CHAR, value: 13 }, { type: types.CHAR, value: 32 }, { type: types.CHAR, value: 160 }, { type: types.CHAR, value: 5760 }, { type: types.RANGE, from: 8192, to: 8200 }, { type: types.CHAR, value: 8232 }, { type: types.CHAR, value: 8233 }, { type: types.CHAR, value: 8239 }, { type: types.CHAR, value: 8287 }, { type: types.CHAR, value: 12288 }, { type: types.CHAR, value: 65279 }, ], 'Set simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: false }), `[${similarToWhitespaceSet}]`); }, 'Negative set simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: true }), `[^${similarToWhitespaceSet}]`); }, }, }, }, 'Set simplification tests': { INTS: { topic: [{ type: types.RANGE, from: 48, to: 57 }], 'Set simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: false }), '\\d'); }, 'Negative set simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: true }), '\\D'); }, }, WORDS: { topic: [ { type: types.CHAR, value: 95 }, { type: types.RANGE, from: 97, to: 122 }, { type: types.RANGE, from: 65, to: 90 }, { type: types.RANGE, from: 48, to: 57 }, ], 'Set simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: false }), '\\w'); }, 'Negative set simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: true }), '\\W'); }, }, WHITESPACE: { topic: [ { type: types.CHAR, value: 9 }, { type: types.CHAR, value: 10 }, { type: types.CHAR, value: 11 }, { type: types.CHAR, value: 12 }, { type: types.CHAR, value: 13 }, { type: types.CHAR, value: 32 }, { type: types.CHAR, value: 160 }, { type: types.CHAR, value: 5760 }, { type: types.RANGE, from: 8192, to: 8202 }, { type: types.CHAR, value: 8232 }, { type: types.CHAR, value: 8233 }, { type: types.CHAR, value: 8239 }, { type: types.CHAR, value: 8287 }, { type: types.CHAR, value: 12288 }, { type: types.CHAR, value: 65279 }, ], 'Set simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: false }), '\\s'); }, 'Negative set simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: true }), '\\S'); }, }, NOTANYCHAR: { topic: [ { type: types.CHAR, value: 10 }, { type: types.CHAR, value: 13 }, { type: types.CHAR, value: 8232 }, { type: types.CHAR, value: 8233 }, ], 'Set simplification works': set => { assert.deepStrictEqual(reconstruct({ type: types.SET, set, not: true }), '.'); }, }, }, }, 'Reconstruct error test (bad root)': { topic: () => { try { return reconstruct({ type: ret.types.ROOT }); } catch (e) { return e; } }, 'throws error emessage': err => { assert.isObject(err); assert.include(err.message, 'options or stack must be Root or Group token'); }, }, 'Reconstruct error test (invalid token)': { topic: () => { try { return reconstruct({}); } catch (e) { return e; } }, 'throws error emessage': err => { assert.isObject(err); assert.include(err.message, 'Invalid token type'); }, }, 'Reconsutructs individual range tokens outisde of set 0-8': { topic: reconstruct({ type: types.RANGE, from: 48, to: 56 }), 'Outputs range correctly': res => { assert.deepStrictEqual(res, '0-8'); }, }, 'Reconsutructs individual range tokens outisde of set 0-\\]': { topic: reconstruct({ type: types.RANGE, from: 48, to: 93 }), 'Outputs range correctly': res => { assert.deepStrictEqual(res, '0-\\]'); }, }, }, }) .export(module); ret.js-0.5.0/test/util-test.js000066400000000000000000000061661440466374500162160ustar00rootroot00000000000000const vows = require('vows'); const assert = require('assert'); const util = require('../dist/util'); const types = require('../dist').types; const sets = require('../dist/sets'); vows.describe('strToChars') .addBatch({ 'Convert escaped chars in str to their unescaped versions': { topic: () => util.strToChars( '\\v \\xFF hellow \\u00A3 \\50 \\u0028 there \\cB \\n \\w [\\b]'), 'Returned string has converted characters': str => { assert.equal(str, '\v \xFF hellow \u00A3 \\50 \\( there  \n \\w \u0008'); }, }, 'Escaped chars in regex source remain espaced': { topic: () => util.strToChars( /\\xFF hellow \\u00A3 \\50 \\u0028 there \\cB \\n \\w/.source), 'Returned string has escaped characters': str => { assert.equal(str, '\\\\xFF hellow \\\\u00A3 \\\\50 \\\\u0028 there \\\\cB \\\\n \\\\w'); }, }, }) .export(module); vows.describe('tokenizeClass') .addBatch({ 'Class tokens': { topic: util.tokenizeClass('\\w\\d$\\s\\]\\B\\W\\D\\S.+-] will ignore'), 'Get a words set token': t => { assert.isArray(t[0]); assert.deepEqual(t[0][0], sets.words()); }, 'Get an integers set token': t => { assert.isArray(t[0]); assert.deepEqual(t[0][1], sets.ints()); }, 'Get some char tokens': t => { assert.isArray(t[0]); assert.deepEqual(t[0][2], { type: types.CHAR, value: 36 }); assert.deepEqual(t[0][4], { type: types.CHAR, value: 93 }); assert.deepEqual(t[0][5], { type: types.CHAR, value: 66 }); }, 'Get a whitespace set token': t => { assert.isArray(t[0]); assert.deepEqual(t[0][3], sets.whitespace()); }, 'Get negated sets': t => { assert.isArray(t[0]); assert.deepEqual(t[0][6], sets.notWords()); assert.deepEqual(t[0][7], sets.notInts()); assert.deepEqual(t[0][8], sets.notWhitespace()); }, 'Get correct char tokens at end of set': t => { assert.isArray(t[0]); assert.deepEqual(t[0][9], { type: types.CHAR, value: 46 }); assert.deepEqual(t[0][10], { type: types.CHAR, value: 43 }); assert.deepEqual(t[0][11], { type: types.CHAR, value: 45 }); }, 'Get correct position of closing brace': t => { assert.isNumber(t[1]); assert.equal(t[1], 21); }, }, Ranges: { topic: util.tokenizeClass('a-z0-9]'), 'Get alphabetic range': t => { assert.isArray(t[0]); assert.deepEqual(t[0][0], { type: types.RANGE, from: 97, to: 122, }); }, 'Get numeric range': t => { assert.isArray(t[0]); assert.deepEqual(t[0][1], { type: types.RANGE, from: 48, to: 57, }); }, }, 'Ranges with escaped characters': { topic: util.tokenizeClass('\\\\-~]'), 'Get escaped backslash range': t => { assert.isArray(t[0]); assert.deepEqual(t[0][0], { type: types.RANGE, from: 92, to: 126, }); }, }, }) .export(module); ret.js-0.5.0/tsconfig.json000066400000000000000000000136261440466374500154550ustar00rootroot00000000000000{ "compilerOptions": { /* Visit https://aka.ms/tsconfig.json to read more about this file */ /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ "declaration": true, /* Generates corresponding '.d.ts' file. */ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ "sourceMap": true, /* Generates corresponding '.map' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ "outDir": "./dist", /* Redirect output structure to the directory. */ // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "composite": true, /* Enable project compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ // "strict": true, /* Enable all strict type-checking options. */ "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ "strictNullChecks": false, /* Enable strict null checks. */ "strictFunctionTypes": true, /* Enable strict checking of function types. */ "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ "strictPropertyInitialization": false, /* Enable strict checking of property initialization in classes. */ "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ /* Additional Checks */ "noUnusedLocals": true, /* Report errors on unused locals. */ "noUnusedParameters": true, /* Report errors on unused parameters. */ "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ /* Source Map Options */ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ /* Experimental Options */ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Advanced Options */ "skipLibCheck": true, /* Skip type checking of declaration files. */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ } }