├── .eslintrc ├── .github └── workflows │ └── build.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── lib ├── index.js └── syntax-extension │ ├── index.js │ ├── less │ ├── LessEscaping.js │ ├── LessNamespace.js │ ├── LessVariable.js │ ├── LessVariableReference.js │ └── index.js │ └── sass │ ├── SassInterpolation.js │ ├── SassNamespace.js │ ├── SassVariable.js │ └── index.js ├── package-lock.json ├── package.json ├── scripts └── esm-to-cjs.js └── test ├── css.js ├── preprocessors.js └── utils └── tester.js /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true, 4 | "mocha": true, 5 | "es6": true 6 | }, 7 | "parserOptions": { 8 | "ecmaVersion": 2020, 9 | "sourceType": "module" 10 | }, 11 | "rules": { 12 | "no-duplicate-case": 2, 13 | "no-undef": 2, 14 | "no-unused-vars": [ 15 | 2, 16 | { 17 | "vars": "all", 18 | "args": "after-used" 19 | } 20 | ], 21 | "no-empty": [ 22 | 2, 23 | { 24 | "allowEmptyCatch": true 25 | } 26 | ], 27 | "no-implicit-coercion": [ 28 | 2, 29 | { 30 | "boolean": true, 31 | "string": true, 32 | "number": true 33 | } 34 | ], 35 | "no-with": 2, 36 | "brace-style": 2, 37 | "no-mixed-spaces-and-tabs": 2, 38 | "no-multiple-empty-lines": 2, 39 | "no-multi-str": 2, 40 | "dot-location": [ 41 | 2, 42 | "property" 43 | ], 44 | "operator-linebreak": [ 45 | 2, 46 | "after", 47 | { 48 | "overrides": { 49 | "?": "before", 50 | ":": "before" 51 | } 52 | } 53 | ], 54 | "key-spacing": [ 55 | 2, 56 | { 57 | "beforeColon": false, 58 | "afterColon": true 59 | } 60 | ], 61 | "space-unary-ops": [ 62 | 2, 63 | { 64 | "words": false, 65 | "nonwords": false 66 | } 67 | ], 68 | "no-spaced-func": 2, 69 | "space-before-function-paren": [ 70 | 2, 71 | { 72 | "anonymous": "ignore", 73 | "named": "never" 74 | } 75 | ], 76 | "array-bracket-spacing": [ 77 | 2, 78 | "never" 79 | ], 80 | "space-in-parens": [ 81 | 2, 82 | "never" 83 | ], 84 | "comma-dangle": [ 85 | 2, 86 | "never" 87 | ], 88 | "no-trailing-spaces": 2, 89 | "yoda": [ 90 | 2, 91 | "never" 92 | ], 93 | "camelcase": [ 94 | 2, 95 | { 96 | "properties": "never" 97 | } 98 | ], 99 | "comma-style": [ 100 | 2, 101 | "last" 102 | ], 103 | "curly": [ 104 | 2, 105 | "all" 106 | ], 107 | "dot-notation": 2, 108 | "eol-last": 2, 109 | "one-var": [ 110 | 2, 111 | "never" 112 | ], 113 | "wrap-iife": 2, 114 | "space-infix-ops": 2, 115 | "keyword-spacing": [ 116 | 2, 117 | { 118 | "overrides": { 119 | "else": { 120 | "before": true 121 | }, 122 | "while": { 123 | "before": true 124 | }, 125 | "catch": { 126 | "before": true 127 | }, 128 | "finally": { 129 | "before": true 130 | } 131 | } 132 | } 133 | ], 134 | "spaced-comment": [ 135 | 2, 136 | "always" 137 | ], 138 | "space-before-blocks": [ 139 | 2, 140 | "always" 141 | ], 142 | "semi": [ 143 | 2, 144 | "always" 145 | ], 146 | "indent": [ 147 | 2, 148 | 4, 149 | { 150 | "SwitchCase": 1 151 | } 152 | ], 153 | "linebreak-style": [ 154 | 2, 155 | "unix" 156 | ], 157 | "quotes": [ 158 | 2, 159 | "single", 160 | { 161 | "avoidEscape": true 162 | } 163 | ] 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | env: 8 | PRIMARY_NODEJS_VERSION: 18 9 | REPORTER: "min" 10 | 11 | jobs: 12 | lint: 13 | name: Lint 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Setup node ${{ env.PRIMARY_NODEJS_VERSION }} 18 | uses: actions/setup-node@v2 19 | with: 20 | node-version: ${{ env.PRIMARY_NODEJS_VERSION }} 21 | cache: "npm" 22 | - run: npm ci 23 | - run: npm run lint 24 | 25 | unit-tests: 26 | name: Unit tests 27 | runs-on: ubuntu-latest 28 | 29 | strategy: 30 | matrix: 31 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 32 | node_version: 33 | - 14.13.0 34 | - 16 35 | - 18 36 | - 20 37 | 38 | steps: 39 | - uses: actions/checkout@v2 40 | - name: Setup node ${{ matrix.node_version }} 41 | uses: actions/setup-node@v2 42 | with: 43 | node-version: ${{ matrix.node_version }} 44 | cache: "npm" 45 | - run: npm ci 46 | - run: npm run test 47 | - run: npm run esm-to-cjs-and-test 48 | 49 | - run: npm run coverage 50 | if: ${{ matrix.node_version == env.PRIMARY_NODEJS_VERSION }} 51 | - name: Coveralls parallel 52 | if: ${{ matrix.node_version == env.PRIMARY_NODEJS_VERSION }} 53 | uses: coverallsapp/github-action@1.1.3 54 | with: 55 | github-token: ${{ secrets.GITHUB_TOKEN }} 56 | flag-name: node-${{ matrix.node_version }} 57 | parallel: true 58 | 59 | send-to-coveralls: 60 | name: Send coverage to Coveralls 61 | needs: unit-tests 62 | runs-on: ubuntu-latest 63 | steps: 64 | - name: Send coverage to Coveralls 65 | uses: coverallsapp/github-action@1.1.3 66 | with: 67 | github-token: ${{ secrets.GITHUB_TOKEN }} 68 | parallel-finished: true 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | cjs 2 | cjs-test 3 | coverage 4 | node_modules 5 | npm-debug.log 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 3.0.0 (June 12, 2023) 2 | 3 | - Added support for stylelint 15 (#53) 4 | - Dropped support for Node.js below 14.13 5 | 6 | ## 2.1.0 (January 29, 2023) 7 | 8 | - Bumped `css-tree` to `^2.3.1` 9 | - Extended `ignoreAtrules` and `ignoreProperties` options to accept [RegExp patterns](README.md#regexp-patterns) (#19, #45) 10 | - Fixed Sass's `@else` at-rule to allow have no a prelude (#46) 11 | - Changed at-rule prelude validation to emit no warnings when a prelude contains Sass/Less syntax extensions (#44) 12 | 13 | ## 2.0.0 (December 14, 2021) 14 | 15 | - Added `syntaxExtensions` option to specify syntax extensions, i.e. `sass` or/and `less`. For now **the plugin validates CSS only by default** 16 | - Added at-rule validation for name, prelude and descriptors 17 | - Added `atrules` option to extend or alter at-rule syntax definition dictionary or disable at-rule validation when `false` is passed as a value for the option 18 | - Added `ignoreAtrules` option to specify at-rule names which should not be validated 19 | - Used `isStandardSyntax*()` helpers from `stylelint` to reduce failures for non-standard syntax (e.g. Less or Sass) 20 | - Added support for Less & Sass namespaces, a value with such constructions are ignored now instead of failure (#39) 21 | - Added a column to mismatch error details 22 | - Renamed `ignore` option into `ignoreProperties` to be more clear what is ignoring; `ignore` option is still work but cause to a deprecation warning 23 | - Fixed `ignoreValue` option to apply for parse errors either (#43) 24 | - Fixed failure on a declaration with a Less variable reference, i.e. ignore such declarations for now 25 | - Package 26 | - Changed supported versions of Node.js to `^12.20.0`, `^14.13.0` and `>=15.0.0` 27 | - Converted to ES modules. However, CommonJS is supported as well (dual module) 28 | - Bumped `css-tree` to [`2.0`](https://github.com/csstree/csstree/releases/tag/v2.0.0) and latest `mdn-data` dictionaries 29 | 30 | ## 1.9.0 (October 27, 2020) 31 | 32 | - Bumped CSSTree to `^1.0.0` (mdn-data is bumped to `2.0.12`) 33 | - Added `properties` and `types` options to extend syntax dictionary 34 | - Added `ignoreValue` option (#14) 35 | 36 | ## 1.8.0 (January 24, 2020) 37 | 38 | - Added support for stylelint 13 (#25, thanks to @limonte) 39 | 40 | ## 1.7.0 (November 25, 2019) 41 | 42 | - Added support for stylelint 12 (#24, #23, thanks to @limonte & @gforcada) 43 | - Bumped CSSTree to `1.0.0-alpha.38` (mdn-data is bumped to `2.0.6`) 44 | 45 | ## 1.6.1 (October 6, 2019) 46 | 47 | - Fixed regression after CSSTree bump to 1.0.0-alpha.34 48 | 49 | ## 1.6.0 (October 6, 2019) 50 | 51 | - Added support for stylelint 11 (#21, thanks to @ntwb) 52 | - Bumped CSSTree to [1.0.0-alpha.34](https://github.com/csstree/csstree/releases/tag/v1.0.0-alpha.34) 53 | 54 | ## 1.5.2 (July 11, 2019) 55 | 56 | - Bumped CSSTree to [1.0.0-alpha.33](https://github.com/csstree/csstree/releases/tag/v1.0.0-alpha.33) 57 | 58 | ## 1.5.1 (July 11, 2019) 59 | 60 | - Bumped CSSTree to [1.0.0-alpha.32](https://github.com/csstree/csstree/releases/tag/v1.0.0-alpha.32) 61 | 62 | ## 1.5.0 (July 11, 2019) 63 | 64 | - Bumped CSSTree to [1.0.0-alpha.31](https://github.com/csstree/csstree/releases/tag/v1.0.0-alpha.31) 65 | 66 | ## 1.4.1 (July 5, 2019) 67 | 68 | - Fixed missed `console.log()` (#18) 69 | 70 | ## 1.4.0 (July 3, 2019) 71 | 72 | - Added support for stylelint 10 (#17, thanks to @limonte) 73 | - Bumped CSSTree to [1.0.0-alpha.30](https://github.com/csstree/csstree/releases/tag/v1.0.0-alpha.30) 74 | 75 | ## 1.3.0 (May 30, 2018) 76 | 77 | - Bumped CSSTree to [1.0.0-alpha.29](https://github.com/csstree/csstree/releases/tag/v1.0.0-alpha.29) 78 | 79 | ## 1.2.2 (February 19, 2018) 80 | 81 | - Bumped CSSTree to `1.0.0-alpha.28` (bug fixes) 82 | - Bumped stylelint to `>=7.0.0 <10.0.0` and make it a peer dependency 83 | 84 | ## 1.2.1 (November 12, 2017) 85 | 86 | - Bumped CSSTree to `1.0.0-alpha.26` (improved parsing and bug fixes) 87 | 88 | ## 1.2.0 (September 4, 2017) 89 | 90 | - Bumped CSSTree to `1.0.0-alpha21` (improved parsing and updated property grammars) 91 | 92 | ## 1.1.1 (February 15, 2017) 93 | 94 | - Ignore any declaration which property name looks using a preprocessor interpolation (e.g. `smth-@{foo}` or `smth-#{$foo}`) 95 | - Ignore values with `Sass` interpolation (#7) 96 | 97 | ## 1.1.0 (February 14, 2017) 98 | 99 | - Ignore `Less` and `Sass` var declarations that treats as regular declarations by PostCSS (#4) 100 | - Implemented `ignore` option to define a list of property names that should be ignored by the validator. It may be used as a workaround to avoid warnings about syntax extensions (#5) 101 | 102 | ## 1.0.6 (February 12, 2017) 103 | 104 | - Bump CSSTree to `1.0.0-alpha16` 105 | - Ignore values with `Less` and `Sass` extensions (#3) 106 | 107 | ## 1.0.5 (January 19, 2017) 108 | 109 | - Bump CSSTree to `1.0.0-alpha12` 110 | 111 | ## 1.0.4 (December 21, 2016) 112 | 113 | - Bump CSSTree to `1.0.0-alpha9` 114 | 115 | ## 1.0.3 (November 21, 2016) 116 | 117 | - Bump CSSTree to `1.0.0-alpha8` 118 | 119 | ## 1.0.2 (September 19, 2016) 120 | 121 | - Bump CSSTree to `1.0.0-alpha5` 122 | 123 | ## 1.0.1 (September 17, 2016) 124 | 125 | - Tweak description files 126 | 127 | ## 1.0.0 (September 17, 2016) 128 | 129 | - Initial implementation 130 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2016-2021 by Roman Dvornov 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![NPM version](https://img.shields.io/npm/v/stylelint-csstree-validator.svg)](https://www.npmjs.com/package/stylelint-csstree-validator) 2 | [![Build Status](https://github.com/csstree/stylelint-validator/actions/workflows/build.yml/badge.svg)](https://github.com/csstree/stylelint-validator/actions/workflows/build.yml) 3 | [![Coverage Status](https://coveralls.io/repos/github/csstree/stylelint-validator/badge.svg?branch=master)](https://coveralls.io/github/csstree/stylelint-validator?branch=master) 4 | 5 | # stylelint-csstree-validator 6 | 7 | A [stylelint](http://stylelint.io/) plugin based on [csstree](https://github.com/csstree/csstree) to examinate CSS syntax. It examinates at-rules and declaration values to match W3C specs and browsers extensions. It might be extended in future to validate other parts of CSS. 8 | 9 | > ⚠️ Warning ⚠️: The plugin is designed to validate CSS syntax only. However `stylelint` may be configured to use for other syntaxes like Less or Sass. In this case, the plugin avoids examination of expressions containing non-standard syntax, but you need specify which preprocessor is used with the [`syntaxExtensions`](#syntaxextensions) option. 10 | 11 | ## Install 12 | 13 | ``` 14 | $ npm install --save-dev stylelint-csstree-validator 15 | ``` 16 | 17 | ## Usage 18 | 19 | Setup plugin in [stylelint config](http://stylelint.io/user-guide/configuration/): 20 | 21 | ```json 22 | { 23 | "plugins": [ 24 | "stylelint-csstree-validator" 25 | ], 26 | "rules": { 27 | "csstree/validator": true 28 | } 29 | } 30 | ``` 31 | 32 | ### Options 33 | 34 | - [syntaxExtensions](#syntaxextensions) 35 | - [atrules](#atrules) 36 | - [properties](#properties) 37 | - [types](#types) 38 | - [ignore](#ignore) (deprecated) 39 | - [ignoreAtrules](#ignoreatrules) 40 | - [ignoreProperties](#ignoreproperties) 41 | - [ignoreValue](#ignorevalue) 42 | 43 | #### syntaxExtensions 44 | 45 | Type: `Array<'sass' | 'less'>` or `false` 46 | Default: `false` 47 | 48 | Since the plugin focuses on CSS syntax validation it warns on a syntax which is introducing by preprocessors like Less or Sass. The `syntaxExtensions` option allows to specify that some preprocessor's syntaxes are used for styles so the plugin may avoid warnings when met such a syntax. 49 | 50 | By default the plugin exams styles as pure CSS. To specify that a preprocessor's syntax is used, you must specify an array with the names of these extensions. Currently supported: 51 | 52 | - `sass` – declaration values with Sass syntax will be ignored as well as custom at-rules introduced by Saas (e.g. `@if`, `@else`, `@mixin` etc). For now Sass at-rules are allowed with any prelude, but it might be replaced for real syntax definitions in future releases 53 | - `less` – declaration values with Sass syntax will be ignored as well as `@plugin` at-rule introduced by Less 54 | 55 | Using both syntax extensions is also possible: 56 | 57 | ```json 58 | { 59 | "plugins": [ 60 | "stylelint-csstree-validator" 61 | ], 62 | "rules": { 63 | "csstree/validator": { 64 | "syntaxExtensions": ["sass", "less"] 65 | } 66 | } 67 | } 68 | ``` 69 | 70 | #### atrules 71 | 72 | Type: `Object`, `false` or `null` 73 | Default: `null` 74 | 75 | Using `false` value for the option disables at-rule validation. 76 | 77 | Otherwise the option is using for extending or altering at-rules syntax dictionary. An atrule definition consists of `prelude` and `descriptors`, both are optional. A `prelude` is a single expression that comes after at-rule name. A `descriptors` is a dictionary like [`properties`](#properties) option but for a specific at-rule. [CSS Value Definition Syntax](https://github.com/csstree/csstree/blob/master/docs/definition-syntax.md) is used to define value's syntax. If a definition starts with `|` it is adding to existing definition value if any. See [CSS syntax reference](https://csstree.github.io/docs/syntax/) for default definitions. 78 | 79 | The following example defines new atrule `@example` with a prelude and two descriptors (a descriptor is the same as a declaration but with no `!important` allowed): 80 | 81 | ```json 82 | { 83 | "plugins": [ 84 | "stylelint-csstree-validator" 85 | ], 86 | "rules": { 87 | "csstree/validator": { 88 | "atrules": { 89 | "example": { 90 | "prelude": "", 91 | "descriptors": { 92 | "foo": "", 93 | "bar": "" 94 | } 95 | } 96 | } 97 | } 98 | } 99 | } 100 | ``` 101 | 102 | #### properties 103 | 104 | Type: `Object` or `null` 105 | Default: `null` 106 | 107 | An option for extending or altering properties syntax dictionary. [CSS Value Definition Syntax](https://github.com/csstree/csstree/blob/master/docs/definition-syntax.md) is used to define value's syntax. If a definition starts with `|` it is adding to existing definition value if any. See [CSS syntax reference](https://csstree.github.io/docs/syntax/) for default definitions. 108 | 109 | The following example extends `width` and defines `size` properties: 110 | 111 | ```json 112 | { 113 | "plugins": [ 114 | "stylelint-csstree-validator" 115 | ], 116 | "rules": { 117 | "csstree/validator": { 118 | "properties": { 119 | "width": "| new-keyword | custom-function(, )", 120 | "size": "" 121 | } 122 | } 123 | } 124 | } 125 | ``` 126 | 127 | Using `` for a property definition is an alternative for `ignoreProperties` option. 128 | 129 | ```json 130 | { 131 | "plugins": [ 132 | "stylelint-csstree-validator" 133 | ], 134 | "rules": { 135 | "csstree/validator": { 136 | "properties": { 137 | "my-custom-property": "" 138 | } 139 | } 140 | } 141 | } 142 | ``` 143 | 144 | #### types 145 | 146 | Type: `Object` or `null` 147 | Default: `null` 148 | 149 | An option for extending or altering types syntax dictionary. Types are something like a preset which allow reuse a definition across other definitions. [CSS Value Definition Syntax](https://github.com/csstree/csstree/blob/master/docs/definition-syntax.md) is used to define value's syntax. If a definition starts with `|` it is adding to existing definition value if any. See [CSS syntax reference](https://csstree.github.io/docs/syntax/) for default definitions. 150 | 151 | The following example defines a new functional type `my-fn()` and extends `color` type: 152 | 153 | ```json 154 | { 155 | "plugins": [ 156 | "stylelint-csstree-validator" 157 | ], 158 | "rules": { 159 | "csstree/validator": { 160 | "properties": { 161 | "some-property": "" 162 | }, 163 | "types": { 164 | "color": "| darken(, [ | ])", 165 | "my-fn()": "my-fn( )" 166 | } 167 | } 168 | } 169 | } 170 | ``` 171 | 172 | #### ignore 173 | 174 | Works the same as [`ignoreProperties`](#ignoreproperties) but **deprecated**, use `ignoreProperties` instead. 175 | 176 | #### ignoreAtrules 177 | 178 | Type: `Array` or `false` 179 | Default: `false` 180 | 181 | Defines a list of at-rules names that should be ignored by the plugin. Ignorance for an at-rule means no validation for its name, prelude or descriptors. The names provided are used for full case-insensitive matching, i.e. a vendor prefix is mandatory and prefixed names should be provided as well if you need to ignore them. You can use [RegExp patterns](#regexp-patterns) in the list as well. 182 | 183 | ```json 184 | { 185 | "plugins": [ 186 | "stylelint-csstree-validator" 187 | ], 188 | "rules": { 189 | "csstree/validator": { 190 | "ignoreAtrules": ["custom-at-rule", "-webkit-keyframes"] 191 | } 192 | } 193 | } 194 | ``` 195 | 196 | #### ignoreProperties 197 | 198 | Type: `Array` or `false` 199 | Default: `false` 200 | 201 | Defines a list of property names that should be ignored by the plugin. The names provided are used for full case-insensitive matching, i.e. a vendor prefix is mandatory and prefixed names should be provided as well if you need to ignore them. 202 | 203 | ```json 204 | { 205 | "plugins": [ 206 | "stylelint-csstree-validator" 207 | ], 208 | "rules": { 209 | "csstree/validator": { 210 | "ignoreProperties": ["composes", "mask", "-webkit-mask"] 211 | } 212 | } 213 | } 214 | ``` 215 | 216 | In this example, plugin will not test declarations with a property name `composes`, `mask` or `-webkit-mask`, i.e. no warnings for these declarations would be raised. You can use [RegExp patterns](#regexp-patterns) in the list as well. 217 | 218 | #### ignoreValue 219 | 220 | Type: `RegExp` or `false` 221 | Default: `false` 222 | 223 | Defines a pattern for values that should be ignored by the validator. 224 | 225 | ```json 226 | { 227 | "plugins": [ 228 | "stylelint-csstree-validator" 229 | ], 230 | "rules": { 231 | "csstree/validator": { 232 | "ignoreValue": "^pattern$" 233 | } 234 | } 235 | } 236 | ``` 237 | 238 | For this example, the plugin will not report warnings for values which is matched the given pattern. However, warnings will still be reported for unknown properties. 239 | 240 | ## RegExp patterns 241 | 242 | In some cases a more general match patterns are needed instead of exact name matching. In such cases a RegExp pattern can be used. 243 | 244 | Since CSS names are an indentifiers which can't contain a special characters used for RegExp's, a distinguishing between a CSS name and RegExp is a trivial problem. When the plugin encounters a string in a ignore pattern list containing any character other than `a-z`, `A-Z`, `0-9` or `-`, it produces a RegExp using the construction `new RegExp('^(' + pattern + ')$', 'i')`. In other words, the pattern should be fully matched case-insensitive. 245 | 246 | To have a full control over a RegExp pattern, a regular RegExp instance or its stringified version (i.e. `"/pattern/flags?"`) can be used. 247 | 248 | - `"foo|bar"` transforms into `/^(foo|bar)$/i` 249 | - `"/foo|bar/i"` transforms into `/foo|bar/i` (note: it's not the same as previous RegExp, since not requires a full match with a name) 250 | - `/foo|bar/` used as is (note: with no `i` flag a matching will be case-sensitive which makes no sense in CSS) 251 | 252 | ## License 253 | 254 | MIT 255 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | import stylelint from 'stylelint'; 2 | import isStandardSyntaxAtRule from 'stylelint/lib/utils/isStandardSyntaxAtRule.js'; 3 | import isStandardSyntaxDeclaration from 'stylelint/lib/utils/isStandardSyntaxDeclaration.js'; 4 | import isStandardSyntaxProperty from 'stylelint/lib/utils/isStandardSyntaxProperty.js'; 5 | import isStandardSyntaxValue from 'stylelint/lib/utils/isStandardSyntaxValue.js'; 6 | import { fork, lexer, parse } from 'css-tree'; 7 | import { less, sass } from './syntax-extension/index.js'; 8 | 9 | const { utils, createPlugin } = stylelint; 10 | const isRegExp = value => toString.call(value) === '[object RegExp]'; 11 | const getRaw = (node, name) => (node.raws && node.raws[name]) || ''; 12 | const allowedSyntaxExtensions = new Set(['less', 'sass']); 13 | const lessExtendedSyntax = fork(less); 14 | const sassExtendedSyntax = fork(sass); 15 | const syntaxExtensions = { 16 | none: { fork, lexer, parse }, 17 | less: lessExtendedSyntax, 18 | sass: sassExtendedSyntax, 19 | all: fork(less).fork(sass) 20 | }; 21 | 22 | const ruleName = 'csstree/validator'; 23 | const messages = utils.ruleMessages(ruleName, { 24 | csstree(value) { 25 | return value; 26 | }, 27 | parseError(value) { 28 | return 'Can\'t parse value "' + value + '"'; 29 | }, 30 | unknownAtrule(atrule) { 31 | return 'Unknown at-rule `@' + atrule + '`'; 32 | }, 33 | invalidPrelude(atrule) { 34 | return 'Invalid prelude for `@' + atrule + '`'; 35 | }, 36 | unknownProperty(property) { 37 | return 'Unknown property `' + property + '`'; 38 | }, 39 | invalidValue(property) { 40 | return 'Invalid value for "' + property + '"'; 41 | } 42 | }); 43 | 44 | function createIgnoreMatcher(patterns) { 45 | if (Array.isArray(patterns)) { 46 | const names = new Set(); 47 | const regexpes = []; 48 | 49 | for (let pattern of patterns) { 50 | if (typeof pattern === 'string') { 51 | const stringifiedRegExp = pattern.match(/^\/(.+)\/([a-z]*)/); 52 | 53 | if (stringifiedRegExp) { 54 | regexpes.push(new RegExp(stringifiedRegExp[1], stringifiedRegExp[2])); 55 | } else if (/[^a-z0-9\-]/i.test(pattern)) { 56 | regexpes.push(new RegExp(`^(${pattern})$`, 'i')); 57 | } else { 58 | names.add(pattern.toLowerCase()); 59 | } 60 | } else if (isRegExp(pattern)) { 61 | regexpes.push(pattern); 62 | } 63 | } 64 | 65 | const matchRegExpes = regexpes.length 66 | ? name => regexpes.some(pattern => pattern.test(name)) 67 | : null; 68 | 69 | if (names.size > 0) { 70 | return matchRegExpes !== null 71 | ? name => names.has(name.toLowerCase()) || matchRegExpes(name) 72 | : name => names.has(name.toLowerCase()); 73 | } else if (matchRegExpes !== null) { 74 | return matchRegExpes; 75 | } 76 | } 77 | 78 | return false; 79 | } 80 | 81 | const plugin = createPlugin(ruleName, function(options) { 82 | options = options || {}; 83 | 84 | const optionSyntaxExtension = new Set(Array.isArray(options.syntaxExtensions) ? options.syntaxExtensions : []); 85 | 86 | const ignoreValue = options.ignoreValue && (typeof options.ignoreValue === 'string' || isRegExp(options.ignoreValue)) 87 | ? new RegExp(options.ignoreValue) 88 | : false; 89 | const ignoreProperties = createIgnoreMatcher(options.ignoreProperties || options.ignore); 90 | const ignoreAtrules = createIgnoreMatcher(options.ignoreAtrules); 91 | const atrulesValidationDisabled = options.atrules === false; 92 | const syntax = optionSyntaxExtension.has('less') 93 | ? optionSyntaxExtension.has('sass') 94 | ? syntaxExtensions.all 95 | : syntaxExtensions.less 96 | : optionSyntaxExtension.has('sass') 97 | ? syntaxExtensions.sass 98 | : syntaxExtensions.none; 99 | const lexer = !options.properties && !options.types && !options.atrules 100 | ? syntax.lexer // default syntax 101 | : syntax.fork({ 102 | properties: options.properties || {}, 103 | types: options.types || {}, 104 | atrules: options.atrules || {} 105 | }).lexer; 106 | 107 | return function(root, result) { 108 | const ignoreAtruleNodes = new WeakSet(); 109 | 110 | stylelint.utils.validateOptions(result, ruleName, { 111 | actual: { 112 | ignore: options.ignore, 113 | syntaxExtensions: [...optionSyntaxExtension] 114 | }, 115 | possible: { 116 | ignore: value => value === undefined, 117 | syntaxExtensions: value => allowedSyntaxExtensions.has(value) 118 | } 119 | }); 120 | 121 | root.walkAtRules(function(atrule) { 122 | let error; 123 | 124 | // ignore non-standard at-rules 125 | if (syntax !== syntaxExtensions.none && !isStandardSyntaxAtRule(atrule)) { 126 | return; 127 | } 128 | 129 | // at-rule validation is disabled 130 | if (atrulesValidationDisabled) { 131 | ignoreAtruleNodes.add(atrule); 132 | return; 133 | } 134 | 135 | if (ignoreAtrules !== false && ignoreAtrules(atrule.name)) { 136 | ignoreAtruleNodes.add(atrule); 137 | return; 138 | } 139 | 140 | if (error = lexer.checkAtruleName(atrule.name)) { 141 | ignoreAtruleNodes.add(atrule); 142 | utils.report({ 143 | ruleName, 144 | result, 145 | message: messages.csstree(error.message), 146 | node: atrule 147 | }); 148 | 149 | return; 150 | } 151 | 152 | if (error = lexer.matchAtrulePrelude(atrule.name, atrule.params).error) { 153 | let message = error.rawMessage || error.message; 154 | let index = 2 + atrule.name.length + getRaw('afterName').length; 155 | 156 | if (message === 'Mismatch') { 157 | // ignore mismatch errors for a prelude with syntax extensions 158 | if (syntax !== syntaxExtensions.none && atrule.params) { 159 | try { 160 | syntax.parse(atrule.params, { 161 | atrule: 'unknown', // to use default parsing rules 162 | context: 'atrulePrelude' 163 | }); 164 | } catch (e) { 165 | if (e.type === 'PreprocessorExtensionError') { 166 | return; 167 | } 168 | } 169 | } 170 | 171 | message = messages.invalidPrelude(atrule.name); 172 | index += error.mismatchOffset; 173 | } else { 174 | message = messages.csstree(message); 175 | } 176 | 177 | utils.report({ 178 | ruleName, 179 | result, 180 | message, 181 | node: atrule, 182 | index 183 | }); 184 | } 185 | }); 186 | 187 | root.walkDecls((decl) => { 188 | // don't check for descriptors in bad at-rules 189 | if (ignoreAtruleNodes.has(decl.parent)) { 190 | return; 191 | } 192 | 193 | // ignore properties from ignore list 194 | if (ignoreProperties !== false && ignoreProperties(decl.prop)) { 195 | return; 196 | } 197 | 198 | // ignore declarations with non-standard syntax (Less, Sass, etc) 199 | if (syntax !== syntaxExtensions.none) { 200 | if (!isStandardSyntaxDeclaration(decl) || 201 | !isStandardSyntaxProperty(decl.prop) || 202 | !isStandardSyntaxValue(decl.value)) { 203 | return; 204 | } 205 | } 206 | 207 | try { 208 | syntax.parse(decl.value, { 209 | context: 'value' 210 | }); 211 | } catch (e) { 212 | // ignore values with preprocessor's extensions 213 | if (e.type === 'PreprocessorExtensionError') { 214 | return; 215 | } 216 | 217 | // ignore values by a pattern 218 | if (ignoreValue && ignoreValue.test(decl.value)) { 219 | return; 220 | } 221 | 222 | return utils.report({ 223 | message: messages.parseError(decl.value), 224 | node: decl, 225 | result, 226 | ruleName 227 | }); 228 | } 229 | 230 | const { error } = decl.parent.type === 'atrule' 231 | ? lexer.matchAtruleDescriptor(decl.parent.name, decl.prop, decl.value) 232 | : lexer.matchProperty(decl.prop, decl.value); 233 | 234 | if (error) { 235 | let message = error.rawMessage || error.message || error; 236 | let index = undefined; 237 | 238 | // ignore errors except those which make sense 239 | if (error.name !== 'SyntaxMatchError' && 240 | error.name !== 'SyntaxReferenceError') { 241 | return; 242 | } 243 | 244 | if (message === 'Mismatch') { 245 | // ignore values by a pattern 246 | if (ignoreValue && ignoreValue.test(decl.value)) { 247 | return; 248 | } 249 | 250 | message = messages.invalidValue(decl.prop); 251 | index = decl.prop.length + getRaw(decl, 'between').length + error.mismatchOffset; 252 | } else { 253 | message = messages.csstree(message); 254 | } 255 | 256 | utils.report({ 257 | ruleName, 258 | result, 259 | message, 260 | node: decl, 261 | index 262 | }); 263 | } 264 | }); 265 | }; 266 | }); 267 | 268 | export default Object.assign(plugin, { 269 | ruleName, 270 | messages 271 | }); 272 | -------------------------------------------------------------------------------- /lib/syntax-extension/index.js: -------------------------------------------------------------------------------- 1 | export { default as less } from './less/index.js'; 2 | export { default as sass } from './sass/index.js'; 3 | -------------------------------------------------------------------------------- /lib/syntax-extension/less/LessEscaping.js: -------------------------------------------------------------------------------- 1 | import { tokenTypes } from 'css-tree'; 2 | 3 | const STRING = tokenTypes.String; 4 | const TILDE = 0x007E; // U+007E TILDE (~) 5 | 6 | export const name = 'LessEscaping'; 7 | export const structure = { 8 | value: 'String' 9 | }; 10 | export function parse() { 11 | const start = this.tokenStart; 12 | 13 | this.eatDelim(TILDE); 14 | 15 | return { 16 | type: 'LessEscaping', 17 | loc: this.getLocation(start, this.tokenEnd), 18 | value: this.consume(STRING) 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /lib/syntax-extension/less/LessNamespace.js: -------------------------------------------------------------------------------- 1 | import { tokenTypes } from 'css-tree'; 2 | 3 | const HASH = tokenTypes.Hash; 4 | const FUNCTION = tokenTypes.Function; 5 | const IDENT = tokenTypes.Ident; 6 | const FULLSTOP = 0x002E; // U+002E FULL STOP (.) 7 | const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>) 8 | 9 | function consumeRaw() { 10 | return this.createSingleNodeList( 11 | this.Raw(this.tokenIndex, null, false) 12 | ); 13 | } 14 | 15 | export const name = 'LessNamespace'; 16 | export const structure = { 17 | name: 'Identifier', 18 | member: ['Function', 'Identifier'] 19 | }; 20 | export function parse() { 21 | const start = this.tokenStart; 22 | const name = this.consume(HASH).substr(1); 23 | let member; 24 | 25 | this.skipSC(); // deprecated 26 | 27 | 28 | // deprecated 29 | if (this.isDelim(GREATERTHANSIGN)) { 30 | this.next(); 31 | this.skipSC(); 32 | } 33 | 34 | this.eatDelim(FULLSTOP); 35 | 36 | switch (this.tokenType) { 37 | case FUNCTION: 38 | member = this.Function(consumeRaw, this.scope.Value); 39 | break; 40 | 41 | case IDENT: 42 | member = this.Identifier(); 43 | break; 44 | 45 | default: 46 | this.error('Function or ident expected'); 47 | } 48 | 49 | return { 50 | type: 'LessNamespace', 51 | loc: this.getLocation(start, this.tokenEnd), 52 | name, 53 | member 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /lib/syntax-extension/less/LessVariable.js: -------------------------------------------------------------------------------- 1 | import { tokenTypes } from 'css-tree'; 2 | 3 | const ATKEYWORD = tokenTypes.AtKeyword; 4 | 5 | export const name = 'LessVariable'; 6 | export const structure = { 7 | name: 'Identifier' 8 | }; 9 | export function parse() { 10 | const start = this.tokenStart; 11 | 12 | this.eat(ATKEYWORD); 13 | 14 | return { 15 | type: 'LessVariable', 16 | loc: this.getLocation(start, this.tokenEnd), 17 | name: this.substrToCursor(start + 1) 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /lib/syntax-extension/less/LessVariableReference.js: -------------------------------------------------------------------------------- 1 | import { tokenTypes } from 'css-tree'; 2 | 3 | const ATRULE = tokenTypes.AtKeyword; 4 | const COMMERCIALAT = 0x0040; // U+0040 COMMERCIAL AT (@) 5 | 6 | export const name = 'LessVariableReference'; 7 | export const structure = { 8 | name: 'Identifier' 9 | }; 10 | export function parse() { 11 | const start = this.tokenStart; 12 | 13 | this.eatDelim(COMMERCIALAT); 14 | this.eat(ATRULE); 15 | 16 | return { 17 | type: 'LessVariableReference', 18 | loc: this.getLocation(start, this.tokenEnd), 19 | name: this.substrToCursor(start + 2) 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /lib/syntax-extension/less/index.js: -------------------------------------------------------------------------------- 1 | import { tokenTypes as TYPE } from 'css-tree'; 2 | import * as LessVariableReference from './LessVariableReference.js'; 3 | import * as LessVariable from './LessVariable.js'; 4 | import * as LessEscaping from './LessEscaping.js'; 5 | import * as LessNamespace from './LessNamespace.js'; 6 | 7 | const FULLSTOP = 0x002E; // U+002E FULL STOP (.) 8 | const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>) 9 | const COMMERCIALAT = 0x0040; // U+0040 COMMERCIAL AT (@) 10 | const TILDE = 0x007E; // U+007E TILDE (~) 11 | 12 | // custom error 13 | class PreprocessorExtensionError { 14 | constructor() { 15 | this.type = 'PreprocessorExtensionError'; 16 | } 17 | } 18 | 19 | function throwOnSyntaxExtension() { 20 | let node = null; 21 | 22 | switch (this.tokenType) { 23 | case TYPE.AtKeyword: // less: @var 24 | node = this.LessVariable(); 25 | break; 26 | 27 | case TYPE.Hash: { 28 | let sc = 0; 29 | let tokenType = 0; 30 | 31 | // deprecated 32 | do { 33 | tokenType = this.lookupType(++sc); 34 | if (tokenType !== TYPE.WhiteSpace && tokenType !== TYPE.Comment) { 35 | break; 36 | } 37 | } while (tokenType !== TYPE.EOF); 38 | 39 | if (this.isDelim(FULLSTOP, sc) || /* preferred */ 40 | this.isDelim(GREATERTHANSIGN, sc) /* deprecated */) { 41 | node = this.LessNamespace(); 42 | } 43 | 44 | break; 45 | } 46 | 47 | case TYPE.Delim: 48 | switch (this.source.charCodeAt(this.tokenStart)) { 49 | case COMMERCIALAT: // less: @@var 50 | if (this.lookupType(1) === TYPE.AtKeyword) { 51 | node = this.LessVariableReference(); 52 | } 53 | break; 54 | 55 | case TILDE: // less: ~"asd" | ~'asd' 56 | node = this.LessEscaping(); 57 | break; 58 | 59 | 60 | } 61 | 62 | break; 63 | } 64 | 65 | // currently we can't validate values that contain less/sass extensions 66 | if (node !== null) { 67 | throw new PreprocessorExtensionError(); 68 | } 69 | } 70 | 71 | export default function less(syntaxConfig) { 72 | // new node types 73 | syntaxConfig.node.LessVariableReference = LessVariableReference; 74 | syntaxConfig.node.LessVariable = LessVariable; 75 | syntaxConfig.node.LessEscaping = LessEscaping; 76 | syntaxConfig.node.LessNamespace = LessNamespace; 77 | 78 | // custom at-rules 79 | syntaxConfig.atrules.plugin = { 80 | prelude: '' 81 | }; 82 | 83 | // extend parser's at-rule preluder parser 84 | const originalAttrulePreludeGetNode = syntaxConfig.scope.AtrulePrelude.getNode; 85 | syntaxConfig.scope.AtrulePrelude.getNode = function(context) { 86 | throwOnSyntaxExtension.call(this); 87 | 88 | return originalAttrulePreludeGetNode.call(this, context); 89 | }; 90 | 91 | // extend parser's value parser 92 | const originalValueGetNode = syntaxConfig.scope.Value.getNode; 93 | syntaxConfig.scope.Value.getNode = function(context) { 94 | throwOnSyntaxExtension.call(this); 95 | 96 | return originalValueGetNode.call(this, context); 97 | }; 98 | 99 | return syntaxConfig; 100 | } 101 | -------------------------------------------------------------------------------- /lib/syntax-extension/sass/SassInterpolation.js: -------------------------------------------------------------------------------- 1 | import { List, tokenTypes } from 'css-tree'; 2 | 3 | const LEFTCURLYBRACKET = tokenTypes.LeftCurlyBracket; 4 | const RIGHTCURLYBRACKET = tokenTypes.RightCurlyBracket; 5 | const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) 6 | 7 | export const name = 'SassInterpolation'; 8 | export const structure = { 9 | children: [[]] 10 | }; 11 | export function parse(recognizer, readSequence) { 12 | const start = this.tokenStart; 13 | let children = new List(); 14 | 15 | this.eatDelim(NUMBERSIGN); 16 | this.eat(LEFTCURLYBRACKET); 17 | children = readSequence.call(this, recognizer); 18 | this.eat(RIGHTCURLYBRACKET); 19 | 20 | return { 21 | type: 'SassInterpolation', 22 | loc: this.getLocation(start, this.tokenStart), 23 | children 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /lib/syntax-extension/sass/SassNamespace.js: -------------------------------------------------------------------------------- 1 | import { tokenTypes } from 'css-tree'; 2 | 3 | const FUNCTION = tokenTypes.Function; 4 | const IDENT = tokenTypes.Ident; 5 | const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($) 6 | const FULLSTOP = 0x002E; // U+002E FULL STOP (.) 7 | 8 | function consumeRaw() { 9 | return this.createSingleNodeList( 10 | this.Raw(this.tokenIndex, null, false) 11 | ); 12 | } 13 | 14 | export const name = 'SassNamespace'; 15 | export const structure = { 16 | name: 'Identifier', 17 | member: ['Function', 'Ident'] 18 | }; 19 | export function parse() { 20 | const start = this.tokenStart; 21 | const name = this.consume(IDENT); 22 | let member; 23 | 24 | this.eatDelim(FULLSTOP); 25 | 26 | switch (this.tokenType) { 27 | case FUNCTION: 28 | member = this.Function(consumeRaw, this.scope.Value); 29 | break; 30 | 31 | default: 32 | if (this.isDelim(DOLLARSIGN)) { 33 | member = this.SassVariable(); 34 | } else { 35 | this.error('Function or ident expected'); 36 | } 37 | } 38 | 39 | return { 40 | type: 'SassNamespace', 41 | loc: this.getLocation(start, this.tokenEnd), 42 | name, 43 | member 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /lib/syntax-extension/sass/SassVariable.js: -------------------------------------------------------------------------------- 1 | import { tokenTypes } from 'css-tree'; 2 | const IDENT = tokenTypes.Ident; 3 | const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($) 4 | 5 | export const name = 'SassVariable'; 6 | export const structure = { 7 | name: 'Identifier' 8 | }; 9 | export function parse() { 10 | const start = this.tokenStart; 11 | 12 | this.eatDelim(DOLLARSIGN); 13 | 14 | return { 15 | type: 'SassVariable', 16 | loc: this.getLocation(start, this.tokenEnd), 17 | name: this.consume(IDENT) 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /lib/syntax-extension/sass/index.js: -------------------------------------------------------------------------------- 1 | import { tokenTypes as TYPE } from 'css-tree'; 2 | import * as SassVariable from './SassVariable.js'; 3 | import * as SassInterpolation from './SassInterpolation.js'; 4 | import * as SassNamespace from './SassNamespace.js'; 5 | 6 | const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#) 7 | const DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($) 8 | const PERCENTAGESIGN = 0x0025; // U+0025 PERCENTAGE SIGN (%) 9 | const FULLSTOP = 0x002E; // U+002E FULL STOP (.) 10 | 11 | // custom error 12 | class PreprocessorExtensionError { 13 | constructor() { 14 | this.type = 'PreprocessorExtensionError'; 15 | } 16 | } 17 | 18 | function throwOnSyntaxExtension() { 19 | let node = null; 20 | 21 | switch (this.tokenType) { 22 | case TYPE.Ident: 23 | if (this.isDelim(FULLSTOP, 1)) { 24 | node = this.SassNamespace(); 25 | } 26 | break; 27 | 28 | case TYPE.Delim: 29 | switch (this.source.charCodeAt(this.tokenStart)) { 30 | case DOLLARSIGN: // sass: $var 31 | node = this.SassVariable(); 32 | break; 33 | 34 | case NUMBERSIGN: // sass: #{ } 35 | if (this.lookupType(1) === TYPE.LeftCurlyBracket) { 36 | node = this.SassInterpolation(this.scope.Value, this.readSequence); 37 | } 38 | break; 39 | 40 | case PERCENTAGESIGN: // sass: 5 % 4 41 | node = this.Operator(); 42 | break; 43 | } 44 | break; 45 | } 46 | 47 | // currently we can't validate values that contain less/sass extensions 48 | if (node !== null) { 49 | throw new PreprocessorExtensionError(); 50 | } 51 | } 52 | 53 | export default function sass(syntaxConfig) { 54 | // new node types 55 | syntaxConfig.node.SassVariable = SassVariable; 56 | syntaxConfig.node.SassInterpolation = SassInterpolation; 57 | syntaxConfig.node.SassNamespace = SassNamespace; 58 | 59 | // custom at-rules 60 | syntaxConfig.atrules['at-root'] = { 61 | prelude: '' 62 | }; 63 | syntaxConfig.atrules.content = { 64 | prelude: '' 65 | }; 66 | syntaxConfig.atrules.debug = { 67 | prelude: '' 68 | }; 69 | syntaxConfig.atrules.each = { 70 | prelude: '' 71 | }; 72 | syntaxConfig.atrules.else = { 73 | prelude: '?' 74 | }; 75 | syntaxConfig.atrules.error = { 76 | prelude: '' 77 | }; 78 | syntaxConfig.atrules.extend = { 79 | prelude: '' 80 | }; 81 | syntaxConfig.atrules.for = { 82 | prelude: '' 83 | }; 84 | syntaxConfig.atrules.forward = { 85 | prelude: '' 86 | }; 87 | syntaxConfig.atrules.function = { 88 | prelude: '' 89 | }; 90 | syntaxConfig.atrules.if = { 91 | prelude: '' 92 | }; 93 | syntaxConfig.atrules.import = { 94 | prelude: syntaxConfig.atrules.import.prelude + '| #' // FIXME: fix prelude extension in css-tree 95 | }; 96 | syntaxConfig.atrules.include = { 97 | prelude: '' 98 | }; 99 | syntaxConfig.atrules.mixin = { 100 | prelude: '' 101 | }; 102 | syntaxConfig.atrules.return = { 103 | prelude: '' 104 | }; 105 | syntaxConfig.atrules.use = { 106 | prelude: '' 107 | }; 108 | syntaxConfig.atrules.warn = { 109 | prelude: '' 110 | }; 111 | syntaxConfig.atrules.while = { 112 | prelude: '' 113 | }; 114 | 115 | // extend parser's at-rule preluder parser 116 | const originalAttrulePreludeGetNode = syntaxConfig.scope.AtrulePrelude.getNode; 117 | syntaxConfig.scope.AtrulePrelude.getNode = function(context) { 118 | throwOnSyntaxExtension.call(this); 119 | 120 | return originalAttrulePreludeGetNode.call(this, context); 121 | }; 122 | 123 | // extend parser's value parser 124 | const originalValueGetNode = syntaxConfig.scope.Value.getNode; 125 | syntaxConfig.scope.Value.getNode = function(context) { 126 | throwOnSyntaxExtension.call(this); 127 | 128 | return originalValueGetNode.call(this, context); 129 | }; 130 | 131 | return syntaxConfig; 132 | }; 133 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stylelint-csstree-validator", 3 | "version": "3.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.22.5", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", 10 | "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.22.5" 14 | } 15 | }, 16 | "@babel/helper-validator-identifier": { 17 | "version": "7.22.5", 18 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", 19 | "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", 20 | "dev": true 21 | }, 22 | "@babel/highlight": { 23 | "version": "7.22.5", 24 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", 25 | "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", 26 | "dev": true, 27 | "requires": { 28 | "@babel/helper-validator-identifier": "^7.22.5", 29 | "chalk": "^2.0.0", 30 | "js-tokens": "^4.0.0" 31 | }, 32 | "dependencies": { 33 | "ansi-styles": { 34 | "version": "3.2.1", 35 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 36 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 37 | "dev": true, 38 | "requires": { 39 | "color-convert": "^1.9.0" 40 | } 41 | }, 42 | "chalk": { 43 | "version": "2.4.2", 44 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 45 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 46 | "dev": true, 47 | "requires": { 48 | "ansi-styles": "^3.2.1", 49 | "escape-string-regexp": "^1.0.5", 50 | "supports-color": "^5.3.0" 51 | } 52 | }, 53 | "color-convert": { 54 | "version": "1.9.3", 55 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 56 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 57 | "dev": true, 58 | "requires": { 59 | "color-name": "1.1.3" 60 | } 61 | }, 62 | "color-name": { 63 | "version": "1.1.3", 64 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 65 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", 66 | "dev": true 67 | }, 68 | "escape-string-regexp": { 69 | "version": "1.0.5", 70 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 71 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", 72 | "dev": true 73 | }, 74 | "has-flag": { 75 | "version": "3.0.0", 76 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 77 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", 78 | "dev": true 79 | }, 80 | "supports-color": { 81 | "version": "5.5.0", 82 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 83 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 84 | "dev": true, 85 | "requires": { 86 | "has-flag": "^3.0.0" 87 | } 88 | } 89 | } 90 | }, 91 | "@bcoe/v8-coverage": { 92 | "version": "0.2.3", 93 | "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", 94 | "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", 95 | "dev": true 96 | }, 97 | "@csstools/css-parser-algorithms": { 98 | "version": "2.2.0", 99 | "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.2.0.tgz", 100 | "integrity": "sha512-9BoQ/jSrPq4vv3b9jjLW+PNNv56KlDH5JMx5yASSNrCtvq70FCNZUjXRvbCeR9hYj9ZyhURtqpU/RFIgg6kiOw==", 101 | "dev": true 102 | }, 103 | "@csstools/css-tokenizer": { 104 | "version": "2.1.1", 105 | "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.1.1.tgz", 106 | "integrity": "sha512-GbrTj2Z8MCTUv+52GE0RbFGM527xuXZ0Xa5g0Z+YN573uveS4G0qi6WNOMyz3yrFM/jaILTTwJ0+umx81EzqfA==", 107 | "dev": true 108 | }, 109 | "@csstools/media-query-list-parser": { 110 | "version": "2.1.0", 111 | "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.0.tgz", 112 | "integrity": "sha512-MXkR+TeaS2q9IkpyO6jVCdtA/bfpABJxIrfkLswThFN8EZZgI2RfAHhm6sDNDuYV25d5+b8Lj1fpTccIcSLPsQ==", 113 | "dev": true 114 | }, 115 | "@csstools/selector-specificity": { 116 | "version": "2.2.0", 117 | "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", 118 | "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", 119 | "dev": true 120 | }, 121 | "@eslint-community/eslint-utils": { 122 | "version": "4.4.0", 123 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", 124 | "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", 125 | "dev": true, 126 | "requires": { 127 | "eslint-visitor-keys": "^3.3.0" 128 | } 129 | }, 130 | "@eslint-community/regexpp": { 131 | "version": "4.5.1", 132 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", 133 | "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", 134 | "dev": true 135 | }, 136 | "@eslint/eslintrc": { 137 | "version": "2.0.3", 138 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", 139 | "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", 140 | "dev": true, 141 | "requires": { 142 | "ajv": "^6.12.4", 143 | "debug": "^4.3.2", 144 | "espree": "^9.5.2", 145 | "globals": "^13.19.0", 146 | "ignore": "^5.2.0", 147 | "import-fresh": "^3.2.1", 148 | "js-yaml": "^4.1.0", 149 | "minimatch": "^3.1.2", 150 | "strip-json-comments": "^3.1.1" 151 | } 152 | }, 153 | "@eslint/js": { 154 | "version": "8.42.0", 155 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz", 156 | "integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==", 157 | "dev": true 158 | }, 159 | "@humanwhocodes/config-array": { 160 | "version": "0.11.10", 161 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", 162 | "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", 163 | "dev": true, 164 | "requires": { 165 | "@humanwhocodes/object-schema": "^1.2.1", 166 | "debug": "^4.1.1", 167 | "minimatch": "^3.0.5" 168 | } 169 | }, 170 | "@humanwhocodes/module-importer": { 171 | "version": "1.0.1", 172 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 173 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 174 | "dev": true 175 | }, 176 | "@humanwhocodes/object-schema": { 177 | "version": "1.2.1", 178 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", 179 | "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", 180 | "dev": true 181 | }, 182 | "@istanbuljs/schema": { 183 | "version": "0.1.3", 184 | "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", 185 | "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", 186 | "dev": true 187 | }, 188 | "@jridgewell/resolve-uri": { 189 | "version": "3.1.0", 190 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", 191 | "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", 192 | "dev": true 193 | }, 194 | "@jridgewell/sourcemap-codec": { 195 | "version": "1.4.14", 196 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", 197 | "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", 198 | "dev": true 199 | }, 200 | "@jridgewell/trace-mapping": { 201 | "version": "0.3.18", 202 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", 203 | "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", 204 | "dev": true, 205 | "requires": { 206 | "@jridgewell/resolve-uri": "3.1.0", 207 | "@jridgewell/sourcemap-codec": "1.4.14" 208 | } 209 | }, 210 | "@nodelib/fs.scandir": { 211 | "version": "2.1.5", 212 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 213 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 214 | "dev": true, 215 | "requires": { 216 | "@nodelib/fs.stat": "2.0.5", 217 | "run-parallel": "^1.1.9" 218 | } 219 | }, 220 | "@nodelib/fs.stat": { 221 | "version": "2.0.5", 222 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 223 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 224 | "dev": true 225 | }, 226 | "@nodelib/fs.walk": { 227 | "version": "1.2.8", 228 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 229 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 230 | "dev": true, 231 | "requires": { 232 | "@nodelib/fs.scandir": "2.1.5", 233 | "fastq": "^1.6.0" 234 | } 235 | }, 236 | "@types/istanbul-lib-coverage": { 237 | "version": "2.0.4", 238 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", 239 | "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", 240 | "dev": true 241 | }, 242 | "@types/minimist": { 243 | "version": "1.2.2", 244 | "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", 245 | "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", 246 | "dev": true 247 | }, 248 | "@types/normalize-package-data": { 249 | "version": "2.4.1", 250 | "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", 251 | "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", 252 | "dev": true 253 | }, 254 | "acorn": { 255 | "version": "8.8.2", 256 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", 257 | "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", 258 | "dev": true 259 | }, 260 | "acorn-jsx": { 261 | "version": "5.3.2", 262 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 263 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 264 | "dev": true 265 | }, 266 | "ajv": { 267 | "version": "6.12.6", 268 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 269 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 270 | "dev": true, 271 | "requires": { 272 | "fast-deep-equal": "^3.1.1", 273 | "fast-json-stable-stringify": "^2.0.0", 274 | "json-schema-traverse": "^0.4.1", 275 | "uri-js": "^4.2.2" 276 | } 277 | }, 278 | "ansi-colors": { 279 | "version": "4.1.1", 280 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 281 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 282 | "dev": true 283 | }, 284 | "ansi-regex": { 285 | "version": "5.0.1", 286 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 287 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 288 | "dev": true 289 | }, 290 | "ansi-styles": { 291 | "version": "4.3.0", 292 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 293 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 294 | "dev": true, 295 | "requires": { 296 | "color-convert": "^2.0.1" 297 | } 298 | }, 299 | "anymatch": { 300 | "version": "3.1.3", 301 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 302 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 303 | "dev": true, 304 | "requires": { 305 | "normalize-path": "^3.0.0", 306 | "picomatch": "^2.0.4" 307 | } 308 | }, 309 | "argparse": { 310 | "version": "2.0.1", 311 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 312 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 313 | "dev": true 314 | }, 315 | "array-union": { 316 | "version": "2.1.0", 317 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", 318 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", 319 | "dev": true 320 | }, 321 | "arrify": { 322 | "version": "1.0.1", 323 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", 324 | "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", 325 | "dev": true 326 | }, 327 | "astral-regex": { 328 | "version": "2.0.0", 329 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", 330 | "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", 331 | "dev": true 332 | }, 333 | "balanced-match": { 334 | "version": "1.0.2", 335 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 336 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 337 | "dev": true 338 | }, 339 | "binary-extensions": { 340 | "version": "2.2.0", 341 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 342 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 343 | "dev": true 344 | }, 345 | "brace-expansion": { 346 | "version": "1.1.11", 347 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 348 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 349 | "dev": true, 350 | "requires": { 351 | "balanced-match": "^1.0.0", 352 | "concat-map": "0.0.1" 353 | } 354 | }, 355 | "braces": { 356 | "version": "3.0.2", 357 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 358 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 359 | "dev": true, 360 | "requires": { 361 | "fill-range": "^7.0.1" 362 | } 363 | }, 364 | "browser-stdout": { 365 | "version": "1.3.1", 366 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 367 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 368 | "dev": true 369 | }, 370 | "c8": { 371 | "version": "7.14.0", 372 | "resolved": "https://registry.npmjs.org/c8/-/c8-7.14.0.tgz", 373 | "integrity": "sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==", 374 | "dev": true, 375 | "requires": { 376 | "@bcoe/v8-coverage": "^0.2.3", 377 | "@istanbuljs/schema": "^0.1.3", 378 | "find-up": "^5.0.0", 379 | "foreground-child": "^2.0.0", 380 | "istanbul-lib-coverage": "^3.2.0", 381 | "istanbul-lib-report": "^3.0.0", 382 | "istanbul-reports": "^3.1.4", 383 | "rimraf": "^3.0.2", 384 | "test-exclude": "^6.0.0", 385 | "v8-to-istanbul": "^9.0.0", 386 | "yargs": "^16.2.0", 387 | "yargs-parser": "^20.2.9" 388 | } 389 | }, 390 | "callsites": { 391 | "version": "3.1.0", 392 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 393 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 394 | "dev": true 395 | }, 396 | "camelcase": { 397 | "version": "6.3.0", 398 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", 399 | "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", 400 | "dev": true 401 | }, 402 | "camelcase-keys": { 403 | "version": "6.2.2", 404 | "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", 405 | "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", 406 | "dev": true, 407 | "requires": { 408 | "camelcase": "^5.3.1", 409 | "map-obj": "^4.0.0", 410 | "quick-lru": "^4.0.1" 411 | }, 412 | "dependencies": { 413 | "camelcase": { 414 | "version": "5.3.1", 415 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 416 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 417 | "dev": true 418 | } 419 | } 420 | }, 421 | "chalk": { 422 | "version": "4.1.2", 423 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 424 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 425 | "dev": true, 426 | "requires": { 427 | "ansi-styles": "^4.1.0", 428 | "supports-color": "^7.1.0" 429 | } 430 | }, 431 | "chokidar": { 432 | "version": "3.5.3", 433 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 434 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 435 | "dev": true, 436 | "requires": { 437 | "anymatch": "~3.1.2", 438 | "braces": "~3.0.2", 439 | "fsevents": "~2.3.2", 440 | "glob-parent": "~5.1.2", 441 | "is-binary-path": "~2.1.0", 442 | "is-glob": "~4.0.1", 443 | "normalize-path": "~3.0.0", 444 | "readdirp": "~3.6.0" 445 | }, 446 | "dependencies": { 447 | "glob-parent": { 448 | "version": "5.1.2", 449 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 450 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 451 | "dev": true, 452 | "requires": { 453 | "is-glob": "^4.0.1" 454 | } 455 | } 456 | } 457 | }, 458 | "cliui": { 459 | "version": "7.0.4", 460 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 461 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 462 | "dev": true, 463 | "requires": { 464 | "string-width": "^4.2.0", 465 | "strip-ansi": "^6.0.0", 466 | "wrap-ansi": "^7.0.0" 467 | } 468 | }, 469 | "color-convert": { 470 | "version": "2.0.1", 471 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 472 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 473 | "dev": true, 474 | "requires": { 475 | "color-name": "~1.1.4" 476 | } 477 | }, 478 | "color-name": { 479 | "version": "1.1.4", 480 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 481 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 482 | "dev": true 483 | }, 484 | "colord": { 485 | "version": "2.9.3", 486 | "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", 487 | "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", 488 | "dev": true 489 | }, 490 | "concat-map": { 491 | "version": "0.0.1", 492 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 493 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 494 | "dev": true 495 | }, 496 | "convert-source-map": { 497 | "version": "1.9.0", 498 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", 499 | "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", 500 | "dev": true 501 | }, 502 | "cosmiconfig": { 503 | "version": "8.2.0", 504 | "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", 505 | "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", 506 | "dev": true, 507 | "requires": { 508 | "import-fresh": "^3.2.1", 509 | "js-yaml": "^4.1.0", 510 | "parse-json": "^5.0.0", 511 | "path-type": "^4.0.0" 512 | } 513 | }, 514 | "cross-spawn": { 515 | "version": "7.0.3", 516 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 517 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 518 | "dev": true, 519 | "requires": { 520 | "path-key": "^3.1.0", 521 | "shebang-command": "^2.0.0", 522 | "which": "^2.0.1" 523 | } 524 | }, 525 | "css-functions-list": { 526 | "version": "3.1.0", 527 | "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.1.0.tgz", 528 | "integrity": "sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w==", 529 | "dev": true 530 | }, 531 | "css-tree": { 532 | "version": "2.3.1", 533 | "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", 534 | "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", 535 | "requires": { 536 | "mdn-data": "2.0.30", 537 | "source-map-js": "^1.0.1" 538 | } 539 | }, 540 | "cssesc": { 541 | "version": "3.0.0", 542 | "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", 543 | "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", 544 | "dev": true 545 | }, 546 | "debug": { 547 | "version": "4.3.4", 548 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 549 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 550 | "dev": true, 551 | "requires": { 552 | "ms": "2.1.2" 553 | } 554 | }, 555 | "decamelize": { 556 | "version": "4.0.0", 557 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", 558 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", 559 | "dev": true 560 | }, 561 | "decamelize-keys": { 562 | "version": "1.1.1", 563 | "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", 564 | "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", 565 | "dev": true, 566 | "requires": { 567 | "decamelize": "^1.1.0", 568 | "map-obj": "^1.0.0" 569 | }, 570 | "dependencies": { 571 | "decamelize": { 572 | "version": "1.2.0", 573 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 574 | "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", 575 | "dev": true 576 | }, 577 | "map-obj": { 578 | "version": "1.0.1", 579 | "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", 580 | "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", 581 | "dev": true 582 | } 583 | } 584 | }, 585 | "deep-is": { 586 | "version": "0.1.4", 587 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 588 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 589 | "dev": true 590 | }, 591 | "diff": { 592 | "version": "5.0.0", 593 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", 594 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", 595 | "dev": true 596 | }, 597 | "dir-glob": { 598 | "version": "3.0.1", 599 | "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", 600 | "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", 601 | "dev": true, 602 | "requires": { 603 | "path-type": "^4.0.0" 604 | } 605 | }, 606 | "doctrine": { 607 | "version": "3.0.0", 608 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 609 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 610 | "dev": true, 611 | "requires": { 612 | "esutils": "^2.0.2" 613 | } 614 | }, 615 | "emoji-regex": { 616 | "version": "8.0.0", 617 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 618 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 619 | "dev": true 620 | }, 621 | "error-ex": { 622 | "version": "1.3.2", 623 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", 624 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", 625 | "dev": true, 626 | "requires": { 627 | "is-arrayish": "^0.2.1" 628 | } 629 | }, 630 | "escalade": { 631 | "version": "3.1.1", 632 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 633 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 634 | "dev": true 635 | }, 636 | "escape-string-regexp": { 637 | "version": "4.0.0", 638 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 639 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 640 | "dev": true 641 | }, 642 | "eslint": { 643 | "version": "8.42.0", 644 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", 645 | "integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==", 646 | "dev": true, 647 | "requires": { 648 | "@eslint-community/eslint-utils": "^4.2.0", 649 | "@eslint-community/regexpp": "^4.4.0", 650 | "@eslint/eslintrc": "^2.0.3", 651 | "@eslint/js": "8.42.0", 652 | "@humanwhocodes/config-array": "^0.11.10", 653 | "@humanwhocodes/module-importer": "^1.0.1", 654 | "@nodelib/fs.walk": "^1.2.8", 655 | "ajv": "^6.10.0", 656 | "chalk": "^4.0.0", 657 | "cross-spawn": "^7.0.2", 658 | "debug": "^4.3.2", 659 | "doctrine": "^3.0.0", 660 | "escape-string-regexp": "^4.0.0", 661 | "eslint-scope": "^7.2.0", 662 | "eslint-visitor-keys": "^3.4.1", 663 | "espree": "^9.5.2", 664 | "esquery": "^1.4.2", 665 | "esutils": "^2.0.2", 666 | "fast-deep-equal": "^3.1.3", 667 | "file-entry-cache": "^6.0.1", 668 | "find-up": "^5.0.0", 669 | "glob-parent": "^6.0.2", 670 | "globals": "^13.19.0", 671 | "graphemer": "^1.4.0", 672 | "ignore": "^5.2.0", 673 | "import-fresh": "^3.0.0", 674 | "imurmurhash": "^0.1.4", 675 | "is-glob": "^4.0.0", 676 | "is-path-inside": "^3.0.3", 677 | "js-yaml": "^4.1.0", 678 | "json-stable-stringify-without-jsonify": "^1.0.1", 679 | "levn": "^0.4.1", 680 | "lodash.merge": "^4.6.2", 681 | "minimatch": "^3.1.2", 682 | "natural-compare": "^1.4.0", 683 | "optionator": "^0.9.1", 684 | "strip-ansi": "^6.0.1", 685 | "strip-json-comments": "^3.1.0", 686 | "text-table": "^0.2.0" 687 | } 688 | }, 689 | "eslint-scope": { 690 | "version": "7.2.0", 691 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", 692 | "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", 693 | "dev": true, 694 | "requires": { 695 | "esrecurse": "^4.3.0", 696 | "estraverse": "^5.2.0" 697 | } 698 | }, 699 | "eslint-visitor-keys": { 700 | "version": "3.4.1", 701 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", 702 | "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", 703 | "dev": true 704 | }, 705 | "espree": { 706 | "version": "9.5.2", 707 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", 708 | "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", 709 | "dev": true, 710 | "requires": { 711 | "acorn": "^8.8.0", 712 | "acorn-jsx": "^5.3.2", 713 | "eslint-visitor-keys": "^3.4.1" 714 | } 715 | }, 716 | "esquery": { 717 | "version": "1.5.0", 718 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", 719 | "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", 720 | "dev": true, 721 | "requires": { 722 | "estraverse": "^5.1.0" 723 | } 724 | }, 725 | "esrecurse": { 726 | "version": "4.3.0", 727 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 728 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 729 | "dev": true, 730 | "requires": { 731 | "estraverse": "^5.2.0" 732 | } 733 | }, 734 | "estraverse": { 735 | "version": "5.3.0", 736 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 737 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 738 | "dev": true 739 | }, 740 | "esutils": { 741 | "version": "2.0.3", 742 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 743 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 744 | "dev": true 745 | }, 746 | "fast-deep-equal": { 747 | "version": "3.1.3", 748 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 749 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 750 | "dev": true 751 | }, 752 | "fast-glob": { 753 | "version": "3.2.12", 754 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", 755 | "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", 756 | "dev": true, 757 | "requires": { 758 | "@nodelib/fs.stat": "^2.0.2", 759 | "@nodelib/fs.walk": "^1.2.3", 760 | "glob-parent": "^5.1.2", 761 | "merge2": "^1.3.0", 762 | "micromatch": "^4.0.4" 763 | }, 764 | "dependencies": { 765 | "glob-parent": { 766 | "version": "5.1.2", 767 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 768 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 769 | "dev": true, 770 | "requires": { 771 | "is-glob": "^4.0.1" 772 | } 773 | } 774 | } 775 | }, 776 | "fast-json-stable-stringify": { 777 | "version": "2.1.0", 778 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 779 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 780 | "dev": true 781 | }, 782 | "fast-levenshtein": { 783 | "version": "2.0.6", 784 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 785 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 786 | "dev": true 787 | }, 788 | "fastest-levenshtein": { 789 | "version": "1.0.16", 790 | "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", 791 | "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", 792 | "dev": true 793 | }, 794 | "fastq": { 795 | "version": "1.15.0", 796 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", 797 | "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", 798 | "dev": true, 799 | "requires": { 800 | "reusify": "^1.0.4" 801 | } 802 | }, 803 | "file-entry-cache": { 804 | "version": "6.0.1", 805 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", 806 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", 807 | "dev": true, 808 | "requires": { 809 | "flat-cache": "^3.0.4" 810 | } 811 | }, 812 | "fill-range": { 813 | "version": "7.0.1", 814 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 815 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 816 | "dev": true, 817 | "requires": { 818 | "to-regex-range": "^5.0.1" 819 | } 820 | }, 821 | "find-up": { 822 | "version": "5.0.0", 823 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 824 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 825 | "dev": true, 826 | "requires": { 827 | "locate-path": "^6.0.0", 828 | "path-exists": "^4.0.0" 829 | } 830 | }, 831 | "flat": { 832 | "version": "5.0.2", 833 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 834 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 835 | "dev": true 836 | }, 837 | "flat-cache": { 838 | "version": "3.0.4", 839 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", 840 | "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", 841 | "dev": true, 842 | "requires": { 843 | "flatted": "^3.1.0", 844 | "rimraf": "^3.0.2" 845 | } 846 | }, 847 | "flatted": { 848 | "version": "3.2.7", 849 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", 850 | "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", 851 | "dev": true 852 | }, 853 | "foreground-child": { 854 | "version": "2.0.0", 855 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", 856 | "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", 857 | "dev": true, 858 | "requires": { 859 | "cross-spawn": "^7.0.0", 860 | "signal-exit": "^3.0.2" 861 | } 862 | }, 863 | "fs.realpath": { 864 | "version": "1.0.0", 865 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 866 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 867 | "dev": true 868 | }, 869 | "fsevents": { 870 | "version": "2.3.2", 871 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 872 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 873 | "dev": true, 874 | "optional": true 875 | }, 876 | "function-bind": { 877 | "version": "1.1.1", 878 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 879 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 880 | "dev": true 881 | }, 882 | "get-caller-file": { 883 | "version": "2.0.5", 884 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 885 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 886 | "dev": true 887 | }, 888 | "glob": { 889 | "version": "7.2.3", 890 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 891 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 892 | "dev": true, 893 | "requires": { 894 | "fs.realpath": "^1.0.0", 895 | "inflight": "^1.0.4", 896 | "inherits": "2", 897 | "minimatch": "^3.1.1", 898 | "once": "^1.3.0", 899 | "path-is-absolute": "^1.0.0" 900 | } 901 | }, 902 | "glob-parent": { 903 | "version": "6.0.2", 904 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 905 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 906 | "dev": true, 907 | "requires": { 908 | "is-glob": "^4.0.3" 909 | } 910 | }, 911 | "global-modules": { 912 | "version": "2.0.0", 913 | "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", 914 | "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", 915 | "dev": true, 916 | "requires": { 917 | "global-prefix": "^3.0.0" 918 | } 919 | }, 920 | "global-prefix": { 921 | "version": "3.0.0", 922 | "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", 923 | "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", 924 | "dev": true, 925 | "requires": { 926 | "ini": "^1.3.5", 927 | "kind-of": "^6.0.2", 928 | "which": "^1.3.1" 929 | }, 930 | "dependencies": { 931 | "which": { 932 | "version": "1.3.1", 933 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 934 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 935 | "dev": true, 936 | "requires": { 937 | "isexe": "^2.0.0" 938 | } 939 | } 940 | } 941 | }, 942 | "globals": { 943 | "version": "13.20.0", 944 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", 945 | "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", 946 | "dev": true, 947 | "requires": { 948 | "type-fest": "^0.20.2" 949 | } 950 | }, 951 | "globby": { 952 | "version": "11.1.0", 953 | "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", 954 | "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", 955 | "dev": true, 956 | "requires": { 957 | "array-union": "^2.1.0", 958 | "dir-glob": "^3.0.1", 959 | "fast-glob": "^3.2.9", 960 | "ignore": "^5.2.0", 961 | "merge2": "^1.4.1", 962 | "slash": "^3.0.0" 963 | } 964 | }, 965 | "globjoin": { 966 | "version": "0.1.4", 967 | "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", 968 | "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", 969 | "dev": true 970 | }, 971 | "graphemer": { 972 | "version": "1.4.0", 973 | "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", 974 | "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", 975 | "dev": true 976 | }, 977 | "hard-rejection": { 978 | "version": "2.1.0", 979 | "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", 980 | "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", 981 | "dev": true 982 | }, 983 | "has": { 984 | "version": "1.0.3", 985 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 986 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 987 | "dev": true, 988 | "requires": { 989 | "function-bind": "^1.1.1" 990 | } 991 | }, 992 | "has-flag": { 993 | "version": "4.0.0", 994 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 995 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 996 | "dev": true 997 | }, 998 | "he": { 999 | "version": "1.2.0", 1000 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 1001 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 1002 | "dev": true 1003 | }, 1004 | "hosted-git-info": { 1005 | "version": "4.1.0", 1006 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", 1007 | "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", 1008 | "dev": true, 1009 | "requires": { 1010 | "lru-cache": "^6.0.0" 1011 | } 1012 | }, 1013 | "html-escaper": { 1014 | "version": "2.0.2", 1015 | "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", 1016 | "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", 1017 | "dev": true 1018 | }, 1019 | "html-tags": { 1020 | "version": "3.3.1", 1021 | "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", 1022 | "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", 1023 | "dev": true 1024 | }, 1025 | "ignore": { 1026 | "version": "5.2.4", 1027 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", 1028 | "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", 1029 | "dev": true 1030 | }, 1031 | "import-fresh": { 1032 | "version": "3.3.0", 1033 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 1034 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 1035 | "dev": true, 1036 | "requires": { 1037 | "parent-module": "^1.0.0", 1038 | "resolve-from": "^4.0.0" 1039 | } 1040 | }, 1041 | "import-lazy": { 1042 | "version": "4.0.0", 1043 | "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", 1044 | "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", 1045 | "dev": true 1046 | }, 1047 | "imurmurhash": { 1048 | "version": "0.1.4", 1049 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1050 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 1051 | "dev": true 1052 | }, 1053 | "indent-string": { 1054 | "version": "4.0.0", 1055 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", 1056 | "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", 1057 | "dev": true 1058 | }, 1059 | "inflight": { 1060 | "version": "1.0.6", 1061 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1062 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 1063 | "dev": true, 1064 | "requires": { 1065 | "once": "^1.3.0", 1066 | "wrappy": "1" 1067 | } 1068 | }, 1069 | "inherits": { 1070 | "version": "2.0.4", 1071 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1072 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1073 | "dev": true 1074 | }, 1075 | "ini": { 1076 | "version": "1.3.8", 1077 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", 1078 | "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", 1079 | "dev": true 1080 | }, 1081 | "is-arrayish": { 1082 | "version": "0.2.1", 1083 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 1084 | "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", 1085 | "dev": true 1086 | }, 1087 | "is-binary-path": { 1088 | "version": "2.1.0", 1089 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 1090 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 1091 | "dev": true, 1092 | "requires": { 1093 | "binary-extensions": "^2.0.0" 1094 | } 1095 | }, 1096 | "is-core-module": { 1097 | "version": "2.12.1", 1098 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", 1099 | "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", 1100 | "dev": true, 1101 | "requires": { 1102 | "has": "^1.0.3" 1103 | } 1104 | }, 1105 | "is-extglob": { 1106 | "version": "2.1.1", 1107 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1108 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1109 | "dev": true 1110 | }, 1111 | "is-fullwidth-code-point": { 1112 | "version": "3.0.0", 1113 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1114 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1115 | "dev": true 1116 | }, 1117 | "is-glob": { 1118 | "version": "4.0.3", 1119 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1120 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1121 | "dev": true, 1122 | "requires": { 1123 | "is-extglob": "^2.1.1" 1124 | } 1125 | }, 1126 | "is-number": { 1127 | "version": "7.0.0", 1128 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1129 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1130 | "dev": true 1131 | }, 1132 | "is-path-inside": { 1133 | "version": "3.0.3", 1134 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", 1135 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", 1136 | "dev": true 1137 | }, 1138 | "is-plain-obj": { 1139 | "version": "2.1.0", 1140 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 1141 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 1142 | "dev": true 1143 | }, 1144 | "is-plain-object": { 1145 | "version": "5.0.0", 1146 | "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", 1147 | "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", 1148 | "dev": true 1149 | }, 1150 | "is-unicode-supported": { 1151 | "version": "0.1.0", 1152 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", 1153 | "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", 1154 | "dev": true 1155 | }, 1156 | "isexe": { 1157 | "version": "2.0.0", 1158 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1159 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1160 | "dev": true 1161 | }, 1162 | "istanbul-lib-coverage": { 1163 | "version": "3.2.0", 1164 | "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", 1165 | "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", 1166 | "dev": true 1167 | }, 1168 | "istanbul-lib-report": { 1169 | "version": "3.0.0", 1170 | "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", 1171 | "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", 1172 | "dev": true, 1173 | "requires": { 1174 | "istanbul-lib-coverage": "^3.0.0", 1175 | "make-dir": "^3.0.0", 1176 | "supports-color": "^7.1.0" 1177 | } 1178 | }, 1179 | "istanbul-reports": { 1180 | "version": "3.1.5", 1181 | "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", 1182 | "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", 1183 | "dev": true, 1184 | "requires": { 1185 | "html-escaper": "^2.0.0", 1186 | "istanbul-lib-report": "^3.0.0" 1187 | } 1188 | }, 1189 | "js-tokens": { 1190 | "version": "4.0.0", 1191 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1192 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 1193 | "dev": true 1194 | }, 1195 | "js-yaml": { 1196 | "version": "4.1.0", 1197 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 1198 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 1199 | "dev": true, 1200 | "requires": { 1201 | "argparse": "^2.0.1" 1202 | } 1203 | }, 1204 | "json-parse-even-better-errors": { 1205 | "version": "2.3.1", 1206 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", 1207 | "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", 1208 | "dev": true 1209 | }, 1210 | "json-schema-traverse": { 1211 | "version": "0.4.1", 1212 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1213 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1214 | "dev": true 1215 | }, 1216 | "json-stable-stringify-without-jsonify": { 1217 | "version": "1.0.1", 1218 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1219 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 1220 | "dev": true 1221 | }, 1222 | "kind-of": { 1223 | "version": "6.0.3", 1224 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", 1225 | "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", 1226 | "dev": true 1227 | }, 1228 | "known-css-properties": { 1229 | "version": "0.27.0", 1230 | "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.27.0.tgz", 1231 | "integrity": "sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg==", 1232 | "dev": true 1233 | }, 1234 | "levn": { 1235 | "version": "0.4.1", 1236 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 1237 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 1238 | "dev": true, 1239 | "requires": { 1240 | "prelude-ls": "^1.2.1", 1241 | "type-check": "~0.4.0" 1242 | } 1243 | }, 1244 | "lines-and-columns": { 1245 | "version": "1.2.4", 1246 | "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", 1247 | "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", 1248 | "dev": true 1249 | }, 1250 | "locate-path": { 1251 | "version": "6.0.0", 1252 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 1253 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 1254 | "dev": true, 1255 | "requires": { 1256 | "p-locate": "^5.0.0" 1257 | } 1258 | }, 1259 | "lodash.merge": { 1260 | "version": "4.6.2", 1261 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 1262 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 1263 | "dev": true 1264 | }, 1265 | "lodash.truncate": { 1266 | "version": "4.4.2", 1267 | "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", 1268 | "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", 1269 | "dev": true 1270 | }, 1271 | "log-symbols": { 1272 | "version": "4.1.0", 1273 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", 1274 | "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", 1275 | "dev": true, 1276 | "requires": { 1277 | "chalk": "^4.1.0", 1278 | "is-unicode-supported": "^0.1.0" 1279 | } 1280 | }, 1281 | "lru-cache": { 1282 | "version": "6.0.0", 1283 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1284 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 1285 | "dev": true, 1286 | "requires": { 1287 | "yallist": "^4.0.0" 1288 | } 1289 | }, 1290 | "make-dir": { 1291 | "version": "3.1.0", 1292 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", 1293 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", 1294 | "dev": true, 1295 | "requires": { 1296 | "semver": "^6.0.0" 1297 | } 1298 | }, 1299 | "map-obj": { 1300 | "version": "4.3.0", 1301 | "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", 1302 | "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", 1303 | "dev": true 1304 | }, 1305 | "mathml-tag-names": { 1306 | "version": "2.1.3", 1307 | "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", 1308 | "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", 1309 | "dev": true 1310 | }, 1311 | "mdn-data": { 1312 | "version": "2.0.30", 1313 | "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", 1314 | "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" 1315 | }, 1316 | "meow": { 1317 | "version": "9.0.0", 1318 | "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", 1319 | "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", 1320 | "dev": true, 1321 | "requires": { 1322 | "@types/minimist": "^1.2.0", 1323 | "camelcase-keys": "^6.2.2", 1324 | "decamelize": "^1.2.0", 1325 | "decamelize-keys": "^1.1.0", 1326 | "hard-rejection": "^2.1.0", 1327 | "minimist-options": "4.1.0", 1328 | "normalize-package-data": "^3.0.0", 1329 | "read-pkg-up": "^7.0.1", 1330 | "redent": "^3.0.0", 1331 | "trim-newlines": "^3.0.0", 1332 | "type-fest": "^0.18.0", 1333 | "yargs-parser": "^20.2.3" 1334 | }, 1335 | "dependencies": { 1336 | "decamelize": { 1337 | "version": "1.2.0", 1338 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 1339 | "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", 1340 | "dev": true 1341 | }, 1342 | "type-fest": { 1343 | "version": "0.18.1", 1344 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", 1345 | "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", 1346 | "dev": true 1347 | } 1348 | } 1349 | }, 1350 | "merge2": { 1351 | "version": "1.4.1", 1352 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 1353 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 1354 | "dev": true 1355 | }, 1356 | "micromatch": { 1357 | "version": "4.0.5", 1358 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 1359 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 1360 | "dev": true, 1361 | "requires": { 1362 | "braces": "^3.0.2", 1363 | "picomatch": "^2.3.1" 1364 | } 1365 | }, 1366 | "min-indent": { 1367 | "version": "1.0.1", 1368 | "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", 1369 | "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", 1370 | "dev": true 1371 | }, 1372 | "minimatch": { 1373 | "version": "3.1.2", 1374 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1375 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1376 | "dev": true, 1377 | "requires": { 1378 | "brace-expansion": "^1.1.7" 1379 | } 1380 | }, 1381 | "minimist-options": { 1382 | "version": "4.1.0", 1383 | "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", 1384 | "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", 1385 | "dev": true, 1386 | "requires": { 1387 | "arrify": "^1.0.1", 1388 | "is-plain-obj": "^1.1.0", 1389 | "kind-of": "^6.0.3" 1390 | }, 1391 | "dependencies": { 1392 | "is-plain-obj": { 1393 | "version": "1.1.0", 1394 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", 1395 | "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", 1396 | "dev": true 1397 | } 1398 | } 1399 | }, 1400 | "mocha": { 1401 | "version": "10.2.0", 1402 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", 1403 | "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", 1404 | "dev": true, 1405 | "requires": { 1406 | "ansi-colors": "4.1.1", 1407 | "browser-stdout": "1.3.1", 1408 | "chokidar": "3.5.3", 1409 | "debug": "4.3.4", 1410 | "diff": "5.0.0", 1411 | "escape-string-regexp": "4.0.0", 1412 | "find-up": "5.0.0", 1413 | "glob": "7.2.0", 1414 | "he": "1.2.0", 1415 | "js-yaml": "4.1.0", 1416 | "log-symbols": "4.1.0", 1417 | "minimatch": "5.0.1", 1418 | "ms": "2.1.3", 1419 | "nanoid": "3.3.3", 1420 | "serialize-javascript": "6.0.0", 1421 | "strip-json-comments": "3.1.1", 1422 | "supports-color": "8.1.1", 1423 | "workerpool": "6.2.1", 1424 | "yargs": "16.2.0", 1425 | "yargs-parser": "20.2.4", 1426 | "yargs-unparser": "2.0.0" 1427 | }, 1428 | "dependencies": { 1429 | "glob": { 1430 | "version": "7.2.0", 1431 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 1432 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 1433 | "dev": true, 1434 | "requires": { 1435 | "fs.realpath": "^1.0.0", 1436 | "inflight": "^1.0.4", 1437 | "inherits": "2", 1438 | "minimatch": "^3.0.4", 1439 | "once": "^1.3.0", 1440 | "path-is-absolute": "^1.0.0" 1441 | }, 1442 | "dependencies": { 1443 | "minimatch": { 1444 | "version": "3.1.2", 1445 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1446 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1447 | "dev": true, 1448 | "requires": { 1449 | "brace-expansion": "^1.1.7" 1450 | } 1451 | } 1452 | } 1453 | }, 1454 | "minimatch": { 1455 | "version": "5.0.1", 1456 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", 1457 | "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", 1458 | "dev": true, 1459 | "requires": { 1460 | "brace-expansion": "^2.0.1" 1461 | }, 1462 | "dependencies": { 1463 | "brace-expansion": { 1464 | "version": "2.0.1", 1465 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 1466 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 1467 | "dev": true, 1468 | "requires": { 1469 | "balanced-match": "^1.0.0" 1470 | } 1471 | } 1472 | } 1473 | }, 1474 | "ms": { 1475 | "version": "2.1.3", 1476 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1477 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1478 | "dev": true 1479 | }, 1480 | "supports-color": { 1481 | "version": "8.1.1", 1482 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 1483 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 1484 | "dev": true, 1485 | "requires": { 1486 | "has-flag": "^4.0.0" 1487 | } 1488 | }, 1489 | "yargs-parser": { 1490 | "version": "20.2.4", 1491 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", 1492 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", 1493 | "dev": true 1494 | } 1495 | } 1496 | }, 1497 | "ms": { 1498 | "version": "2.1.2", 1499 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1500 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1501 | "dev": true 1502 | }, 1503 | "nanoid": { 1504 | "version": "3.3.3", 1505 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", 1506 | "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", 1507 | "dev": true 1508 | }, 1509 | "natural-compare": { 1510 | "version": "1.4.0", 1511 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1512 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 1513 | "dev": true 1514 | }, 1515 | "normalize-package-data": { 1516 | "version": "3.0.3", 1517 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", 1518 | "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", 1519 | "dev": true, 1520 | "requires": { 1521 | "hosted-git-info": "^4.0.1", 1522 | "is-core-module": "^2.5.0", 1523 | "semver": "^7.3.4", 1524 | "validate-npm-package-license": "^3.0.1" 1525 | }, 1526 | "dependencies": { 1527 | "semver": { 1528 | "version": "7.5.1", 1529 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", 1530 | "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", 1531 | "dev": true, 1532 | "requires": { 1533 | "lru-cache": "^6.0.0" 1534 | } 1535 | } 1536 | } 1537 | }, 1538 | "normalize-path": { 1539 | "version": "3.0.0", 1540 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1541 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1542 | "dev": true 1543 | }, 1544 | "once": { 1545 | "version": "1.4.0", 1546 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1547 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1548 | "dev": true, 1549 | "requires": { 1550 | "wrappy": "1" 1551 | } 1552 | }, 1553 | "optionator": { 1554 | "version": "0.9.1", 1555 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", 1556 | "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", 1557 | "dev": true, 1558 | "requires": { 1559 | "deep-is": "^0.1.3", 1560 | "fast-levenshtein": "^2.0.6", 1561 | "levn": "^0.4.1", 1562 | "prelude-ls": "^1.2.1", 1563 | "type-check": "^0.4.0", 1564 | "word-wrap": "^1.2.3" 1565 | } 1566 | }, 1567 | "p-limit": { 1568 | "version": "3.1.0", 1569 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 1570 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 1571 | "dev": true, 1572 | "requires": { 1573 | "yocto-queue": "^0.1.0" 1574 | } 1575 | }, 1576 | "p-locate": { 1577 | "version": "5.0.0", 1578 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 1579 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 1580 | "dev": true, 1581 | "requires": { 1582 | "p-limit": "^3.0.2" 1583 | } 1584 | }, 1585 | "p-try": { 1586 | "version": "2.2.0", 1587 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 1588 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 1589 | "dev": true 1590 | }, 1591 | "parent-module": { 1592 | "version": "1.0.1", 1593 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1594 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1595 | "dev": true, 1596 | "requires": { 1597 | "callsites": "^3.0.0" 1598 | } 1599 | }, 1600 | "parse-json": { 1601 | "version": "5.2.0", 1602 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", 1603 | "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", 1604 | "dev": true, 1605 | "requires": { 1606 | "@babel/code-frame": "^7.0.0", 1607 | "error-ex": "^1.3.1", 1608 | "json-parse-even-better-errors": "^2.3.0", 1609 | "lines-and-columns": "^1.1.6" 1610 | } 1611 | }, 1612 | "path-exists": { 1613 | "version": "4.0.0", 1614 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1615 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1616 | "dev": true 1617 | }, 1618 | "path-is-absolute": { 1619 | "version": "1.0.1", 1620 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1621 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1622 | "dev": true 1623 | }, 1624 | "path-key": { 1625 | "version": "3.1.1", 1626 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1627 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1628 | "dev": true 1629 | }, 1630 | "path-parse": { 1631 | "version": "1.0.7", 1632 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1633 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1634 | "dev": true 1635 | }, 1636 | "path-type": { 1637 | "version": "4.0.0", 1638 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", 1639 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", 1640 | "dev": true 1641 | }, 1642 | "picocolors": { 1643 | "version": "1.0.0", 1644 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 1645 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 1646 | "dev": true 1647 | }, 1648 | "picomatch": { 1649 | "version": "2.3.1", 1650 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1651 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1652 | "dev": true 1653 | }, 1654 | "postcss": { 1655 | "version": "8.4.24", 1656 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", 1657 | "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", 1658 | "dev": true, 1659 | "requires": { 1660 | "nanoid": "^3.3.6", 1661 | "picocolors": "^1.0.0", 1662 | "source-map-js": "^1.0.2" 1663 | }, 1664 | "dependencies": { 1665 | "nanoid": { 1666 | "version": "3.3.6", 1667 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", 1668 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", 1669 | "dev": true 1670 | } 1671 | } 1672 | }, 1673 | "postcss-less": { 1674 | "version": "6.0.0", 1675 | "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-6.0.0.tgz", 1676 | "integrity": "sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==", 1677 | "dev": true 1678 | }, 1679 | "postcss-media-query-parser": { 1680 | "version": "0.2.3", 1681 | "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", 1682 | "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", 1683 | "dev": true 1684 | }, 1685 | "postcss-resolve-nested-selector": { 1686 | "version": "0.1.1", 1687 | "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", 1688 | "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", 1689 | "dev": true 1690 | }, 1691 | "postcss-safe-parser": { 1692 | "version": "6.0.0", 1693 | "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", 1694 | "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", 1695 | "dev": true 1696 | }, 1697 | "postcss-scss": { 1698 | "version": "4.0.6", 1699 | "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.6.tgz", 1700 | "integrity": "sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ==", 1701 | "dev": true 1702 | }, 1703 | "postcss-selector-parser": { 1704 | "version": "6.0.13", 1705 | "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", 1706 | "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", 1707 | "dev": true, 1708 | "requires": { 1709 | "cssesc": "^3.0.0", 1710 | "util-deprecate": "^1.0.2" 1711 | } 1712 | }, 1713 | "postcss-value-parser": { 1714 | "version": "4.2.0", 1715 | "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", 1716 | "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", 1717 | "dev": true 1718 | }, 1719 | "prelude-ls": { 1720 | "version": "1.2.1", 1721 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 1722 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 1723 | "dev": true 1724 | }, 1725 | "punycode": { 1726 | "version": "2.3.0", 1727 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", 1728 | "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", 1729 | "dev": true 1730 | }, 1731 | "queue-microtask": { 1732 | "version": "1.2.3", 1733 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 1734 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 1735 | "dev": true 1736 | }, 1737 | "quick-lru": { 1738 | "version": "4.0.1", 1739 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", 1740 | "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", 1741 | "dev": true 1742 | }, 1743 | "randombytes": { 1744 | "version": "2.1.0", 1745 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 1746 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 1747 | "dev": true, 1748 | "requires": { 1749 | "safe-buffer": "^5.1.0" 1750 | } 1751 | }, 1752 | "read-pkg": { 1753 | "version": "5.2.0", 1754 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", 1755 | "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", 1756 | "dev": true, 1757 | "requires": { 1758 | "@types/normalize-package-data": "^2.4.0", 1759 | "normalize-package-data": "^2.5.0", 1760 | "parse-json": "^5.0.0", 1761 | "type-fest": "^0.6.0" 1762 | }, 1763 | "dependencies": { 1764 | "hosted-git-info": { 1765 | "version": "2.8.9", 1766 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", 1767 | "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", 1768 | "dev": true 1769 | }, 1770 | "normalize-package-data": { 1771 | "version": "2.5.0", 1772 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", 1773 | "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", 1774 | "dev": true, 1775 | "requires": { 1776 | "hosted-git-info": "^2.1.4", 1777 | "resolve": "^1.10.0", 1778 | "semver": "2 || 3 || 4 || 5", 1779 | "validate-npm-package-license": "^3.0.1" 1780 | } 1781 | }, 1782 | "semver": { 1783 | "version": "5.7.1", 1784 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1785 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 1786 | "dev": true 1787 | }, 1788 | "type-fest": { 1789 | "version": "0.6.0", 1790 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", 1791 | "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", 1792 | "dev": true 1793 | } 1794 | } 1795 | }, 1796 | "read-pkg-up": { 1797 | "version": "7.0.1", 1798 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", 1799 | "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", 1800 | "dev": true, 1801 | "requires": { 1802 | "find-up": "^4.1.0", 1803 | "read-pkg": "^5.2.0", 1804 | "type-fest": "^0.8.1" 1805 | }, 1806 | "dependencies": { 1807 | "find-up": { 1808 | "version": "4.1.0", 1809 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", 1810 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", 1811 | "dev": true, 1812 | "requires": { 1813 | "locate-path": "^5.0.0", 1814 | "path-exists": "^4.0.0" 1815 | } 1816 | }, 1817 | "locate-path": { 1818 | "version": "5.0.0", 1819 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", 1820 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", 1821 | "dev": true, 1822 | "requires": { 1823 | "p-locate": "^4.1.0" 1824 | } 1825 | }, 1826 | "p-limit": { 1827 | "version": "2.3.0", 1828 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 1829 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 1830 | "dev": true, 1831 | "requires": { 1832 | "p-try": "^2.0.0" 1833 | } 1834 | }, 1835 | "p-locate": { 1836 | "version": "4.1.0", 1837 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", 1838 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", 1839 | "dev": true, 1840 | "requires": { 1841 | "p-limit": "^2.2.0" 1842 | } 1843 | }, 1844 | "type-fest": { 1845 | "version": "0.8.1", 1846 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 1847 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", 1848 | "dev": true 1849 | } 1850 | } 1851 | }, 1852 | "readdirp": { 1853 | "version": "3.6.0", 1854 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 1855 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 1856 | "dev": true, 1857 | "requires": { 1858 | "picomatch": "^2.2.1" 1859 | } 1860 | }, 1861 | "redent": { 1862 | "version": "3.0.0", 1863 | "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", 1864 | "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", 1865 | "dev": true, 1866 | "requires": { 1867 | "indent-string": "^4.0.0", 1868 | "strip-indent": "^3.0.0" 1869 | } 1870 | }, 1871 | "require-directory": { 1872 | "version": "2.1.1", 1873 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1874 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", 1875 | "dev": true 1876 | }, 1877 | "require-from-string": { 1878 | "version": "2.0.2", 1879 | "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", 1880 | "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", 1881 | "dev": true 1882 | }, 1883 | "resolve": { 1884 | "version": "1.22.2", 1885 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", 1886 | "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", 1887 | "dev": true, 1888 | "requires": { 1889 | "is-core-module": "^2.11.0", 1890 | "path-parse": "^1.0.7", 1891 | "supports-preserve-symlinks-flag": "^1.0.0" 1892 | } 1893 | }, 1894 | "resolve-from": { 1895 | "version": "4.0.0", 1896 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1897 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1898 | "dev": true 1899 | }, 1900 | "reusify": { 1901 | "version": "1.0.4", 1902 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 1903 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 1904 | "dev": true 1905 | }, 1906 | "rimraf": { 1907 | "version": "3.0.2", 1908 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 1909 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 1910 | "dev": true, 1911 | "requires": { 1912 | "glob": "^7.1.3" 1913 | } 1914 | }, 1915 | "rollup": { 1916 | "version": "2.79.1", 1917 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", 1918 | "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", 1919 | "dev": true, 1920 | "requires": { 1921 | "fsevents": "~2.3.2" 1922 | } 1923 | }, 1924 | "run-parallel": { 1925 | "version": "1.2.0", 1926 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1927 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1928 | "dev": true, 1929 | "requires": { 1930 | "queue-microtask": "^1.2.2" 1931 | } 1932 | }, 1933 | "safe-buffer": { 1934 | "version": "5.2.1", 1935 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1936 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1937 | "dev": true 1938 | }, 1939 | "semver": { 1940 | "version": "6.3.0", 1941 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 1942 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 1943 | "dev": true 1944 | }, 1945 | "serialize-javascript": { 1946 | "version": "6.0.0", 1947 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", 1948 | "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", 1949 | "dev": true, 1950 | "requires": { 1951 | "randombytes": "^2.1.0" 1952 | } 1953 | }, 1954 | "shebang-command": { 1955 | "version": "2.0.0", 1956 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1957 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1958 | "dev": true, 1959 | "requires": { 1960 | "shebang-regex": "^3.0.0" 1961 | } 1962 | }, 1963 | "shebang-regex": { 1964 | "version": "3.0.0", 1965 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1966 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1967 | "dev": true 1968 | }, 1969 | "signal-exit": { 1970 | "version": "3.0.7", 1971 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", 1972 | "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", 1973 | "dev": true 1974 | }, 1975 | "slash": { 1976 | "version": "3.0.0", 1977 | "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", 1978 | "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", 1979 | "dev": true 1980 | }, 1981 | "slice-ansi": { 1982 | "version": "4.0.0", 1983 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", 1984 | "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", 1985 | "dev": true, 1986 | "requires": { 1987 | "ansi-styles": "^4.0.0", 1988 | "astral-regex": "^2.0.0", 1989 | "is-fullwidth-code-point": "^3.0.0" 1990 | } 1991 | }, 1992 | "source-map-js": { 1993 | "version": "1.0.2", 1994 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 1995 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" 1996 | }, 1997 | "spdx-correct": { 1998 | "version": "3.2.0", 1999 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", 2000 | "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", 2001 | "dev": true, 2002 | "requires": { 2003 | "spdx-expression-parse": "^3.0.0", 2004 | "spdx-license-ids": "^3.0.0" 2005 | } 2006 | }, 2007 | "spdx-exceptions": { 2008 | "version": "2.3.0", 2009 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", 2010 | "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", 2011 | "dev": true 2012 | }, 2013 | "spdx-expression-parse": { 2014 | "version": "3.0.1", 2015 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", 2016 | "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", 2017 | "dev": true, 2018 | "requires": { 2019 | "spdx-exceptions": "^2.1.0", 2020 | "spdx-license-ids": "^3.0.0" 2021 | } 2022 | }, 2023 | "spdx-license-ids": { 2024 | "version": "3.0.13", 2025 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", 2026 | "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", 2027 | "dev": true 2028 | }, 2029 | "string-width": { 2030 | "version": "4.2.3", 2031 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2032 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2033 | "dev": true, 2034 | "requires": { 2035 | "emoji-regex": "^8.0.0", 2036 | "is-fullwidth-code-point": "^3.0.0", 2037 | "strip-ansi": "^6.0.1" 2038 | } 2039 | }, 2040 | "strip-ansi": { 2041 | "version": "6.0.1", 2042 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2043 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2044 | "dev": true, 2045 | "requires": { 2046 | "ansi-regex": "^5.0.1" 2047 | } 2048 | }, 2049 | "strip-indent": { 2050 | "version": "3.0.0", 2051 | "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", 2052 | "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", 2053 | "dev": true, 2054 | "requires": { 2055 | "min-indent": "^1.0.0" 2056 | } 2057 | }, 2058 | "strip-json-comments": { 2059 | "version": "3.1.1", 2060 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 2061 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 2062 | "dev": true 2063 | }, 2064 | "style-search": { 2065 | "version": "0.1.0", 2066 | "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", 2067 | "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", 2068 | "dev": true 2069 | }, 2070 | "stylelint": { 2071 | "version": "15.7.0", 2072 | "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.7.0.tgz", 2073 | "integrity": "sha512-fQRwHwWuZsDn4ENyE9AsKkOkV9WlD2CmYiVDbdZPdS3iZh0ceypOn1EuwTNuZ8xTrHF+jVeIEzLtFFSlD/nJHg==", 2074 | "dev": true, 2075 | "requires": { 2076 | "@csstools/css-parser-algorithms": "^2.2.0", 2077 | "@csstools/css-tokenizer": "^2.1.1", 2078 | "@csstools/media-query-list-parser": "^2.1.0", 2079 | "@csstools/selector-specificity": "^2.2.0", 2080 | "balanced-match": "^2.0.0", 2081 | "colord": "^2.9.3", 2082 | "cosmiconfig": "^8.2.0", 2083 | "css-functions-list": "^3.1.0", 2084 | "css-tree": "^2.3.1", 2085 | "debug": "^4.3.4", 2086 | "fast-glob": "^3.2.12", 2087 | "fastest-levenshtein": "^1.0.16", 2088 | "file-entry-cache": "^6.0.1", 2089 | "global-modules": "^2.0.0", 2090 | "globby": "^11.1.0", 2091 | "globjoin": "^0.1.4", 2092 | "html-tags": "^3.3.1", 2093 | "ignore": "^5.2.4", 2094 | "import-lazy": "^4.0.0", 2095 | "imurmurhash": "^0.1.4", 2096 | "is-plain-object": "^5.0.0", 2097 | "known-css-properties": "^0.27.0", 2098 | "mathml-tag-names": "^2.1.3", 2099 | "meow": "^9.0.0", 2100 | "micromatch": "^4.0.5", 2101 | "normalize-path": "^3.0.0", 2102 | "picocolors": "^1.0.0", 2103 | "postcss": "^8.4.24", 2104 | "postcss-media-query-parser": "^0.2.3", 2105 | "postcss-resolve-nested-selector": "^0.1.1", 2106 | "postcss-safe-parser": "^6.0.0", 2107 | "postcss-selector-parser": "^6.0.13", 2108 | "postcss-value-parser": "^4.2.0", 2109 | "resolve-from": "^5.0.0", 2110 | "string-width": "^4.2.3", 2111 | "strip-ansi": "^6.0.1", 2112 | "style-search": "^0.1.0", 2113 | "supports-hyperlinks": "^3.0.0", 2114 | "svg-tags": "^1.0.0", 2115 | "table": "^6.8.1", 2116 | "v8-compile-cache": "^2.3.0", 2117 | "write-file-atomic": "^5.0.1" 2118 | }, 2119 | "dependencies": { 2120 | "balanced-match": { 2121 | "version": "2.0.0", 2122 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", 2123 | "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", 2124 | "dev": true 2125 | }, 2126 | "resolve-from": { 2127 | "version": "5.0.0", 2128 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", 2129 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", 2130 | "dev": true 2131 | } 2132 | } 2133 | }, 2134 | "supports-color": { 2135 | "version": "7.2.0", 2136 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2137 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2138 | "dev": true, 2139 | "requires": { 2140 | "has-flag": "^4.0.0" 2141 | } 2142 | }, 2143 | "supports-hyperlinks": { 2144 | "version": "3.0.0", 2145 | "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", 2146 | "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", 2147 | "dev": true, 2148 | "requires": { 2149 | "has-flag": "^4.0.0", 2150 | "supports-color": "^7.0.0" 2151 | } 2152 | }, 2153 | "supports-preserve-symlinks-flag": { 2154 | "version": "1.0.0", 2155 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 2156 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 2157 | "dev": true 2158 | }, 2159 | "svg-tags": { 2160 | "version": "1.0.0", 2161 | "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", 2162 | "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", 2163 | "dev": true 2164 | }, 2165 | "table": { 2166 | "version": "6.8.1", 2167 | "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", 2168 | "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", 2169 | "dev": true, 2170 | "requires": { 2171 | "ajv": "^8.0.1", 2172 | "lodash.truncate": "^4.4.2", 2173 | "slice-ansi": "^4.0.0", 2174 | "string-width": "^4.2.3", 2175 | "strip-ansi": "^6.0.1" 2176 | }, 2177 | "dependencies": { 2178 | "ajv": { 2179 | "version": "8.12.0", 2180 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", 2181 | "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", 2182 | "dev": true, 2183 | "requires": { 2184 | "fast-deep-equal": "^3.1.1", 2185 | "json-schema-traverse": "^1.0.0", 2186 | "require-from-string": "^2.0.2", 2187 | "uri-js": "^4.2.2" 2188 | } 2189 | }, 2190 | "json-schema-traverse": { 2191 | "version": "1.0.0", 2192 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", 2193 | "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", 2194 | "dev": true 2195 | } 2196 | } 2197 | }, 2198 | "test-exclude": { 2199 | "version": "6.0.0", 2200 | "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", 2201 | "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", 2202 | "dev": true, 2203 | "requires": { 2204 | "@istanbuljs/schema": "^0.1.2", 2205 | "glob": "^7.1.4", 2206 | "minimatch": "^3.0.4" 2207 | } 2208 | }, 2209 | "text-table": { 2210 | "version": "0.2.0", 2211 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 2212 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", 2213 | "dev": true 2214 | }, 2215 | "to-regex-range": { 2216 | "version": "5.0.1", 2217 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2218 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2219 | "dev": true, 2220 | "requires": { 2221 | "is-number": "^7.0.0" 2222 | } 2223 | }, 2224 | "trim-newlines": { 2225 | "version": "3.0.1", 2226 | "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", 2227 | "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", 2228 | "dev": true 2229 | }, 2230 | "type-check": { 2231 | "version": "0.4.0", 2232 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 2233 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 2234 | "dev": true, 2235 | "requires": { 2236 | "prelude-ls": "^1.2.1" 2237 | } 2238 | }, 2239 | "type-fest": { 2240 | "version": "0.20.2", 2241 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 2242 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 2243 | "dev": true 2244 | }, 2245 | "uri-js": { 2246 | "version": "4.4.1", 2247 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 2248 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 2249 | "dev": true, 2250 | "requires": { 2251 | "punycode": "^2.1.0" 2252 | } 2253 | }, 2254 | "util-deprecate": { 2255 | "version": "1.0.2", 2256 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 2257 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 2258 | "dev": true 2259 | }, 2260 | "v8-compile-cache": { 2261 | "version": "2.3.0", 2262 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", 2263 | "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", 2264 | "dev": true 2265 | }, 2266 | "v8-to-istanbul": { 2267 | "version": "9.1.0", 2268 | "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", 2269 | "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", 2270 | "dev": true, 2271 | "requires": { 2272 | "@jridgewell/trace-mapping": "^0.3.12", 2273 | "@types/istanbul-lib-coverage": "^2.0.1", 2274 | "convert-source-map": "^1.6.0" 2275 | } 2276 | }, 2277 | "validate-npm-package-license": { 2278 | "version": "3.0.4", 2279 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", 2280 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", 2281 | "dev": true, 2282 | "requires": { 2283 | "spdx-correct": "^3.0.0", 2284 | "spdx-expression-parse": "^3.0.0" 2285 | } 2286 | }, 2287 | "which": { 2288 | "version": "2.0.2", 2289 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2290 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2291 | "dev": true, 2292 | "requires": { 2293 | "isexe": "^2.0.0" 2294 | } 2295 | }, 2296 | "word-wrap": { 2297 | "version": "1.2.3", 2298 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 2299 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 2300 | "dev": true 2301 | }, 2302 | "workerpool": { 2303 | "version": "6.2.1", 2304 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", 2305 | "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", 2306 | "dev": true 2307 | }, 2308 | "wrap-ansi": { 2309 | "version": "7.0.0", 2310 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 2311 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 2312 | "dev": true, 2313 | "requires": { 2314 | "ansi-styles": "^4.0.0", 2315 | "string-width": "^4.1.0", 2316 | "strip-ansi": "^6.0.0" 2317 | } 2318 | }, 2319 | "wrappy": { 2320 | "version": "1.0.2", 2321 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2322 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 2323 | "dev": true 2324 | }, 2325 | "write-file-atomic": { 2326 | "version": "5.0.1", 2327 | "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", 2328 | "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", 2329 | "dev": true, 2330 | "requires": { 2331 | "imurmurhash": "^0.1.4", 2332 | "signal-exit": "^4.0.1" 2333 | }, 2334 | "dependencies": { 2335 | "signal-exit": { 2336 | "version": "4.0.2", 2337 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", 2338 | "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", 2339 | "dev": true 2340 | } 2341 | } 2342 | }, 2343 | "y18n": { 2344 | "version": "5.0.8", 2345 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 2346 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 2347 | "dev": true 2348 | }, 2349 | "yallist": { 2350 | "version": "4.0.0", 2351 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 2352 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 2353 | "dev": true 2354 | }, 2355 | "yargs": { 2356 | "version": "16.2.0", 2357 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 2358 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 2359 | "dev": true, 2360 | "requires": { 2361 | "cliui": "^7.0.2", 2362 | "escalade": "^3.1.1", 2363 | "get-caller-file": "^2.0.5", 2364 | "require-directory": "^2.1.1", 2365 | "string-width": "^4.2.0", 2366 | "y18n": "^5.0.5", 2367 | "yargs-parser": "^20.2.2" 2368 | } 2369 | }, 2370 | "yargs-parser": { 2371 | "version": "20.2.9", 2372 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", 2373 | "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", 2374 | "dev": true 2375 | }, 2376 | "yargs-unparser": { 2377 | "version": "2.0.0", 2378 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", 2379 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", 2380 | "dev": true, 2381 | "requires": { 2382 | "camelcase": "^6.0.0", 2383 | "decamelize": "^4.0.0", 2384 | "flat": "^5.0.2", 2385 | "is-plain-obj": "^2.1.0" 2386 | } 2387 | }, 2388 | "yocto-queue": { 2389 | "version": "0.1.0", 2390 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 2391 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 2392 | "dev": true 2393 | } 2394 | } 2395 | } 2396 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stylelint-csstree-validator", 3 | "version": "3.0.0", 4 | "description": "Stylelint plugin to validate CSS syntax", 5 | "repository": "csstree/stylelint-validator", 6 | "author": "Roman Dvornov ", 7 | "license": "MIT", 8 | "type": "module", 9 | "main": "./cjs/index.cjs", 10 | "exports": { 11 | ".": { 12 | "import": "./lib/index.js", 13 | "require": "./cjs/index.cjs" 14 | }, 15 | "./package.json": "./package.json" 16 | }, 17 | "keywords": [ 18 | "stylelint-plugin", 19 | "stylelint", 20 | "csstree", 21 | "css", 22 | "validator", 23 | "syntax" 24 | ], 25 | "scripts": { 26 | "test": "mocha test --reporter ${REPORTER:-progress}", 27 | "test:cjs": "mocha cjs-test --reporter ${REPORTER:-progress}", 28 | "lint": "eslint lib test", 29 | "build": "npm run esm-to-cjs", 30 | "build-and-test": "npm run esm-to-cjs-and-test", 31 | "esm-to-cjs": "node scripts/esm-to-cjs", 32 | "esm-to-cjs-and-test": "npm run esm-to-cjs && npm run test:cjs", 33 | "coverage": "c8 --reporter=lcovonly npm test", 34 | "prepublishOnly": "npm run lint && npm test && npm run build-and-test" 35 | }, 36 | "engines": { 37 | "node": "^14.13.0 || >=15.0.0", 38 | "npm": ">=7.0.0" 39 | }, 40 | "dependencies": { 41 | "css-tree": "^2.3.1" 42 | }, 43 | "peerDependencies": { 44 | "stylelint": ">=7.0.0 <16.0.0" 45 | }, 46 | "devDependencies": { 47 | "c8": "^7.12.0", 48 | "eslint": "^8.33.0", 49 | "mocha": "^10.2.0", 50 | "postcss-less": "^6.0.0", 51 | "postcss-scss": "^4.0.6", 52 | "rollup": "^2.79.1", 53 | "stylelint": "^15.7.0" 54 | }, 55 | "files": [ 56 | "cjs", 57 | "lib" 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /scripts/esm-to-cjs.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import { rollup } from 'rollup'; 3 | 4 | const external = [ 5 | 'assert', 6 | 'stylelint-csstree-validator', 7 | 'css-tree', 8 | 'stylelint', 9 | 'stylelint/lib/utils/isStandardSyntaxAtRule.js', 10 | 'stylelint/lib/utils/isStandardSyntaxDeclaration.js', 11 | 'stylelint/lib/utils/isStandardSyntaxProperty.js', 12 | 'stylelint/lib/utils/isStandardSyntaxValue.js', 13 | 'postcss', 14 | 'postcss-scss', 15 | 'postcss-less' 16 | ]; 17 | 18 | function readDir(dir) { 19 | return fs.readdirSync(dir) 20 | .filter(fn => fn.endsWith('.js')) 21 | .map(fn => `${dir}/${fn}`); 22 | } 23 | 24 | async function build(outputDir, ...entryPoints) { 25 | const startTime = Date.now(); 26 | 27 | console.log(); 28 | console.log(`Convert ESM to CommonJS (output: ${outputDir})`); 29 | 30 | const res = await rollup({ 31 | external, 32 | input: entryPoints 33 | }); 34 | await res.write({ 35 | dir: outputDir, 36 | entryFileNames: '[name].cjs', 37 | format: 'cjs', 38 | exports: 'auto', 39 | preserveModules: true, 40 | interop: false, 41 | esModule: false, 42 | generatedCode: { 43 | constBindings: true 44 | } 45 | }); 46 | await res.close(); 47 | 48 | console.log(`Done in ${Date.now() - startTime}ms`); 49 | } 50 | 51 | async function buildAll() { 52 | await build('./cjs', 'lib/index.js'); 53 | await build('./cjs-test', ...readDir('test')); 54 | } 55 | 56 | buildAll(); 57 | -------------------------------------------------------------------------------- /test/css.js: -------------------------------------------------------------------------------- 1 | import validator from 'stylelint-csstree-validator'; 2 | import ruleTester from './utils/tester.js'; 3 | 4 | const { rule, ruleName, messages } = validator; 5 | const css = ruleTester(rule, ruleName); 6 | const unknownAtrule = (atrule, line, column) => { 7 | return invalid(messages.unknownAtrule(atrule), line, column); 8 | }; 9 | const invalidPrelude = (atrule, line, column) => { 10 | return invalid(messages.invalidPrelude(atrule), line, column); 11 | }; 12 | const unknownProperty = (atrule, line, column) => { 13 | return invalid(messages.unknownProperty(atrule), line, column); 14 | }; 15 | const invalidValue = (prop, line, column) => { 16 | return invalid(messages.invalidValue(prop), line, column); 17 | }; 18 | const invalid = (message, line, column) => { 19 | if (typeof line !== 'number' && typeof column !== 'number') { 20 | return message; 21 | } 22 | 23 | return { message, line, column }; 24 | }; 25 | 26 | // base test 27 | css(null, function(tr) { 28 | tr.ok('.foo { color: red }'); 29 | tr.ok('.foo { color: #123456 }'); 30 | tr.ok('.foo { color: inherit }'); 31 | tr.ok('.foo { color: initial }'); 32 | tr.ok('.foo { color: unset }'); 33 | tr.notOk('.foo { color: red green }', invalidValue('color')); 34 | tr.notOk('.foo { color: 1 }', invalidValue('color')); 35 | tr.notOk('.foo { color: #12345 }', invalidValue('color')); 36 | tr.notOk('.foo { color: &a }', messages.parseError('&a')); 37 | tr.notOk('.foo { baz: 123 }', unknownProperty('baz')); 38 | tr.notOk('@plugin "my-plugin"', unknownAtrule('plugin')); 39 | tr.notOk('@test;', unknownAtrule('test')); 40 | tr.notOk('.foo { color: @foo }', messages.parseError('@foo')); 41 | }); 42 | 43 | // loc 44 | css(null, function(tr) { 45 | tr.notOk('.foo { color: red green }', invalidValue('color', 1, 19)); 46 | tr.notOk('.foo {\n width: 10px;\n color: red green;\n}', invalidValue('color', 3, 14)); 47 | }); 48 | 49 | // atrules 50 | css(null, function(tr) { 51 | tr.notOk(' @unknown {}', unknownAtrule('unknown', 1, 3)); 52 | tr.notOk(' @media ??? {}', invalidPrelude('media', 1, 10)); 53 | }); 54 | css({ ignoreAtrules: ['unknown', 'IMPORT'] }, function(tr) { 55 | tr.ok(' @UNKNOWN {}'); 56 | tr.ok(' @import {}'); 57 | tr.notOk(' @unknown-import {}', unknownAtrule('unknown-import', 1, 3)); 58 | tr.notOk(' @media ??? {}', invalidPrelude('media', 1, 10)); 59 | }); 60 | css({ ignoreAtrules: ['unknown|import'] }, function(tr) { 61 | tr.ok(' @unknown {}'); 62 | tr.ok(' @import {}'); 63 | tr.notOk(' @unknown-import {}', unknownAtrule('unknown-import', 1, 3)); 64 | tr.notOk(' @media ??? {}', invalidPrelude('media', 1, 10)); 65 | }); 66 | css({ ignoreAtrules: ['unknown', 'very-unknown|import'] }, function(tr) { 67 | tr.ok(' @unknown {}'); 68 | tr.ok(' @very-unknown {}'); 69 | tr.ok(' @import {}'); 70 | tr.notOk(' @media ??? {}', invalidPrelude('media', 1, 10)); 71 | }); 72 | css({ atrules: false }, function(tr) { 73 | tr.ok('@unknown;'); 74 | tr.ok('@media ??? {}'); 75 | }); 76 | 77 | // should ignore properties from `ignore` list 78 | css({ ignoreProperties: ['foo', 'bar'] }, function(tr) { 79 | tr.ok('.foo { foo: 1 }'); 80 | tr.ok('.foo { bar: 1 }'); 81 | tr.notOk('.foo { foobar: 1 }', unknownProperty('foobar')); 82 | tr.ok('.foo { BAR: 1 }'); 83 | tr.notOk('.foo { baz: 1 }', unknownProperty('baz')); 84 | }); 85 | css({ ignoreProperties: ['foo|bar'] }, function(tr) { 86 | tr.ok('.foo { foo: 1 }'); 87 | tr.ok('.foo { bar: 1 }'); 88 | tr.notOk('.foo { foobar: 1 }', unknownProperty('foobar')); 89 | tr.ok('.foo { BAR: 1 }'); 90 | tr.notOk('.foo { baz: 1 }', unknownProperty('baz')); 91 | }); 92 | css({ ignoreProperties: ['/foo|bar/', '/qux/i'] }, function(tr) { 93 | tr.ok('.foo { foo: 1 }'); 94 | tr.ok('.foo { bar: 1 }'); 95 | tr.ok('.foo { foobar: 1 }'); 96 | tr.notOk('.foo { BAR: 1 }', unknownProperty('BAR')); 97 | tr.ok('.foo { QUX: 1; qux: 2 }'); 98 | }); 99 | css({ ignoreProperties: [/foo|bar/, /qux/i] }, function(tr) { 100 | tr.ok('.foo { foo: 1 }'); 101 | tr.ok('.foo { bar: 1 }'); 102 | tr.ok('.foo { foobar: 1 }'); 103 | tr.notOk('.foo { BAR: 1 }', unknownProperty('BAR')); 104 | tr.ok('.foo { QUX: 1; qux: 2 }'); 105 | }); 106 | css({ ignoreProperties: ['FOO', 'bar|QUX'] }, function(tr) { 107 | tr.ok('.foo { foo: 1 }'); 108 | tr.ok('.foo { BAR: 1 }'); 109 | tr.ok('.foo { qux: 1 }'); 110 | tr.notOk('.foo { baz: 1 }', unknownProperty('baz')); 111 | }); 112 | css({ ignoreProperties: ['token-\\d+'] }, function(tr) { 113 | tr.ok('.foo { token-1: 1 }'); 114 | tr.ok('.foo { token-23: 1 }'); 115 | tr.notOk('.foo { token-1-postfix: 1 }', unknownProperty('token-1-postfix')); 116 | tr.notOk('.foo { baz: 1 }', unknownProperty('baz')); 117 | }); 118 | 119 | // should ignore by ignoreValue pattern 120 | css({ ignoreValue: '^patternToIgnore$|=', ignoreProperties: ['bar'] }, function(tr) { 121 | tr.ok('.foo { color: red }'); 122 | tr.ok('.foo { color: #fff }'); 123 | tr.ok('.foo { color: patternToIgnore }'); 124 | tr.ok('.foo { bar: notMatchingPattern }'); 125 | tr.ok('.foo { color: alpha(opacity=1) }'); 126 | tr.notOk('.foo { color: notMatchingPattern }', invalidValue('color')); 127 | tr.notOk('.foo { foo: patternToIgnore }', unknownProperty('foo', 1, 8)); 128 | tr.notOk('.foo { foo: notMatchingPattern }', unknownProperty('foo')); 129 | }); 130 | 131 | // extend dictionary 132 | css({ 133 | properties: { 134 | foo: '', 135 | bar: '| ', 136 | qux: '', 137 | relax: '' 138 | }, 139 | types: { 140 | 'my-fn()': 'my-fn()', 141 | qux: '| ', 142 | color: '| darken(, )' 143 | } 144 | }, function(tr) { 145 | tr.ok('.foo { foo: my-fn(10px) }'); 146 | tr.ok('.foo { foo: my-fn(10%) }'); 147 | tr.ok('.foo { foo: my-fn(0) }'); 148 | tr.ok('.bar { bar: my-fn(10px) }'); 149 | tr.notOk('.baz { baz: my-fn(10px) }', unknownProperty('baz')); 150 | tr.ok('.qux { qux: 10px }'); 151 | tr.notOk('.foo { color: my-fn(10px) }', invalidValue('color')); 152 | tr.ok('.foo { color: darken(white, 5%) }'); 153 | tr.ok('.foo { color: white }'); 154 | tr.notOk('.foo { color: darken(white, .05) }', invalidValue('color')); 155 | tr.ok('.foo { relax: white }'); 156 | tr.ok('.foo { relax: 10px solid whatever }'); 157 | }); 158 | 159 | css({ 160 | properties: { 161 | composes: '+ [ from [ | global ] ]?' 162 | } 163 | }, function(tr) { 164 | tr.ok('.foo { composes: className }'); 165 | tr.ok('.foo { composes: classNameA classNameB }'); 166 | tr.ok('.foo { composes: classNameA from "foo.css" }'); 167 | tr.ok('.foo { composes: classNameA from global }'); 168 | tr.ok('.foo { composes: classNameA classNameB from "foo.css" }'); 169 | tr.notOk('.foo { composes: from "foo.css" }', invalidValue('composes', 1, 23)); 170 | tr.notOk('.foo { composes: classNameA "foo.css" }', invalidValue('composes', 1, 29)); 171 | }); 172 | 173 | // atrule validation 174 | css({ 175 | ignoreValue: /ignore-this/, 176 | ignoreProperties: ['ignore-descriptor'] 177 | }, function(tr) { 178 | tr.ok('@import url("foo.css")'); 179 | tr.ok('@import url("foo.css");'); 180 | tr.ok('@imPOrt url("foo.css");'); 181 | tr.ok('@font-face { font-display: swap }'); 182 | tr.ok('@font-face { font-display: ignore-this }'); 183 | tr.ok('@font-face { ignore-descriptor: foo }'); 184 | tr.notOk('@font-face { font-display: ignore-that }', invalidValue('font-display', 1, 28)); 185 | tr.notOk('.foo { font-display: swap }', invalid(`Unknown property \`font-display\` (${ruleName})`, 1, 8)); 186 | tr.notOk(' @not-import url("foo.css");', unknownAtrule('not-import', 1, 3)); 187 | // tr.notOk(' @-unknown-import url("foo.css");', unknownAtrule("-")known-mport`', 1, 3)); 188 | tr.notOk(' @import { color: red }', invalid(`At-rule \`@import\` should contain a prelude (${ruleName})`, 1, 11)); 189 | tr.notOk(' @import url("foo.css") .a', invalidPrelude('import', 1, 26)); 190 | tr.notOk(' @font-face xx {}', invalid(`At-rule \`@font-face\` should not contain a prelude (${ruleName})`, 1, 14)); 191 | tr.notOk(' @font-face { font-display: foo }', invalidValue('font-display', 1, 30)); 192 | tr.notOk(' @font-face { font-displa: block }', invalid(`Unknown at-rule descriptor \`font-displa\` (${ruleName})`, 1, 16)); 193 | tr.notOk(' @foo { color: ref }', [unknownAtrule('foo', 1, 3)]); 194 | tr.notOk(' @media zzz zzz { color: ref }', [invalidPrelude('media', 1, 14)]); 195 | }); 196 | 197 | // options varnings 198 | css({ 199 | ignore: ['ignore-descriptor'] 200 | }, function(tr) { 201 | tr.notOk('a {}', `Invalid value "ignore-descriptor" for option "ignore" of rule "${ruleName}"`); 202 | }); 203 | css({ 204 | syntaxExtensions: ['sass', 'xxx'] 205 | }, function(tr) { 206 | tr.notOk('a {}', `Invalid value "xxx" for option "syntaxExtensions" of rule "${ruleName}"`); 207 | }); 208 | -------------------------------------------------------------------------------- /test/preprocessors.js: -------------------------------------------------------------------------------- 1 | import validator from 'stylelint-csstree-validator'; 2 | import lessSyntax from 'postcss-less'; 3 | import scssSyntax from 'postcss-scss'; 4 | import ruleTester from './utils/tester.js'; 5 | 6 | const { rule, ruleName, messages } = validator; 7 | const less = ruleTester(rule, ruleName, { 8 | postcssOptions: { syntax: lessSyntax } 9 | }); 10 | const sass = ruleTester(rule, ruleName, { 11 | postcssOptions: { syntax: scssSyntax } 12 | }); 13 | 14 | const lessTests = function(tr) { 15 | // variables 16 | tr.ok('.foo { color: @var }'); 17 | tr.ok('.foo { color: @@var }'); 18 | tr.ok('.foo { color: @ }', messages.parseError('@')); 19 | tr.ok('.foo { color: @123 }', messages.parseError('@123')); 20 | tr.ok('.foo { color: @@@var }', messages.parseError('@@@var')); 21 | 22 | // escaping 23 | tr.ok('.foo { color: ~"test" }'); 24 | tr.ok('.foo { color: ~\'test\' }'); 25 | tr.notOk('.foo { color: ~ }', messages.parseError('~')); 26 | tr.notOk('.foo { color: ~123 }', messages.parseError('~123')); 27 | 28 | // interpolation 29 | tr.ok('.foo { @{property}: 1 }'); 30 | tr.ok('.foo { test-@{property}: 1 }'); 31 | tr.ok('.foo { @{property}-test: 1 }'); 32 | 33 | // standalone var declarations 34 | tr.ok('@foo: 2'); 35 | 36 | // namespaces 37 | tr.ok('.foo { color: #outer > .inner(); }'); // deprecated 38 | tr.ok('.foo { color: #outer> .inner(); }'); // deprecated 39 | tr.ok('.foo { color: #outer >.inner(); }'); // deprecated 40 | tr.ok('.foo { color: #outer>.inner(); }'); // deprecated 41 | tr.ok('.foo { color: #outer .inner(); }'); // deprecated 42 | tr.ok('.foo { color: #outer.inner(); }'); // preferred 43 | tr.ok('.foo { color: #outer.inner(1 + 2); }'); // preferred 44 | 45 | // at-rule with Less expressions in a prelude 46 | tr.ok('@keyframes @name {}'); 47 | tr.notOk('@keyframes "foo" "bar" {}', messages.invalidPrelude('keyframes')); 48 | 49 | // custom at-rules 50 | tr.ok('@plugin "my-plugin";'); 51 | }; 52 | 53 | const sassTests = function(tr) { 54 | // variables 55 | tr.ok('.foo { color: $red }'); 56 | tr.ok('.foo { color: $ }', messages.parseError('$')); 57 | tr.ok('.foo { color: $123 }', messages.parseError('$123')); 58 | tr.ok('.foo { color: $$123 }', messages.parseError('$$123')); 59 | 60 | // modulo operator 61 | tr.ok('.foo { color: 3 % 6 }'); 62 | 63 | // interpolation 64 | tr.ok('.foo { color: #{$var} }'); 65 | tr.ok('.foo { color: #{1 + 2} }'); 66 | tr.ok('.foo { max-height: calc(100vh - #{$navbar-height}); }'); 67 | tr.ok('.foo { #{$property}: 1 }'); 68 | tr.ok('.foo { test-#{$property}: 1 }'); 69 | tr.ok('.foo { #{$property}-test: 1 }'); 70 | 71 | // standalone var declarations 72 | tr.ok('$foo: 1'); 73 | 74 | // namespace 75 | tr.ok('.foo { color: fonts.$font-family-text; }'); 76 | tr.ok('.foo { color: fonts.foo(); }'); 77 | tr.ok('.foo { color: fonts.foo(1 + 2); }'); 78 | 79 | // at-rule with Sass expressions in a prelude 80 | tr.ok('@media ($from: $breakpoint) {}'); 81 | tr.notOk('@media (123) {}', messages.invalidPrelude('media')); 82 | tr.ok('@keyframes #{$animationName} {}'); 83 | tr.notOk('@keyframes "foo" "bar" {}', messages.invalidPrelude('keyframes')); 84 | 85 | // custom at-rules 86 | tr.ok('@at-root xxx'); 87 | tr.ok('@content xxx'); 88 | tr.ok('@debug xxx'); 89 | tr.ok('@each xxx'); 90 | tr.ok('@error xxx'); 91 | tr.ok('@extend xxx'); 92 | tr.ok('@for xxx'); 93 | tr.ok('@forward xxx'); 94 | tr.ok('@function xxx'); 95 | tr.ok('@if xxx'); 96 | tr.ok('@else xxx'); 97 | tr.ok('@else {}'); 98 | tr.ok('@else if {}'); 99 | tr.ok('@import "theme.css";'); 100 | tr.ok('@import "http://fonts.googleapis.com/css?family=Droid+Sans";'); 101 | tr.ok('@import url(theme);'); 102 | tr.ok('@import "landscape" screen and (orientation: landscape);'); 103 | tr.ok('@include xxx'); 104 | tr.ok('@mixin xxx'); 105 | tr.ok('@return xxx'); 106 | tr.ok('@use xxx'); 107 | tr.ok('@warn xxx'); 108 | tr.ok('@while xxx'); 109 | }; 110 | 111 | // less extenstions 112 | less({ syntaxExtensions: ['less'] }, (tr) => { 113 | lessTests(tr); 114 | 115 | // custom Sass at-rules 116 | tr.notOk('@if $test {}', messages.unknownAtrule('if')); 117 | }); 118 | less({ syntaxExtensions: ['less', 'sass'] }, lessTests); 119 | 120 | // sass extenstions 121 | sass({ syntaxExtensions: ['sass'] }, (tr) => { 122 | sassTests(tr); 123 | 124 | // custom Sass at-rules 125 | tr.notOk('@plugin "foo";', messages.unknownAtrule('plugin')); 126 | }); 127 | sass({ syntaxExtensions: ['sass', 'less'] }, sassTests); 128 | -------------------------------------------------------------------------------- /test/utils/tester.js: -------------------------------------------------------------------------------- 1 | // Reworked stylelint-rule-tester 2 | 3 | import assert, { deepStrictEqual } from 'assert'; 4 | import postcss from 'postcss'; 5 | 6 | const isRegExp = value => toString.call(value) === '[object RegExp]'; 7 | 8 | /** 9 | * Create a ruleTester for a specified rule. 10 | * 11 | * The ruleTester is a function accepting options and a callback. 12 | * The callback is passed on object exposing `ok` and `notOk` functions, 13 | * which check CSS strings against the rule configured with the specified options. 14 | * 15 | * @param {function} rule 16 | * @param {string} ruleName 17 | * @param {object} [testerOptions] 18 | * @param {function[]} [testerOptions.preceedingPlugins] - Array of PostCSS plugins to 19 | * run the CSS string through *before* linting it 20 | * @param {boolean} [testerOptions.escapeCss = true] - If `false`, the CSS string printed 21 | * to the console will not be escaped. 22 | * This is useful if you want to read newlines and indentation. 23 | * @param {object} [testerOptions.postcssOptions] - An objects object passed 24 | * to postcssProcessor.process(). 25 | * cf. https://github.com/postcss/postcss/blob/master/docs/api.md#processorprocesscss-opts 26 | * @return {function} ruleTester for the specified rule/options 27 | */ 28 | function ruleTester(rule, ruleName, testerOptions) { 29 | testerOptions = testerOptions || {}; 30 | testerOptions.escapeCss = testerOptions.escapeCss !== false; 31 | 32 | return ruleTester; 33 | 34 | function ruleTester(rulePrimaryOptions, ruleSecondaryOptions, cb) { 35 | if (typeof ruleSecondaryOptions === 'function') { 36 | cb = ruleSecondaryOptions; 37 | ruleSecondaryOptions = null; 38 | } 39 | 40 | const ruleOptionsString = rulePrimaryOptions 41 | ? JSON.stringify(rulePrimaryOptions, (_, value) => 42 | isRegExp(value) ? 'regexp:' + String(value) : value 43 | ).replace(/"regexp:(.*?)"/g, '$1') 44 | : ''; 45 | if (ruleOptionsString && ruleSecondaryOptions) { 46 | ruleOptionsString += ', ' + JSON.stringify(ruleSecondaryOptions, (_, value) => 47 | isRegExp(value) ? 'regexp:' + String(value) : value 48 | ).replace(/"regexp:(.*?)"/g, '$1'); 49 | } 50 | 51 | const ok = Object.assign(createOkAssertFactory(it), { 52 | only: createOkAssertFactory(it.only), 53 | skip: createOkAssertFactory(it.skip) 54 | }); 55 | const notOk = Object.assign(createFailureAssertFactory(it), { 56 | only: createFailureAssertFactory(it.only), 57 | skip: createFailureAssertFactory(it.skip) 58 | }); 59 | 60 | describe(ruleName + (ruleOptionsString ? ' (options: ' + ruleOptionsString + ')' : ''), () => { 61 | cb({ ok, notOk }); 62 | }); 63 | 64 | // Checks that a CSS string is valid according to the specified rule/options. 65 | function createOkAssertFactory(it) { 66 | return (cssString, description) => 67 | it(testTitleStr(cssString), () => { 68 | return postcssProcess(cssString).then(function(result) { 69 | const warnings = result.warnings().map(warn => ({ 70 | ...warn, 71 | node: '' 72 | })); 73 | 74 | deepStrictEqual(warnings, [], description); 75 | }); 76 | }); 77 | } 78 | 79 | // Checks that a CSS string is INVALID according to the 80 | // specified rule/options -- i.e. that a warning is registered 81 | // with the expected warning message. 82 | function createFailureAssertFactory(it) { 83 | return (cssString, expected) => 84 | it(testTitleStr(cssString), function() { 85 | return postcssProcess(cssString).then(function(result) { 86 | if (!Array.isArray(expected)) { 87 | expected = [expected]; 88 | } 89 | 90 | const expectedWarnings = expected.map(entry => 91 | typeof entry === 'string' ? { message: entry } : entry 92 | ); 93 | const actualWarnings = result.warnings().map((entry, idx) => { 94 | const result = { message: entry.text }; 95 | const shape = expectedWarnings[idx] || {}; 96 | 97 | for (let key in shape) { 98 | if (key !== 'message') { 99 | result[key] = entry[key]; 100 | } 101 | } 102 | 103 | return result; 104 | }); 105 | 106 | assert(actualWarnings.length > 0, 'should warn'); 107 | deepStrictEqual(actualWarnings, expectedWarnings); 108 | }); 109 | }); 110 | } 111 | 112 | function postcssProcess(cssString) { 113 | const processor = postcss(); 114 | 115 | if (testerOptions.preceedingPlugins) { 116 | testerOptions.preceedingPlugins.forEach(function(plugin) { 117 | processor.use(plugin); 118 | }); 119 | } 120 | 121 | return processor 122 | .use(rule(rulePrimaryOptions, ruleSecondaryOptions)) 123 | .process(cssString, { from: undefined, ...testerOptions.postcssOptions }); 124 | } 125 | 126 | function testTitleStr(css) { 127 | let result = testerOptions.escapeCss 128 | ? JSON.stringify(css) 129 | : '\n' + css; 130 | 131 | return result; 132 | } 133 | } 134 | } 135 | 136 | export default ruleTester; 137 | --------------------------------------------------------------------------------