├── .github
└── workflows
│ └── publish.yml
├── .gitignore
├── .vscode
├── extensions.json
├── launch.json
├── settings.json
└── tasks.json
├── .vscodeignore
├── LICENSE.md
├── README.md
├── SECURITY.md
├── images
├── banner.png
├── icon.png
├── screenshot-config.gif
├── screenshot-env.gif
├── screenshot-middleware.gif
├── screenshot-mix.gif
├── screenshot-route.gif
├── screenshot-section.gif
├── screenshot-trans.gif
├── screenshot-validation.gif
└── screenshot-view.gif
├── package-lock.json
├── package.json
├── src
├── AssetProvider.ts
├── AuthProvider.ts
├── BladeProvider.ts
├── ConfigProvider.ts
├── EloquentProvider.ts
├── EnvProvider.ts
├── MiddlewareProvider.ts
├── MixProvider.ts
├── RouteProvider.ts
├── TranslationProvider.ts
├── ValidationProvider.ts
├── ViewProvider.ts
├── ViteProvider.ts
├── extension.ts
└── helpers.ts
├── tsconfig.json
├── tslint.json
└── webpack.config.js
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Deploy
2 |
3 | on:
4 | push:
5 | tags:
6 | - "*"
7 |
8 | jobs:
9 | deploy:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v2
13 | - uses: actions/setup-node@v1
14 | with:
15 | node-version: 16
16 | - run: npm i
17 | - name: Publish to Visual Studio Marketplace
18 | uses: HaaLeo/publish-vscode-extension@v1
19 | with:
20 | pat: ${{ secrets.VS_MARKETPLACE_TOKEN }}
21 | registryUrl: https://marketplace.visualstudio.com
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 | node_modules
3 | .vscode-test/
4 | *.vsix
5 | dist
6 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // See http://go.microsoft.com/fwlink/?LinkId=827846
3 | // for the documentation about the extensions.json format
4 | "recommendations": [
5 | "ms-vscode.vscode-typescript-tslint-plugin"
6 | ]
7 | }
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | // A launch configuration that compiles the extension and then opens it inside a new window
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | {
6 | "version": "0.2.0",
7 | "configurations": [
8 | {
9 | "name": "Run Extension",
10 | "type": "extensionHost",
11 | "request": "launch",
12 | "runtimeExecutable": "${execPath}",
13 | "args": [
14 | "--extensionDevelopmentPath=${workspaceFolder}"
15 | ],
16 | "outFiles": [
17 | "${workspaceFolder}/dist/*.js"
18 | ]
19 | },
20 | {
21 | "name": "Extension Tests",
22 | "type": "extensionHost",
23 | "request": "launch",
24 | "runtimeExecutable": "${execPath}",
25 | "args": [
26 | "--extensionDevelopmentPath=${workspaceFolder}",
27 | "--extensionTestsPath=${workspaceFolder}/dist/test"
28 | ],
29 | "outFiles": [
30 | "${workspaceFolder}/dist/test/*.js"
31 | ]
32 | }
33 | ]
34 | }
35 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | // Place your settings in this file to overwrite default and user settings.
2 | {
3 | "files.exclude": {
4 | "out": false // set this to true to hide the "out" folder with the compiled JS files
5 | },
6 | "search.exclude": {
7 | "out": true // set this to false to include "out" folder in search results
8 | },
9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts
10 | "typescript.tsc.autoDetect": "off"
11 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | // See https://go.microsoft.com/fwlink/?LinkId=733558
2 | // for the documentation about the tasks.json format
3 | {
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "type": "npm",
8 | "script": "watch",
9 | "problemMatcher": "$tsc-watch",
10 | "isBackground": true,
11 | "presentation": {
12 | "reveal": "never"
13 | },
14 | "group": {
15 | "kind": "build",
16 | "isDefault": true
17 | }
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/.vscodeignore:
--------------------------------------------------------------------------------
1 | .vscode/**
2 | .vscode-test/**
3 | src/**
4 | images/screenshot.gif
5 | .gitignore
6 | vsc-extension-quickstart.md
7 | **/tsconfig.json
8 | **/tslint.json
9 | **/*.map
10 | **/*.ts
11 | node_modules/**
12 | .vscode
13 | tsconfig.json
14 | webpack.config.js
15 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 amir alizadeh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
Laravel Extra Intellisense
3 |
4 |
5 |

6 |
7 |
8 | This extension provides [Laravel](https://laravel.com/) routes, views and ... autocomplete for [VSCode](https://code.visualstudio.com/).
9 |
10 | Please read the [security note](#security-note) and [how to configure](#sample-config-to-use-docker) before using the extension.
11 |
12 | ## Autocomplete
13 | * [Route names and route parameters](#route-names-and-route-parameters)
14 | * [Views and variables](#views-and-variables)
15 | * [Configs](#configs)
16 | * [Translations and translation parameters](#translations-and-translation-parameters)
17 | * [Laravel mix and vite functions](#laravel-mix-and-vite-functions)
18 | * [Validation rules](#validation-rules)
19 | * [View sections and stacks](#view-sections-and-stacks)
20 | * [Env](#env)
21 | * [Route Middlewares](#route-middlewares)
22 | * Asset
23 | * Model Attributes (Beta!)
24 | * Blade directives
25 |
26 | ### Route names and route parameters
27 | 
28 | ### Views and variables
29 | 
30 | ### Configs
31 | 
32 | ### Translations and translation parameters
33 | 
34 | ### Laravel mix and vite functions
35 | 
36 | ### Validation rules
37 | 
38 | ### View sections and stacks
39 | 
40 | ### Env
41 | 
42 | ### Route Middlewares
43 | 
44 |
45 | ## Configuration
46 | ### LaravelExtraIntellisense.customValidationRules:
47 | Your custom validation rules snippets.
48 |
49 | Example:
50 | ```json
51 | "LaravelExtraIntellisense.customValidationRules": {
52 | "mobile": "mobile",
53 | "distance_gt": "distance_gt:${0:1km}"
54 | }
55 | ```
56 |
57 | ### LaravelExtraIntellisense.phpCommand
58 | Command to run PHP codes to interact with your Laravel application.
59 |
60 | Default:
61 | `php -r \"{code}\"`
62 | > Note: {code} is PHP code generated by extension and should be wrapped with "".
63 |
64 | ### LaravelExtraIntellisense.basePath
65 | Base path of your Laravel application. useful if your Laravel project is not at the root of you project directory.
66 | > If the base path starts with `.` (like `./src`) it will be considered a relative path otherwise it will be considered an absolute path.
67 |
68 | ### LaravelExtraIntellisense.basePathForCode
69 | Same as `LaravelExtraIntellisense.basePath` but this one using for `require_once` in generated PHP codes.
70 |
71 | ### LaravelExtraIntellisense.viewDirectorySeparator
72 | You also can use `/` instead of `.` as directory separator for view autocomplete.
73 |
74 | ### LaravelExtraIntellisense.modelsPaths
75 | Array of paths including your models. (Default: `["app", "app/Models"]`)
76 |
77 | ### LaravelExtraIntellisense.modelVariables
78 | Variable names that should provide autocomplete with specific model class. Finding variable type (especially in views) is not easy so you need to manually define variable types.
79 |
80 | Example: The Following setting provides auto completion each time you type `discountedProduct->` with `App\Models\Product` model attributes.
81 | ```json
82 | "LaravelExtraIntellisense.modelVariables": {
83 | "discountedProduct": "App\\Models\\Product"
84 | }
85 | ```
86 | > All `camelCase` and `snake_case` of model names provide autocomplete by default.
87 | > For example `productDiscount` and `product_discount` provides member autocomplete from `App\Models\ProductDiscount` model.
88 |
89 | ### LaravelExtraIntellisense.modelAttributeCase
90 | Change model attribute names case to `snake_case`, `camelCase` or `default`. (Default = `default`)
91 |
92 | ### LaravelExtraIntellisense.modelAccessorCase
93 | Change model accessor names case to `snake_case`, `camelCase` or `default`. (Default = `snake`)
94 |
95 | ### LaravelExtraIntellisense.disableBlade
96 | If you want to disable blade directives autocomplete set this to true.
97 |
98 | ### LaravelExtraIntellisense.disableAuth
99 | If you want to disable authorization autocomplete set this to true
100 |
101 | ### LaravelExtraIntellisense.disableErrorAlert
102 | Hide error alerts when extension can't get data from your application.
103 |
104 | #### Sample config to use docker
105 | This is a simple configuration to use via [Laradock](https://github.com/laradock/laradock).
106 |
107 | ```json
108 | "LaravelExtraIntellisense.phpCommand": "docker exec -w /var/www/your-project -u laradock laradock_workspace_1 php -r \"{code}\"",
109 | "LaravelExtraIntellisense.basePathForCode": "/var/www/your-project"
110 | ```
111 |
112 | Another sample for [Laravel Sail](https://laravel.com/docs/sail).
113 |
114 | ```json
115 | "LaravelExtraIntellisense.basePathForCode": "/var/www/html",
116 | "LaravelExtraIntellisense.phpCommand": "docker-compose exec -w /var/www/html YOUR_SERVICE_NAME php -r \"{code}\""
117 | ```
118 | Default YOUR_SERVICE_NAME for Laravel sail is `laravel.test`.
119 |
120 | It is possible to use this extension with other docker images or even other virtual machines.
121 |
122 | ## Security Note
123 | This extension runs your Laravel application automatically and periodically to get the information needed to provide autocomplete.
124 |
125 | So if you have any unknown errors in your log make sure the extension not causing it.
126 |
127 | Also if you writing any sensitive code in your service providers, disable the extension temporarily to prevent unwanted application executing.
128 |
129 | ## Release Notes
130 |
131 | ### 0.6.x
132 | * Add blade directives autocomplete (#45).
133 | * Add change case option for model attributes (#46).
134 | * Add support workspace with multiple directory (#54).
135 | * Add nested translations support (#54).
136 | * Add Vite autocompletion support (#131)
137 |
138 | ### 0.5.x
139 | * Add `asset` support.
140 | * Add Model attributes autocomplete (Beta).
141 |
142 | ### 0.4.x
143 | * Add Docker support.
144 |
145 | ### 0.3.x
146 | * `env` autocomplete added.
147 | * Route `middleware` autocomplete added.
148 | * Nested stack and section support added.
149 | * Function parser improvement.
150 | * Performance improvement.
151 | * Bug fixes (#25, #26)
152 | * Add configuration for views separator (#22).
153 | * `can`, `cannot` autocomplete.
154 | * Fix #18.
155 |
156 | ### 0.2.x
157 | * Validation rules autocomplete added.
158 | * works with `Validator` class, `validate` functions and inside request classes.
159 | * `markdown` function added to view functions for autocomplete.
160 | * Using file watcher instead of save event. Better change detect for view autocomplete.
161 | * json translation autocomplete added.
162 | * Auto-Retry removed from all providers. causes some performance issues.
163 | * Disable logging added.
164 | * View parameters autocomplete.
165 | * Route autocomplete bug in linux fixed.
166 | * Blade section autocomplete added.
167 | * Blade stack autocomplete added.
168 | * Duplicate section autocomplete items fixed.
169 | * PHP commands converted to async functions to prevent unresponsive extension host error.
170 |
171 | ### 0.1.x
172 | * Fix problems with linux.
173 | * Add translation autocomplete.
174 | * Improved providers.
175 | * Add mix autocomplete.
176 | * Performance improvments.
177 | * Route action autocomplete added. `Route::get`, *`Route::post`, ... autocompletes controller actions inside app\Http\Controllers.
178 |
179 | ### 0.0.x
180 | * Config autocomplete added.
181 | * Route bug fix.
182 | * View names with namespaces ready to use.
183 | * View functions autocomplete added.
184 | * Blade bug fix.
185 | * Add route autocomplete.
186 |
187 | ## Recommended extensions
188 | * [PHP Intelephense](https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client)
189 | * [PHPCS](https://marketplace.visualstudio.com/items?itemName=ikappas.phpcs)
190 | * [PHP DocBlocker](https://marketplace.visualstudio.com/items?itemName=neilbrayfield.php-docblocker)
191 | * [PHP formatter](https://marketplace.visualstudio.com/items?itemName=kokororin.vscode-phpfmt)
192 | * [Laravel Blade Snippets](https://marketplace.visualstudio.com/items?itemName=onecentlin.laravel-blade)
193 | * [Laravel goto view](https://marketplace.visualstudio.com/items?itemName=codingyu.laravel-goto-view)
194 | * [Laravel goto controller](https://marketplace.visualstudio.com/items?itemName=stef-k.laravel-goto-controller)
195 | * [DevDb](https://marketplace.visualstudio.com/items?itemName=damms005.devdb)
196 |
197 | ## Credits
198 | * [PHP parser](https://github.com/glayzzle/php-parser)
199 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Reporting a Vulnerability
4 |
5 | If you discover a security vulnerability within Laravel, please send an email to me at amiralizadeh9480@gmail.com.
--------------------------------------------------------------------------------
/images/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amir9480/vscode-laravel-extra-intellisense/a6d75a64e7b0d16f14b58abcc928b42290688ed8/images/banner.png
--------------------------------------------------------------------------------
/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amir9480/vscode-laravel-extra-intellisense/a6d75a64e7b0d16f14b58abcc928b42290688ed8/images/icon.png
--------------------------------------------------------------------------------
/images/screenshot-config.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amir9480/vscode-laravel-extra-intellisense/a6d75a64e7b0d16f14b58abcc928b42290688ed8/images/screenshot-config.gif
--------------------------------------------------------------------------------
/images/screenshot-env.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amir9480/vscode-laravel-extra-intellisense/a6d75a64e7b0d16f14b58abcc928b42290688ed8/images/screenshot-env.gif
--------------------------------------------------------------------------------
/images/screenshot-middleware.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amir9480/vscode-laravel-extra-intellisense/a6d75a64e7b0d16f14b58abcc928b42290688ed8/images/screenshot-middleware.gif
--------------------------------------------------------------------------------
/images/screenshot-mix.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amir9480/vscode-laravel-extra-intellisense/a6d75a64e7b0d16f14b58abcc928b42290688ed8/images/screenshot-mix.gif
--------------------------------------------------------------------------------
/images/screenshot-route.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amir9480/vscode-laravel-extra-intellisense/a6d75a64e7b0d16f14b58abcc928b42290688ed8/images/screenshot-route.gif
--------------------------------------------------------------------------------
/images/screenshot-section.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amir9480/vscode-laravel-extra-intellisense/a6d75a64e7b0d16f14b58abcc928b42290688ed8/images/screenshot-section.gif
--------------------------------------------------------------------------------
/images/screenshot-trans.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amir9480/vscode-laravel-extra-intellisense/a6d75a64e7b0d16f14b58abcc928b42290688ed8/images/screenshot-trans.gif
--------------------------------------------------------------------------------
/images/screenshot-validation.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amir9480/vscode-laravel-extra-intellisense/a6d75a64e7b0d16f14b58abcc928b42290688ed8/images/screenshot-validation.gif
--------------------------------------------------------------------------------
/images/screenshot-view.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amir9480/vscode-laravel-extra-intellisense/a6d75a64e7b0d16f14b58abcc928b42290688ed8/images/screenshot-view.gif
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "laravel-extra-intellisense",
3 | "version": "0.7.2",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "laravel-extra-intellisense",
9 | "version": "0.7.2",
10 | "dependencies": {
11 | "php-parser": "^3.0.2"
12 | },
13 | "devDependencies": {
14 | "@types/mocha": "^8.2.1",
15 | "@types/node": "^14.14.31",
16 | "@types/vscode": "^1.83.0",
17 | "ts-loader": "^8.0.17",
18 | "tslint": "^6.1.3",
19 | "typescript": "^4.2.2",
20 | "vscode-test": "^1.6.1",
21 | "webpack": "^5.24.2",
22 | "webpack-cli": "^4.5.0"
23 | },
24 | "engines": {
25 | "vscode": "^1.83.0"
26 | }
27 | },
28 | "node_modules/@babel/code-frame": {
29 | "version": "7.22.13",
30 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
31 | "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
32 | "dev": true,
33 | "dependencies": {
34 | "@babel/highlight": "^7.22.13",
35 | "chalk": "^2.4.2"
36 | },
37 | "engines": {
38 | "node": ">=6.9.0"
39 | }
40 | },
41 | "node_modules/@babel/code-frame/node_modules/ansi-styles": {
42 | "version": "3.2.1",
43 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
44 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
45 | "dev": true,
46 | "dependencies": {
47 | "color-convert": "^1.9.0"
48 | },
49 | "engines": {
50 | "node": ">=4"
51 | }
52 | },
53 | "node_modules/@babel/code-frame/node_modules/chalk": {
54 | "version": "2.4.2",
55 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
56 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
57 | "dev": true,
58 | "dependencies": {
59 | "ansi-styles": "^3.2.1",
60 | "escape-string-regexp": "^1.0.5",
61 | "supports-color": "^5.3.0"
62 | },
63 | "engines": {
64 | "node": ">=4"
65 | }
66 | },
67 | "node_modules/@babel/code-frame/node_modules/color-convert": {
68 | "version": "1.9.3",
69 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
70 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
71 | "dev": true,
72 | "dependencies": {
73 | "color-name": "1.1.3"
74 | }
75 | },
76 | "node_modules/@babel/code-frame/node_modules/color-name": {
77 | "version": "1.1.3",
78 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
79 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
80 | "dev": true
81 | },
82 | "node_modules/@babel/code-frame/node_modules/has-flag": {
83 | "version": "3.0.0",
84 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
85 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
86 | "dev": true,
87 | "engines": {
88 | "node": ">=4"
89 | }
90 | },
91 | "node_modules/@babel/code-frame/node_modules/supports-color": {
92 | "version": "5.5.0",
93 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
94 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
95 | "dev": true,
96 | "dependencies": {
97 | "has-flag": "^3.0.0"
98 | },
99 | "engines": {
100 | "node": ">=4"
101 | }
102 | },
103 | "node_modules/@babel/helper-validator-identifier": {
104 | "version": "7.22.20",
105 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
106 | "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
107 | "dev": true,
108 | "engines": {
109 | "node": ">=6.9.0"
110 | }
111 | },
112 | "node_modules/@babel/highlight": {
113 | "version": "7.22.20",
114 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
115 | "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
116 | "dev": true,
117 | "dependencies": {
118 | "@babel/helper-validator-identifier": "^7.22.20",
119 | "chalk": "^2.4.2",
120 | "js-tokens": "^4.0.0"
121 | },
122 | "engines": {
123 | "node": ">=6.9.0"
124 | }
125 | },
126 | "node_modules/@babel/highlight/node_modules/ansi-styles": {
127 | "version": "3.2.1",
128 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
129 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
130 | "dev": true,
131 | "dependencies": {
132 | "color-convert": "^1.9.0"
133 | },
134 | "engines": {
135 | "node": ">=4"
136 | }
137 | },
138 | "node_modules/@babel/highlight/node_modules/chalk": {
139 | "version": "2.4.2",
140 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
141 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
142 | "dev": true,
143 | "dependencies": {
144 | "ansi-styles": "^3.2.1",
145 | "escape-string-regexp": "^1.0.5",
146 | "supports-color": "^5.3.0"
147 | },
148 | "engines": {
149 | "node": ">=4"
150 | }
151 | },
152 | "node_modules/@babel/highlight/node_modules/color-convert": {
153 | "version": "1.9.3",
154 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
155 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
156 | "dev": true,
157 | "dependencies": {
158 | "color-name": "1.1.3"
159 | }
160 | },
161 | "node_modules/@babel/highlight/node_modules/color-name": {
162 | "version": "1.1.3",
163 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
164 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
165 | "dev": true
166 | },
167 | "node_modules/@babel/highlight/node_modules/has-flag": {
168 | "version": "3.0.0",
169 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
170 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
171 | "dev": true,
172 | "engines": {
173 | "node": ">=4"
174 | }
175 | },
176 | "node_modules/@babel/highlight/node_modules/supports-color": {
177 | "version": "5.5.0",
178 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
179 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
180 | "dev": true,
181 | "dependencies": {
182 | "has-flag": "^3.0.0"
183 | },
184 | "engines": {
185 | "node": ">=4"
186 | }
187 | },
188 | "node_modules/@discoveryjs/json-ext": {
189 | "version": "0.5.7",
190 | "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
191 | "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
192 | "dev": true,
193 | "engines": {
194 | "node": ">=10.0.0"
195 | }
196 | },
197 | "node_modules/@jridgewell/gen-mapping": {
198 | "version": "0.3.3",
199 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
200 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
201 | "dev": true,
202 | "dependencies": {
203 | "@jridgewell/set-array": "^1.0.1",
204 | "@jridgewell/sourcemap-codec": "^1.4.10",
205 | "@jridgewell/trace-mapping": "^0.3.9"
206 | },
207 | "engines": {
208 | "node": ">=6.0.0"
209 | }
210 | },
211 | "node_modules/@jridgewell/resolve-uri": {
212 | "version": "3.1.1",
213 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
214 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
215 | "dev": true,
216 | "engines": {
217 | "node": ">=6.0.0"
218 | }
219 | },
220 | "node_modules/@jridgewell/set-array": {
221 | "version": "1.1.2",
222 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
223 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
224 | "dev": true,
225 | "engines": {
226 | "node": ">=6.0.0"
227 | }
228 | },
229 | "node_modules/@jridgewell/source-map": {
230 | "version": "0.3.5",
231 | "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
232 | "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
233 | "dev": true,
234 | "dependencies": {
235 | "@jridgewell/gen-mapping": "^0.3.0",
236 | "@jridgewell/trace-mapping": "^0.3.9"
237 | }
238 | },
239 | "node_modules/@jridgewell/sourcemap-codec": {
240 | "version": "1.4.15",
241 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
242 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
243 | "dev": true
244 | },
245 | "node_modules/@jridgewell/trace-mapping": {
246 | "version": "0.3.19",
247 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
248 | "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
249 | "dev": true,
250 | "dependencies": {
251 | "@jridgewell/resolve-uri": "^3.1.0",
252 | "@jridgewell/sourcemap-codec": "^1.4.14"
253 | }
254 | },
255 | "node_modules/@tootallnate/once": {
256 | "version": "1.1.2",
257 | "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
258 | "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
259 | "dev": true,
260 | "engines": {
261 | "node": ">= 6"
262 | }
263 | },
264 | "node_modules/@types/eslint": {
265 | "version": "8.44.3",
266 | "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.3.tgz",
267 | "integrity": "sha512-iM/WfkwAhwmPff3wZuPLYiHX18HI24jU8k1ZSH7P8FHwxTjZ2P6CoX2wnF43oprR+YXJM6UUxATkNvyv/JHd+g==",
268 | "dev": true,
269 | "dependencies": {
270 | "@types/estree": "*",
271 | "@types/json-schema": "*"
272 | }
273 | },
274 | "node_modules/@types/eslint-scope": {
275 | "version": "3.7.5",
276 | "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.5.tgz",
277 | "integrity": "sha512-JNvhIEyxVW6EoMIFIvj93ZOywYFatlpu9deeH6eSx6PE3WHYvHaQtmHmQeNw7aA81bYGBPPQqdtBm6b1SsQMmA==",
278 | "dev": true,
279 | "dependencies": {
280 | "@types/eslint": "*",
281 | "@types/estree": "*"
282 | }
283 | },
284 | "node_modules/@types/estree": {
285 | "version": "1.0.2",
286 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.2.tgz",
287 | "integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==",
288 | "dev": true
289 | },
290 | "node_modules/@types/json-schema": {
291 | "version": "7.0.13",
292 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz",
293 | "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==",
294 | "dev": true
295 | },
296 | "node_modules/@types/mocha": {
297 | "version": "8.2.3",
298 | "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz",
299 | "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==",
300 | "dev": true
301 | },
302 | "node_modules/@types/node": {
303 | "version": "14.18.63",
304 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz",
305 | "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==",
306 | "dev": true
307 | },
308 | "node_modules/@types/vscode": {
309 | "version": "1.83.0",
310 | "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.83.0.tgz",
311 | "integrity": "sha512-3mUtHqLAVz9hegut9au4xehuBrzRE3UJiQMpoEHkNl6XHliihO7eATx2BMHs0odsmmrwjJrlixx/Pte6M3ygDQ==",
312 | "dev": true
313 | },
314 | "node_modules/@webassemblyjs/ast": {
315 | "version": "1.11.6",
316 | "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
317 | "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
318 | "dev": true,
319 | "dependencies": {
320 | "@webassemblyjs/helper-numbers": "1.11.6",
321 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
322 | }
323 | },
324 | "node_modules/@webassemblyjs/floating-point-hex-parser": {
325 | "version": "1.11.6",
326 | "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
327 | "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
328 | "dev": true
329 | },
330 | "node_modules/@webassemblyjs/helper-api-error": {
331 | "version": "1.11.6",
332 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
333 | "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
334 | "dev": true
335 | },
336 | "node_modules/@webassemblyjs/helper-buffer": {
337 | "version": "1.11.6",
338 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
339 | "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
340 | "dev": true
341 | },
342 | "node_modules/@webassemblyjs/helper-numbers": {
343 | "version": "1.11.6",
344 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
345 | "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
346 | "dev": true,
347 | "dependencies": {
348 | "@webassemblyjs/floating-point-hex-parser": "1.11.6",
349 | "@webassemblyjs/helper-api-error": "1.11.6",
350 | "@xtuc/long": "4.2.2"
351 | }
352 | },
353 | "node_modules/@webassemblyjs/helper-wasm-bytecode": {
354 | "version": "1.11.6",
355 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
356 | "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
357 | "dev": true
358 | },
359 | "node_modules/@webassemblyjs/helper-wasm-section": {
360 | "version": "1.11.6",
361 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
362 | "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
363 | "dev": true,
364 | "dependencies": {
365 | "@webassemblyjs/ast": "1.11.6",
366 | "@webassemblyjs/helper-buffer": "1.11.6",
367 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
368 | "@webassemblyjs/wasm-gen": "1.11.6"
369 | }
370 | },
371 | "node_modules/@webassemblyjs/ieee754": {
372 | "version": "1.11.6",
373 | "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
374 | "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
375 | "dev": true,
376 | "dependencies": {
377 | "@xtuc/ieee754": "^1.2.0"
378 | }
379 | },
380 | "node_modules/@webassemblyjs/leb128": {
381 | "version": "1.11.6",
382 | "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
383 | "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
384 | "dev": true,
385 | "dependencies": {
386 | "@xtuc/long": "4.2.2"
387 | }
388 | },
389 | "node_modules/@webassemblyjs/utf8": {
390 | "version": "1.11.6",
391 | "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
392 | "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
393 | "dev": true
394 | },
395 | "node_modules/@webassemblyjs/wasm-edit": {
396 | "version": "1.11.6",
397 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
398 | "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
399 | "dev": true,
400 | "dependencies": {
401 | "@webassemblyjs/ast": "1.11.6",
402 | "@webassemblyjs/helper-buffer": "1.11.6",
403 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
404 | "@webassemblyjs/helper-wasm-section": "1.11.6",
405 | "@webassemblyjs/wasm-gen": "1.11.6",
406 | "@webassemblyjs/wasm-opt": "1.11.6",
407 | "@webassemblyjs/wasm-parser": "1.11.6",
408 | "@webassemblyjs/wast-printer": "1.11.6"
409 | }
410 | },
411 | "node_modules/@webassemblyjs/wasm-gen": {
412 | "version": "1.11.6",
413 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
414 | "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
415 | "dev": true,
416 | "dependencies": {
417 | "@webassemblyjs/ast": "1.11.6",
418 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
419 | "@webassemblyjs/ieee754": "1.11.6",
420 | "@webassemblyjs/leb128": "1.11.6",
421 | "@webassemblyjs/utf8": "1.11.6"
422 | }
423 | },
424 | "node_modules/@webassemblyjs/wasm-opt": {
425 | "version": "1.11.6",
426 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
427 | "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
428 | "dev": true,
429 | "dependencies": {
430 | "@webassemblyjs/ast": "1.11.6",
431 | "@webassemblyjs/helper-buffer": "1.11.6",
432 | "@webassemblyjs/wasm-gen": "1.11.6",
433 | "@webassemblyjs/wasm-parser": "1.11.6"
434 | }
435 | },
436 | "node_modules/@webassemblyjs/wasm-parser": {
437 | "version": "1.11.6",
438 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
439 | "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
440 | "dev": true,
441 | "dependencies": {
442 | "@webassemblyjs/ast": "1.11.6",
443 | "@webassemblyjs/helper-api-error": "1.11.6",
444 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
445 | "@webassemblyjs/ieee754": "1.11.6",
446 | "@webassemblyjs/leb128": "1.11.6",
447 | "@webassemblyjs/utf8": "1.11.6"
448 | }
449 | },
450 | "node_modules/@webassemblyjs/wast-printer": {
451 | "version": "1.11.6",
452 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
453 | "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
454 | "dev": true,
455 | "dependencies": {
456 | "@webassemblyjs/ast": "1.11.6",
457 | "@xtuc/long": "4.2.2"
458 | }
459 | },
460 | "node_modules/@webpack-cli/configtest": {
461 | "version": "1.2.0",
462 | "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz",
463 | "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==",
464 | "dev": true,
465 | "peerDependencies": {
466 | "webpack": "4.x.x || 5.x.x",
467 | "webpack-cli": "4.x.x"
468 | }
469 | },
470 | "node_modules/@webpack-cli/info": {
471 | "version": "1.5.0",
472 | "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz",
473 | "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==",
474 | "dev": true,
475 | "dependencies": {
476 | "envinfo": "^7.7.3"
477 | },
478 | "peerDependencies": {
479 | "webpack-cli": "4.x.x"
480 | }
481 | },
482 | "node_modules/@webpack-cli/serve": {
483 | "version": "1.7.0",
484 | "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz",
485 | "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==",
486 | "dev": true,
487 | "peerDependencies": {
488 | "webpack-cli": "4.x.x"
489 | },
490 | "peerDependenciesMeta": {
491 | "webpack-dev-server": {
492 | "optional": true
493 | }
494 | }
495 | },
496 | "node_modules/@xtuc/ieee754": {
497 | "version": "1.2.0",
498 | "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
499 | "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
500 | "dev": true
501 | },
502 | "node_modules/@xtuc/long": {
503 | "version": "4.2.2",
504 | "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
505 | "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
506 | "dev": true
507 | },
508 | "node_modules/acorn": {
509 | "version": "8.10.0",
510 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
511 | "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
512 | "dev": true,
513 | "bin": {
514 | "acorn": "bin/acorn"
515 | },
516 | "engines": {
517 | "node": ">=0.4.0"
518 | }
519 | },
520 | "node_modules/acorn-import-assertions": {
521 | "version": "1.9.0",
522 | "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
523 | "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
524 | "dev": true,
525 | "peerDependencies": {
526 | "acorn": "^8"
527 | }
528 | },
529 | "node_modules/agent-base": {
530 | "version": "6.0.2",
531 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
532 | "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
533 | "dev": true,
534 | "dependencies": {
535 | "debug": "4"
536 | },
537 | "engines": {
538 | "node": ">= 6.0.0"
539 | }
540 | },
541 | "node_modules/ajv": {
542 | "version": "6.12.6",
543 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
544 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
545 | "dev": true,
546 | "dependencies": {
547 | "fast-deep-equal": "^3.1.1",
548 | "fast-json-stable-stringify": "^2.0.0",
549 | "json-schema-traverse": "^0.4.1",
550 | "uri-js": "^4.2.2"
551 | },
552 | "funding": {
553 | "type": "github",
554 | "url": "https://github.com/sponsors/epoberezkin"
555 | }
556 | },
557 | "node_modules/ajv-keywords": {
558 | "version": "3.5.2",
559 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
560 | "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
561 | "dev": true,
562 | "peerDependencies": {
563 | "ajv": "^6.9.1"
564 | }
565 | },
566 | "node_modules/ansi-styles": {
567 | "version": "4.3.0",
568 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
569 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
570 | "dev": true,
571 | "dependencies": {
572 | "color-convert": "^2.0.1"
573 | },
574 | "engines": {
575 | "node": ">=8"
576 | },
577 | "funding": {
578 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
579 | }
580 | },
581 | "node_modules/argparse": {
582 | "version": "1.0.10",
583 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
584 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
585 | "dev": true,
586 | "dependencies": {
587 | "sprintf-js": "~1.0.2"
588 | }
589 | },
590 | "node_modules/balanced-match": {
591 | "version": "1.0.2",
592 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
593 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
594 | "dev": true
595 | },
596 | "node_modules/big-integer": {
597 | "version": "1.6.51",
598 | "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
599 | "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
600 | "dev": true,
601 | "engines": {
602 | "node": ">=0.6"
603 | }
604 | },
605 | "node_modules/big.js": {
606 | "version": "5.2.2",
607 | "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
608 | "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
609 | "dev": true,
610 | "engines": {
611 | "node": "*"
612 | }
613 | },
614 | "node_modules/binary": {
615 | "version": "0.3.0",
616 | "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
617 | "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==",
618 | "dev": true,
619 | "dependencies": {
620 | "buffers": "~0.1.1",
621 | "chainsaw": "~0.1.0"
622 | },
623 | "engines": {
624 | "node": "*"
625 | }
626 | },
627 | "node_modules/bluebird": {
628 | "version": "3.4.7",
629 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz",
630 | "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==",
631 | "dev": true
632 | },
633 | "node_modules/brace-expansion": {
634 | "version": "1.1.11",
635 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
636 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
637 | "dev": true,
638 | "dependencies": {
639 | "balanced-match": "^1.0.0",
640 | "concat-map": "0.0.1"
641 | }
642 | },
643 | "node_modules/braces": {
644 | "version": "3.0.2",
645 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
646 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
647 | "dev": true,
648 | "dependencies": {
649 | "fill-range": "^7.0.1"
650 | },
651 | "engines": {
652 | "node": ">=8"
653 | }
654 | },
655 | "node_modules/browserslist": {
656 | "version": "4.22.1",
657 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
658 | "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
659 | "dev": true,
660 | "funding": [
661 | {
662 | "type": "opencollective",
663 | "url": "https://opencollective.com/browserslist"
664 | },
665 | {
666 | "type": "tidelift",
667 | "url": "https://tidelift.com/funding/github/npm/browserslist"
668 | },
669 | {
670 | "type": "github",
671 | "url": "https://github.com/sponsors/ai"
672 | }
673 | ],
674 | "dependencies": {
675 | "caniuse-lite": "^1.0.30001541",
676 | "electron-to-chromium": "^1.4.535",
677 | "node-releases": "^2.0.13",
678 | "update-browserslist-db": "^1.0.13"
679 | },
680 | "bin": {
681 | "browserslist": "cli.js"
682 | },
683 | "engines": {
684 | "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
685 | }
686 | },
687 | "node_modules/buffer-from": {
688 | "version": "1.1.2",
689 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
690 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
691 | "dev": true
692 | },
693 | "node_modules/buffer-indexof-polyfill": {
694 | "version": "1.0.2",
695 | "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz",
696 | "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==",
697 | "dev": true,
698 | "engines": {
699 | "node": ">=0.10"
700 | }
701 | },
702 | "node_modules/buffers": {
703 | "version": "0.1.1",
704 | "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
705 | "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==",
706 | "dev": true,
707 | "engines": {
708 | "node": ">=0.2.0"
709 | }
710 | },
711 | "node_modules/builtin-modules": {
712 | "version": "1.1.1",
713 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
714 | "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==",
715 | "dev": true,
716 | "engines": {
717 | "node": ">=0.10.0"
718 | }
719 | },
720 | "node_modules/caniuse-lite": {
721 | "version": "1.0.30001546",
722 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001546.tgz",
723 | "integrity": "sha512-zvtSJwuQFpewSyRrI3AsftF6rM0X80mZkChIt1spBGEvRglCrjTniXvinc8JKRoqTwXAgvqTImaN9igfSMtUBw==",
724 | "dev": true,
725 | "funding": [
726 | {
727 | "type": "opencollective",
728 | "url": "https://opencollective.com/browserslist"
729 | },
730 | {
731 | "type": "tidelift",
732 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
733 | },
734 | {
735 | "type": "github",
736 | "url": "https://github.com/sponsors/ai"
737 | }
738 | ]
739 | },
740 | "node_modules/chainsaw": {
741 | "version": "0.1.0",
742 | "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
743 | "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==",
744 | "dev": true,
745 | "dependencies": {
746 | "traverse": ">=0.3.0 <0.4"
747 | },
748 | "engines": {
749 | "node": "*"
750 | }
751 | },
752 | "node_modules/chalk": {
753 | "version": "4.1.2",
754 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
755 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
756 | "dev": true,
757 | "dependencies": {
758 | "ansi-styles": "^4.1.0",
759 | "supports-color": "^7.1.0"
760 | },
761 | "engines": {
762 | "node": ">=10"
763 | },
764 | "funding": {
765 | "url": "https://github.com/chalk/chalk?sponsor=1"
766 | }
767 | },
768 | "node_modules/chrome-trace-event": {
769 | "version": "1.0.3",
770 | "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
771 | "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
772 | "dev": true,
773 | "engines": {
774 | "node": ">=6.0"
775 | }
776 | },
777 | "node_modules/clone-deep": {
778 | "version": "4.0.1",
779 | "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
780 | "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
781 | "dev": true,
782 | "dependencies": {
783 | "is-plain-object": "^2.0.4",
784 | "kind-of": "^6.0.2",
785 | "shallow-clone": "^3.0.0"
786 | },
787 | "engines": {
788 | "node": ">=6"
789 | }
790 | },
791 | "node_modules/color-convert": {
792 | "version": "2.0.1",
793 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
794 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
795 | "dev": true,
796 | "dependencies": {
797 | "color-name": "~1.1.4"
798 | },
799 | "engines": {
800 | "node": ">=7.0.0"
801 | }
802 | },
803 | "node_modules/color-name": {
804 | "version": "1.1.4",
805 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
806 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
807 | "dev": true
808 | },
809 | "node_modules/colorette": {
810 | "version": "2.0.20",
811 | "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
812 | "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
813 | "dev": true
814 | },
815 | "node_modules/commander": {
816 | "version": "2.20.3",
817 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
818 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
819 | "dev": true
820 | },
821 | "node_modules/concat-map": {
822 | "version": "0.0.1",
823 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
824 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
825 | "dev": true
826 | },
827 | "node_modules/core-util-is": {
828 | "version": "1.0.3",
829 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
830 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
831 | "dev": true
832 | },
833 | "node_modules/cross-spawn": {
834 | "version": "7.0.3",
835 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
836 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
837 | "dev": true,
838 | "dependencies": {
839 | "path-key": "^3.1.0",
840 | "shebang-command": "^2.0.0",
841 | "which": "^2.0.1"
842 | },
843 | "engines": {
844 | "node": ">= 8"
845 | }
846 | },
847 | "node_modules/debug": {
848 | "version": "4.3.4",
849 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
850 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
851 | "dev": true,
852 | "dependencies": {
853 | "ms": "2.1.2"
854 | },
855 | "engines": {
856 | "node": ">=6.0"
857 | },
858 | "peerDependenciesMeta": {
859 | "supports-color": {
860 | "optional": true
861 | }
862 | }
863 | },
864 | "node_modules/diff": {
865 | "version": "4.0.2",
866 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
867 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
868 | "dev": true,
869 | "engines": {
870 | "node": ">=0.3.1"
871 | }
872 | },
873 | "node_modules/duplexer2": {
874 | "version": "0.1.4",
875 | "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
876 | "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==",
877 | "dev": true,
878 | "dependencies": {
879 | "readable-stream": "^2.0.2"
880 | }
881 | },
882 | "node_modules/electron-to-chromium": {
883 | "version": "1.4.544",
884 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.544.tgz",
885 | "integrity": "sha512-54z7squS1FyFRSUqq/knOFSptjjogLZXbKcYk3B0qkE1KZzvqASwRZnY2KzZQJqIYLVD38XZeoiMRflYSwyO4w==",
886 | "dev": true
887 | },
888 | "node_modules/emojis-list": {
889 | "version": "3.0.0",
890 | "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
891 | "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
892 | "dev": true,
893 | "engines": {
894 | "node": ">= 4"
895 | }
896 | },
897 | "node_modules/enhanced-resolve": {
898 | "version": "4.5.0",
899 | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz",
900 | "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==",
901 | "dev": true,
902 | "dependencies": {
903 | "graceful-fs": "^4.1.2",
904 | "memory-fs": "^0.5.0",
905 | "tapable": "^1.0.0"
906 | },
907 | "engines": {
908 | "node": ">=6.9.0"
909 | }
910 | },
911 | "node_modules/envinfo": {
912 | "version": "7.10.0",
913 | "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz",
914 | "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==",
915 | "dev": true,
916 | "bin": {
917 | "envinfo": "dist/cli.js"
918 | },
919 | "engines": {
920 | "node": ">=4"
921 | }
922 | },
923 | "node_modules/errno": {
924 | "version": "0.1.8",
925 | "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
926 | "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
927 | "dev": true,
928 | "dependencies": {
929 | "prr": "~1.0.1"
930 | },
931 | "bin": {
932 | "errno": "cli.js"
933 | }
934 | },
935 | "node_modules/es-module-lexer": {
936 | "version": "1.3.1",
937 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz",
938 | "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==",
939 | "dev": true
940 | },
941 | "node_modules/escalade": {
942 | "version": "3.1.1",
943 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
944 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
945 | "dev": true,
946 | "engines": {
947 | "node": ">=6"
948 | }
949 | },
950 | "node_modules/escape-string-regexp": {
951 | "version": "1.0.5",
952 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
953 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
954 | "dev": true,
955 | "engines": {
956 | "node": ">=0.8.0"
957 | }
958 | },
959 | "node_modules/eslint-scope": {
960 | "version": "5.1.1",
961 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
962 | "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
963 | "dev": true,
964 | "dependencies": {
965 | "esrecurse": "^4.3.0",
966 | "estraverse": "^4.1.1"
967 | },
968 | "engines": {
969 | "node": ">=8.0.0"
970 | }
971 | },
972 | "node_modules/esprima": {
973 | "version": "4.0.1",
974 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
975 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
976 | "dev": true,
977 | "bin": {
978 | "esparse": "bin/esparse.js",
979 | "esvalidate": "bin/esvalidate.js"
980 | },
981 | "engines": {
982 | "node": ">=4"
983 | }
984 | },
985 | "node_modules/esrecurse": {
986 | "version": "4.3.0",
987 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
988 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
989 | "dev": true,
990 | "dependencies": {
991 | "estraverse": "^5.2.0"
992 | },
993 | "engines": {
994 | "node": ">=4.0"
995 | }
996 | },
997 | "node_modules/esrecurse/node_modules/estraverse": {
998 | "version": "5.3.0",
999 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
1000 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
1001 | "dev": true,
1002 | "engines": {
1003 | "node": ">=4.0"
1004 | }
1005 | },
1006 | "node_modules/estraverse": {
1007 | "version": "4.3.0",
1008 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
1009 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
1010 | "dev": true,
1011 | "engines": {
1012 | "node": ">=4.0"
1013 | }
1014 | },
1015 | "node_modules/events": {
1016 | "version": "3.3.0",
1017 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
1018 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
1019 | "dev": true,
1020 | "engines": {
1021 | "node": ">=0.8.x"
1022 | }
1023 | },
1024 | "node_modules/fast-deep-equal": {
1025 | "version": "3.1.3",
1026 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
1027 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
1028 | "dev": true
1029 | },
1030 | "node_modules/fast-json-stable-stringify": {
1031 | "version": "2.1.0",
1032 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
1033 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
1034 | "dev": true
1035 | },
1036 | "node_modules/fastest-levenshtein": {
1037 | "version": "1.0.16",
1038 | "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
1039 | "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
1040 | "dev": true,
1041 | "engines": {
1042 | "node": ">= 4.9.1"
1043 | }
1044 | },
1045 | "node_modules/fill-range": {
1046 | "version": "7.0.1",
1047 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
1048 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
1049 | "dev": true,
1050 | "dependencies": {
1051 | "to-regex-range": "^5.0.1"
1052 | },
1053 | "engines": {
1054 | "node": ">=8"
1055 | }
1056 | },
1057 | "node_modules/find-up": {
1058 | "version": "4.1.0",
1059 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
1060 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
1061 | "dev": true,
1062 | "dependencies": {
1063 | "locate-path": "^5.0.0",
1064 | "path-exists": "^4.0.0"
1065 | },
1066 | "engines": {
1067 | "node": ">=8"
1068 | }
1069 | },
1070 | "node_modules/fs.realpath": {
1071 | "version": "1.0.0",
1072 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
1073 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
1074 | "dev": true
1075 | },
1076 | "node_modules/fstream": {
1077 | "version": "1.0.12",
1078 | "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
1079 | "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
1080 | "dev": true,
1081 | "dependencies": {
1082 | "graceful-fs": "^4.1.2",
1083 | "inherits": "~2.0.0",
1084 | "mkdirp": ">=0.5 0",
1085 | "rimraf": "2"
1086 | },
1087 | "engines": {
1088 | "node": ">=0.6"
1089 | }
1090 | },
1091 | "node_modules/fstream/node_modules/rimraf": {
1092 | "version": "2.7.1",
1093 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
1094 | "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
1095 | "dev": true,
1096 | "dependencies": {
1097 | "glob": "^7.1.3"
1098 | },
1099 | "bin": {
1100 | "rimraf": "bin.js"
1101 | }
1102 | },
1103 | "node_modules/glob": {
1104 | "version": "7.2.3",
1105 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
1106 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
1107 | "dev": true,
1108 | "dependencies": {
1109 | "fs.realpath": "^1.0.0",
1110 | "inflight": "^1.0.4",
1111 | "inherits": "2",
1112 | "minimatch": "^3.1.1",
1113 | "once": "^1.3.0",
1114 | "path-is-absolute": "^1.0.0"
1115 | },
1116 | "engines": {
1117 | "node": "*"
1118 | },
1119 | "funding": {
1120 | "url": "https://github.com/sponsors/isaacs"
1121 | }
1122 | },
1123 | "node_modules/glob-to-regexp": {
1124 | "version": "0.4.1",
1125 | "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
1126 | "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
1127 | "dev": true
1128 | },
1129 | "node_modules/graceful-fs": {
1130 | "version": "4.2.11",
1131 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
1132 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
1133 | "dev": true
1134 | },
1135 | "node_modules/has": {
1136 | "version": "1.0.4",
1137 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
1138 | "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
1139 | "dev": true,
1140 | "engines": {
1141 | "node": ">= 0.4.0"
1142 | }
1143 | },
1144 | "node_modules/has-flag": {
1145 | "version": "4.0.0",
1146 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
1147 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
1148 | "dev": true,
1149 | "engines": {
1150 | "node": ">=8"
1151 | }
1152 | },
1153 | "node_modules/http-proxy-agent": {
1154 | "version": "4.0.1",
1155 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
1156 | "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
1157 | "dev": true,
1158 | "dependencies": {
1159 | "@tootallnate/once": "1",
1160 | "agent-base": "6",
1161 | "debug": "4"
1162 | },
1163 | "engines": {
1164 | "node": ">= 6"
1165 | }
1166 | },
1167 | "node_modules/https-proxy-agent": {
1168 | "version": "5.0.1",
1169 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
1170 | "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
1171 | "dev": true,
1172 | "dependencies": {
1173 | "agent-base": "6",
1174 | "debug": "4"
1175 | },
1176 | "engines": {
1177 | "node": ">= 6"
1178 | }
1179 | },
1180 | "node_modules/import-local": {
1181 | "version": "3.1.0",
1182 | "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
1183 | "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
1184 | "dev": true,
1185 | "dependencies": {
1186 | "pkg-dir": "^4.2.0",
1187 | "resolve-cwd": "^3.0.0"
1188 | },
1189 | "bin": {
1190 | "import-local-fixture": "fixtures/cli.js"
1191 | },
1192 | "engines": {
1193 | "node": ">=8"
1194 | },
1195 | "funding": {
1196 | "url": "https://github.com/sponsors/sindresorhus"
1197 | }
1198 | },
1199 | "node_modules/inflight": {
1200 | "version": "1.0.6",
1201 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
1202 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
1203 | "dev": true,
1204 | "dependencies": {
1205 | "once": "^1.3.0",
1206 | "wrappy": "1"
1207 | }
1208 | },
1209 | "node_modules/inherits": {
1210 | "version": "2.0.4",
1211 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1212 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1213 | "dev": true
1214 | },
1215 | "node_modules/interpret": {
1216 | "version": "2.2.0",
1217 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz",
1218 | "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
1219 | "dev": true,
1220 | "engines": {
1221 | "node": ">= 0.10"
1222 | }
1223 | },
1224 | "node_modules/is-core-module": {
1225 | "version": "2.13.0",
1226 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
1227 | "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
1228 | "dev": true,
1229 | "dependencies": {
1230 | "has": "^1.0.3"
1231 | },
1232 | "funding": {
1233 | "url": "https://github.com/sponsors/ljharb"
1234 | }
1235 | },
1236 | "node_modules/is-number": {
1237 | "version": "7.0.0",
1238 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1239 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1240 | "dev": true,
1241 | "engines": {
1242 | "node": ">=0.12.0"
1243 | }
1244 | },
1245 | "node_modules/is-plain-object": {
1246 | "version": "2.0.4",
1247 | "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
1248 | "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
1249 | "dev": true,
1250 | "dependencies": {
1251 | "isobject": "^3.0.1"
1252 | },
1253 | "engines": {
1254 | "node": ">=0.10.0"
1255 | }
1256 | },
1257 | "node_modules/isarray": {
1258 | "version": "1.0.0",
1259 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
1260 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
1261 | "dev": true
1262 | },
1263 | "node_modules/isexe": {
1264 | "version": "2.0.0",
1265 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1266 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
1267 | "dev": true
1268 | },
1269 | "node_modules/isobject": {
1270 | "version": "3.0.1",
1271 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
1272 | "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
1273 | "dev": true,
1274 | "engines": {
1275 | "node": ">=0.10.0"
1276 | }
1277 | },
1278 | "node_modules/jest-worker": {
1279 | "version": "27.5.1",
1280 | "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
1281 | "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
1282 | "dev": true,
1283 | "dependencies": {
1284 | "@types/node": "*",
1285 | "merge-stream": "^2.0.0",
1286 | "supports-color": "^8.0.0"
1287 | },
1288 | "engines": {
1289 | "node": ">= 10.13.0"
1290 | }
1291 | },
1292 | "node_modules/jest-worker/node_modules/supports-color": {
1293 | "version": "8.1.1",
1294 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
1295 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
1296 | "dev": true,
1297 | "dependencies": {
1298 | "has-flag": "^4.0.0"
1299 | },
1300 | "engines": {
1301 | "node": ">=10"
1302 | },
1303 | "funding": {
1304 | "url": "https://github.com/chalk/supports-color?sponsor=1"
1305 | }
1306 | },
1307 | "node_modules/js-tokens": {
1308 | "version": "4.0.0",
1309 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1310 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1311 | "dev": true
1312 | },
1313 | "node_modules/js-yaml": {
1314 | "version": "3.14.1",
1315 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
1316 | "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
1317 | "dev": true,
1318 | "dependencies": {
1319 | "argparse": "^1.0.7",
1320 | "esprima": "^4.0.0"
1321 | },
1322 | "bin": {
1323 | "js-yaml": "bin/js-yaml.js"
1324 | }
1325 | },
1326 | "node_modules/json-parse-even-better-errors": {
1327 | "version": "2.3.1",
1328 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
1329 | "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
1330 | "dev": true
1331 | },
1332 | "node_modules/json-schema-traverse": {
1333 | "version": "0.4.1",
1334 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
1335 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
1336 | "dev": true
1337 | },
1338 | "node_modules/json5": {
1339 | "version": "2.2.3",
1340 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
1341 | "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
1342 | "dev": true,
1343 | "bin": {
1344 | "json5": "lib/cli.js"
1345 | },
1346 | "engines": {
1347 | "node": ">=6"
1348 | }
1349 | },
1350 | "node_modules/kind-of": {
1351 | "version": "6.0.3",
1352 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
1353 | "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
1354 | "dev": true,
1355 | "engines": {
1356 | "node": ">=0.10.0"
1357 | }
1358 | },
1359 | "node_modules/listenercount": {
1360 | "version": "1.0.1",
1361 | "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz",
1362 | "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==",
1363 | "dev": true
1364 | },
1365 | "node_modules/loader-runner": {
1366 | "version": "4.3.0",
1367 | "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
1368 | "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
1369 | "dev": true,
1370 | "engines": {
1371 | "node": ">=6.11.5"
1372 | }
1373 | },
1374 | "node_modules/loader-utils": {
1375 | "version": "2.0.4",
1376 | "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
1377 | "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
1378 | "dev": true,
1379 | "dependencies": {
1380 | "big.js": "^5.2.2",
1381 | "emojis-list": "^3.0.0",
1382 | "json5": "^2.1.2"
1383 | },
1384 | "engines": {
1385 | "node": ">=8.9.0"
1386 | }
1387 | },
1388 | "node_modules/locate-path": {
1389 | "version": "5.0.0",
1390 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
1391 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
1392 | "dev": true,
1393 | "dependencies": {
1394 | "p-locate": "^4.1.0"
1395 | },
1396 | "engines": {
1397 | "node": ">=8"
1398 | }
1399 | },
1400 | "node_modules/lru-cache": {
1401 | "version": "6.0.0",
1402 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
1403 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
1404 | "dev": true,
1405 | "dependencies": {
1406 | "yallist": "^4.0.0"
1407 | },
1408 | "engines": {
1409 | "node": ">=10"
1410 | }
1411 | },
1412 | "node_modules/memory-fs": {
1413 | "version": "0.5.0",
1414 | "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
1415 | "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==",
1416 | "dev": true,
1417 | "dependencies": {
1418 | "errno": "^0.1.3",
1419 | "readable-stream": "^2.0.1"
1420 | },
1421 | "engines": {
1422 | "node": ">=4.3.0 <5.0.0 || >=5.10"
1423 | }
1424 | },
1425 | "node_modules/merge-stream": {
1426 | "version": "2.0.0",
1427 | "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
1428 | "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
1429 | "dev": true
1430 | },
1431 | "node_modules/micromatch": {
1432 | "version": "4.0.5",
1433 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
1434 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
1435 | "dev": true,
1436 | "dependencies": {
1437 | "braces": "^3.0.2",
1438 | "picomatch": "^2.3.1"
1439 | },
1440 | "engines": {
1441 | "node": ">=8.6"
1442 | }
1443 | },
1444 | "node_modules/mime-db": {
1445 | "version": "1.52.0",
1446 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1447 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
1448 | "dev": true,
1449 | "engines": {
1450 | "node": ">= 0.6"
1451 | }
1452 | },
1453 | "node_modules/mime-types": {
1454 | "version": "2.1.35",
1455 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1456 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1457 | "dev": true,
1458 | "dependencies": {
1459 | "mime-db": "1.52.0"
1460 | },
1461 | "engines": {
1462 | "node": ">= 0.6"
1463 | }
1464 | },
1465 | "node_modules/minimatch": {
1466 | "version": "3.1.2",
1467 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
1468 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
1469 | "dev": true,
1470 | "dependencies": {
1471 | "brace-expansion": "^1.1.7"
1472 | },
1473 | "engines": {
1474 | "node": "*"
1475 | }
1476 | },
1477 | "node_modules/minimist": {
1478 | "version": "1.2.8",
1479 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
1480 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
1481 | "dev": true,
1482 | "funding": {
1483 | "url": "https://github.com/sponsors/ljharb"
1484 | }
1485 | },
1486 | "node_modules/mkdirp": {
1487 | "version": "0.5.6",
1488 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
1489 | "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
1490 | "dev": true,
1491 | "dependencies": {
1492 | "minimist": "^1.2.6"
1493 | },
1494 | "bin": {
1495 | "mkdirp": "bin/cmd.js"
1496 | }
1497 | },
1498 | "node_modules/ms": {
1499 | "version": "2.1.2",
1500 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1501 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
1502 | "dev": true
1503 | },
1504 | "node_modules/neo-async": {
1505 | "version": "2.6.2",
1506 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
1507 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
1508 | "dev": true
1509 | },
1510 | "node_modules/node-releases": {
1511 | "version": "2.0.13",
1512 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
1513 | "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
1514 | "dev": true
1515 | },
1516 | "node_modules/once": {
1517 | "version": "1.4.0",
1518 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1519 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
1520 | "dev": true,
1521 | "dependencies": {
1522 | "wrappy": "1"
1523 | }
1524 | },
1525 | "node_modules/p-limit": {
1526 | "version": "2.3.0",
1527 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
1528 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
1529 | "dev": true,
1530 | "dependencies": {
1531 | "p-try": "^2.0.0"
1532 | },
1533 | "engines": {
1534 | "node": ">=6"
1535 | },
1536 | "funding": {
1537 | "url": "https://github.com/sponsors/sindresorhus"
1538 | }
1539 | },
1540 | "node_modules/p-locate": {
1541 | "version": "4.1.0",
1542 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
1543 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
1544 | "dev": true,
1545 | "dependencies": {
1546 | "p-limit": "^2.2.0"
1547 | },
1548 | "engines": {
1549 | "node": ">=8"
1550 | }
1551 | },
1552 | "node_modules/p-try": {
1553 | "version": "2.2.0",
1554 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
1555 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
1556 | "dev": true,
1557 | "engines": {
1558 | "node": ">=6"
1559 | }
1560 | },
1561 | "node_modules/path-exists": {
1562 | "version": "4.0.0",
1563 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
1564 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
1565 | "dev": true,
1566 | "engines": {
1567 | "node": ">=8"
1568 | }
1569 | },
1570 | "node_modules/path-is-absolute": {
1571 | "version": "1.0.1",
1572 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1573 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
1574 | "dev": true,
1575 | "engines": {
1576 | "node": ">=0.10.0"
1577 | }
1578 | },
1579 | "node_modules/path-key": {
1580 | "version": "3.1.1",
1581 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1582 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
1583 | "dev": true,
1584 | "engines": {
1585 | "node": ">=8"
1586 | }
1587 | },
1588 | "node_modules/path-parse": {
1589 | "version": "1.0.7",
1590 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
1591 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
1592 | "dev": true
1593 | },
1594 | "node_modules/php-parser": {
1595 | "version": "3.1.5",
1596 | "resolved": "https://registry.npmjs.org/php-parser/-/php-parser-3.1.5.tgz",
1597 | "integrity": "sha512-jEY2DcbgCm5aclzBdfW86GM6VEIWcSlhTBSHN1qhJguVePlYe28GhwS0yoeLYXpM2K8y6wzLwrbq814n2PHSoQ=="
1598 | },
1599 | "node_modules/picocolors": {
1600 | "version": "1.0.0",
1601 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
1602 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
1603 | "dev": true
1604 | },
1605 | "node_modules/picomatch": {
1606 | "version": "2.3.1",
1607 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1608 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1609 | "dev": true,
1610 | "engines": {
1611 | "node": ">=8.6"
1612 | },
1613 | "funding": {
1614 | "url": "https://github.com/sponsors/jonschlinkert"
1615 | }
1616 | },
1617 | "node_modules/pkg-dir": {
1618 | "version": "4.2.0",
1619 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
1620 | "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
1621 | "dev": true,
1622 | "dependencies": {
1623 | "find-up": "^4.0.0"
1624 | },
1625 | "engines": {
1626 | "node": ">=8"
1627 | }
1628 | },
1629 | "node_modules/process-nextick-args": {
1630 | "version": "2.0.1",
1631 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
1632 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
1633 | "dev": true
1634 | },
1635 | "node_modules/prr": {
1636 | "version": "1.0.1",
1637 | "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
1638 | "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
1639 | "dev": true
1640 | },
1641 | "node_modules/punycode": {
1642 | "version": "2.3.0",
1643 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
1644 | "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
1645 | "dev": true,
1646 | "engines": {
1647 | "node": ">=6"
1648 | }
1649 | },
1650 | "node_modules/randombytes": {
1651 | "version": "2.1.0",
1652 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
1653 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
1654 | "dev": true,
1655 | "dependencies": {
1656 | "safe-buffer": "^5.1.0"
1657 | }
1658 | },
1659 | "node_modules/readable-stream": {
1660 | "version": "2.3.8",
1661 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
1662 | "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
1663 | "dev": true,
1664 | "dependencies": {
1665 | "core-util-is": "~1.0.0",
1666 | "inherits": "~2.0.3",
1667 | "isarray": "~1.0.0",
1668 | "process-nextick-args": "~2.0.0",
1669 | "safe-buffer": "~5.1.1",
1670 | "string_decoder": "~1.1.1",
1671 | "util-deprecate": "~1.0.1"
1672 | }
1673 | },
1674 | "node_modules/rechoir": {
1675 | "version": "0.7.1",
1676 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz",
1677 | "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==",
1678 | "dev": true,
1679 | "dependencies": {
1680 | "resolve": "^1.9.0"
1681 | },
1682 | "engines": {
1683 | "node": ">= 0.10"
1684 | }
1685 | },
1686 | "node_modules/resolve": {
1687 | "version": "1.22.6",
1688 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz",
1689 | "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==",
1690 | "dev": true,
1691 | "dependencies": {
1692 | "is-core-module": "^2.13.0",
1693 | "path-parse": "^1.0.7",
1694 | "supports-preserve-symlinks-flag": "^1.0.0"
1695 | },
1696 | "bin": {
1697 | "resolve": "bin/resolve"
1698 | },
1699 | "funding": {
1700 | "url": "https://github.com/sponsors/ljharb"
1701 | }
1702 | },
1703 | "node_modules/resolve-cwd": {
1704 | "version": "3.0.0",
1705 | "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
1706 | "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
1707 | "dev": true,
1708 | "dependencies": {
1709 | "resolve-from": "^5.0.0"
1710 | },
1711 | "engines": {
1712 | "node": ">=8"
1713 | }
1714 | },
1715 | "node_modules/resolve-from": {
1716 | "version": "5.0.0",
1717 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
1718 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
1719 | "dev": true,
1720 | "engines": {
1721 | "node": ">=8"
1722 | }
1723 | },
1724 | "node_modules/rimraf": {
1725 | "version": "3.0.2",
1726 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
1727 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
1728 | "dev": true,
1729 | "dependencies": {
1730 | "glob": "^7.1.3"
1731 | },
1732 | "bin": {
1733 | "rimraf": "bin.js"
1734 | },
1735 | "funding": {
1736 | "url": "https://github.com/sponsors/isaacs"
1737 | }
1738 | },
1739 | "node_modules/safe-buffer": {
1740 | "version": "5.1.2",
1741 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
1742 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
1743 | "dev": true
1744 | },
1745 | "node_modules/schema-utils": {
1746 | "version": "3.3.0",
1747 | "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
1748 | "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
1749 | "dev": true,
1750 | "dependencies": {
1751 | "@types/json-schema": "^7.0.8",
1752 | "ajv": "^6.12.5",
1753 | "ajv-keywords": "^3.5.2"
1754 | },
1755 | "engines": {
1756 | "node": ">= 10.13.0"
1757 | },
1758 | "funding": {
1759 | "type": "opencollective",
1760 | "url": "https://opencollective.com/webpack"
1761 | }
1762 | },
1763 | "node_modules/semver": {
1764 | "version": "7.5.4",
1765 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
1766 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
1767 | "dev": true,
1768 | "dependencies": {
1769 | "lru-cache": "^6.0.0"
1770 | },
1771 | "bin": {
1772 | "semver": "bin/semver.js"
1773 | },
1774 | "engines": {
1775 | "node": ">=10"
1776 | }
1777 | },
1778 | "node_modules/serialize-javascript": {
1779 | "version": "6.0.1",
1780 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
1781 | "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
1782 | "dev": true,
1783 | "dependencies": {
1784 | "randombytes": "^2.1.0"
1785 | }
1786 | },
1787 | "node_modules/setimmediate": {
1788 | "version": "1.0.5",
1789 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
1790 | "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
1791 | "dev": true
1792 | },
1793 | "node_modules/shallow-clone": {
1794 | "version": "3.0.1",
1795 | "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
1796 | "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
1797 | "dev": true,
1798 | "dependencies": {
1799 | "kind-of": "^6.0.2"
1800 | },
1801 | "engines": {
1802 | "node": ">=8"
1803 | }
1804 | },
1805 | "node_modules/shebang-command": {
1806 | "version": "2.0.0",
1807 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
1808 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
1809 | "dev": true,
1810 | "dependencies": {
1811 | "shebang-regex": "^3.0.0"
1812 | },
1813 | "engines": {
1814 | "node": ">=8"
1815 | }
1816 | },
1817 | "node_modules/shebang-regex": {
1818 | "version": "3.0.0",
1819 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1820 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
1821 | "dev": true,
1822 | "engines": {
1823 | "node": ">=8"
1824 | }
1825 | },
1826 | "node_modules/source-map": {
1827 | "version": "0.6.1",
1828 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
1829 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
1830 | "dev": true,
1831 | "engines": {
1832 | "node": ">=0.10.0"
1833 | }
1834 | },
1835 | "node_modules/source-map-support": {
1836 | "version": "0.5.21",
1837 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
1838 | "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
1839 | "dev": true,
1840 | "dependencies": {
1841 | "buffer-from": "^1.0.0",
1842 | "source-map": "^0.6.0"
1843 | }
1844 | },
1845 | "node_modules/sprintf-js": {
1846 | "version": "1.0.3",
1847 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
1848 | "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
1849 | "dev": true
1850 | },
1851 | "node_modules/string_decoder": {
1852 | "version": "1.1.1",
1853 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
1854 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
1855 | "dev": true,
1856 | "dependencies": {
1857 | "safe-buffer": "~5.1.0"
1858 | }
1859 | },
1860 | "node_modules/supports-color": {
1861 | "version": "7.2.0",
1862 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
1863 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
1864 | "dev": true,
1865 | "dependencies": {
1866 | "has-flag": "^4.0.0"
1867 | },
1868 | "engines": {
1869 | "node": ">=8"
1870 | }
1871 | },
1872 | "node_modules/supports-preserve-symlinks-flag": {
1873 | "version": "1.0.0",
1874 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
1875 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
1876 | "dev": true,
1877 | "engines": {
1878 | "node": ">= 0.4"
1879 | },
1880 | "funding": {
1881 | "url": "https://github.com/sponsors/ljharb"
1882 | }
1883 | },
1884 | "node_modules/tapable": {
1885 | "version": "1.1.3",
1886 | "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
1887 | "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
1888 | "dev": true,
1889 | "engines": {
1890 | "node": ">=6"
1891 | }
1892 | },
1893 | "node_modules/terser": {
1894 | "version": "5.21.0",
1895 | "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz",
1896 | "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==",
1897 | "dev": true,
1898 | "dependencies": {
1899 | "@jridgewell/source-map": "^0.3.3",
1900 | "acorn": "^8.8.2",
1901 | "commander": "^2.20.0",
1902 | "source-map-support": "~0.5.20"
1903 | },
1904 | "bin": {
1905 | "terser": "bin/terser"
1906 | },
1907 | "engines": {
1908 | "node": ">=10"
1909 | }
1910 | },
1911 | "node_modules/terser-webpack-plugin": {
1912 | "version": "5.3.9",
1913 | "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
1914 | "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
1915 | "dev": true,
1916 | "dependencies": {
1917 | "@jridgewell/trace-mapping": "^0.3.17",
1918 | "jest-worker": "^27.4.5",
1919 | "schema-utils": "^3.1.1",
1920 | "serialize-javascript": "^6.0.1",
1921 | "terser": "^5.16.8"
1922 | },
1923 | "engines": {
1924 | "node": ">= 10.13.0"
1925 | },
1926 | "funding": {
1927 | "type": "opencollective",
1928 | "url": "https://opencollective.com/webpack"
1929 | },
1930 | "peerDependencies": {
1931 | "webpack": "^5.1.0"
1932 | },
1933 | "peerDependenciesMeta": {
1934 | "@swc/core": {
1935 | "optional": true
1936 | },
1937 | "esbuild": {
1938 | "optional": true
1939 | },
1940 | "uglify-js": {
1941 | "optional": true
1942 | }
1943 | }
1944 | },
1945 | "node_modules/to-regex-range": {
1946 | "version": "5.0.1",
1947 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1948 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1949 | "dev": true,
1950 | "dependencies": {
1951 | "is-number": "^7.0.0"
1952 | },
1953 | "engines": {
1954 | "node": ">=8.0"
1955 | }
1956 | },
1957 | "node_modules/traverse": {
1958 | "version": "0.3.9",
1959 | "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
1960 | "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==",
1961 | "dev": true,
1962 | "engines": {
1963 | "node": "*"
1964 | }
1965 | },
1966 | "node_modules/ts-loader": {
1967 | "version": "8.4.0",
1968 | "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.4.0.tgz",
1969 | "integrity": "sha512-6nFY3IZ2//mrPc+ImY3hNWx1vCHyEhl6V+wLmL4CZcm6g1CqX7UKrkc6y0i4FwcfOhxyMPCfaEvh20f4r9GNpw==",
1970 | "dev": true,
1971 | "dependencies": {
1972 | "chalk": "^4.1.0",
1973 | "enhanced-resolve": "^4.0.0",
1974 | "loader-utils": "^2.0.0",
1975 | "micromatch": "^4.0.0",
1976 | "semver": "^7.3.4"
1977 | },
1978 | "engines": {
1979 | "node": ">=10.0.0"
1980 | },
1981 | "peerDependencies": {
1982 | "typescript": "*",
1983 | "webpack": "*"
1984 | }
1985 | },
1986 | "node_modules/tslib": {
1987 | "version": "1.14.1",
1988 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
1989 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
1990 | "dev": true
1991 | },
1992 | "node_modules/tslint": {
1993 | "version": "6.1.3",
1994 | "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
1995 | "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
1996 | "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.",
1997 | "dev": true,
1998 | "dependencies": {
1999 | "@babel/code-frame": "^7.0.0",
2000 | "builtin-modules": "^1.1.1",
2001 | "chalk": "^2.3.0",
2002 | "commander": "^2.12.1",
2003 | "diff": "^4.0.1",
2004 | "glob": "^7.1.1",
2005 | "js-yaml": "^3.13.1",
2006 | "minimatch": "^3.0.4",
2007 | "mkdirp": "^0.5.3",
2008 | "resolve": "^1.3.2",
2009 | "semver": "^5.3.0",
2010 | "tslib": "^1.13.0",
2011 | "tsutils": "^2.29.0"
2012 | },
2013 | "bin": {
2014 | "tslint": "bin/tslint"
2015 | },
2016 | "engines": {
2017 | "node": ">=4.8.0"
2018 | },
2019 | "peerDependencies": {
2020 | "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev"
2021 | }
2022 | },
2023 | "node_modules/tslint/node_modules/ansi-styles": {
2024 | "version": "3.2.1",
2025 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
2026 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
2027 | "dev": true,
2028 | "dependencies": {
2029 | "color-convert": "^1.9.0"
2030 | },
2031 | "engines": {
2032 | "node": ">=4"
2033 | }
2034 | },
2035 | "node_modules/tslint/node_modules/chalk": {
2036 | "version": "2.4.2",
2037 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
2038 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
2039 | "dev": true,
2040 | "dependencies": {
2041 | "ansi-styles": "^3.2.1",
2042 | "escape-string-regexp": "^1.0.5",
2043 | "supports-color": "^5.3.0"
2044 | },
2045 | "engines": {
2046 | "node": ">=4"
2047 | }
2048 | },
2049 | "node_modules/tslint/node_modules/color-convert": {
2050 | "version": "1.9.3",
2051 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
2052 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
2053 | "dev": true,
2054 | "dependencies": {
2055 | "color-name": "1.1.3"
2056 | }
2057 | },
2058 | "node_modules/tslint/node_modules/color-name": {
2059 | "version": "1.1.3",
2060 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
2061 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
2062 | "dev": true
2063 | },
2064 | "node_modules/tslint/node_modules/has-flag": {
2065 | "version": "3.0.0",
2066 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
2067 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
2068 | "dev": true,
2069 | "engines": {
2070 | "node": ">=4"
2071 | }
2072 | },
2073 | "node_modules/tslint/node_modules/semver": {
2074 | "version": "5.7.2",
2075 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
2076 | "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
2077 | "dev": true,
2078 | "bin": {
2079 | "semver": "bin/semver"
2080 | }
2081 | },
2082 | "node_modules/tslint/node_modules/supports-color": {
2083 | "version": "5.5.0",
2084 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
2085 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
2086 | "dev": true,
2087 | "dependencies": {
2088 | "has-flag": "^3.0.0"
2089 | },
2090 | "engines": {
2091 | "node": ">=4"
2092 | }
2093 | },
2094 | "node_modules/tsutils": {
2095 | "version": "2.29.0",
2096 | "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
2097 | "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
2098 | "dev": true,
2099 | "dependencies": {
2100 | "tslib": "^1.8.1"
2101 | },
2102 | "peerDependencies": {
2103 | "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev"
2104 | }
2105 | },
2106 | "node_modules/typescript": {
2107 | "version": "4.9.5",
2108 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
2109 | "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
2110 | "dev": true,
2111 | "bin": {
2112 | "tsc": "bin/tsc",
2113 | "tsserver": "bin/tsserver"
2114 | },
2115 | "engines": {
2116 | "node": ">=4.2.0"
2117 | }
2118 | },
2119 | "node_modules/unzipper": {
2120 | "version": "0.10.14",
2121 | "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz",
2122 | "integrity": "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==",
2123 | "dev": true,
2124 | "dependencies": {
2125 | "big-integer": "^1.6.17",
2126 | "binary": "~0.3.0",
2127 | "bluebird": "~3.4.1",
2128 | "buffer-indexof-polyfill": "~1.0.0",
2129 | "duplexer2": "~0.1.4",
2130 | "fstream": "^1.0.12",
2131 | "graceful-fs": "^4.2.2",
2132 | "listenercount": "~1.0.1",
2133 | "readable-stream": "~2.3.6",
2134 | "setimmediate": "~1.0.4"
2135 | }
2136 | },
2137 | "node_modules/update-browserslist-db": {
2138 | "version": "1.0.13",
2139 | "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
2140 | "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
2141 | "dev": true,
2142 | "funding": [
2143 | {
2144 | "type": "opencollective",
2145 | "url": "https://opencollective.com/browserslist"
2146 | },
2147 | {
2148 | "type": "tidelift",
2149 | "url": "https://tidelift.com/funding/github/npm/browserslist"
2150 | },
2151 | {
2152 | "type": "github",
2153 | "url": "https://github.com/sponsors/ai"
2154 | }
2155 | ],
2156 | "dependencies": {
2157 | "escalade": "^3.1.1",
2158 | "picocolors": "^1.0.0"
2159 | },
2160 | "bin": {
2161 | "update-browserslist-db": "cli.js"
2162 | },
2163 | "peerDependencies": {
2164 | "browserslist": ">= 4.21.0"
2165 | }
2166 | },
2167 | "node_modules/uri-js": {
2168 | "version": "4.4.1",
2169 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
2170 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
2171 | "dev": true,
2172 | "dependencies": {
2173 | "punycode": "^2.1.0"
2174 | }
2175 | },
2176 | "node_modules/util-deprecate": {
2177 | "version": "1.0.2",
2178 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
2179 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
2180 | "dev": true
2181 | },
2182 | "node_modules/vscode-test": {
2183 | "version": "1.6.1",
2184 | "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.6.1.tgz",
2185 | "integrity": "sha512-086q88T2ca1k95mUzffvbzb7esqQNvJgiwY4h29ukPhFo8u+vXOOmelUoU5EQUHs3Of8+JuQ3oGdbVCqaxuTXA==",
2186 | "deprecated": "This package has been renamed to @vscode/test-electron, please update to the new name",
2187 | "dev": true,
2188 | "dependencies": {
2189 | "http-proxy-agent": "^4.0.1",
2190 | "https-proxy-agent": "^5.0.0",
2191 | "rimraf": "^3.0.2",
2192 | "unzipper": "^0.10.11"
2193 | },
2194 | "engines": {
2195 | "node": ">=8.9.3"
2196 | }
2197 | },
2198 | "node_modules/watchpack": {
2199 | "version": "2.4.0",
2200 | "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
2201 | "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
2202 | "dev": true,
2203 | "dependencies": {
2204 | "glob-to-regexp": "^0.4.1",
2205 | "graceful-fs": "^4.1.2"
2206 | },
2207 | "engines": {
2208 | "node": ">=10.13.0"
2209 | }
2210 | },
2211 | "node_modules/webpack": {
2212 | "version": "5.88.2",
2213 | "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
2214 | "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
2215 | "dev": true,
2216 | "dependencies": {
2217 | "@types/eslint-scope": "^3.7.3",
2218 | "@types/estree": "^1.0.0",
2219 | "@webassemblyjs/ast": "^1.11.5",
2220 | "@webassemblyjs/wasm-edit": "^1.11.5",
2221 | "@webassemblyjs/wasm-parser": "^1.11.5",
2222 | "acorn": "^8.7.1",
2223 | "acorn-import-assertions": "^1.9.0",
2224 | "browserslist": "^4.14.5",
2225 | "chrome-trace-event": "^1.0.2",
2226 | "enhanced-resolve": "^5.15.0",
2227 | "es-module-lexer": "^1.2.1",
2228 | "eslint-scope": "5.1.1",
2229 | "events": "^3.2.0",
2230 | "glob-to-regexp": "^0.4.1",
2231 | "graceful-fs": "^4.2.9",
2232 | "json-parse-even-better-errors": "^2.3.1",
2233 | "loader-runner": "^4.2.0",
2234 | "mime-types": "^2.1.27",
2235 | "neo-async": "^2.6.2",
2236 | "schema-utils": "^3.2.0",
2237 | "tapable": "^2.1.1",
2238 | "terser-webpack-plugin": "^5.3.7",
2239 | "watchpack": "^2.4.0",
2240 | "webpack-sources": "^3.2.3"
2241 | },
2242 | "bin": {
2243 | "webpack": "bin/webpack.js"
2244 | },
2245 | "engines": {
2246 | "node": ">=10.13.0"
2247 | },
2248 | "funding": {
2249 | "type": "opencollective",
2250 | "url": "https://opencollective.com/webpack"
2251 | },
2252 | "peerDependenciesMeta": {
2253 | "webpack-cli": {
2254 | "optional": true
2255 | }
2256 | }
2257 | },
2258 | "node_modules/webpack-cli": {
2259 | "version": "4.10.0",
2260 | "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz",
2261 | "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==",
2262 | "dev": true,
2263 | "dependencies": {
2264 | "@discoveryjs/json-ext": "^0.5.0",
2265 | "@webpack-cli/configtest": "^1.2.0",
2266 | "@webpack-cli/info": "^1.5.0",
2267 | "@webpack-cli/serve": "^1.7.0",
2268 | "colorette": "^2.0.14",
2269 | "commander": "^7.0.0",
2270 | "cross-spawn": "^7.0.3",
2271 | "fastest-levenshtein": "^1.0.12",
2272 | "import-local": "^3.0.2",
2273 | "interpret": "^2.2.0",
2274 | "rechoir": "^0.7.0",
2275 | "webpack-merge": "^5.7.3"
2276 | },
2277 | "bin": {
2278 | "webpack-cli": "bin/cli.js"
2279 | },
2280 | "engines": {
2281 | "node": ">=10.13.0"
2282 | },
2283 | "funding": {
2284 | "type": "opencollective",
2285 | "url": "https://opencollective.com/webpack"
2286 | },
2287 | "peerDependencies": {
2288 | "webpack": "4.x.x || 5.x.x"
2289 | },
2290 | "peerDependenciesMeta": {
2291 | "@webpack-cli/generators": {
2292 | "optional": true
2293 | },
2294 | "@webpack-cli/migrate": {
2295 | "optional": true
2296 | },
2297 | "webpack-bundle-analyzer": {
2298 | "optional": true
2299 | },
2300 | "webpack-dev-server": {
2301 | "optional": true
2302 | }
2303 | }
2304 | },
2305 | "node_modules/webpack-cli/node_modules/commander": {
2306 | "version": "7.2.0",
2307 | "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
2308 | "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
2309 | "dev": true,
2310 | "engines": {
2311 | "node": ">= 10"
2312 | }
2313 | },
2314 | "node_modules/webpack-merge": {
2315 | "version": "5.9.0",
2316 | "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz",
2317 | "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==",
2318 | "dev": true,
2319 | "dependencies": {
2320 | "clone-deep": "^4.0.1",
2321 | "wildcard": "^2.0.0"
2322 | },
2323 | "engines": {
2324 | "node": ">=10.0.0"
2325 | }
2326 | },
2327 | "node_modules/webpack-sources": {
2328 | "version": "3.2.3",
2329 | "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
2330 | "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
2331 | "dev": true,
2332 | "engines": {
2333 | "node": ">=10.13.0"
2334 | }
2335 | },
2336 | "node_modules/webpack/node_modules/enhanced-resolve": {
2337 | "version": "5.15.0",
2338 | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
2339 | "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
2340 | "dev": true,
2341 | "dependencies": {
2342 | "graceful-fs": "^4.2.4",
2343 | "tapable": "^2.2.0"
2344 | },
2345 | "engines": {
2346 | "node": ">=10.13.0"
2347 | }
2348 | },
2349 | "node_modules/webpack/node_modules/tapable": {
2350 | "version": "2.2.1",
2351 | "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
2352 | "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
2353 | "dev": true,
2354 | "engines": {
2355 | "node": ">=6"
2356 | }
2357 | },
2358 | "node_modules/which": {
2359 | "version": "2.0.2",
2360 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
2361 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
2362 | "dev": true,
2363 | "dependencies": {
2364 | "isexe": "^2.0.0"
2365 | },
2366 | "bin": {
2367 | "node-which": "bin/node-which"
2368 | },
2369 | "engines": {
2370 | "node": ">= 8"
2371 | }
2372 | },
2373 | "node_modules/wildcard": {
2374 | "version": "2.0.1",
2375 | "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
2376 | "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
2377 | "dev": true
2378 | },
2379 | "node_modules/wrappy": {
2380 | "version": "1.0.2",
2381 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
2382 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
2383 | "dev": true
2384 | },
2385 | "node_modules/yallist": {
2386 | "version": "4.0.0",
2387 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
2388 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
2389 | "dev": true
2390 | }
2391 | }
2392 | }
2393 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "laravel-extra-intellisense",
3 | "displayName": "Laravel Extra Intellisense",
4 | "description": "better intellisense for laravel projects.",
5 | "version": "0.7.2",
6 | "publisher": "amiralizadeh9480",
7 | "icon": "images/icon.png",
8 | "engines": {
9 | "vscode": "^1.83.0"
10 | },
11 | "categories": [
12 | "Languages"
13 | ],
14 | "activationEvents": [
15 | "onLanguage:php",
16 | "onLanguage:blade"
17 | ],
18 | "repository": {
19 | "type": "git",
20 | "url": "https://github.com/amir9480/vscode-laravel-extra-intellisense"
21 | },
22 | "main": "./dist/extension.js",
23 | "contributes": {
24 | "configuration": [
25 | {
26 | "title": "Laravel Extra Intellisense",
27 | "type": "object",
28 | "properties": {
29 | "LaravelExtraIntellisense.customValidationRules": {
30 | "type": "object",
31 | "default": {},
32 | "description": "Custom validation rules snippets."
33 | },
34 | "LaravelExtraIntellisense.viewDirectorySeparator": {
35 | "type": "string",
36 | "default": ".",
37 | "description": ". or /"
38 | },
39 | "LaravelExtraIntellisense.phpCommand": {
40 | "type": "string",
41 | "default": "php -r \"{code}\"",
42 | "description": "PHP Command using to run PHP codes"
43 | },
44 | "LaravelExtraIntellisense.basePath": {
45 | "type": "string",
46 | "description": "Base path using to read files."
47 | },
48 | "LaravelExtraIntellisense.basePathForCode": {
49 | "type": "string",
50 | "description": "This base path using for require_once inside PHP code."
51 | },
52 | "LaravelExtraIntellisense.modelsPaths": {
53 | "type": "array",
54 | "default": [
55 | "app",
56 | "app/Models"
57 | ],
58 | "description": "Path of models you put your model codes."
59 | },
60 | "LaravelExtraIntellisense.modelVariables": {
61 | "type": "object",
62 | "default": {
63 | "user": "App\\Models\\User"
64 | },
65 | "description": "Variables that should provide model autocomplete."
66 | },
67 | "LaravelExtraIntellisense.modelAttributeCase": {
68 | "type": "string",
69 | "enum": [
70 | "default",
71 | "snake",
72 | "camel"
73 | ],
74 | "default": "default",
75 | "description": "Change attribute name case to snake or camel."
76 | },
77 | "LaravelExtraIntellisense.modelAccessorCase": {
78 | "type": "string",
79 | "enum": [
80 | "default",
81 | "snake",
82 | "camel"
83 | ],
84 | "default": "snake",
85 | "description": "Change accessor name case to snake or camel."
86 | },
87 | "LaravelExtraIntellisense.disableBlade": {
88 | "type": "boolean",
89 | "default": false,
90 | "description": "If you want to disable blade directives autocomplete set this to true."
91 | },
92 | "LaravelExtraIntellisense.disableAuth": {
93 | "type": "boolean",
94 | "default": false,
95 | "description": "If you want to disable authorization autocomplete set this to true."
96 | },
97 | "LaravelExtraIntellisense.disableErrorAlert": {
98 | "type": "boolean",
99 | "default": false,
100 | "description": "Hide error alerts when extension can't get data from your application."
101 | }
102 | }
103 | }
104 | ]
105 | },
106 | "scripts": {
107 | "vscode:prepublish": "webpack --mode production",
108 | "compile": "webpack --mode development",
109 | "watch": "webpack --mode development --watch",
110 | "test": "tsc -p ./",
111 | "lint": "eslint . --ext .ts,.tsx"
112 | },
113 | "dependencies": {
114 | "php-parser": "^3.0.2"
115 | },
116 | "devDependencies": {
117 | "@types/mocha": "^8.2.1",
118 | "@types/node": "^14.14.31",
119 | "@types/vscode": "^1.83.0",
120 | "ts-loader": "^8.0.17",
121 | "tslint": "^6.1.3",
122 | "typescript": "^4.2.2",
123 | "vscode-test": "^1.6.1",
124 | "webpack": "^5.24.2",
125 | "webpack-cli": "^4.5.0"
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/AssetProvider.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import * as fs from 'fs';
5 | import Helpers from './helpers';
6 |
7 |
8 | export default class AssetProvider implements vscode.CompletionItemProvider {
9 | private publicFiles: Array = [];
10 | private timer: any = null;
11 | private watcher: any = null;
12 |
13 | constructor () {
14 | this.loadFiles();
15 | if (vscode.workspace.workspaceFolders !== undefined) {
16 | this.watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(vscode.workspace.workspaceFolders[0], "public/**/*"));
17 | this.watcher.onDidChange((e: vscode.Uri) => this.onChange());
18 | this.watcher.onDidCreate((e: vscode.Uri) => this.onChange());
19 | this.watcher.onDidDelete((e: vscode.Uri) => this.onChange());
20 | }
21 | }
22 |
23 | provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Array {
24 | var out:Array = [];
25 | var func = Helpers.parseDocumentFunction(document, position);
26 | if (func === null) {
27 | return out;
28 | }
29 |
30 | if (func && (Helpers.tags.asset.functions.some((fn:string) => func.function.includes(fn)))) {
31 | for (var i in this.publicFiles) {
32 | var completeItem = new vscode.CompletionItem(this.publicFiles[i], vscode.CompletionItemKind.Constant);
33 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
34 | out.push(completeItem);
35 | }
36 | }
37 |
38 | return out;
39 | }
40 |
41 | onChange() {
42 | var self = this;
43 | if (self.timer !== null) {
44 | clearTimeout(self.timer);
45 | }
46 | self.timer = setTimeout(function () {
47 | self.loadFiles();
48 | self.timer = null;
49 | }, 2000);
50 | }
51 |
52 | loadFiles() {
53 | this.publicFiles = this.getFiles().map((path) => path.replace(/\/?public\/?/g, ""));
54 | }
55 |
56 | getFiles(scanPath: string = "public", depth: number = 0) {
57 | let out: Array = [];
58 | try {
59 | let projectScanPath = Helpers.projectPath(scanPath);
60 | if (depth <= 10 && fs.existsSync(projectScanPath)) {
61 | for (let filePath of fs.readdirSync(projectScanPath)) {
62 | let fullFilePath = projectScanPath + "/" + filePath;
63 | if (fs.lstatSync(fullFilePath).isDirectory()) {
64 | out = out.concat(this.getFiles(scanPath + "/" + filePath, depth + 1));
65 | } else if (fs.lstatSync(fullFilePath).isFile()) {
66 | if (filePath[0] != '.' && filePath.endsWith(".php") == false) {
67 | out.push(scanPath + "/" + filePath);
68 | }
69 | }
70 | }
71 | }
72 | } catch (exception) {
73 | console.error(exception);
74 | }
75 |
76 | return out;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/AuthProvider.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import Helpers from './helpers';
5 |
6 |
7 | export default class AuthProvider implements vscode.CompletionItemProvider {
8 | private abilities: Array = [];
9 | private models: Array = [];
10 |
11 | constructor () {
12 | var self = this;
13 | if (vscode.workspace.getConfiguration("LaravelExtraIntellisense").get('disableAuth', false)) {
14 | return;
15 | }
16 | self.loadAbilities();
17 | setInterval(function () {
18 | self.loadAbilities();
19 | }, 60000);
20 | }
21 |
22 | provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Array {
23 | var out:Array = [];
24 | var func = Helpers.parseDocumentFunction(document, position);
25 | if (func === null) {
26 | return out;
27 | }
28 |
29 | if (func && ((func.class && Helpers.tags.auth.classes.some((cls:string) => func.class.includes(cls))) || Helpers.tags.auth.functions.some((fn:string) => func.function.includes(fn)))) {
30 | if (func.paramIndex === 1) {
31 | for (let i in this.models) {
32 | let completeItem = new vscode.CompletionItem(this.models[i].replace(/\\/, '\\\\'), vscode.CompletionItemKind.Value);
33 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
34 | out.push(completeItem);
35 | }
36 | } else {
37 | for (let i in this.abilities) {
38 | let completeItem = new vscode.CompletionItem(this.abilities[i], vscode.CompletionItemKind.Value);
39 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
40 | out.push(completeItem);
41 | }
42 | }
43 | }
44 | return out;
45 | }
46 |
47 | loadAbilities() {
48 | try {
49 | var self = this;
50 | Helpers.getModels().then((models) => self.models = models);
51 | Helpers.runLaravel(`
52 | echo json_encode(
53 | array_merge(
54 | array_keys(Illuminate\\Support\\Facades\\Gate::abilities()),
55 | array_values(
56 | array_filter(
57 | array_unique(
58 | Illuminate\\Support\\Arr::flatten(
59 | array_map(
60 | function ($val, $key) {
61 | return array_map(
62 | function ($rm) {
63 | return $rm->getName();
64 | },
65 | (new ReflectionClass($val))->getMethods()
66 | );
67 | },
68 | Illuminate\\Support\\Facades\\Gate::policies(),
69 | array_keys(Illuminate\\Support\\Facades\\Gate::policies())
70 | )
71 | )
72 | ),
73 | function ($an) {return !in_array($an, ['allow', 'deny']);}
74 | )
75 | )
76 | )
77 | );
78 | `, 'Auth Data'
79 | ).then(function (result) {
80 | var abilities = JSON.parse(result);
81 | self.abilities = abilities;
82 | });
83 | } catch (exception) {
84 | console.error(exception);
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/BladeProvider.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import Helpers from './helpers';
5 |
6 |
7 | export default class BladeProvider implements vscode.CompletionItemProvider {
8 | private customDirectives: Array = [];
9 |
10 | constructor () {
11 | var self = this;
12 | self.loadCustomDirectives();
13 | setInterval(() => self.loadCustomDirectives(), 600000);
14 | }
15 |
16 | provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Array {
17 | let isBlade = document.languageId == 'blade' || document.languageId == 'laravel-blade' || document.fileName.endsWith('.blade.php');
18 | if (vscode.workspace.getConfiguration("LaravelExtraIntellisense").get('disableBlade', false) || isBlade === false) {
19 | return [];
20 | }
21 | var out:Array = this.getDefaultDirectives(document, position);
22 |
23 | for (var i in this.customDirectives) {
24 | var completeItem = new vscode.CompletionItem('@' + this.customDirectives[i].name + (this.customDirectives[i].hasParams ? '(...)' : ''), vscode.CompletionItemKind.Keyword);
25 | completeItem.insertText = new vscode.SnippetString('@' + this.customDirectives[i].name + (this.customDirectives[i].hasParams ? '(${1})' : ''));
26 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
27 | out.push(completeItem);
28 | }
29 | return out;
30 | }
31 |
32 | loadCustomDirectives() {
33 | try {
34 | var self = this;
35 | //
36 | Helpers.runLaravel(
37 | "$out = [];" +
38 | "foreach (app(Illuminate\\View\\Compilers\\BladeCompiler::class)->getCustomDirectives() as $name => $customDirective) {" +
39 | " if ($customDirective instanceof \\Closure) {" +
40 | " $out[] = ['name' => $name, 'hasParams' => (new ReflectionFunction($customDirective))->getNumberOfParameters() >= 1];" +
41 | " } elseif (is_array($customDirective)) {" +
42 | " $out[] = ['name' => $name, 'hasParams' => (new ReflectionMethod($customDirective[0], $customDirective[1]))->getNumberOfParameters() >= 1];" +
43 | " }" +
44 | "}" +
45 | "echo json_encode($out);",
46 | "Custom Blade Directives"
47 | )
48 | .then(function (result) {
49 | var customDirectives = JSON.parse(result);
50 | self.customDirectives = customDirectives;
51 | });
52 | } catch (exception) {
53 | console.error(exception);
54 | }
55 | }
56 |
57 | getDefaultDirectives(document: vscode.TextDocument, position: vscode.Position): Array {
58 | var snippets : any = {
59 | '@if(...)': new vscode.SnippetString('@if (${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endif'),
60 | '@error(...)': new vscode.SnippetString('@error(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@enderror'),
61 | '@if(...) ... @else ... @endif': new vscode.SnippetString('@if (${1})\n' + Helpers.getSpacer() + '${2}\n' + '@else\n' + Helpers.getSpacer() + '${3}\n' + '@endif'),
62 | '@foreach(...)': new vscode.SnippetString('@foreach (${1} as ${2})\n' + Helpers.getSpacer() + '${3}\n' + '@endforeach'),
63 | '@forelse(...)': new vscode.SnippetString('@forelse (${1} as ${2})\n' + Helpers.getSpacer() + '${3}\n' + '@empty\n' + Helpers.getSpacer() + '${4}\n' + '@endforelse'),
64 | '@for(...)': new vscode.SnippetString('@for (${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endfor'),
65 | '@while(...)': new vscode.SnippetString('@while (${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endwhile'),
66 | '@switch(...)': new vscode.SnippetString('@switch(${1})\n' + Helpers.getSpacer() + '@case(${2})\n' + Helpers.getSpacer().repeat(2) + '${3}\n' + Helpers.getSpacer().repeat(2) + '@break\n\n' + Helpers.getSpacer() + '@default\n' + Helpers.getSpacer().repeat(2) + '${4}\n@endswitch'),
67 | '@case(...)': new vscode.SnippetString('@case(${1})\n' + Helpers.getSpacer() + '${2}\n@break'),
68 | '@break': new vscode.SnippetString('@break'),
69 | '@continue': new vscode.SnippetString('@continue'),
70 | '@break(...)': new vscode.SnippetString('@break(${1})'),
71 | '@continue(...)': new vscode.SnippetString('@continue(${1})'),
72 | '@default': new vscode.SnippetString('@default'),
73 | '@extends(...)': new vscode.SnippetString('@extends(${1})'),
74 | '@empty': new vscode.SnippetString('@empty'),
75 | '@verbatim ...': new vscode.SnippetString('@verbatim\n' + Helpers.getSpacer() + '${2}\n' + '@endverbatim'),
76 | '@json(...)': new vscode.SnippetString('@json(${1})'),
77 | '@elseif (...)': new vscode.SnippetString('@elseif (${1})'),
78 | '@else': new vscode.SnippetString('@else'),
79 | '@unless(...)': new vscode.SnippetString('@unless (${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endunless'),
80 | '@isset(...)': new vscode.SnippetString('@isset(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endisset'),
81 | '@empty(...)': new vscode.SnippetString('@empty(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endempty'),
82 | '@auth': new vscode.SnippetString('@auth\n' + Helpers.getSpacer() + '${1}\n' + '@endauth'),
83 | '@guest': new vscode.SnippetString('@guest\n' + Helpers.getSpacer() + '${1}\n' + '@endguest'),
84 | '@auth(...)': new vscode.SnippetString('@auth(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endauth'),
85 | '@guest(...)': new vscode.SnippetString('@guest(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endguest'),
86 | '@can(...)': new vscode.SnippetString('@can(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endcan'),
87 | '@cannot(...)': new vscode.SnippetString('@cannot(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endcannot'),
88 | '@elsecan(...)': new vscode.SnippetString('@elsecan(${1})'),
89 | '@elsecannot(...)': new vscode.SnippetString('@elsecannot(${1})'),
90 | '@production': new vscode.SnippetString('@production\n' + Helpers.getSpacer() + '${1}\n' + '@endproduction'),
91 | '@env(...)': new vscode.SnippetString('@env(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endenv'),
92 | '@hasSection(...)': new vscode.SnippetString('@hasSection(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endif'),
93 | '@sectionMissing(...)': new vscode.SnippetString('@sectionMissing(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endif'),
94 | '@include(...)': new vscode.SnippetString('@include(${1})'),
95 | '@includeIf(...)': new vscode.SnippetString('@includeIf(${1})'),
96 | '@includeWhen(...)': new vscode.SnippetString('@includeWhen(${1}, ${2})'),
97 | '@includeUnless(...)': new vscode.SnippetString('@includeUnless(${1}, ${2})'),
98 | '@includeFirst(...)': new vscode.SnippetString('@includeFirst(${1})'),
99 | '@each(...)': new vscode.SnippetString('@each(${1}, ${2}, ${3})'),
100 | '@once': new vscode.SnippetString('@production\n' + Helpers.getSpacer() + '${1}\n' + '@endonce'),
101 | '@yield(...)': new vscode.SnippetString('@yield(${1})'),
102 | '@slot(...)': new vscode.SnippetString('@slot(${1})'),
103 | '@stack(...)': new vscode.SnippetString('@stack(${1})'),
104 | '@push(...)': new vscode.SnippetString('@push(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endpush'),
105 | '@prepend(...)': new vscode.SnippetString('@prepend(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endprepend'),
106 | '@php': new vscode.SnippetString('@php\n' + Helpers.getSpacer() + '${1}\n' + '@endphp'),
107 | '@component(...)': new vscode.SnippetString('@component(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endcomponent'),
108 | '@section(...) ... @endsection': new vscode.SnippetString('@section(${1})\n' + Helpers.getSpacer() + '${2}\n' + '@endsection'),
109 | '@section(...)': new vscode.SnippetString('@section(${1})'),
110 | '@props(...)': new vscode.SnippetString('@props(${1})'),
111 | '@show': new vscode.SnippetString('@show'),
112 | '@stop': new vscode.SnippetString('@stop'),
113 | '@parent': new vscode.SnippetString('@parent'),
114 | '@csrf': new vscode.SnippetString('@csrf'),
115 | '@method(...)': new vscode.SnippetString('@method(${1})'),
116 | '@inject(...)': new vscode.SnippetString('@inject(${1}, ${2})'),
117 | '@dump(...)': new vscode.SnippetString('@dump(${1})'),
118 | '@dd(...)': new vscode.SnippetString('@dd(${1})'),
119 | '@lang(...)': new vscode.SnippetString('@lang(${1})'),
120 |
121 | '@endif': new vscode.SnippetString('@endif'),
122 | '@enderror': new vscode.SnippetString('@enderror'),
123 | '@endforeach': new vscode.SnippetString('@endforeach'),
124 | '@endforelse': new vscode.SnippetString('@endforelse'),
125 | '@endfor': new vscode.SnippetString('@endfor'),
126 | '@endwhile': new vscode.SnippetString('@endwhile'),
127 | '@endswitch': new vscode.SnippetString('@endswitch'),
128 | '@endverbatim': new vscode.SnippetString('@endverbatim'),
129 | '@endunless': new vscode.SnippetString('@endunless'),
130 | '@endisset': new vscode.SnippetString('@endisset'),
131 | '@endempty': new vscode.SnippetString('@endempty'),
132 | '@endauth': new vscode.SnippetString('@endauth'),
133 | '@endguest': new vscode.SnippetString('@endguest'),
134 | '@endproduction': new vscode.SnippetString('@endproduction'),
135 | '@endenv': new vscode.SnippetString('@endenv'),
136 | '@endonce': new vscode.SnippetString('@endonce'),
137 | '@endpush': new vscode.SnippetString('@endpush'),
138 | '@endprepend': new vscode.SnippetString('@endprepend'),
139 | '@endphp': new vscode.SnippetString('@endphp'),
140 | '@endcomponent': new vscode.SnippetString('@endcomponent'),
141 | '@endsection': new vscode.SnippetString('@endsection'),
142 | '@endslot': new vscode.SnippetString('@endslot'),
143 | '@endcan': new vscode.SnippetString('@endcan'),
144 | '@endcannot': new vscode.SnippetString('@endcannot'),
145 | };
146 |
147 | var out:Array = [];
148 | for (let snippet in snippets) {
149 | var completeItem = new vscode.CompletionItem(snippet, vscode.CompletionItemKind.Keyword);
150 | if (snippets[snippet] instanceof vscode.SnippetString) {
151 | completeItem.insertText = snippets[snippet];
152 | }
153 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
154 | out.push(completeItem);
155 | }
156 | return out;
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/ConfigProvider.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import Helpers from './helpers';
5 |
6 |
7 | export default class ConfigProvider implements vscode.CompletionItemProvider {
8 | private timer: any = null;
9 | private configs: Array = [];
10 | private watcher: any = null;
11 |
12 | constructor () {
13 | var self = this;
14 | self.loadConfigs();
15 | if (vscode.workspace.workspaceFolders !== undefined) {
16 | this.watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(vscode.workspace.workspaceFolders[0], "config/{,*,**/*}.php"));
17 | this.watcher.onDidChange((e: vscode.Uri) => this.onChange());
18 | this.watcher.onDidCreate((e: vscode.Uri) => this.onChange());
19 | this.watcher.onDidDelete((e: vscode.Uri) => this.onChange());
20 | }
21 | }
22 |
23 | provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Array {
24 | var out:Array = [];
25 | var func = Helpers.parseDocumentFunction(document, position);
26 | if (func === null) {
27 | return out;
28 | }
29 |
30 | if (func && ((func.class && Helpers.tags.config.classes.some((cls:string) => func.class.includes(cls))) || Helpers.tags.config.functions.some((fn:string) => func.function.includes(fn)))) {
31 | for (var i in this.configs) {
32 | var completeItem = new vscode.CompletionItem(this.configs[i].name, vscode.CompletionItemKind.Value);
33 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
34 | if (this.configs[i].value) {
35 | completeItem.detail = this.configs[i].value.toString();
36 | }
37 | out.push(completeItem);
38 | }
39 | }
40 | return out;
41 | }
42 |
43 | onChange() {
44 | var self = this;
45 | if (self.timer !== null) {
46 | clearTimeout(self.timer);
47 | }
48 | self.timer = setTimeout(function () {
49 | self.loadConfigs();
50 | self.timer = null;
51 | }, 5000);
52 | }
53 |
54 | loadConfigs() {
55 | try {
56 | var self = this;
57 | Helpers.runLaravel("echo json_encode(config()->all());", "Configs")
58 | .then(function (result) {
59 | var configs = JSON.parse(result);
60 | self.configs = self.getConfigs(configs);
61 | });
62 | } catch (exception) {
63 | console.error(exception);
64 | }
65 | }
66 |
67 | getConfigs(conf: any): Array {
68 | var out: Array = [];
69 | for (var i in conf) {
70 | if (conf[i] instanceof Array) {
71 | out.push({name: i, value: 'array(...)'});
72 | } else if (conf[i] instanceof Object) {
73 | out.push({name: i, value: 'array(...)'});
74 | out = out.concat(this.getConfigs(conf[i]).map(function (c) {
75 | c.name = i + "." + c.name;
76 | return c;
77 | }));
78 | } else {
79 | out.push({name: i, value: conf[i]});
80 | }
81 | }
82 | return out;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/EloquentProvider.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import Helpers from './helpers';
5 |
6 |
7 | export default class EloquentProvider implements vscode.CompletionItemProvider {
8 | private timer: any = null;
9 | private models: {[key:string]: any} = {};
10 | private watchers: Array = [];
11 |
12 | constructor () {
13 | var self = this;
14 | if (vscode.workspace.workspaceFolders !== undefined) {
15 | for (let modelsPath of vscode.workspace.getConfiguration("LaravelExtraIntellisense").get>('modelsPaths', ['app', 'app/Models']).concat(['database/migrations'])) {
16 | let watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(vscode.workspace.workspaceFolders[0], modelsPath + '/*.php'));
17 | watcher.onDidChange((e: vscode.Uri) => self.onChange());
18 | watcher.onDidCreate((e: vscode.Uri) => self.onChange());
19 | watcher.onDidDelete((e: vscode.Uri) => self.onChange());
20 | this.watchers.push(watcher);
21 | }
22 | }
23 | self.loadModels();
24 | }
25 |
26 | provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Array {
27 | var out:Array = [];
28 | var func = Helpers.parseDocumentFunction(document, position);
29 | let sourceCode = document.getText();
30 | let sourceBeforeCursor = sourceCode.substr(0, document.offsetAt(position));
31 | var isFactory = sourceBeforeCursor.includes("extends Factory") || sourceBeforeCursor.includes("$factory->define(");
32 | var match = null;
33 | var objectName = "";
34 | var modelName = "";
35 | var modelClass = "";
36 | if (func != null || isFactory) {
37 | if (func) {
38 | let modelNameRegex = /([A-z0-9_\\]+)::[^:;]+$/g;
39 | var namespaceRegex = /namespace\s+(.+);/g;
40 | var namespace = "";
41 | while ((match = modelNameRegex.exec(sourceBeforeCursor)) !== null) {
42 | modelName = match[1];
43 | }
44 | if (modelName.length === 0) {
45 | let variableNameRegex = /(\$([A-z0-9_\\]+))->[^;]+$/g;
46 | while ((match = variableNameRegex.exec(sourceBeforeCursor)) !== null) {
47 | objectName = match[2];
48 | }
49 | if (objectName.length > 0) {
50 | modelNameRegex = new RegExp("\\$" + objectName + "\\s*=\\s*([A-z0-9_\\\\]+)::[^:]", "g");
51 | while ((match = modelNameRegex.exec(sourceBeforeCursor)) !== null) {
52 | modelName = match[1];
53 | }
54 | }
55 | }
56 | if ((match = namespaceRegex.exec(sourceBeforeCursor)) !== null) {
57 | namespace = match[1];
58 | }
59 | modelClass = this.getModelClass(modelName, sourceBeforeCursor);
60 | } else {
61 | var factoryModelClassRegex = /(protected \$model = ([A-Za-z0-9_\\]+)::class;)|(\$factory->define\(\s*([A-Za-z0-9_\\]+)::class)/g
62 | if ((match = factoryModelClassRegex.exec(sourceBeforeCursor)) !== null) {
63 | if (typeof match[4] !== 'undefined') { // Laravel 7 <
64 | modelName = match[4];
65 | } else { // Laravel >= 8
66 | modelName = match[2];
67 | }
68 | }
69 | modelClass = this.getModelClass(modelName, sourceBeforeCursor);
70 | }
71 |
72 | if (typeof this.models[modelClass] !== 'undefined') {
73 | if (func && Helpers.relationMethods.some((fn:string) => func.function.includes(fn))) {
74 | out = out.concat(this.getCompletionItems(document, position, this.models[modelClass].relations));
75 | } else {
76 | out = out.concat(this.getCompletionItems(document, position, this.models[modelClass].attributes));
77 | }
78 | }
79 | } else {
80 | let isArrayObject = false;
81 | let objectRegex = /(\$?([A-z0-9_\[\]]+)|(Auth::user\(\)))\-\>[A-z0-9_]*$/g;
82 | while ((match = objectRegex.exec(sourceBeforeCursor)) !== null) {
83 | objectName = typeof match[2] !== 'undefined' ? match[2] : match[3];
84 | }
85 | if (objectName.match(/\$?[A-z0-9_]+\[.+\].*$/g)) {
86 | isArrayObject = true;
87 | objectName = objectName.replace(/\[.+\].*$/g, '');
88 | }
89 | if (objectName.length > 0 && objectName != 'Auth::user()') {
90 | let modelNameRegex = new RegExp("\\$" + objectName + "\\s*=\\s*([A-z0-9_\\\\]+)::[^:;]", "g");
91 | while ((match = modelNameRegex.exec(sourceBeforeCursor)) !== null) {
92 | modelName = match[1];
93 | }
94 | modelClass = this.getModelClass(modelName, sourceBeforeCursor);
95 | }
96 | if (modelClass == 'Auth' || objectName == 'Auth::user()') {
97 | if (typeof this.models['App\\User'] !== 'undefined') {
98 | out = out.concat(this.getModelAttributesCompletionItems(document, position, 'App\\User'));
99 | } else if (typeof this.models['App\\Models\\User'] !== 'undefined') {
100 | out = out.concat(this.getModelAttributesCompletionItems(document, position, 'App\\Models\\User'));
101 | }
102 | }
103 | let customVariables = vscode.workspace.getConfiguration("LaravelExtraIntellisense").get('modelVariables', {});
104 | for (let customVariable in customVariables) {
105 | if (customVariable === objectName && typeof this.models[customVariables[customVariable]] !== 'undefined') {
106 | out = out.concat(this.getModelAttributesCompletionItems(document, position, customVariables[customVariable]));
107 | }
108 | }
109 | for (let i in this.models) {
110 | if (i == modelClass ||
111 | (this.models[i].camelCase == objectName || this.models[i].snakeCase == objectName) ||
112 | (isArrayObject == true && (this.models[i].pluralCamelCase == objectName || this.models[i].pluralSnakeCase == objectName))
113 | ) {
114 | out = out.concat(this.getModelAttributesCompletionItems(document, position, i));
115 | }
116 | }
117 | }
118 | out = out.filter((v, i, a) => a.map((ai) => ai.label).indexOf(v.label) === i); // Remove duplicate items
119 | return out;
120 | }
121 |
122 | getModelClass(modelName: string, sourceBeforeCursor: string) {
123 | let match = null;
124 | let modelClass = "";
125 | if (modelName.length === 0) {
126 | return "";
127 | }
128 | var modelClassRegex = new RegExp("use (.+)" + modelName + ";", "g");
129 | if (modelName.substr(0, 1) === '\\') {
130 | modelClass = modelName.substr(1);
131 | } else if ((match = modelClassRegex.exec(sourceBeforeCursor)) !== null) {
132 | modelClass = match[1] + modelName;
133 | } else {
134 | modelClass = modelName;
135 | }
136 | return modelClass;
137 | }
138 |
139 | getModelAttributesCompletionItems(document: vscode.TextDocument, position: vscode.Position, modelClass: string) : Array {
140 | let out: Array = [];
141 | if (typeof this.models[modelClass] !== 'undefined') {
142 | out = out.concat(this.getCompletionItems(document, position, this.models[modelClass].attributes.map((attr: any) => attr[vscode.workspace.getConfiguration("LaravelExtraIntellisense").get('modelAttributeCase', 'default')])));
143 | out = out.concat(this.getCompletionItems(document, position, this.models[modelClass].accessors.map((attr: any) => attr[vscode.workspace.getConfiguration("LaravelExtraIntellisense").get('modelAccessorCase', 'snake')]), vscode.CompletionItemKind.Constant));
144 | out = out.concat(this.getCompletionItems(document, position, this.models[modelClass].relations, vscode.CompletionItemKind.Value));
145 | }
146 | return out;
147 | }
148 |
149 | getCompletionItems(document: vscode.TextDocument, position: vscode.Position, items: Array, type: vscode.CompletionItemKind = vscode.CompletionItemKind.Property) : Array {
150 | let out: Array = [];
151 | for (let item of items) {
152 | var completeItem = new vscode.CompletionItem(item, type);
153 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
154 | out.push(completeItem);
155 | }
156 | return out;
157 | }
158 |
159 | onChange() {
160 | var self = this;
161 | if (self.timer !== null) {
162 | clearTimeout(self.timer);
163 | }
164 | self.timer = setTimeout(function () {
165 | self.loadModels();
166 | self.timer = null;
167 | }, 5000);
168 | }
169 |
170 | loadModels() {
171 | var self = this;
172 | try {
173 | Helpers.runLaravel(
174 | "foreach (['" + vscode.workspace.getConfiguration("LaravelExtraIntellisense").get>('modelsPaths', ['app', 'app/Models']).join('\', \'') + "'] as $modelPath) {" +
175 | " if (is_dir(base_path($modelPath))) {" +
176 | " foreach (scandir(base_path($modelPath)) as $sourceFile) {" +
177 | " if (substr($sourceFile, -4) == '.php' && is_file(base_path(\"$modelPath/$sourceFile\"))) {" +
178 | " include_once base_path(\"$modelPath/$sourceFile\");" +
179 | " }" +
180 | " }" +
181 | " }" +
182 | "}" +
183 | "$modelClasses = array_values(array_filter(get_declared_classes(), function ($declaredClass) {" +
184 | " return is_subclass_of($declaredClass, 'Illuminate\\Database\\Eloquent\\Model') && $declaredClass != 'Illuminate\\Database\\Eloquent\\Relations\\Pivot' && $declaredClass != 'Illuminate\\Foundation\\Auth\\User';" +
185 | "}));" +
186 | "$output = [];" +
187 | "foreach ($modelClasses as $modelClass) {" +
188 | " $classReflection = new \\ReflectionClass($modelClass);" +
189 | " $output[$modelClass] = [" +
190 | " 'name' => $classReflection->getShortName()," +
191 | " 'camelCase' => Illuminate\\Support\\Str::camel($classReflection->getShortName())," +
192 | " 'snakeCase' => Illuminate\\Support\\Str::snake($classReflection->getShortName())," +
193 | " 'pluralCamelCase' => Illuminate\\Support\\Str::camel(Illuminate\\Support\\Str::plural($classReflection->getShortName()))," +
194 | " 'pluralSnakeCase' => Illuminate\\Support\\Str::snake(Illuminate\\Support\\Str::plural($classReflection->getShortName()))," +
195 | " 'attributes' => []," +
196 | " 'accessors' => []," +
197 | " 'relations' => []" +
198 | " ];" +
199 | " try {" +
200 | " $modelInstance = $modelClass::first();" +
201 | " $attributes = array_values(array_unique(array_merge(app($modelClass)->getFillable(), array_keys($modelInstance ? $modelInstance->getAttributes() : []))));" +
202 | " $output[$modelClass]['attributes'] = array_map(function ($attribute) {" +
203 | " return ['default' => $attribute, 'snake' => Illuminate\\Support\\Str::snake($attribute), 'camel' => Illuminate\\Support\\Str::camel($attribute)];" +
204 | " }, $attributes);" +
205 | " } catch (\\Throwable $e) {}" +
206 | " foreach ($classReflection->getMethods() as $classMethod) {" +
207 | " try {" +
208 | " if (" +
209 | " $classMethod->isStatic() == false &&" +
210 | " $classMethod->isPublic() == true &&" +
211 | " substr($classMethod->getName(), 0, 3) != 'get' &&" +
212 | " substr($classMethod->getName(), 0, 3) != 'set' &&" +
213 | " count($classMethod->getParameters()) == 0 &&" +
214 | " preg_match('/belongsTo|hasMany|hasOne|morphOne|morphMany|morphTo/', implode('', array_slice(file($classMethod->getFileName()), $classMethod->getStartLine(), $classMethod->getEndLine() - $classMethod->getStartLine() - 1)))" +
215 | " ) {" +
216 | " $output[$modelClass]['relations'][] = $classMethod->getName();" +
217 | " } elseif (" +
218 | " substr($classMethod->getName(), 0, 3) == 'get' && " +
219 | " substr($classMethod->getName(), -9) == 'Attribute' &&" +
220 | " !empty(substr($classMethod->getName(), 3, -9))" +
221 | " ) {" +
222 | " $attributeName = substr($classMethod->getName(), 3, -9);" +
223 | " $output[$modelClass]['accessors'][] = ['default' => $attributeName, 'snake' => Illuminate\\Support\\Str::snake($attributeName), 'camel' => Illuminate\\Support\\Str::camel($attributeName)];" +
224 | " }" +
225 | " } catch (\\Throwable $e) {}" +
226 | " }" +
227 | " sort($output[$modelClass]['attributes']);" +
228 | " sort($output[$modelClass]['relations']);" +
229 | "}" +
230 | "echo json_encode($output);",
231 | "Eloquent Attributes and Relations"
232 | ).then(function (result) {
233 | let models = JSON.parse(result);
234 | self.models = models;
235 | }).catch(function (e) {
236 | console.error(e);
237 | });
238 | } catch (exception) {
239 | console.error(exception);
240 | }
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/src/EnvProvider.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import * as fs from 'fs';
5 | import Helpers from './helpers';
6 |
7 |
8 | export default class EnvProvider implements vscode.CompletionItemProvider {
9 | private enviroments: { [key: string]: string } = {};
10 | private timer: any = null;
11 | private watcher: any = null;
12 |
13 | constructor () {
14 | this.loadEnv();
15 | if (vscode.workspace.workspaceFolders !== undefined) {
16 | this.watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(vscode.workspace.workspaceFolders[0], ".env"));
17 | this.watcher.onDidChange((e: vscode.Uri) => this.onChange());
18 | this.watcher.onDidCreate((e: vscode.Uri) => this.onChange());
19 | this.watcher.onDidDelete((e: vscode.Uri) => this.onChange());
20 | }
21 | }
22 |
23 | provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Array {
24 | var out:Array = [];
25 | var func = Helpers.parseDocumentFunction(document, position);
26 | if (func === null) {
27 | return out;
28 | }
29 |
30 | if (func && (Helpers.tags.env.functions.some((fn:string) => func.function.includes(fn)))) {
31 | for (var i in this.enviroments) {
32 | var completeItem = new vscode.CompletionItem(i, vscode.CompletionItemKind.Constant);
33 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
34 | completeItem.detail = this.enviroments[i];
35 | out.push(completeItem);
36 | }
37 | }
38 | return out;
39 | }
40 |
41 | onChange() {
42 | var self = this;
43 | if (self.timer !== null) {
44 | clearTimeout(self.timer);
45 | }
46 | self.timer = setTimeout(function () {
47 | self.loadEnv();
48 | self.timer = null;
49 | }, 5000);
50 | }
51 |
52 | loadEnv() {
53 | try {
54 | if (fs.existsSync(Helpers.projectPath(".env"))) {
55 | let enviroments: any = {};
56 | let envs = fs.readFileSync(Helpers.projectPath('.env'), 'utf8').split("\n");
57 | for (let i in envs) {
58 | let envKeyValue = envs[i].split('=');
59 | if (envKeyValue.length == 2) {
60 | enviroments[envKeyValue[0]] = envKeyValue[1];
61 | }
62 | }
63 | this.enviroments = enviroments;
64 | }
65 | } catch (exception) {
66 | console.error(exception);
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/MiddlewareProvider.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import Helpers from './helpers';
5 |
6 |
7 | export default class MiddlewareProvider implements vscode.CompletionItemProvider {
8 | private timer: any = null;
9 | private middlewares: Array = [];
10 | private watcher: any = null;
11 |
12 |
13 | constructor () {
14 | var self = this;
15 | self.loadMiddlewares();
16 | if (vscode.workspace.workspaceFolders !== undefined) {
17 | this.watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(vscode.workspace.workspaceFolders[0], "app/Http/Kernel.php"));
18 | this.watcher.onDidChange((e: vscode.Uri) => this.onChange());
19 | }
20 | }
21 |
22 | provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Array {
23 | var out:Array = [];
24 | var func = Helpers.parseDocumentFunction(document, position);
25 | if (func === null) {
26 | return out;
27 | }
28 |
29 | if (func.function.includes("middleware")) {
30 | for (let i in this.middlewares) {
31 | var completeItem = new vscode.CompletionItem(i, vscode.CompletionItemKind.Enum);
32 | completeItem.detail = this.middlewares[i];
33 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
34 | out.push(completeItem);
35 | }
36 | }
37 | return out;
38 | }
39 |
40 | onChange() {
41 | var self = this;
42 | if (self.timer !== null) {
43 | clearTimeout(self.timer);
44 | }
45 | self.timer = setTimeout(function () {
46 | self.loadMiddlewares();
47 | self.timer = null;
48 | }, 5000);
49 | }
50 |
51 | loadMiddlewares() {
52 | if (vscode.workspace.workspaceFolders instanceof Array && vscode.workspace.workspaceFolders.length > 0) {
53 | try {
54 | var self = this;
55 | // array_map(function ($rh) {return $rh->getName();}, array_filter((new ReflectionMethod('App\Http\Middleware\Authenticate', 'handle'))->getParameters(), function ($rc) {return $rc->getName() != 'request' && $rc->getName() != 'next';}))
56 | Helpers.runLaravel(
57 | "$middlewares = array_merge(app('Illuminate\\Contracts\\Http\\Kernel')->getMiddlewareGroups(), app('Illuminate\\Contracts\\Http\\Kernel')->getRouteMiddleware());" +
58 | "foreach ($middlewares as $key => &$value) {" +
59 | " if (is_array($value)) {" +
60 | " $value = null;" +
61 | " } else {" +
62 | " $parameters = array_filter((new ReflectionMethod($value, 'handle'))->getParameters(), function ($rc) {" +
63 | " return $rc->getName() != 'request' && $rc->getName() != 'next';" +
64 | " });" +
65 | " $value = implode(',', array_map(function ($rh) {" +
66 | " return $rh->getName() . ($rh->isVariadic() ? '...' : '');" +
67 | " }, $parameters));" +
68 | " if (empty($value)) {" +
69 | " $value = null;" +
70 | " }" +
71 | " };" +
72 | "}" +
73 | "echo json_encode($middlewares);",
74 | "Middlewares"
75 | )
76 | .then(function (result) {
77 | let middlewares = JSON.parse(result);
78 | self.middlewares = middlewares;
79 | });
80 | } catch (exception) {
81 | console.error(exception);
82 | }
83 | }
84 | }
85 | }
86 |
87 |
--------------------------------------------------------------------------------
/src/MixProvider.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import * as fs from 'fs';
5 | import Helpers from './helpers';
6 |
7 |
8 | export default class MixProvider implements vscode.CompletionItemProvider {
9 | private mixes: Array = [];
10 |
11 | constructor () {
12 | this.loadMix();
13 | setInterval(() => this.loadMix(), 60000);
14 | }
15 |
16 | provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Array {
17 | var out:Array = [];
18 | var func = Helpers.parseDocumentFunction(document, position);
19 | if (func === null) {
20 | return out;
21 | }
22 |
23 | if (func && (Helpers.tags.mix.functions.some((fn:string) => func.function.includes(fn)))) {
24 | for (var i in this.mixes) {
25 | var completeItem = new vscode.CompletionItem(this.mixes[i], vscode.CompletionItemKind.Value);
26 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
27 | out.push(completeItem);
28 | }
29 | }
30 | return out;
31 | }
32 |
33 | loadMix() {
34 | try {
35 | if (fs.existsSync(Helpers.projectPath("public/mix-manifest.json"))) {
36 | var mixes = JSON.parse(fs.readFileSync(Helpers.projectPath('public/mix-manifest.json'), 'utf8'));
37 | this.mixes = Object.keys(mixes).map((mixFile) => mixFile.replace(/^\//g, ''));
38 | }
39 | } catch (exception) {
40 | console.error(exception);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/RouteProvider.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import * as fs from 'fs';
5 | import Helpers from './helpers';
6 |
7 |
8 | export default class RouteProvider implements vscode.CompletionItemProvider {
9 | private timer: any = null;
10 | private routes: Array = [];
11 | private controllers: Array = [];
12 | private watcher: any = null;
13 |
14 |
15 | constructor () {
16 | var self = this;
17 | self.loadRoutes();
18 | self.loadControllers();
19 | if (vscode.workspace.workspaceFolders !== undefined) {
20 | this.watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(vscode.workspace.workspaceFolders[0], "{,**/}{Controllers,[Rr]oute}{,s}{.php,/*.php,/**/*.php}"));
21 | this.watcher.onDidChange((e: vscode.Uri) => this.onChange());
22 | this.watcher.onDidCreate((e: vscode.Uri) => this.onChange());
23 | this.watcher.onDidDelete((e: vscode.Uri) => this.onChange());
24 | }
25 | }
26 |
27 | provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Array {
28 | var out:Array = [];
29 | var func = Helpers.parseDocumentFunction(document, position);
30 | if (func === null) {
31 | return out;
32 | }
33 |
34 | if (func && ((func.class && Helpers.tags.route.classes.some((cls:string) => func.class.includes(cls))) || Helpers.tags.route.functions.some((fn:string) => func.function.includes(fn)))) {
35 | if (func.class === 'Route' && ['get', 'post', 'put', 'patch', 'delete', 'options', 'any', 'match'].some((fc:string) => func.function.includes(fc))) {
36 | if ((func.function === 'match' && func.paramIndex === 2) || (func.function !== 'match' && func.paramIndex === 1)) {
37 | // Route action autocomplete.
38 | for (let i in this.controllers) {
39 | if (typeof this.controllers[i] === "string" && this.controllers[i].length > 0) {
40 | var completeItem2 = new vscode.CompletionItem(this.controllers[i], vscode.CompletionItemKind.Enum);
41 | completeItem2.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
42 | out.push(completeItem2);
43 | }
44 | }
45 | }
46 | } else if (func.function.includes('middleware') === false) {
47 | if (func.paramIndex === 1) {
48 | // route parameters autocomplete
49 | for (let i in this.routes) {
50 | if (this.routes[i].name === func.parameters[0]) {
51 | for (var j in this.routes[i].parameters) {
52 | var completeItem = new vscode.CompletionItem(this.routes[i].parameters[j], vscode.CompletionItemKind.Variable);
53 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
54 | out.push(completeItem);
55 | }
56 | return out;
57 | }
58 | }
59 | }
60 |
61 | // Route name autocomplete
62 | for (let i in this.routes) {
63 | if (typeof this.routes[i].name === "string" && this.routes[i].name.length > 0) {
64 | var completeItem3 = new vscode.CompletionItem(this.routes[i].name, vscode.CompletionItemKind.Enum);
65 | completeItem3.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
66 | completeItem3.detail = this.routes[i].action +
67 | "\n\n" +
68 | this.routes[i].method +
69 | ":" +
70 | this.routes[i].uri;
71 | out.push(completeItem3);
72 | }
73 | }
74 | }
75 | }
76 | return out;
77 | }
78 |
79 | onChange() {
80 | var self = this;
81 | if (self.timer !== null) {
82 | clearTimeout(self.timer);
83 | }
84 | self.timer = setTimeout(function () {
85 | self.loadRoutes();
86 | self.loadControllers();
87 | self.timer = null;
88 | }, 5000);
89 | }
90 |
91 | loadRoutes() {
92 | if (vscode.workspace.workspaceFolders instanceof Array && vscode.workspace.workspaceFolders.length > 0) {
93 | try {
94 | var self = this;
95 | Helpers.runLaravel(
96 | "echo json_encode(array_map(function ($route) {" +
97 | " return ['method' => implode('|', array_filter($route->methods(), function ($method) {" +
98 | " return $method != 'HEAD';" +
99 | " })), 'uri' => $route->uri(), 'name' => $route->getName(), 'action' => str_replace('App\\\\Http\\\\Controllers\\\\', '', $route->getActionName()), 'parameters' => $route->parameterNames()];" +
100 | "}, app('router')->getRoutes()->getRoutes()));",
101 | "HTTP Routes"
102 | )
103 | .then(function (result) {
104 | var routes = JSON.parse(result);
105 | routes = routes.filter((route: any) => route !== 'null');
106 | self.routes = routes;
107 | });
108 | } catch (exception) {
109 | console.error(exception);
110 | }
111 | }
112 | }
113 |
114 | loadControllers() {
115 | try {
116 | this.controllers = this.getControllers(Helpers.projectPath("app/Http/Controllers")).map((contoller) => contoller.replace(/@__invoke/, ''));
117 | this.controllers = this.controllers.filter((v, i, a) => a.indexOf(v) === i);
118 | } catch (exception) {
119 | console.error(exception);
120 | }
121 | }
122 |
123 | getControllers(path: string): Array {
124 | var self = this;
125 | var controllers: Array = [];
126 | if (path.substr(-1) !== '/' && path.substr(-1) !== '\\') {
127 | path += "/";
128 | }
129 | if (fs.existsSync(path) && fs.lstatSync(path).isDirectory()) {
130 | fs.readdirSync(path).forEach(function (file) {
131 | if (fs.lstatSync(path+file).isDirectory()) {
132 | controllers = controllers.concat(self.getControllers(path + file + "/"));
133 | } else {
134 | if (file.includes(".php")) {
135 | var controllerContent = fs.readFileSync(path + file, 'utf8');
136 | if (controllerContent.length < 50000) {
137 | var match = ((/class\s+([A-Za-z0-9_]+)\s+extends\s+.+/g).exec(controllerContent));
138 | var matchNamespace = ((/namespace .+\\Http\\Controllers\\?([A-Za-z0-9_]*)/g).exec(controllerContent));
139 | var functionRegex = /public\s+function\s+([A-Za-z0-9_]+)\(.*\)/g;
140 | if (match !== null && matchNamespace) {
141 | var className = match[1];
142 | var namespace = matchNamespace[1];
143 | while ((match = functionRegex.exec(controllerContent)) !== null && match[1] !== '__construct') {
144 | if (namespace.length > 0) {
145 | controllers.push(namespace + '\\' + className + '@' + match[1]);
146 | }
147 | controllers.push(className + '@' + match[1]);
148 | }
149 | }
150 | }
151 | }
152 | }
153 | });
154 | }
155 | return controllers;
156 | }
157 | }
158 |
159 |
--------------------------------------------------------------------------------
/src/TranslationProvider.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import * as fs from "fs";
5 | import Helpers from './helpers';
6 |
7 |
8 | export default class TranslationProvider implements vscode.CompletionItemProvider {
9 | private timer: any = null;
10 | private translations: Array = [];
11 | private watcher: any = null;
12 |
13 | constructor () {
14 | var self = this;
15 | self.loadTranslations();
16 | if (vscode.workspace.workspaceFolders !== undefined) {
17 | this.watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(vscode.workspace.workspaceFolders[0], "{,**/}{lang,localization,localizations,trans,translation,translations}/{*,**/*}"));
18 | this.watcher.onDidChange((e: vscode.Uri) => this.onChange());
19 | this.watcher.onDidCreate((e: vscode.Uri) => this.onChange());
20 | this.watcher.onDidDelete((e: vscode.Uri) => this.onChange());
21 | }
22 | }
23 |
24 | provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Array {
25 | var out:Array = [];
26 | var func = Helpers.parseDocumentFunction(document, position);
27 | if (func === null) {
28 | return out;
29 | }
30 |
31 | if (func && ((func.class && Helpers.tags.trans.classes.some((cls:string) => func.class.includes(cls))) || Helpers.tags.trans.functions.some((fn:string) => func.function.includes(fn)))) {
32 | if (func.paramIndex === 1) {
33 | // parameters autocomplete
34 | var paramRegex = /\:([A-Za-z0-9_]+)/g;
35 | var match = null;
36 |
37 | for (let i in this.translations) {
38 | if (this.translations[i].name === func.parameters[0]) {
39 | while ((match = paramRegex.exec(this.translations[i].value)) !== null) {
40 | var completeItem = new vscode.CompletionItem(match[1], vscode.CompletionItemKind.Variable);
41 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
42 | out.push(completeItem);
43 | }
44 | return out;
45 | }
46 | }
47 | return out;
48 | }
49 |
50 | for (let i in this.translations) {
51 | var completeItem = new vscode.CompletionItem(this.translations[i].name, vscode.CompletionItemKind.Value);
52 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
53 | if (this.translations[i].value) {
54 | completeItem.detail = this.translations[i].value.toString();
55 | }
56 | out.push(completeItem);
57 | }
58 | }
59 | return out;
60 | }
61 |
62 | onChange() {
63 | var self = this;
64 | if (self.timer) {
65 | clearTimeout(self.timer);
66 | }
67 | self.timer = setTimeout(function () {
68 | self.loadTranslations();
69 | self.timer = null;
70 | }, 5000);
71 | }
72 |
73 | loadTranslations () {
74 | var translations:Array = [];
75 | try {
76 | var self = this;
77 | Helpers.runLaravel("echo json_encode(app('translator')->getLoader()->namespaces());", "Translation namespaces")
78 | .then(async function (result) {
79 | var tranlationNamespaces = JSON.parse(result);
80 | for (let i in tranlationNamespaces) {
81 | tranlationNamespaces[i + '::'] = tranlationNamespaces[i];
82 | delete tranlationNamespaces[i];
83 | }
84 | let langPath = JSON.parse(await Helpers.runLaravel('echo json_encode(app()->langPath());', "Translation Path"));
85 | tranlationNamespaces[''] = langPath;
86 | var nestedTranslationGroups = function (basePath:string, relativePath: string = '') : Array {
87 | let path = basePath + '/' + relativePath;
88 | let out: Array = [];
89 | if (fs.existsSync(path) && fs.lstatSync(path).isDirectory()) {
90 | fs.readdirSync(path).forEach(function (file) {
91 | if (fs.lstatSync(path + '/' + file).isFile()) {
92 | out.push(relativePath + '/' + file.replace(/\.php/, ''));
93 | } else if (fs.lstatSync(path + '/' + file).isDirectory()) {
94 | let nestedOut = nestedTranslationGroups(basePath, (relativePath.length > 0 ? relativePath + '/' : '') + file);
95 | for (let nested of nestedOut) {
96 | out.push(nested);
97 | }
98 | }
99 | });
100 | }
101 | return out;
102 | }
103 | var translationGroups:any = [];
104 | fs.readdirSync(langPath).forEach(function (langDir) {
105 | var path:any = langPath + '/' + langDir;
106 | if (fs.existsSync(path) && fs.lstatSync(path).isDirectory()) {
107 | fs.readdirSync(path).forEach(function (subDirectory) {
108 | let subDirectoryPath = path + '/' + subDirectory;
109 | if (fs.existsSync(subDirectoryPath) && fs.lstatSync(subDirectoryPath).isDirectory()) {
110 | let nestedDirectories = nestedTranslationGroups(path, subDirectory);
111 | for (let nestedDirectory of nestedDirectories) {
112 | translationGroups.push(nestedDirectory);
113 | }
114 | }
115 | });
116 | }
117 | });
118 | for (let i in tranlationNamespaces) {
119 | if (fs.existsSync(tranlationNamespaces[i]) && fs.lstatSync(tranlationNamespaces[i]).isDirectory()) {
120 | fs.readdirSync(tranlationNamespaces[i]).forEach(function (langDir) {
121 | var path:any = tranlationNamespaces[i] + '/' + langDir;
122 | if (fs.existsSync(path) && fs.lstatSync(path).isDirectory()) {
123 | fs.readdirSync(path).forEach(function (file) {
124 | if (fs.lstatSync(path + '/' + file).isFile()) {
125 | translationGroups.push(i + file.replace(/\.php/, ''));
126 | }
127 | });
128 | }
129 | });
130 | }
131 | }
132 | translationGroups = translationGroups.filter(function(item:any, index:any, array:any){ return array.indexOf(item) === index; });
133 | Helpers.runLaravel("echo json_encode([" + translationGroups.map((transGroup: string) => "'" + transGroup + "' => __('" + transGroup + "')").join(",") + "]);", "Translations inside namespaces")
134 | .then(function (translationGroupsResult) {
135 | translationGroups = JSON.parse(translationGroupsResult);
136 | for(var i in translationGroups) {
137 | translations = translations.concat(self.getTranslations(translationGroups[i], i));
138 | }
139 | self.translations = translations;
140 | Helpers.runLaravel("echo json_encode(__('*'));", "Default path Translations")
141 | .then(function (jsontransResult) {
142 | translations = translations.concat(self.getTranslations(JSON.parse(jsontransResult), '').map(function (transInfo) {
143 | transInfo.name = transInfo.name.replace(/^\./, '');
144 | return transInfo;
145 | }));
146 | self.translations = translations;
147 | });
148 | });
149 | });
150 | } catch (exception) {
151 | console.error(exception);
152 | }
153 | }
154 |
155 | getTranslations(translations: Array, prefix: string): Array {
156 | var out: Array = [];
157 | for (var i in translations) {
158 | if (translations[i] instanceof Object) {
159 | out.push({name: prefix + '.' + i, value: "array(...)"});
160 | out = out.concat(this.getTranslations(translations[i], prefix + '.' + i));
161 | } else {
162 | out.push({name: prefix + '.' + i, value: translations[i]});
163 | }
164 | }
165 | return out;
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/src/ValidationProvider.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import Helpers from './helpers';
5 |
6 |
7 | export default class ValidationProvider implements vscode.CompletionItemProvider {
8 | private rules: any = {
9 | 'accepted' : 'accepted',
10 | 'active_url' : 'active_url',
11 | 'after_or_equal' : 'after_or_equal:${0:date}',
12 | 'after' : 'after:date',
13 | 'alpha_dash' : 'alpha_dash',
14 | 'alpha_num' : 'alpha_num',
15 | 'alpha' : 'alpha',
16 | 'array' : 'array',
17 | 'ascii' : 'ascii',
18 | 'bail' : 'bail',
19 | 'before_or_equal' : 'before_or_equal:${1:date}',
20 | 'before' : 'before:${1:date}',
21 | 'between' : 'between:${1:min},${2:max}',
22 | 'boolean' : 'boolean',
23 | 'confirmed' : 'confirmed',
24 | 'current_password' : 'current_password:${1:api}',
25 | 'date_equals' : 'date_equals:${1:date}',
26 | 'date_format' : 'date_format:${1:format}',
27 | 'date' : 'date',
28 | 'decimal' : 'decimal:${1:min},${2:max}',
29 | 'declined_if' : 'declined_if:${1:anotherfield},${2:value}',
30 | 'declined' : 'declined',
31 | 'different' : 'different:${1:field}',
32 | 'digits_between' : 'digits_between:${1:min},${2:max}',
33 | 'digits' : 'digits:${1:value}',
34 | 'dimensions' : 'dimensions',
35 | 'distinct' : 'distinct',
36 | 'doesnt_end_with' : 'doesnt_end_with:${1:foo},${2:bar}',
37 | 'doesnt_start_with' : 'doesnt_start_with:${1:foo},${2:bar}',
38 | 'email' : 'email',
39 | 'ends_with' : 'ends_with:${1}',
40 | 'exists' : 'exists:${2:table},${3:column}',
41 | 'file' : 'file',
42 | 'filled' : 'filled',
43 | 'gt' : 'gt:${1:field}',
44 | 'gte' : 'gte:${1:field}',
45 | 'image' : 'image',
46 | 'in_array' : 'in_array:${1:anotherfield.*}',
47 | 'in' : 'in:${1:something},${2:something else}',
48 | 'integer' : 'integer',
49 | 'ip' : 'ip',
50 | 'ipv4' : 'ipv4',
51 | 'ipv6' : 'ipv6',
52 | 'json' : 'json',
53 | 'lowercase' : 'lowercase',
54 | 'lt' : 'lt:${1:field}',
55 | 'lte' : 'lte:${1:field}',
56 | 'mac_address' : 'mac_address',
57 | 'max_digits' : 'max_digits:${1:value}',
58 | 'max' : 'max:${1:value}',
59 | 'mimes' : 'mimes:${1:png,jpg}',
60 | 'mimetypes' : 'mimetypes:${1:text/plain}',
61 | 'min_digits' : 'min_digits:${1:value}',
62 | 'min' : 'min:${1:value}',
63 | 'multiple_of' : 'multiple_of:${1:value}',
64 | 'not_in' : 'not_in:${1:something},${2:something else}',
65 | 'not_regex' : 'not_regex:${1:pattern}',
66 | 'nullable' : 'nullable',
67 | 'numeric' : 'numeric',
68 | 'password' : 'password',
69 | 'present' : 'present',
70 | 'prohibited_if' : 'prohibited_if:${1:anotherfield},${2:value}',
71 | 'prohibited_unless' : 'prohibited_unless:${1:anotherfield},${2:value}',
72 | 'prohibited' : 'prohibited',
73 | 'regex' : 'regex:${1:pattern}',
74 | 'required_array_keys' : 'required_array_keys:${1:foo},${2:bar}',
75 | 'required_if' : 'required_if:${1:anotherfield},${2:value}',
76 | 'required_unless' : 'required_unless:${1:anotherfield},${2:value}',
77 | 'required_with_all' : 'required_with_all:${1:anotherfield},${2:anotherfield}',
78 | 'required_with' : 'required_with:${1:anotherfield}',
79 | 'required_without_all' : 'required_without_all:${1:anotherfield},${2:anotherfield}',
80 | 'required_without' : 'required_without:${1:anotherfield}',
81 | 'required' : 'required',
82 | 'same' : 'same:${1:field}',
83 | 'size' : 'size:${1:value}',
84 | 'sometimes' : 'sometimes',
85 | 'starts_with' : 'starts_with:${1:foo},${2:bar}',
86 | 'string' : 'string',
87 | 'timezone' : 'timezone',
88 | 'unique' : 'unique:${1:table},${2:column},${3:except},${4:id}',
89 | 'uppercase' : 'uppercase',
90 | 'url' : 'url',
91 | 'uuid' : 'uuid',
92 | };
93 |
94 | provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Array {
95 | var out:Array = [];
96 | var func = Helpers.parseDocumentFunction(document, position);
97 |
98 | if (
99 | (func && func.paramIndex !== null && func.function && Helpers.tags.validation.functions.some((fn:string) => func.function.includes(fn))) ||
100 | (func && func.paramIndex !== null && func.class && Helpers.tags.validation.classes.some((cls:string) => func.class.includes(cls))) ||
101 | (document
102 | .getText()
103 | .match(/class .* extends (\S+Request)/g) ||
104 | document
105 | .getText()
106 | .match(
107 | /use (Illuminate\\Foundation\\Http\\FormRequest)/g
108 | ))
109 | ) {
110 | var rules = this.rules;
111 | Object.assign(rules, vscode.workspace.getConfiguration("LaravelExtraIntellisense.customValidationRules"));
112 | for (var i in rules) {
113 | var completeItem = new vscode.CompletionItem(i, vscode.CompletionItemKind.Enum);
114 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
115 | completeItem.insertText = new vscode.SnippetString(this.rules[i]);
116 | out.push(completeItem);
117 | }
118 | }
119 | return out;
120 | }
121 | }
--------------------------------------------------------------------------------
/src/ViewProvider.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import * as fs from "fs";
5 | import Helpers from './helpers';
6 |
7 | export default class ViewProvider implements vscode.CompletionItemProvider {
8 | private timer: any = null;
9 | private views: {[key:string]: string} = {};
10 | private watcher: any = null;
11 |
12 | constructor () {
13 | var self = this;
14 | self.loadViews();
15 | if (vscode.workspace.workspaceFolders !== undefined) {
16 | this.watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(vscode.workspace.workspaceFolders[0], "{,**/}{view,views}/{*,**/*}"));
17 | this.watcher.onDidCreate((e: vscode.Uri) => this.onChange());
18 | this.watcher.onDidDelete((e: vscode.Uri) => this.onChange());
19 | }
20 | }
21 |
22 | provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Array {
23 | var out:Array = [];
24 | var func = Helpers.parseDocumentFunction(document, position);
25 | if (func === null) {
26 | return out;
27 | }
28 |
29 | if (func && ((func.class && Helpers.tags.view.classes.some((cls:string) => func.class.includes(cls))) || Helpers.tags.view.functions.some((fn:string) => func.function.includes(fn)))) {
30 | if (func.paramIndex === 0) {
31 | for (let i in this.views) {
32 | var completeItem = new vscode.CompletionItem(i, vscode.CompletionItemKind.Constant);
33 | completeItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
34 | out.push(completeItem);
35 | }
36 | } else if (typeof this.views[func.parameters[0]] !== 'undefined') {
37 | var viewContent = fs.readFileSync(this.views[func.parameters[0]], 'utf8');
38 | var variableRegex = /\$([A-Za-z_][A-Za-z0-9_]*)/g;
39 | var r:any = [];
40 | var variableNames = [];
41 | while (r = variableRegex.exec(viewContent)) {
42 | variableNames.push(r[1]);
43 | }
44 | variableNames = variableNames.filter((v, i, a) => a.indexOf(v) === i);
45 | for (let i in variableNames) {
46 | var variableCompleteItem = new vscode.CompletionItem(variableNames[i], vscode.CompletionItemKind.Constant);
47 | variableCompleteItem.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
48 | out.push(variableCompleteItem);
49 | }
50 | }
51 | } else if (func && (func.function === '@section' || func.function === '@push')) {
52 | out = this.getYields(func.function, document.getText());
53 | }
54 | return out;
55 | }
56 |
57 | getYields(func:string, documentText: string): Array {
58 | var out: Array = [];
59 | var extendsRegex = /@extends\s*\([\'\"](.+)[\'\"]\)/g;
60 | var regexResult:any = [];
61 | if (regexResult = extendsRegex.exec(documentText)) {
62 | if (typeof this.views[regexResult[1]] !== 'undefined') {
63 | var parentContent = fs.readFileSync(this.views[regexResult[1]], 'utf8');
64 | var yieldRegex = /@yield\s*\([\'\"]([A-Za-z0-9_\-\.]+)[\'\"](,.*)?\)/g;
65 | if (func === '@push') {
66 | yieldRegex = /@stack\s*\([\'\"]([A-Za-z0-9_\-\.]+)[\'\"](,.*)?\)/g;
67 | }
68 | var yieldNames = [];
69 | while (regexResult = yieldRegex.exec(parentContent)) {
70 | yieldNames.push(regexResult[1]);
71 | }
72 | yieldNames = yieldNames.filter((v, i, a) => a.indexOf(v) === i);
73 | for (var i in yieldNames) {
74 | var yieldCompleteItem = new vscode.CompletionItem(yieldNames[i], vscode.CompletionItemKind.Constant);
75 | out.push(yieldCompleteItem);
76 | }
77 | out = out.concat(this.getYields(func, parentContent));
78 | }
79 | }
80 | return out;
81 | }
82 |
83 | onChange() {
84 | var self = this;
85 | if (self.timer) {
86 | clearTimeout(self.timer);
87 | }
88 | self.timer = setTimeout(function () {
89 | self.loadViews();
90 | self.timer = null;
91 | }, 5000);
92 | }
93 |
94 | loadViews () {
95 | try {
96 | var self = this;
97 | var code = "echo json_encode(app('view')->getFinder()->getHints());";
98 | Helpers.runLaravel(code.replace("getHints", "getPaths"), "Views paths")
99 | .then(function (viewPathsResult) {
100 | var viewPaths = JSON.parse(viewPathsResult);
101 | Helpers.runLaravel(code, "Views")
102 | .then(function (viewNamespacesResult) {
103 | var viewNamespaces = JSON.parse(viewNamespacesResult);
104 | for (let i in viewPaths) {
105 | viewPaths[i] = viewPaths[i].replace(Helpers.projectPath('/', true), Helpers.projectPath('/'));
106 | }
107 | for (let i in viewNamespaces) {
108 | for (let j in viewNamespaces[i]) {
109 | viewNamespaces[i][j] = viewNamespaces[i][j].replace(Helpers.projectPath('/', true), Helpers.projectPath('/'));
110 | }
111 | }
112 | let views:any = {};
113 | for (let i in viewPaths) {
114 | views = Object.assign(views, self.getViews(viewPaths[i]));
115 | }
116 | for (let i in viewNamespaces) {
117 | for (var j in viewNamespaces[i]) {
118 | var viewsInNamespace = self.getViews(viewNamespaces[i][j]);
119 | for (var k in viewsInNamespace) {
120 | views[i + "::" + k] = viewNamespaces[k];
121 | }
122 | }
123 | }
124 | self.views = views;
125 | });
126 | });
127 | } catch (exception) {
128 | console.error(exception);
129 | }
130 | }
131 |
132 | getViews(path: string): {[key:string]: string} {
133 | if (path.substr(-1) !== '/' && path.substr(-1) !== '\\') {
134 | path += "/";
135 | }
136 | var out: {[key:string]: string} = {};
137 | var self = this;
138 | if (fs.existsSync(path) && fs.lstatSync(path).isDirectory()) {
139 | fs.readdirSync(path).forEach(function (file) {
140 | if (fs.lstatSync(path+file).isDirectory()) {
141 | var viewsInDirectory = self.getViews(path + file + "/");
142 | for (var i in viewsInDirectory) {
143 | out[file + vscode.workspace.getConfiguration("LaravelExtraIntellisense").get('viewDirectorySeparator') + i] = viewsInDirectory[i];
144 | }
145 | } else {
146 | if (file.includes("blade.php")) {
147 | out[file.replace(".blade.php", "")] = path + file;
148 | }
149 | }
150 | });
151 | }
152 | return out;
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/ViteProvider.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import * as fs from 'fs';
5 | import Helpers from './helpers';
6 |
7 | export default class ViteProvider implements vscode.CompletionItemProvider {
8 | private viteAssets: Array = [];
9 |
10 | constructor() {
11 | this.loadViteManifest();
12 | setInterval(() => this.loadViteManifest(), 60000);
13 | }
14 |
15 | provideCompletionItems(
16 | document: vscode.TextDocument,
17 | position: vscode.Position,
18 | token: vscode.CancellationToken,
19 | context: vscode.CompletionContext
20 | ): Array {
21 | const completions: Array = [];
22 | const func = Helpers.parseDocumentFunction(document, position);
23 |
24 | if (func === null) {
25 | return completions;
26 | }
27 |
28 | if (func && (Helpers.tags.vite.functions.some((fn: string) => func.function.includes(fn)))) {
29 | for (const asset of this.viteAssets) {
30 | const item = new vscode.CompletionItem(asset, vscode.CompletionItemKind.Value);
31 | item.range = document.getWordRangeAtPosition(position, Helpers.wordMatchRegex);
32 | completions.push(item);
33 | }
34 | }
35 |
36 | return completions;
37 | }
38 |
39 | private loadViteManifest() {
40 | try {
41 | const manifestPath = Helpers.projectPath('public/build/manifest.json');
42 | if (fs.existsSync(manifestPath)) {
43 | const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
44 | this.viteAssets = Object.keys(manifest);
45 | }
46 | } catch (exception) {
47 | console.error(exception);
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/src/extension.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import * as fs from "fs";
5 | import Helpers from "./helpers";
6 |
7 | import RouteProvider from "./RouteProvider";
8 | import ViewProvider from "./ViewProvider";
9 | import ConfigProvider from './ConfigProvider';
10 | import TranslationProvider from './TranslationProvider';
11 | import MixProvider from './MixProvider';
12 | import ViteProvider from './ViteProvider';
13 | import ValidationProvider from './ValidationProvider';
14 | import EnvProvider from './EnvProvider';
15 | import MiddlewareProvider from './MiddlewareProvider';
16 | import AuthProvider from './AuthProvider';
17 | import AssetProvider from './AssetProvider';
18 | import EloquentProvider from './EloquentProvider';
19 | import BladeProvider from './BladeProvider';
20 | import { sep } from 'path';
21 |
22 |
23 | export function activate(context: vscode.ExtensionContext) {
24 | showWelcomeMessage(context);
25 | vscode.workspace.onDidOpenTextDocument((document) => {
26 | if (isDatabaseRelatedFile(document)) {
27 | suggestDevDbExtension(context);
28 | }
29 | });
30 |
31 | if (vscode.workspace.workspaceFolders instanceof Array && vscode.workspace.workspaceFolders.length > 0) {
32 | if (fs.existsSync(Helpers.projectPath("artisan"))) {
33 | if (Helpers.outputChannel === null) {
34 | Helpers.outputChannel = vscode.window.createOutputChannel("Laravel Extra Intellisense", {log: true});
35 | Helpers.outputChannel.info("Laravel Extra Intellisense Started...");
36 | }
37 |
38 | const LANGUAGES =
39 | [
40 | { scheme: 'file', language: 'php' },
41 | { scheme: 'file', language: 'blade' },
42 | { scheme: 'file', language: 'laravel-blade' }
43 | ];
44 | const TRIGGER_CHARACTERS = "\"'".split("");
45 |
46 | context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LANGUAGES, new RouteProvider, ...TRIGGER_CHARACTERS));
47 | context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LANGUAGES, new ViewProvider, ...TRIGGER_CHARACTERS));
48 | context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LANGUAGES, new ConfigProvider, ...TRIGGER_CHARACTERS));
49 | context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LANGUAGES, new TranslationProvider, ...TRIGGER_CHARACTERS));
50 | context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LANGUAGES, new MixProvider, ...TRIGGER_CHARACTERS));
51 | context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LANGUAGES, new ViteProvider(), ...TRIGGER_CHARACTERS));
52 | context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LANGUAGES, new ValidationProvider, ...TRIGGER_CHARACTERS.concat(['|'])));
53 | context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LANGUAGES, new EnvProvider, ...TRIGGER_CHARACTERS));
54 | context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LANGUAGES, new MiddlewareProvider, ...TRIGGER_CHARACTERS));
55 | context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LANGUAGES, new AuthProvider, ...TRIGGER_CHARACTERS));
56 | context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LANGUAGES, new AssetProvider, ...TRIGGER_CHARACTERS));
57 | context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LANGUAGES, new EloquentProvider, ...TRIGGER_CHARACTERS.concat(['>'])));
58 | context.subscriptions.push(vscode.languages.registerCompletionItemProvider(LANGUAGES, new BladeProvider, '@'));
59 | }
60 | }
61 | }
62 |
63 | export function deactivate() {}
64 |
65 | function showWelcomeMessage(context: vscode.ExtensionContext) {
66 | let previousVersion = context.globalState.get('laravel-extra-intellisense-version');
67 | let currentVersion = vscode.extensions.getExtension('amiralizadeh9480.laravel-extra-intellisense')?.packageJSON?.version;
68 | let message : string | null = null;
69 | let previousVersionArray = previousVersion ? previousVersion.split('.').map((s: string) => Number(s)) : [0, 0, 0];
70 | let currentVersionArray = currentVersion.split('.').map((s: string) => Number(s));
71 | if (previousVersion === undefined || previousVersion.length === 0) {
72 | message = "Thanks for using Laravel Extra Intellisense. Please consider configure the extension settings, so it can boot your Laravel project currectly and get data needed for autocompletion.";
73 | } else if (currentVersion !== previousVersion && (
74 | // (previousVersionArray[0] === currentVersionArray[0] && previousVersionArray[1] === currentVersionArray[1] && previousVersionArray[2] < currentVersionArray[2]) ||
75 | (previousVersionArray[0] === currentVersionArray[0] && previousVersionArray[1] < currentVersionArray[1]) ||
76 | (previousVersionArray[0] < currentVersionArray[0])
77 | )
78 | ) {
79 | message = "Laravel Extra Intellisense updated to " + currentVersion + " - New Feature✨ : Add Vite autocompletion support.";
80 | }
81 | if (message) {
82 | vscode.window.showInformationMessage(message, '⭐️ Star on Github', '🐞 Report Bug')
83 | .then(function (val: string | undefined) {
84 | if (val === '⭐️ Rate') {
85 | vscode.env.openExternal(vscode.Uri.parse('https://marketplace.visualstudio.com/items?itemName=amiralizadeh9480.laravel-extra-intellisense'));
86 | } else if (val === '🐞 Report Bug') {
87 | vscode.env.openExternal(vscode.Uri.parse('https://github.com/amir9480/vscode-laravel-extra-intellisense/issues'));
88 | } else if (val === '⭐️ Star on Github') {
89 | vscode.env.openExternal(vscode.Uri.parse('https://github.com/amir9480/vscode-laravel-extra-intellisense'));
90 | }
91 | });
92 | context.globalState.update('laravel-extra-intellisense-version', currentVersion);
93 | }
94 | }
95 |
96 | function isDatabaseRelatedFile(document: vscode.TextDocument): boolean {
97 | const filePath = document.uri.fsPath;
98 | const isInModelsPath = filePath.includes(`app${sep}Models`);
99 | const isInDatabasePath = filePath.includes(`database${sep}`);
100 |
101 | return isInModelsPath || isInDatabasePath
102 | }
103 |
104 | async function suggestDevDbExtension(context: vscode.ExtensionContext) {
105 | const DEVDB_EXTENSION_ID = 'damms005.devdb';
106 | const RECOMMENDATION_KEY = 'laravel-extra-intellisense-devdb-extension-recommendation';
107 | const NOT_INTERESTED_KEY = 'laravel-extra-intellisense-devdb-extension-not-interested';
108 | const isDevDbExtensionInstalled = vscode.extensions.getExtension(DEVDB_EXTENSION_ID) !== undefined;
109 |
110 | if (isDevDbExtensionInstalled || context.globalState.get(NOT_INTERESTED_KEY)) {
111 | return;
112 | }
113 |
114 | const currentTime = Date.now();
115 | const lastRecommendation = context.globalState.get(RECOMMENDATION_KEY);
116 | const aYearSinceLastRecommendation = lastRecommendation && (((currentTime - lastRecommendation) > 365 * 24 * 60 * 60 * 1000));
117 |
118 | if (!lastRecommendation || aYearSinceLastRecommendation) {
119 | const selection = await vscode.window.showInformationMessage(
120 | 'Would you like to have Laravel Eloquent model code lens and query explainer?',
121 | 'Check it Out',
122 | 'Not Interested',
123 | 'Remind Me Later'
124 | );
125 |
126 | if (selection === 'Check it Out') {
127 | vscode.commands.executeCommand(
128 | 'extension.open',
129 | DEVDB_EXTENSION_ID
130 | );
131 | } else if (selection === 'Not Interested') {
132 | context.globalState.update(NOT_INTERESTED_KEY, true);
133 | } else if (selection === 'Remind Me Later') {
134 | context.globalState.update(RECOMMENDATION_KEY, currentTime);
135 | }
136 | }
137 | }
--------------------------------------------------------------------------------
/src/helpers.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import * as vscode from 'vscode';
4 | import * as cp from 'child_process';
5 | import * as fs from 'fs';
6 | import * as os from 'os';
7 | import { resolve } from 'path';
8 |
9 | export default class Helpers {
10 |
11 | static wordMatchRegex = /[\w\d\-_\.\:\\\/@]+/g;
12 | static phpParser:any = null;
13 | static cachedParseFunction:any = null;
14 | static modelsCache: Array;
15 | static modelsCacheTime: number = 0;
16 | static outputChannel: vscode.LogOutputChannel|null = null;
17 | static lastErrorMessage: number = 0;
18 | static disableErrorMessage: boolean = false;
19 |
20 | static tags:any = {
21 | config: {classes: ['Config'] , functions: ['config']},
22 | mix: {classes: [] , functions: ['mix']},
23 | vite: {classes: [] , functions: ['vite', '@vite']},
24 | route: {classes: ['Route'] , functions: ['route', 'signedRoute']},
25 | trans: {classes: ['Lang'] , functions: ['__', 'trans', '@lang']},
26 | validation: {classes: ['Validator'] , functions: ['validate', 'sometimes', 'rules']},
27 | view: {classes: ['View'] , functions: ['view', 'markdown', 'links', '@extends', '@component', '@include', '@each']},
28 | env: {classes: [] , functions: ['env']},
29 | auth: {classes: ['Gate'] , functions: ['can', '@can', '@cannot', '@canany']},
30 | asset: {classes: [] , functions: ['asset']},
31 | model: {classes: [] , functions: []},
32 | };
33 | static functionRegex: any = null;
34 |
35 | static relationMethods = ['has', 'orHas', 'whereHas', 'orWhereHas', 'whereDoesntHave', 'orWhereDoesntHave',
36 | 'doesntHave', 'orDoesntHave', 'hasMorph', 'orHasMorph', 'doesntHaveMorph', 'orDoesntHaveMorph',
37 | 'whereHasMorph', 'orWhereHasMorph', 'whereDoesntHaveMorph', 'orWhereDoesntHaveMorph',
38 | 'withAggregate', 'withCount', 'withMax', 'withMin', 'withSum', 'withAvg'];
39 |
40 | /**
41 | * Create full path from project file name
42 | *
43 | * @param path
44 | * @param forCode
45 | * @param string
46 | */
47 | static projectPath(path:string, forCode: boolean = false) : string {
48 | if (path[0] !== '/') {
49 | path = '/' + path;
50 | }
51 |
52 | let basePath = vscode.workspace.getConfiguration("LaravelExtraIntellisense").get('basePath');
53 | if (forCode === false && basePath && basePath.length > 0) {
54 | if (basePath.startsWith('.') && vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) {
55 | basePath = resolve(vscode.workspace.workspaceFolders[0].uri.fsPath, basePath);
56 | }
57 | basePath = basePath.replace(/[\/\\]$/, "");
58 | return basePath + path;
59 | }
60 |
61 | let basePathForCode = vscode.workspace.getConfiguration("LaravelExtraIntellisense").get('basePathForCode');
62 | if (forCode && basePathForCode && basePathForCode.length > 0) {
63 | if (basePathForCode.startsWith('.') && vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) {
64 | basePathForCode = resolve(vscode.workspace.workspaceFolders[0].uri.fsPath, basePathForCode);
65 | }
66 | basePathForCode = basePathForCode.replace(/[\/\\]$/, "");
67 | return basePathForCode + path;
68 | }
69 |
70 | if (vscode.workspace.workspaceFolders instanceof Array && vscode.workspace.workspaceFolders.length > 0) {
71 | for (let workspaceFolder of vscode.workspace.workspaceFolders) {
72 | if (fs.existsSync(workspaceFolder.uri.fsPath + "/artisan")) {
73 | return workspaceFolder.uri.fsPath + path;
74 | }
75 | }
76 | }
77 | return "";
78 | }
79 |
80 | static arrayUnique(value:any, index:any, self:Array) {
81 | return self.indexOf(value) === index;
82 | }
83 |
84 | static showErrorPopup() {
85 | let disableErrorAlert = vscode.workspace.getConfiguration("LaravelExtraIntellisense").get('disableErrorAlert');
86 | if (
87 | disableErrorAlert == false &&
88 | Helpers.disableErrorMessage == false &&
89 | Helpers.lastErrorMessage + 10 < Date.now()/1000
90 | ) {
91 | Helpers.lastErrorMessage = Date.now()/1000;
92 |
93 | vscode.window.showErrorMessage('Laravel Extra Intellisense error', 'View Error', 'Don\'t show again')
94 | .then(function (val: string | undefined) {
95 | if (val === 'Don\'t show again') {
96 | Helpers.disableErrorMessage = true;
97 | } else if (val === 'View Error') {
98 | Helpers.outputChannel?.show(true);
99 | }
100 | });
101 | }
102 | }
103 |
104 | /**
105 | * Boot laravel and run simple php code.
106 | *
107 | * @param code
108 | */
109 | static runLaravel(code: string, description: string|null = null) : Promise {
110 | code = code.replace(/(?:\r\n|\r|\n)/g, ' ');
111 | if (fs.existsSync(Helpers.projectPath("vendor/autoload.php")) && fs.existsSync(Helpers.projectPath("bootstrap/app.php"))) {
112 | var command =
113 | "define('LARAVEL_START', microtime(true));" +
114 | "require_once '" + Helpers.projectPath("vendor/autoload.php", true) + "';" +
115 | "$app = require_once '" + Helpers.projectPath("bootstrap/app.php", true) + "';" +
116 | "class VscodeLaravelExtraIntellisenseProvider extends \\Illuminate\\Support\\ServiceProvider" +
117 | "{" +
118 | " public function register() {}" +
119 | " public function boot()" +
120 | " {" +
121 | " if (method_exists($this->app['log'], 'setHandlers')) {" +
122 | " $this->app['log']->setHandlers([new \\Monolog\\Handler\\ProcessHandler()]);" +
123 | " }" +
124 | " }" +
125 | "}" +
126 | "$app->register(new VscodeLaravelExtraIntellisenseProvider($app));" +
127 | "$kernel = $app->make(Illuminate\\Contracts\\Console\\Kernel::class);" +
128 |
129 | "$status = $kernel->handle(" +
130 | "$input = new Symfony\\Component\\Console\\Input\\ArgvInput," +
131 | "new Symfony\\Component\\Console\\Output\\ConsoleOutput" +
132 | ");" +
133 | "if ($status == 0) {" +
134 | " echo '___VSCODE_LARAVEL_EXTRA_INSTELLISENSE_OUTPUT___';" +
135 | code +
136 | " echo '___VSCODE_LARAVEL_EXTRA_INSTELLISENSE_END_OUTPUT___';" +
137 | "}" +
138 | "$kernel->terminate($input, $status);" +
139 | "exit($status);"
140 |
141 | var self = this;
142 |
143 | return new Promise(function (resolve, error) {
144 | self.runPhp(command, description)
145 | .then(function (result: string) {
146 | var out : string | null | RegExpExecArray = result;
147 | out = /___VSCODE_LARAVEL_EXTRA_INSTELLISENSE_OUTPUT___(.*)___VSCODE_LARAVEL_EXTRA_INSTELLISENSE_END_OUTPUT___/g.exec(out);
148 | if (out) {
149 | resolve(out[1]);
150 | } else {
151 | error("PARSE ERROR: " + result);
152 |
153 | Helpers.outputChannel?.error("Laravel Extra Intellisense Parse Error:\n " + (description ?? '') + '\n\n' + result);
154 | Helpers.showErrorPopup();
155 | }
156 | })
157 | .catch(function (e : Error) {
158 | error(e);
159 | });
160 | });
161 | }
162 | return new Promise((resolve, error) => resolve(""));
163 | }
164 |
165 | /**
166 | * run simple php code.
167 | *
168 | * @param code
169 | */
170 | static async runPhp(code: string, description: string|null = null) : Promise {
171 | code = code.replace(/\"/g, "\\\"");
172 | if (['linux', 'openbsd', 'sunos', 'darwin'].some(unixPlatforms => os.platform().includes(unixPlatforms))) {
173 | code = code.replace(/\$/g, "\\$");
174 | code = code.replace(/\\\\'/g, '\\\\\\\\\'');
175 | code = code.replace(/\\\\"/g, '\\\\\\\\\"');
176 | }
177 | let commandTemplate = vscode.workspace.getConfiguration("LaravelExtraIntellisense").get('phpCommand') ?? "php -r \"{code}\"";
178 | let command = commandTemplate.replace("{code}", code);
179 | let out = new Promise(function (resolve, error) {
180 | if (description != null) {
181 | Helpers.outputChannel?.info("Laravel Extra Intellisense command started: " + description);
182 | }
183 |
184 | cp.exec(command,
185 | { cwd: vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0 ? vscode.workspace.workspaceFolders[0].uri.fsPath : undefined },
186 | function (err, stdout, stderr) {
187 | if (err == null) {
188 | if (description != null) {
189 | Helpers.outputChannel?.info("Laravel Extra Intellisense Resolved: " + description);
190 | }
191 | resolve(stdout);
192 | } else {
193 | const errorOutput = stderr.length > 0 ? stderr : stdout;
194 | Helpers.outputChannel?.error("Laravel Extra Intellisense Error:\n " + (description ?? '') + '\n\n' + errorOutput);
195 | Helpers.showErrorPopup();
196 | error(errorOutput);
197 | }
198 | }
199 | );
200 | });
201 | return out;
202 | }
203 |
204 | /**
205 | * Parse php code with 'php-parser' package.
206 | * @param code
207 | */
208 | static parsePhp(code: string): any {
209 | if (! Helpers.phpParser) {
210 | var PhpEngine = require('php-parser');
211 | Helpers.phpParser = new PhpEngine({
212 | parser: {
213 | extractDoc: true,
214 | php7: true
215 | },
216 | ast: {
217 | withPositions: true
218 | }
219 | });
220 | }
221 | try {
222 | return Helpers.phpParser.parseCode(code);
223 | } catch (exception) {
224 | return null;
225 | }
226 | }
227 |
228 | /**
229 | * Convert php variable defination to javascript variable.
230 | * @param code
231 | */
232 | static evalPhp(code: string): any {
233 | var out = Helpers.parsePhp('= match.index && match[0] && position < match.index + match[0].length) {
269 | if ((match2 = inlineFunctionMatch.exec(match[0])) !== null && typeof match2[3] === 'string' && typeof match[1] === 'string' && typeof match[6] === 'string' && typeof match2[1] === 'string') {
270 | out = this.parseFunction(match2[3], position - (match.index + match[1].length + match[6].length + match2[1].length), level + 1);
271 | } else if (typeof match[1] === 'string' && typeof match[6]=== 'string' && typeof match[7]=== 'string') {
272 | var textParameters = [];
273 | var paramIndex = null;
274 | var paramIndexCounter = 0;
275 | var paramsPosition = position - (match.index + match[1].length + match[6].length);
276 |
277 | var functionInsideParameter;
278 | if (match[7].length >= 4 && (functionInsideParameter = this.parseFunction(match[7], paramsPosition))) {
279 | return functionInsideParameter;
280 | }
281 |
282 | while ((match2 = paramsRegex.exec(match[7])) !== null) {
283 | textParameters.push(match2[3]);
284 | if (paramsPosition >= match2.index && typeof match2[0] === 'string' && paramsPosition <= match2.index + match2[0].length) {
285 | paramIndex = paramIndexCounter;
286 | }
287 | paramIndexCounter++;
288 | }
289 | var functionParametrs = [];
290 | for (let i in textParameters) {
291 | functionParametrs.push(this.evalPhp(textParameters[i]));
292 | }
293 | out = {
294 | class: match[3],
295 | function: match[4],
296 | paramIndex: paramIndex,
297 | parameters: functionParametrs,
298 | textParameters: textParameters
299 | };
300 | }
301 | if (level === 0) {
302 | Helpers.cachedParseFunction = {text, position, out};
303 | }
304 | }
305 | }
306 | }
307 | return out;
308 | }
309 |
310 | /**
311 | * Parse php function call from vscode editor.
312 | *
313 | * @param document
314 | * @param position
315 | */
316 | static parseDocumentFunction(document: vscode.TextDocument, position: vscode.Position) {
317 | var pos = document.offsetAt(position);
318 | return Helpers.parseFunction(document.getText(), pos);
319 | }
320 |
321 | /**
322 | * Get laravel models as array.
323 | *
324 | * @returns array
325 | */
326 | static getModels() : Promise> {
327 | var self = this;
328 | return new Promise>(function (resolve, reject) {
329 | if (Math.floor(Date.now()/1000) - self.modelsCacheTime < 60) {
330 | return resolve(self.modelsCache);
331 | } else {
332 | Helpers.runLaravel(`
333 | echo json_encode(array_values(array_filter(array_map(function ($name) {return app()->getNamespace().str_replace([app_path().'/', app_path().'\\\\', '.php', '/'], ['', '', '', '\\\\'], $name);}, array_merge(glob(app_path('*')), glob(app_path('Models/*')))), function ($class) {
334 | return class_exists($class) && is_subclass_of($class, 'Illuminate\\\\Database\\\\Eloquent\\\\Model');
335 | })));
336 | `, "Application Models").then(function (result) {
337 | var models = JSON.parse(result);
338 | self.modelsCache = models;
339 | resolve(models);
340 | })
341 | .catch(function (error) {
342 | console.error(error);
343 | resolve([]);
344 | });
345 | }
346 | });
347 | }
348 |
349 | /**
350 | * Get indent space based on user configuration
351 | */
352 | static getSpacer() : string {
353 | const editor = vscode.window.activeTextEditor;
354 | if (editor && editor.options.insertSpaces) {
355 | return ' '.repeat(editor.options.tabSize);
356 | }
357 | return '\t';
358 | }
359 | }
360 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es2019",
5 | "lib": ["ES2019"],
6 | "outDir": "out",
7 | "sourceMap": true,
8 | "strict": true,
9 | "rootDir": "src"
10 | },
11 | "include": [
12 | "src/**/*.ts",
13 | "./node_modules/vscode/vscode.d.ts",
14 | "./node_modules/vscode/lib/*",
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "no-string-throw": true,
4 | "no-unused-expression": true,
5 | "no-duplicate-variable": true,
6 | "curly": true,
7 | "class-name": true,
8 | "semicolon": [
9 | true,
10 | "always"
11 | ],
12 | "triple-equals": true
13 | },
14 | "defaultSeverity": "warning"
15 | }
16 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | //@ts-check
2 |
3 | 'use strict';
4 |
5 | const path = require('path');
6 |
7 | /**@type {import('webpack').Configuration}*/
8 | const config = {
9 | target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
10 |
11 | entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
12 | output: { // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
13 | path: path.resolve(__dirname, 'dist'),
14 | filename: 'extension.js',
15 | libraryTarget: "commonjs2",
16 | devtoolModuleFilenameTemplate: "../[resource-path]",
17 | },
18 | devtool: 'source-map',
19 | cache: false,
20 | externals: {
21 | vscode: "commonjs vscode" // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/
22 | },
23 | resolve: { // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
24 | extensions: ['.ts', '.js']
25 | },
26 | module: {
27 | rules: [
28 | {
29 | test: /\.ts$/,
30 | exclude: /node_modules/,
31 | use: [
32 | {
33 | loader: 'ts-loader',
34 | options: {
35 | compilerOptions: {
36 | "module": "es6" // override `tsconfig.json` so that TypeScript emits native JavaScript modules.
37 | }
38 | }
39 | }
40 | ]
41 | }
42 | ]
43 | }
44 | };
45 | module.exports = config;
46 |
--------------------------------------------------------------------------------